From b53fc7caa6f41bf3bd7df7d2bd947cbbe670c352 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 5 Feb 2026 08:58:41 +0000 Subject: [PATCH 001/498] GH-144179: Use recorded values to make optimizer more robust (GH-144437) * Add three new symbol kinds * Do not smuggle code object in _PUSH_FRAME operand * Fix small bug in predicate analysis --- Include/internal/pycore_opcode_metadata.h | 22 +- Include/internal/pycore_optimizer.h | 14 + Include/internal/pycore_optimizer_types.h | 24 + Include/internal/pycore_uop_ids.h | 2020 +++++++++++---------- Include/internal/pycore_uop_metadata.h | 31 +- Lib/test/test_capi/test_opt.py | 44 - Modules/_testinternalcapi/test_cases.c.h | 139 +- Python/bytecodes.c | 52 +- Python/executor_cases.c.h | 109 +- Python/generated_cases.c.h | 139 +- Python/optimizer.c | 27 +- Python/optimizer_analysis.c | 31 +- Python/optimizer_bytecodes.c | 173 +- Python/optimizer_cases.c.h | 170 +- Python/optimizer_symbols.c | 527 +++++- Python/record_functions.c.h | 47 +- 16 files changed, 2062 insertions(+), 1507 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index db28839a860008..98d9c2b51a7834 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1179,7 +1179,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, - [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, @@ -1280,10 +1280,10 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [RESERVED] = { true, INSTR_FMT_IX, 0 }, [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, - [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, - [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, + [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, - [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, + [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, @@ -1320,7 +1320,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [ANNOTATIONS_PLACEHOLDER] = { true, -1, HAS_PURE_FLAG }, [JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [JUMP_IF_FALSE] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1354,7 +1354,7 @@ _PyOpcode_macro_expansion[256] = { [BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } }, [BINARY_OP_MULTIPLY_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_DICT] = { .nuops = 4, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, - [BINARY_OP_SUBSCR_GETITEM] = { .nuops = 5, .uops = { { _RECORD_TOS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } }, + [BINARY_OP_SUBSCR_GETITEM] = { .nuops = 5, .uops = { { _RECORD_NOS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 3, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_STR_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_COMPACT_ASCII, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } }, @@ -1424,7 +1424,7 @@ _PyOpcode_macro_expansion[256] = { [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { _FORMAT_SIMPLE, OPARG_SIMPLE, 0 } } }, [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { _FORMAT_WITH_SPEC, OPARG_SIMPLE, 0 } } }, [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, OPARG_REPLACED, 0 } } }, - [FOR_ITER_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _FOR_ITER_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, + [FOR_ITER_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS_GEN_FUNC, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _FOR_ITER_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, OPARG_SIMPLE, 1 }, { _ITER_JUMP_LIST, OPARG_REPLACED, 1 }, { _ITER_NEXT_LIST, OPARG_REPLACED, 1 } } }, [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, OPARG_SIMPLE, 1 }, { _ITER_JUMP_RANGE, OPARG_REPLACED, 1 }, { _ITER_NEXT_RANGE, OPARG_SIMPLE, 1 } } }, [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, OPARG_SIMPLE, 1 }, { _ITER_JUMP_TUPLE, OPARG_REPLACED, 1 }, { _ITER_NEXT_TUPLE, OPARG_SIMPLE, 1 } } }, @@ -1494,9 +1494,9 @@ _PyOpcode_macro_expansion[256] = { [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, OPARG_SIMPLE, 0 } } }, [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, OPARG_SIMPLE, 0 } } }, [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, OPARG_SIMPLE, 0 } } }, - [RETURN_GENERATOR] = { .nuops = 2, .uops = { { _RECORD_CALLER_CODE, OPARG_SIMPLE, 0 }, { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } }, - [RETURN_VALUE] = { .nuops = 2, .uops = { { _RECORD_CALLER_CODE, OPARG_SIMPLE, 0 }, { _RETURN_VALUE, OPARG_SIMPLE, 0 } } }, - [SEND_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, + [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } }, + [RETURN_VALUE] = { .nuops = 1, .uops = { { _RETURN_VALUE, OPARG_SIMPLE, 0 } } }, + [SEND_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS_GEN_FUNC, OPARG_SIMPLE, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, OPARG_SIMPLE, 0 } } }, [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, OPARG_SIMPLE, 0 } } }, [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, OPARG_SIMPLE, 0 } } }, @@ -1532,7 +1532,7 @@ _PyOpcode_macro_expansion[256] = { [UNPACK_SEQUENCE_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TUPLE, OPARG_SIMPLE, 1 } } }, [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TWO_TUPLE, OPARG_SIMPLE, 1 } } }, [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, OPARG_SIMPLE, 0 } } }, - [YIELD_VALUE] = { .nuops = 2, .uops = { { _RECORD_CALLER_CODE, OPARG_SIMPLE, 0 }, { _YIELD_VALUE, OPARG_SIMPLE, 0 } } }, + [YIELD_VALUE] = { .nuops = 1, .uops = { { _YIELD_VALUE, OPARG_SIMPLE, 0 } } }, }; #endif // NEED_OPCODE_METADATA diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index bb2028c59356b2..79a2d60eb788ea 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -298,6 +298,11 @@ extern JitOptRef _Py_uop_sym_new_compact_int(JitOptContext *ctx); extern void _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef sym); extern JitOptRef _Py_uop_sym_new_predicate(JitOptContext *ctx, JitOptRef lhs_ref, JitOptRef rhs_ref, JitOptPredicateKind kind); extern void _Py_uop_sym_apply_predicate_narrowing(JitOptContext *ctx, JitOptRef sym, bool branch_is_true); +extern void _Py_uop_sym_set_recorded_value(JitOptContext *ctx, JitOptRef sym, PyObject *value); +extern void _Py_uop_sym_set_recorded_type(JitOptContext *ctx, JitOptRef sym, PyTypeObject *type); +extern void _Py_uop_sym_set_recorded_gen_func(JitOptContext *ctx, JitOptRef ref, PyFunctionObject *value); +extern PyCodeObject *_Py_uop_sym_get_probable_func_code(JitOptRef sym); +extern PyObject *_Py_uop_sym_get_probable_value(JitOptRef sym); extern void _Py_uop_abstractcontext_init(JitOptContext *ctx); extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx); @@ -308,6 +313,14 @@ extern _Py_UOpsAbstractFrame *_Py_uop_frame_new( int curr_stackentries, JitOptRef *args, int arg_len); + +extern _Py_UOpsAbstractFrame *_Py_uop_frame_new_from_symbol( + JitOptContext *ctx, + JitOptRef callable, + int curr_stackentries, + JitOptRef *args, + int arg_len); + extern int _Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co, int curr_stackentries); PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored); @@ -341,6 +354,7 @@ _PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, int oparg, _PyExecutorObject *current_executor); PyAPI_FUNC(void) _PyJit_FinalizeTracing(PyThreadState *tstate, int err); +void _PyPrintExecutor(_PyExecutorObject *executor, const _PyUOpInstruction *marker); void _PyJit_TracerFree(_PyThreadStateImpl *_tstate); void _PyJit_Tracer_InvalidateDependency(PyThreadState *old_tstate, void *obj); diff --git a/Include/internal/pycore_optimizer_types.h b/Include/internal/pycore_optimizer_types.h index b4b93e8353812a..57c0c828c2aabd 100644 --- a/Include/internal/pycore_optimizer_types.h +++ b/Include/internal/pycore_optimizer_types.h @@ -41,6 +41,9 @@ typedef enum _JitSymType { JIT_SYM_TRUTHINESS_TAG = 9, JIT_SYM_COMPACT_INT = 10, JIT_SYM_PREDICATE_TAG = 11, + JIT_SYM_RECORDED_VALUE_TAG = 12, + JIT_SYM_RECORDED_TYPE_TAG = 13, + JIT_SYM_RECORDED_GEN_FUNC_TAG = 14, } JitSymType; typedef struct _jit_opt_known_class { @@ -87,6 +90,24 @@ typedef struct { uint16_t rhs; } JitOptPredicate; +typedef struct _jit_opt_recorded_value { + uint8_t tag; + bool known_type; + PyObject *value; +} JitOptRecordedValue; + +typedef struct _jit_opt_recorded_type { + uint8_t tag; + PyTypeObject *type; +} JitOptRecordedType; + +/* Represents a generator, but we record the + * function as the generator is emphemeral */ +typedef struct _jit_opt_recorded_gen_func { + uint8_t tag; + PyFunctionObject *func; +} JitOptRecordedGenFunc; + typedef struct { uint8_t tag; } JitOptCompactInt; @@ -100,6 +121,9 @@ typedef union _jit_opt_symbol { JitOptTruthiness truthiness; JitOptCompactInt compact; JitOptPredicate predicate; + JitOptRecordedValue recorded_value; + JitOptRecordedType recorded_type; + JitOptRecordedGenFunc recorded_gen_func; } JitOptSymbol; // This mimics the _PyStackRef API diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 850ae446dc7aca..f9313621756b45 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -147,57 +147,58 @@ extern "C" { #define _GUARD_CALLABLE_STR_1 402 #define _GUARD_CALLABLE_TUPLE_1 403 #define _GUARD_CALLABLE_TYPE_1 404 -#define _GUARD_DORV_NO_DICT 405 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 406 -#define _GUARD_GLOBALS_VERSION 407 -#define _GUARD_IP_RETURN_GENERATOR 408 -#define _GUARD_IP_RETURN_VALUE 409 -#define _GUARD_IP_YIELD_VALUE 410 -#define _GUARD_IP__PUSH_FRAME 411 -#define _GUARD_IS_FALSE_POP 412 -#define _GUARD_IS_NONE_POP 413 -#define _GUARD_IS_NOT_NONE_POP 414 -#define _GUARD_IS_TRUE_POP 415 -#define _GUARD_KEYS_VERSION 416 -#define _GUARD_NOS_COMPACT_ASCII 417 -#define _GUARD_NOS_DICT 418 -#define _GUARD_NOS_FLOAT 419 -#define _GUARD_NOS_INT 420 -#define _GUARD_NOS_LIST 421 -#define _GUARD_NOS_NOT_NULL 422 -#define _GUARD_NOS_NULL 423 -#define _GUARD_NOS_OVERFLOWED 424 -#define _GUARD_NOS_TUPLE 425 -#define _GUARD_NOS_UNICODE 426 -#define _GUARD_NOT_EXHAUSTED_LIST 427 -#define _GUARD_NOT_EXHAUSTED_RANGE 428 -#define _GUARD_NOT_EXHAUSTED_TUPLE 429 -#define _GUARD_THIRD_NULL 430 -#define _GUARD_TOS_ANY_SET 431 -#define _GUARD_TOS_DICT 432 -#define _GUARD_TOS_FLOAT 433 -#define _GUARD_TOS_INT 434 -#define _GUARD_TOS_LIST 435 -#define _GUARD_TOS_OVERFLOWED 436 -#define _GUARD_TOS_SLICE 437 -#define _GUARD_TOS_TUPLE 438 -#define _GUARD_TOS_UNICODE 439 -#define _GUARD_TYPE_VERSION 440 -#define _GUARD_TYPE_VERSION_AND_LOCK 441 -#define _HANDLE_PENDING_AND_DEOPT 442 +#define _GUARD_CODE 405 +#define _GUARD_DORV_NO_DICT 406 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 407 +#define _GUARD_GLOBALS_VERSION 408 +#define _GUARD_IP_RETURN_GENERATOR 409 +#define _GUARD_IP_RETURN_VALUE 410 +#define _GUARD_IP_YIELD_VALUE 411 +#define _GUARD_IP__PUSH_FRAME 412 +#define _GUARD_IS_FALSE_POP 413 +#define _GUARD_IS_NONE_POP 414 +#define _GUARD_IS_NOT_NONE_POP 415 +#define _GUARD_IS_TRUE_POP 416 +#define _GUARD_KEYS_VERSION 417 +#define _GUARD_NOS_COMPACT_ASCII 418 +#define _GUARD_NOS_DICT 419 +#define _GUARD_NOS_FLOAT 420 +#define _GUARD_NOS_INT 421 +#define _GUARD_NOS_LIST 422 +#define _GUARD_NOS_NOT_NULL 423 +#define _GUARD_NOS_NULL 424 +#define _GUARD_NOS_OVERFLOWED 425 +#define _GUARD_NOS_TUPLE 426 +#define _GUARD_NOS_UNICODE 427 +#define _GUARD_NOT_EXHAUSTED_LIST 428 +#define _GUARD_NOT_EXHAUSTED_RANGE 429 +#define _GUARD_NOT_EXHAUSTED_TUPLE 430 +#define _GUARD_THIRD_NULL 431 +#define _GUARD_TOS_ANY_SET 432 +#define _GUARD_TOS_DICT 433 +#define _GUARD_TOS_FLOAT 434 +#define _GUARD_TOS_INT 435 +#define _GUARD_TOS_LIST 436 +#define _GUARD_TOS_OVERFLOWED 437 +#define _GUARD_TOS_SLICE 438 +#define _GUARD_TOS_TUPLE 439 +#define _GUARD_TOS_UNICODE 440 +#define _GUARD_TYPE_VERSION 441 +#define _GUARD_TYPE_VERSION_AND_LOCK 442 +#define _HANDLE_PENDING_AND_DEOPT 443 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 443 -#define _INIT_CALL_PY_EXACT_ARGS 444 -#define _INIT_CALL_PY_EXACT_ARGS_0 445 -#define _INIT_CALL_PY_EXACT_ARGS_1 446 -#define _INIT_CALL_PY_EXACT_ARGS_2 447 -#define _INIT_CALL_PY_EXACT_ARGS_3 448 -#define _INIT_CALL_PY_EXACT_ARGS_4 449 -#define _INSERT_1_LOAD_CONST_INLINE 450 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW 451 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW 452 -#define _INSERT_NULL 453 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 444 +#define _INIT_CALL_PY_EXACT_ARGS 445 +#define _INIT_CALL_PY_EXACT_ARGS_0 446 +#define _INIT_CALL_PY_EXACT_ARGS_1 447 +#define _INIT_CALL_PY_EXACT_ARGS_2 448 +#define _INIT_CALL_PY_EXACT_ARGS_3 449 +#define _INIT_CALL_PY_EXACT_ARGS_4 450 +#define _INSERT_1_LOAD_CONST_INLINE 451 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW 452 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW 453 +#define _INSERT_NULL 454 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -207,133 +208,134 @@ extern "C" { #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE -#define _IS_NONE 454 -#define _IS_OP 455 -#define _ITER_CHECK_LIST 456 -#define _ITER_CHECK_RANGE 457 -#define _ITER_CHECK_TUPLE 458 -#define _ITER_JUMP_LIST 459 -#define _ITER_JUMP_RANGE 460 -#define _ITER_JUMP_TUPLE 461 -#define _ITER_NEXT_LIST 462 -#define _ITER_NEXT_LIST_TIER_TWO 463 -#define _ITER_NEXT_RANGE 464 -#define _ITER_NEXT_TUPLE 465 +#define _IS_NONE 455 +#define _IS_OP 456 +#define _ITER_CHECK_LIST 457 +#define _ITER_CHECK_RANGE 458 +#define _ITER_CHECK_TUPLE 459 +#define _ITER_JUMP_LIST 460 +#define _ITER_JUMP_RANGE 461 +#define _ITER_JUMP_TUPLE 462 +#define _ITER_NEXT_LIST 463 +#define _ITER_NEXT_LIST_TIER_TWO 464 +#define _ITER_NEXT_RANGE 465 +#define _ITER_NEXT_TUPLE 466 #define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT -#define _JUMP_TO_TOP 466 +#define _JUMP_TO_TOP 467 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 467 -#define _LOAD_ATTR_CLASS 468 +#define _LOAD_ATTR 468 +#define _LOAD_ATTR_CLASS 469 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 469 -#define _LOAD_ATTR_METHOD_LAZY_DICT 470 -#define _LOAD_ATTR_METHOD_NO_DICT 471 -#define _LOAD_ATTR_METHOD_WITH_VALUES 472 -#define _LOAD_ATTR_MODULE 473 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 474 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 475 -#define _LOAD_ATTR_PROPERTY_FRAME 476 -#define _LOAD_ATTR_SLOT 477 -#define _LOAD_ATTR_WITH_HINT 478 +#define _LOAD_ATTR_INSTANCE_VALUE 470 +#define _LOAD_ATTR_METHOD_LAZY_DICT 471 +#define _LOAD_ATTR_METHOD_NO_DICT 472 +#define _LOAD_ATTR_METHOD_WITH_VALUES 473 +#define _LOAD_ATTR_MODULE 474 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 475 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 476 +#define _LOAD_ATTR_PROPERTY_FRAME 477 +#define _LOAD_ATTR_SLOT 478 +#define _LOAD_ATTR_WITH_HINT 479 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 479 +#define _LOAD_BYTECODE 480 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 480 -#define _LOAD_CONST_INLINE_BORROW 481 -#define _LOAD_CONST_UNDER_INLINE 482 -#define _LOAD_CONST_UNDER_INLINE_BORROW 483 +#define _LOAD_CONST_INLINE 481 +#define _LOAD_CONST_INLINE_BORROW 482 +#define _LOAD_CONST_UNDER_INLINE 483 +#define _LOAD_CONST_UNDER_INLINE_BORROW 484 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 484 -#define _LOAD_FAST_0 485 -#define _LOAD_FAST_1 486 -#define _LOAD_FAST_2 487 -#define _LOAD_FAST_3 488 -#define _LOAD_FAST_4 489 -#define _LOAD_FAST_5 490 -#define _LOAD_FAST_6 491 -#define _LOAD_FAST_7 492 +#define _LOAD_FAST 485 +#define _LOAD_FAST_0 486 +#define _LOAD_FAST_1 487 +#define _LOAD_FAST_2 488 +#define _LOAD_FAST_3 489 +#define _LOAD_FAST_4 490 +#define _LOAD_FAST_5 491 +#define _LOAD_FAST_6 492 +#define _LOAD_FAST_7 493 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 493 -#define _LOAD_FAST_BORROW_0 494 -#define _LOAD_FAST_BORROW_1 495 -#define _LOAD_FAST_BORROW_2 496 -#define _LOAD_FAST_BORROW_3 497 -#define _LOAD_FAST_BORROW_4 498 -#define _LOAD_FAST_BORROW_5 499 -#define _LOAD_FAST_BORROW_6 500 -#define _LOAD_FAST_BORROW_7 501 +#define _LOAD_FAST_BORROW 494 +#define _LOAD_FAST_BORROW_0 495 +#define _LOAD_FAST_BORROW_1 496 +#define _LOAD_FAST_BORROW_2 497 +#define _LOAD_FAST_BORROW_3 498 +#define _LOAD_FAST_BORROW_4 499 +#define _LOAD_FAST_BORROW_5 500 +#define _LOAD_FAST_BORROW_6 501 +#define _LOAD_FAST_BORROW_7 502 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 502 -#define _LOAD_GLOBAL_BUILTINS 503 -#define _LOAD_GLOBAL_MODULE 504 +#define _LOAD_GLOBAL 503 +#define _LOAD_GLOBAL_BUILTINS 504 +#define _LOAD_GLOBAL_MODULE 505 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 505 -#define _LOAD_SMALL_INT_0 506 -#define _LOAD_SMALL_INT_1 507 -#define _LOAD_SMALL_INT_2 508 -#define _LOAD_SMALL_INT_3 509 -#define _LOAD_SPECIAL 510 +#define _LOAD_SMALL_INT 506 +#define _LOAD_SMALL_INT_0 507 +#define _LOAD_SMALL_INT_1 508 +#define _LOAD_SMALL_INT_2 509 +#define _LOAD_SMALL_INT_3 510 +#define _LOAD_SPECIAL 511 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 511 +#define _MAKE_CALLARGS_A_TUPLE 512 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 512 +#define _MAKE_WARM 513 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 513 -#define _MAYBE_EXPAND_METHOD_KW 514 -#define _MONITOR_CALL 515 -#define _MONITOR_CALL_KW 516 -#define _MONITOR_JUMP_BACKWARD 517 -#define _MONITOR_RESUME 518 +#define _MAYBE_EXPAND_METHOD 514 +#define _MAYBE_EXPAND_METHOD_KW 515 +#define _MONITOR_CALL 516 +#define _MONITOR_CALL_KW 517 +#define _MONITOR_JUMP_BACKWARD 518 +#define _MONITOR_RESUME 519 #define _NOP NOP -#define _POP_CALL 519 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 520 -#define _POP_CALL_ONE 521 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 522 -#define _POP_CALL_TWO 523 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 524 +#define _POP_CALL 520 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 521 +#define _POP_CALL_ONE 522 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 523 +#define _POP_CALL_TWO 524 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 525 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 525 -#define _POP_JUMP_IF_TRUE 526 +#define _POP_JUMP_IF_FALSE 526 +#define _POP_JUMP_IF_TRUE 527 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 527 -#define _POP_TOP_INT 528 -#define _POP_TOP_LOAD_CONST_INLINE 529 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 530 -#define _POP_TOP_NOP 531 -#define _POP_TOP_UNICODE 532 -#define _POP_TWO 533 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 534 +#define _POP_TOP_FLOAT 528 +#define _POP_TOP_INT 529 +#define _POP_TOP_LOAD_CONST_INLINE 530 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 531 +#define _POP_TOP_NOP 532 +#define _POP_TOP_UNICODE 533 +#define _POP_TWO 534 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 535 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 535 +#define _PUSH_FRAME 536 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 536 -#define _PY_FRAME_EX 537 -#define _PY_FRAME_GENERAL 538 -#define _PY_FRAME_KW 539 -#define _QUICKEN_RESUME 540 -#define _RECORD_4OS 541 -#define _RECORD_BOUND_METHOD 542 -#define _RECORD_CALLABLE 543 -#define _RECORD_CALLER_CODE 544 -#define _RECORD_NOS 545 -#define _RECORD_TOS 546 -#define _RECORD_TOS_TYPE 547 -#define _REPLACE_WITH_TRUE 548 +#define _PUSH_NULL_CONDITIONAL 537 +#define _PY_FRAME_EX 538 +#define _PY_FRAME_GENERAL 539 +#define _PY_FRAME_KW 540 +#define _QUICKEN_RESUME 541 +#define _RECORD_4OS 542 +#define _RECORD_BOUND_METHOD 543 +#define _RECORD_CALLABLE 544 +#define _RECORD_CODE 545 +#define _RECORD_NOS 546 +#define _RECORD_NOS_GEN_FUNC 547 +#define _RECORD_TOS 548 +#define _RECORD_TOS_TYPE 549 +#define _REPLACE_WITH_TRUE 550 #define _RESUME_CHECK RESUME_CHECK -#define _RETURN_GENERATOR 549 -#define _RETURN_VALUE 550 +#define _RETURN_GENERATOR RETURN_GENERATOR +#define _RETURN_VALUE RETURN_VALUE #define _SAVE_RETURN_OFFSET 551 #define _SEND 552 #define _SEND_GEN_FRAME 553 @@ -385,867 +387,871 @@ extern "C" { #define _UNPACK_SEQUENCE_TUPLE 587 #define _UNPACK_SEQUENCE_TWO_TUPLE 588 #define _WITH_EXCEPT_START WITH_EXCEPT_START -#define _YIELD_VALUE 589 -#define MAX_UOP_ID 589 -#define _BINARY_OP_r23 590 -#define _BINARY_OP_ADD_FLOAT_r03 591 -#define _BINARY_OP_ADD_FLOAT_r13 592 -#define _BINARY_OP_ADD_FLOAT_r23 593 -#define _BINARY_OP_ADD_INT_r03 594 -#define _BINARY_OP_ADD_INT_r13 595 -#define _BINARY_OP_ADD_INT_r23 596 -#define _BINARY_OP_ADD_UNICODE_r03 597 -#define _BINARY_OP_ADD_UNICODE_r13 598 -#define _BINARY_OP_ADD_UNICODE_r23 599 -#define _BINARY_OP_EXTEND_r23 600 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 601 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 602 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 603 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 604 -#define _BINARY_OP_MULTIPLY_INT_r03 605 -#define _BINARY_OP_MULTIPLY_INT_r13 606 -#define _BINARY_OP_MULTIPLY_INT_r23 607 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 608 -#define _BINARY_OP_SUBSCR_DICT_r23 609 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 610 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 611 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 612 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 613 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 614 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 615 -#define _BINARY_OP_SUBSCR_STR_INT_r23 616 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 617 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 618 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 619 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 620 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 621 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 622 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 623 -#define _BINARY_OP_SUBTRACT_INT_r03 624 -#define _BINARY_OP_SUBTRACT_INT_r13 625 -#define _BINARY_OP_SUBTRACT_INT_r23 626 -#define _BINARY_SLICE_r31 627 -#define _BUILD_INTERPOLATION_r01 628 -#define _BUILD_LIST_r01 629 -#define _BUILD_MAP_r01 630 -#define _BUILD_SET_r01 631 -#define _BUILD_SLICE_r01 632 -#define _BUILD_STRING_r01 633 -#define _BUILD_TEMPLATE_r21 634 -#define _BUILD_TUPLE_r01 635 -#define _CALL_BUILTIN_CLASS_r01 636 -#define _CALL_BUILTIN_FAST_r01 637 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 638 -#define _CALL_BUILTIN_O_r03 639 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 640 -#define _CALL_INTRINSIC_1_r11 641 -#define _CALL_INTRINSIC_2_r21 642 -#define _CALL_ISINSTANCE_r31 643 -#define _CALL_KW_NON_PY_r11 644 -#define _CALL_LEN_r33 645 -#define _CALL_LIST_APPEND_r03 646 -#define _CALL_LIST_APPEND_r13 647 -#define _CALL_LIST_APPEND_r23 648 -#define _CALL_LIST_APPEND_r33 649 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 650 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 651 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 652 -#define _CALL_METHOD_DESCRIPTOR_O_r03 653 -#define _CALL_NON_PY_GENERAL_r01 654 -#define _CALL_STR_1_r32 655 -#define _CALL_TUPLE_1_r32 656 -#define _CALL_TYPE_1_r02 657 -#define _CALL_TYPE_1_r12 658 -#define _CALL_TYPE_1_r22 659 -#define _CALL_TYPE_1_r32 660 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 661 -#define _CHECK_ATTR_CLASS_r01 662 -#define _CHECK_ATTR_CLASS_r11 663 -#define _CHECK_ATTR_CLASS_r22 664 -#define _CHECK_ATTR_CLASS_r33 665 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 666 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 667 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 668 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 669 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 670 -#define _CHECK_EG_MATCH_r22 671 -#define _CHECK_EXC_MATCH_r22 672 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 673 -#define _CHECK_FUNCTION_VERSION_r00 674 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 675 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 676 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 677 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 678 -#define _CHECK_FUNCTION_VERSION_KW_r11 679 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 680 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 681 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 682 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 683 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 684 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 685 -#define _CHECK_IS_PY_CALLABLE_EX_r03 686 -#define _CHECK_IS_PY_CALLABLE_EX_r13 687 -#define _CHECK_IS_PY_CALLABLE_EX_r23 688 -#define _CHECK_IS_PY_CALLABLE_EX_r33 689 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 690 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 691 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 692 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 693 -#define _CHECK_METHOD_VERSION_r00 694 -#define _CHECK_METHOD_VERSION_KW_r11 695 -#define _CHECK_PEP_523_r00 696 -#define _CHECK_PEP_523_r11 697 -#define _CHECK_PEP_523_r22 698 -#define _CHECK_PEP_523_r33 699 -#define _CHECK_PERIODIC_r00 700 -#define _CHECK_PERIODIC_AT_END_r00 701 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 702 -#define _CHECK_RECURSION_REMAINING_r00 703 -#define _CHECK_RECURSION_REMAINING_r11 704 -#define _CHECK_RECURSION_REMAINING_r22 705 -#define _CHECK_RECURSION_REMAINING_r33 706 -#define _CHECK_STACK_SPACE_r00 707 -#define _CHECK_STACK_SPACE_OPERAND_r00 708 -#define _CHECK_STACK_SPACE_OPERAND_r11 709 -#define _CHECK_STACK_SPACE_OPERAND_r22 710 -#define _CHECK_STACK_SPACE_OPERAND_r33 711 -#define _CHECK_VALIDITY_r00 712 -#define _CHECK_VALIDITY_r11 713 -#define _CHECK_VALIDITY_r22 714 -#define _CHECK_VALIDITY_r33 715 -#define _COLD_DYNAMIC_EXIT_r00 716 -#define _COLD_EXIT_r00 717 -#define _COMPARE_OP_r21 718 -#define _COMPARE_OP_FLOAT_r03 719 -#define _COMPARE_OP_FLOAT_r13 720 -#define _COMPARE_OP_FLOAT_r23 721 -#define _COMPARE_OP_INT_r23 722 -#define _COMPARE_OP_STR_r23 723 -#define _CONTAINS_OP_r23 724 -#define _CONTAINS_OP_DICT_r23 725 -#define _CONTAINS_OP_SET_r23 726 -#define _CONVERT_VALUE_r11 727 -#define _COPY_r01 728 -#define _COPY_1_r02 729 -#define _COPY_1_r12 730 -#define _COPY_1_r23 731 -#define _COPY_2_r03 732 -#define _COPY_2_r13 733 -#define _COPY_2_r23 734 -#define _COPY_3_r03 735 -#define _COPY_3_r13 736 -#define _COPY_3_r23 737 -#define _COPY_3_r33 738 -#define _COPY_FREE_VARS_r00 739 -#define _COPY_FREE_VARS_r11 740 -#define _COPY_FREE_VARS_r22 741 -#define _COPY_FREE_VARS_r33 742 -#define _CREATE_INIT_FRAME_r01 743 -#define _DELETE_ATTR_r10 744 -#define _DELETE_DEREF_r00 745 -#define _DELETE_FAST_r00 746 -#define _DELETE_GLOBAL_r00 747 -#define _DELETE_NAME_r00 748 -#define _DELETE_SUBSCR_r20 749 -#define _DEOPT_r00 750 -#define _DEOPT_r10 751 -#define _DEOPT_r20 752 -#define _DEOPT_r30 753 -#define _DICT_MERGE_r10 754 -#define _DICT_UPDATE_r10 755 -#define _DO_CALL_r01 756 -#define _DO_CALL_FUNCTION_EX_r31 757 -#define _DO_CALL_KW_r11 758 -#define _DYNAMIC_EXIT_r00 759 -#define _DYNAMIC_EXIT_r10 760 -#define _DYNAMIC_EXIT_r20 761 -#define _DYNAMIC_EXIT_r30 762 -#define _END_FOR_r10 763 -#define _END_SEND_r21 764 -#define _ERROR_POP_N_r00 765 -#define _EXIT_INIT_CHECK_r10 766 -#define _EXIT_TRACE_r00 767 -#define _EXIT_TRACE_r10 768 -#define _EXIT_TRACE_r20 769 -#define _EXIT_TRACE_r30 770 -#define _EXPAND_METHOD_r00 771 -#define _EXPAND_METHOD_KW_r11 772 -#define _FATAL_ERROR_r00 773 -#define _FATAL_ERROR_r11 774 -#define _FATAL_ERROR_r22 775 -#define _FATAL_ERROR_r33 776 -#define _FORMAT_SIMPLE_r11 777 -#define _FORMAT_WITH_SPEC_r21 778 -#define _FOR_ITER_r23 779 -#define _FOR_ITER_GEN_FRAME_r03 780 -#define _FOR_ITER_GEN_FRAME_r13 781 -#define _FOR_ITER_GEN_FRAME_r23 782 -#define _FOR_ITER_TIER_TWO_r23 783 -#define _GET_AITER_r11 784 -#define _GET_ANEXT_r12 785 -#define _GET_AWAITABLE_r11 786 -#define _GET_ITER_r12 787 -#define _GET_LEN_r12 788 -#define _GET_YIELD_FROM_ITER_r11 789 -#define _GUARD_BINARY_OP_EXTEND_r22 790 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 791 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 792 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 793 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 794 -#define _GUARD_BIT_IS_SET_POP_r00 795 -#define _GUARD_BIT_IS_SET_POP_r10 796 -#define _GUARD_BIT_IS_SET_POP_r21 797 -#define _GUARD_BIT_IS_SET_POP_r32 798 -#define _GUARD_BIT_IS_SET_POP_4_r00 799 -#define _GUARD_BIT_IS_SET_POP_4_r10 800 -#define _GUARD_BIT_IS_SET_POP_4_r21 801 -#define _GUARD_BIT_IS_SET_POP_4_r32 802 -#define _GUARD_BIT_IS_SET_POP_5_r00 803 -#define _GUARD_BIT_IS_SET_POP_5_r10 804 -#define _GUARD_BIT_IS_SET_POP_5_r21 805 -#define _GUARD_BIT_IS_SET_POP_5_r32 806 -#define _GUARD_BIT_IS_SET_POP_6_r00 807 -#define _GUARD_BIT_IS_SET_POP_6_r10 808 -#define _GUARD_BIT_IS_SET_POP_6_r21 809 -#define _GUARD_BIT_IS_SET_POP_6_r32 810 -#define _GUARD_BIT_IS_SET_POP_7_r00 811 -#define _GUARD_BIT_IS_SET_POP_7_r10 812 -#define _GUARD_BIT_IS_SET_POP_7_r21 813 -#define _GUARD_BIT_IS_SET_POP_7_r32 814 -#define _GUARD_BIT_IS_UNSET_POP_r00 815 -#define _GUARD_BIT_IS_UNSET_POP_r10 816 -#define _GUARD_BIT_IS_UNSET_POP_r21 817 -#define _GUARD_BIT_IS_UNSET_POP_r32 818 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 819 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 820 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 821 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 822 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 823 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 824 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 825 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 826 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 827 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 828 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 829 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 830 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 831 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 832 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 833 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 834 -#define _GUARD_CALLABLE_ISINSTANCE_r03 835 -#define _GUARD_CALLABLE_ISINSTANCE_r13 836 -#define _GUARD_CALLABLE_ISINSTANCE_r23 837 -#define _GUARD_CALLABLE_ISINSTANCE_r33 838 -#define _GUARD_CALLABLE_LEN_r03 839 -#define _GUARD_CALLABLE_LEN_r13 840 -#define _GUARD_CALLABLE_LEN_r23 841 -#define _GUARD_CALLABLE_LEN_r33 842 -#define _GUARD_CALLABLE_LIST_APPEND_r03 843 -#define _GUARD_CALLABLE_LIST_APPEND_r13 844 -#define _GUARD_CALLABLE_LIST_APPEND_r23 845 -#define _GUARD_CALLABLE_LIST_APPEND_r33 846 -#define _GUARD_CALLABLE_STR_1_r03 847 -#define _GUARD_CALLABLE_STR_1_r13 848 -#define _GUARD_CALLABLE_STR_1_r23 849 -#define _GUARD_CALLABLE_STR_1_r33 850 -#define _GUARD_CALLABLE_TUPLE_1_r03 851 -#define _GUARD_CALLABLE_TUPLE_1_r13 852 -#define _GUARD_CALLABLE_TUPLE_1_r23 853 -#define _GUARD_CALLABLE_TUPLE_1_r33 854 -#define _GUARD_CALLABLE_TYPE_1_r03 855 -#define _GUARD_CALLABLE_TYPE_1_r13 856 -#define _GUARD_CALLABLE_TYPE_1_r23 857 -#define _GUARD_CALLABLE_TYPE_1_r33 858 -#define _GUARD_DORV_NO_DICT_r01 859 -#define _GUARD_DORV_NO_DICT_r11 860 -#define _GUARD_DORV_NO_DICT_r22 861 -#define _GUARD_DORV_NO_DICT_r33 862 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 863 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 864 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 865 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 866 -#define _GUARD_GLOBALS_VERSION_r00 867 -#define _GUARD_GLOBALS_VERSION_r11 868 -#define _GUARD_GLOBALS_VERSION_r22 869 -#define _GUARD_GLOBALS_VERSION_r33 870 -#define _GUARD_IP_RETURN_GENERATOR_r00 871 -#define _GUARD_IP_RETURN_GENERATOR_r11 872 -#define _GUARD_IP_RETURN_GENERATOR_r22 873 -#define _GUARD_IP_RETURN_GENERATOR_r33 874 -#define _GUARD_IP_RETURN_VALUE_r00 875 -#define _GUARD_IP_RETURN_VALUE_r11 876 -#define _GUARD_IP_RETURN_VALUE_r22 877 -#define _GUARD_IP_RETURN_VALUE_r33 878 -#define _GUARD_IP_YIELD_VALUE_r00 879 -#define _GUARD_IP_YIELD_VALUE_r11 880 -#define _GUARD_IP_YIELD_VALUE_r22 881 -#define _GUARD_IP_YIELD_VALUE_r33 882 -#define _GUARD_IP__PUSH_FRAME_r00 883 -#define _GUARD_IP__PUSH_FRAME_r11 884 -#define _GUARD_IP__PUSH_FRAME_r22 885 -#define _GUARD_IP__PUSH_FRAME_r33 886 -#define _GUARD_IS_FALSE_POP_r00 887 -#define _GUARD_IS_FALSE_POP_r10 888 -#define _GUARD_IS_FALSE_POP_r21 889 -#define _GUARD_IS_FALSE_POP_r32 890 -#define _GUARD_IS_NONE_POP_r00 891 -#define _GUARD_IS_NONE_POP_r10 892 -#define _GUARD_IS_NONE_POP_r21 893 -#define _GUARD_IS_NONE_POP_r32 894 -#define _GUARD_IS_NOT_NONE_POP_r10 895 -#define _GUARD_IS_TRUE_POP_r00 896 -#define _GUARD_IS_TRUE_POP_r10 897 -#define _GUARD_IS_TRUE_POP_r21 898 -#define _GUARD_IS_TRUE_POP_r32 899 -#define _GUARD_KEYS_VERSION_r01 900 -#define _GUARD_KEYS_VERSION_r11 901 -#define _GUARD_KEYS_VERSION_r22 902 -#define _GUARD_KEYS_VERSION_r33 903 -#define _GUARD_NOS_COMPACT_ASCII_r02 904 -#define _GUARD_NOS_COMPACT_ASCII_r12 905 -#define _GUARD_NOS_COMPACT_ASCII_r22 906 -#define _GUARD_NOS_COMPACT_ASCII_r33 907 -#define _GUARD_NOS_DICT_r02 908 -#define _GUARD_NOS_DICT_r12 909 -#define _GUARD_NOS_DICT_r22 910 -#define _GUARD_NOS_DICT_r33 911 -#define _GUARD_NOS_FLOAT_r02 912 -#define _GUARD_NOS_FLOAT_r12 913 -#define _GUARD_NOS_FLOAT_r22 914 -#define _GUARD_NOS_FLOAT_r33 915 -#define _GUARD_NOS_INT_r02 916 -#define _GUARD_NOS_INT_r12 917 -#define _GUARD_NOS_INT_r22 918 -#define _GUARD_NOS_INT_r33 919 -#define _GUARD_NOS_LIST_r02 920 -#define _GUARD_NOS_LIST_r12 921 -#define _GUARD_NOS_LIST_r22 922 -#define _GUARD_NOS_LIST_r33 923 -#define _GUARD_NOS_NOT_NULL_r02 924 -#define _GUARD_NOS_NOT_NULL_r12 925 -#define _GUARD_NOS_NOT_NULL_r22 926 -#define _GUARD_NOS_NOT_NULL_r33 927 -#define _GUARD_NOS_NULL_r02 928 -#define _GUARD_NOS_NULL_r12 929 -#define _GUARD_NOS_NULL_r22 930 -#define _GUARD_NOS_NULL_r33 931 -#define _GUARD_NOS_OVERFLOWED_r02 932 -#define _GUARD_NOS_OVERFLOWED_r12 933 -#define _GUARD_NOS_OVERFLOWED_r22 934 -#define _GUARD_NOS_OVERFLOWED_r33 935 -#define _GUARD_NOS_TUPLE_r02 936 -#define _GUARD_NOS_TUPLE_r12 937 -#define _GUARD_NOS_TUPLE_r22 938 -#define _GUARD_NOS_TUPLE_r33 939 -#define _GUARD_NOS_UNICODE_r02 940 -#define _GUARD_NOS_UNICODE_r12 941 -#define _GUARD_NOS_UNICODE_r22 942 -#define _GUARD_NOS_UNICODE_r33 943 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 944 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 945 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 946 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 947 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 948 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 949 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 950 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 951 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 952 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 953 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 954 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 955 -#define _GUARD_THIRD_NULL_r03 956 -#define _GUARD_THIRD_NULL_r13 957 -#define _GUARD_THIRD_NULL_r23 958 -#define _GUARD_THIRD_NULL_r33 959 -#define _GUARD_TOS_ANY_SET_r01 960 -#define _GUARD_TOS_ANY_SET_r11 961 -#define _GUARD_TOS_ANY_SET_r22 962 -#define _GUARD_TOS_ANY_SET_r33 963 -#define _GUARD_TOS_DICT_r01 964 -#define _GUARD_TOS_DICT_r11 965 -#define _GUARD_TOS_DICT_r22 966 -#define _GUARD_TOS_DICT_r33 967 -#define _GUARD_TOS_FLOAT_r01 968 -#define _GUARD_TOS_FLOAT_r11 969 -#define _GUARD_TOS_FLOAT_r22 970 -#define _GUARD_TOS_FLOAT_r33 971 -#define _GUARD_TOS_INT_r01 972 -#define _GUARD_TOS_INT_r11 973 -#define _GUARD_TOS_INT_r22 974 -#define _GUARD_TOS_INT_r33 975 -#define _GUARD_TOS_LIST_r01 976 -#define _GUARD_TOS_LIST_r11 977 -#define _GUARD_TOS_LIST_r22 978 -#define _GUARD_TOS_LIST_r33 979 -#define _GUARD_TOS_OVERFLOWED_r01 980 -#define _GUARD_TOS_OVERFLOWED_r11 981 -#define _GUARD_TOS_OVERFLOWED_r22 982 -#define _GUARD_TOS_OVERFLOWED_r33 983 -#define _GUARD_TOS_SLICE_r01 984 -#define _GUARD_TOS_SLICE_r11 985 -#define _GUARD_TOS_SLICE_r22 986 -#define _GUARD_TOS_SLICE_r33 987 -#define _GUARD_TOS_TUPLE_r01 988 -#define _GUARD_TOS_TUPLE_r11 989 -#define _GUARD_TOS_TUPLE_r22 990 -#define _GUARD_TOS_TUPLE_r33 991 -#define _GUARD_TOS_UNICODE_r01 992 -#define _GUARD_TOS_UNICODE_r11 993 -#define _GUARD_TOS_UNICODE_r22 994 -#define _GUARD_TOS_UNICODE_r33 995 -#define _GUARD_TYPE_VERSION_r01 996 -#define _GUARD_TYPE_VERSION_r11 997 -#define _GUARD_TYPE_VERSION_r22 998 -#define _GUARD_TYPE_VERSION_r33 999 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1000 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1001 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1002 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1003 -#define _HANDLE_PENDING_AND_DEOPT_r00 1004 -#define _HANDLE_PENDING_AND_DEOPT_r10 1005 -#define _HANDLE_PENDING_AND_DEOPT_r20 1006 -#define _HANDLE_PENDING_AND_DEOPT_r30 1007 -#define _IMPORT_FROM_r12 1008 -#define _IMPORT_NAME_r21 1009 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1010 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1011 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1012 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1013 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1014 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1015 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1016 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1017 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1018 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1019 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1020 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1021 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1022 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1023 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1024 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1025 -#define _INSERT_NULL_r10 1026 -#define _INSTRUMENTED_FOR_ITER_r23 1027 -#define _INSTRUMENTED_INSTRUCTION_r00 1028 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1029 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1030 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1031 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1032 -#define _INSTRUMENTED_LINE_r00 1033 -#define _INSTRUMENTED_NOT_TAKEN_r00 1034 -#define _INSTRUMENTED_NOT_TAKEN_r11 1035 -#define _INSTRUMENTED_NOT_TAKEN_r22 1036 -#define _INSTRUMENTED_NOT_TAKEN_r33 1037 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1038 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1039 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1040 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1041 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1042 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1043 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1044 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1045 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1046 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1047 -#define _IS_NONE_r11 1048 -#define _IS_OP_r03 1049 -#define _IS_OP_r13 1050 -#define _IS_OP_r23 1051 -#define _ITER_CHECK_LIST_r02 1052 -#define _ITER_CHECK_LIST_r12 1053 -#define _ITER_CHECK_LIST_r22 1054 -#define _ITER_CHECK_LIST_r33 1055 -#define _ITER_CHECK_RANGE_r02 1056 -#define _ITER_CHECK_RANGE_r12 1057 -#define _ITER_CHECK_RANGE_r22 1058 -#define _ITER_CHECK_RANGE_r33 1059 -#define _ITER_CHECK_TUPLE_r02 1060 -#define _ITER_CHECK_TUPLE_r12 1061 -#define _ITER_CHECK_TUPLE_r22 1062 -#define _ITER_CHECK_TUPLE_r33 1063 -#define _ITER_JUMP_LIST_r02 1064 -#define _ITER_JUMP_LIST_r12 1065 -#define _ITER_JUMP_LIST_r22 1066 -#define _ITER_JUMP_LIST_r33 1067 -#define _ITER_JUMP_RANGE_r02 1068 -#define _ITER_JUMP_RANGE_r12 1069 -#define _ITER_JUMP_RANGE_r22 1070 -#define _ITER_JUMP_RANGE_r33 1071 -#define _ITER_JUMP_TUPLE_r02 1072 -#define _ITER_JUMP_TUPLE_r12 1073 -#define _ITER_JUMP_TUPLE_r22 1074 -#define _ITER_JUMP_TUPLE_r33 1075 -#define _ITER_NEXT_LIST_r23 1076 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1077 -#define _ITER_NEXT_RANGE_r03 1078 -#define _ITER_NEXT_RANGE_r13 1079 -#define _ITER_NEXT_RANGE_r23 1080 -#define _ITER_NEXT_TUPLE_r03 1081 -#define _ITER_NEXT_TUPLE_r13 1082 -#define _ITER_NEXT_TUPLE_r23 1083 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1084 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1085 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1086 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1087 -#define _JUMP_TO_TOP_r00 1088 -#define _LIST_APPEND_r10 1089 -#define _LIST_EXTEND_r10 1090 -#define _LOAD_ATTR_r10 1091 -#define _LOAD_ATTR_CLASS_r11 1092 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1093 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1094 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1095 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1096 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1097 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1098 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1099 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1100 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1101 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1102 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1103 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1104 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1105 -#define _LOAD_ATTR_MODULE_r12 1106 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1107 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1108 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1109 -#define _LOAD_ATTR_SLOT_r02 1110 -#define _LOAD_ATTR_SLOT_r12 1111 -#define _LOAD_ATTR_SLOT_r23 1112 -#define _LOAD_ATTR_WITH_HINT_r12 1113 -#define _LOAD_BUILD_CLASS_r01 1114 -#define _LOAD_BYTECODE_r00 1115 -#define _LOAD_COMMON_CONSTANT_r01 1116 -#define _LOAD_COMMON_CONSTANT_r12 1117 -#define _LOAD_COMMON_CONSTANT_r23 1118 -#define _LOAD_CONST_r01 1119 -#define _LOAD_CONST_r12 1120 -#define _LOAD_CONST_r23 1121 -#define _LOAD_CONST_INLINE_r01 1122 -#define _LOAD_CONST_INLINE_r12 1123 -#define _LOAD_CONST_INLINE_r23 1124 -#define _LOAD_CONST_INLINE_BORROW_r01 1125 -#define _LOAD_CONST_INLINE_BORROW_r12 1126 -#define _LOAD_CONST_INLINE_BORROW_r23 1127 -#define _LOAD_CONST_UNDER_INLINE_r02 1128 -#define _LOAD_CONST_UNDER_INLINE_r12 1129 -#define _LOAD_CONST_UNDER_INLINE_r23 1130 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1131 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1132 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1133 -#define _LOAD_DEREF_r01 1134 -#define _LOAD_FAST_r01 1135 -#define _LOAD_FAST_r12 1136 -#define _LOAD_FAST_r23 1137 -#define _LOAD_FAST_0_r01 1138 -#define _LOAD_FAST_0_r12 1139 -#define _LOAD_FAST_0_r23 1140 -#define _LOAD_FAST_1_r01 1141 -#define _LOAD_FAST_1_r12 1142 -#define _LOAD_FAST_1_r23 1143 -#define _LOAD_FAST_2_r01 1144 -#define _LOAD_FAST_2_r12 1145 -#define _LOAD_FAST_2_r23 1146 -#define _LOAD_FAST_3_r01 1147 -#define _LOAD_FAST_3_r12 1148 -#define _LOAD_FAST_3_r23 1149 -#define _LOAD_FAST_4_r01 1150 -#define _LOAD_FAST_4_r12 1151 -#define _LOAD_FAST_4_r23 1152 -#define _LOAD_FAST_5_r01 1153 -#define _LOAD_FAST_5_r12 1154 -#define _LOAD_FAST_5_r23 1155 -#define _LOAD_FAST_6_r01 1156 -#define _LOAD_FAST_6_r12 1157 -#define _LOAD_FAST_6_r23 1158 -#define _LOAD_FAST_7_r01 1159 -#define _LOAD_FAST_7_r12 1160 -#define _LOAD_FAST_7_r23 1161 -#define _LOAD_FAST_AND_CLEAR_r01 1162 -#define _LOAD_FAST_AND_CLEAR_r12 1163 -#define _LOAD_FAST_AND_CLEAR_r23 1164 -#define _LOAD_FAST_BORROW_r01 1165 -#define _LOAD_FAST_BORROW_r12 1166 -#define _LOAD_FAST_BORROW_r23 1167 -#define _LOAD_FAST_BORROW_0_r01 1168 -#define _LOAD_FAST_BORROW_0_r12 1169 -#define _LOAD_FAST_BORROW_0_r23 1170 -#define _LOAD_FAST_BORROW_1_r01 1171 -#define _LOAD_FAST_BORROW_1_r12 1172 -#define _LOAD_FAST_BORROW_1_r23 1173 -#define _LOAD_FAST_BORROW_2_r01 1174 -#define _LOAD_FAST_BORROW_2_r12 1175 -#define _LOAD_FAST_BORROW_2_r23 1176 -#define _LOAD_FAST_BORROW_3_r01 1177 -#define _LOAD_FAST_BORROW_3_r12 1178 -#define _LOAD_FAST_BORROW_3_r23 1179 -#define _LOAD_FAST_BORROW_4_r01 1180 -#define _LOAD_FAST_BORROW_4_r12 1181 -#define _LOAD_FAST_BORROW_4_r23 1182 -#define _LOAD_FAST_BORROW_5_r01 1183 -#define _LOAD_FAST_BORROW_5_r12 1184 -#define _LOAD_FAST_BORROW_5_r23 1185 -#define _LOAD_FAST_BORROW_6_r01 1186 -#define _LOAD_FAST_BORROW_6_r12 1187 -#define _LOAD_FAST_BORROW_6_r23 1188 -#define _LOAD_FAST_BORROW_7_r01 1189 -#define _LOAD_FAST_BORROW_7_r12 1190 -#define _LOAD_FAST_BORROW_7_r23 1191 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1192 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1193 -#define _LOAD_FAST_CHECK_r01 1194 -#define _LOAD_FAST_CHECK_r12 1195 -#define _LOAD_FAST_CHECK_r23 1196 -#define _LOAD_FAST_LOAD_FAST_r02 1197 -#define _LOAD_FAST_LOAD_FAST_r13 1198 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1199 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1200 -#define _LOAD_GLOBAL_r00 1201 -#define _LOAD_GLOBAL_BUILTINS_r01 1202 -#define _LOAD_GLOBAL_MODULE_r01 1203 -#define _LOAD_LOCALS_r01 1204 -#define _LOAD_LOCALS_r12 1205 -#define _LOAD_LOCALS_r23 1206 -#define _LOAD_NAME_r01 1207 -#define _LOAD_SMALL_INT_r01 1208 -#define _LOAD_SMALL_INT_r12 1209 -#define _LOAD_SMALL_INT_r23 1210 -#define _LOAD_SMALL_INT_0_r01 1211 -#define _LOAD_SMALL_INT_0_r12 1212 -#define _LOAD_SMALL_INT_0_r23 1213 -#define _LOAD_SMALL_INT_1_r01 1214 -#define _LOAD_SMALL_INT_1_r12 1215 -#define _LOAD_SMALL_INT_1_r23 1216 -#define _LOAD_SMALL_INT_2_r01 1217 -#define _LOAD_SMALL_INT_2_r12 1218 -#define _LOAD_SMALL_INT_2_r23 1219 -#define _LOAD_SMALL_INT_3_r01 1220 -#define _LOAD_SMALL_INT_3_r12 1221 -#define _LOAD_SMALL_INT_3_r23 1222 -#define _LOAD_SPECIAL_r00 1223 -#define _LOAD_SUPER_ATTR_ATTR_r31 1224 -#define _LOAD_SUPER_ATTR_METHOD_r32 1225 -#define _MAKE_CALLARGS_A_TUPLE_r33 1226 -#define _MAKE_CELL_r00 1227 -#define _MAKE_FUNCTION_r11 1228 -#define _MAKE_WARM_r00 1229 -#define _MAKE_WARM_r11 1230 -#define _MAKE_WARM_r22 1231 -#define _MAKE_WARM_r33 1232 -#define _MAP_ADD_r20 1233 -#define _MATCH_CLASS_r31 1234 -#define _MATCH_KEYS_r23 1235 -#define _MATCH_MAPPING_r02 1236 -#define _MATCH_MAPPING_r12 1237 -#define _MATCH_MAPPING_r23 1238 -#define _MATCH_SEQUENCE_r02 1239 -#define _MATCH_SEQUENCE_r12 1240 -#define _MATCH_SEQUENCE_r23 1241 -#define _MAYBE_EXPAND_METHOD_r00 1242 -#define _MAYBE_EXPAND_METHOD_KW_r11 1243 -#define _MONITOR_CALL_r00 1244 -#define _MONITOR_CALL_KW_r11 1245 -#define _MONITOR_JUMP_BACKWARD_r00 1246 -#define _MONITOR_JUMP_BACKWARD_r11 1247 -#define _MONITOR_JUMP_BACKWARD_r22 1248 -#define _MONITOR_JUMP_BACKWARD_r33 1249 -#define _MONITOR_RESUME_r00 1250 -#define _NOP_r00 1251 -#define _NOP_r11 1252 -#define _NOP_r22 1253 -#define _NOP_r33 1254 -#define _POP_CALL_r20 1255 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1256 -#define _POP_CALL_ONE_r30 1257 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1258 -#define _POP_CALL_TWO_r30 1259 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1260 -#define _POP_EXCEPT_r10 1261 -#define _POP_ITER_r20 1262 -#define _POP_JUMP_IF_FALSE_r00 1263 -#define _POP_JUMP_IF_FALSE_r10 1264 -#define _POP_JUMP_IF_FALSE_r21 1265 -#define _POP_JUMP_IF_FALSE_r32 1266 -#define _POP_JUMP_IF_TRUE_r00 1267 -#define _POP_JUMP_IF_TRUE_r10 1268 -#define _POP_JUMP_IF_TRUE_r21 1269 -#define _POP_JUMP_IF_TRUE_r32 1270 -#define _POP_TOP_r10 1271 -#define _POP_TOP_FLOAT_r00 1272 -#define _POP_TOP_FLOAT_r10 1273 -#define _POP_TOP_FLOAT_r21 1274 -#define _POP_TOP_FLOAT_r32 1275 -#define _POP_TOP_INT_r00 1276 -#define _POP_TOP_INT_r10 1277 -#define _POP_TOP_INT_r21 1278 -#define _POP_TOP_INT_r32 1279 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1280 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1281 -#define _POP_TOP_NOP_r00 1282 -#define _POP_TOP_NOP_r10 1283 -#define _POP_TOP_NOP_r21 1284 -#define _POP_TOP_NOP_r32 1285 -#define _POP_TOP_UNICODE_r00 1286 -#define _POP_TOP_UNICODE_r10 1287 -#define _POP_TOP_UNICODE_r21 1288 -#define _POP_TOP_UNICODE_r32 1289 -#define _POP_TWO_r20 1290 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1291 -#define _PUSH_EXC_INFO_r02 1292 -#define _PUSH_EXC_INFO_r12 1293 -#define _PUSH_EXC_INFO_r23 1294 -#define _PUSH_FRAME_r10 1295 -#define _PUSH_NULL_r01 1296 -#define _PUSH_NULL_r12 1297 -#define _PUSH_NULL_r23 1298 -#define _PUSH_NULL_CONDITIONAL_r00 1299 -#define _PY_FRAME_EX_r31 1300 -#define _PY_FRAME_GENERAL_r01 1301 -#define _PY_FRAME_KW_r11 1302 -#define _QUICKEN_RESUME_r00 1303 -#define _QUICKEN_RESUME_r11 1304 -#define _QUICKEN_RESUME_r22 1305 -#define _QUICKEN_RESUME_r33 1306 -#define _REPLACE_WITH_TRUE_r02 1307 -#define _REPLACE_WITH_TRUE_r12 1308 -#define _REPLACE_WITH_TRUE_r23 1309 -#define _RESUME_CHECK_r00 1310 -#define _RESUME_CHECK_r11 1311 -#define _RESUME_CHECK_r22 1312 -#define _RESUME_CHECK_r33 1313 -#define _RETURN_GENERATOR_r01 1314 -#define _RETURN_VALUE_r11 1315 -#define _SAVE_RETURN_OFFSET_r00 1316 -#define _SAVE_RETURN_OFFSET_r11 1317 -#define _SAVE_RETURN_OFFSET_r22 1318 -#define _SAVE_RETURN_OFFSET_r33 1319 -#define _SEND_r22 1320 -#define _SEND_GEN_FRAME_r22 1321 -#define _SETUP_ANNOTATIONS_r00 1322 -#define _SET_ADD_r10 1323 -#define _SET_FUNCTION_ATTRIBUTE_r01 1324 -#define _SET_FUNCTION_ATTRIBUTE_r11 1325 -#define _SET_FUNCTION_ATTRIBUTE_r21 1326 -#define _SET_FUNCTION_ATTRIBUTE_r32 1327 -#define _SET_IP_r00 1328 -#define _SET_IP_r11 1329 -#define _SET_IP_r22 1330 -#define _SET_IP_r33 1331 -#define _SET_UPDATE_r10 1332 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1333 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1334 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1335 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1336 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1337 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1338 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1339 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1340 -#define _SPILL_OR_RELOAD_r01 1341 -#define _SPILL_OR_RELOAD_r02 1342 -#define _SPILL_OR_RELOAD_r03 1343 -#define _SPILL_OR_RELOAD_r10 1344 -#define _SPILL_OR_RELOAD_r12 1345 -#define _SPILL_OR_RELOAD_r13 1346 -#define _SPILL_OR_RELOAD_r20 1347 -#define _SPILL_OR_RELOAD_r21 1348 -#define _SPILL_OR_RELOAD_r23 1349 -#define _SPILL_OR_RELOAD_r30 1350 -#define _SPILL_OR_RELOAD_r31 1351 -#define _SPILL_OR_RELOAD_r32 1352 -#define _START_EXECUTOR_r00 1353 -#define _STORE_ATTR_r20 1354 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1355 -#define _STORE_ATTR_SLOT_r21 1356 -#define _STORE_ATTR_WITH_HINT_r21 1357 -#define _STORE_DEREF_r10 1358 -#define _STORE_FAST_LOAD_FAST_r11 1359 -#define _STORE_FAST_STORE_FAST_r20 1360 -#define _STORE_GLOBAL_r10 1361 -#define _STORE_NAME_r10 1362 -#define _STORE_SLICE_r30 1363 -#define _STORE_SUBSCR_r30 1364 -#define _STORE_SUBSCR_DICT_r31 1365 -#define _STORE_SUBSCR_LIST_INT_r32 1366 -#define _SWAP_r11 1367 -#define _SWAP_2_r02 1368 -#define _SWAP_2_r12 1369 -#define _SWAP_2_r22 1370 -#define _SWAP_2_r33 1371 -#define _SWAP_3_r03 1372 -#define _SWAP_3_r13 1373 -#define _SWAP_3_r23 1374 -#define _SWAP_3_r33 1375 -#define _SWAP_FAST_r01 1376 -#define _SWAP_FAST_r11 1377 -#define _SWAP_FAST_r22 1378 -#define _SWAP_FAST_r33 1379 -#define _SWAP_FAST_0_r01 1380 -#define _SWAP_FAST_0_r11 1381 -#define _SWAP_FAST_0_r22 1382 -#define _SWAP_FAST_0_r33 1383 -#define _SWAP_FAST_1_r01 1384 -#define _SWAP_FAST_1_r11 1385 -#define _SWAP_FAST_1_r22 1386 -#define _SWAP_FAST_1_r33 1387 -#define _SWAP_FAST_2_r01 1388 -#define _SWAP_FAST_2_r11 1389 -#define _SWAP_FAST_2_r22 1390 -#define _SWAP_FAST_2_r33 1391 -#define _SWAP_FAST_3_r01 1392 -#define _SWAP_FAST_3_r11 1393 -#define _SWAP_FAST_3_r22 1394 -#define _SWAP_FAST_3_r33 1395 -#define _SWAP_FAST_4_r01 1396 -#define _SWAP_FAST_4_r11 1397 -#define _SWAP_FAST_4_r22 1398 -#define _SWAP_FAST_4_r33 1399 -#define _SWAP_FAST_5_r01 1400 -#define _SWAP_FAST_5_r11 1401 -#define _SWAP_FAST_5_r22 1402 -#define _SWAP_FAST_5_r33 1403 -#define _SWAP_FAST_6_r01 1404 -#define _SWAP_FAST_6_r11 1405 -#define _SWAP_FAST_6_r22 1406 -#define _SWAP_FAST_6_r33 1407 -#define _SWAP_FAST_7_r01 1408 -#define _SWAP_FAST_7_r11 1409 -#define _SWAP_FAST_7_r22 1410 -#define _SWAP_FAST_7_r33 1411 -#define _TIER2_RESUME_CHECK_r00 1412 -#define _TIER2_RESUME_CHECK_r11 1413 -#define _TIER2_RESUME_CHECK_r22 1414 -#define _TIER2_RESUME_CHECK_r33 1415 -#define _TO_BOOL_r11 1416 -#define _TO_BOOL_BOOL_r01 1417 -#define _TO_BOOL_BOOL_r11 1418 -#define _TO_BOOL_BOOL_r22 1419 -#define _TO_BOOL_BOOL_r33 1420 -#define _TO_BOOL_INT_r02 1421 -#define _TO_BOOL_INT_r12 1422 -#define _TO_BOOL_INT_r23 1423 -#define _TO_BOOL_LIST_r02 1424 -#define _TO_BOOL_LIST_r12 1425 -#define _TO_BOOL_LIST_r23 1426 -#define _TO_BOOL_NONE_r01 1427 -#define _TO_BOOL_NONE_r11 1428 -#define _TO_BOOL_NONE_r22 1429 -#define _TO_BOOL_NONE_r33 1430 -#define _TO_BOOL_STR_r02 1431 -#define _TO_BOOL_STR_r12 1432 -#define _TO_BOOL_STR_r23 1433 -#define _TRACE_RECORD_r00 1434 -#define _UNARY_INVERT_r12 1435 -#define _UNARY_NEGATIVE_r12 1436 -#define _UNARY_NOT_r01 1437 -#define _UNARY_NOT_r11 1438 -#define _UNARY_NOT_r22 1439 -#define _UNARY_NOT_r33 1440 -#define _UNPACK_EX_r10 1441 -#define _UNPACK_SEQUENCE_r10 1442 -#define _UNPACK_SEQUENCE_LIST_r10 1443 -#define _UNPACK_SEQUENCE_TUPLE_r10 1444 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1445 -#define _WITH_EXCEPT_START_r33 1446 -#define _YIELD_VALUE_r11 1447 -#define MAX_UOP_REGS_ID 1447 +#define _YIELD_VALUE YIELD_VALUE +#define MAX_UOP_ID 588 +#define _BINARY_OP_r23 589 +#define _BINARY_OP_ADD_FLOAT_r03 590 +#define _BINARY_OP_ADD_FLOAT_r13 591 +#define _BINARY_OP_ADD_FLOAT_r23 592 +#define _BINARY_OP_ADD_INT_r03 593 +#define _BINARY_OP_ADD_INT_r13 594 +#define _BINARY_OP_ADD_INT_r23 595 +#define _BINARY_OP_ADD_UNICODE_r03 596 +#define _BINARY_OP_ADD_UNICODE_r13 597 +#define _BINARY_OP_ADD_UNICODE_r23 598 +#define _BINARY_OP_EXTEND_r23 599 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 600 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 601 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 602 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 603 +#define _BINARY_OP_MULTIPLY_INT_r03 604 +#define _BINARY_OP_MULTIPLY_INT_r13 605 +#define _BINARY_OP_MULTIPLY_INT_r23 606 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 607 +#define _BINARY_OP_SUBSCR_DICT_r23 608 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 609 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 610 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 611 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 612 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 613 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 614 +#define _BINARY_OP_SUBSCR_STR_INT_r23 615 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 616 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 617 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 618 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 619 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 620 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 621 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 622 +#define _BINARY_OP_SUBTRACT_INT_r03 623 +#define _BINARY_OP_SUBTRACT_INT_r13 624 +#define _BINARY_OP_SUBTRACT_INT_r23 625 +#define _BINARY_SLICE_r31 626 +#define _BUILD_INTERPOLATION_r01 627 +#define _BUILD_LIST_r01 628 +#define _BUILD_MAP_r01 629 +#define _BUILD_SET_r01 630 +#define _BUILD_SLICE_r01 631 +#define _BUILD_STRING_r01 632 +#define _BUILD_TEMPLATE_r21 633 +#define _BUILD_TUPLE_r01 634 +#define _CALL_BUILTIN_CLASS_r01 635 +#define _CALL_BUILTIN_FAST_r01 636 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 637 +#define _CALL_BUILTIN_O_r03 638 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 639 +#define _CALL_INTRINSIC_1_r11 640 +#define _CALL_INTRINSIC_2_r21 641 +#define _CALL_ISINSTANCE_r31 642 +#define _CALL_KW_NON_PY_r11 643 +#define _CALL_LEN_r33 644 +#define _CALL_LIST_APPEND_r03 645 +#define _CALL_LIST_APPEND_r13 646 +#define _CALL_LIST_APPEND_r23 647 +#define _CALL_LIST_APPEND_r33 648 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 649 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 650 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 651 +#define _CALL_METHOD_DESCRIPTOR_O_r03 652 +#define _CALL_NON_PY_GENERAL_r01 653 +#define _CALL_STR_1_r32 654 +#define _CALL_TUPLE_1_r32 655 +#define _CALL_TYPE_1_r02 656 +#define _CALL_TYPE_1_r12 657 +#define _CALL_TYPE_1_r22 658 +#define _CALL_TYPE_1_r32 659 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 660 +#define _CHECK_ATTR_CLASS_r01 661 +#define _CHECK_ATTR_CLASS_r11 662 +#define _CHECK_ATTR_CLASS_r22 663 +#define _CHECK_ATTR_CLASS_r33 664 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 665 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 666 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 667 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 668 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 669 +#define _CHECK_EG_MATCH_r22 670 +#define _CHECK_EXC_MATCH_r22 671 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 672 +#define _CHECK_FUNCTION_VERSION_r00 673 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 674 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 675 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 676 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 677 +#define _CHECK_FUNCTION_VERSION_KW_r11 678 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 679 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 680 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 681 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 682 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 683 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 684 +#define _CHECK_IS_PY_CALLABLE_EX_r03 685 +#define _CHECK_IS_PY_CALLABLE_EX_r13 686 +#define _CHECK_IS_PY_CALLABLE_EX_r23 687 +#define _CHECK_IS_PY_CALLABLE_EX_r33 688 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 689 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 690 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 691 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 692 +#define _CHECK_METHOD_VERSION_r00 693 +#define _CHECK_METHOD_VERSION_KW_r11 694 +#define _CHECK_PEP_523_r00 695 +#define _CHECK_PEP_523_r11 696 +#define _CHECK_PEP_523_r22 697 +#define _CHECK_PEP_523_r33 698 +#define _CHECK_PERIODIC_r00 699 +#define _CHECK_PERIODIC_AT_END_r00 700 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 701 +#define _CHECK_RECURSION_REMAINING_r00 702 +#define _CHECK_RECURSION_REMAINING_r11 703 +#define _CHECK_RECURSION_REMAINING_r22 704 +#define _CHECK_RECURSION_REMAINING_r33 705 +#define _CHECK_STACK_SPACE_r00 706 +#define _CHECK_STACK_SPACE_OPERAND_r00 707 +#define _CHECK_STACK_SPACE_OPERAND_r11 708 +#define _CHECK_STACK_SPACE_OPERAND_r22 709 +#define _CHECK_STACK_SPACE_OPERAND_r33 710 +#define _CHECK_VALIDITY_r00 711 +#define _CHECK_VALIDITY_r11 712 +#define _CHECK_VALIDITY_r22 713 +#define _CHECK_VALIDITY_r33 714 +#define _COLD_DYNAMIC_EXIT_r00 715 +#define _COLD_EXIT_r00 716 +#define _COMPARE_OP_r21 717 +#define _COMPARE_OP_FLOAT_r03 718 +#define _COMPARE_OP_FLOAT_r13 719 +#define _COMPARE_OP_FLOAT_r23 720 +#define _COMPARE_OP_INT_r23 721 +#define _COMPARE_OP_STR_r23 722 +#define _CONTAINS_OP_r23 723 +#define _CONTAINS_OP_DICT_r23 724 +#define _CONTAINS_OP_SET_r23 725 +#define _CONVERT_VALUE_r11 726 +#define _COPY_r01 727 +#define _COPY_1_r02 728 +#define _COPY_1_r12 729 +#define _COPY_1_r23 730 +#define _COPY_2_r03 731 +#define _COPY_2_r13 732 +#define _COPY_2_r23 733 +#define _COPY_3_r03 734 +#define _COPY_3_r13 735 +#define _COPY_3_r23 736 +#define _COPY_3_r33 737 +#define _COPY_FREE_VARS_r00 738 +#define _COPY_FREE_VARS_r11 739 +#define _COPY_FREE_VARS_r22 740 +#define _COPY_FREE_VARS_r33 741 +#define _CREATE_INIT_FRAME_r01 742 +#define _DELETE_ATTR_r10 743 +#define _DELETE_DEREF_r00 744 +#define _DELETE_FAST_r00 745 +#define _DELETE_GLOBAL_r00 746 +#define _DELETE_NAME_r00 747 +#define _DELETE_SUBSCR_r20 748 +#define _DEOPT_r00 749 +#define _DEOPT_r10 750 +#define _DEOPT_r20 751 +#define _DEOPT_r30 752 +#define _DICT_MERGE_r10 753 +#define _DICT_UPDATE_r10 754 +#define _DO_CALL_r01 755 +#define _DO_CALL_FUNCTION_EX_r31 756 +#define _DO_CALL_KW_r11 757 +#define _DYNAMIC_EXIT_r00 758 +#define _DYNAMIC_EXIT_r10 759 +#define _DYNAMIC_EXIT_r20 760 +#define _DYNAMIC_EXIT_r30 761 +#define _END_FOR_r10 762 +#define _END_SEND_r21 763 +#define _ERROR_POP_N_r00 764 +#define _EXIT_INIT_CHECK_r10 765 +#define _EXIT_TRACE_r00 766 +#define _EXIT_TRACE_r10 767 +#define _EXIT_TRACE_r20 768 +#define _EXIT_TRACE_r30 769 +#define _EXPAND_METHOD_r00 770 +#define _EXPAND_METHOD_KW_r11 771 +#define _FATAL_ERROR_r00 772 +#define _FATAL_ERROR_r11 773 +#define _FATAL_ERROR_r22 774 +#define _FATAL_ERROR_r33 775 +#define _FORMAT_SIMPLE_r11 776 +#define _FORMAT_WITH_SPEC_r21 777 +#define _FOR_ITER_r23 778 +#define _FOR_ITER_GEN_FRAME_r03 779 +#define _FOR_ITER_GEN_FRAME_r13 780 +#define _FOR_ITER_GEN_FRAME_r23 781 +#define _FOR_ITER_TIER_TWO_r23 782 +#define _GET_AITER_r11 783 +#define _GET_ANEXT_r12 784 +#define _GET_AWAITABLE_r11 785 +#define _GET_ITER_r12 786 +#define _GET_LEN_r12 787 +#define _GET_YIELD_FROM_ITER_r11 788 +#define _GUARD_BINARY_OP_EXTEND_r22 789 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 790 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 791 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 792 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 793 +#define _GUARD_BIT_IS_SET_POP_r00 794 +#define _GUARD_BIT_IS_SET_POP_r10 795 +#define _GUARD_BIT_IS_SET_POP_r21 796 +#define _GUARD_BIT_IS_SET_POP_r32 797 +#define _GUARD_BIT_IS_SET_POP_4_r00 798 +#define _GUARD_BIT_IS_SET_POP_4_r10 799 +#define _GUARD_BIT_IS_SET_POP_4_r21 800 +#define _GUARD_BIT_IS_SET_POP_4_r32 801 +#define _GUARD_BIT_IS_SET_POP_5_r00 802 +#define _GUARD_BIT_IS_SET_POP_5_r10 803 +#define _GUARD_BIT_IS_SET_POP_5_r21 804 +#define _GUARD_BIT_IS_SET_POP_5_r32 805 +#define _GUARD_BIT_IS_SET_POP_6_r00 806 +#define _GUARD_BIT_IS_SET_POP_6_r10 807 +#define _GUARD_BIT_IS_SET_POP_6_r21 808 +#define _GUARD_BIT_IS_SET_POP_6_r32 809 +#define _GUARD_BIT_IS_SET_POP_7_r00 810 +#define _GUARD_BIT_IS_SET_POP_7_r10 811 +#define _GUARD_BIT_IS_SET_POP_7_r21 812 +#define _GUARD_BIT_IS_SET_POP_7_r32 813 +#define _GUARD_BIT_IS_UNSET_POP_r00 814 +#define _GUARD_BIT_IS_UNSET_POP_r10 815 +#define _GUARD_BIT_IS_UNSET_POP_r21 816 +#define _GUARD_BIT_IS_UNSET_POP_r32 817 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 818 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 819 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 820 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 821 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 822 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 823 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 824 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 825 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 826 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 827 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 828 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 829 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 830 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 831 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 832 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 833 +#define _GUARD_CALLABLE_ISINSTANCE_r03 834 +#define _GUARD_CALLABLE_ISINSTANCE_r13 835 +#define _GUARD_CALLABLE_ISINSTANCE_r23 836 +#define _GUARD_CALLABLE_ISINSTANCE_r33 837 +#define _GUARD_CALLABLE_LEN_r03 838 +#define _GUARD_CALLABLE_LEN_r13 839 +#define _GUARD_CALLABLE_LEN_r23 840 +#define _GUARD_CALLABLE_LEN_r33 841 +#define _GUARD_CALLABLE_LIST_APPEND_r03 842 +#define _GUARD_CALLABLE_LIST_APPEND_r13 843 +#define _GUARD_CALLABLE_LIST_APPEND_r23 844 +#define _GUARD_CALLABLE_LIST_APPEND_r33 845 +#define _GUARD_CALLABLE_STR_1_r03 846 +#define _GUARD_CALLABLE_STR_1_r13 847 +#define _GUARD_CALLABLE_STR_1_r23 848 +#define _GUARD_CALLABLE_STR_1_r33 849 +#define _GUARD_CALLABLE_TUPLE_1_r03 850 +#define _GUARD_CALLABLE_TUPLE_1_r13 851 +#define _GUARD_CALLABLE_TUPLE_1_r23 852 +#define _GUARD_CALLABLE_TUPLE_1_r33 853 +#define _GUARD_CALLABLE_TYPE_1_r03 854 +#define _GUARD_CALLABLE_TYPE_1_r13 855 +#define _GUARD_CALLABLE_TYPE_1_r23 856 +#define _GUARD_CALLABLE_TYPE_1_r33 857 +#define _GUARD_CODE_r00 858 +#define _GUARD_CODE_r11 859 +#define _GUARD_CODE_r22 860 +#define _GUARD_CODE_r33 861 +#define _GUARD_DORV_NO_DICT_r01 862 +#define _GUARD_DORV_NO_DICT_r11 863 +#define _GUARD_DORV_NO_DICT_r22 864 +#define _GUARD_DORV_NO_DICT_r33 865 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 866 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 867 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 868 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 869 +#define _GUARD_GLOBALS_VERSION_r00 870 +#define _GUARD_GLOBALS_VERSION_r11 871 +#define _GUARD_GLOBALS_VERSION_r22 872 +#define _GUARD_GLOBALS_VERSION_r33 873 +#define _GUARD_IP_RETURN_GENERATOR_r00 874 +#define _GUARD_IP_RETURN_GENERATOR_r11 875 +#define _GUARD_IP_RETURN_GENERATOR_r22 876 +#define _GUARD_IP_RETURN_GENERATOR_r33 877 +#define _GUARD_IP_RETURN_VALUE_r00 878 +#define _GUARD_IP_RETURN_VALUE_r11 879 +#define _GUARD_IP_RETURN_VALUE_r22 880 +#define _GUARD_IP_RETURN_VALUE_r33 881 +#define _GUARD_IP_YIELD_VALUE_r00 882 +#define _GUARD_IP_YIELD_VALUE_r11 883 +#define _GUARD_IP_YIELD_VALUE_r22 884 +#define _GUARD_IP_YIELD_VALUE_r33 885 +#define _GUARD_IP__PUSH_FRAME_r00 886 +#define _GUARD_IP__PUSH_FRAME_r11 887 +#define _GUARD_IP__PUSH_FRAME_r22 888 +#define _GUARD_IP__PUSH_FRAME_r33 889 +#define _GUARD_IS_FALSE_POP_r00 890 +#define _GUARD_IS_FALSE_POP_r10 891 +#define _GUARD_IS_FALSE_POP_r21 892 +#define _GUARD_IS_FALSE_POP_r32 893 +#define _GUARD_IS_NONE_POP_r00 894 +#define _GUARD_IS_NONE_POP_r10 895 +#define _GUARD_IS_NONE_POP_r21 896 +#define _GUARD_IS_NONE_POP_r32 897 +#define _GUARD_IS_NOT_NONE_POP_r10 898 +#define _GUARD_IS_TRUE_POP_r00 899 +#define _GUARD_IS_TRUE_POP_r10 900 +#define _GUARD_IS_TRUE_POP_r21 901 +#define _GUARD_IS_TRUE_POP_r32 902 +#define _GUARD_KEYS_VERSION_r01 903 +#define _GUARD_KEYS_VERSION_r11 904 +#define _GUARD_KEYS_VERSION_r22 905 +#define _GUARD_KEYS_VERSION_r33 906 +#define _GUARD_NOS_COMPACT_ASCII_r02 907 +#define _GUARD_NOS_COMPACT_ASCII_r12 908 +#define _GUARD_NOS_COMPACT_ASCII_r22 909 +#define _GUARD_NOS_COMPACT_ASCII_r33 910 +#define _GUARD_NOS_DICT_r02 911 +#define _GUARD_NOS_DICT_r12 912 +#define _GUARD_NOS_DICT_r22 913 +#define _GUARD_NOS_DICT_r33 914 +#define _GUARD_NOS_FLOAT_r02 915 +#define _GUARD_NOS_FLOAT_r12 916 +#define _GUARD_NOS_FLOAT_r22 917 +#define _GUARD_NOS_FLOAT_r33 918 +#define _GUARD_NOS_INT_r02 919 +#define _GUARD_NOS_INT_r12 920 +#define _GUARD_NOS_INT_r22 921 +#define _GUARD_NOS_INT_r33 922 +#define _GUARD_NOS_LIST_r02 923 +#define _GUARD_NOS_LIST_r12 924 +#define _GUARD_NOS_LIST_r22 925 +#define _GUARD_NOS_LIST_r33 926 +#define _GUARD_NOS_NOT_NULL_r02 927 +#define _GUARD_NOS_NOT_NULL_r12 928 +#define _GUARD_NOS_NOT_NULL_r22 929 +#define _GUARD_NOS_NOT_NULL_r33 930 +#define _GUARD_NOS_NULL_r02 931 +#define _GUARD_NOS_NULL_r12 932 +#define _GUARD_NOS_NULL_r22 933 +#define _GUARD_NOS_NULL_r33 934 +#define _GUARD_NOS_OVERFLOWED_r02 935 +#define _GUARD_NOS_OVERFLOWED_r12 936 +#define _GUARD_NOS_OVERFLOWED_r22 937 +#define _GUARD_NOS_OVERFLOWED_r33 938 +#define _GUARD_NOS_TUPLE_r02 939 +#define _GUARD_NOS_TUPLE_r12 940 +#define _GUARD_NOS_TUPLE_r22 941 +#define _GUARD_NOS_TUPLE_r33 942 +#define _GUARD_NOS_UNICODE_r02 943 +#define _GUARD_NOS_UNICODE_r12 944 +#define _GUARD_NOS_UNICODE_r22 945 +#define _GUARD_NOS_UNICODE_r33 946 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 947 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 948 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 949 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 950 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 951 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 952 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 953 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 954 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 955 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 956 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 957 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 958 +#define _GUARD_THIRD_NULL_r03 959 +#define _GUARD_THIRD_NULL_r13 960 +#define _GUARD_THIRD_NULL_r23 961 +#define _GUARD_THIRD_NULL_r33 962 +#define _GUARD_TOS_ANY_SET_r01 963 +#define _GUARD_TOS_ANY_SET_r11 964 +#define _GUARD_TOS_ANY_SET_r22 965 +#define _GUARD_TOS_ANY_SET_r33 966 +#define _GUARD_TOS_DICT_r01 967 +#define _GUARD_TOS_DICT_r11 968 +#define _GUARD_TOS_DICT_r22 969 +#define _GUARD_TOS_DICT_r33 970 +#define _GUARD_TOS_FLOAT_r01 971 +#define _GUARD_TOS_FLOAT_r11 972 +#define _GUARD_TOS_FLOAT_r22 973 +#define _GUARD_TOS_FLOAT_r33 974 +#define _GUARD_TOS_INT_r01 975 +#define _GUARD_TOS_INT_r11 976 +#define _GUARD_TOS_INT_r22 977 +#define _GUARD_TOS_INT_r33 978 +#define _GUARD_TOS_LIST_r01 979 +#define _GUARD_TOS_LIST_r11 980 +#define _GUARD_TOS_LIST_r22 981 +#define _GUARD_TOS_LIST_r33 982 +#define _GUARD_TOS_OVERFLOWED_r01 983 +#define _GUARD_TOS_OVERFLOWED_r11 984 +#define _GUARD_TOS_OVERFLOWED_r22 985 +#define _GUARD_TOS_OVERFLOWED_r33 986 +#define _GUARD_TOS_SLICE_r01 987 +#define _GUARD_TOS_SLICE_r11 988 +#define _GUARD_TOS_SLICE_r22 989 +#define _GUARD_TOS_SLICE_r33 990 +#define _GUARD_TOS_TUPLE_r01 991 +#define _GUARD_TOS_TUPLE_r11 992 +#define _GUARD_TOS_TUPLE_r22 993 +#define _GUARD_TOS_TUPLE_r33 994 +#define _GUARD_TOS_UNICODE_r01 995 +#define _GUARD_TOS_UNICODE_r11 996 +#define _GUARD_TOS_UNICODE_r22 997 +#define _GUARD_TOS_UNICODE_r33 998 +#define _GUARD_TYPE_VERSION_r01 999 +#define _GUARD_TYPE_VERSION_r11 1000 +#define _GUARD_TYPE_VERSION_r22 1001 +#define _GUARD_TYPE_VERSION_r33 1002 +#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1003 +#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1004 +#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1005 +#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1006 +#define _HANDLE_PENDING_AND_DEOPT_r00 1007 +#define _HANDLE_PENDING_AND_DEOPT_r10 1008 +#define _HANDLE_PENDING_AND_DEOPT_r20 1009 +#define _HANDLE_PENDING_AND_DEOPT_r30 1010 +#define _IMPORT_FROM_r12 1011 +#define _IMPORT_NAME_r21 1012 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1013 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1014 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1015 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1016 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1017 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1018 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1019 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1020 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1021 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1022 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1023 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1024 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1025 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1026 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1027 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1028 +#define _INSERT_NULL_r10 1029 +#define _INSTRUMENTED_FOR_ITER_r23 1030 +#define _INSTRUMENTED_INSTRUCTION_r00 1031 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1032 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1033 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1034 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1035 +#define _INSTRUMENTED_LINE_r00 1036 +#define _INSTRUMENTED_NOT_TAKEN_r00 1037 +#define _INSTRUMENTED_NOT_TAKEN_r11 1038 +#define _INSTRUMENTED_NOT_TAKEN_r22 1039 +#define _INSTRUMENTED_NOT_TAKEN_r33 1040 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1041 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1042 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1043 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1044 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1045 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1046 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1047 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1048 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1049 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1050 +#define _IS_NONE_r11 1051 +#define _IS_OP_r03 1052 +#define _IS_OP_r13 1053 +#define _IS_OP_r23 1054 +#define _ITER_CHECK_LIST_r02 1055 +#define _ITER_CHECK_LIST_r12 1056 +#define _ITER_CHECK_LIST_r22 1057 +#define _ITER_CHECK_LIST_r33 1058 +#define _ITER_CHECK_RANGE_r02 1059 +#define _ITER_CHECK_RANGE_r12 1060 +#define _ITER_CHECK_RANGE_r22 1061 +#define _ITER_CHECK_RANGE_r33 1062 +#define _ITER_CHECK_TUPLE_r02 1063 +#define _ITER_CHECK_TUPLE_r12 1064 +#define _ITER_CHECK_TUPLE_r22 1065 +#define _ITER_CHECK_TUPLE_r33 1066 +#define _ITER_JUMP_LIST_r02 1067 +#define _ITER_JUMP_LIST_r12 1068 +#define _ITER_JUMP_LIST_r22 1069 +#define _ITER_JUMP_LIST_r33 1070 +#define _ITER_JUMP_RANGE_r02 1071 +#define _ITER_JUMP_RANGE_r12 1072 +#define _ITER_JUMP_RANGE_r22 1073 +#define _ITER_JUMP_RANGE_r33 1074 +#define _ITER_JUMP_TUPLE_r02 1075 +#define _ITER_JUMP_TUPLE_r12 1076 +#define _ITER_JUMP_TUPLE_r22 1077 +#define _ITER_JUMP_TUPLE_r33 1078 +#define _ITER_NEXT_LIST_r23 1079 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1080 +#define _ITER_NEXT_RANGE_r03 1081 +#define _ITER_NEXT_RANGE_r13 1082 +#define _ITER_NEXT_RANGE_r23 1083 +#define _ITER_NEXT_TUPLE_r03 1084 +#define _ITER_NEXT_TUPLE_r13 1085 +#define _ITER_NEXT_TUPLE_r23 1086 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1087 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1088 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1089 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1090 +#define _JUMP_TO_TOP_r00 1091 +#define _LIST_APPEND_r10 1092 +#define _LIST_EXTEND_r10 1093 +#define _LOAD_ATTR_r10 1094 +#define _LOAD_ATTR_CLASS_r11 1095 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1096 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1097 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1098 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1099 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1100 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1101 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1102 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1103 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1104 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1105 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1106 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1107 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1108 +#define _LOAD_ATTR_MODULE_r12 1109 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1110 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1111 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1112 +#define _LOAD_ATTR_SLOT_r02 1113 +#define _LOAD_ATTR_SLOT_r12 1114 +#define _LOAD_ATTR_SLOT_r23 1115 +#define _LOAD_ATTR_WITH_HINT_r12 1116 +#define _LOAD_BUILD_CLASS_r01 1117 +#define _LOAD_BYTECODE_r00 1118 +#define _LOAD_COMMON_CONSTANT_r01 1119 +#define _LOAD_COMMON_CONSTANT_r12 1120 +#define _LOAD_COMMON_CONSTANT_r23 1121 +#define _LOAD_CONST_r01 1122 +#define _LOAD_CONST_r12 1123 +#define _LOAD_CONST_r23 1124 +#define _LOAD_CONST_INLINE_r01 1125 +#define _LOAD_CONST_INLINE_r12 1126 +#define _LOAD_CONST_INLINE_r23 1127 +#define _LOAD_CONST_INLINE_BORROW_r01 1128 +#define _LOAD_CONST_INLINE_BORROW_r12 1129 +#define _LOAD_CONST_INLINE_BORROW_r23 1130 +#define _LOAD_CONST_UNDER_INLINE_r02 1131 +#define _LOAD_CONST_UNDER_INLINE_r12 1132 +#define _LOAD_CONST_UNDER_INLINE_r23 1133 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1134 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1135 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1136 +#define _LOAD_DEREF_r01 1137 +#define _LOAD_FAST_r01 1138 +#define _LOAD_FAST_r12 1139 +#define _LOAD_FAST_r23 1140 +#define _LOAD_FAST_0_r01 1141 +#define _LOAD_FAST_0_r12 1142 +#define _LOAD_FAST_0_r23 1143 +#define _LOAD_FAST_1_r01 1144 +#define _LOAD_FAST_1_r12 1145 +#define _LOAD_FAST_1_r23 1146 +#define _LOAD_FAST_2_r01 1147 +#define _LOAD_FAST_2_r12 1148 +#define _LOAD_FAST_2_r23 1149 +#define _LOAD_FAST_3_r01 1150 +#define _LOAD_FAST_3_r12 1151 +#define _LOAD_FAST_3_r23 1152 +#define _LOAD_FAST_4_r01 1153 +#define _LOAD_FAST_4_r12 1154 +#define _LOAD_FAST_4_r23 1155 +#define _LOAD_FAST_5_r01 1156 +#define _LOAD_FAST_5_r12 1157 +#define _LOAD_FAST_5_r23 1158 +#define _LOAD_FAST_6_r01 1159 +#define _LOAD_FAST_6_r12 1160 +#define _LOAD_FAST_6_r23 1161 +#define _LOAD_FAST_7_r01 1162 +#define _LOAD_FAST_7_r12 1163 +#define _LOAD_FAST_7_r23 1164 +#define _LOAD_FAST_AND_CLEAR_r01 1165 +#define _LOAD_FAST_AND_CLEAR_r12 1166 +#define _LOAD_FAST_AND_CLEAR_r23 1167 +#define _LOAD_FAST_BORROW_r01 1168 +#define _LOAD_FAST_BORROW_r12 1169 +#define _LOAD_FAST_BORROW_r23 1170 +#define _LOAD_FAST_BORROW_0_r01 1171 +#define _LOAD_FAST_BORROW_0_r12 1172 +#define _LOAD_FAST_BORROW_0_r23 1173 +#define _LOAD_FAST_BORROW_1_r01 1174 +#define _LOAD_FAST_BORROW_1_r12 1175 +#define _LOAD_FAST_BORROW_1_r23 1176 +#define _LOAD_FAST_BORROW_2_r01 1177 +#define _LOAD_FAST_BORROW_2_r12 1178 +#define _LOAD_FAST_BORROW_2_r23 1179 +#define _LOAD_FAST_BORROW_3_r01 1180 +#define _LOAD_FAST_BORROW_3_r12 1181 +#define _LOAD_FAST_BORROW_3_r23 1182 +#define _LOAD_FAST_BORROW_4_r01 1183 +#define _LOAD_FAST_BORROW_4_r12 1184 +#define _LOAD_FAST_BORROW_4_r23 1185 +#define _LOAD_FAST_BORROW_5_r01 1186 +#define _LOAD_FAST_BORROW_5_r12 1187 +#define _LOAD_FAST_BORROW_5_r23 1188 +#define _LOAD_FAST_BORROW_6_r01 1189 +#define _LOAD_FAST_BORROW_6_r12 1190 +#define _LOAD_FAST_BORROW_6_r23 1191 +#define _LOAD_FAST_BORROW_7_r01 1192 +#define _LOAD_FAST_BORROW_7_r12 1193 +#define _LOAD_FAST_BORROW_7_r23 1194 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1195 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1196 +#define _LOAD_FAST_CHECK_r01 1197 +#define _LOAD_FAST_CHECK_r12 1198 +#define _LOAD_FAST_CHECK_r23 1199 +#define _LOAD_FAST_LOAD_FAST_r02 1200 +#define _LOAD_FAST_LOAD_FAST_r13 1201 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1202 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1203 +#define _LOAD_GLOBAL_r00 1204 +#define _LOAD_GLOBAL_BUILTINS_r01 1205 +#define _LOAD_GLOBAL_MODULE_r01 1206 +#define _LOAD_LOCALS_r01 1207 +#define _LOAD_LOCALS_r12 1208 +#define _LOAD_LOCALS_r23 1209 +#define _LOAD_NAME_r01 1210 +#define _LOAD_SMALL_INT_r01 1211 +#define _LOAD_SMALL_INT_r12 1212 +#define _LOAD_SMALL_INT_r23 1213 +#define _LOAD_SMALL_INT_0_r01 1214 +#define _LOAD_SMALL_INT_0_r12 1215 +#define _LOAD_SMALL_INT_0_r23 1216 +#define _LOAD_SMALL_INT_1_r01 1217 +#define _LOAD_SMALL_INT_1_r12 1218 +#define _LOAD_SMALL_INT_1_r23 1219 +#define _LOAD_SMALL_INT_2_r01 1220 +#define _LOAD_SMALL_INT_2_r12 1221 +#define _LOAD_SMALL_INT_2_r23 1222 +#define _LOAD_SMALL_INT_3_r01 1223 +#define _LOAD_SMALL_INT_3_r12 1224 +#define _LOAD_SMALL_INT_3_r23 1225 +#define _LOAD_SPECIAL_r00 1226 +#define _LOAD_SUPER_ATTR_ATTR_r31 1227 +#define _LOAD_SUPER_ATTR_METHOD_r32 1228 +#define _MAKE_CALLARGS_A_TUPLE_r33 1229 +#define _MAKE_CELL_r00 1230 +#define _MAKE_FUNCTION_r11 1231 +#define _MAKE_WARM_r00 1232 +#define _MAKE_WARM_r11 1233 +#define _MAKE_WARM_r22 1234 +#define _MAKE_WARM_r33 1235 +#define _MAP_ADD_r20 1236 +#define _MATCH_CLASS_r31 1237 +#define _MATCH_KEYS_r23 1238 +#define _MATCH_MAPPING_r02 1239 +#define _MATCH_MAPPING_r12 1240 +#define _MATCH_MAPPING_r23 1241 +#define _MATCH_SEQUENCE_r02 1242 +#define _MATCH_SEQUENCE_r12 1243 +#define _MATCH_SEQUENCE_r23 1244 +#define _MAYBE_EXPAND_METHOD_r00 1245 +#define _MAYBE_EXPAND_METHOD_KW_r11 1246 +#define _MONITOR_CALL_r00 1247 +#define _MONITOR_CALL_KW_r11 1248 +#define _MONITOR_JUMP_BACKWARD_r00 1249 +#define _MONITOR_JUMP_BACKWARD_r11 1250 +#define _MONITOR_JUMP_BACKWARD_r22 1251 +#define _MONITOR_JUMP_BACKWARD_r33 1252 +#define _MONITOR_RESUME_r00 1253 +#define _NOP_r00 1254 +#define _NOP_r11 1255 +#define _NOP_r22 1256 +#define _NOP_r33 1257 +#define _POP_CALL_r20 1258 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1259 +#define _POP_CALL_ONE_r30 1260 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1261 +#define _POP_CALL_TWO_r30 1262 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1263 +#define _POP_EXCEPT_r10 1264 +#define _POP_ITER_r20 1265 +#define _POP_JUMP_IF_FALSE_r00 1266 +#define _POP_JUMP_IF_FALSE_r10 1267 +#define _POP_JUMP_IF_FALSE_r21 1268 +#define _POP_JUMP_IF_FALSE_r32 1269 +#define _POP_JUMP_IF_TRUE_r00 1270 +#define _POP_JUMP_IF_TRUE_r10 1271 +#define _POP_JUMP_IF_TRUE_r21 1272 +#define _POP_JUMP_IF_TRUE_r32 1273 +#define _POP_TOP_r10 1274 +#define _POP_TOP_FLOAT_r00 1275 +#define _POP_TOP_FLOAT_r10 1276 +#define _POP_TOP_FLOAT_r21 1277 +#define _POP_TOP_FLOAT_r32 1278 +#define _POP_TOP_INT_r00 1279 +#define _POP_TOP_INT_r10 1280 +#define _POP_TOP_INT_r21 1281 +#define _POP_TOP_INT_r32 1282 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1283 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1284 +#define _POP_TOP_NOP_r00 1285 +#define _POP_TOP_NOP_r10 1286 +#define _POP_TOP_NOP_r21 1287 +#define _POP_TOP_NOP_r32 1288 +#define _POP_TOP_UNICODE_r00 1289 +#define _POP_TOP_UNICODE_r10 1290 +#define _POP_TOP_UNICODE_r21 1291 +#define _POP_TOP_UNICODE_r32 1292 +#define _POP_TWO_r20 1293 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1294 +#define _PUSH_EXC_INFO_r02 1295 +#define _PUSH_EXC_INFO_r12 1296 +#define _PUSH_EXC_INFO_r23 1297 +#define _PUSH_FRAME_r10 1298 +#define _PUSH_NULL_r01 1299 +#define _PUSH_NULL_r12 1300 +#define _PUSH_NULL_r23 1301 +#define _PUSH_NULL_CONDITIONAL_r00 1302 +#define _PY_FRAME_EX_r31 1303 +#define _PY_FRAME_GENERAL_r01 1304 +#define _PY_FRAME_KW_r11 1305 +#define _QUICKEN_RESUME_r00 1306 +#define _QUICKEN_RESUME_r11 1307 +#define _QUICKEN_RESUME_r22 1308 +#define _QUICKEN_RESUME_r33 1309 +#define _REPLACE_WITH_TRUE_r02 1310 +#define _REPLACE_WITH_TRUE_r12 1311 +#define _REPLACE_WITH_TRUE_r23 1312 +#define _RESUME_CHECK_r00 1313 +#define _RESUME_CHECK_r11 1314 +#define _RESUME_CHECK_r22 1315 +#define _RESUME_CHECK_r33 1316 +#define _RETURN_GENERATOR_r01 1317 +#define _RETURN_VALUE_r11 1318 +#define _SAVE_RETURN_OFFSET_r00 1319 +#define _SAVE_RETURN_OFFSET_r11 1320 +#define _SAVE_RETURN_OFFSET_r22 1321 +#define _SAVE_RETURN_OFFSET_r33 1322 +#define _SEND_r22 1323 +#define _SEND_GEN_FRAME_r22 1324 +#define _SETUP_ANNOTATIONS_r00 1325 +#define _SET_ADD_r10 1326 +#define _SET_FUNCTION_ATTRIBUTE_r01 1327 +#define _SET_FUNCTION_ATTRIBUTE_r11 1328 +#define _SET_FUNCTION_ATTRIBUTE_r21 1329 +#define _SET_FUNCTION_ATTRIBUTE_r32 1330 +#define _SET_IP_r00 1331 +#define _SET_IP_r11 1332 +#define _SET_IP_r22 1333 +#define _SET_IP_r33 1334 +#define _SET_UPDATE_r10 1335 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1336 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1337 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1338 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1339 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1340 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1341 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1342 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1343 +#define _SPILL_OR_RELOAD_r01 1344 +#define _SPILL_OR_RELOAD_r02 1345 +#define _SPILL_OR_RELOAD_r03 1346 +#define _SPILL_OR_RELOAD_r10 1347 +#define _SPILL_OR_RELOAD_r12 1348 +#define _SPILL_OR_RELOAD_r13 1349 +#define _SPILL_OR_RELOAD_r20 1350 +#define _SPILL_OR_RELOAD_r21 1351 +#define _SPILL_OR_RELOAD_r23 1352 +#define _SPILL_OR_RELOAD_r30 1353 +#define _SPILL_OR_RELOAD_r31 1354 +#define _SPILL_OR_RELOAD_r32 1355 +#define _START_EXECUTOR_r00 1356 +#define _STORE_ATTR_r20 1357 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1358 +#define _STORE_ATTR_SLOT_r21 1359 +#define _STORE_ATTR_WITH_HINT_r21 1360 +#define _STORE_DEREF_r10 1361 +#define _STORE_FAST_LOAD_FAST_r11 1362 +#define _STORE_FAST_STORE_FAST_r20 1363 +#define _STORE_GLOBAL_r10 1364 +#define _STORE_NAME_r10 1365 +#define _STORE_SLICE_r30 1366 +#define _STORE_SUBSCR_r30 1367 +#define _STORE_SUBSCR_DICT_r31 1368 +#define _STORE_SUBSCR_LIST_INT_r32 1369 +#define _SWAP_r11 1370 +#define _SWAP_2_r02 1371 +#define _SWAP_2_r12 1372 +#define _SWAP_2_r22 1373 +#define _SWAP_2_r33 1374 +#define _SWAP_3_r03 1375 +#define _SWAP_3_r13 1376 +#define _SWAP_3_r23 1377 +#define _SWAP_3_r33 1378 +#define _SWAP_FAST_r01 1379 +#define _SWAP_FAST_r11 1380 +#define _SWAP_FAST_r22 1381 +#define _SWAP_FAST_r33 1382 +#define _SWAP_FAST_0_r01 1383 +#define _SWAP_FAST_0_r11 1384 +#define _SWAP_FAST_0_r22 1385 +#define _SWAP_FAST_0_r33 1386 +#define _SWAP_FAST_1_r01 1387 +#define _SWAP_FAST_1_r11 1388 +#define _SWAP_FAST_1_r22 1389 +#define _SWAP_FAST_1_r33 1390 +#define _SWAP_FAST_2_r01 1391 +#define _SWAP_FAST_2_r11 1392 +#define _SWAP_FAST_2_r22 1393 +#define _SWAP_FAST_2_r33 1394 +#define _SWAP_FAST_3_r01 1395 +#define _SWAP_FAST_3_r11 1396 +#define _SWAP_FAST_3_r22 1397 +#define _SWAP_FAST_3_r33 1398 +#define _SWAP_FAST_4_r01 1399 +#define _SWAP_FAST_4_r11 1400 +#define _SWAP_FAST_4_r22 1401 +#define _SWAP_FAST_4_r33 1402 +#define _SWAP_FAST_5_r01 1403 +#define _SWAP_FAST_5_r11 1404 +#define _SWAP_FAST_5_r22 1405 +#define _SWAP_FAST_5_r33 1406 +#define _SWAP_FAST_6_r01 1407 +#define _SWAP_FAST_6_r11 1408 +#define _SWAP_FAST_6_r22 1409 +#define _SWAP_FAST_6_r33 1410 +#define _SWAP_FAST_7_r01 1411 +#define _SWAP_FAST_7_r11 1412 +#define _SWAP_FAST_7_r22 1413 +#define _SWAP_FAST_7_r33 1414 +#define _TIER2_RESUME_CHECK_r00 1415 +#define _TIER2_RESUME_CHECK_r11 1416 +#define _TIER2_RESUME_CHECK_r22 1417 +#define _TIER2_RESUME_CHECK_r33 1418 +#define _TO_BOOL_r11 1419 +#define _TO_BOOL_BOOL_r01 1420 +#define _TO_BOOL_BOOL_r11 1421 +#define _TO_BOOL_BOOL_r22 1422 +#define _TO_BOOL_BOOL_r33 1423 +#define _TO_BOOL_INT_r02 1424 +#define _TO_BOOL_INT_r12 1425 +#define _TO_BOOL_INT_r23 1426 +#define _TO_BOOL_LIST_r02 1427 +#define _TO_BOOL_LIST_r12 1428 +#define _TO_BOOL_LIST_r23 1429 +#define _TO_BOOL_NONE_r01 1430 +#define _TO_BOOL_NONE_r11 1431 +#define _TO_BOOL_NONE_r22 1432 +#define _TO_BOOL_NONE_r33 1433 +#define _TO_BOOL_STR_r02 1434 +#define _TO_BOOL_STR_r12 1435 +#define _TO_BOOL_STR_r23 1436 +#define _TRACE_RECORD_r00 1437 +#define _UNARY_INVERT_r12 1438 +#define _UNARY_NEGATIVE_r12 1439 +#define _UNARY_NOT_r01 1440 +#define _UNARY_NOT_r11 1441 +#define _UNARY_NOT_r22 1442 +#define _UNARY_NOT_r33 1443 +#define _UNPACK_EX_r10 1444 +#define _UNPACK_SEQUENCE_r10 1445 +#define _UNPACK_SEQUENCE_LIST_r10 1446 +#define _UNPACK_SEQUENCE_TUPLE_r10 1447 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1448 +#define _WITH_EXCEPT_START_r33 1449 +#define _YIELD_VALUE_r11 1450 +#define MAX_UOP_REGS_ID 1450 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 85f2948ece4b4d..0835ee5c9499d1 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -370,6 +370,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_TIER2_RESUME_CHECK] = HAS_PERIODIC_FLAG, [_COLD_EXIT] = HAS_SYNC_SP_FLAG, [_COLD_DYNAMIC_EXIT] = HAS_SYNC_SP_FLAG, + [_GUARD_CODE] = HAS_EXIT_FLAG, [_GUARD_IP__PUSH_FRAME] = HAS_EXIT_FLAG, [_GUARD_IP_YIELD_VALUE] = HAS_EXIT_FLAG, [_GUARD_IP_RETURN_VALUE] = HAS_EXIT_FLAG, @@ -377,10 +378,11 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_RECORD_TOS] = HAS_RECORDS_VALUE_FLAG, [_RECORD_TOS_TYPE] = HAS_RECORDS_VALUE_FLAG, [_RECORD_NOS] = HAS_RECORDS_VALUE_FLAG, + [_RECORD_NOS_GEN_FUNC] = HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG, [_RECORD_4OS] = HAS_RECORDS_VALUE_FLAG, [_RECORD_CALLABLE] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG, [_RECORD_BOUND_METHOD] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG, - [_RECORD_CALLER_CODE] = HAS_RECORDS_VALUE_FLAG, + [_RECORD_CODE] = HAS_RECORDS_VALUE_FLAG, }; const ReplicationRange _PyUop_Replication[MAX_UOP_ID+1] = { @@ -3402,6 +3404,15 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, }, }, + [_GUARD_CODE] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 0, 0, _GUARD_CODE_r00 }, + { 1, 1, _GUARD_CODE_r11 }, + { 2, 2, _GUARD_CODE_r22 }, + { 3, 3, _GUARD_CODE_r33 }, + }, + }, [_GUARD_IP__PUSH_FRAME] = { .best = { 0, 1, 2, 3 }, .entries = { @@ -4210,6 +4221,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_TIER2_RESUME_CHECK_r33] = _TIER2_RESUME_CHECK, [_COLD_EXIT_r00] = _COLD_EXIT, [_COLD_DYNAMIC_EXIT_r00] = _COLD_DYNAMIC_EXIT, + [_GUARD_CODE_r00] = _GUARD_CODE, + [_GUARD_CODE_r11] = _GUARD_CODE, + [_GUARD_CODE_r22] = _GUARD_CODE, + [_GUARD_CODE_r33] = _GUARD_CODE, [_GUARD_IP__PUSH_FRAME_r00] = _GUARD_IP__PUSH_FRAME, [_GUARD_IP__PUSH_FRAME_r11] = _GUARD_IP__PUSH_FRAME, [_GUARD_IP__PUSH_FRAME_r22] = _GUARD_IP__PUSH_FRAME, @@ -4640,6 +4655,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_CALLABLE_TYPE_1_r13] = "_GUARD_CALLABLE_TYPE_1_r13", [_GUARD_CALLABLE_TYPE_1_r23] = "_GUARD_CALLABLE_TYPE_1_r23", [_GUARD_CALLABLE_TYPE_1_r33] = "_GUARD_CALLABLE_TYPE_1_r33", + [_GUARD_CODE] = "_GUARD_CODE", + [_GUARD_CODE_r00] = "_GUARD_CODE_r00", + [_GUARD_CODE_r11] = "_GUARD_CODE_r11", + [_GUARD_CODE_r22] = "_GUARD_CODE_r22", + [_GUARD_CODE_r33] = "_GUARD_CODE_r33", [_GUARD_DORV_NO_DICT] = "_GUARD_DORV_NO_DICT", [_GUARD_DORV_NO_DICT_r01] = "_GUARD_DORV_NO_DICT_r01", [_GUARD_DORV_NO_DICT_r11] = "_GUARD_DORV_NO_DICT_r11", @@ -5179,8 +5199,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_RECORD_4OS] = "_RECORD_4OS", [_RECORD_BOUND_METHOD] = "_RECORD_BOUND_METHOD", [_RECORD_CALLABLE] = "_RECORD_CALLABLE", - [_RECORD_CALLER_CODE] = "_RECORD_CALLER_CODE", + [_RECORD_CODE] = "_RECORD_CODE", [_RECORD_NOS] = "_RECORD_NOS", + [_RECORD_NOS_GEN_FUNC] = "_RECORD_NOS_GEN_FUNC", [_RECORD_TOS] = "_RECORD_TOS", [_RECORD_TOS_TYPE] = "_RECORD_TOS_TYPE", [_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE", @@ -6049,6 +6070,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _COLD_DYNAMIC_EXIT: return 0; + case _GUARD_CODE: + return 0; case _GUARD_IP__PUSH_FRAME: return 0; case _GUARD_IP_YIELD_VALUE: @@ -6063,13 +6086,15 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _RECORD_NOS: return 0; + case _RECORD_NOS_GEN_FUNC: + return 0; case _RECORD_4OS: return 0; case _RECORD_CALLABLE: return 0; case _RECORD_BOUND_METHOD: return 0; - case _RECORD_CALLER_CODE: + case _RECORD_CODE: return 0; default: return -1; diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 437cc340fc90e3..43b268b0206a46 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -978,50 +978,6 @@ def return_tenth(): # Constant narrowing allows constant folding for second comparison self.assertLessEqual(count_ops(ex, "_COMPARE_OP_FLOAT"), 1) - def test_compare_str_eq_narrows_to_constant(self): - def f(n): - def return_hello(): - return "hello" - - hits = 0 - v = return_hello() - for _ in range(n): - if v == "hello": - if v == "hello": - hits += 1 - return hits - - res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD) - self.assertEqual(res, TIER2_THRESHOLD) - self.assertIsNotNone(ex) - uops = get_opnames(ex) - - # Constant narrowing allows constant folding for second comparison - self.assertLessEqual(count_ops(ex, "_COMPARE_OP_STR"), 1) - - def test_compare_str_ne_narrows_to_constant(self): - def f(n): - def return_hello(): - return "hello" - - hits = 0 - v = return_hello() - for _ in range(n): - if v != "hello": - hits += 1000 - else: - if v == "hello": - hits += 1 - return hits - - res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD) - self.assertEqual(res, TIER2_THRESHOLD) - self.assertIsNotNone(ex) - uops = get_opnames(ex) - - # Constant narrowing allows constant folding for second comparison - self.assertLessEqual(count_ops(ex, "_COMPARE_OP_STR"), 1) - def test_combine_stack_space_checks_sequential(self): def dummy12(x): return x - 1 diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 64c9ffeb4dc411..c89c790988c52d 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -749,11 +749,11 @@ JUMP_TO_PREDICTED(BINARY_OP); } getitem = PyStackRef_FromPyObjectNew(getitem_o); - STAT_INC(BINARY_OP, hit); } // _BINARY_OP_SUBSCR_INIT_CALL { sub = stack_pointer[-1]; + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -10449,33 +10449,30 @@ next_instr += 1; INSTRUCTION_STATS(RETURN_GENERATOR); _PyStackRef res; - // _RETURN_GENERATOR - { - assert(PyStackRef_FunctionCheck(frame->f_funcobj)); - PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (gen == NULL) { - JUMP_TO_LABEL(error); - } - assert(STACK_LEVEL() <= 2); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyInterpreterFrame *gen_frame = &gen->gi_iframe; - frame->instr_ptr++; - _PyFrame_Copy(frame, gen_frame); - assert(frame->frame_obj == NULL); - gen->gi_frame_state = FRAME_CREATED; - gen_frame->owner = FRAME_OWNED_BY_GENERATOR; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *prev = frame->previous; - _PyThreadState_PopFrame(tstate, frame); - frame = tstate->current_frame = prev; - LOAD_IP(frame->return_offset); - stack_pointer = _PyFrame_GetStackPointer(frame); - res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); - LLTRACE_RESUME_FRAME(); + assert(PyStackRef_FunctionCheck(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (gen == NULL) { + JUMP_TO_LABEL(error); } + assert(STACK_LEVEL() <= 2); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = &gen->gi_iframe; + frame->instr_ptr++; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = tstate->current_frame = prev; + LOAD_IP(frame->return_offset); + stack_pointer = _PyFrame_GetStackPointer(frame); + res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); + LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -10492,24 +10489,21 @@ INSTRUCTION_STATS(RETURN_VALUE); _PyStackRef retval; _PyStackRef res; - // _RETURN_VALUE - { - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - assert(STACK_LEVEL() == 0); - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *dying = frame; - frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); - } + retval = stack_pointer[-1]; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(STACK_LEVEL() == 0); + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(frame->return_offset); + res = temp; + LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -12326,40 +12320,37 @@ INSTRUCTION_STATS(YIELD_VALUE); _PyStackRef retval; _PyStackRef value; - // _YIELD_VALUE - { - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - frame->instr_ptr++; - PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); - assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); - assert(oparg == 0 || oparg == 1); - _PyStackRef temp = retval; - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *gen_frame = frame; - frame = tstate->current_frame = frame->previous; - gen_frame->previous = NULL; - ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; - FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); - assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); - #if TIER_ONE - assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || + retval = stack_pointer[-1]; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + frame->instr_ptr++; + PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + _PyStackRef temp = retval; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + #if TIER_ONE + assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || frame->instr_ptr->op.code == INSTRUMENTED_INSTRUCTION || _PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND || _PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER || _PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT || _PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR); - #endif - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); - LLTRACE_RESUME_FRAME(); - } + #endif + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + value = PyStackRef_MakeHeapSafe(temp); + LLTRACE_RESUME_FRAME(); stack_pointer[0] = value; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index a990ab28577c73..a014f56deb202e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1095,10 +1095,10 @@ dummy_func( assert(code->co_argcount == 2); DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); getitem = PyStackRef_FromPyObjectNew(getitem_o); - STAT_INC(BINARY_OP, hit); } op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) { + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -1108,7 +1108,7 @@ dummy_func( } macro(BINARY_OP_SUBSCR_GETITEM) = - _RECORD_TOS + + _RECORD_NOS + unused/5 + // Skip over the counter and cache _CHECK_PEP_523 + _BINARY_OP_SUBSCR_CHECK_FUNC + @@ -1269,7 +1269,7 @@ dummy_func( // The stack effect here is a bit misleading. // retval is popped from the stack, but res // is pushed to a different frame, the callers' frame. - op(_RETURN_VALUE, (retval -- res)) { + inst(RETURN_VALUE, (retval -- res)) { assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); DEAD(retval); @@ -1293,13 +1293,9 @@ dummy_func( ERROR_IF(err); } - macro(RETURN_VALUE) = - _RECORD_CALLER_CODE + - _RETURN_VALUE; - macro(INSTRUMENTED_RETURN_VALUE) = _RETURN_VALUE_EVENT + - _RETURN_VALUE; + RETURN_VALUE; inst(GET_AITER, (obj -- iter)) { unaryfunc getter = NULL; @@ -1436,11 +1432,12 @@ dummy_func( macro(SEND_GEN) = unused/1 + + _RECORD_NOS_GEN_FUNC + _CHECK_PEP_523 + _SEND_GEN_FRAME + _PUSH_FRAME; - op(_YIELD_VALUE, (retval -- value)) { + inst(YIELD_VALUE, (retval -- value)) { // NOTE: It's important that YIELD_VALUE never raises an exception! // The compiler treats any exception raised here as a failed close() // or throw() call. @@ -1476,10 +1473,6 @@ dummy_func( LLTRACE_RESUME_FRAME(); } - macro(YIELD_VALUE) = - _RECORD_CALLER_CODE + - _YIELD_VALUE; - tier1 op(_YIELD_VALUE_EVENT, (val -- val)) { int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_YIELD, @@ -1495,7 +1488,7 @@ dummy_func( macro(INSTRUMENTED_YIELD_VALUE) = _YIELD_VALUE_EVENT + - _YIELD_VALUE; + YIELD_VALUE; inst(POP_EXCEPT, (exc_value -- )) { _PyErr_StackItem *exc_info = tstate->exc_info; @@ -3523,7 +3516,7 @@ dummy_func( } macro(FOR_ITER_GEN) = - _RECORD_NOS + + _RECORD_NOS_GEN_FUNC + unused/1 + _CHECK_PEP_523 + _FOR_ITER_GEN_FRAME + @@ -5074,7 +5067,7 @@ dummy_func( *ptr = attr; } - op(_RETURN_GENERATOR, (-- res)) { + inst(RETURN_GENERATOR, (-- res)) { assert(PyStackRef_FunctionCheck(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -5097,10 +5090,6 @@ dummy_func( LLTRACE_RESUME_FRAME(); } - macro(RETURN_GENERATOR) = - _RECORD_CALLER_CODE + - _RETURN_GENERATOR; - inst(BUILD_SLICE, (args[oparg] -- slice)) { PyObject *start_o = PyStackRef_AsPyObjectBorrow(args[0]); PyObject *stop_o = PyStackRef_AsPyObjectBorrow(args[1]); @@ -5646,6 +5635,12 @@ dummy_func( Py_UNREACHABLE(); } + tier2 op(_GUARD_CODE, (version/2 -- )) { + PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); + EXIT_IF(code == Py_None); + EXIT_IF(((PyCodeObject *)code)->co_version != version); + } + tier2 op(_GUARD_IP__PUSH_FRAME, (ip/4 --)) { _Py_CODEUNIT *target = frame->instr_ptr; if (target != (_Py_CODEUNIT *)ip) { @@ -5694,6 +5689,14 @@ dummy_func( RECORD_VALUE(PyStackRef_AsPyObjectBorrow(nos)); } + tier2 op(_RECORD_NOS_GEN_FUNC, (nos, tos -- nos, tos)) { + PyObject *obj = PyStackRef_AsPyObjectBorrow(nos); + if (PyGen_Check(obj)) { + PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe); + RECORD_VALUE(func); + } + } + tier2 op(_RECORD_4OS, (value, _3os, nos, tos -- value, _3os, nos, tos)) { RECORD_VALUE(PyStackRef_AsPyObjectBorrow(value)); } @@ -5710,12 +5713,9 @@ dummy_func( } } - tier2 op(_RECORD_CALLER_CODE, ( -- )) { - _PyInterpreterFrame *caller_frame = frame->previous; - if (caller_frame->owner < FRAME_OWNED_BY_INTERPRETER) { - PyCodeObject *code = _PyFrame_GetCode(frame->previous); - RECORD_VALUE(code); - } + /* Inserted by the JIT tracer. Never executed. */ + tier2 op(_RECORD_CODE, ( -- )) { + RECORD_VALUE(NULL); } label(pop_2_error) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9c82f1acdef493..08c547c4a0a3b4 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -6184,7 +6184,6 @@ JUMP_TO_JUMP_TARGET(); } getitem = PyStackRef_FromPyObjectNew(getitem_o); - STAT_INC(BINARY_OP, hit); _tos_cache2 = getitem; _tos_cache1 = _stack_item_1; _tos_cache0 = container; @@ -6203,6 +6202,7 @@ getitem = stack_pointer[-1]; sub = stack_pointer[-2]; container = stack_pointer[-3]; + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -6227,6 +6227,7 @@ getitem = _stack_item_0; sub = stack_pointer[-1]; container = stack_pointer[-2]; + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -6252,6 +6253,7 @@ getitem = _stack_item_1; sub = _stack_item_0; container = stack_pointer[-1]; + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -6278,6 +6280,7 @@ getitem = _stack_item_2; sub = _stack_item_1; container = _stack_item_0; + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -20142,6 +20145,110 @@ GOTO_TIER_ONE(target); } + case _GUARD_CODE_r00: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); + if (code == Py_None) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + if (((PyCodeObject *)code)->co_version != version) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + SET_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_CODE_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef _stack_item_0 = _tos_cache0; + uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); + if (code == Py_None) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + if (((PyCodeObject *)code)->co_version != version) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_CODE_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); + if (code == Py_None) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + if (((PyCodeObject *)code)->co_version != version) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_CODE_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); + if (code == Py_None) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = _stack_item_2; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + if (((PyCodeObject *)code)->co_version != version) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = _stack_item_2; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = _stack_item_2; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _GUARD_IP__PUSH_FRAME_r00: { CHECK_CURRENT_CACHED_VALUES(0); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index d3c5f526efd6a8..be5dbfcc747935 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -749,11 +749,11 @@ JUMP_TO_PREDICTED(BINARY_OP); } getitem = PyStackRef_FromPyObjectNew(getitem_o); - STAT_INC(BINARY_OP, hit); } // _BINARY_OP_SUBSCR_INIT_CALL { sub = stack_pointer[-1]; + STAT_INC(BINARY_OP, hit); _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); pushed_frame->localsplus[0] = container; pushed_frame->localsplus[1] = sub; @@ -10446,33 +10446,30 @@ next_instr += 1; INSTRUCTION_STATS(RETURN_GENERATOR); _PyStackRef res; - // _RETURN_GENERATOR - { - assert(PyStackRef_FunctionCheck(frame->f_funcobj)); - PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (gen == NULL) { - JUMP_TO_LABEL(error); - } - assert(STACK_LEVEL() <= 2); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyInterpreterFrame *gen_frame = &gen->gi_iframe; - frame->instr_ptr++; - _PyFrame_Copy(frame, gen_frame); - assert(frame->frame_obj == NULL); - gen->gi_frame_state = FRAME_CREATED; - gen_frame->owner = FRAME_OWNED_BY_GENERATOR; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *prev = frame->previous; - _PyThreadState_PopFrame(tstate, frame); - frame = tstate->current_frame = prev; - LOAD_IP(frame->return_offset); - stack_pointer = _PyFrame_GetStackPointer(frame); - res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); - LLTRACE_RESUME_FRAME(); + assert(PyStackRef_FunctionCheck(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (gen == NULL) { + JUMP_TO_LABEL(error); } + assert(STACK_LEVEL() <= 2); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = &gen->gi_iframe; + frame->instr_ptr++; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = tstate->current_frame = prev; + LOAD_IP(frame->return_offset); + stack_pointer = _PyFrame_GetStackPointer(frame); + res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); + LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -10489,24 +10486,21 @@ INSTRUCTION_STATS(RETURN_VALUE); _PyStackRef retval; _PyStackRef res; - // _RETURN_VALUE - { - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - assert(STACK_LEVEL() == 0); - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *dying = frame; - frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); - } + retval = stack_pointer[-1]; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(STACK_LEVEL() == 0); + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(frame->return_offset); + res = temp; + LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -12323,40 +12317,37 @@ INSTRUCTION_STATS(YIELD_VALUE); _PyStackRef retval; _PyStackRef value; - // _YIELD_VALUE - { - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - frame->instr_ptr++; - PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); - assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); - assert(oparg == 0 || oparg == 1); - _PyStackRef temp = retval; - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *gen_frame = frame; - frame = tstate->current_frame = frame->previous; - gen_frame->previous = NULL; - ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; - FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); - assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); - #if TIER_ONE - assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || + retval = stack_pointer[-1]; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + frame->instr_ptr++; + PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + _PyStackRef temp = retval; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + #if TIER_ONE + assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || frame->instr_ptr->op.code == INSTRUMENTED_INSTRUCTION || _PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND || _PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER || _PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT || _PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR); - #endif - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); - LLTRACE_RESUME_FRAME(); - } + #endif + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + value = PyStackRef_MakeHeapSafe(temp); + LLTRACE_RESUME_FRAME(); stack_pointer[0] = value; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); diff --git a/Python/optimizer.c b/Python/optimizer.c index e4e18f14bdc9b1..bf5d8a28264635 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -928,22 +928,8 @@ _PyJit_translate_single_bytecode_to_trace( } if (uop == _PUSH_FRAME || uop == _RETURN_VALUE || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { PyCodeObject *new_code = (PyCodeObject *)PyStackRef_AsPyObjectBorrow(frame->f_executable); - PyFunctionObject *new_func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); - - operand = 0; - if (frame->owner < FRAME_OWNED_BY_INTERPRETER) { - // Don't add nested code objects to the dependency. - // It causes endless re-traces. - if (new_func != NULL && !Py_IsNone((PyObject*)new_func) && !(new_code->co_flags & CO_NESTED)) { - operand = (uintptr_t)new_func; - DPRINTF(2, "Adding %p func to op\n", (void *)operand); - _Py_BloomFilter_Add(dependencies, new_func); - } - else if (new_code != NULL && !Py_IsNone((PyObject*)new_code)) { - operand = (uintptr_t)new_code | 1; - DPRINTF(2, "Adding %p code to op\n", (void *)operand); - _Py_BloomFilter_Add(dependencies, new_code); - } + if (new_code != NULL && !Py_IsNone((PyObject*)new_code)) { + _Py_BloomFilter_Add(dependencies, new_code); } ADD_TO_TRACE(uop, oparg, operand, target); uop_buffer_last(trace)->operand1 = PyStackRef_IsNone(frame->f_executable) ? 2 : ((int)(frame->stackpointer - _PyFrame_Stackbase(frame))); @@ -974,7 +960,13 @@ _PyJit_translate_single_bytecode_to_trace( DPRINTF(1, "Unknown uop needing guard ip %s\n", _PyOpcode_uop_name[uop_buffer_last(trace)->opcode]); Py_UNREACHABLE(); } + PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); + Py_INCREF(code); + ADD_TO_TRACE(_RECORD_CODE, 0, (uintptr_t)code, 0); ADD_TO_TRACE(guard_ip, 0, (uintptr_t)next_instr, 0); + if (PyCode_Check(code)) { + ADD_TO_TRACE(_GUARD_CODE, 0, ((PyCodeObject *)code)->co_version, 0); + } } // Loop back to the start int is_first_instr = tracer->initial_state.close_loop_instr == next_instr || @@ -1224,7 +1216,8 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length) base_opcode == _GUARD_IP__PUSH_FRAME || base_opcode == _GUARD_IP_RETURN_VALUE || base_opcode == _GUARD_IP_YIELD_VALUE || - base_opcode == _GUARD_IP_RETURN_GENERATOR + base_opcode == _GUARD_IP_RETURN_GENERATOR || + base_opcode == _GUARD_CODE ) { base_exit_op = _DYNAMIC_EXIT; } diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 039aacf23ae3a3..381b2500158ef0 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -226,6 +226,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr, uint16_t opcode, uint16_t oparg, uintptr_t operand0) { _PyUOpInstruction *out = ctx->out_buffer.next; + assert(out < ctx->out_buffer.end); out->opcode = (opcode); out->format = this_instr->format; out->oparg = (oparg); @@ -261,6 +262,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr, #define sym_is_bottom _Py_uop_sym_is_bottom #define sym_truthiness _Py_uop_sym_truthiness #define frame_new _Py_uop_frame_new +#define frame_new_from_symbol _Py_uop_frame_new_from_symbol #define frame_pop _Py_uop_frame_pop #define sym_new_tuple _Py_uop_sym_new_tuple #define sym_tuple_getitem _Py_uop_sym_tuple_getitem @@ -271,6 +273,11 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr, #define sym_new_truthiness _Py_uop_sym_new_truthiness #define sym_new_predicate _Py_uop_sym_new_predicate #define sym_apply_predicate_narrowing _Py_uop_sym_apply_predicate_narrowing +#define sym_set_recorded_type(SYM, TYPE) _Py_uop_sym_set_recorded_type(ctx, SYM, TYPE) +#define sym_set_recorded_value(SYM, VAL) _Py_uop_sym_set_recorded_value(ctx, SYM, VAL) +#define sym_set_recorded_gen_func(SYM, VAL) _Py_uop_sym_set_recorded_gen_func(ctx, SYM, VAL) +#define sym_get_probable_func_code _Py_uop_sym_get_probable_func_code +#define sym_get_probable_value _Py_uop_sym_get_probable_value /* Comparison oparg masks */ #define COMPARE_LT_MASK 2 @@ -355,30 +362,6 @@ lookup_attr(JitOptContext *ctx, _PyBloomFilter *dependencies, _PyUOpInstruction return sym_new_not_null(ctx); } -static PyCodeObject * -get_code_with_logging(_PyUOpInstruction *op) -{ - PyCodeObject *co = NULL; - uint64_t push_operand = op->operand0; - if (push_operand & 1) { - co = (PyCodeObject *)(push_operand & ~1); - DPRINTF(3, " code=%p\n", co); - assert(PyCode_Check(co)); - } - else { - PyFunctionObject *func = (PyFunctionObject *)push_operand; - DPRINTF(3, " func=%p ", func); - if (func == NULL) { - DPRINTF(3, "\n"); - DPRINTF(1, "Missing function\n"); - return NULL; - } - co = (PyCodeObject *)func->func_code; - DPRINTF(3, "code=%p\n", co); - } - return co; -} - static PyCodeObject * get_current_code_object(JitOptContext *ctx) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 89c6707160326c..0863d5dd8f8df7 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -30,6 +30,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; #define sym_set_compact_int(SYM) _Py_uop_sym_set_compact_int(ctx, SYM) #define sym_is_bottom _Py_uop_sym_is_bottom #define frame_new _Py_uop_frame_new +#define frame_new_from_symbol _Py_uop_frame_new_from_symbol #define frame_pop _Py_uop_frame_pop #define sym_new_tuple _Py_uop_sym_new_tuple #define sym_tuple_getitem _Py_uop_sym_tuple_getitem @@ -40,6 +41,11 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; #define sym_new_truthiness _Py_uop_sym_new_truthiness #define sym_new_predicate _Py_uop_sym_new_predicate #define sym_apply_predicate_narrowing _Py_uop_sym_apply_predicate_narrowing +#define sym_set_recorded_type(SYM, TYPE) _Py_uop_sym_set_recorded_type(ctx, SYM, TYPE) +#define sym_set_recorded_value(SYM, VAL) _Py_uop_sym_set_recorded_value(ctx, SYM, VAL) +#define sym_set_recorded_gen_func(SYM, VAL) _Py_uop_sym_set_recorded_gen_func(ctx, SYM, VAL) +#define sym_get_probable_func_code _Py_uop_sym_get_probable_func_code +#define sym_get_probable_value _Py_uop_sym_get_probable_value extern int optimize_to_bool( @@ -337,14 +343,23 @@ dummy_func(void) { GETLOCAL(this_instr->operand0) = sym_new_null(ctx); } - op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) { - assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging(this_instr + 1); - if (co == NULL) { - ctx->done = true; - break; + op(_BINARY_OP_SUBSCR_CHECK_FUNC, (container, unused -- container, unused, getitem)) { + getitem = sym_new_not_null(ctx); + PyTypeObject *tp = sym_get_type(container); + if (tp == NULL) { + PyObject *c = sym_get_probable_value(container); + if (c != NULL) { + tp = Py_TYPE(c); + } } - _Py_UOpsAbstractFrame *f = frame_new(ctx, co, 0, NULL, 0); + if (tp != NULL) { + PyObject *getitem_o = ((PyHeapTypeObject *)tp)->_spec_cache.getitem; + sym_set_recorded_value(getitem, getitem_o); + } + } + + op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) { + _Py_UOpsAbstractFrame *f = frame_new_from_symbol(ctx, getitem, 0, NULL, 0); if (f == NULL) { break; } @@ -556,17 +571,10 @@ dummy_func(void) { } op(_COMPARE_OP_STR, (left, right -- res, l, r)) { - int cmp_mask = oparg & (COMPARE_LT_MASK | COMPARE_GT_MASK | COMPARE_EQ_MASK); - - if (cmp_mask == COMPARE_EQ_MASK) { - res = sym_new_predicate(ctx, left, right, JIT_PRED_EQ); - } - else if (cmp_mask == (COMPARE_LT_MASK | COMPARE_GT_MASK)) { - res = sym_new_predicate(ctx, left, right, JIT_PRED_NE); - } - else { - res = sym_new_type(ctx, &PyBool_Type); - } + /* Cannot use predicate optimization here, as `a == b` + * does not imply that `a` is equivalent to `b`. `a` may be + * mortal, while `b` is immortal */ + res = sym_new_type(ctx, &PyBool_Type); l = left; r = right; REPLACE_OPCODE_IF_EVALUATES_PURE(left, right, res); @@ -814,12 +822,8 @@ dummy_func(void) { op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) { // + 1 for _SAVE_RETURN_OFFSET - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging(this_instr + 2); - if (co == NULL) { - ctx->done = true; - break; - } + // FIX ME -- This needs a version check and function watcher + PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; _Py_UOpsAbstractFrame *f = frame_new(ctx, co, 0, NULL, 0); if (f == NULL) { break; @@ -872,14 +876,6 @@ dummy_func(void) { op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame)) { int argcount = oparg; - - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - assert(!PyJitRef_IsNull(self_or_null)); assert(args != NULL); if (sym_is_not_null(self_or_null)) { @@ -889,9 +885,9 @@ dummy_func(void) { } if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args, argcount)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, args, argcount)); } else { - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); } } @@ -902,36 +898,15 @@ dummy_func(void) { } op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) { - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); } op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) { - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); } op(_PY_FRAME_EX, (func_st, null, callargs_st, kwargs_st -- ex_frame)) { - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - - ex_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + ex_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, func_st, 0, NULL, 0)); } op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) { @@ -954,8 +929,7 @@ dummy_func(void) { ctx->frame = shim; ctx->curr_frame_depth++; assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 1)); - init_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args-1, oparg+1)); + init_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, init, 0, args-1, oparg+1)); } op(_RETURN_VALUE, (retval -- res)) { @@ -964,7 +938,9 @@ dummy_func(void) { DEAD(retval); SAVE_STACK(); ctx->frame->stack_pointer = stack_pointer; - PyCodeObject *returning_code = get_code_with_logging(this_instr); + assert(this_instr[1].opcode == _RECORD_CODE); + PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; + assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; @@ -973,8 +949,8 @@ dummy_func(void) { if (ctx->curr_frame_depth >= 2) { PyCodeObject *expected_code = ctx->frames[ctx->curr_frame_depth - 2].code; if (expected_code == returning_code) { - assert((this_instr + 1)->opcode == _GUARD_IP_RETURN_VALUE); - REPLACE_OP((this_instr + 1), _NOP, 0, 0); + assert(this_instr[2].opcode == _GUARD_IP_RETURN_VALUE); + REPLACE_OP((this_instr + 2), _NOP, 0, 0); } } if (frame_pop(ctx, returning_code, returning_stacklevel)) { @@ -989,7 +965,9 @@ dummy_func(void) { op(_RETURN_GENERATOR, ( -- res)) { SYNC_SP(); ctx->frame->stack_pointer = stack_pointer; - PyCodeObject *returning_code = get_code_with_logging(this_instr); + assert(this_instr[1].opcode == _RECORD_CODE); + PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; + assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; @@ -1009,7 +987,9 @@ dummy_func(void) { DEAD(retval); SAVE_STACK(); ctx->frame->stack_pointer = stack_pointer; - PyCodeObject *returning_code = get_code_with_logging(this_instr); + assert(this_instr[1].opcode == _RECORD_CODE); + PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; + assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; @@ -1035,14 +1015,8 @@ dummy_func(void) { } } - op(_FOR_ITER_GEN_FRAME, (unused, unused -- unused, unused, gen_frame)) { - assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 1)); - if (co == NULL) { - ctx->done = true; - break; - } - _Py_UOpsAbstractFrame *new_frame = frame_new(ctx, co, 1, NULL, 0); + op(_FOR_ITER_GEN_FRAME, (iter, unused -- iter, unused, gen_frame)) { + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, iter, 1, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; @@ -1051,14 +1025,8 @@ dummy_func(void) { gen_frame = PyJitRef_WrapInvalid(new_frame); } - op(_SEND_GEN_FRAME, (unused, v -- unused, gen_frame)) { - assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 1)); - if (co == NULL) { - ctx->done = true; - break; - } - _Py_UOpsAbstractFrame *new_frame = frame_new(ctx, co, 1, NULL, 0); + op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) { + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, 1, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; @@ -1067,9 +1035,8 @@ dummy_func(void) { gen_frame = PyJitRef_WrapInvalid(new_frame); } - op(_CHECK_STACK_SPACE, (unused, unused, unused[oparg] -- unused, unused, unused[oparg])) { - assert((this_instr + 4)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 4)); + op(_CHECK_STACK_SPACE, (callable, unused, unused[oparg] -- callable, unused, unused[oparg])) { + PyCodeObject *co = sym_get_probable_func_code(callable); if (co == NULL) { ctx->done = true; break; @@ -1089,22 +1056,12 @@ dummy_func(void) { ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame); ctx->curr_frame_depth++; stack_pointer = ctx->frame->stack_pointer; - uint64_t operand = this_instr->operand0; - if (operand == 0) { - ctx->done = true; - break; - } - if (!(operand & 1)) { - PyFunctionObject *func = (PyFunctionObject *)operand; - // No need to re-add to dependencies here. Already - // handled by the tracer. - ctx->frame->func = func; - } // Fixed calls don't need IP guards. if ((this_instr-1)->opcode == _CREATE_INIT_FRAME) { assert((this_instr+1)->opcode == _GUARD_IP__PUSH_FRAME); REPLACE_OP(this_instr+1, _NOP, 0, 0); } + assert(ctx->frame->locals != NULL); } op(_UNPACK_SEQUENCE, (seq -- values[oparg], top[0])) { @@ -1653,6 +1610,32 @@ dummy_func(void) { ss = sub_st; } + op(_RECORD_TOS, (tos -- tos)) { + sym_set_recorded_value(tos, (PyObject *)this_instr->operand0); + } + + op(_RECORD_TOS_TYPE, (tos -- tos)) { + PyTypeObject *tp = (PyTypeObject *)this_instr->operand0; + sym_set_recorded_type(tos, tp); + } + + op(_RECORD_NOS, (nos, tos -- nos, tos)) { + sym_set_recorded_value(nos, (PyObject *)this_instr->operand0); + } + + op(_RECORD_4OS, (value, _3os, nos, tos -- value, _3os, nos, tos)) { + sym_set_recorded_value(value, (PyObject *)this_instr->operand0); + } + + op(_RECORD_CALLABLE, (func, self, args[oparg] -- func, self, args[oparg])) { + sym_set_recorded_value(func, (PyObject *)this_instr->operand0); + } + + op(_RECORD_NOS_GEN_FUNC, (nos, tos -- nos, tos)) { + PyFunctionObject *func = (PyFunctionObject *)this_instr->operand0; + assert(func == NULL || PyFunction_Check(func)); + sym_set_recorded_gen_func(nos, func); + } // END BYTECODES // diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 61a30314c21789..9a51d2fa366661 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1115,8 +1115,21 @@ } case _BINARY_OP_SUBSCR_CHECK_FUNC: { + JitOptRef container; JitOptRef getitem; + container = stack_pointer[-2]; getitem = sym_new_not_null(ctx); + PyTypeObject *tp = sym_get_type(container); + if (tp == NULL) { + PyObject *c = sym_get_probable_value(container); + if (c != NULL) { + tp = Py_TYPE(c); + } + } + if (tp != NULL) { + PyObject *getitem_o = ((PyHeapTypeObject *)tp)->_spec_cache.getitem; + sym_set_recorded_value(getitem, getitem_o); + } CHECK_STACK_BOUNDS(1); stack_pointer[0] = getitem; stack_pointer += 1; @@ -1125,18 +1138,14 @@ } case _BINARY_OP_SUBSCR_INIT_CALL: { + JitOptRef getitem; JitOptRef sub; JitOptRef container; JitOptRef new_frame; + getitem = stack_pointer[-1]; sub = stack_pointer[-2]; container = stack_pointer[-3]; - assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging(this_instr + 1); - if (co == NULL) { - ctx->done = true; - break; - } - _Py_UOpsAbstractFrame *f = frame_new(ctx, co, 0, NULL, 0); + _Py_UOpsAbstractFrame *f = frame_new_from_symbol(ctx, getitem, 0, NULL, 0); if (f == NULL) { break; } @@ -1239,7 +1248,9 @@ stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); ctx->frame->stack_pointer = stack_pointer; - PyCodeObject *returning_code = get_code_with_logging(this_instr); + assert(this_instr[1].opcode == _RECORD_CODE); + PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; + assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; @@ -1248,8 +1259,8 @@ if (ctx->curr_frame_depth >= 2) { PyCodeObject *expected_code = ctx->frames[ctx->curr_frame_depth - 2].code; if (expected_code == returning_code) { - assert((this_instr + 1)->opcode == _GUARD_IP_RETURN_VALUE); - REPLACE_OP((this_instr + 1), _NOP, 0, 0); + assert(this_instr[2].opcode == _GUARD_IP_RETURN_VALUE); + REPLACE_OP((this_instr + 2), _NOP, 0, 0); } } if (frame_pop(ctx, returning_code, returning_stacklevel)) { @@ -1292,15 +1303,11 @@ case _SEND_GEN_FRAME: { JitOptRef v; + JitOptRef receiver; JitOptRef gen_frame; v = stack_pointer[-1]; - assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 1)); - if (co == NULL) { - ctx->done = true; - break; - } - _Py_UOpsAbstractFrame *new_frame = frame_new(ctx, co, 1, NULL, 0); + receiver = stack_pointer[-2]; + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, 1, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; @@ -1320,7 +1327,9 @@ stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); ctx->frame->stack_pointer = stack_pointer; - PyCodeObject *returning_code = get_code_with_logging(this_instr); + assert(this_instr[1].opcode == _RECORD_CODE); + PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; + assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; @@ -1984,12 +1993,7 @@ JitOptRef new_frame; owner = stack_pointer[-1]; PyObject *fget = (PyObject *)this_instr->operand0; - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging(this_instr + 2); - if (co == NULL) { - ctx->done = true; - break; - } + PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; _Py_UOpsAbstractFrame *f = frame_new(ctx, co, 0, NULL, 0); if (f == NULL) { break; @@ -2267,16 +2271,7 @@ JitOptRef r; right = stack_pointer[-1]; left = stack_pointer[-2]; - int cmp_mask = oparg & (COMPARE_LT_MASK | COMPARE_GT_MASK | COMPARE_EQ_MASK); - if (cmp_mask == COMPARE_EQ_MASK) { - res = sym_new_predicate(ctx, left, right, JIT_PRED_EQ); - } - else if (cmp_mask == (COMPARE_LT_MASK | COMPARE_GT_MASK)) { - res = sym_new_predicate(ctx, left, right, JIT_PRED_NE); - } - else { - res = sym_new_type(ctx, &PyBool_Type); - } + res = sym_new_type(ctx, &PyBool_Type); l = left; r = right; if ( @@ -2694,14 +2689,10 @@ } case _FOR_ITER_GEN_FRAME: { + JitOptRef iter; JitOptRef gen_frame; - assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 1)); - if (co == NULL) { - ctx->done = true; - break; - } - _Py_UOpsAbstractFrame *new_frame = frame_new(ctx, co, 1, NULL, 0); + iter = stack_pointer[-2]; + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, iter, 1, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; @@ -2884,14 +2875,10 @@ /* _MONITOR_CALL is not a viable micro-op for tier 2 */ case _PY_FRAME_GENERAL: { + JitOptRef callable; JitOptRef new_frame; - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + callable = stack_pointer[-2 - oparg]; + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); CHECK_STACK_BOUNDS(-1 - oparg); stack_pointer[-2 - oparg] = new_frame; stack_pointer += -1 - oparg; @@ -2996,8 +2983,9 @@ } case _CHECK_STACK_SPACE: { - assert((this_instr + 4)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 4)); + JitOptRef callable; + callable = stack_pointer[-2 - oparg]; + PyCodeObject *co = sym_get_probable_func_code(callable); if (co == NULL) { ctx->done = true; break; @@ -3013,16 +3001,12 @@ case _INIT_CALL_PY_EXACT_ARGS: { JitOptRef *args; JitOptRef self_or_null; + JitOptRef callable; JitOptRef new_frame; args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; int argcount = oparg; - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } assert(!PyJitRef_IsNull(self_or_null)); assert(args != NULL); if (sym_is_not_null(self_or_null)) { @@ -3030,9 +3014,9 @@ argcount++; } if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args, argcount)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, args, argcount)); } else { - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); } CHECK_STACK_BOUNDS(-1 - oparg); stack_pointer[-2 - oparg] = new_frame; @@ -3053,19 +3037,11 @@ ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame); ctx->curr_frame_depth++; stack_pointer = ctx->frame->stack_pointer; - uint64_t operand = this_instr->operand0; - if (operand == 0) { - ctx->done = true; - break; - } - if (!(operand & 1)) { - PyFunctionObject *func = (PyFunctionObject *)operand; - ctx->frame->func = func; - } if ((this_instr-1)->opcode == _CREATE_INIT_FRAME) { assert((this_instr+1)->opcode == _GUARD_IP__PUSH_FRAME); REPLACE_OP(this_instr+1, _NOP, 0, 0); } + assert(ctx->frame->locals != NULL); break; } @@ -3212,9 +3188,11 @@ case _CREATE_INIT_FRAME: { JitOptRef *args; JitOptRef self; + JitOptRef init; JitOptRef init_frame; args = &stack_pointer[-oparg]; self = stack_pointer[-1 - oparg]; + init = stack_pointer[-2 - oparg]; ctx->frame->stack_pointer = stack_pointer - oparg - 2; _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, 0, NULL, 0); if (shim == NULL) { @@ -3226,8 +3204,7 @@ ctx->frame = shim; ctx->curr_frame_depth++; assert((this_instr + 1)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 1)); - init_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args-1, oparg+1)); + init_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, init, 0, args-1, oparg+1)); CHECK_STACK_BOUNDS(-1 - oparg); stack_pointer[-2 - oparg] = init_frame; stack_pointer += -1 - oparg; @@ -3501,14 +3478,10 @@ /* _DO_CALL_KW is not a viable micro-op for tier 2 */ case _PY_FRAME_KW: { + JitOptRef callable; JitOptRef new_frame; - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + callable = stack_pointer[-3 - oparg]; + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); CHECK_STACK_BOUNDS(-2 - oparg); stack_pointer[-3 - oparg] = new_frame; stack_pointer += -2 - oparg; @@ -3553,14 +3526,10 @@ } case _PY_FRAME_EX: { + JitOptRef func_st; JitOptRef ex_frame; - assert((this_instr + 2)->opcode == _PUSH_FRAME); - PyCodeObject *co = get_code_with_logging((this_instr + 2)); - if (co == NULL) { - ctx->done = true; - break; - } - ex_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0)); + func_st = stack_pointer[-4]; + ex_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, func_st, 0, NULL, 0)); CHECK_STACK_BOUNDS(-3); stack_pointer[-4] = ex_frame; stack_pointer += -3; @@ -3602,7 +3571,9 @@ case _RETURN_GENERATOR: { JitOptRef res; ctx->frame->stack_pointer = stack_pointer; - PyCodeObject *returning_code = get_code_with_logging(this_instr); + assert(this_instr[1].opcode == _RECORD_CODE); + PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; + assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; @@ -4167,6 +4138,10 @@ break; } + case _GUARD_CODE: { + break; + } + case _GUARD_IP__PUSH_FRAME: { break; } @@ -4184,22 +4159,47 @@ } case _RECORD_TOS: { + JitOptRef tos; + tos = stack_pointer[-1]; + sym_set_recorded_value(tos, (PyObject *)this_instr->operand0); break; } case _RECORD_TOS_TYPE: { + JitOptRef tos; + tos = stack_pointer[-1]; + PyTypeObject *tp = (PyTypeObject *)this_instr->operand0; + sym_set_recorded_type(tos, tp); break; } case _RECORD_NOS: { + JitOptRef nos; + nos = stack_pointer[-2]; + sym_set_recorded_value(nos, (PyObject *)this_instr->operand0); + break; + } + + case _RECORD_NOS_GEN_FUNC: { + JitOptRef nos; + nos = stack_pointer[-2]; + PyFunctionObject *func = (PyFunctionObject *)this_instr->operand0; + assert(func == NULL || PyFunction_Check(func)); + sym_set_recorded_gen_func(nos, func); break; } case _RECORD_4OS: { + JitOptRef value; + value = stack_pointer[-4]; + sym_set_recorded_value(value, (PyObject *)this_instr->operand0); break; } case _RECORD_CALLABLE: { + JitOptRef func; + func = stack_pointer[-2 - oparg]; + sym_set_recorded_value(func, (PyObject *)this_instr->operand0); break; } @@ -4207,7 +4207,7 @@ break; } - case _RECORD_CALLER_CODE: { + case _RECORD_CODE: { break; } diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c index bdf1b860d4e789..635ce622c3c589 100644 --- a/Python/optimizer_symbols.c +++ b/Python/optimizer_symbols.c @@ -4,6 +4,7 @@ #include "pycore_code.h" #include "pycore_frame.h" +#include "pycore_interpframe.h" #include "pycore_long.h" #include "pycore_optimizer.h" #include "pycore_stats.h" @@ -25,26 +26,26 @@ state represents no information, and the BOTTOM state represents contradictory information. Though symbols logically progress through all intermediate nodes, we often skip in-between states for convenience: - UNKNOWN-------------------+ - | | | -NULL | | -| | | <- Anything below this level is an object. -| NON_NULL-+ | -| | | | <- Anything below this level has a known type version. -| TYPE_VERSION | | -| | | | <- Anything below this level has a known type. -| KNOWN_CLASS | | -| | | | | | PREDICATE -| | | INT* | | | -| | | | | | | <- Anything below this level has a known truthiness. -| | | | | TRUTHINESS | -| | | | | | | -| TUPLE | | | | | -| | | | | | | <- Anything below this level is a known constant. -| KNOWN_VALUE--+----------+ -| | <- Anything below this level is unreachable. + UNKNOWN-------------------+------+ + | | | | +NULL | | RECORDED_VALUE* +| | | | <- Anything below this level is an object. +| NON_NULL-+ | | +| | | | | <- Anything below this level has a known type version. +| TYPE_VERSION | | | +| | | | | <- Anything below this level has a known type. +| KNOWN_CLASS | | | +| | | | | | PREDICATE RECORDED_VALUE(known type) +| | | INT* | | | | +| | | | | | | | <- Anything below this level has a known truthiness. +| TUPLE | | | TRUTHINESS | | +| | | | | | | | <- Anything below this level is a known constant. +| KNOWN_VALUE--+----------+------+ +| | <- Anything below this level is unreachable. BOTTOM + + For example, after guarding that the type of an UNKNOWN local is int, we can narrow the symbol to KNOWN_CLASS (logically progressing though NON_NULL and TYPE_VERSION to get there). Later, we may learn that it is falsey based on the @@ -54,6 +55,7 @@ the same symbol, that would be a contradiction, and the symbol would be set to BOTTOM (indicating that the code is unreachable). INT* is a limited range int, currently a "compact" int. +RECORDED_VALUE* includes RECORDED_TYPE and RECORDED_GEN_FUNC */ @@ -81,7 +83,8 @@ _PyUOpSymPrint(JitOptRef ref) return; } JitOptSymbol *sym = PyJitRef_Unwrap(ref); - switch (sym->tag) { + JitSymType tag = sym->tag; + switch (tag) { case JIT_SYM_UNKNOWN_TAG: printf("", (void *)sym); break; @@ -116,8 +119,17 @@ _PyUOpSymPrint(JitOptRef ref) case JIT_SYM_PREDICATE_TAG: printf("", (void *)sym); break; + case JIT_SYM_RECORDED_VALUE_TAG: + printf("", sym->recorded_value.value); + break; + case JIT_SYM_RECORDED_TYPE_TAG: + printf("", sym->recorded_type.type->tp_name); + break; + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + printf("", (void *)sym); + break; default: - printf("", sym->tag, (void *)sym); + printf("", tag, (void *)sym); break; } } @@ -304,8 +316,31 @@ _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef ref, PyTypeObject *typ) sym_set_bottom(ctx, sym); } return; + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + if (typ != &PyGen_Type) { + sym_set_bottom(ctx, sym); + } + return; case JIT_SYM_BOTTOM_TAG: return; + case JIT_SYM_RECORDED_VALUE_TAG: + if (Py_TYPE(sym->recorded_value.value) == typ) { + sym->recorded_value.known_type = true; + } + else { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_RECORDED_TYPE_TAG: + if (sym->recorded_type.type == typ) { + sym->tag = JIT_SYM_KNOWN_CLASS_TAG; + sym->cls.version = 0; + sym->cls.type = typ; + } + else { + sym_set_bottom(ctx, sym); + } + return; case JIT_SYM_NON_NULL_TAG: case JIT_SYM_UNKNOWN_TAG: sym->tag = JIT_SYM_KNOWN_CLASS_TAG; @@ -361,6 +396,12 @@ _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef ref, unsigned int ver return false; }; return true; + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + if (PyGen_Type.tp_version_tag != version) { + sym_set_bottom(ctx, sym); + return false; + } + return true; case JIT_SYM_TYPE_VERSION_TAG: if (sym->version.version != version) { sym_set_bottom(ctx, sym); @@ -387,6 +428,29 @@ _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef ref, unsigned int ver return false; } return true; + case JIT_SYM_RECORDED_VALUE_TAG: + if (Py_TYPE(sym->recorded_value.value)->tp_version_tag == version) { + sym->recorded_value.known_type = true; + sym->tag = JIT_SYM_KNOWN_CLASS_TAG; + sym->cls.type = Py_TYPE(sym->recorded_value.value); + sym->cls.version = version; + return true; + } + else { + sym_set_bottom(ctx, sym); + return false; + } + case JIT_SYM_RECORDED_TYPE_TAG: + if (sym->recorded_type.type->tp_version_tag == version) { + sym->tag = JIT_SYM_KNOWN_CLASS_TAG; + sym->cls.type = sym->recorded_type.type; + sym->cls.version = version; + return true; + } + else { + sym_set_bottom(ctx, sym); + return false; + } } Py_UNREACHABLE(); } @@ -398,6 +462,7 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef ref, PyObject *const_val) JitSymType tag = sym->tag; switch(tag) { case JIT_SYM_NULL_TAG: + case JIT_SYM_RECORDED_GEN_FUNC_TAG: sym_set_bottom(ctx, sym); return; case JIT_SYM_KNOWN_CLASS_TAG: @@ -437,6 +502,11 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef ref, PyObject *const_val) return; case JIT_SYM_BOTTOM_TAG: return; + case JIT_SYM_RECORDED_VALUE_TAG: + case JIT_SYM_RECORDED_TYPE_TAG: + /* The given value might contradict the recorded one, + * in which case we could return bottom. + * Just discard the recorded value for now */ case JIT_SYM_NON_NULL_TAG: case JIT_SYM_UNKNOWN_TAG: make_const(sym, const_val); @@ -592,6 +662,12 @@ _Py_uop_sym_get_type(JitOptRef ref) case JIT_SYM_BOTTOM_TAG: case JIT_SYM_NON_NULL_TAG: case JIT_SYM_UNKNOWN_TAG: + case JIT_SYM_RECORDED_TYPE_TAG: + return NULL; + case JIT_SYM_RECORDED_VALUE_TAG: + if (sym->recorded_value.known_type) { + return Py_TYPE(sym->recorded_value.value); + } return NULL; case JIT_SYM_KNOWN_CLASS_TAG: return sym->cls.type; @@ -606,7 +682,8 @@ _Py_uop_sym_get_type(JitOptRef ref) return &PyBool_Type; case JIT_SYM_COMPACT_INT: return &PyLong_Type; - + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + return &PyGen_Type; } Py_UNREACHABLE(); } @@ -621,6 +698,8 @@ _Py_uop_sym_get_type_version(JitOptRef ref) case JIT_SYM_BOTTOM_TAG: case JIT_SYM_NON_NULL_TAG: case JIT_SYM_UNKNOWN_TAG: + case JIT_SYM_RECORDED_VALUE_TAG: + case JIT_SYM_RECORDED_TYPE_TAG: return 0; case JIT_SYM_TYPE_VERSION_TAG: return sym->version.version; @@ -635,6 +714,8 @@ _Py_uop_sym_get_type_version(JitOptRef ref) return PyBool_Type.tp_version_tag; case JIT_SYM_COMPACT_INT: return PyLong_Type.tp_version_tag; + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + return PyGen_Type.tp_version_tag; } Py_UNREACHABLE(); } @@ -658,11 +739,69 @@ _Py_uop_sym_matches_type_version(JitOptRef sym, unsigned int version) return _Py_uop_sym_get_type_version(sym) == version; } +PyObject * +_Py_uop_sym_get_probable_value(JitOptRef ref) +{ + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + JitSymType tag = sym->tag; + switch(tag) { + case JIT_SYM_NULL_TAG: + case JIT_SYM_BOTTOM_TAG: + case JIT_SYM_NON_NULL_TAG: + case JIT_SYM_UNKNOWN_TAG: + case JIT_SYM_RECORDED_TYPE_TAG: + case JIT_SYM_TYPE_VERSION_TAG: + case JIT_SYM_TUPLE_TAG: + case JIT_SYM_PREDICATE_TAG: + case JIT_SYM_TRUTHINESS_TAG: + case JIT_SYM_COMPACT_INT: + case JIT_SYM_KNOWN_CLASS_TAG: + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + return NULL; + case JIT_SYM_RECORDED_VALUE_TAG: + return sym->recorded_value.value; + case JIT_SYM_KNOWN_VALUE_TAG: + return sym->value.value; + } + Py_UNREACHABLE(); +} + +PyCodeObject * +_Py_uop_sym_get_probable_func_code(JitOptRef ref) +{ + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + if (sym->tag == JIT_SYM_RECORDED_GEN_FUNC_TAG) { + return (PyCodeObject *)PyFunction_GET_CODE(sym->recorded_gen_func.func); + } + PyObject *obj = _Py_uop_sym_get_probable_value(ref); + if (obj != NULL) { + if (PyFunction_Check(obj)) { + return (PyCodeObject *)PyFunction_GET_CODE(obj); + } + } + return NULL; +} + +PyFunctionObject * +_Py_uop_sym_get_probable_function(JitOptRef ref) +{ + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + if (sym->tag == JIT_SYM_RECORDED_GEN_FUNC_TAG) { + return sym->recorded_gen_func.func; + } + PyObject *obj = _Py_uop_sym_get_probable_value(ref); + if (obj != NULL && PyFunction_Check(obj)) { + return (PyFunctionObject *)obj; + } + return NULL; +} + int _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef ref) { JitOptSymbol *sym = PyJitRef_Unwrap(ref); - switch(sym->tag) { + JitSymType tag = sym->tag; + switch (tag) { case JIT_SYM_NULL_TAG: case JIT_SYM_TYPE_VERSION_TAG: case JIT_SYM_BOTTOM_TAG: @@ -670,6 +809,9 @@ _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef ref) case JIT_SYM_UNKNOWN_TAG: case JIT_SYM_COMPACT_INT: case JIT_SYM_PREDICATE_TAG: + case JIT_SYM_RECORDED_VALUE_TAG: + case JIT_SYM_RECORDED_TYPE_TAG: + case JIT_SYM_RECORDED_GEN_FUNC_TAG: return -1; case JIT_SYM_KNOWN_CLASS_TAG: /* TODO : @@ -681,7 +823,7 @@ _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef ref) case JIT_SYM_TUPLE_TAG: return sym->tuple.length != 0; case JIT_SYM_TRUTHINESS_TAG: - ; + { JitOptSymbol *value = allocation_base(ctx) + sym->truthiness.value; int truthiness = _Py_uop_sym_truthiness(ctx, PyJitRef_Wrap(value)); @@ -691,6 +833,7 @@ _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef ref) truthiness ^= sym->truthiness.invert; make_const(sym, truthiness ? Py_True : Py_False); return truthiness; + } } PyObject *value = sym->value.value; /* Only handle a few known safe types */ @@ -801,6 +944,7 @@ _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref) JitSymType tag = sym->tag; switch(tag) { case JIT_SYM_NULL_TAG: + case JIT_SYM_RECORDED_GEN_FUNC_TAG: sym_set_bottom(ctx, sym); return; case JIT_SYM_KNOWN_CLASS_TAG: @@ -832,6 +976,11 @@ _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref) case JIT_SYM_BOTTOM_TAG: case JIT_SYM_COMPACT_INT: return; + case JIT_SYM_RECORDED_VALUE_TAG: + case JIT_SYM_RECORDED_TYPE_TAG: + /* The given value might contradict the recorded one, + * in which case we could return bottom. + * Just discard the recorded value for now */ case JIT_SYM_NON_NULL_TAG: case JIT_SYM_UNKNOWN_TAG: sym->tag = JIT_SYM_COMPACT_INT; @@ -941,6 +1090,222 @@ _Py_uop_sym_new_compact_int(JitOptContext *ctx) return PyJitRef_Wrap(sym); } +void +_Py_uop_sym_set_recorded_value(JitOptContext *ctx, JitOptRef ref, PyObject *value) +{ + // It is possible for value to be NULL due to respecialization + // during execution of the traced instruction. + if (value == NULL) { + return; + } + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + JitSymType tag = sym->tag; + switch(tag) { + case JIT_SYM_NULL_TAG: + sym_set_bottom(ctx, sym); + return; + case JIT_SYM_BOTTOM_TAG: + return; + case JIT_SYM_NON_NULL_TAG: + case JIT_SYM_UNKNOWN_TAG: + sym->tag = JIT_SYM_RECORDED_VALUE_TAG; + sym->recorded_value.known_type = false; + sym->recorded_value.value = value; + return; + case JIT_SYM_RECORDED_VALUE_TAG: + if (sym->recorded_value.value != value) { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_RECORDED_TYPE_TAG: + if (sym->recorded_type.type == Py_TYPE(value)) { + sym->tag = JIT_SYM_RECORDED_VALUE_TAG; + sym->recorded_value.known_type = false; + sym->recorded_value.value = value; + } + else { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_KNOWN_CLASS_TAG: + if (sym->cls.type == Py_TYPE(value)) { + sym->tag = JIT_SYM_RECORDED_VALUE_TAG; + sym->recorded_value.known_type = true; + sym->recorded_value.value = value; + } + else { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_KNOWN_VALUE_TAG: + return; + case JIT_SYM_TYPE_VERSION_TAG: + if (sym->version.version == Py_TYPE(value)->tp_version_tag) { + sym->tag = JIT_SYM_RECORDED_VALUE_TAG; + sym->recorded_value.known_type = true; + sym->recorded_value.value = value; + } + else { + sym_set_bottom(ctx, sym); + } + return; + // In these cases the original information is more valuable + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + case JIT_SYM_TUPLE_TAG: + case JIT_SYM_PREDICATE_TAG: + case JIT_SYM_TRUTHINESS_TAG: + case JIT_SYM_COMPACT_INT: + return; + } + Py_UNREACHABLE(); +} +void +_Py_uop_sym_set_recorded_gen_func(JitOptContext *ctx, JitOptRef ref, PyFunctionObject *value) +{ + // It is possible for value to be NULL due to respecialization + // during execution of the traced instruction. + if (value == NULL) { + return; + } + assert(!PyJitRef_IsNull(ref)); + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + JitSymType tag = sym->tag; + switch(tag) { + case JIT_SYM_NULL_TAG: + case JIT_SYM_RECORDED_VALUE_TAG: + case JIT_SYM_KNOWN_VALUE_TAG: + case JIT_SYM_TUPLE_TAG: + case JIT_SYM_PREDICATE_TAG: + case JIT_SYM_TRUTHINESS_TAG: + case JIT_SYM_COMPACT_INT: + sym_set_bottom(ctx, sym); + return; + case JIT_SYM_BOTTOM_TAG: + return; + case JIT_SYM_NON_NULL_TAG: + case JIT_SYM_UNKNOWN_TAG: + sym->tag = JIT_SYM_RECORDED_GEN_FUNC_TAG; + sym->recorded_gen_func.func = value; + return; + case JIT_SYM_RECORDED_TYPE_TAG: + if (sym->recorded_type.type == &PyGen_Type) { + sym->tag = JIT_SYM_RECORDED_GEN_FUNC_TAG; + sym->recorded_gen_func.func = value; + } + else { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_KNOWN_CLASS_TAG: + if (sym->cls.type == &PyGen_Type) { + sym->tag = JIT_SYM_RECORDED_GEN_FUNC_TAG; + sym->recorded_gen_func.func = value; + } + else { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_TYPE_VERSION_TAG: + if (sym->version.version == PyGen_Type.tp_version_tag) { + sym->tag = JIT_SYM_RECORDED_GEN_FUNC_TAG; + sym->recorded_gen_func.func = value; + } + else { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + if (sym->recorded_gen_func.func != value) { + sym_set_bottom(ctx, sym); + } + return; + } + Py_UNREACHABLE(); +} + +void +_Py_uop_sym_set_recorded_type(JitOptContext *ctx, JitOptRef ref, PyTypeObject *type) +{ + // It is possible for type to be NULL due to respecialization + // during execution of the traced instruction. + if (type == NULL) { + return; + } + assert(PyType_Check((PyObject *)type)); + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + JitSymType tag = sym->tag; + switch(tag) { + case JIT_SYM_NULL_TAG: + sym_set_bottom(ctx, sym); + return; + case JIT_SYM_BOTTOM_TAG: + return; + case JIT_SYM_NON_NULL_TAG: + case JIT_SYM_UNKNOWN_TAG: + sym->tag = JIT_SYM_RECORDED_TYPE_TAG; + sym->recorded_type.type = type; + return; + case JIT_SYM_RECORDED_VALUE_TAG: + if (Py_TYPE(sym->recorded_value.value) != type) { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_RECORDED_TYPE_TAG: + if (sym->recorded_type.type != type) { + sym_set_bottom(ctx, sym); + } + return; + case JIT_SYM_KNOWN_CLASS_TAG: + return; + case JIT_SYM_KNOWN_VALUE_TAG: + return; + case JIT_SYM_TYPE_VERSION_TAG: + if (sym->version.version == type->tp_version_tag) { + sym->tag = JIT_SYM_KNOWN_CLASS_TAG; + sym->cls.type = type; + } + else { + sym_set_bottom(ctx, sym); + } + return; + // In these cases the original information is more valuable + case JIT_SYM_TUPLE_TAG: + case JIT_SYM_PREDICATE_TAG: + case JIT_SYM_TRUTHINESS_TAG: + case JIT_SYM_COMPACT_INT: + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + return; + } + Py_UNREACHABLE(); +} + +// 0 on success, -1 on error. +_Py_UOpsAbstractFrame * +_Py_uop_frame_new_from_symbol( + JitOptContext *ctx, + JitOptRef callable, + int curr_stackentries, + JitOptRef *args, + int arg_len) +{ + PyCodeObject *co = _Py_uop_sym_get_probable_func_code(callable); + if (co == NULL) { + ctx->done = true; + return NULL; + } + _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, co, curr_stackentries, args, arg_len); + if (frame == NULL) { + return NULL; + } + PyFunctionObject *func = _Py_uop_sym_get_probable_function(callable); + if (func != NULL) { + assert(PyFunction_Check(func)); + frame->func = func; + } + assert(frame->stack_pointer != NULL); + return frame; +} + // 0 on success, -1 on error. _Py_UOpsAbstractFrame * _Py_uop_frame_new( @@ -950,6 +1315,7 @@ _Py_uop_frame_new( JitOptRef *args, int arg_len) { + assert(co != NULL); if (ctx->curr_frame_depth >= MAX_ABSTRACT_FRAME_DEPTH) { ctx->done = true; ctx->out_of_space = true; @@ -988,13 +1354,13 @@ _Py_uop_frame_new( frame->locals[i] = local; } - // Initialize the stack as well for (int i = 0; i < curr_stackentries; i++) { JitOptRef stackvar = _Py_uop_sym_new_unknown(ctx); frame->stack[i] = stackvar; } + assert(frame->locals != NULL); return frame; } @@ -1052,6 +1418,7 @@ _Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co, int curr_stackentries) if (ctx->curr_frame_depth >= 1) { ctx->frame = &ctx->frames[ctx->curr_frame_depth - 1]; + assert(ctx->frame->locals != NULL); // We returned to the correct code. Nothing to do here. if (co == ctx->frame->code) { @@ -1079,6 +1446,7 @@ _Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co, int curr_stackentries) ctx->curr_frame_depth++; ctx->frame = new_frame; + assert(ctx->frame->locals != NULL); return 0; } @@ -1111,6 +1479,7 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) PyObject *val_43 = NULL; PyObject *val_big = NULL; PyObject *tuple = NULL; + PyFunctionObject *func = NULL; // Use a single 'sym' variable so copy-pasting tests is easier. JitOptRef ref = _Py_uop_sym_new_unknown(ctx); @@ -1521,11 +1890,118 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) TEST_PREDICATE(_Py_uop_sym_matches_type(ref_int, &PyLong_Type), "43 is not an int"); TEST_PREDICATE(_Py_uop_sym_get_const(ctx, ref_int) == val_43, "43 isn't 43"); + // Test recorded values + + /* Test that recorded values aren't treated as known values*/ + JitOptRef rv1 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_value(ctx, rv1, val_42); + TEST_PREDICATE(!_Py_uop_sym_matches_type(rv1, &PyLong_Type), "recorded value is treated as known"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rv1) == NULL, "recorded value is treated as known"); + TEST_PREDICATE(!_Py_uop_sym_is_compact_int(rv1), "recorded value is treated as known"); + + /* Test that setting type or value narrows correctly */ + JitOptRef rv2 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_value(ctx, rv2, val_42); + _Py_uop_sym_set_const(ctx, rv2, val_42); + TEST_PREDICATE(_Py_uop_sym_matches_type(rv2, &PyLong_Type), "recorded value doesn't narrow"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rv2) == val_42, "recorded value doesn't narrow"); + + JitOptRef rv3 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_value(ctx, rv3, val_42); + _Py_uop_sym_set_type(ctx, rv3, &PyLong_Type); + TEST_PREDICATE(_Py_uop_sym_matches_type(rv3, &PyLong_Type), "recorded value doesn't narrow"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rv3) == NULL, "recorded value with type is treated as known"); + + JitOptRef rv4 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_value(ctx, rv4, val_42); + _Py_uop_sym_set_type_version(ctx, rv4, PyLong_Type.tp_version_tag); + TEST_PREDICATE(_Py_uop_sym_matches_type(rv4, &PyLong_Type), "recorded value doesn't narrow"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rv4) == NULL, "recorded value with type is treated as known"); + + // test recorded types + + /* Test that recorded type aren't treated as known values*/ + JitOptRef rt1 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_type(ctx, rt1, &PyLong_Type); + TEST_PREDICATE(!_Py_uop_sym_matches_type(rt1, &PyLong_Type), "recorded type is treated as known"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rt1) == NULL, "recorded type is treated as known value"); + + /* Test that setting type or value narrows correctly */ + JitOptRef rt2 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_type(ctx, rt2, &PyLong_Type); + _Py_uop_sym_set_const(ctx, rt2, val_42); + TEST_PREDICATE(_Py_uop_sym_matches_type(rt2, &PyLong_Type), "recorded value doesn't narrow"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rt2) == val_42, "recorded value doesn't narrow"); + + JitOptRef rt3 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_type(ctx, rt3, &PyLong_Type); + _Py_uop_sym_set_type(ctx, rt3, &PyLong_Type); + TEST_PREDICATE(_Py_uop_sym_matches_type(rt3, &PyLong_Type), "recorded value doesn't narrow"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rt3) == NULL, "known type is treated as known value"); + + JitOptRef rt4 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_type(ctx, rt4, &PyLong_Type); + _Py_uop_sym_set_type_version(ctx, rt4, PyLong_Type.tp_version_tag); + TEST_PREDICATE(_Py_uop_sym_matches_type(rt4, &PyLong_Type), "recorded value doesn't narrow"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rt4) == NULL, "recorded value with type is treated as known"); + + // test recorded gen function + + PyObject *dict = PyDict_New(); + if (dict == NULL) { + goto fail; + } + PyCodeObject *code = PyCode_NewEmpty(__FILE__, "uop_symbols_test", __LINE__); + if (code == NULL) { + goto fail; + } + func = (PyFunctionObject *)PyFunction_New((PyObject *)code, dict); + if (func == NULL) { + goto fail; + } + + /* Test that recorded type aren't treated as known values*/ + JitOptRef rg1 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_gen_func(ctx, rg1, func); + TEST_PREDICATE(_Py_uop_sym_matches_type(rg1, &PyGen_Type), "recorded gen func not treated as generator"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rg1) == NULL, "recorded gen func is treated as known value"); + + /* Test that setting type narrows correctly */ + + JitOptRef rg2 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_gen_func(ctx, rg2, func); + _Py_uop_sym_set_type(ctx, rg2, &PyGen_Type); + TEST_PREDICATE(_Py_uop_sym_matches_type(rg1, &PyGen_Type), "recorded gen func not treated as generator"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rg2) == NULL, "known type is treated as known value"); + + JitOptRef rg3 = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_recorded_gen_func(ctx, rg3, func); + _Py_uop_sym_set_type_version(ctx, rg3, PyGen_Type.tp_version_tag); + TEST_PREDICATE(_Py_uop_sym_matches_type(rg1, &PyGen_Type), "recorded gen func not treated as generator"); + TEST_PREDICATE(_Py_uop_sym_get_const(ctx, rg3) == NULL, "recorded value with type is treated as known"); + + /* Test contradictions */ + _Py_uop_sym_set_type(ctx, rv1, &PyFloat_Type); + TEST_PREDICATE(_Py_uop_sym_is_bottom(rv1), "recorded value cast to other type isn't bottom"); + _Py_uop_sym_set_type_version(ctx, rv2, PyFloat_Type.tp_version_tag); + TEST_PREDICATE(_Py_uop_sym_is_bottom(rv2), "recorded value cast to other type version isn't bottom"); + + _Py_uop_sym_set_type(ctx, rt1, &PyFloat_Type); + TEST_PREDICATE(_Py_uop_sym_is_bottom(rv1), "recorded type cast to other type isn't bottom"); + _Py_uop_sym_set_type_version(ctx, rt2, PyFloat_Type.tp_version_tag); + TEST_PREDICATE(_Py_uop_sym_is_bottom(rv2), "recorded type cast to other type version isn't bottom"); + + _Py_uop_sym_set_type(ctx, rg1, &PyFloat_Type); + TEST_PREDICATE(_Py_uop_sym_is_bottom(rg1), "recorded gen func cast to other type isn't bottom"); + _Py_uop_sym_set_type_version(ctx, rg2, PyFloat_Type.tp_version_tag); + TEST_PREDICATE(_Py_uop_sym_is_bottom(rg2), "recorded gen func cast to other type version isn't bottom"); + _Py_uop_abstractcontext_fini(ctx); Py_DECREF(val_42); Py_DECREF(val_43); Py_DECREF(val_big); Py_DECREF(tuple); + Py_DECREF(func); Py_RETURN_NONE; fail: @@ -1533,7 +2009,8 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) Py_XDECREF(val_42); Py_XDECREF(val_43); Py_XDECREF(val_big); - Py_DECREF(tuple); + Py_XDECREF(tuple); + Py_XDECREF(func); return NULL; } diff --git a/Python/record_functions.c.h b/Python/record_functions.c.h index ba85ed752d2c96..c6709f9a9d6bec 100644 --- a/Python/record_functions.c.h +++ b/Python/record_functions.c.h @@ -27,6 +27,19 @@ void _PyOpcode_RecordFunction_NOS(_PyInterpreterFrame *frame, _PyStackRef *stack Py_INCREF(*recorded_value); } +void _PyOpcode_RecordFunction_NOS_GEN_FUNC(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) { + _PyStackRef nos; + nos = stack_pointer[-2]; + PyObject *obj = PyStackRef_AsPyObjectBorrow(nos); + if (PyGen_Check(obj)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe); + stack_pointer = _PyFrame_GetStackPointer(frame); + *recorded_value = (PyObject *)func; + Py_INCREF(*recorded_value); + } +} + void _PyOpcode_RecordFunction_4OS(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) { _PyStackRef value; value = stack_pointer[-4]; @@ -52,27 +65,21 @@ void _PyOpcode_RecordFunction_BOUND_METHOD(_PyInterpreterFrame *frame, _PyStackR } } -void _PyOpcode_RecordFunction_CALLER_CODE(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) { - _PyInterpreterFrame *caller_frame = frame->previous; - if (caller_frame->owner < FRAME_OWNED_BY_INTERPRETER) { - PyCodeObject *code = _PyFrame_GetCode(frame->previous); - *recorded_value = (PyObject *)code; - Py_INCREF(*recorded_value); - } +void _PyOpcode_RecordFunction_CODE(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) { + *recorded_value = (PyObject *)NULL; + Py_INCREF(*recorded_value); } #define _RECORD_TOS_TYPE_INDEX 1 -#define _RECORD_TOS_INDEX 2 -#define _RECORD_CALLER_CODE_INDEX 3 -#define _RECORD_NOS_INDEX 4 -#define _RECORD_CALLABLE_INDEX 5 -#define _RECORD_BOUND_METHOD_INDEX 6 -#define _RECORD_4OS_INDEX 7 +#define _RECORD_NOS_INDEX 2 +#define _RECORD_NOS_GEN_FUNC_INDEX 3 +#define _RECORD_CALLABLE_INDEX 4 +#define _RECORD_BOUND_METHOD_INDEX 5 +#define _RECORD_4OS_INDEX 6 const uint8_t _PyOpcode_RecordFunctionIndices[256] = { [TO_BOOL_ALWAYS_TRUE] = _RECORD_TOS_TYPE_INDEX, - [BINARY_OP_SUBSCR_GETITEM] = _RECORD_TOS_INDEX, - [RETURN_VALUE] = _RECORD_CALLER_CODE_INDEX, - [YIELD_VALUE] = _RECORD_CALLER_CODE_INDEX, + [BINARY_OP_SUBSCR_GETITEM] = _RECORD_NOS_INDEX, + [SEND_GEN] = _RECORD_NOS_GEN_FUNC_INDEX, [LOAD_ATTR_INSTANCE_VALUE] = _RECORD_TOS_TYPE_INDEX, [LOAD_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX, [LOAD_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX, @@ -80,7 +87,7 @@ const uint8_t _PyOpcode_RecordFunctionIndices[256] = { [LOAD_ATTR_PROPERTY] = _RECORD_TOS_TYPE_INDEX, [STORE_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX, [STORE_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX, - [FOR_ITER_GEN] = _RECORD_NOS_INDEX, + [FOR_ITER_GEN] = _RECORD_NOS_GEN_FUNC_INDEX, [LOAD_ATTR_METHOD_WITH_VALUES] = _RECORD_TOS_TYPE_INDEX, [LOAD_ATTR_METHOD_NO_DICT] = _RECORD_TOS_TYPE_INDEX, [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = _RECORD_TOS_TYPE_INDEX, @@ -100,15 +107,13 @@ const uint8_t _PyOpcode_RecordFunctionIndices[256] = { [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = _RECORD_CALLABLE_INDEX, [CALL_METHOD_DESCRIPTOR_NOARGS] = _RECORD_CALLABLE_INDEX, [CALL_EX_PY] = _RECORD_4OS_INDEX, - [RETURN_GENERATOR] = _RECORD_CALLER_CODE_INDEX, }; -const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[8] = { +const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[7] = { [0] = NULL, [_RECORD_TOS_TYPE_INDEX] = _PyOpcode_RecordFunction_TOS_TYPE, - [_RECORD_TOS_INDEX] = _PyOpcode_RecordFunction_TOS, - [_RECORD_CALLER_CODE_INDEX] = _PyOpcode_RecordFunction_CALLER_CODE, [_RECORD_NOS_INDEX] = _PyOpcode_RecordFunction_NOS, + [_RECORD_NOS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_NOS_GEN_FUNC, [_RECORD_CALLABLE_INDEX] = _PyOpcode_RecordFunction_CALLABLE, [_RECORD_BOUND_METHOD_INDEX] = _PyOpcode_RecordFunction_BOUND_METHOD, [_RECORD_4OS_INDEX] = _PyOpcode_RecordFunction_4OS, From ffa68529b40210d4c55ad3a4114e48007ae0e55a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Feb 2026 11:32:56 +0100 Subject: [PATCH 002/498] gh-144330: Initialize classmethod and staticmethod in new (#144469) Move classmethod and staticmethod initialization from __init__() to __new__(). PyClassMethod_New() and PyStaticMethod_New() now copy attributes of the wrapped functions: __module__, __name__, __qualname__ and __doc__. Change static type initialization: initialize PyStaticMethod_Type and PyCFunction_Type earlier. Remove test_refleaks_in_classmethod___init__() and test_refleaks_in_staticmethod___init__() tests from test_descr since classmethod and staticmethod have no __init__() method anymore. --- Lib/test/test_descr.py | 32 ++--- ...-02-04-11-19-45.gh-issue-144330.kOowSb.rst | 2 + Objects/funcobject.c | 130 +++++++++++++----- Objects/object.c | 7 +- 4 files changed, 116 insertions(+), 55 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 0dc61ca7fb0da3..d6e3719479a214 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1727,6 +1727,18 @@ def annotated(cls) -> int: pass del method.__annotate__ self.assertIs(method.__annotate__, original_annotate) + def test_classmethod_without_dict_access(self): + class Spam: + @classmethod + def method(cls, x, y): + pass + + obj = Spam.__dict__['method'] + self.assertIsInstance(obj, classmethod) + self.assertEqual(obj.__annotations__, {}) + self.assertEqual(obj.__name__, 'method') + self.assertEqual(obj.__module__, __name__) + def test_staticmethod_annotations_without_dict_access(self): # gh-125017: this used to crash class Spam: @@ -1737,15 +1749,8 @@ def __new__(cls, x, y): obj = Spam.__dict__['__new__'] self.assertIsInstance(obj, staticmethod) self.assertEqual(obj.__annotations__, {}) - - @support.refcount_test - def test_refleaks_in_classmethod___init__(self): - gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') - cm = classmethod(None) - refs_before = gettotalrefcount() - for i in range(100): - cm.__init__(None) - self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) + self.assertEqual(obj.__name__, '__new__') + self.assertEqual(obj.__module__, __name__) @support.impl_detail("the module 'xxsubtype' is internal") @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") @@ -1822,15 +1827,6 @@ class D(C): del sm.x self.assertNotHasAttr(sm, "x") - @support.refcount_test - def test_refleaks_in_staticmethod___init__(self): - gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') - sm = staticmethod(None) - refs_before = gettotalrefcount() - for i in range(100): - sm.__init__(None) - self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) - @support.impl_detail("the module 'xxsubtype' is internal") @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_staticmethods_in_c(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst new file mode 100644 index 00000000000000..b3c61e162f4ffb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst @@ -0,0 +1,2 @@ +Move ``classmethod`` and ``staticmethod`` initialization from ``__init__()`` +to ``__new__()``. Patch by Victor Stinner. diff --git a/Objects/funcobject.c b/Objects/funcobject.c index b659ac8023373b..2bf21fa045e3f1 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -1466,33 +1466,59 @@ static PyObject * cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) { classmethod *cm = (classmethod *)self; - - if (cm->cm_callable == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "uninitialized classmethod object"); - return NULL; - } if (type == NULL) type = (PyObject *)(Py_TYPE(obj)); return PyMethod_New(cm->cm_callable, type); } static int -cm_init(PyObject *self, PyObject *args, PyObject *kwds) +cm_set_callable(classmethod *cm, PyObject *callable) { - classmethod *cm = (classmethod *)self; - PyObject *callable; + assert(callable != NULL); + if (cm->cm_callable == callable) { + // cm_init() sets the same callable than cm_new() + return 0; + } - if (!_PyArg_NoKeywords("classmethod", kwds)) - return -1; - if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) - return -1; Py_XSETREF(cm->cm_callable, Py_NewRef(callable)); + return functools_wraps((PyObject *)cm, cm->cm_callable); +} + +static PyObject * +cm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (!_PyArg_NoKeywords("classmethod", kwds)) { + return NULL; + } + PyObject *callable; // borrowed ref + if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) { + return NULL; + } - if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) { + classmethod *cm = (classmethod *)PyType_GenericAlloc(type, 0); + if (cm == NULL) { + return NULL; + } + if (cm_set_callable(cm, callable) < 0) { + Py_DECREF(cm); + return NULL; + } + return (PyObject *)cm; +} + +static int +cm_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + if (!_PyArg_NoKeywords("classmethod", kwds)) { return -1; } - return 0; + PyObject *callable; // borrowed ref + if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) { + return -1; + } + + classmethod *cm = (classmethod *)self; + return cm_set_callable(cm, callable); } static PyMemberDef cm_memberlist[] = { @@ -1623,7 +1649,7 @@ PyTypeObject PyClassMethod_Type = { offsetof(classmethod, cm_dict), /* tp_dictoffset */ cm_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ + cm_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; @@ -1632,8 +1658,12 @@ PyClassMethod_New(PyObject *callable) { classmethod *cm = (classmethod *) PyType_GenericAlloc(&PyClassMethod_Type, 0); - if (cm != NULL) { - cm->cm_callable = Py_NewRef(callable); + if (cm == NULL) { + return NULL; + } + if (cm_set_callable(cm, callable) < 0) { + Py_DECREF(cm); + return NULL; } return (PyObject *)cm; } @@ -1699,31 +1729,57 @@ static PyObject * sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) { staticmethod *sm = (staticmethod *)self; + return Py_NewRef(sm->sm_callable); +} - if (sm->sm_callable == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "uninitialized staticmethod object"); +static int +sm_set_callable(staticmethod *sm, PyObject *callable) +{ + assert(callable != NULL); + if (sm->sm_callable == callable) { + // sm_init() sets the same callable than sm_new() + return 0; + } + + Py_XSETREF(sm->sm_callable, Py_NewRef(callable)); + return functools_wraps((PyObject *)sm, sm->sm_callable); +} + +static PyObject * +sm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (!_PyArg_NoKeywords("staticmethod", kwds)) { return NULL; } - return Py_NewRef(sm->sm_callable); + PyObject *callable; // borrowed ref + if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) { + return NULL; + } + + staticmethod *sm = (staticmethod *)PyType_GenericAlloc(type, 0); + if (sm == NULL) { + return NULL; + } + if (sm_set_callable(sm, callable) < 0) { + Py_DECREF(sm); + return NULL; + } + return (PyObject *)sm; } static int sm_init(PyObject *self, PyObject *args, PyObject *kwds) { - staticmethod *sm = (staticmethod *)self; - PyObject *callable; - - if (!_PyArg_NoKeywords("staticmethod", kwds)) + if (!_PyArg_NoKeywords("staticmethod", kwds)) { return -1; - if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) - return -1; - Py_XSETREF(sm->sm_callable, Py_NewRef(callable)); - - if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) { + } + PyObject *callable; // borrowed ref + if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) { return -1; } - return 0; + + staticmethod *sm = (staticmethod *)self; + return sm_set_callable(sm, callable); } static PyObject* @@ -1858,7 +1914,7 @@ PyTypeObject PyStaticMethod_Type = { offsetof(staticmethod, sm_dict), /* tp_dictoffset */ sm_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ + sm_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; @@ -1867,8 +1923,12 @@ PyStaticMethod_New(PyObject *callable) { staticmethod *sm = (staticmethod *) PyType_GenericAlloc(&PyStaticMethod_Type, 0); - if (sm != NULL) { - sm->sm_callable = Py_NewRef(callable); + if (sm == NULL) { + return NULL; + } + if (sm_set_callable(sm, callable) < 0) { + Py_DECREF(sm); + return NULL; } return (PyObject *)sm; } diff --git a/Objects/object.c b/Objects/object.c index 649b109d5cb0bc..38717def24239f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2446,13 +2446,17 @@ static PyTypeObject* static_types[] = { &PyBaseObject_Type, &PyType_Type, + // PyStaticMethod_Type and PyCFunction_Type are used by PyType_Ready() + // on other types and so must be initialized first. + &PyStaticMethod_Type, + &PyCFunction_Type, + // Static types with base=&PyBaseObject_Type &PyAsyncGen_Type, &PyByteArrayIter_Type, &PyByteArray_Type, &PyBytesIter_Type, &PyBytes_Type, - &PyCFunction_Type, &PyCallIter_Type, &PyCapsule_Type, &PyCell_Type, @@ -2509,7 +2513,6 @@ static PyTypeObject* static_types[] = { &PySetIter_Type, &PySet_Type, &PySlice_Type, - &PyStaticMethod_Type, &PyStdPrinter_Type, &PySuper_Type, &PyTraceBack_Type, From d5cb9f6a9b6f48cc08c4422259498d4fd023357a Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 5 Feb 2026 12:58:18 +0000 Subject: [PATCH 003/498] gh-144363: Update bundled libexpat to 2.7.4 (#144365) * Update to 2.7.4 * update expat license copyright year to match and a pedantic #define * include COPYING update in refresh.sh * Update checksum for copying --------- Co-authored-by: Gregory P. Smith Co-authored-by: Petr Viktorin --- ...-01-31-17-15-49.gh-issue-144363.X9f0sU.rst | 1 + Misc/sbom.spdx.json | 40 +++---- Modules/expat/COPYING | 2 +- Modules/expat/expat.h | 4 +- Modules/expat/expat_config.h | 2 +- Modules/expat/expat_external.h | 5 +- Modules/expat/internal.h | 2 +- Modules/expat/refresh.sh | 9 +- Modules/expat/xmlparse.c | 110 ++++++++++-------- Modules/expat/xmlrole.c | 2 +- Modules/expat/xmltok.c | 2 +- Modules/expat/xmltok_ns.c | 5 +- 12 files changed, 98 insertions(+), 86 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst diff --git a/Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst b/Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst new file mode 100644 index 00000000000000..c17cea6613d06b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst @@ -0,0 +1 @@ +Update bundled `libexpat `_ to 2.7.4 diff --git a/Misc/sbom.spdx.json b/Misc/sbom.spdx.json index e9554bf78374a6..c79bbd2878271e 100644 --- a/Misc/sbom.spdx.json +++ b/Misc/sbom.spdx.json @@ -6,11 +6,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "39e6f567a10e36b2e77727e98e60bbcb3eb3af0b" + "checksumValue": "f1b1126ed7da8f2068302e7a692b0600e6f94b07" }, { "algorithm": "SHA256", - "checksumValue": "122f2c27000472a201d337b9b31f7eb2b52d091b02857061a8880371612d9534" + "checksumValue": "31b15de82aa19a845156169a17a5488bf597e561b2c318d159ed583139b25e87" } ], "fileName": "Modules/expat/COPYING" @@ -48,11 +48,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "a4395dd0589a97aab0904f7a5f5dc5781a086aa2" + "checksumValue": "9bd33bd279c0d7ea37b0f2d7e07c7c53b7053507" }, { "algorithm": "SHA256", - "checksumValue": "610b844bbfa3ec955772cc825db4d4db470827d57adcb214ad372d0eaf00e591" + "checksumValue": "d20997001462356b5ce3810ebf5256c8205f58462c64f21eb9bf80f8d1822b08" } ], "fileName": "Modules/expat/expat.h" @@ -62,11 +62,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "c22196e3d8bee88fcdda715623b3b9d2119d2fb3" + "checksumValue": "e658ee5d638ab326109282ff09f1541e27fff8c2" }, { "algorithm": "SHA256", - "checksumValue": "f2c2283ba03b057e92beefc7f81ba901ebb6dfc1a45b036c8a7d65808eb77a84" + "checksumValue": "dbe0582b8f8a8140aca97009e8760105ceed9e7df01ea9d8b3fe47cebf2e5b2d" } ], "fileName": "Modules/expat/expat_external.h" @@ -90,11 +90,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "7dce7d98943c5db33ae05e54801dcafb4547b9dd" + "checksumValue": "6a4a232233ba1034c3f2b459159d502e9b2d413b" }, { "algorithm": "SHA256", - "checksumValue": "6bfe307d52e7e4c71dbc30d3bd902a4905cdd83bbe4226a7e8dfa8e4c462a157" + "checksumValue": "c803935722f0dbdeeede7f040028fb119135e96dfad949479f8a5304b885bdd6" } ], "fileName": "Modules/expat/internal.h" @@ -174,11 +174,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "4c81a1f04fc653877c63c834145c18f93cd95f3e" + "checksumValue": "7d3d7d72aa56c53fb5b9e10c0e74e161381f0255" }, { "algorithm": "SHA256", - "checksumValue": "04a379615f476d55f95ca1853107e20627b48ca4afe8d0fd5981ac77188bf0a6" + "checksumValue": "f4f87aa0268d92f2b8f5e663788bfadd2e926477d0b061ed4463c02ad29a3e25" } ], "fileName": "Modules/expat/xmlparse.c" @@ -188,11 +188,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "ef767128d2dda99436712dcf3465dde5dbaab876" + "checksumValue": "c8769fcb93f00272a6e6ca560be633649c817ff7" }, { "algorithm": "SHA256", - "checksumValue": "71fb52aa302cf6f56e41943009965804f49ff2210d9bd15b258f70aaf70db772" + "checksumValue": "5b81f0eb0e144b611dbd1bc9e6037075a16bff94f823d57a81eb2a3e4999e91a" } ], "fileName": "Modules/expat/xmlrole.c" @@ -216,11 +216,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "1e2d35d90a1c269217f83d3bdf3c71cc22cb4c3f" + "checksumValue": "63e4766a09e63760c6518670509198f8d638f4ad" }, { "algorithm": "SHA256", - "checksumValue": "98d0fc735041956cc2e7bbbe2fb8f03130859410e0aee5e8015f406a37c02a3c" + "checksumValue": "0ad3f915f2748dc91bf4e4b4a50cf40bf2c95769d0eca7e3b293a230d82bb779" } ], "fileName": "Modules/expat/xmltok.c" @@ -272,11 +272,11 @@ "checksums": [ { "algorithm": "SHA1", - "checksumValue": "2d82d0a1201f78d478b30d108ff8fc27ee3e2672" + "checksumValue": "41b8c8fc275882c76d4210b7d40a18e506b07147" }, { "algorithm": "SHA256", - "checksumValue": "6ce6d03193279078d55280150fe91e7370370b504a6c123a79182f28341f3e90" + "checksumValue": "b2188c7e5fa5b33e355cf6cf342dfb8f6e23859f2a6b1ddf79841d7f84f7b196" } ], "fileName": "Modules/expat/xmltok_ns.c" @@ -1730,14 +1730,14 @@ "checksums": [ { "algorithm": "SHA256", - "checksumValue": "821ac9710d2c073eaf13e1b1895a9c9aa66c1157a99635c639fbff65cdbdd732" + "checksumValue": "461ecc8aa98ab1a68c2db788175665d1a4db640dc05bf0e289b6ea17122144ec" } ], - "downloadLocation": "https://github.com/libexpat/libexpat/releases/download/R_2_7_3/expat-2.7.3.tar.gz", + "downloadLocation": "https://github.com/libexpat/libexpat/releases/download/R_2_7_4/expat-2.7.4.tar.gz", "externalRefs": [ { "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:a:libexpat_project:libexpat:2.7.3:*:*:*:*:*:*:*", + "referenceLocator": "cpe:2.3:a:libexpat_project:libexpat:2.7.4:*:*:*:*:*:*:*", "referenceType": "cpe23Type" } ], @@ -1745,7 +1745,7 @@ "name": "expat", "originator": "Organization: Expat development team", "primaryPackagePurpose": "SOURCE", - "versionInfo": "2.7.3" + "versionInfo": "2.7.4" }, { "SPDXID": "SPDXRef-PACKAGE-hacl-star", diff --git a/Modules/expat/COPYING b/Modules/expat/COPYING index ce9e5939291e45..c6d184a8aae845 100644 --- a/Modules/expat/COPYING +++ b/Modules/expat/COPYING @@ -1,5 +1,5 @@ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001-2022 Expat maintainers +Copyright (c) 2001-2025 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 290dfeb0f6dd6a..6c7c4186927725 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -11,7 +11,7 @@ Copyright (c) 2000-2005 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2016-2025 Sebastian Pipping + Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2016 Cristian Rodríguez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James @@ -1082,7 +1082,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); */ # define XML_MAJOR_VERSION 2 # define XML_MINOR_VERSION 7 -# define XML_MICRO_VERSION 3 +# define XML_MICRO_VERSION 4 # ifdef __cplusplus } diff --git a/Modules/expat/expat_config.h b/Modules/expat/expat_config.h index e7d9499d9078d9..09d3161dbc0fb2 100644 --- a/Modules/expat/expat_config.h +++ b/Modules/expat/expat_config.h @@ -3,7 +3,7 @@ * distribution. */ #ifndef EXPAT_CONFIG_H -#define EXPAT_CONFIG_H +#define EXPAT_CONFIG_H 1 #include #ifdef WORDS_BIGENDIAN diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 0f01a05d0e9560..6f3f3c48ce9cff 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -12,7 +12,7 @@ Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2016 Cristian Rodríguez - Copyright (c) 2016-2019 Sebastian Pipping + Copyright (c) 2016-2025 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2018 Yury Gribov Licensed under the MIT license: @@ -91,8 +91,7 @@ # ifndef XML_BUILDING_EXPAT /* using Expat from an application */ -# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) \ - && ! defined(__CYGWIN__) +# if defined(_MSC_VER) && ! defined(__BEOS__) && ! defined(__CYGWIN__) # define XMLIMPORT __declspec(dllimport) # endif diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h index 8f5edf48ef7c00..61266ebb7723d1 100644 --- a/Modules/expat/internal.h +++ b/Modules/expat/internal.h @@ -128,7 +128,7 @@ # elif ULONG_MAX == 18446744073709551615u // 2^64-1 # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu" -# elif defined(EMSCRIPTEN) // 32bit mode Emscripten +# elif defined(__wasm32__) // 32bit mode Emscripten or WASI SDK # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "zu" # else diff --git a/Modules/expat/refresh.sh b/Modules/expat/refresh.sh index d1bf5d19afa007..550340467a15a7 100755 --- a/Modules/expat/refresh.sh +++ b/Modules/expat/refresh.sh @@ -12,9 +12,9 @@ fi # Update this when updating to a new version after verifying that the changes # the update brings in are good. These values are used for verifying the SBOM, too. -expected_libexpat_tag="R_2_7_3" -expected_libexpat_version="2.7.3" -expected_libexpat_sha256="821ac9710d2c073eaf13e1b1895a9c9aa66c1157a99635c639fbff65cdbdd732" +expected_libexpat_tag="R_2_7_4" +expected_libexpat_version="2.7.4" +expected_libexpat_sha256="461ecc8aa98ab1a68c2db788175665d1a4db640dc05bf0e289b6ea17122144ec" expat_dir="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")" cd ${expat_dir} @@ -24,6 +24,9 @@ curl --location "https://github.com/libexpat/libexpat/releases/download/${expect echo "${expected_libexpat_sha256} libexpat.tar.gz" | sha256sum --check # Step 2: Pull files from the libexpat distribution + +tar xzvf libexpat.tar.gz "expat-${expected_libexpat_version}/COPYING" --strip-components 2 + declare -a lib_files lib_files=( ascii.h diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index a187a3a18f1994..086fca59112ee1 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* 28bcd8b1ba7eb595d82822908257fd9c3589b4243e3c922d0369f35bfcd7b506 (2.7.3+) +/* fab937ab8b186d7d296013669c332e6dfce2f99567882cff1f8eb24223c524a7 (2.7.4+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -13,7 +13,7 @@ Copyright (c) 2002-2016 Karl Waclawek Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016 Eric Rahm - Copyright (c) 2016-2025 Sebastian Pipping + Copyright (c) 2016-2026 Sebastian Pipping Copyright (c) 2016 Gaurav Copyright (c) 2016 Thomas Beutlich Copyright (c) 2016 Gustavo Grieco @@ -42,6 +42,9 @@ Copyright (c) 2024-2025 Berkay Eren Ürün Copyright (c) 2024 Hanno Böck Copyright (c) 2025 Matthew Fernandez + Copyright (c) 2025 Atrem Borovik + Copyright (c) 2025 Alfonso Gregory + Copyright (c) 2026 Rosen Penev Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -101,7 +104,7 @@ #include /* INT_MAX, UINT_MAX */ #include /* fprintf */ #include /* getenv, rand_s */ -#include /* uintptr_t */ +#include /* SIZE_MAX, uintptr_t */ #include /* isnan */ #ifdef _WIN32 @@ -134,11 +137,6 @@ # endif /* defined(GRND_NONBLOCK) */ #endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ -#if defined(HAVE_LIBBSD) \ - && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) -# include -#endif - #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 #endif @@ -155,8 +153,6 @@ * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ * BSD / macOS >=10.7 / glibc >=2.36 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ * BSD / macOS (including <10.7) / glibc >=2.36 (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) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ @@ -311,8 +307,11 @@ typedef struct tag { const char *rawName; /* tagName in the original encoding */ int rawNameLength; TAG_NAME name; /* tagName in the API encoding */ - char *buf; /* buffer for name components */ - char *bufEnd; /* end of the buffer */ + union { + char *raw; /* for byte-level access (rawName storage) */ + XML_Char *str; /* for character-level access (converted name) */ + } buf; /* buffer for name components */ + char *bufEnd; /* end of the buffer */ BINDING *bindings; } TAG; @@ -349,7 +348,7 @@ typedef struct { typedef struct block { struct block *next; int size; - XML_Char s[1]; + XML_Char s[]; } BLOCK; typedef struct { @@ -1230,8 +1229,11 @@ generate_hash_secret_salt(XML_Parser parser) { # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ /* .. and self-made low quality for backup: */ + entropy = gather_time_entropy(); +# if ! defined(__wasi__) /* Process ID is 0 bits entropy if attacker has local access */ - entropy = gather_time_entropy() ^ getpid(); + entropy ^= getpid(); +# endif /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ if (sizeof(unsigned long) == 4) { @@ -1754,6 +1756,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, XML_ExternalEntityRefHandler oldExternalEntityRefHandler; XML_SkippedEntityHandler oldSkippedEntityHandler; XML_UnknownEncodingHandler oldUnknownEncodingHandler; + void *oldUnknownEncodingHandlerData; XML_ElementDeclHandler oldElementDeclHandler; XML_AttlistDeclHandler oldAttlistDeclHandler; XML_EntityDeclHandler oldEntityDeclHandler; @@ -1799,6 +1802,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; oldSkippedEntityHandler = parser->m_skippedEntityHandler; oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; + oldUnknownEncodingHandlerData = parser->m_unknownEncodingHandlerData; oldElementDeclHandler = parser->m_elementDeclHandler; oldAttlistDeclHandler = parser->m_attlistDeclHandler; oldEntityDeclHandler = parser->m_entityDeclHandler; @@ -1859,6 +1863,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; parser->m_skippedEntityHandler = oldSkippedEntityHandler; parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; + parser->m_unknownEncodingHandlerData = oldUnknownEncodingHandlerData; parser->m_elementDeclHandler = oldElementDeclHandler; parser->m_attlistDeclHandler = oldAttlistDeclHandler; parser->m_entityDeclHandler = oldEntityDeclHandler; @@ -1934,7 +1939,7 @@ XML_ParserFree(XML_Parser parser) { } p = tagList; tagList = tagList->parent; - FREE(parser, p->buf); + FREE(parser, p->buf.raw); destroyBindings(p->bindings, parser); FREE(parser, p); } @@ -2599,7 +2604,7 @@ XML_GetBuffer(XML_Parser parser, int len) { // NOTE: We are avoiding MALLOC(..) here to leave limiting // the input size to the application using Expat. newBuf = parser->m_mem.malloc_fcn(bufferSize); - if (newBuf == 0) { + if (newBuf == NULL) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return NULL; } @@ -3126,7 +3131,7 @@ storeRawNames(XML_Parser parser) { size_t bufSize; size_t nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); size_t rawNameLen; - char *rawNameBuf = tag->buf + nameLen; + char *rawNameBuf = tag->buf.raw + nameLen; /* Stop if already stored. Since m_tagStack is a stack, we can stop at the first entry that has already been copied; everything below it in the stack is already been accounted for in a @@ -3142,22 +3147,22 @@ storeRawNames(XML_Parser parser) { if (rawNameLen > (size_t)INT_MAX - nameLen) return XML_FALSE; bufSize = nameLen + rawNameLen; - if (bufSize > (size_t)(tag->bufEnd - tag->buf)) { - char *temp = REALLOC(parser, tag->buf, bufSize); + if (bufSize > (size_t)(tag->bufEnd - tag->buf.raw)) { + char *temp = REALLOC(parser, tag->buf.raw, bufSize); if (temp == NULL) return XML_FALSE; - /* if tag->name.str points to tag->buf (only when namespace + /* if tag->name.str points to tag->buf.str (only when namespace processing is off) then we have to update it */ - if (tag->name.str == (XML_Char *)tag->buf) + if (tag->name.str == tag->buf.str) tag->name.str = (XML_Char *)temp; /* if tag->name.localPart is set (when namespace processing is on) then update it as well, since it will always point into tag->buf */ if (tag->name.localPart) tag->name.localPart - = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); - tag->buf = temp; + = (XML_Char *)temp + (tag->name.localPart - tag->buf.str); + tag->buf.raw = temp; tag->bufEnd = temp + bufSize; rawNameBuf = temp + nameLen; } @@ -3472,12 +3477,12 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, tag = MALLOC(parser, sizeof(TAG)); if (! tag) return XML_ERROR_NO_MEMORY; - tag->buf = MALLOC(parser, INIT_TAG_BUF_SIZE); - if (! tag->buf) { + tag->buf.raw = MALLOC(parser, INIT_TAG_BUF_SIZE); + if (! tag->buf.raw) { FREE(parser, tag); return XML_ERROR_NO_MEMORY; } - tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; + tag->bufEnd = tag->buf.raw + INIT_TAG_BUF_SIZE; } tag->bindings = NULL; tag->parent = parser->m_tagStack; @@ -3490,31 +3495,32 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, { const char *rawNameEnd = tag->rawName + tag->rawNameLength; const char *fromPtr = tag->rawName; - toPtr = (XML_Char *)tag->buf; + toPtr = tag->buf.str; for (;;) { - int bufSize; int convLen; const enum XML_Convert_Result convert_res = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); - convLen = (int)(toPtr - (XML_Char *)tag->buf); + convLen = (int)(toPtr - tag->buf.str); if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; break; } - bufSize = (int)(tag->bufEnd - tag->buf) << 1; + if (SIZE_MAX / 2 < (size_t)(tag->bufEnd - tag->buf.raw)) + return XML_ERROR_NO_MEMORY; + const size_t bufSize = (size_t)(tag->bufEnd - tag->buf.raw) * 2; { - char *temp = REALLOC(parser, tag->buf, bufSize); + char *temp = REALLOC(parser, tag->buf.raw, bufSize); if (temp == NULL) return XML_ERROR_NO_MEMORY; - tag->buf = temp; + tag->buf.raw = temp; tag->bufEnd = temp + bufSize; toPtr = (XML_Char *)temp + convLen; } } } - tag->name.str = (XML_Char *)tag->buf; + tag->name.str = tag->buf.str; *toPtr = XML_T('\0'); result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account); @@ -3878,7 +3884,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { + if ((unsigned)parser->m_attsSize > SIZE_MAX / sizeof(ATTRIBUTE)) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } @@ -3897,7 +3903,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ # if UINT_MAX >= SIZE_MAX - if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { + if ((unsigned)parser->m_attsSize > SIZE_MAX / sizeof(XML_AttrInfo)) { parser->m_attsSize = oldAttsSize; return XML_ERROR_NO_MEMORY; } @@ -4073,7 +4079,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { + if (nsAttsSize > SIZE_MAX / sizeof(NS_ATT)) { /* Restore actual size of memory in m_nsAtts */ parser->m_nsAttsPower = oldNsAttsPower; return XML_ERROR_NO_MEMORY; @@ -4256,7 +4262,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + if ((unsigned)(n + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) { return XML_ERROR_NO_MEMORY; } #endif @@ -4502,7 +4508,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + if ((unsigned)(len + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) { return XML_ERROR_NO_MEMORY; } #endif @@ -4529,7 +4535,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + if ((unsigned)(len + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) { return XML_ERROR_NO_MEMORY; } #endif @@ -5920,15 +5926,18 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { + if (parser->m_groupSize > SIZE_MAX / sizeof(int)) { + parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; } #endif int *const new_scaff_index = REALLOC( parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); - if (new_scaff_index == NULL) + if (new_scaff_index == NULL) { + parser->m_groupSize /= 2; return XML_ERROR_NO_MEMORY; + } dtd->scaffIndex = new_scaff_index; } } else { @@ -7190,7 +7199,7 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { + if ((unsigned)count > SIZE_MAX / sizeof(DEFAULT_ATTRIBUTE)) { return 0; } #endif @@ -7666,8 +7675,7 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, * from -Wtype-limits on platforms where * sizeof(int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if ((size_t)oldE->nDefaultAtts - > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) { + if ((size_t)oldE->nDefaultAtts > SIZE_MAX / sizeof(DEFAULT_ATTRIBUTE)) { return 0; } #endif @@ -7869,7 +7877,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { unsigned long newMask = (unsigned long)newSize - 1; /* Detect and prevent integer overflow */ - if (newSize > (size_t)(-1) / sizeof(NAMED *)) { + if (newSize > SIZE_MAX / sizeof(NAMED *)) { return NULL; } @@ -8105,7 +8113,7 @@ poolBytesToAllocateFor(int blockSize) { static XML_Bool FASTCALL poolGrow(STRING_POOL *pool) { if (pool->freeBlocks) { - if (pool->start == 0) { + if (pool->start == NULL) { pool->blocks = pool->freeBlocks; pool->freeBlocks = pool->freeBlocks->next; pool->blocks->next = NULL; @@ -8217,7 +8225,7 @@ nextScaffoldPart(XML_Parser parser) { * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) { + if (parser->m_groupSize > SIZE_MAX / sizeof(int)) { return -1; } #endif @@ -8244,7 +8252,7 @@ nextScaffoldPart(XML_Parser parser) { * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { + if (dtd->scaffSize > SIZE_MAX / 2u / sizeof(CONTENT_SCAFFOLD)) { return -1; } #endif @@ -8294,15 +8302,15 @@ build_model(XML_Parser parser) { * from -Wtype-limits on platforms where * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ #if UINT_MAX >= SIZE_MAX - if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { + if (dtd->scaffCount > SIZE_MAX / sizeof(XML_Content)) { return NULL; } - if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { + if (dtd->contentStringLen > SIZE_MAX / sizeof(XML_Char)) { return NULL; } #endif if (dtd->scaffCount * sizeof(XML_Content) - > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { + > SIZE_MAX - dtd->contentStringLen * sizeof(XML_Char)) { return NULL; } diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 2c48bf40867953..d56bee82dd2d13 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -16,6 +16,7 @@ Copyright (c) 2017 Rhodri James Copyright (c) 2019 David Loffredo Copyright (c) 2021 Donghee Na + Copyright (c) 2025 Alfonso Gregory Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -46,7 +47,6 @@ # include "winconfig.h" #endif -#include "expat_external.h" #include "internal.h" #include "xmlrole.h" #include "ascii.h" diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 95d5e84b67f11c..32cd5f147e9322 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -24,6 +24,7 @@ Copyright (c) 2022 Martin Ettl Copyright (c) 2022 Sean McBride Copyright (c) 2023 Hanno Böck + Copyright (c) 2025 Alfonso Gregory Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -56,7 +57,6 @@ # include "winconfig.h" #endif -#include "expat_external.h" #include "internal.h" #include "xmltok.h" #include "nametab.h" diff --git a/Modules/expat/xmltok_ns.c b/Modules/expat/xmltok_ns.c index fbdd3e3c7b7999..810ca2c6d0485e 100644 --- a/Modules/expat/xmltok_ns.c +++ b/Modules/expat/xmltok_ns.c @@ -12,6 +12,7 @@ Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2017-2021 Sebastian Pipping + Copyright (c) 2025 Alfonso Gregory Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -98,13 +99,13 @@ NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { int i; XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); if (ptr != end) - return 0; + return NULL; *p = 0; if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) return enc; i = getEncodingIndex(buf); if (i == UNKNOWN_ENC) - return 0; + return NULL; return NS(encodings)[i]; } From 67ddba9aa9c0405c68e691643c4aa75fdbcefe1d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Feb 2026 16:32:17 +0200 Subject: [PATCH 004/498] gh-144148: Update the urllib.parse documentation (GH-144497) Document urlsplit() as the main parsing function and urlparse() as an obsolete variant. --- Doc/library/urllib.parse.rst | 216 +++++++++++++---------------------- Doc/library/venv.rst | 4 +- Doc/whatsnew/3.15.rst | 8 +- Lib/test/test_urlparse.py | 18 +-- Lib/urllib/parse.py | 24 ++-- 5 files changed, 109 insertions(+), 161 deletions(-) diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index ba6e46858f9d26..95b6c2bb4da026 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -50,11 +50,12 @@ URL Parsing The URL parsing functions focus on splitting a URL string into its components, or on combining URL components into a URL string. -.. function:: urlparse(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False) +.. function:: urlsplit(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False) - Parse a URL into six components, returning a 6-item :term:`named tuple`. This - corresponds to the general structure of a URL: - ``scheme://netloc/path;parameters?query#fragment``. + Parse a URL into five components, returning a 5-item :term:`named tuple` + :class:`SplitResult` or :class:`SplitResultBytes`. + This corresponds to the general structure of a URL: + ``scheme://netloc/path?query#fragment``. Each tuple item is a string, possibly empty, or ``None`` if *missing_as_none* is true. Not defined component are represented an empty string (by default) or @@ -68,15 +69,15 @@ or on combining URL components into a URL string. .. doctest:: :options: +NORMALIZE_WHITESPACE - >>> from urllib.parse import urlparse - >>> urlparse("scheme://netloc/path;parameters?query#fragment") - ParseResult(scheme='scheme', netloc='netloc', path='/path;parameters', params='', + >>> from urllib.parse import urlsplit + >>> urlsplit("scheme://netloc/path?query#fragment") + SplitResult(scheme='scheme', netloc='netloc', path='/path', query='query', fragment='fragment') - >>> o = urlparse("http://docs.python.org:80/3/library/urllib.parse.html?" + >>> o = urlsplit("http://docs.python.org:80/3/library/urllib.parse.html?" ... "highlight=params#url-parsing") >>> o - ParseResult(scheme='http', netloc='docs.python.org:80', - path='/3/library/urllib.parse.html', params='', + SplitResult(scheme='http', netloc='docs.python.org:80', + path='/3/library/urllib.parse.html', query='highlight=params', fragment='url-parsing') >>> o.scheme 'http' @@ -88,14 +89,14 @@ or on combining URL components into a URL string. 80 >>> o._replace(fragment="").geturl() 'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params' - >>> urlparse("http://docs.python.org?") - ParseResult(scheme='http', netloc='docs.python.org', - path='', params='', query='', fragment='') - >>> urlparse("http://docs.python.org?", missing_as_none=True) - ParseResult(scheme='http', netloc='docs.python.org', - path='', params=None, query='', fragment=None) - - Following the syntax specifications in :rfc:`1808`, urlparse recognizes + >>> urlsplit("http://docs.python.org?") + SplitResult(scheme='http', netloc='docs.python.org', path='', + query='', fragment='') + >>> urlsplit("http://docs.python.org?", missing_as_none=True) + SplitResult(scheme='http', netloc='docs.python.org', path='', + query='', fragment=None) + + Following the syntax specifications in :rfc:`1808`, :func:`!urlsplit` recognizes a netloc only if it is properly introduced by '//'. Otherwise the input is presumed to be a relative URL and thus to start with a path component. @@ -103,19 +104,19 @@ or on combining URL components into a URL string. .. doctest:: :options: +NORMALIZE_WHITESPACE - >>> from urllib.parse import urlparse - >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html') - ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', - params='', query='', fragment='') - >>> urlparse('www.cwi.nl/%7Eguido/Python.html') - ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html', - params='', query='', fragment='') - >>> urlparse('help/Python.html') - ParseResult(scheme='', netloc='', path='help/Python.html', - params='', query='', fragment='') - >>> urlparse('help/Python.html', missing_as_none=True) - ParseResult(scheme=None, netloc=None, path='help/Python.html', - params=None, query=None, fragment=None) + >>> from urllib.parse import urlsplit + >>> urlsplit('//www.cwi.nl:80/%7Eguido/Python.html') + SplitResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', + query='', fragment='') + >>> urlsplit('www.cwi.nl/%7Eguido/Python.html') + SplitResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html', + query='', fragment='') + >>> urlsplit('help/Python.html') + SplitResult(scheme='', netloc='', path='help/Python.html', + query='', fragment='') + >>> urlsplit('help/Python.html', missing_as_none=True) + SplitResult(scheme=None, netloc=None, path='help/Python.html', + query=None, fragment=None) The *scheme* argument gives the default addressing scheme, to be used only if the URL does not specify one. It should be the same type @@ -123,7 +124,7 @@ or on combining URL components into a URL string. always allowed, and is automatically converted to ``b''`` if appropriate. If the *allow_fragments* argument is false, fragment identifiers are not - recognized. Instead, they are parsed as part of the path, parameters + recognized. Instead, they are parsed as part of the path or query component, and :attr:`fragment` is set to ``None`` or the empty string (depending on the value of *missing_as_none*) in the return value. @@ -140,12 +141,9 @@ or on combining URL components into a URL string. +------------------+-------+-------------------------+-------------------------------+ | :attr:`path` | 2 | Hierarchical path | empty string | +------------------+-------+-------------------------+-------------------------------+ - | :attr:`params` | 3 | Parameters for last | ``None`` or empty string [1]_ | - | | | path element | | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`query` | 4 | Query component | ``None`` or empty string [1]_ | + | :attr:`query` | 3 | Query component | ``None`` or empty string [1]_ | +------------------+-------+-------------------------+-------------------------------+ - | :attr:`fragment` | 5 | Fragment identifier | ``None`` or empty string [1]_ | + | :attr:`fragment` | 4 | Fragment identifier | ``None`` or empty string [1]_ | +------------------+-------+-------------------------+-------------------------------+ | :attr:`username` | | User name | ``None`` | +------------------+-------+-------------------------+-------------------------------+ @@ -171,26 +169,30 @@ or on combining URL components into a URL string. ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is decomposed before parsing, no error will be raised. + Following some of the `WHATWG spec`_ that updates :rfc:`3986`, leading C0 + control and space characters are stripped from the URL. ``\n``, + ``\r`` and tab ``\t`` characters are removed from the URL at any position. + As is the case with all named tuples, the subclass has a few additional methods and attributes that are particularly useful. One such method is :meth:`_replace`. - The :meth:`_replace` method will return a new ParseResult object replacing specified - fields with new values. + The :meth:`_replace` method will return a new :class:`SplitResult` object + replacing specified fields with new values. .. doctest:: :options: +NORMALIZE_WHITESPACE - >>> from urllib.parse import urlparse - >>> u = urlparse('//www.cwi.nl:80/%7Eguido/Python.html') + >>> from urllib.parse import urlsplit + >>> u = urlsplit('//www.cwi.nl:80/%7Eguido/Python.html') >>> u - ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', - params='', query='', fragment='') + SplitResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', + query='', fragment='') >>> u._replace(scheme='http') - ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', - params='', query='', fragment='') + SplitResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', + query='', fragment='') .. warning:: - :func:`urlparse` does not perform validation. See :ref:`URL parsing + :func:`urlsplit` does not perform validation. See :ref:`URL parsing security ` for details. .. versionchanged:: 3.2 @@ -209,9 +211,17 @@ or on combining URL components into a URL string. Characters that affect netloc parsing under NFKC normalization will now raise :exc:`ValueError`. + .. versionchanged:: 3.10 + ASCII newline and tab characters are stripped from the URL. + + .. versionchanged:: 3.12 + Leading WHATWG C0 control and space characters are stripped from the URL. + .. versionchanged:: next Added the *missing_as_none* parameter. +.. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser + .. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&') @@ -306,11 +316,11 @@ or on combining URL components into a URL string. separator key, with ``&`` as the default separator. -.. function:: urlunparse(parts) - urlunparse(parts, *, keep_empty) +.. function:: urlunsplit(parts) + urlunsplit(parts, *, keep_empty) - Construct a URL from a tuple as returned by ``urlparse()``. The *parts* - argument can be any six-item iterable. + Construct a URL from a tuple as returned by :func:`urlsplit`. The *parts* + argument can be any five-item iterable. This may result in a slightly different, but equivalent URL, if the URL that was parsed originally had unnecessary delimiters (for example, @@ -321,97 +331,33 @@ or on combining URL components into a URL string. This allows rebuilding a URL that was parsed with option ``missing_as_none=True``. By default, *keep_empty* is true if *parts* is the result of the - :func:`urlparse` call with ``missing_as_none=True``. + :func:`urlsplit` call with ``missing_as_none=True``. .. versionchanged:: next Added the *keep_empty* parameter. -.. function:: urlsplit(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False) - - This is similar to :func:`urlparse`, but does not split the params from the URL. - This should generally be used instead of :func:`urlparse` if the more recent URL - syntax allowing parameters to be applied to each segment of the *path* portion - of the URL (see :rfc:`2396`) is wanted. A separate function is needed to - separate the path segments and parameters. This function returns a 5-item - :term:`named tuple`:: - - (addressing scheme, network location, path, query, fragment identifier). - - The return value is a :term:`named tuple`, its items can be accessed by index - or as named attributes: - - +------------------+-------+-------------------------+-------------------------------+ - | Attribute | Index | Value | Value if not present | - +==================+=======+=========================+===============================+ - | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter or | - | | | | empty string [1]_ | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`netloc` | 1 | Network location part | ``None`` or empty string [2]_ | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`path` | 2 | Hierarchical path | empty string | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`query` | 3 | Query component | ``None`` or empty string [2]_ | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`fragment` | 4 | Fragment identifier | ``None`` or empty string [2]_ | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`username` | | User name | ``None`` | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`password` | | Password | ``None`` | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`hostname` | | Host name (lower case) | ``None`` | - +------------------+-------+-------------------------+-------------------------------+ - | :attr:`port` | | Port number as integer, | ``None`` | - | | | if present | | - +------------------+-------+-------------------------+-------------------------------+ - - .. [2] Depending on the value of the *missing_as_none* argument. - - Reading the :attr:`port` attribute will raise a :exc:`ValueError` if - an invalid port is specified in the URL. See section - :ref:`urlparse-result-object` for more information on the result object. - - Unmatched square brackets in the :attr:`netloc` attribute will raise a - :exc:`ValueError`. - - Characters in the :attr:`netloc` attribute that decompose under NFKC - normalization (as used by the IDNA encoding) into any of ``/``, ``?``, - ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is - decomposed before parsing, no error will be raised. - - Following some of the `WHATWG spec`_ that updates RFC 3986, leading C0 - control and space characters are stripped from the URL. ``\n``, - ``\r`` and tab ``\t`` characters are removed from the URL at any position. - - .. warning:: - - :func:`urlsplit` does not perform validation. See :ref:`URL parsing - security ` for details. - - .. versionchanged:: 3.6 - Out-of-range port numbers now raise :exc:`ValueError`, instead of - returning ``None``. - - .. versionchanged:: 3.8 - Characters that affect netloc parsing under NFKC normalization will - now raise :exc:`ValueError`. - - .. versionchanged:: 3.10 - ASCII newline and tab characters are stripped from the URL. - - .. versionchanged:: 3.12 - Leading WHATWG C0 control and space characters are stripped from the URL. +.. function:: urlparse(urlstring, scheme=None, allow_fragments=True, *, missing_as_none=False) - .. versionchanged:: next - Added the *missing_as_none* parameter. + This is similar to :func:`urlsplit`, but additionally splits the *path* + component on *path* and *params*. + This function returns a 6-item :term:`named tuple` :class:`ParseResult` + or :class:`ParseResultBytes`. + Its items are the same as for the :func:`!urlsplit` result, except that + *params* is inserted at index 3, between *path* and *query*. -.. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser + This function is based on obsoleted :rfc:`1738` and :rfc:`1808`, which + listed *params* as the main URL component. + The more recent URL syntax allows parameters to be applied to each segment + of the *path* portion of the URL (see :rfc:`3986`). + :func:`urlsplit` should generally be used instead of :func:`urlparse`. + A separate function is needed to separate the path segments and parameters. -.. function:: urlunsplit(parts) - urlunsplit(parts, *, keep_empty) +.. function:: urlunparse(parts) + urlunparse(parts, *, keep_empty) - Combine the elements of a tuple as returned by :func:`urlsplit` into a - complete URL as a string. The *parts* argument can be any five-item + Combine the elements of a tuple as returned by :func:`urlparse` into a + complete URL as a string. The *parts* argument can be any six-item iterable. This may result in a slightly different, but equivalent URL, if the @@ -423,7 +369,7 @@ or on combining URL components into a URL string. This allows rebuilding a URL that was parsed with option ``missing_as_none=True``. By default, *keep_empty* is true if *parts* is the result of the - :func:`urlsplit` call with ``missing_as_none=True``. + :func:`urlparse` call with ``missing_as_none=True``. .. versionchanged:: next Added the *keep_empty* parameter. @@ -441,7 +387,7 @@ or on combining URL components into a URL string. 'http://www.cwi.nl/%7Eguido/FAQ.html' The *allow_fragments* argument has the same meaning and default as for - :func:`urlparse`. + :func:`urlsplit`. .. note:: @@ -587,7 +533,7 @@ individual URL quoting functions. Structured Parse Results ------------------------ -The result objects from the :func:`urlparse`, :func:`urlsplit` and +The result objects from the :func:`urlsplit`, :func:`urlparse` and :func:`urldefrag` functions are subclasses of the :class:`tuple` type. These subclasses add the attributes listed in the documentation for those functions, the encoding and decoding support described in the diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 4c000a92e87d0e..c75d7348343e16 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -550,7 +550,7 @@ subclass which installs setuptools and pip into a created virtual environment:: from subprocess import Popen, PIPE import sys from threading import Thread - from urllib.parse import urlparse + from urllib.parse import urlsplit from urllib.request import urlretrieve import venv @@ -621,7 +621,7 @@ subclass which installs setuptools and pip into a created virtual environment:: stream.close() def install_script(self, context, name, url): - _, _, path, _, _, _ = urlparse(url) + _, _, path, _, _ = urlsplit(url) fn = os.path.split(path)[-1] binpath = context.bin_path distpath = os.path.join(binpath, fn) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 2291228e721ffd..05cd7404066167 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -968,10 +968,10 @@ unittest urllib.parse ------------ -* Add the *missing_as_none* parameter to :func:`~urllib.parse.urlparse`, - :func:`~urllib.parse.urlsplit` and :func:`~urllib.parse.urldefrag` functions. - Add the *keep_empty* parameter to :func:`~urllib.parse.urlunparse` and - :func:`~urllib.parse.urlunsplit` functions. +* Add the *missing_as_none* parameter to :func:`~urllib.parse.urlsplit`, + :func:`~urllib.parse.urlparse` and :func:`~urllib.parse.urldefrag` functions. + Add the *keep_empty* parameter to :func:`~urllib.parse.urlunsplit` and + :func:`~urllib.parse.urlunparse` functions. This allows to distinguish between empty and not defined URI components and preserve empty components. (Contributed by Serhiy Storchaka in :gh:`67041`.) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 49a292df934bfc..8e4da0e0f09919 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1916,63 +1916,63 @@ def test_splittype_deprecation(self): urllib.parse.splittype('') self.assertEqual(str(cm.warning), 'urllib.parse.splittype() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splithost_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splithost('') self.assertEqual(str(cm.warning), 'urllib.parse.splithost() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splituser_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splituser('') self.assertEqual(str(cm.warning), 'urllib.parse.splituser() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splitpasswd_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splitpasswd('') self.assertEqual(str(cm.warning), 'urllib.parse.splitpasswd() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splitport_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splitport('') self.assertEqual(str(cm.warning), 'urllib.parse.splitport() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splitnport_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splitnport('') self.assertEqual(str(cm.warning), 'urllib.parse.splitnport() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splitquery_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splitquery('') self.assertEqual(str(cm.warning), 'urllib.parse.splitquery() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splittag_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splittag('') self.assertEqual(str(cm.warning), 'urllib.parse.splittag() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splitattr_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: urllib.parse.splitattr('') self.assertEqual(str(cm.warning), 'urllib.parse.splitattr() is deprecated as of 3.8, ' - 'use urllib.parse.urlparse() instead') + 'use urllib.parse.urlsplit() instead') def test_splitvalue_deprecation(self): with self.assertWarns(DeprecationWarning) as cm: diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index e917f8b61bbd9e..d64f678d235b6f 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -1,6 +1,6 @@ """Parse (absolute and relative) URLs. -urlparse module is based upon the following RFC specifications. +urllib.parse module is based upon the following RFC specifications. RFC 3986 (STD66): "Uniform Resource Identifiers" by T. Berners-Lee, R. Fielding and L. Masinter, January 2005. @@ -20,7 +20,7 @@ McCahill, December 1994 RFC 3986 is considered the current standard and any future changes to -urlparse module should conform with it. The urlparse module is +urllib.parse module should conform with it. The urllib.parse module is currently not entirely compliant with this RFC due to defacto scenarios for parsing, and for backward compatibility purposes, some parsing quirks from older RFCs are retained. The testcases in @@ -463,6 +463,8 @@ def urlparse(url, scheme=None, allow_fragments=True, *, missing_as_none=_MISSING path or query. Note that % escapes are not expanded. + + urlsplit() should generally be used instead of urlparse(). """ url, scheme, _coerce_result = _coerce_args(url, scheme) if url is None: @@ -1233,7 +1235,7 @@ def unwrap(url): def splittype(url): warnings.warn("urllib.parse.splittype() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splittype(url) @@ -1254,7 +1256,7 @@ def _splittype(url): def splithost(url): warnings.warn("urllib.parse.splithost() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splithost(url) @@ -1277,7 +1279,7 @@ def _splithost(url): def splituser(host): warnings.warn("urllib.parse.splituser() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splituser(host) @@ -1290,7 +1292,7 @@ def _splituser(host): def splitpasswd(user): warnings.warn("urllib.parse.splitpasswd() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splitpasswd(user) @@ -1303,7 +1305,7 @@ def _splitpasswd(user): def splitport(host): warnings.warn("urllib.parse.splitport() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splitport(host) @@ -1326,7 +1328,7 @@ def _splitport(host): def splitnport(host, defport=-1): warnings.warn("urllib.parse.splitnport() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splitnport(host, defport) @@ -1350,7 +1352,7 @@ def _splitnport(host, defport=-1): def splitquery(url): warnings.warn("urllib.parse.splitquery() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splitquery(url) @@ -1365,7 +1367,7 @@ def _splitquery(url): def splittag(url): warnings.warn("urllib.parse.splittag() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splittag(url) @@ -1380,7 +1382,7 @@ def _splittag(url): def splitattr(url): warnings.warn("urllib.parse.splitattr() is deprecated as of 3.8, " - "use urllib.parse.urlparse() instead", + "use urllib.parse.urlsplit() instead", DeprecationWarning, stacklevel=2) return _splitattr(url) From 7e777c587f01434ac5eea3d63d096f191278dad2 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Thu, 5 Feb 2026 09:43:39 -0600 Subject: [PATCH 005/498] gh-144484: Warn users not to use wsgiref in production --- Doc/library/wsgiref.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 381c993834753d..157d7058931c16 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -11,6 +11,11 @@ -------------- +.. warning:: + + :mod:`wsgiref` is a reference implementation and is not recommended for + production. The module only implements basic security checks. + The Web Server Gateway Interface (WSGI) is a standard interface between web server software and web applications written in Python. Having a standard interface makes it easy to use an application that supports WSGI with a number From d9a2e587fca4b4583dcea66d855b36b84320f98f Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Fri, 6 Feb 2026 01:45:14 +0800 Subject: [PATCH 006/498] gh-142407: Clarify copy performance on Windows in shutil docs (GH-142408) --- Doc/library/shutil.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 2c15fed8dd5e4d..ec3c8d600ad171 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -540,7 +540,9 @@ On Solaris :func:`os.sendfile` is used. On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB instead of 64 KiB) and a :func:`memoryview`-based variant of -:func:`shutil.copyfileobj` is used. +:func:`shutil.copyfileobj` is used, which is still reads and writes in a loop. +:func:`shutil.copy2` uses the native ``CopyFile2`` call on Windows, which is the most +efficient method, supports copy-on-write, and preserves metadata. If the fast-copy operation fails and no data was written in the destination file then shutil will silently fallback on using less efficient From 50e107f14996b55c60355fb901513e84cc2e589a Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Thu, 5 Feb 2026 12:04:12 -0600 Subject: [PATCH 007/498] More realistic lru_cache example (gh-144517) --- Doc/library/functools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 221c0712c7c96a..b7c34bc64135ba 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -180,8 +180,8 @@ The :mod:`functools` module defines the following functions: the *maxsize* at its default value of 128:: @lru_cache - def count_vowels(sentence): - return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou') + def count_vowels(word): + return sum(word.count(vowel) for vowel in 'AEIOUaeiou') If *maxsize* is set to ``None``, the LRU feature is disabled and the cache can grow without bound. From c81e1843d4bc0a51cf4f77d19b5ac4e49f714a0d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Feb 2026 20:06:33 +0200 Subject: [PATCH 008/498] gh-74955: Document that __all__ must contain strings in normalization form NFKC (GH-144504) --- Doc/reference/simple_stmts.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 643ca106548367..36b30c9b16b0db 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -831,7 +831,9 @@ where the :keyword:`import` statement occurs. The *public names* defined by a module are determined by checking the module's namespace for a variable named ``__all__``; if defined, it must be a sequence -of strings which are names defined or imported by that module. The names +of strings which are names defined or imported by that module. +Names containing non-ASCII characters must be in the `normalization form`_ +NFKC; see :ref:`lexical-names-nonascii` for details. The names given in ``__all__`` are all considered public and are required to exist. If ``__all__`` is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character @@ -865,6 +867,8 @@ determine dynamically the modules to be loaded. .. audit-event:: import module,filename,sys.path,sys.meta_path,sys.path_hooks import +.. _normalization form: https://www.unicode.org/reports/tr15/#Norm_Forms + .. _future: Future statements From 4644fed8190e4646663605f3e824f0767a0d026d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Feb 2026 21:14:49 +0200 Subject: [PATCH 009/498] gh-144001: Support ignoring the invalid pad character in Base64 decoding (GH-144306) --- Doc/library/base64.rst | 3 + Doc/library/binascii.rst | 3 + Lib/test/test_base64.py | 13 ++-- Lib/test/test_binascii.py | 126 ++++++++++++++++++++++++++------------ Modules/binascii.c | 34 +++++----- 5 files changed, 118 insertions(+), 61 deletions(-) diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 478686bc30035c..554d6e7d04ded2 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -87,6 +87,9 @@ POST request. If *ignorechars* is specified, it should be a :term:`bytes-like object` containing characters to ignore from the input when *validate* is true. + If *ignorechars* contains the pad character ``'='``, the pad characters + presented before the end of the encoded data and the excess pad characters + will be ignored. The default value of *validate* is ``True`` if *ignorechars* is specified, ``False`` otherwise. diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index d9f0baedec85f2..eb801175ee6179 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -56,6 +56,9 @@ The :mod:`binascii` module defines the following functions: If *ignorechars* is specified, it should be a :term:`bytes-like object` containing characters to ignore from the input when *strict_mode* is true. + If *ignorechars* contains the pad character ``'='``, the pad characters + presented before the end of the encoded data and the excess pad characters + will be ignored. The default value of *strict_mode* is ``True`` if *ignorechars* is specified, ``False`` otherwise. diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 0f947409f0694b..fef18a1b757c08 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -306,7 +306,7 @@ def test_b64decode_invalid_chars(self): # issue 1466065: Test some invalid characters. tests = ((b'%3d==', b'\xdd', b'%$'), (b'$3d==', b'\xdd', b'%$'), - (b'[==', b'', None), + (b'[==', b'', b'[='), (b'YW]3=', b'am', b']'), (b'3{d==', b'\xdd', b'{}'), (b'3d}==', b'\xdd', b'{}'), @@ -314,6 +314,12 @@ def test_b64decode_invalid_chars(self): (b'!', b'', b'@!'), (b"YWJj\n", b"abc", b'\n'), (b'YWJj\nYWI=', b'abcab', b'\n'), + (b'=YWJj', b'abc', b'='), + (b'Y=WJj', b'abc', b'='), + (b'Y==WJj', b'abc', b'='), + (b'Y===WJj', b'abc', b'='), + (b'YW=Jj', b'abc', b'='), + (b'YWJj=', b'abc', b'='), (b'YW\nJj', b'abc', b'\n'), (b'YW\nJj', b'abc', bytearray(b'\n')), (b'YW\nJj', b'abc', memoryview(b'\n')), @@ -335,9 +341,8 @@ def test_b64decode_invalid_chars(self): with self.assertRaises(binascii.Error): # Even empty ignorechars enables the strict mode. base64.b64decode(bstr, ignorechars=b'') - if ignorechars is not None: - r = base64.b64decode(bstr, ignorechars=ignorechars) - self.assertEqual(r, res) + r = base64.b64decode(bstr, ignorechars=ignorechars) + self.assertEqual(r, res) with self.assertRaises(TypeError): base64.b64decode(b'', ignorechars='') diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 49accb08b62e40..a4928794e0acfb 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -118,66 +118,78 @@ def addnoise(line): # empty strings. TBD: shouldn't it raise an exception instead ? self.assertEqual(binascii.a2b_base64(self.type2test(fillers)), b'') - def test_base64_strict_mode(self): - # Test base64 with strict mode on - def _assertRegexTemplate(assert_regex: str, data: bytes, non_strict_mode_expected_result: bytes): + def test_base64_bad_padding(self): + # Test malformed padding + def _assertRegexTemplate(assert_regex, data, + non_strict_mode_expected_result): + data = self.type2test(data) with self.assertRaisesRegex(binascii.Error, assert_regex): - binascii.a2b_base64(self.type2test(data), strict_mode=True) - self.assertEqual(binascii.a2b_base64(self.type2test(data), strict_mode=False), + binascii.a2b_base64(data, strict_mode=True) + self.assertEqual(binascii.a2b_base64(data, strict_mode=False), non_strict_mode_expected_result) - self.assertEqual(binascii.a2b_base64(self.type2test(data)), + self.assertEqual(binascii.a2b_base64(data, strict_mode=True, + ignorechars=b'='), + non_strict_mode_expected_result) + self.assertEqual(binascii.a2b_base64(data), non_strict_mode_expected_result) - def assertExcessData(data, non_strict_mode_expected_result: bytes): - _assertRegexTemplate(r'(?i)Excess data', data, non_strict_mode_expected_result) - - def assertNonBase64Data(data, non_strict_mode_expected_result: bytes): - _assertRegexTemplate(r'(?i)Only base64 data', data, non_strict_mode_expected_result) + def assertLeadingPadding(*args): + _assertRegexTemplate(r'(?i)Leading padding', *args) - def assertLeadingPadding(data, non_strict_mode_expected_result: bytes): - _assertRegexTemplate(r'(?i)Leading padding', data, non_strict_mode_expected_result) + def assertDiscontinuousPadding(*args): + _assertRegexTemplate(r'(?i)Discontinuous padding', *args) - def assertDiscontinuousPadding(data, non_strict_mode_expected_result: bytes): - _assertRegexTemplate(r'(?i)Discontinuous padding', data, non_strict_mode_expected_result) + def assertExcessPadding(*args): + _assertRegexTemplate(r'(?i)Excess padding', *args) - def assertExcessPadding(data, non_strict_mode_expected_result: bytes): - _assertRegexTemplate(r'(?i)Excess padding', data, non_strict_mode_expected_result) + def assertInvalidLength(*args): + _assertRegexTemplate(r'(?i)Invalid.+number of data characters', *args) - # Test excess data exceptions - assertExcessData(b'ab==a', b'i') assertExcessPadding(b'ab===', b'i') assertExcessPadding(b'ab====', b'i') - assertNonBase64Data(b'ab==:', b'i') - assertExcessData(b'abc=a', b'i\xb7') - assertNonBase64Data(b'abc=:', b'i\xb7') - assertNonBase64Data(b'ab==\n', b'i') assertExcessPadding(b'abc==', b'i\xb7') assertExcessPadding(b'abc===', b'i\xb7') assertExcessPadding(b'abc====', b'i\xb7') assertExcessPadding(b'abc=====', b'i\xb7') - # Test non-base64 data exceptions - assertNonBase64Data(b'\nab==', b'i') - assertNonBase64Data(b'ab:(){:|:&};:==', b'i') - assertNonBase64Data(b'a\nb==', b'i') - assertNonBase64Data(b'a\x00b==', b'i') - - # Test malformed padding assertLeadingPadding(b'=', b'') assertLeadingPadding(b'==', b'') assertLeadingPadding(b'===', b'') assertLeadingPadding(b'====', b'') assertLeadingPadding(b'=====', b'') + assertLeadingPadding(b'=abcd', b'i\xb7\x1d') + assertLeadingPadding(b'==abcd', b'i\xb7\x1d') + assertLeadingPadding(b'===abcd', b'i\xb7\x1d') + assertLeadingPadding(b'====abcd', b'i\xb7\x1d') + assertLeadingPadding(b'=====abcd', b'i\xb7\x1d') + + assertInvalidLength(b'a=b==', b'i') + assertInvalidLength(b'a=bc=', b'i\xb7') + assertInvalidLength(b'a=bc==', b'i\xb7') + assertInvalidLength(b'a=bcd', b'i\xb7\x1d') + assertInvalidLength(b'a=bcd=', b'i\xb7\x1d') + assertDiscontinuousPadding(b'ab=c=', b'i\xb7') - assertDiscontinuousPadding(b'ab=ab==', b'i\xb6\x9b') - assertNonBase64Data(b'ab=:=', b'i') + assertDiscontinuousPadding(b'ab=cd', b'i\xb7\x1d') + assertDiscontinuousPadding(b'ab=cd==', b'i\xb7\x1d') + assertExcessPadding(b'abcd=', b'i\xb7\x1d') assertExcessPadding(b'abcd==', b'i\xb7\x1d') assertExcessPadding(b'abcd===', b'i\xb7\x1d') assertExcessPadding(b'abcd====', b'i\xb7\x1d') assertExcessPadding(b'abcd=====', b'i\xb7\x1d') + assertExcessPadding(b'abcd==', b'i\xb7\x1d') + assertExcessPadding(b'abcd===', b'i\xb7\x1d') + assertExcessPadding(b'abcd====', b'i\xb7\x1d') + assertExcessPadding(b'abcd=====', b'i\xb7\x1d') + assertExcessPadding(b'abcd=efgh', b'i\xb7\x1dy\xf8!') + assertExcessPadding(b'abcd==efgh', b'i\xb7\x1dy\xf8!') + assertExcessPadding(b'abcd===efgh', b'i\xb7\x1dy\xf8!') + assertExcessPadding(b'abcd====efgh', b'i\xb7\x1dy\xf8!') + assertExcessPadding(b'abcd=====efgh', b'i\xb7\x1dy\xf8!') def test_base64_invalidchars(self): + # Test non-base64 data exceptions def assertNonBase64Data(data, expected, ignorechars): data = self.type2test(data) assert_regex = r'(?i)Only base64 data' @@ -195,10 +207,11 @@ def assertNonBase64Data(data, expected, ignorechars): assertNonBase64Data(b'ab:(){:|:&};:==', b'i', ignorechars=b':;(){}|&') assertNonBase64Data(b'a\nb==', b'i', ignorechars=b'\n') assertNonBase64Data(b'a\x00b==', b'i', ignorechars=b'\x00') + assertNonBase64Data(b'ab:==', b'i', ignorechars=b':') + assertNonBase64Data(b'ab=:=', b'i', ignorechars=b':') assertNonBase64Data(b'ab==:', b'i', ignorechars=b':') assertNonBase64Data(b'abc=:', b'i\xb7', ignorechars=b':') assertNonBase64Data(b'ab==\n', b'i', ignorechars=b'\n') - assertNonBase64Data(b'ab=:=', b'i', ignorechars=b':') assertNonBase64Data(b'a\nb==', b'i', ignorechars=bytearray(b'\n')) assertNonBase64Data(b'a\nb==', b'i', ignorechars=memoryview(b'\n')) @@ -221,11 +234,37 @@ def assertNonBase64Data(data, expected, ignorechars): with self.assertRaises(TypeError): binascii.a2b_base64(data, ignorechars=None) + def test_base64_excess_data(self): + # Test excess data exceptions + def assertExcessData(data, non_strict_expected, + ignore_padchar_expected=None): + assert_regex = r'(?i)Excess data' + data = self.type2test(data) + with self.assertRaisesRegex(binascii.Error, assert_regex): + binascii.a2b_base64(data, strict_mode=True) + self.assertEqual(binascii.a2b_base64(data, strict_mode=False), + non_strict_expected) + if ignore_padchar_expected is not None: + self.assertEqual(binascii.a2b_base64(data, strict_mode=True, + ignorechars=b'='), + ignore_padchar_expected) + self.assertEqual(binascii.a2b_base64(data), non_strict_expected) + + assertExcessData(b'ab==c', b'i') + assertExcessData(b'ab==cd', b'i', b'i\xb7\x1d') + assertExcessData(b'abc=d', b'i\xb7', b'i\xb7\x1d') + def test_base64errors(self): # Test base64 with invalid padding - def assertIncorrectPadding(data): + def assertIncorrectPadding(data, strict_mode=True): + data = self.type2test(data) with self.assertRaisesRegex(binascii.Error, r'(?i)Incorrect padding'): - binascii.a2b_base64(self.type2test(data)) + binascii.a2b_base64(data) + with self.assertRaisesRegex(binascii.Error, r'(?i)Incorrect padding'): + binascii.a2b_base64(data, strict_mode=False) + if strict_mode: + with self.assertRaisesRegex(binascii.Error, r'(?i)Incorrect padding'): + binascii.a2b_base64(data, strict_mode=True) assertIncorrectPadding(b'ab') assertIncorrectPadding(b'ab=') @@ -233,16 +272,22 @@ def assertIncorrectPadding(data): assertIncorrectPadding(b'abcdef') assertIncorrectPadding(b'abcdef=') assertIncorrectPadding(b'abcdefg') - assertIncorrectPadding(b'a=b=') - assertIncorrectPadding(b'a\nb=') + assertIncorrectPadding(b'a=b=', strict_mode=False) + assertIncorrectPadding(b'a\nb=', strict_mode=False) # Test base64 with invalid number of valid characters (1 mod 4) - def assertInvalidLength(data): + def assertInvalidLength(data, strict_mode=True): n_data_chars = len(re.sub(br'[^A-Za-z0-9/+]', br'', data)) + data = self.type2test(data) expected_errmsg_re = \ r'(?i)Invalid.+number of data characters.+' + str(n_data_chars) with self.assertRaisesRegex(binascii.Error, expected_errmsg_re): - binascii.a2b_base64(self.type2test(data)) + binascii.a2b_base64(data) + with self.assertRaisesRegex(binascii.Error, expected_errmsg_re): + binascii.a2b_base64(data, strict_mode=False) + if strict_mode: + with self.assertRaisesRegex(binascii.Error, expected_errmsg_re): + binascii.a2b_base64(data, strict_mode=True) assertInvalidLength(b'a') assertInvalidLength(b'a=') @@ -250,7 +295,8 @@ def assertInvalidLength(data): assertInvalidLength(b'a===') assertInvalidLength(b'a' * 5) assertInvalidLength(b'a' * (4 * 87 + 1)) - assertInvalidLength(b'A\tB\nC ??DE') # only 5 valid characters + assertInvalidLength(b'A\tB\nC ??DE', # only 5 valid characters + strict_mode=False) def test_uu(self): MAX_UU = 45 diff --git a/Modules/binascii.c b/Modules/binascii.c index 201e7798bb7a8c..6d3d4e1a6d6daa 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -564,26 +564,24 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode, pads++; if (strict_mode) { - if (quad_pos == 0) { - state = get_binascii_state(module); - if (state) { - PyErr_SetString(state->Error, (ascii_data == data->buf) - ? "Leading padding not allowed" - : "Excess padding not allowed"); - } - goto error_end; + if (quad_pos >= 2 && quad_pos + pads <= 4) { + continue; + } + if (ignorechar(BASE64_PAD, ignorechars, ignorecache)) { + continue; } if (quad_pos == 1) { /* Set an error below. */ break; } - if (quad_pos + pads > 4) { - state = get_binascii_state(module); - if (state) { - PyErr_SetString(state->Error, "Excess padding not allowed"); - } - goto error_end; + state = get_binascii_state(module); + if (state) { + PyErr_SetString(state->Error, + (quad_pos == 0 && ascii_data == data->buf) + ? "Leading padding not allowed" + : "Excess padding not allowed"); } + goto error_end; } else { if (quad_pos >= 2 && quad_pos + pads >= 4) { @@ -592,8 +590,8 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode, */ goto done; } + continue; } - continue; } unsigned char v = table_a2b_base64[this_ch]; @@ -609,7 +607,9 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode, } // Characters that are not '=', in the middle of the padding, are not allowed - if (strict_mode && pads) { + if (pads && strict_mode && + !ignorechar(BASE64_PAD, ignorechars, ignorecache)) + { state = get_binascii_state(module); if (state) { PyErr_SetString(state->Error, (quad_pos + pads == 4) @@ -662,7 +662,7 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode, goto error_end; } - if (quad_pos != 0 && quad_pos + pads != 4) { + if (quad_pos != 0 && quad_pos + pads < 4) { state = get_binascii_state(module); if (state) { PyErr_SetString(state->Error, "Incorrect padding"); From 01a1dd283b2d39af822f38f005233d1f5cadc927 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 5 Feb 2026 11:50:51 -0800 Subject: [PATCH 010/498] gh-77188: Add support for pickling private methods and nested classes (GH-21480) Co-authored-by: Serhiy Storchaka --- Doc/whatsnew/3.15.rst | 7 +++ Include/internal/pycore_symtable.h | 7 ++- Lib/pickle.py | 11 +++++ Lib/test/picklecommon.py | 45 +++++++++++++++++++ Lib/test/pickletester.py | 27 +++++++++++ ...0-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst | 1 + Modules/_pickle.c | 41 +++++++++++++++++ Objects/classobject.c | 15 +++++++ Python/symtable.c | 21 +++++++++ 9 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 05cd7404066167..20250003dca34e 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -704,6 +704,13 @@ os.path (Contributed by Petr Viktorin for :cve:`2025-4517`.) +pickle +------ + +* Add support for pickling private methods and nested classes. + (Contributed by Zackery Spytz and Serhiy Storchaka in :gh:`77188`.) + + resource -------- diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index 9dbfa913219afa..c0164507ea033e 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -151,7 +151,12 @@ extern int _PySymtable_LookupOptional(struct symtable *, void *, PySTEntryObject extern void _PySymtable_Free(struct symtable *); extern PyObject *_Py_MaybeMangle(PyObject *privateobj, PySTEntryObject *ste, PyObject *name); -extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); + +// Export for '_pickle' shared extension +PyAPI_FUNC(PyObject *) +_Py_Mangle(PyObject *, PyObject *); +PyAPI_FUNC(int) +_Py_IsPrivateName(PyObject *); /* Flags for def-use information */ diff --git a/Lib/pickle.py b/Lib/pickle.py index 71c12c50f7f035..3e7cf25cb05337 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1175,6 +1175,17 @@ def save_global(self, obj, name=None): if name is None: name = obj.__name__ + if '.__' in name: + # Mangle names of private attributes. + dotted_path = name.split('.') + for i, subpath in enumerate(dotted_path): + if i and subpath.startswith('__') and not subpath.endswith('__'): + prev = prev.lstrip('_') + if prev: + dotted_path[i] = f"_{prev.lstrip('_')}{subpath}" + prev = subpath + name = '.'.join(dotted_path) + module_name = whichmodule(obj, name) if self.proto >= 2: code = _extension_registry.get((module_name, name), _NoValue) diff --git a/Lib/test/picklecommon.py b/Lib/test/picklecommon.py index 4c19b6c421fc61..b749ee09f564bf 100644 --- a/Lib/test/picklecommon.py +++ b/Lib/test/picklecommon.py @@ -388,3 +388,48 @@ def pie(self): class Subclass(tuple): class Nested(str): pass + +# For test_private_methods +class PrivateMethods: + def __init__(self, value): + self.value = value + + def __private_method(self): + return self.value + + def get_method(self): + return self.__private_method + + @classmethod + def get_unbound_method(cls): + return cls.__private_method + + @classmethod + def __private_classmethod(cls): + return 43 + + @classmethod + def get_classmethod(cls): + return cls.__private_classmethod + + @staticmethod + def __private_staticmethod(): + return 44 + + @classmethod + def get_staticmethod(cls): + return cls.__private_staticmethod + +# For test_private_nested_classes +class PrivateNestedClasses: + @classmethod + def get_nested(cls): + return cls.__Nested + + class __Nested: + @classmethod + def get_nested2(cls): + return cls.__Nested2 + + class __Nested2: + pass diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index d2b8d036bfd9e7..7b1b117d6d3e32 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -4118,6 +4118,33 @@ def test_c_methods(self): with self.subTest(proto=proto, descr=descr): self.assertRaises(TypeError, self.dumps, descr, proto) + def test_private_methods(self): + if self.py_version < (3, 15): + self.skipTest('not supported in Python < 3.15') + obj = PrivateMethods(42) + for proto in protocols: + with self.subTest(proto=proto): + unpickled = self.loads(self.dumps(obj.get_method(), proto)) + self.assertEqual(unpickled(), 42) + unpickled = self.loads(self.dumps(obj.get_unbound_method(), proto)) + self.assertEqual(unpickled(obj), 42) + unpickled = self.loads(self.dumps(obj.get_classmethod(), proto)) + self.assertEqual(unpickled(), 43) + unpickled = self.loads(self.dumps(obj.get_staticmethod(), proto)) + self.assertEqual(unpickled(), 44) + + def test_private_nested_classes(self): + if self.py_version < (3, 15): + self.skipTest('not supported in Python < 3.15') + cls1 = PrivateNestedClasses.get_nested() + cls2 = cls1.get_nested2() + for proto in protocols: + with self.subTest(proto=proto): + unpickled = self.loads(self.dumps(cls1, proto)) + self.assertIs(unpickled, cls1) + unpickled = self.loads(self.dumps(cls2, proto)) + self.assertIs(unpickled, cls2) + def test_object_with_attrs(self): obj = Object() obj.a = 1 diff --git a/Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst b/Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst new file mode 100644 index 00000000000000..3e956409d52a58 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst @@ -0,0 +1 @@ +The :mod:`pickle` module now properly handles name-mangled private methods. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 063547c9a4d020..a897e45f00fab6 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -19,6 +19,7 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_runtime.h" // _Py_ID() #include "pycore_setobject.h" // _PySet_NextEntry() +#include "pycore_symtable.h" // _Py_Mangle() #include "pycore_sysmodule.h" // _PySys_GetSizeOf() #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString() @@ -1928,6 +1929,37 @@ get_dotted_path(PyObject *name) return PyUnicode_Split(name, _Py_LATIN1_CHR('.'), -1); } +static PyObject * +join_dotted_path(PyObject *dotted_path) +{ + return PyUnicode_Join(_Py_LATIN1_CHR('.'), dotted_path); +} + +/* Returns -1 (with an exception set) on error, 0 if there were no changes, + * 1 if some names were mangled. */ +static int +mangle_dotted_path(PyObject *dotted_path) +{ + int rc = 0; + Py_ssize_t n = PyList_GET_SIZE(dotted_path); + for (Py_ssize_t i = n-1; i > 0; i--) { + PyObject *subpath = PyList_GET_ITEM(dotted_path, i); + if (_Py_IsPrivateName(subpath)) { + PyObject *parent = PyList_GET_ITEM(dotted_path, i-1); + PyObject *mangled = _Py_Mangle(parent, subpath); + if (mangled == NULL) { + return -1; + } + if (mangled != subpath) { + rc = 1; + } + PyList_SET_ITEM(dotted_path, i, mangled); + Py_DECREF(subpath); + } + } + return rc; +} + static int check_dotted_path(PickleState *st, PyObject *obj, PyObject *dotted_path) { @@ -3809,6 +3841,15 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj, dotted_path = get_dotted_path(global_name); if (dotted_path == NULL) goto error; + switch (mangle_dotted_path(dotted_path)) { + case -1: + goto error; + case 1: + Py_SETREF(global_name, join_dotted_path(dotted_path)); + if (global_name == NULL) { + goto error; + } + } module_name = whichmodule(st, obj, global_name, dotted_path); if (module_name == NULL) goto error; diff --git a/Objects/classobject.c b/Objects/classobject.c index e71f301f2efd77..4c99c194df53a5 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -7,6 +7,7 @@ #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_symtable.h" // _Py_Mangle() #include "pycore_weakref.h" // FT_CLEAR_WEAKREFS() @@ -143,6 +144,20 @@ method___reduce___impl(PyMethodObject *self) if (funcname == NULL) { return NULL; } + if (_Py_IsPrivateName(funcname)) { + PyObject *classname = PyType_Check(funcself) + ? PyType_GetName((PyTypeObject *)funcself) + : PyType_GetName(Py_TYPE(funcself)); + if (classname == NULL) { + Py_DECREF(funcname); + return NULL; + } + Py_SETREF(funcname, _Py_Mangle(classname, funcname)); + Py_DECREF(classname); + if (funcname == NULL) { + return NULL; + } + } return Py_BuildValue( "N(ON)", _PyEval_GetBuiltin(&_Py_ID(getattr)), funcself, funcname); } diff --git a/Python/symtable.c b/Python/symtable.c index 29cf9190a4e95b..29ac8f6880c575 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -3183,6 +3183,27 @@ _Py_MaybeMangle(PyObject *privateobj, PySTEntryObject *ste, PyObject *name) return _Py_Mangle(privateobj, name); } +int +_Py_IsPrivateName(PyObject *ident) +{ + if (!PyUnicode_Check(ident)) { + return 0; + } + Py_ssize_t nlen = PyUnicode_GET_LENGTH(ident); + if (nlen < 3 || + PyUnicode_READ_CHAR(ident, 0) != '_' || + PyUnicode_READ_CHAR(ident, 1) != '_') + { + return 0; + } + if (PyUnicode_READ_CHAR(ident, nlen-1) == '_' && + PyUnicode_READ_CHAR(ident, nlen-2) == '_') + { + return 0; /* Don't mangle __whatever__ */ + } + return 1; +} + PyObject * _Py_Mangle(PyObject *privateobj, PyObject *ident) { From 957f9fe162398fceeaa9ddba8b40046b8a03176d Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Thu, 5 Feb 2026 14:37:05 -0600 Subject: [PATCH 011/498] gh-74453: Deprecate os.path.commonprefix (#144436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Doc/deprecations/pending-removal-in-future.rst | 8 ++++++++ Doc/library/os.path.rst | 8 ++++++++ Lib/genericpath.py | 9 +++++++++ Lib/posixpath.py | 2 +- Lib/test/test_genericpath.py | 9 +++++++-- Lib/test/test_ntpath.py | 5 +++++ Lib/unittest/util.py | 13 +++++++++++-- .../2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst | 8 ++++++++ 8 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst diff --git a/Doc/deprecations/pending-removal-in-future.rst b/Doc/deprecations/pending-removal-in-future.rst index 301867416701ea..a54f98d6866e9f 100644 --- a/Doc/deprecations/pending-removal-in-future.rst +++ b/Doc/deprecations/pending-removal-in-future.rst @@ -78,6 +78,14 @@ although there is currently no date scheduled for their removal. * :mod:`os`: Calling :func:`os.register_at_fork` in a multi-threaded process. +* :mod:`os.path`: :func:`os.path.commonprefix` is deprecated, use + :func:`os.path.commonpath` for path prefixes. The :func:`os.path.commonprefix` + function is being deprecated due to having a misleading name and module. + The function is not safe to use for path prefixes despite being included in a + module about path manipulation, meaning it is easy to accidentally + introduce path traversal vulnerabilities into Python programs by using this + function. + * :class:`!pydoc.ErrorDuringImport`: A tuple value for *exc_info* parameter is deprecated, use an exception instance. diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index bfd59fc5a82049..409fcf4adb754b 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -120,6 +120,14 @@ the :mod:`glob` module.) .. versionchanged:: 3.6 Accepts a :term:`path-like object`. + .. deprecated:: next + Deprecated in favor of :func:`os.path.commonpath` for path prefixes. + The :func:`os.path.commonprefix` function is being deprecated due to + having a misleading name and module. The function is not safe to use for + path prefixes despite being included in a module about path manipulation, + meaning it is easy to accidentally introduce path traversal + vulnerabilities into Python programs by using this function. + .. function:: dirname(path, /) diff --git a/Lib/genericpath.py b/Lib/genericpath.py index 7588fe5e8020f9..71ae19190839ae 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -105,6 +105,15 @@ def getctime(filename, /): # Return the longest prefix of all list elements. def commonprefix(m, /): "Given a list of pathnames, returns the longest common leading component" + import warnings + warnings.warn('os.path.commonprefix() is deprecated. Use ' + 'os.path.commonpath() for longest path prefix.', + category=DeprecationWarning, + stacklevel=2) + return _commonprefix(m) + +def _commonprefix(m, /): + "Internal implementation of commonprefix()" if not m: return '' # Some people pass in a list of pathname parts to operate in an OS-agnostic # fashion; don't try to translate in that case as that's an abuse of the diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 1ee27de3206c7f..8025b063397a03 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -542,7 +542,7 @@ def relpath(path, start=None): start_list = start_tail.split(sep) if start_tail else [] path_list = path_tail.split(sep) if path_tail else [] # Work out how much of the filepath is shared by start and path. - i = len(commonprefix([start_list, path_list])) + i = len(genericpath._commonprefix([start_list, path_list])) rel_list = [pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index dfc0817da45fa2..10d3f409d883c5 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -34,6 +34,10 @@ def test_no_argument(self): .format(self.pathmodule.__name__, attr)) def test_commonprefix(self): + with warnings_helper.check_warnings((".*commonpath().*", DeprecationWarning)): + self.do_test_commonprefix() + + def do_test_commonprefix(self): commonprefix = self.pathmodule.commonprefix self.assertEqual( commonprefix([]), @@ -606,8 +610,9 @@ def test_path_isdir(self): self.assertPathEqual(os.path.isdir) def test_path_commonprefix(self): - self.assertEqual(os.path.commonprefix([self.file_path, self.file_name]), - self.file_name) + with warnings_helper.check_warnings((".*commonpath().*", DeprecationWarning)): + self.assertEqual(os.path.commonprefix([self.file_path, self.file_name]), + self.file_name) def test_path_getsize(self): self.assertPathEqual(os.path.getsize) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 3a3c60dea1345f..a3728b58335e63 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -10,6 +10,7 @@ from ntpath import ALL_BUT_LAST, ALLOW_MISSING from test import support from test.support import os_helper +from test.support import warnings_helper from test.support.os_helper import FakePath from test import test_genericpath from tempfile import TemporaryFile @@ -298,6 +299,10 @@ def test_isabs(self): tester('ntpath.isabs("\\\\.\\C:")', 1) def test_commonprefix(self): + with warnings_helper.check_warnings((".*commonpath().*", DeprecationWarning)): + self.do_test_commonprefix() + + def do_test_commonprefix(self): tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])', "/home/swen") tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])', diff --git a/Lib/unittest/util.py b/Lib/unittest/util.py index 050eaed0b3f58f..c7e6b941978cd5 100644 --- a/Lib/unittest/util.py +++ b/Lib/unittest/util.py @@ -1,7 +1,6 @@ """Various utility functions.""" from collections import namedtuple, Counter -from os.path import commonprefix __unittest = True @@ -21,13 +20,23 @@ def _shorten(s, prefixlen, suffixlen): s = '%s[%d chars]%s' % (s[:prefixlen], skip, s[len(s) - suffixlen:]) return s +def _common_prefix(m): + if not m: + return "" + s1 = min(m) + s2 = max(m) + for i, c in enumerate(s1): + if c != s2[i]: + return s1[:i] + return s1 + def _common_shorten_repr(*args): args = tuple(map(safe_repr, args)) maxlen = max(map(len, args)) if maxlen <= _MAX_LENGTH: return args - prefix = commonprefix(args) + prefix = _common_prefix(args) prefixlen = len(prefix) common_len = _MAX_LENGTH - \ diff --git a/Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst b/Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst new file mode 100644 index 00000000000000..8629c834e5b0cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst @@ -0,0 +1,8 @@ +Deprecate :func:`os.path.commonprefix` in favor of +:func:`os.path.commonpath` for path segment prefixes. + +The :func:`os.path.commonprefix` function is being deprecated due to +having a misleading name and module. The function is not safe to use for +path prefixes despite being included in a module about path manipulation, +meaning it is easy to accidentally introduce path traversal +vulnerabilities into Python programs by using this function. From 56590f820e94987edf532f7b47772452a25d9c8f Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 6 Feb 2026 02:51:19 -0600 Subject: [PATCH 012/498] gh-144493: Improve error message in _overlapped.BindLocal() (#144495) Replace a confusing error message with one that actually explains what the error is in `_overlapped.BindLocal()`. Fixes: https://github.com/python/cpython/issues/144493 --- .../next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst | 1 + Modules/overlapped.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst b/Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst new file mode 100644 index 00000000000000..fe205b58013af0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst @@ -0,0 +1 @@ +Improve an exception error message in ``_overlapped.BindLocal()`` that is raised when :meth:`asyncio.loop.sock_connect` is called on a :class:`asyncio.ProactorEventLoop` with a socket that has an invalid address family. diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 09b57ce4b9773a..8c3575ff5678eb 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -559,7 +559,7 @@ _overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family) ret = bind((SOCKET)Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; } else { - PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4"); + PyErr_SetString(PyExc_ValueError, "Only AF_INET and AF_INET6 families are supported"); return NULL; } From cf60e0c4527b910c93c85e257e33c8b966c7e810 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 6 Feb 2026 08:54:34 +0000 Subject: [PATCH 013/498] Docs: Pull expat license from `Modules/expat/` in `license.rst` (#144488) Use license directly from Modules/expat/COPYING. Co-authored-by: Victor Stinner --- Doc/license.rst | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/Doc/license.rst b/Doc/license.rst index e0683c34967c83..23860815e7c107 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -848,29 +848,10 @@ expat ----- The :mod:`pyexpat ` extension is built using an included copy of the expat -sources unless the build is configured ``--with-system-expat``:: +sources unless the build is configured :option:`--with-system-expat`: - Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - and Clark Cooper - - 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. +.. literalinclude:: ../Modules/expat/COPYING + :language: text libffi From f85e1170d2b22d2ee42cd568144e0c9f57b0db67 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 6 Feb 2026 11:55:11 +0100 Subject: [PATCH 014/498] gh-141004: Reorganize and reword the 'Useful macros' section (GH-144471) - Group the macros - Roughly order them to put the most important ones first - Add expansions where it makes sense; especially if there's an equivalent in modern C or a common compiler Co-authored-by: Victor Stinner Co-authored-by: Peter Bierma --- Doc/c-api/intro.rst | 423 +++++++++++++++++++++++++------------------- 1 file changed, 238 insertions(+), 185 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 9828e537a90654..e7ea5b9ba4016c 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -156,68 +156,6 @@ defined closer to where they are useful (for example, :c:macro:`Py_RETURN_NONE`, Others of a more general utility are defined here. This is not necessarily a complete listing. - -.. c:macro:: Py_ABS(x) - - Return the absolute value of ``x``. - - If the result cannot be represented (for example, if ``x`` has - :c:macro:`!INT_MIN` value for :c:expr:`int` type), the behavior is - undefined. - - .. versionadded:: 3.3 - -.. c:macro:: Py_ALIGNED(num) - - Specify alignment to *num* bytes on compilers that support it. - - Consider using the C11 standard ``_Alignas`` specifier over this macro. - -.. c:macro:: Py_ARITHMETIC_RIGHT_SHIFT(type, integer, positions) - - Similar to ``integer >> positions``, but forces sign extension, as the C - standard does not define whether a right-shift of a signed integer will - perform sign extension or a zero-fill. - - *integer* should be any signed integer type. - *positions* is the number of positions to shift to the right. - - Both *integer* and *positions* can be evaluated more than once; - consequently, avoid directly passing a function call or some other - operation with side-effects to this macro. Instead, store the result as a - variable and then pass it. - - *type* is unused and only kept for backwards compatibility. Historically, - *type* was used to cast *integer*. - - .. versionchanged:: 3.1 - - This macro is now valid for all signed integer types, not just those for - which ``unsigned type`` is legal. As a result, *type* is no longer - used. - -.. c:macro:: Py_ALWAYS_INLINE - - Ask the compiler to always inline a static inline function. The compiler can - ignore it and decide to not inline the function. - - It can be used to inline performance critical static inline functions when - building Python in debug mode with function inlining disabled. For example, - MSC disables function inlining when building in debug mode. - - Marking blindly a static inline function with Py_ALWAYS_INLINE can result in - worse performances (due to increased code size for example). The compiler is - usually smarter than the developer for the cost/benefit analysis. - - If Python is :ref:`built in debug mode ` (if the :c:macro:`Py_DEBUG` - macro is defined), the :c:macro:`Py_ALWAYS_INLINE` macro does nothing. - - It must be specified before the function return type. Usage:: - - static inline Py_ALWAYS_INLINE int random(void) { return 4; } - - .. versionadded:: 3.11 - .. c:macro:: Py_CAN_START_THREADS If this macro is defined, then the current system is able to start threads. @@ -227,139 +165,143 @@ complete listing. .. versionadded:: 3.13 -.. c:macro:: Py_CHARMASK(c) - - Argument must be a character or an integer in the range [-128, 127] or [0, - 255]. This macro returns ``c`` cast to an ``unsigned char``. - -.. c:macro:: Py_DEPRECATED(version) +.. c:macro:: Py_GETENV(s) - Use this for deprecated declarations. The macro must be placed before the - symbol name. + Like :samp:`getenv({s})`, but returns ``NULL`` if :option:`-E` was passed + on the command line (see :c:member:`PyConfig.use_environment`). - Example:: - Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); +Docstring macros +---------------- - .. versionchanged:: 3.8 - MSVC support was added. +.. c:macro:: PyDoc_STRVAR(name, str) -.. c:macro:: Py_FORCE_EXPANSION(X) + Creates a variable with name *name* that can be used in docstrings. + If Python is built without docstrings (:option:`--without-doc-strings`), + the value will be an empty string. - This is equivalent to ``X``, which is useful for token-pasting in - macros, as macro expansions in *X* are forcefully evaluated by the - preprocessor. + Example:: -.. c:macro:: Py_GCC_ATTRIBUTE(name) + PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element."); - Use a GCC attribute *name*, hiding it from compilers that don't support GCC - attributes (such as MSVC). + static PyMethodDef deque_methods[] = { + // ... + {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc}, + // ... + } - This expands to ``__attribute__((name))`` on a GCC compiler, and expands - to nothing on compilers that don't support GCC attributes. + Expands to :samp:`PyDoc_VAR({name}) = PyDoc_STR({str})`. -.. c:macro:: Py_GETENV(s) +.. c:macro:: PyDoc_STR(str) - Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the - command line (see :c:member:`PyConfig.use_environment`). + Expands to the given input string, or an empty string + if docstrings are disabled (:option:`--without-doc-strings`). -.. c:macro:: Py_LL(number) + Example:: - Use *number* as a ``long long`` integer literal. + static PyMethodDef pysqlite_row_methods[] = { + {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, + PyDoc_STR("Returns the keys of the row.")}, + {NULL, NULL} + }; - This usally expands to *number* followed by ``LL``, but will expand to some - compiler-specific suffixes (such as ``I64``) on older compilers. +.. c:macro:: PyDoc_VAR(name) - In modern versions of Python, this macro is not very useful, as C99 and - later require the ``LL`` suffix to be valid for an integer. + Declares a static character array variable with the given *name*. + Expands to :samp:`static const char {name}[]` -.. c:macro:: Py_LOCAL(type) + For example:: - Declare a function returning the specified *type* using a fast-calling - qualifier for functions that are local to the current file. - Semantically, this is equivalent to ``static type``. + PyDoc_VAR(python_doc) = PyDoc_STR( + "A genus of constricting snakes in the Pythonidae family native " + "to the tropics and subtropics of the Eastern Hemisphere."); -.. c:macro:: Py_LOCAL_INLINE(type) - Equivalent to :c:macro:`Py_LOCAL` but additionally requests the function - be inlined. +General utility macros +---------------------- -.. c:macro:: Py_LOCAL_SYMBOL +The following macros common tasks not specific to Python. - Macro used to declare a symbol as local to the shared library (hidden). - On supported platforms, it ensures the symbol is not exported. +.. c:macro:: Py_UNUSED(arg) - On compatible versions of GCC/Clang, it - expands to ``__attribute__((visibility("hidden")))``. + Use this for unused arguments in a function definition to silence compiler + warnings. Example: ``int func(int a, int Py_UNUSED(b)) { return a; }``. -.. c:macro:: Py_MAX(x, y) + .. versionadded:: 3.4 - Return the maximum value between ``x`` and ``y``. +.. c:macro:: Py_GCC_ATTRIBUTE(name) - .. versionadded:: 3.3 + Use a GCC attribute *name*, hiding it from compilers that don't support GCC + attributes (such as MSVC). -.. c:macro:: Py_MEMBER_SIZE(type, member) + This expands to :samp:`__attribute__(({name)})` on a GCC compiler, + and expands to nothing on compilers that don't support GCC attributes. - Return the size of a structure (``type``) ``member`` in bytes. - .. versionadded:: 3.6 +Numeric utilities +^^^^^^^^^^^^^^^^^ -.. c:macro:: Py_MEMCPY(dest, src, n) +.. c:macro:: Py_ABS(x) - This is a :term:`soft deprecated` alias to :c:func:`!memcpy`. - Use :c:func:`!memcpy` directly instead. + Return the absolute value of ``x``. - .. deprecated:: 3.14 - The macro is :term:`soft deprecated`. + The argument may be evaluated more than once. + Consequently, do not pass an expression with side-effects directly + to this macro. -.. c:macro:: Py_MIN(x, y) + If the result cannot be represented (for example, if ``x`` has + :c:macro:`!INT_MIN` value for :c:expr:`int` type), the behavior is + undefined. - Return the minimum value between ``x`` and ``y``. + Corresponds roughly to :samp:`(({x}) < 0 ? -({x}) : ({x}))` .. versionadded:: 3.3 -.. c:macro:: Py_NO_INLINE +.. c:macro:: Py_MAX(x, y) + Py_MIN(x, y) - Disable inlining on a function. For example, it reduces the C stack - consumption: useful on LTO+PGO builds which heavily inline code (see - :issue:`33720`). + Return the larger or smaller of the arguments, respectively. - Usage:: + Any arguments may be evaluated more than once. + Consequently, do not pass an expression with side-effects directly + to this macro. - Py_NO_INLINE static int random(void) { return 4; } + :c:macro:`!Py_MAX` corresponds roughly to + :samp:`((({x}) > ({y})) ? ({x}) : ({y}))`. - .. versionadded:: 3.11 + .. versionadded:: 3.3 -.. c:macro:: Py_SAFE_DOWNCAST(value, larger, smaller) +.. c:macro:: Py_ARITHMETIC_RIGHT_SHIFT(type, integer, positions) - Cast *value* to type *smaller* from type *larger*, validating that no - information was lost. + Similar to :samp:`{integer} >> {positions}`, but forces sign extension, + as the C standard does not define whether a right-shift of a signed + integer will perform sign extension or a zero-fill. - On release builds of Python, this is roughly equivalent to - ``(smaller) value`` (in C++, ``static_cast(value)`` will be - used instead). + *integer* should be any signed integer type. + *positions* is the number of positions to shift to the right. - On debug builds (implying that :c:macro:`Py_DEBUG` is defined), this asserts - that no information was lost with the cast from *larger* to *smaller*. + Both *integer* and *positions* can be evaluated more than once; + consequently, avoid directly passing a function call or some other + operation with side-effects to this macro. Instead, store the result as a + variable and then pass it. - *value*, *larger*, and *smaller* may all be evaluated more than once in the - expression; consequently, do not pass an expression with side-effects directly to - this macro. + *type* is unused and only kept for backwards compatibility. Historically, + *type* was used to cast *integer*. -.. c:macro:: Py_STRINGIFY(x) + .. versionchanged:: 3.1 - Convert ``x`` to a C string. E.g. ``Py_STRINGIFY(123)`` returns - ``"123"``. + This macro is now valid for all signed integer types, not just those for + which ``unsigned type`` is legal. As a result, *type* is no longer + used. - .. versionadded:: 3.4 +.. c:macro:: Py_CHARMASK(c) -.. c:macro:: Py_ULL(number) + Argument must be a character or an integer in the range [-128, 127] or [0, + 255]. This macro returns ``c`` cast to an ``unsigned char``. - Similar to :c:macro:`Py_LL`, but *number* will be an ``unsigned long long`` - literal instead. This is done by appending ``U`` to the result of ``Py_LL``. - In modern versions of Python, this macro is not very useful, as C99 and - later require the ``ULL``/``LLU`` suffixes to be valid for an integer. +Assertion utilities +^^^^^^^^^^^^^^^^^^^ .. c:macro:: Py_UNREACHABLE() @@ -372,8 +314,11 @@ complete listing. avoids a warning about unreachable code. For example, the macro is implemented with ``__builtin_unreachable()`` on GCC in release mode. + In debug mode, and on unsupported compilers, the macro expands to a call to + :c:func:`Py_FatalError`. + A use for ``Py_UNREACHABLE()`` is following a call a function that - never returns but that is not declared :c:macro:`_Py_NO_RETURN`. + never returns but that is not declared ``_Noreturn``. If a code path is very unlikely code but can be reached under exceptional case, this macro must not be used. For example, under low memory condition @@ -383,18 +328,29 @@ complete listing. .. versionadded:: 3.7 -.. c:macro:: Py_UNUSED(arg) +.. c:macro:: Py_SAFE_DOWNCAST(value, larger, smaller) - Use this for unused arguments in a function definition to silence compiler - warnings. Example: ``int func(int a, int Py_UNUSED(b)) { return a; }``. + Cast *value* to type *smaller* from type *larger*, validating that no + information was lost. - .. versionadded:: 3.4 + On release builds of Python, this is roughly equivalent to + :samp:`(({smaller}) {value})` + (in C++, :samp:`static_cast<{smaller}>({value})` will be used instead). + + On debug builds (implying that :c:macro:`Py_DEBUG` is defined), this asserts + that no information was lost with the cast from *larger* to *smaller*. + + *value*, *larger*, and *smaller* may all be evaluated more than once in the + expression; consequently, do not pass an expression with side-effects + directly to this macro. .. c:macro:: Py_BUILD_ASSERT(cond) Asserts a compile-time condition *cond*, as a statement. The build will fail if the condition is false or cannot be evaluated at compile time. + Corresponds roughly to :samp:`static_assert({cond})` on C23 and above. + For example:: Py_BUILD_ASSERT(sizeof(PyTime_t) == sizeof(int64_t)); @@ -413,62 +369,127 @@ complete listing. .. versionadded:: 3.3 -.. c:macro:: PyDoc_STRVAR(name, str) - Creates a variable with name *name* that can be used in docstrings. - If Python is built without docstrings, the value will be empty. +Type size utilities +^^^^^^^^^^^^^^^^^^^ - Use :c:macro:`PyDoc_STRVAR` for docstrings to support building - Python without docstrings, as specified in :pep:`7`. +.. c:macro:: Py_ARRAY_LENGTH(array) - Example:: + Compute the length of a statically allocated C array at compile time. - PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element."); + The *array* argument must be a C array with a size known at compile time. + Passing an array with an unknown size, such as a heap-allocated array, + will result in a compilation error on some compilers, or otherwise produce + incorrect results. - static PyMethodDef deque_methods[] = { - // ... - {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc}, - // ... - } + This is roughly equivalent to:: -.. c:macro:: PyDoc_STR(str) + sizeof(array) / sizeof((array)[0]) - Creates a docstring for the given input string or an empty string - if docstrings are disabled. +.. c:macro:: Py_MEMBER_SIZE(type, member) - Use :c:macro:`PyDoc_STR` in specifying docstrings to support - building Python without docstrings, as specified in :pep:`7`. + Return the size of a structure (*type*) *member* in bytes. - Example:: + Corresponds roughly to :samp:`sizeof((({type} *)NULL)->{member})`. - static PyMethodDef pysqlite_row_methods[] = { - {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, - PyDoc_STR("Returns the keys of the row.")}, - {NULL, NULL} - }; + .. versionadded:: 3.6 -.. c:macro:: PyDoc_VAR(name) - Declares a static character array variable with the given name *name*. +Macro definition utilities +^^^^^^^^^^^^^^^^^^^^^^^^^^ - For example:: +.. c:macro:: Py_FORCE_EXPANSION(X) - PyDoc_VAR(python_doc) = PyDoc_STR("A genus of constricting snakes in the Pythonidae family native " - "to the tropics and subtropics of the Eastern Hemisphere."); + This is equivalent to :samp:`{X}`, which is useful for token-pasting in + macros, as macro expansions in *X* are forcefully evaluated by the + preprocessor. -.. c:macro:: Py_ARRAY_LENGTH(array) +.. c:macro:: Py_STRINGIFY(x) - Compute the length of a statically allocated C array at compile time. + Convert ``x`` to a C string. For example, ``Py_STRINGIFY(123)`` returns + ``"123"``. - The *array* argument must be a C array with a size known at compile time. - Passing an array with an unknown size, such as a heap-allocated array, - will result in a compilation error on some compilers, or otherwise produce - incorrect results. + .. versionadded:: 3.4 - This is roughly equivalent to:: - sizeof(array) / sizeof((array)[0]) +Declaration utilities +--------------------- + +The following macros can be used in declarations. +They are most useful for defining the C API itself, and have limited use +for extension authors. +Most of them expand to compiler-specific spellings of common extensions +to the C language. + +.. c:macro:: Py_ALWAYS_INLINE + + Ask the compiler to always inline a static inline function. The compiler can + ignore it and decide to not inline the function. + + Corresponds to ``always_inline`` attribute in GCC and ``__forceinline`` + in MSVC. + + It can be used to inline performance critical static inline functions when + building Python in debug mode with function inlining disabled. For example, + MSC disables function inlining when building in debug mode. + + Marking blindly a static inline function with Py_ALWAYS_INLINE can result in + worse performances (due to increased code size for example). The compiler is + usually smarter than the developer for the cost/benefit analysis. + + If Python is :ref:`built in debug mode ` (if the :c:macro:`Py_DEBUG` + macro is defined), the :c:macro:`Py_ALWAYS_INLINE` macro does nothing. + + It must be specified before the function return type. Usage:: + + static inline Py_ALWAYS_INLINE int random(void) { return 4; } + + .. versionadded:: 3.11 + +.. c:macro:: Py_NO_INLINE + + Disable inlining on a function. For example, it reduces the C stack + consumption: useful on LTO+PGO builds which heavily inline code (see + :issue:`33720`). + Corresponds to the ``noinline`` attribute/specification on GCC and MSVC. + + Usage:: + + Py_NO_INLINE static int random(void) { return 4; } + + .. versionadded:: 3.11 + +.. c:macro:: Py_DEPRECATED(version) + + Use this to declare APIs that were deprecated in a specific CPython version. + The macro must be placed before the symbol name. + + Example:: + + Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); + + .. versionchanged:: 3.8 + MSVC support was added. + +.. c:macro:: Py_LOCAL(type) + + Declare a function returning the specified *type* using a fast-calling + qualifier for functions that are local to the current file. + Semantically, this is equivalent to :samp:`static {type}`. + +.. c:macro:: Py_LOCAL_INLINE(type) + + Equivalent to :c:macro:`Py_LOCAL` but additionally requests the function + be inlined. + +.. c:macro:: Py_LOCAL_SYMBOL + + Macro used to declare a symbol as local to the shared library (hidden). + On supported platforms, it ensures the symbol is not exported. + + On compatible versions of GCC/Clang, it + expands to ``__attribute__((visibility("hidden")))``. .. c:macro:: Py_EXPORTED_SYMBOL @@ -501,6 +522,38 @@ complete listing. This macro is intended for defining CPython's C API itself; extension modules should not use it for their own symbols. + +Outdated macros +--------------- + +The following macros have been used to features that have been standardized +in C11. + +.. c:macro:: Py_ALIGNED(num) + + Specify alignment to *num* bytes on compilers that support it. + + Consider using the C11 standard ``_Alignas`` specifier over this macro. + +.. c:macro:: Py_LL(number) + Py_ULL(number) + + Use *number* as a ``long long`` or ``unsigned long long`` integer literal, + respectively. + + Expands to *number* followed by ``LL`` or ``LLU``, respectively, but will + expand to some compiler-specific suffixes on some older compilers. + + Consider using the C99 standard suffixes ``LL`` and ``LLU`` directly. + +.. c:macro:: Py_MEMCPY(dest, src, n) + + This is a :term:`soft deprecated` alias to :c:func:`!memcpy`. + Use :c:func:`!memcpy` directly instead. + + .. deprecated:: 3.14 + The macro is :term:`soft deprecated`. + .. c:macro:: Py_VA_COPY This is a :term:`soft deprecated` alias to the C99-standard ``va_copy`` From 638d22c6e7b129fcec7fa471abd8ffca62e54cd6 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 6 Feb 2026 06:48:27 -0500 Subject: [PATCH 015/498] Docs: module pages should not link to themselves (#144505) * Docs: module pages should not link to themselves * fix header punctuation --- Doc/library/__future__.rst | 8 +- Doc/library/argparse.rst | 2 +- Doc/library/ast.rst | 12 +- Doc/library/atexit.rst | 12 +- Doc/library/bdb.rst | 4 +- Doc/library/binascii.rst | 6 +- Doc/library/bisect.rst | 6 +- Doc/library/bz2.rst | 4 +- Doc/library/calendar.rst | 6 +- Doc/library/cmath.rst | 4 +- Doc/library/cmd.rst | 2 +- Doc/library/codecs.rst | 2 +- Doc/library/codeop.rst | 4 +- Doc/library/colorsys.rst | 4 +- Doc/library/concurrent.futures.rst | 2 +- Doc/library/configparser.rst | 18 +- Doc/library/contextlib.rst | 2 +- Doc/library/copy.rst | 2 +- Doc/library/copyreg.rst | 2 +- Doc/library/csv.rst | 12 +- Doc/library/ctypes.rst | 84 ++++----- Doc/library/curses.ascii.rst | 2 +- Doc/library/curses.panel.rst | 2 +- Doc/library/curses.rst | 14 +- Doc/library/dbm.rst | 18 +- Doc/library/decimal.rst | 8 +- Doc/library/dis.rst | 10 +- Doc/library/doctest.rst | 28 +-- Doc/library/email.charset.rst | 4 +- Doc/library/email.errors.rst | 2 +- Doc/library/email.generator.rst | 2 +- Doc/library/email.header.rst | 6 +- Doc/library/email.iterators.rst | 2 +- Doc/library/email.message.rst | 2 +- Doc/library/email.parser.rst | 4 +- Doc/library/email.rst | 8 +- Doc/library/email.utils.rst | 2 +- Doc/library/ensurepip.rst | 4 +- Doc/library/fcntl.rst | 4 +- Doc/library/filecmp.rst | 4 +- Doc/library/fractions.rst | 2 +- Doc/library/ftplib.rst | 2 +- Doc/library/functools.rst | 4 +- Doc/library/gc.rst | 2 +- Doc/library/getpass.rst | 2 +- Doc/library/gettext.rst | 16 +- Doc/library/graphlib.rst | 2 +- Doc/library/gzip.rst | 6 +- Doc/library/hashlib.rst | 4 +- Doc/library/http.cookiejar.rst | 18 +- Doc/library/http.cookies.rst | 6 +- Doc/library/http.rst | 4 +- Doc/library/http.server.rst | 4 +- Doc/library/imaplib.rst | 2 +- Doc/library/importlib.rst | 2 +- Doc/library/inspect.rst | 6 +- Doc/library/io.rst | 8 +- Doc/library/ipaddress.rst | 6 +- Doc/library/json.rst | 6 +- Doc/library/linecache.rst | 4 +- Doc/library/locale.rst | 12 +- Doc/library/logging.config.rst | 4 +- Doc/library/logging.handlers.rst | 26 +-- Doc/library/logging.rst | 6 +- Doc/library/marshal.rst | 4 +- Doc/library/math.integer.rst | 4 +- Doc/library/math.rst | 4 +- Doc/library/mimetypes.rst | 4 +- Doc/library/multiprocessing.rst | 54 +++--- Doc/library/operator.rst | 6 +- Doc/library/optparse.rst | 248 +++++++++++++------------- Doc/library/os.path.rst | 2 +- Doc/library/os.rst | 16 +- Doc/library/pathlib.rst | 2 +- Doc/library/pickle.rst | 46 ++--- Doc/library/pickletools.rst | 2 +- Doc/library/platform.rst | 2 +- Doc/library/poplib.rst | 4 +- Doc/library/posix.rst | 10 +- Doc/library/pprint.rst | 2 +- Doc/library/pty.rst | 4 +- Doc/library/py_compile.rst | 2 +- Doc/library/pyclbr.rst | 2 +- Doc/library/pyexpat.rst | 6 +- Doc/library/queue.rst | 4 +- Doc/library/random.rst | 4 +- Doc/library/re.rst | 2 +- Doc/library/readline.rst | 8 +- Doc/library/runpy.rst | 6 +- Doc/library/sched.rst | 2 +- Doc/library/secrets.rst | 12 +- Doc/library/select.rst | 2 +- Doc/library/shelve.rst | 8 +- Doc/library/shlex.rst | 6 +- Doc/library/shutil.rst | 6 +- Doc/library/signal.rst | 6 +- Doc/library/site.rst | 6 +- Doc/library/smtplib.rst | 6 +- Doc/library/socket.rst | 8 +- Doc/library/socketserver.rst | 2 +- Doc/library/ssl.rst | 4 +- Doc/library/stat.rst | 4 +- Doc/library/string.rst | 4 +- Doc/library/stringprep.rst | 4 +- Doc/library/struct.rst | 6 +- Doc/library/subprocess.rst | 20 +-- Doc/library/symtable.rst | 4 +- Doc/library/sys.monitoring.rst | 4 +- Doc/library/sys.rst | 2 +- Doc/library/sysconfig.rst | 18 +- Doc/library/tarfile.rst | 20 +-- Doc/library/tempfile.rst | 2 +- Doc/library/termios.rst | 2 +- Doc/library/test.rst | 18 +- Doc/library/textwrap.rst | 2 +- Doc/library/timeit.rst | 2 +- Doc/library/tkinter.colorchooser.rst | 2 +- Doc/library/tkinter.dnd.rst | 2 +- Doc/library/tkinter.font.rst | 2 +- Doc/library/tkinter.messagebox.rst | 2 +- Doc/library/tkinter.rst | 44 ++--- Doc/library/tkinter.scrolledtext.rst | 2 +- Doc/library/tkinter.ttk.rst | 6 +- Doc/library/tokenize.rst | 6 +- Doc/library/trace.rst | 6 +- Doc/library/tracemalloc.rst | 24 +-- Doc/library/tty.rst | 4 +- Doc/library/unittest.mock.rst | 8 +- Doc/library/unittest.rst | 36 ++-- Doc/library/urllib.error.rst | 4 +- Doc/library/urllib.parse.rst | 2 +- Doc/library/urllib.request.rst | 10 +- Doc/library/uuid.rst | 14 +- Doc/library/warnings.rst | 8 +- Doc/library/wave.rst | 8 +- Doc/library/webbrowser.rst | 4 +- Doc/library/winreg.rst | 2 +- Doc/library/winsound.rst | 2 +- Doc/library/wsgiref.rst | 2 +- Doc/library/xml.dom.minidom.rst | 22 +-- Doc/library/xml.dom.pulldom.rst | 2 +- Doc/library/xml.dom.rst | 4 +- Doc/library/xml.etree.elementtree.rst | 6 +- Doc/library/xml.sax.handler.rst | 4 +- Doc/library/xml.sax.rst | 6 +- Doc/library/xml.sax.utils.rst | 2 +- Doc/library/xmlrpc.client.rst | 4 +- Doc/library/xmlrpc.server.rst | 4 +- Doc/library/zipapp.rst | 2 +- Doc/library/zipfile.rst | 6 +- Doc/library/zipimport.rst | 4 +- Doc/library/zoneinfo.rst | 4 +- 152 files changed, 688 insertions(+), 688 deletions(-) diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index 5d916b30112d3c..749e4543c5b823 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -15,7 +15,7 @@ before the release in which the feature becomes standard. While these future statements are given additional special meaning by the Python compiler, they are still executed like any other import statement and -the :mod:`__future__` exists and is handled by the import system the same way +the :mod:`!__future__` exists and is handled by the import system the same way any other Python module would be. This design serves three purposes: * To avoid confusing existing tools that analyze import statements and expect to @@ -23,17 +23,17 @@ any other Python module would be. This design serves three purposes: * To document when incompatible changes were introduced, and when they will be --- or were --- made mandatory. This is a form of executable documentation, and - can be inspected programmatically via importing :mod:`__future__` and examining + can be inspected programmatically via importing :mod:`!__future__` and examining its contents. * To ensure that :ref:`future statements ` run under releases prior to - Python 2.1 at least yield runtime exceptions (the import of :mod:`__future__` + Python 2.1 at least yield runtime exceptions (the import of :mod:`!__future__` will fail, because there was no module of that name prior to 2.1). Module Contents --------------- -No feature description will ever be deleted from :mod:`__future__`. Since its +No feature description will ever be deleted from :mod:`!__future__`. Since its introduction in Python 2.1 the following features have found their way into the language using this mechanism: diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index f4109fe0e5f2bf..c7532ecd629b02 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -13,7 +13,7 @@ .. note:: - While :mod:`argparse` is the default recommended standard library module + While :mod:`!argparse` is the default recommended standard library module for implementing basic command line applications, authors with more exacting requirements for exactly how their command line applications behave may find it doesn't provide the necessary level of control. diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index bf37540e5faf42..ee7ce15c48b589 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -15,7 +15,7 @@ -------------- -The :mod:`ast` module helps Python applications to process trees of the Python +The :mod:`!ast` module helps Python applications to process trees of the Python abstract syntax grammar. The abstract syntax itself might change with each Python release; this module helps to find out programmatically what the current grammar looks like. @@ -46,7 +46,7 @@ Node classes This is the base of all AST node classes. The actual node classes are derived from the :file:`Parser/Python.asdl` file, which is reproduced :ref:`above `. They are defined in the :mod:`!_ast` C - module and re-exported in :mod:`ast`. + module and re-exported in :mod:`!ast`. There is one class defined for each left-hand side symbol in the abstract grammar (for example, :class:`ast.stmt` or :class:`ast.expr`). In addition, @@ -2200,10 +2200,10 @@ Async and await occurrences of the same value (for example, :class:`ast.Add`). -:mod:`ast` helpers ------------------- +:mod:`!ast` helpers +------------------- -Apart from the node classes, the :mod:`ast` module defines these utility functions +Apart from the node classes, the :mod:`!ast` module defines these utility functions and classes for traversing abstract syntax trees: .. function:: parse(source, filename='', mode='exec', *, type_comments=False, feature_version=None, optimize=-1, module=None) @@ -2576,7 +2576,7 @@ Command-line usage .. versionadded:: 3.9 -The :mod:`ast` module can be executed as a script from the command line. +The :mod:`!ast` module can be executed as a script from the command line. It is as simple as: .. code-block:: sh diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst index 02d2f0807df8f6..24a3492ba10c91 100644 --- a/Doc/library/atexit.rst +++ b/Doc/library/atexit.rst @@ -9,9 +9,9 @@ -------------- -The :mod:`atexit` module defines functions to register and unregister cleanup +The :mod:`!atexit` module defines functions to register and unregister cleanup functions. Functions thus registered are automatically executed upon normal -interpreter termination. :mod:`atexit` runs these functions in the *reverse* +interpreter termination. :mod:`!atexit` runs these functions in the *reverse* order in which they were registered; if you register ``A``, ``B``, and ``C``, at interpreter termination time they will be run in the order ``C``, ``B``, ``A``. @@ -64,7 +64,7 @@ a cleanup function is undefined. Remove *func* from the list of functions to be run at interpreter shutdown. :func:`unregister` silently does nothing if *func* was not previously registered. If *func* has been registered more than once, every occurrence - of that function in the :mod:`atexit` call stack will be removed. Equality + of that function in the :mod:`!atexit` call stack will be removed. Equality comparisons (``==``) are used internally during unregistration, so function references do not need to have matching identities. @@ -72,14 +72,14 @@ a cleanup function is undefined. .. seealso:: Module :mod:`readline` - Useful example of :mod:`atexit` to read and write :mod:`readline` history + Useful example of :mod:`!atexit` to read and write :mod:`readline` history files. .. _atexit-example: -:mod:`atexit` Example ---------------------- +:mod:`!atexit` Example +---------------------- The following simple example demonstrates how a module can initialize a counter from a file when it is imported and save the counter's updated value diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst index a3c6da7a6d686b..c8b48901901f98 100644 --- a/Doc/library/bdb.rst +++ b/Doc/library/bdb.rst @@ -8,7 +8,7 @@ -------------- -The :mod:`bdb` module handles basic debugger functions, like setting breakpoints +The :mod:`!bdb` module handles basic debugger functions, like setting breakpoints or managing execution via the debugger. The following exception is defined: @@ -18,7 +18,7 @@ The following exception is defined: Exception raised by the :class:`Bdb` class for quitting the debugger. -The :mod:`bdb` module also defines two classes: +The :mod:`!bdb` module also defines two classes: .. class:: Breakpoint(self, file, line, temporary=False, cond=None, funcname=None) diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index eb801175ee6179..4693ff6336ef7c 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -10,10 +10,10 @@ -------------- -The :mod:`binascii` module contains a number of methods to convert between +The :mod:`!binascii` module contains a number of methods to convert between binary and various ASCII-encoded binary representations. Normally, you will not use these functions directly but use wrapper modules like -:mod:`base64` instead. The :mod:`binascii` module contains +:mod:`base64` instead. The :mod:`!binascii` module contains low-level functions written in C for greater speed that are used by the higher-level modules. @@ -28,7 +28,7 @@ higher-level modules. ASCII-only unicode strings are now accepted by the ``a2b_*`` functions. -The :mod:`binascii` module defines the following functions: +The :mod:`!binascii` module defines the following functions: .. function:: a2b_uu(string) diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index d5ec4212c1f9f4..3efa3999171646 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -16,7 +16,7 @@ having to sort the list after each insertion. For long lists of items with expensive comparison operations, this can be an improvement over linear searches or frequent resorting. -The module is called :mod:`bisect` because it uses a basic bisection +The module is called :mod:`!bisect` because it uses a basic bisection algorithm to do its work. Unlike other bisection tools that search for a specific value, the functions in this module are designed to locate an insertion point. Accordingly, the functions never call an :meth:`~object.__eq__` @@ -27,9 +27,9 @@ point between values in an array. .. note:: The functions in this module are not thread-safe. If multiple threads - concurrently use :mod:`bisect` functions on the same sequence, this + concurrently use :mod:`!bisect` functions on the same sequence, this may result in undefined behaviour. Likewise, if the provided sequence - is mutated by a different thread while a :mod:`bisect` function + is mutated by a different thread while a :mod:`!bisect` function is operating on it, the result is undefined. For example, using :py:func:`~bisect.insort_left` on the same list from multiple threads may result in the list becoming unsorted. diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 12650861c0fb5d..32e223ddbdd8a2 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -16,7 +16,7 @@ This module provides a comprehensive interface for compressing and decompressing data using the bzip2 compression algorithm. -The :mod:`bz2` module contains: +The :mod:`!bz2` module contains: * The :func:`.open` function and :class:`BZ2File` class for reading and writing compressed files. @@ -317,7 +317,7 @@ One-shot (de)compression Examples of usage ----------------- -Below are some examples of typical usage of the :mod:`bz2` module. +Below are some examples of typical usage of the :mod:`!bz2` module. Using :func:`compress` and :func:`decompress` to demonstrate round-trip compression: diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index 822e627af8db95..48472840eab319 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -452,7 +452,7 @@ For simple text calendars this module provides the following functions. inverse. -The :mod:`calendar` module exports the following data attributes: +The :mod:`!calendar` module exports the following data attributes: .. data:: day_name @@ -578,7 +578,7 @@ The :mod:`calendar` module exports the following data attributes: .. versionadded:: 3.12 -The :mod:`calendar` module defines the following exceptions: +The :mod:`!calendar` module defines the following exceptions: .. exception:: IllegalMonthError(month) @@ -617,7 +617,7 @@ Command-line usage .. versionadded:: 2.5 -The :mod:`calendar` module can be executed as a script from the command line +The :mod:`!calendar` module can be executed as a script from the command line to interactively print a calendar. .. code-block:: shell diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst index b6d5dbee21dcd5..f602003e49b821 100644 --- a/Doc/library/cmath.rst +++ b/Doc/library/cmath.rst @@ -124,7 +124,7 @@ rectangular coordinates to polar coordinates and back. The modulus (absolute value) of a complex number *z* can be computed using the built-in :func:`abs` function. There is no - separate :mod:`cmath` module function for this operation. + separate :mod:`!cmath` module function for this operation. .. function:: polar(z) @@ -357,7 +357,7 @@ Note that the selection of functions is similar, but not identical, to that in module :mod:`math`. The reason for having two modules is that some users aren't interested in complex numbers, and perhaps don't even know what they are. They would rather have ``math.sqrt(-1)`` raise an exception than return a complex -number. Also note that the functions defined in :mod:`cmath` always return a +number. Also note that the functions defined in :mod:`!cmath` always return a complex number, even if the answer can be expressed as a real number (in which case the complex number has an imaginary part of zero). diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index 66544f82f6ff3f..1757dedabbf633 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -245,7 +245,7 @@ Cmd Example .. sectionauthor:: Raymond Hettinger -The :mod:`cmd` module is mainly useful for building custom shells that let a +The :mod:`!cmd` module is mainly useful for building custom shells that let a user work with a program interactively. This section presents a simple example of how to build a shell around a few of diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 305e5d07a3529e..9f958ee98c6119 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -317,7 +317,7 @@ and writing to platform dependent files: Codec Base Classes ------------------ -The :mod:`codecs` module defines a set of base classes which define the +The :mod:`!codecs` module defines a set of base classes which define the interfaces for working with codec objects, and can also be used as the basis for custom codec implementations. diff --git a/Doc/library/codeop.rst b/Doc/library/codeop.rst index 16f674adb4b22b..2e6d65980381ad 100644 --- a/Doc/library/codeop.rst +++ b/Doc/library/codeop.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`codeop` module provides utilities upon which the Python +The :mod:`!codeop` module provides utilities upon which the Python read-eval-print loop can be emulated, as is done in the :mod:`code` module. As a result, you probably don't want to use the module directly; if you want to include such a loop in your program you probably want to use the :mod:`code` @@ -25,7 +25,7 @@ There are two parts to this job: #. Remembering which future statements the user has entered, so subsequent input can be compiled with these in effect. -The :mod:`codeop` module provides a way of doing each of these things, and a way +The :mod:`!codeop` module provides a way of doing each of these things, and a way of doing them both. To do just the former: diff --git a/Doc/library/colorsys.rst b/Doc/library/colorsys.rst index ffebf4e40dd609..2d3dc2b8b57935 100644 --- a/Doc/library/colorsys.rst +++ b/Doc/library/colorsys.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`colorsys` module defines bidirectional conversions of color values +The :mod:`!colorsys` module defines bidirectional conversions of color values between colors expressed in the RGB (Red Green Blue) color space used in computer monitors and three other coordinate systems: YIQ, HLS (Hue Lightness Saturation) and HSV (Hue Saturation Value). Coordinates in all of these color @@ -24,7 +24,7 @@ spaces, the coordinates are all between 0 and 1. https://poynton.ca/ColorFAQ.html and https://www.cambridgeincolour.com/tutorials/color-spaces.htm. -The :mod:`colorsys` module defines the following functions: +The :mod:`!colorsys` module defines the following functions: .. function:: rgb_to_yiq(r, g, b) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index e4b505c3f9761e..3ea24ea77004ad 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -12,7 +12,7 @@ and :source:`Lib/concurrent/futures/interpreter.py` -------------- -The :mod:`concurrent.futures` module provides a high-level interface for +The :mod:`!concurrent.futures` module provides a high-level interface for asynchronously executing callables. The asynchronous execution can be performed with threads, using diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index bb109a9b742cb7..f73252a90265cf 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -80,7 +80,7 @@ Let's take a very basic configuration file that looks like this: The structure of INI files is described `in the following section <#supported-ini-file-structure>`_. Essentially, the file consists of sections, each of which contains keys with values. -:mod:`configparser` classes can read and write such files. Let's start by +:mod:`!configparser` classes can read and write such files. Let's start by creating the above configuration file programmatically. .. doctest:: @@ -449,7 +449,7 @@ Mapping Protocol Access .. versionadded:: 3.2 Mapping protocol access is a generic name for functionality that enables using -custom objects as if they were dictionaries. In case of :mod:`configparser`, +custom objects as if they were dictionaries. In case of :mod:`!configparser`, the mapping interface implementation is using the ``parser['section']['option']`` notation. @@ -459,7 +459,7 @@ the original parser on demand. What's even more important is that when values are changed on a section proxy, they are actually mutated in the original parser. -:mod:`configparser` objects behave as close to actual dictionaries as possible. +:mod:`!configparser` objects behave as close to actual dictionaries as possible. The mapping interface is complete and adheres to the :class:`~collections.abc.MutableMapping` ABC. However, there are a few differences that should be taken into account: @@ -507,7 +507,7 @@ Customizing Parser Behaviour ---------------------------- There are nearly as many INI format variants as there are applications using it. -:mod:`configparser` goes a long way to provide support for the largest sensible +:mod:`!configparser` goes a long way to provide support for the largest sensible set of INI styles available. The default functionality is mainly dictated by historical background and it's very likely that you will want to customize some of the features. @@ -560,7 +560,7 @@ the :meth:`!__init__` options: * *allow_no_value*, default value: ``False`` Some configuration files are known to include settings without values, but - which otherwise conform to the syntax supported by :mod:`configparser`. The + which otherwise conform to the syntax supported by :mod:`!configparser`. The *allow_no_value* parameter to the constructor can be used to indicate that such values should be accepted: @@ -615,7 +615,7 @@ the :meth:`!__init__` options: prefixes for whole line comments. .. versionchanged:: 3.2 - In previous versions of :mod:`configparser` behaviour matched + In previous versions of :mod:`!configparser` behaviour matched ``comment_prefixes=('#',';')`` and ``inline_comment_prefixes=(';',)``. Please note that config parsers don't support escaping of comment prefixes so @@ -672,7 +672,7 @@ the :meth:`!__init__` options: parsers in new applications. .. versionchanged:: 3.2 - In previous versions of :mod:`configparser` behaviour matched + In previous versions of :mod:`!configparser` behaviour matched ``strict=False``. * *empty_lines_in_values*, default value: ``True`` @@ -842,7 +842,7 @@ be overridden by subclasses or by attribute assignment. Legacy API Examples ------------------- -Mainly because of backwards compatibility concerns, :mod:`configparser` +Mainly because of backwards compatibility concerns, :mod:`!configparser` provides also a legacy API with explicit ``get``/``set`` methods. While there are valid use cases for the methods outlined below, mapping protocol access is preferred for new projects. The legacy API is at times more advanced, @@ -1378,7 +1378,7 @@ Exceptions .. exception:: Error - Base class for all other :mod:`configparser` exceptions. + Base class for all other :mod:`!configparser` exceptions. .. exception:: NoSectionError diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index f2e3c836cec332..564c11d0596c44 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -681,7 +681,7 @@ Examples and Recipes -------------------- This section describes some examples and recipes for making effective use of -the tools provided by :mod:`contextlib`. +the tools provided by :mod:`!contextlib`. Supporting a variable number of context managers diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst index 210ad7188003e6..121c44a16ad43b 100644 --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -80,7 +80,7 @@ of lists by assigning a slice of the entire list, for example, Classes can use the same interfaces to control copying that they use to control pickling. See the description of module :mod:`pickle` for information on these -methods. In fact, the :mod:`copy` module uses the registered +methods. In fact, the :mod:`!copy` module uses the registered pickle functions from the :mod:`copyreg` module. .. index:: diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst index 6e3144824ebe91..d59936029da69d 100644 --- a/Doc/library/copyreg.rst +++ b/Doc/library/copyreg.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`copyreg` module offers a way to define functions used while pickling +The :mod:`!copyreg` module offers a way to define functions used while pickling specific objects. The :mod:`pickle` and :mod:`copy` modules use those functions when pickling/copying those objects. The module provides configuration information about object constructors which are not classes. diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 4a033d823e6a7e..5c086ab94229ac 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -25,14 +25,14 @@ similar enough that it is possible to write a single module which can efficiently manipulate such data, hiding the details of reading and writing the data from the programmer. -The :mod:`csv` module implements classes to read and write tabular data in CSV +The :mod:`!csv` module implements classes to read and write tabular data in CSV format. It allows programmers to say, "write this data in the format preferred by Excel," or "read data from this file which was generated by Excel," without knowing the precise details of the CSV format used by Excel. Programmers can also describe the CSV formats understood by other applications or define their own special-purpose CSV formats. -The :mod:`csv` module's :class:`reader` and :class:`writer` objects read and +The :mod:`!csv` module's :class:`reader` and :class:`writer` objects read and write sequences. Programmers can also read and write data in dictionary form using the :class:`DictReader` and :class:`DictWriter` classes. @@ -47,7 +47,7 @@ using the :class:`DictReader` and :class:`DictWriter` classes. Module Contents --------------- -The :mod:`csv` module defines the following functions: +The :mod:`!csv` module defines the following functions: .. index:: @@ -146,7 +146,7 @@ The :mod:`csv` module defines the following functions: given, this becomes the new limit. -The :mod:`csv` module defines the following classes: +The :mod:`!csv` module defines the following classes: .. class:: DictReader(f, fieldnames=None, restkey=None, restval=None, \ dialect='excel', *args, **kwds) @@ -314,7 +314,7 @@ An example for :class:`Sniffer` use:: .. _csv-constants: -The :mod:`csv` module defines the following constants: +The :mod:`!csv` module defines the following constants: .. data:: QUOTE_ALL @@ -375,7 +375,7 @@ The :mod:`csv` module defines the following constants: .. versionadded:: 3.12 -The :mod:`csv` module defines the following exception: +The :mod:`!csv` module defines the following exception: .. exception:: Error diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index d2f4da08327323..53849ac2a6aeb6 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -10,7 +10,7 @@ -------------- -:mod:`ctypes` is a foreign function library for Python. It provides C compatible +:mod:`!ctypes` is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. @@ -36,7 +36,7 @@ So, you should not be confused if :class:`c_long` is printed if you would expect Loading dynamic link libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:mod:`ctypes` exports the *cdll*, and on Windows *windll* and *oledll* +:mod:`!ctypes` exports the *cdll*, and on Windows *windll* and *oledll* objects, for loading dynamic link libraries. You load libraries by accessing them as attributes of these objects. *cdll* @@ -182,7 +182,7 @@ handle (passing ``None`` as single argument to call it with a ``NULL`` pointer): To find out the correct calling convention you have to look into the C header file or the documentation for the function you want to call. -On Windows, :mod:`ctypes` uses win32 structured exception handling to prevent +On Windows, :mod:`!ctypes` uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values:: @@ -192,7 +192,7 @@ argument values:: OSError: exception: access violation reading 0x00000020 >>> -There are, however, enough ways to crash Python with :mod:`ctypes`, so you +There are, however, enough ways to crash Python with :mod:`!ctypes`, so you should be careful anyway. The :mod:`faulthandler` module can be helpful in debugging crashes (e.g. from segmentation faults produced by erroneous C library calls). @@ -205,7 +205,7 @@ as pointer to the memory block that contains their data (:c:expr:`char *` or :c:expr:`int` type, their value is masked to fit into the C type. Before we move on calling functions with other parameter types, we have to learn -more about :mod:`ctypes` data types. +more about :mod:`!ctypes` data types. .. _ctypes-fundamental-data-types: @@ -213,7 +213,7 @@ more about :mod:`ctypes` data types. Fundamental data types ^^^^^^^^^^^^^^^^^^^^^^ -:mod:`ctypes` defines a number of primitive C compatible data types: +:mod:`!ctypes` defines a number of primitive C compatible data types: +----------------------+------------------------------------------+----------------------------+ | ctypes type | C type | Python type | @@ -397,7 +397,7 @@ from within *IDLE* or *PythonWin*:: >>> As has been mentioned before, all Python types except integers, strings, and -bytes objects have to be wrapped in their corresponding :mod:`ctypes` type, so +bytes objects have to be wrapped in their corresponding :mod:`!ctypes` type, so that they can be converted to the required C data type:: >>> printf(b"An int %d, a double %f\n", 1234, c_double(3.14)) @@ -431,10 +431,10 @@ specify :attr:`~_CFuncPtr.argtypes` for all variadic functions. Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can also customize :mod:`ctypes` argument conversion to allow instances of -your own classes be used as function arguments. :mod:`ctypes` looks for an +You can also customize :mod:`!ctypes` argument conversion to allow instances of +your own classes be used as function arguments. :mod:`!ctypes` looks for an :attr:`!_as_parameter_` attribute and uses this as the function argument. The -attribute must be an integer, string, bytes, a :mod:`ctypes` instance, or an +attribute must be an integer, string, bytes, a :mod:`!ctypes` instance, or an object with an :attr:`!_as_parameter_` attribute:: >>> class Bottles: @@ -490,7 +490,7 @@ the Python object passed to the function call, it should do a typecheck or whatever is needed to make sure this object is acceptable, and then return the object itself, its :attr:`!_as_parameter_` attribute, or whatever you want to pass as the C function argument in this case. Again, the result should be an -integer, string, bytes, a :mod:`ctypes` instance, or an object with an +integer, string, bytes, a :mod:`!ctypes` instance, or an object with an :attr:`!_as_parameter_` attribute. @@ -600,7 +600,7 @@ Sometimes a C api function expects a *pointer* to a data type as parameter, probably to write into the corresponding location, or if the data is too large to be passed by value. This is also known as *passing parameters by reference*. -:mod:`ctypes` exports the :func:`byref` function which is used to pass parameters +:mod:`!ctypes` exports the :func:`byref` function which is used to pass parameters by reference. The same effect can be achieved with the :func:`pointer` function, although :func:`pointer` does a lot more work since it constructs a real pointer object, so it is faster to use :func:`byref` if you don't need the pointer @@ -625,12 +625,12 @@ Structures and unions ^^^^^^^^^^^^^^^^^^^^^ Structures and unions must derive from the :class:`Structure` and :class:`Union` -base classes which are defined in the :mod:`ctypes` module. Each subclass must +base classes which are defined in the :mod:`!ctypes` module. Each subclass must define a :attr:`~Structure._fields_` attribute. :attr:`!_fields_` must be a list of *2-tuples*, containing a *field name* and a *field type*. -The field type must be a :mod:`ctypes` type like :class:`c_int`, or any other -derived :mod:`ctypes` type: structure, union, array, pointer. +The field type must be a :mod:`!ctypes` type like :class:`c_int`, or any other +derived :mod:`!ctypes` type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named *x* and *y*, and also shows how to initialize a structure in the constructor:: @@ -689,7 +689,7 @@ See :class:`CField`:: .. warning:: - :mod:`ctypes` does not support passing unions or structures with bit-fields + :mod:`!ctypes` does not support passing unions or structures with bit-fields to functions by value. While this may work on 32-bit x86, it's not guaranteed by the library to work in the general case. Unions and structures with bit-fields should always be passed to functions by pointer. @@ -707,7 +707,7 @@ structure itself by setting the class attributes :attr:`~Structure._pack_` and/or :attr:`~Structure._align_`, respectively. See the attribute documentation for details. -:mod:`ctypes` uses the native byte order for Structures and Unions. To build +:mod:`!ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the :class:`BigEndianStructure`, :class:`LittleEndianStructure`, :class:`BigEndianUnion`, and :class:`LittleEndianUnion` base classes. These @@ -796,7 +796,7 @@ Pointers ^^^^^^^^ Pointer instances are created by calling the :func:`pointer` function on a -:mod:`ctypes` type:: +:mod:`!ctypes` type:: >>> from ctypes import * >>> i = c_int(42) @@ -810,7 +810,7 @@ returns the object to which the pointer points, the ``i`` object above:: c_long(42) >>> -Note that :mod:`ctypes` does not have OOR (original object return), it constructs a +Note that :mod:`!ctypes` does not have OOR (original object return), it constructs a new, equivalent object each time you retrieve an attribute:: >>> pi.contents is i @@ -854,7 +854,7 @@ item. Behind the scenes, the :func:`pointer` function does more than simply create pointer instances, it has to create pointer *types* first. This is done with the -:func:`POINTER` function, which accepts any :mod:`ctypes` type, and returns a +:func:`POINTER` function, which accepts any :mod:`!ctypes` type, and returns a new type:: >>> PI = POINTER(c_int) @@ -876,7 +876,7 @@ Calling the pointer type without an argument creates a ``NULL`` pointer. False >>> -:mod:`ctypes` checks for ``NULL`` when dereferencing pointers (but dereferencing +:mod:`!ctypes` checks for ``NULL`` when dereferencing pointers (but dereferencing invalid non-\ ``NULL`` pointers would crash Python):: >>> null_ptr[0] @@ -961,7 +961,7 @@ To set a POINTER type field to ``NULL``, you can assign ``None``:: .. XXX list other conversions... Sometimes you have instances of incompatible types. In C, you can cast one type -into another type. :mod:`ctypes` provides a :func:`cast` function which can be +into another type. :mod:`!ctypes` provides a :func:`cast` function which can be used in the same way. The ``Bar`` structure defined above accepts ``POINTER(c_int)`` pointers or :class:`c_int` arrays for its ``values`` field, but not instances of other types:: @@ -1025,7 +1025,7 @@ work:: >>> because the new ``class cell`` is not available in the class statement itself. -In :mod:`ctypes`, we can define the ``cell`` class and set the +In :mod:`!ctypes`, we can define the ``cell`` class and set the :attr:`~Structure._fields_` attribute later, after the class statement:: >>> from ctypes import * @@ -1059,7 +1059,7 @@ other, and finally follow the pointer chain a few times:: Callback functions ^^^^^^^^^^^^^^^^^^ -:mod:`ctypes` allows creating C callable function pointers from Python callables. +:mod:`!ctypes` allows creating C callable function pointers from Python callables. These are sometimes called *callback functions*. First, you must create a class for the callback function. The class knows the @@ -1158,7 +1158,7 @@ write:: .. note:: Make sure you keep references to :func:`CFUNCTYPE` objects as long as they - are used from C code. :mod:`ctypes` doesn't, and if you don't, they may be + are used from C code. :mod:`!ctypes` doesn't, and if you don't, they may be garbage collected, crashing your program when a callback is made. Also, note that if the callback function is called in a thread created @@ -1177,7 +1177,7 @@ Some shared libraries not only export functions, they also export variables. An example in the Python library itself is the :c:data:`Py_Version`, Python runtime version number encoded in a single constant integer. -:mod:`ctypes` can access values like this with the :meth:`~_CData.in_dll` class methods of +:mod:`!ctypes` can access values like this with the :meth:`~_CData.in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: @@ -1196,7 +1196,7 @@ Quoting the docs for that value: tricks with this to provide a dynamically created collection of frozen modules. So manipulating this pointer could even prove useful. To restrict the example -size, we show only how this table can be read with :mod:`ctypes`:: +size, we show only how this table can be read with :mod:`!ctypes`:: >>> from ctypes import * >>> @@ -1242,7 +1242,7 @@ for testing. Try it out with ``import __hello__`` for example. Surprises ^^^^^^^^^ -There are some edges in :mod:`ctypes` where you might expect something other +There are some edges in :mod:`!ctypes` where you might expect something other than what actually happens. Consider the following example:: @@ -1310,7 +1310,7 @@ constructs a new Python object each time! Variable-sized data types ^^^^^^^^^^^^^^^^^^^^^^^^^ -:mod:`ctypes` provides some support for variable-sized arrays and structures. +:mod:`!ctypes` provides some support for variable-sized arrays and structures. The :func:`resize` function can be used to resize the memory buffer of an existing ctypes object. The function takes the object as first argument, and @@ -1344,7 +1344,7 @@ get errors accessing other elements:: IndexError: invalid index >>> -Another way to use variable-sized data types with :mod:`ctypes` is to use the +Another way to use variable-sized data types with :mod:`!ctypes` is to use the dynamic nature of Python, and (re-)define the data type after the required size is already known, on a case by case basis. @@ -1425,7 +1425,7 @@ On Windows, :func:`~ctypes.util.find_library` searches along the system search p returns the full pathname, but since there is no predefined naming scheme a call like ``find_library("c")`` will fail and return ``None``. -If wrapping a shared library with :mod:`ctypes`, it *may* be better to determine +If wrapping a shared library with :mod:`!ctypes`, it *may* be better to determine the shared library name at development time, and hardcode that into the wrapper module instead of using :func:`~ctypes.util.find_library` to locate the library at runtime. @@ -1551,7 +1551,7 @@ configurable. The *use_errno* parameter, when set to true, enables a ctypes mechanism that allows accessing the system :data:`errno` error number in a safe way. -:mod:`ctypes` maintains a thread-local copy of the system's :data:`errno` +:mod:`!ctypes` maintains a thread-local copy of the system's :data:`errno` variable; if you call foreign functions created with ``use_errno=True`` then the :data:`errno` value before the function call is swapped with the ctypes private copy, the same happens immediately after the function call. @@ -1929,7 +1929,7 @@ the windows header file is this:: LPCWSTR lpCaption, UINT uType); -Here is the wrapping with :mod:`ctypes`:: +Here is the wrapping with :mod:`!ctypes`:: >>> from ctypes import c_int, WINFUNCTYPE, windll >>> from ctypes.wintypes import HWND, LPCWSTR, UINT @@ -1952,7 +1952,7 @@ function retrieves the dimensions of a specified window by copying them into HWND hWnd, LPRECT lpRect); -Here is the wrapping with :mod:`ctypes`:: +Here is the wrapping with :mod:`!ctypes`:: >>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError >>> from ctypes.wintypes import BOOL, HWND, RECT @@ -1980,7 +1980,7 @@ do the error checking, and raises an exception when the api call failed:: >>> If the :attr:`~_CFuncPtr.errcheck` function returns the argument tuple it receives -unchanged, :mod:`ctypes` continues the normal processing it does on the output +unchanged, :mod:`!ctypes` continues the normal processing it does on the output parameters. If you want to return a tuple of window coordinates instead of a ``RECT`` instance, you can retrieve the fields in the function and return them instead, the normal processing will no longer take place:: @@ -2450,7 +2450,7 @@ Fundamental data types Python bytes object or string. When the ``value`` attribute is retrieved from a ctypes instance, usually - a new object is returned each time. :mod:`ctypes` does *not* implement + a new object is returned each time. :mod:`!ctypes` does *not* implement original object return, always a new object is constructed. The same is true for all other ctypes object instances. @@ -2749,7 +2749,7 @@ fields, or any other data types containing pointer type fields. Abstract base class for structures in *native* byte order. Concrete structure and union types must be created by subclassing one of these - types, and at least define a :attr:`_fields_` class variable. :mod:`ctypes` will + types, and at least define a :attr:`_fields_` class variable. :mod:`!ctypes` will create :term:`descriptor`\s which allow reading and writing the fields by direct attribute accesses. These are the @@ -2803,7 +2803,7 @@ fields, or any other data types containing pointer type fields. Setting :attr:`!_pack_` to 0 is the same as not setting it at all. Otherwise, the value must be a positive power of two. The effect is equivalent to ``#pragma pack(N)`` in C, except - :mod:`ctypes` may allow larger *n* than what the compiler accepts. + :mod:`!ctypes` may allow larger *n* than what the compiler accepts. :attr:`!_pack_` must already be defined when :attr:`_fields_` is assigned, otherwise it will have no effect. @@ -2824,7 +2824,7 @@ fields, or any other data types containing pointer type fields. The value must not be negative. The effect is equivalent to ``__attribute__((aligned(N)))`` on GCC - or ``#pragma align(N)`` on MSVC, except :mod:`ctypes` may allow + or ``#pragma align(N)`` on MSVC, except :mod:`!ctypes` may allow values that the compiler would reject. :attr:`!_align_` can only *increase* a structure's alignment @@ -2873,7 +2873,7 @@ fields, or any other data types containing pointer type fields. assigned, otherwise it will have no effect. The fields listed in this variable must be structure or union type fields. - :mod:`ctypes` will create descriptors in the structure type that allows + :mod:`!ctypes` will create descriptors in the structure type that allows accessing the nested fields directly, without the need to create the structure or union field. @@ -3017,7 +3017,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 non-negative 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 @@ -3043,7 +3043,7 @@ Arrays and pointers Create an array. Equivalent to ``type * length``, where *type* is a - :mod:`ctypes` data type and *length* an integer. + :mod:`!ctypes` data type and *length* an integer. This function is :term:`soft deprecated` in favor of multiplication. There are no plans to remove it. diff --git a/Doc/library/curses.ascii.rst b/Doc/library/curses.ascii.rst index cb895664ff1b11..4910954b7784b0 100644 --- a/Doc/library/curses.ascii.rst +++ b/Doc/library/curses.ascii.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`curses.ascii` module supplies name constants for ASCII characters and +The :mod:`!curses.ascii` module supplies name constants for ASCII characters and functions to test membership in various ASCII character classes. The constants supplied are names for control characters as follows: diff --git a/Doc/library/curses.panel.rst b/Doc/library/curses.panel.rst index 11fd841d381f69..e52f588c5bc337 100644 --- a/Doc/library/curses.panel.rst +++ b/Doc/library/curses.panel.rst @@ -18,7 +18,7 @@ displayed. Panels can be added, moved up or down in the stack, and removed. Functions --------- -The module :mod:`curses.panel` defines the following functions: +The module :mod:`!curses.panel` defines the following functions: .. function:: bottom_panel() diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 057d338edda92a..397584e70bf4ce 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -13,7 +13,7 @@ -------------- -The :mod:`curses` module provides an interface to the curses library, the +The :mod:`!curses` module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling. While curses is most widely used in the Unix environment, versions are available @@ -54,7 +54,7 @@ Linux and the BSD variants of Unix. Functions --------- -The module :mod:`curses` defines the following exception: +The module :mod:`!curses` defines the following exception: .. exception:: error @@ -67,7 +67,7 @@ The module :mod:`curses` defines the following exception: default to the current cursor location. Whenever *attr* is optional, it defaults to :const:`A_NORMAL`. -The module :mod:`curses` defines the following functions: +The module :mod:`!curses` defines the following functions: .. function:: assume_default_colors(fg, bg, /) @@ -581,7 +581,7 @@ The module :mod:`curses` defines the following functions: after :func:`initscr`. :func:`start_color` initializes eight basic colors (black, red, green, yellow, - blue, magenta, cyan, and white), and two global variables in the :mod:`curses` + blue, magenta, cyan, and white), and two global variables in the :mod:`!curses` module, :const:`COLORS` and :const:`COLOR_PAIRS`, containing the maximum number of colors and color-pairs the terminal can support. It also restores the colors on the terminal to the values they had when the terminal was just turned on. @@ -1021,7 +1021,7 @@ Window Objects .. method:: window.idlok(flag) - If *flag* is ``True``, :mod:`curses` will try and use hardware line + If *flag* is ``True``, :mod:`!curses` will try and use hardware line editing facilities. Otherwise, line insertion/deletion are disabled. @@ -1109,7 +1109,7 @@ Window Objects .. method:: window.keypad(flag) If *flag* is ``True``, escape sequences generated by some keys (keypad, function keys) - will be interpreted by :mod:`curses`. If *flag* is ``False``, escape sequences will be + will be interpreted by :mod:`!curses`. If *flag* is ``False``, escape sequences will be left as is in the input stream. @@ -1335,7 +1335,7 @@ Window Objects Constants --------- -The :mod:`curses` module defines the following data members: +The :mod:`!curses` module defines the following data members: .. data:: ERR diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 02eb68d7b49b04..64201af2d22a58 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -8,7 +8,7 @@ -------------- -:mod:`dbm` is a generic interface to variants of the DBM database: +:mod:`!dbm` is a generic interface to variants of the DBM database: * :mod:`dbm.sqlite3` * :mod:`dbm.gnu` @@ -107,7 +107,7 @@ will automatically close them when done. .. versionchanged:: 3.2 :meth:`!get` and :meth:`!setdefault` methods are now available for all - :mod:`dbm` backends. + :mod:`!dbm` backends. .. versionchanged:: 3.4 Added native support for the context management protocol to the objects @@ -118,7 +118,7 @@ will automatically close them when done. instead of :exc:`KeyError`. .. versionchanged:: 3.13 - :meth:`!clear` methods are now available for all :mod:`dbm` backends. + :meth:`!clear` methods are now available for all :mod:`!dbm` backends. The following example records some hostnames and a corresponding title, and @@ -171,7 +171,7 @@ The individual submodules are described in the following sections. -------------- This module uses the standard library :mod:`sqlite3` module to provide an -SQLite backend for the :mod:`dbm` module. +SQLite backend for the :mod:`!dbm` module. The files created by :mod:`dbm.sqlite3` can thus be opened by :mod:`sqlite3`, or any other SQLite browser, including the SQLite CLI. @@ -215,7 +215,7 @@ or any other SQLite browser, including the SQLite CLI. .. note:: While reorganizing, as much as two times the size of the original database is required - in free disk space. However, be aware that this factor changes for each :mod:`dbm` submodule. + in free disk space. However, be aware that this factor changes for each :mod:`!dbm` submodule. .. versionadded:: 3.15 @@ -335,7 +335,7 @@ functionality like crash tolerance. .. note:: While reorganizing, as much as one time the size of the original database is required - in free disk space. However, be aware that this factor changes for each :mod:`dbm` submodule. + in free disk space. However, be aware that this factor changes for each :mod:`!dbm` submodule. .. method:: gdbm.sync() @@ -438,7 +438,7 @@ This module can be used with the "classic" NDBM interface or the .. note:: The :mod:`dbm.dumb` module is intended as a last resort fallback for the - :mod:`dbm` module when a more robust module is not available. The :mod:`dbm.dumb` + :mod:`!dbm` module when a more robust module is not available. The :mod:`dbm.dumb` module is not written for speed and is not nearly as heavily used as the other database modules. @@ -446,7 +446,7 @@ This module can be used with the "classic" NDBM interface or the The :mod:`dbm.dumb` module provides a persistent :class:`dict`-like interface which is written entirely in Python. -Unlike other :mod:`dbm` backends, such as :mod:`dbm.gnu`, no +Unlike other :mod:`!dbm` backends, such as :mod:`dbm.gnu`, no external library is required. The :mod:`!dbm.dumb` module defines the following: @@ -517,7 +517,7 @@ The :mod:`!dbm.dumb` module defines the following: .. note:: While reorganizing, no additional free disk space is required. However, be aware - that this factor changes for each :mod:`dbm` submodule. + that this factor changes for each :mod:`!dbm` submodule. .. versionadded:: 3.15 diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 376bcc7aaf9eb2..17b1604dd0ee9b 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -30,7 +30,7 @@ -------------- -The :mod:`decimal` module provides support for fast correctly rounded +The :mod:`!decimal` module provides support for fast correctly rounded decimal floating-point arithmetic. It offers several advantages over the :class:`float` datatype: @@ -289,7 +289,7 @@ For more advanced work, it may be useful to create alternate contexts using the :meth:`Context` constructor. To make an alternate active, use the :func:`setcontext` function. -In accordance with the standard, the :mod:`decimal` module provides two ready to +In accordance with the standard, the :mod:`!decimal` module provides two ready to use standard contexts, :const:`BasicContext` and :const:`ExtendedContext`. The former is especially useful for debugging because many of the traps are enabled: @@ -1847,7 +1847,7 @@ properties of addition: >>> u * (v+w) Decimal('0.0060000') -The :mod:`decimal` module makes it possible to restore the identities by +The :mod:`!decimal` module makes it possible to restore the identities by expanding the precision sufficiently to avoid loss of significance: .. doctest:: newcontext @@ -1869,7 +1869,7 @@ expanding the precision sufficiently to avoid loss of significance: Special values ^^^^^^^^^^^^^^ -The number system for the :mod:`decimal` module provides special values +The number system for the :mod:`!decimal` module provides special values including ``NaN``, ``sNaN``, ``-Infinity``, ``Infinity``, and two zeros, ``+0`` and ``-0``. diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 1486eeb3053da4..1f7014e9cd426f 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -14,7 +14,7 @@ -------------- -The :mod:`dis` module supports the analysis of CPython :term:`bytecode` by +The :mod:`!dis` module supports the analysis of CPython :term:`bytecode` by disassembling it. The CPython bytecode which this module takes as an input is defined in the file :file:`Include/opcode.h` and used by the compiler and the interpreter. @@ -38,7 +38,7 @@ interpreter. Some instructions are accompanied by one or more inline cache entries, which take the form of :opcode:`CACHE` instructions. These instructions are hidden by default, but can be shown by passing ``show_caches=True`` to - any :mod:`dis` utility. Furthermore, the interpreter now adapts the + any :mod:`!dis` utility. Furthermore, the interpreter now adapts the bytecode to specialize it for different runtime conditions. The adaptive bytecode can be shown by passing ``adaptive=True``. @@ -87,7 +87,7 @@ the following command can be used to display the disassembly of Command-line interface ---------------------- -The :mod:`dis` module can be invoked as a script from the command line: +The :mod:`!dis` module can be invoked as a script from the command line: .. code-block:: sh @@ -223,7 +223,7 @@ Example: Analysis functions ------------------ -The :mod:`dis` module also defines the following analysis functions that convert +The :mod:`!dis` module also defines the following analysis functions that convert the input directly to the desired output. They can be useful if only a single operation is being performed, so the intermediate analysis object isn't useful: @@ -1827,7 +1827,7 @@ iterations of the loop. ignore it. Before, only opcodes ``>= HAVE_ARGUMENT`` had an argument. .. versionchanged:: 3.12 - Pseudo instructions were added to the :mod:`dis` module, and for them + Pseudo instructions were added to the :mod:`!dis` module, and for them it is not true that comparison with ``HAVE_ARGUMENT`` indicates whether they use their arg. diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index df3de8f622a091..3bc0f88d229681 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -13,7 +13,7 @@ -------------- -The :mod:`doctest` module searches for pieces of text that look like interactive +The :mod:`!doctest` module searches for pieces of text that look like interactive Python sessions, and then executes those sessions to verify that they work exactly as shown. There are several common ways to use doctest: @@ -85,7 +85,7 @@ Here's a complete but small example module:: import doctest doctest.testmod() -If you run :file:`example.py` directly from the command line, :mod:`doctest` +If you run :file:`example.py` directly from the command line, :mod:`!doctest` works its magic: .. code-block:: shell-session @@ -94,7 +94,7 @@ works its magic: $ There's no output! That's normal, and it means all the examples worked. Pass -``-v`` to the script, and :mod:`doctest` prints a detailed log of what +``-v`` to the script, and :mod:`!doctest` prints a detailed log of what it's trying, and prints a summary at the end: .. code-block:: shell-session @@ -130,7 +130,7 @@ And so on, eventually ending with: Test passed. $ -That's all you need to know to start making productive use of :mod:`doctest`! +That's all you need to know to start making productive use of :mod:`!doctest`! Jump in. The following sections provide full details. Note that there are many examples of doctests in the standard Python test suite and libraries. Especially useful examples can be found in the standard test file @@ -252,7 +252,7 @@ For more information on :func:`testfile`, see section :ref:`doctest-basic-api`. Command-line Usage ------------------ -The :mod:`doctest` module can be invoked as a script from the command line: +The :mod:`!doctest` module can be invoked as a script from the command line: .. code-block:: bash @@ -450,7 +450,7 @@ The fine print: What's the Execution Context? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -By default, each time :mod:`doctest` finds a docstring to test, it uses a +By default, each time :mod:`!doctest` finds a docstring to test, it uses a *shallow copy* of :mod:`!M`'s globals, so that running tests doesn't change the module's real globals, and so that one test in :mod:`!M` can't leave behind crumbs that accidentally allow another test to work. This means examples can @@ -730,7 +730,7 @@ The second group of options controls how test failures are reported: There is also a way to register new option flag names, though this isn't -useful unless you intend to extend :mod:`doctest` internals via subclassing: +useful unless you intend to extend :mod:`!doctest` internals via subclassing: .. function:: register_optionflag(name) @@ -833,7 +833,7 @@ disabling an option via ``-`` in a directive can be useful. Warnings ^^^^^^^^ -:mod:`doctest` is serious about requiring exact matches in expected output. If +:mod:`!doctest` is serious about requiring exact matches in expected output. If even a single character doesn't match, the test fails. This will probably surprise you a few times, as you learn exactly what Python does and doesn't guarantee about output. For example, when printing a set, Python doesn't @@ -1035,7 +1035,7 @@ Unittest API ------------ As your collection of doctest'ed modules grows, you'll want a way to run all -their doctests systematically. :mod:`doctest` provides two functions that can +their doctests systematically. :mod:`!doctest` provides two functions that can be used to create :mod:`unittest` test suites from modules and text files containing doctests. To integrate with :mod:`unittest` test discovery, include a :ref:`load_tests ` function in your test module:: @@ -1179,7 +1179,7 @@ of :class:`!DocTestCase`. So both ways of creating a :class:`unittest.TestSuite` run instances of :class:`!DocTestCase`. This is important for a subtle reason: when you run -:mod:`doctest` functions yourself, you can control the :mod:`!doctest` options in +:mod:`!doctest` functions yourself, you can control the :mod:`!doctest` options in use directly, by passing option flags to :mod:`!doctest` functions. However, if you're writing a :mod:`unittest` framework, :mod:`!unittest` ultimately controls when and how tests get run. The framework author typically wants to control @@ -1187,13 +1187,13 @@ when and how tests get run. The framework author typically wants to control options), but there's no way to pass options through :mod:`!unittest` to :mod:`!doctest` test runners. -For this reason, :mod:`doctest` also supports a notion of :mod:`!doctest` +For this reason, :mod:`!doctest` also supports a notion of :mod:`!doctest` reporting flags specific to :mod:`unittest` support, via this function: .. function:: set_unittest_reportflags(flags) - Set the :mod:`doctest` reporting flags to use. + Set the :mod:`!doctest` reporting flags to use. Argument *flags* takes the :ref:`bitwise OR ` of option flags. See section :ref:`doctest-options`. Only "reporting flags" can be used. @@ -1923,7 +1923,7 @@ There are two exceptions that may be raised by :class:`DebugRunner` instances: Soapbox ------- -As mentioned in the introduction, :mod:`doctest` has grown to have three primary +As mentioned in the introduction, :mod:`!doctest` has grown to have three primary uses: #. Checking examples in docstrings. @@ -1941,7 +1941,7 @@ this that needs to be learned---it may not be natural at first. Examples should add genuine value to the documentation. A good example can often be worth many words. If done with care, the examples will be invaluable for your users, and will pay back the time it takes to collect them many times over as the years go -by and things change. I'm still amazed at how often one of my :mod:`doctest` +by and things change. I'm still amazed at how often one of my :mod:`!doctest` examples stops working after a "harmless" change. Doctest also makes an excellent tool for regression testing, especially if you diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst index 6875af2be49d7a..76a57031862c85 100644 --- a/Doc/library/email.charset.rst +++ b/Doc/library/email.charset.rst @@ -19,7 +19,7 @@ registry and several convenience methods for manipulating this registry. Instances of :class:`Charset` are used in several other modules within the :mod:`email` package. -Import this class from the :mod:`email.charset` module. +Import this class from the :mod:`!email.charset` module. .. class:: Charset(input_charset=DEFAULT_CHARSET) @@ -164,7 +164,7 @@ Import this class from the :mod:`email.charset` module. This method allows you to compare two :class:`Charset` instances for inequality. -The :mod:`email.charset` module also provides the following functions for adding +The :mod:`!email.charset` module also provides the following functions for adding new entries to the global character set, alias, and codec registries: diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 689e7397cbcf1f..2f7c9140cfcbe5 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -8,7 +8,7 @@ -------------- -The following exception classes are defined in the :mod:`email.errors` module: +The following exception classes are defined in the :mod:`!email.errors` module: .. exception:: MessageError() diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index a3132d02687bc9..6f4f813a0f84d8 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -232,7 +232,7 @@ a formatted string representation of a message object. For more detail, see :mod:`email.message`. -The :mod:`email.generator` module also provides a derived class, +The :mod:`!email.generator` module also provides a derived class, :class:`DecodedGenerator`, which is like the :class:`Generator` base class, except that non-\ :mimetype:`text` parts are not serialized, but are instead represented in the output stream by a string derived from a template filled diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst index f49885b8785235..e7e21d036e07de 100644 --- a/Doc/library/email.header.rst +++ b/Doc/library/email.header.rst @@ -28,13 +28,13 @@ transferred using only 7-bit ASCII characters, so a slew of RFCs have been written describing how to encode email containing non-ASCII characters into :rfc:`2822`\ -compliant format. These RFCs include :rfc:`2045`, :rfc:`2046`, :rfc:`2047`, and :rfc:`2231`. The :mod:`email` package supports these standards -in its :mod:`email.header` and :mod:`email.charset` modules. +in its :mod:`!email.header` and :mod:`email.charset` modules. If you want to include non-ASCII characters in your email headers, say in the :mailheader:`Subject` or :mailheader:`To` fields, you should use the :class:`Header` class and assign the field in the :class:`~email.message.Message` object to an instance of :class:`Header` instead of using a string for the header -value. Import the :class:`Header` class from the :mod:`email.header` module. +value. Import the :class:`Header` class from the :mod:`!email.header` module. For example:: >>> from email.message import Message @@ -170,7 +170,7 @@ Here is the :class:`Header` class description: This method allows you to compare two :class:`Header` instances for inequality. -The :mod:`email.header` module also provides the following convenient functions. +The :mod:`!email.header` module also provides the following convenient functions. .. function:: decode_header(header) diff --git a/Doc/library/email.iterators.rst b/Doc/library/email.iterators.rst index 090981d84b4de3..ed300cdb30fdd6 100644 --- a/Doc/library/email.iterators.rst +++ b/Doc/library/email.iterators.rst @@ -10,7 +10,7 @@ Iterating over a message object tree is fairly easy with the :meth:`Message.walk ` method. The -:mod:`email.iterators` module provides some useful higher level iterations over +:mod:`!email.iterators` module provides some useful higher level iterations over message object trees. diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 0aa8e632c2ca80..f6908d2e6e9748 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -14,7 +14,7 @@ .. versionadded:: 3.6 [1]_ The central class in the :mod:`email` package is the :class:`EmailMessage` -class, imported from the :mod:`email.message` module. It is the base class for +class, imported from the :mod:`!email.message` module. It is the base class for the :mod:`email` object model. :class:`EmailMessage` provides the core functionality for setting and querying header fields, for accessing message bodies, and for creating or modifying structured messages. diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst index 6a70714dc3ee42..e0fcce8f0cbb8c 100644 --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -125,10 +125,10 @@ Here is the API for the :class:`BytesFeedParser`: Parser API ^^^^^^^^^^ -The :class:`BytesParser` class, imported from the :mod:`email.parser` module, +The :class:`BytesParser` class, imported from the :mod:`!email.parser` module, provides an API that can be used to parse a message when the complete contents of the message are available in a :term:`bytes-like object` or file. The -:mod:`email.parser` module also provides :class:`Parser` for parsing strings, +:mod:`!email.parser` module also provides :class:`Parser` for parsing strings, and header-only parsers, :class:`BytesHeaderParser` and :class:`HeaderParser`, which can be used if you're only interested in the headers of the message. :class:`BytesHeaderParser` and :class:`HeaderParser` diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 66c42e4a5008ee..03ac1783be08bd 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -12,10 +12,10 @@ -------------- -The :mod:`email` package is a library for managing email messages. It is +The :mod:`!email` package is a library for managing email messages. It is specifically *not* designed to do any sending of email messages to SMTP (:rfc:`2821`), NNTP, or other servers; those are functions of modules such as -:mod:`smtplib`. The :mod:`email` package attempts to be as +:mod:`smtplib`. The :mod:`!email` package attempts to be as RFC-compliant as possible, supporting :rfc:`5322` and :rfc:`6532`, as well as such MIME-related RFCs as :rfc:`2045`, :rfc:`2046`, :rfc:`2047`, :rfc:`2183`, and :rfc:`2231`. @@ -68,7 +68,7 @@ high level structure in question, and not the details of how those structures are represented. Since MIME content types are used widely in modern internet software (not just email), this will be a familiar concept to many programmers. -The following sections describe the functionality of the :mod:`email` package. +The following sections describe the functionality of the :mod:`!email` package. We start with the :mod:`~email.message` object model, which is the primary interface an application will use, and follow that with the :mod:`~email.parser` and :mod:`~email.generator` components. Then we cover the @@ -102,7 +102,7 @@ compatibility reasons. :class:`~email.message.EmailMessage`/:class:`~email.policy.EmailPolicy` API. -Contents of the :mod:`email` package documentation: +Contents of the :mod:`!email` package documentation: .. toctree:: diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 611549604fda15..e0d2c19a3b0737 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -8,7 +8,7 @@ -------------- -There are a couple of useful utilities provided in the :mod:`email.utils` +There are a couple of useful utilities provided in the :mod:`!email.utils` module: .. function:: localtime(dt=None) diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index 32b92c01570004..e0d77229b11802 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`ensurepip` package provides support for bootstrapping the ``pip`` +The :mod:`!ensurepip` package provides support for bootstrapping the ``pip`` installer into an existing Python installation or virtual environment. This bootstrapping approach reflects the fact that ``pip`` is an independent project with its own release cycle, and the latest available stable version @@ -99,7 +99,7 @@ Providing both of the script selection options will trigger an exception. Module API ---------- -:mod:`ensurepip` exposes two functions for programmatic use: +:mod:`!ensurepip` exposes two functions for programmatic use: .. function:: version() diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index f57fcdf0bcf26d..2c9e883f56904f 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -53,7 +53,7 @@ descriptor. the latter setting ``FD_CLOEXEC`` flag in addition. .. versionchanged:: 3.12 - On Linux >= 4.5, the :mod:`fcntl` module exposes the ``FICLONE`` and + On Linux >= 4.5, the :mod:`!fcntl` module exposes the ``FICLONE`` and ``FICLONERANGE`` constants, which allow to share some data of one file with another file by reflinking on some filesystems (e.g., btrfs, OCFS2, and XFS). This behavior is commonly referred to as "copy-on-write". @@ -91,7 +91,7 @@ The module defines the following functions: Perform the operation *cmd* on file descriptor *fd* (file objects providing a :meth:`~io.IOBase.fileno` method are accepted as well). The values used for *cmd* are operating system dependent, and are available as constants - in the :mod:`fcntl` module, using the same names as used in the relevant C + in the :mod:`!fcntl` module, using the same names as used in the relevant C header files. The argument *arg* can either be an integer value, a :term:`bytes-like object`, or a string. The type and size of *arg* must match the type and size of diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst index abd1b8c826d170..e87a7869685d04 100644 --- a/Doc/library/filecmp.rst +++ b/Doc/library/filecmp.rst @@ -10,11 +10,11 @@ -------------- -The :mod:`filecmp` module defines functions to compare files and directories, +The :mod:`!filecmp` module defines functions to compare files and directories, with various optional time/correctness trade-offs. For comparing files, see also the :mod:`difflib` module. -The :mod:`filecmp` module defines the following functions: +The :mod:`!filecmp` module defines the following functions: .. function:: cmp(f1, f2, shallow=True) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index d6d1c7a461c51c..575e90942d48b0 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`fractions` module provides support for rational number arithmetic. +The :mod:`!fractions` module provides support for rational number arithmetic. A Fraction instance can be constructed from a pair of rational numbers, from diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 88eb0be9de88b8..e1baeff3f373bf 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -23,7 +23,7 @@ The default encoding is UTF-8, following :rfc:`2640`. .. include:: ../includes/wasm-notavail.rst -Here's a sample session using the :mod:`ftplib` module:: +Here's a sample session using the :mod:`!ftplib` module:: >>> from ftplib import FTP >>> ftp = FTP('ftp.us.debian.org') # connect to host, default port diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index b7c34bc64135ba..f09e4c0536639e 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -20,11 +20,11 @@ -------------- -The :mod:`functools` module is for higher-order functions: functions that act on +The :mod:`!functools` module is for higher-order functions: functions that act on or return other functions. In general, any callable object can be treated as a function for the purposes of this module. -The :mod:`functools` module defines the following functions: +The :mod:`!functools` module defines the following functions: .. decorator:: cache(user_function) diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 0e041b5395ec93..250c31e7eee63f 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -20,7 +20,7 @@ can be disabled by calling ``gc.disable()``. To debug a leaking program call ``gc.DEBUG_SAVEALL``, causing garbage-collected objects to be saved in gc.garbage for inspection. -The :mod:`gc` module provides the following functions: +The :mod:`!gc` module provides the following functions: .. function:: enable() diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index a0c0c6dee2d513..37ffbe1be55a73 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -14,7 +14,7 @@ .. include:: ../includes/wasm-notavail.rst -The :mod:`getpass` module provides two functions: +The :mod:`!getpass` module provides two functions: .. function:: getpass(prompt='Password: ', stream=None, *, echo_char=None) diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index d0de83907eb297..ddd0188e6614e8 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`gettext` module provides internationalization (I18N) and localization +The :mod:`!gettext` module provides internationalization (I18N) and localization (L10N) services for your Python modules and applications. It supports both the GNU :program:`gettext` message catalog API and a higher level, class-based API that may be more appropriate for Python files. The interface described below allows you @@ -25,7 +25,7 @@ Some hints on localizing your Python modules and applications are also given. GNU :program:`gettext` API -------------------------- -The :mod:`gettext` module defines the following API, which is very similar to +The :mod:`!gettext` module defines the following API, which is very similar to the GNU :program:`gettext` API. If you use this API you will affect the translation of your entire application globally. Often this is what you want if your application is monolingual, with the choice of language dependent on the @@ -37,7 +37,7 @@ class-based API instead. .. function:: bindtextdomain(domain, localedir=None) Bind the *domain* to the locale directory *localedir*. More concretely, - :mod:`gettext` will look for binary :file:`.mo` files for the given domain using + :mod:`!gettext` will look for binary :file:`.mo` files for the given domain using the path (on Unix): :file:`{localedir}/{language}/LC_MESSAGES/{domain}.mo`, where *language* is searched for in the environment variables :envvar:`LANGUAGE`, :envvar:`LC_ALL`, :envvar:`LC_MESSAGES`, and :envvar:`LANG` respectively. @@ -114,7 +114,7 @@ Here's an example of typical usage for this API:: Class-based API --------------- -The class-based API of the :mod:`gettext` module gives you more flexibility and +The class-based API of the :mod:`!gettext` module gives you more flexibility and greater convenience than the GNU :program:`gettext` API. It is the recommended way of localizing your Python applications and modules. :mod:`!gettext` defines a :class:`GNUTranslations` class which implements the parsing of GNU :file:`.mo` format @@ -393,7 +393,7 @@ The Catalog constructor .. index:: single: GNOME -GNOME uses a version of the :mod:`gettext` module by James Henstridge, but this +GNOME uses a version of the :mod:`!gettext` module by James Henstridge, but this version has a slightly different API. Its documented usage was:: import gettext @@ -425,7 +425,7 @@ take the following steps: #. create language-specific translations of the message catalogs -#. use the :mod:`gettext` module so that message strings are properly translated +#. use the :mod:`!gettext` module so that message strings are properly translated In order to prepare your code for I18N, you need to look at all the strings in your files. Any string that needs to be translated should be marked by wrapping @@ -473,10 +473,10 @@ supported natural language. They send back the completed language-specific versions as a :file:`.po` file that's compiled into a machine-readable :file:`.mo` binary catalog file using the :program:`msgfmt` program. The :file:`.mo` files are used by the -:mod:`gettext` module for the actual translation processing at +:mod:`!gettext` module for the actual translation processing at run-time. -How you use the :mod:`gettext` module in your code depends on whether you are +How you use the :mod:`!gettext` module in your code depends on whether you are internationalizing a single module or your entire application. The next two sections will discuss each case. diff --git a/Doc/library/graphlib.rst b/Doc/library/graphlib.rst index 053d5f8231ba0e..21f4d1fb938038 100644 --- a/Doc/library/graphlib.rst +++ b/Doc/library/graphlib.rst @@ -204,7 +204,7 @@ Exceptions ---------- -The :mod:`graphlib` module defines the following exception classes: +The :mod:`!graphlib` module defines the following exception classes: .. exception:: CycleError diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index d23c0741ddbecd..ed9fdaf1d727b0 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -15,7 +15,7 @@ like the GNU programs :program:`gzip` and :program:`gunzip` would. The data compression is provided by the :mod:`zlib` module. -The :mod:`gzip` module provides the :class:`GzipFile` class, as well as the +The :mod:`!gzip` module provides the :class:`GzipFile` class, as well as the :func:`.open`, :func:`compress` and :func:`decompress` convenience functions. The :class:`GzipFile` class reads and writes :program:`gzip`\ -format files, automatically compressing or decompressing the data so that it looks like an @@ -286,10 +286,10 @@ Example of how to GZIP compress a binary string:: Command-line interface ---------------------- -The :mod:`gzip` module provides a simple command line interface to compress or +The :mod:`!gzip` module provides a simple command line interface to compress or decompress files. -Once executed the :mod:`gzip` module keeps the input file(s). +Once executed the :mod:`!gzip` module keeps the input file(s). .. versionchanged:: 3.8 diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index b21ecdaede622a..542a72d4afe933 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -61,7 +61,7 @@ if you are using a rare "FIPS compliant" build of Python. These correspond to :data:`algorithms_guaranteed`. Additional algorithms may also be available if your Python distribution's -:mod:`hashlib` was linked against a build of OpenSSL that provides others. +:mod:`!hashlib` was linked against a build of OpenSSL that provides others. Others *are not guaranteed available* on all installations and will only be accessible by name via :func:`new`. See :data:`algorithms_available`. @@ -397,7 +397,7 @@ BLAKE2 supports **keyed mode** (a faster and simpler replacement for HMAC_), **salted hashing**, **personalization**, and **tree hashing**. Hash objects from this module follow the API of standard library's -:mod:`hashlib` objects. +:mod:`!hashlib` objects. Creating hash objects diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index fcb0069b760e59..90daaf28f8d505 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`http.cookiejar` module defines classes for automatic handling of HTTP +The :mod:`!http.cookiejar` module defines classes for automatic handling of HTTP cookies. It is useful for accessing websites that require small pieces of data -- :dfn:`cookies` -- to be set on the client machine by an HTTP response from a web server, and then returned to the server in later HTTP requests. @@ -21,7 +21,7 @@ Both the regular Netscape cookie protocol and the protocol defined by :rfc:`2109` cookies are parsed as Netscape cookies and subsequently treated either as Netscape or RFC 2965 cookies according to the 'policy' in effect. Note that the great majority of cookies on the internet are Netscape cookies. -:mod:`http.cookiejar` attempts to follow the de-facto Netscape cookie protocol (which +:mod:`!http.cookiejar` attempts to follow the de-facto Netscape cookie protocol (which differs substantially from that set out in the original Netscape specification), including taking note of the ``max-age`` and ``port`` cookie-attributes introduced with RFC 2965. @@ -109,7 +109,7 @@ The following classes are provided: .. class:: Cookie() This class represents Netscape, :rfc:`2109` and :rfc:`2965` cookies. It is not - expected that users of :mod:`http.cookiejar` construct their own :class:`Cookie` + expected that users of :mod:`!http.cookiejar` construct their own :class:`Cookie` instances. Instead, if necessary, call :meth:`make_cookies` on a :class:`CookieJar` instance. @@ -121,13 +121,13 @@ The following classes are provided: Module :mod:`http.cookies` HTTP cookie classes, principally useful for server-side code. The - :mod:`http.cookiejar` and :mod:`http.cookies` modules do not depend on each + :mod:`!http.cookiejar` and :mod:`http.cookies` modules do not depend on each other. https://curl.se/rfc/cookie_spec.html The specification of the original Netscape cookie protocol. Though this is still the dominant protocol, the 'Netscape cookie protocol' implemented by all - the major browsers (and :mod:`http.cookiejar`) only bears a passing resemblance to + the major browsers (and :mod:`!http.cookiejar`) only bears a passing resemblance to the one sketched out in ``cookie_spec.html``. :rfc:`2109` - HTTP State Management Mechanism @@ -617,7 +617,7 @@ standard cookie-attributes specified in the various cookie standards. The correspondence is not one-to-one, because there are complicated rules for assigning default values, because the ``max-age`` and ``expires`` cookie-attributes contain equivalent information, and because :rfc:`2109` cookies -may be 'downgraded' by :mod:`http.cookiejar` from version 1 to version 0 (Netscape) +may be 'downgraded' by :mod:`!http.cookiejar` from version 1 to version 0 (Netscape) cookies. Assignment to these attributes should not be necessary other than in rare @@ -629,7 +629,7 @@ internal consistency, so you should know what you're doing if you do that. Integer or :const:`None`. Netscape cookies have :attr:`version` 0. :rfc:`2965` and :rfc:`2109` cookies have a ``version`` cookie-attribute of 1. However, note that - :mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which + :mod:`!http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which case :attr:`version` is 0. @@ -692,7 +692,7 @@ internal consistency, so you should know what you're doing if you do that. ``True`` if this cookie was received as an :rfc:`2109` cookie (ie. the cookie arrived in a :mailheader:`Set-Cookie` header, and the value of the Version cookie-attribute in that header was 1). This attribute is provided because - :mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in + :mod:`!http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which case :attr:`version` is 0. @@ -744,7 +744,7 @@ The :class:`Cookie` class also defines the following method: Examples -------- -The first example shows the most common usage of :mod:`http.cookiejar`:: +The first example shows the most common usage of :mod:`!http.cookiejar`:: import http.cookiejar, urllib.request cj = http.cookiejar.CookieJar() diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index 50b65459d2f699..a829fb27363ea5 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`http.cookies` module defines classes for abstracting the concept of +The :mod:`!http.cookies` module defines classes for abstracting the concept of cookies, an HTTP state management mechanism. It supports both simple string-only cookies, and provides an abstraction for having any serializable data-type as cookie value. @@ -67,7 +67,7 @@ in a cookie name (as :attr:`~Morsel.key`). Module :mod:`http.cookiejar` HTTP cookie handling for web *clients*. The :mod:`http.cookiejar` and - :mod:`http.cookies` modules do not depend on each other. + :mod:`!http.cookies` modules do not depend on each other. :rfc:`2109` - HTTP State Management Mechanism This is the state management specification implemented by this module. @@ -266,7 +266,7 @@ Morsel Objects Example ------- -The following example demonstrates how to use the :mod:`http.cookies` module. +The following example demonstrates how to use the :mod:`!http.cookies` module. .. doctest:: :options: +NORMALIZE_WHITESPACE diff --git a/Doc/library/http.rst b/Doc/library/http.rst index b0bdfc65e4508d..43a801416e24f9 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -12,7 +12,7 @@ -------------- -:mod:`http` is a package that collects several modules for working with the +:mod:`!http` is a package that collects several modules for working with the HyperText Transfer Protocol: * :mod:`http.client` is a low-level HTTP protocol client; for high-level URL @@ -22,7 +22,7 @@ HyperText Transfer Protocol: * :mod:`http.cookiejar` provides persistence of cookies -The :mod:`http` module also defines the following enums that help you work with http related code: +The :mod:`!http` module also defines the following enums that help you work with http related code: .. class:: HTTPStatus diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 58f09634f95e0f..bd8c3f09cb43f1 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -19,7 +19,7 @@ This module defines classes for implementing HTTP servers. .. warning:: - :mod:`http.server` is not recommended for production. It only implements + :mod:`!http.server` is not recommended for production. It only implements :ref:`basic security checks `. .. include:: ../includes/wasm-notavail.rst @@ -463,7 +463,7 @@ such as using different index file names by overriding the class attribute Command-line interface ---------------------- -:mod:`http.server` can also be invoked directly using the :option:`-m` +:mod:`!http.server` can also be invoked directly using the :option:`-m` switch of the interpreter. The following example illustrates how to serve files relative to the current directory:: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 0b0537d3bbd104..5129ae7f9d20f7 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -29,7 +29,7 @@ note that the ``STATUS`` command is not supported in IMAP4. .. include:: ../includes/wasm-notavail.rst -Three classes are provided by the :mod:`imaplib` module, :class:`IMAP4` is the +Three classes are provided by the :mod:`!imaplib` module, :class:`IMAP4` is the base class: diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 26964348f5cd25..b2151f4d760927 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -17,7 +17,7 @@ Introduction ------------ -The purpose of the :mod:`importlib` package is three-fold. +The purpose of the :mod:`!importlib` package is three-fold. One is to provide the implementation of the :keyword:`import` statement (and thus, by extension, the diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index f6bc904bdab4bd..57353bfb9717d1 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -16,7 +16,7 @@ -------------- -The :mod:`inspect` module provides several useful functions to help get +The :mod:`!inspect` module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects. For example, it can help you examine the contents of a class, retrieve the source code of a method, extract @@ -1791,7 +1791,7 @@ which is a bitmap of the following flags: The flags are specific to CPython, and may not be defined in other Python implementations. Furthermore, the flags are an implementation detail, and can be removed or deprecated in future Python releases. - It's recommended to use public APIs from the :mod:`inspect` module + It's recommended to use public APIs from the :mod:`!inspect` module for any introspection needs. @@ -1833,7 +1833,7 @@ Buffer flags Command-line interface ---------------------- -The :mod:`inspect` module also provides a basic introspection capability +The :mod:`!inspect` module also provides a basic introspection capability from the command line. .. program:: inspect diff --git a/Doc/library/io.rst b/Doc/library/io.rst index d1a9132db81602..84e28986c31599 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -24,7 +24,7 @@ Overview .. index:: single: file object; io module -The :mod:`io` module provides Python's main facilities for dealing with various +The :mod:`!io` module provides Python's main facilities for dealing with various types of I/O. There are three main types of I/O: *text I/O*, *binary I/O* and *raw I/O*. These are generic categories, and various backing stores can be used for each of them. A concrete object belonging to any of these @@ -292,7 +292,7 @@ interface to a buffered raw stream (:class:`BufferedIOBase`). Finally, Argument names are not part of the specification, and only the arguments of :func:`open` are intended to be used as keyword arguments. -The following table summarizes the ABCs provided by the :mod:`io` module: +The following table summarizes the ABCs provided by the :mod:`!io` module: .. tabularcolumns:: |l|l|L|L| @@ -587,7 +587,7 @@ I/O Base Classes When the underlying raw stream is non-blocking, implementations may either raise :exc:`BlockingIOError` or return ``None`` if no data is - available. :mod:`io` implementations return ``None``. + available. :mod:`!io` implementations return ``None``. .. method:: read1(size=-1, /) @@ -600,7 +600,7 @@ I/O Base Classes When the underlying raw stream is non-blocking, implementations may either raise :exc:`BlockingIOError` or return ``None`` if no data is - available. :mod:`io` implementations return ``None``. + available. :mod:`!io` implementations return ``None``. .. method:: readinto(b, /) diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index 9e887d8e65741b..c546d913cbea9d 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -10,7 +10,7 @@ -------------- -:mod:`ipaddress` provides the capabilities to create, manipulate and +:mod:`!ipaddress` provides the capabilities to create, manipulate and operate on IPv4 and IPv6 addresses and networks. The functions and classes in this module make it straightforward to handle @@ -34,7 +34,7 @@ This is the full module API reference—for an overview and introduction, see Convenience factory functions ----------------------------- -The :mod:`ipaddress` module provides factory functions to conveniently create +The :mod:`!ipaddress` module provides factory functions to conveniently create IP addresses, networks and interfaces: .. function:: ip_address(address) @@ -1027,7 +1027,7 @@ The module also provides the following module level functions: IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') doesn't make sense. There are some times however, where you may wish to - have :mod:`ipaddress` sort these anyway. If you need to do this, you can use + have :mod:`!ipaddress` sort these anyway. If you need to do this, you can use this function as the *key* argument to :func:`sorted`. *obj* is either a network or address object. diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 8b4217c210d5b3..50a41cc29da0f6 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -121,7 +121,7 @@ Extending :class:`JSONEncoder`:: ['[2.0', ', 1.0', ']'] -Using :mod:`json` from the shell to validate and pretty-print: +Using :mod:`!json` from the shell to validate and pretty-print: .. code-block:: shell-session @@ -747,7 +747,7 @@ Command-line interface -------------- -The :mod:`json` module can be invoked as a script via ``python -m json`` +The :mod:`!json` module can be invoked as a script via ``python -m json`` to validate and pretty-print JSON objects. The :mod:`json.tool` submodule implements this interface. @@ -769,7 +769,7 @@ specified, :data:`sys.stdin` and :data:`sys.stdout` will be used respectively: alphabetically by key. .. versionchanged:: 3.14 - The :mod:`json` module may now be directly executed as + The :mod:`!json` module may now be directly executed as ``python -m json``. For backwards compatibility, invoking the CLI as ``python -m json.tool`` remains supported. diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 07305a2a39b252..0a5373ec976371 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`linecache` module allows one to get any line from a Python source file, while +The :mod:`!linecache` module allows one to get any line from a Python source file, while attempting to optimize internally, using a cache, the common case where many lines are read from a single file. This is used by the :mod:`traceback` module to retrieve source lines for inclusion in the formatted traceback. @@ -19,7 +19,7 @@ The :func:`tokenize.open` function is used to open files. This function uses :func:`tokenize.detect_encoding` to get the encoding of the file; in the absence of an encoding token, the file encoding defaults to UTF-8. -The :mod:`linecache` module defines the following functions: +The :mod:`!linecache` module defines the following functions: .. function:: getline(filename, lineno, module_globals=None) diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 00dd616830bf55..72311ecaabfc9f 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -11,17 +11,17 @@ -------------- -The :mod:`locale` module opens access to the POSIX locale database and +The :mod:`!locale` module opens access to the POSIX locale database and functionality. The POSIX locale mechanism allows programmers to deal with certain cultural issues in an application, without requiring the programmer to know all the specifics of each country where the software is executed. .. index:: pair: module; _locale -The :mod:`locale` module is implemented on top of the :mod:`!_locale` module, +The :mod:`!locale` module is implemented on top of the :mod:`!_locale` module, which in turn uses an ANSI C locale implementation if available. -The :mod:`locale` module defines the following exception and functions: +The :mod:`!locale` module defines the following exception and functions: .. exception:: Error @@ -540,7 +540,7 @@ The :mod:`locale` module defines the following exception and functions: .. data:: LC_COLLATE Locale category for sorting strings. The functions :func:`strcoll` and - :func:`strxfrm` of the :mod:`locale` module are affected. + :func:`strxfrm` of the :mod:`!locale` module are affected. .. data:: LC_TIME @@ -569,7 +569,7 @@ The :mod:`locale` module defines the following exception and functions: .. data:: LC_NUMERIC Locale category for formatting numbers. The functions :func:`format_string`, - :func:`atoi`, :func:`atof` and :func:`.str` of the :mod:`locale` module are + :func:`atoi`, :func:`atof` and :func:`.str` of the :mod:`!locale` module are affected by that category. All other numeric formatting operations are not affected. @@ -693,7 +693,7 @@ the current locale is. But since the return value can only be used portably to restore it, that is not very useful (except perhaps to find out whether or not the locale is ``C``). -When Python code uses the :mod:`locale` module to change the locale, this also +When Python code uses the :mod:`!locale` module to change the locale, this also affects the embedding application. If the embedding application doesn't want this to happen, it should remove the :mod:`!_locale` extension module (which does all the work) from the table of built-in modules in the :file:`config.c` file, diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 96cca3073fec7e..6709062dfca72b 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -28,7 +28,7 @@ Configuration functions ^^^^^^^^^^^^^^^^^^^^^^^ The following functions configure the logging module. They are located in the -:mod:`logging.config` module. Their use is optional --- you can configure the +:mod:`!logging.config` module. Their use is optional --- you can configure the logging module using these functions or by making calls to the main API (defined in :mod:`logging` itself) and defining handlers which are declared either in :mod:`logging` or :mod:`logging.handlers`. @@ -55,7 +55,7 @@ in :mod:`logging` itself) and defining handlers which are declared either in Parsing is performed by the :class:`DictConfigurator` class, whose constructor is passed the dictionary used for configuration, and - has a :meth:`configure` method. The :mod:`logging.config` module + has a :meth:`configure` method. The :mod:`!logging.config` module has a callable attribute :attr:`dictConfigClass` which is initially set to :class:`DictConfigurator`. You can replace the value of :attr:`dictConfigClass` with a diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index c9cfbdb4126fda..d128f64aae7236 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -160,7 +160,7 @@ WatchedFileHandler .. currentmodule:: logging.handlers -The :class:`WatchedFileHandler` class, located in the :mod:`logging.handlers` +The :class:`WatchedFileHandler` class, located in the :mod:`!logging.handlers` module, is a :class:`FileHandler` which watches the file it is logging to. If the file changes, it is closed and reopened using the file name. @@ -213,7 +213,7 @@ for this value. BaseRotatingHandler ^^^^^^^^^^^^^^^^^^^ -The :class:`BaseRotatingHandler` class, located in the :mod:`logging.handlers` +The :class:`BaseRotatingHandler` class, located in the :mod:`!logging.handlers` module, is the base class for the rotating file handlers, :class:`RotatingFileHandler` and :class:`TimedRotatingFileHandler`. You should not need to instantiate this class, but it has attributes and methods you may @@ -307,7 +307,7 @@ For an example, see :ref:`cookbook-rotator-namer`. RotatingFileHandler ^^^^^^^^^^^^^^^^^^^ -The :class:`RotatingFileHandler` class, located in the :mod:`logging.handlers` +The :class:`RotatingFileHandler` class, located in the :mod:`!logging.handlers` module, supports rotation of disk log files. @@ -362,7 +362,7 @@ TimedRotatingFileHandler ^^^^^^^^^^^^^^^^^^^^^^^^ The :class:`TimedRotatingFileHandler` class, located in the -:mod:`logging.handlers` module, supports rotation of disk log files at certain +:mod:`!logging.handlers` module, supports rotation of disk log files at certain timed intervals. @@ -475,7 +475,7 @@ timed intervals. SocketHandler ^^^^^^^^^^^^^ -The :class:`SocketHandler` class, located in the :mod:`logging.handlers` module, +The :class:`SocketHandler` class, located in the :mod:`!logging.handlers` module, sends logging output to a network socket. The base class uses a TCP socket. @@ -571,7 +571,7 @@ sends logging output to a network socket. The base class uses a TCP socket. DatagramHandler ^^^^^^^^^^^^^^^ -The :class:`DatagramHandler` class, located in the :mod:`logging.handlers` +The :class:`DatagramHandler` class, located in the :mod:`!logging.handlers` module, inherits from :class:`SocketHandler` to support sending logging messages over UDP sockets. @@ -618,7 +618,7 @@ over UDP sockets. SysLogHandler ^^^^^^^^^^^^^ -The :class:`SysLogHandler` class, located in the :mod:`logging.handlers` module, +The :class:`SysLogHandler` class, located in the :mod:`!logging.handlers` module, supports sending logging messages to a remote or local Unix syslog. @@ -797,7 +797,7 @@ supports sending logging messages to a remote or local Unix syslog. NTEventLogHandler ^^^^^^^^^^^^^^^^^ -The :class:`NTEventLogHandler` class, located in the :mod:`logging.handlers` +The :class:`NTEventLogHandler` class, located in the :mod:`!logging.handlers` module, supports sending logging messages to a local Windows NT, Windows 2000 or Windows XP event log. Before you can use it, you need Mark Hammond's Win32 extensions for Python installed. @@ -864,7 +864,7 @@ extensions for Python installed. SMTPHandler ^^^^^^^^^^^ -The :class:`SMTPHandler` class, located in the :mod:`logging.handlers` module, +The :class:`SMTPHandler` class, located in the :mod:`!logging.handlers` module, supports sending logging messages to an email address via SMTP. @@ -905,7 +905,7 @@ supports sending logging messages to an email address via SMTP. MemoryHandler ^^^^^^^^^^^^^ -The :class:`MemoryHandler` class, located in the :mod:`logging.handlers` module, +The :class:`MemoryHandler` class, located in the :mod:`!logging.handlers` module, supports buffering of logging records in memory, periodically flushing them to a :dfn:`target` handler. Flushing occurs whenever the buffer is full, or when an event of a certain severity or greater is seen. @@ -985,7 +985,7 @@ should, then :meth:`flush` is expected to do the flushing. HTTPHandler ^^^^^^^^^^^ -The :class:`HTTPHandler` class, located in the :mod:`logging.handlers` module, +The :class:`HTTPHandler` class, located in the :mod:`!logging.handlers` module, supports sending logging messages to a web server, using either ``GET`` or ``POST`` semantics. @@ -1037,7 +1037,7 @@ QueueHandler .. versionadded:: 3.2 -The :class:`QueueHandler` class, located in the :mod:`logging.handlers` module, +The :class:`QueueHandler` class, located in the :mod:`!logging.handlers` module, supports sending logging messages to a queue, such as those implemented in the :mod:`queue` or :mod:`multiprocessing` modules. @@ -1130,7 +1130,7 @@ QueueListener .. versionadded:: 3.2 -The :class:`QueueListener` class, located in the :mod:`logging.handlers` +The :class:`QueueListener` class, located in the :mod:`!logging.handlers` module, supports receiving logging messages from a queue, such as those implemented in the :mod:`queue` or :mod:`multiprocessing` modules. The messages are received from a queue in an internal thread and passed, on diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index d17f36bc7131d6..35ee87d736e7d6 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -1551,7 +1551,7 @@ Module-Level Attributes Integration with the warnings module ------------------------------------ -The :func:`captureWarnings` function can be used to integrate :mod:`logging` +The :func:`captureWarnings` function can be used to integrate :mod:`!logging` with the :mod:`warnings` module. .. function:: captureWarnings(capture) @@ -1582,7 +1582,7 @@ with the :mod:`warnings` module. library. `Original Python logging package `_ - This is the original source for the :mod:`logging` package. The version of the + This is the original source for the :mod:`!logging` package. The version of the package available from this site is suitable for use with Python 1.5.2, 2.1.x - and 2.2.x, which do not include the :mod:`logging` package in the standard + and 2.2.x, which do not include the :mod:`!logging` package in the standard library. diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index e8e9071a5c9ef4..ed182ea24e8f3c 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -20,7 +20,7 @@ rarely does). [#]_ This is not a general "persistence" module. For general persistence and transfer of Python objects through RPC calls, see the modules :mod:`pickle` and -:mod:`shelve`. The :mod:`marshal` module exists mainly to support reading and +:mod:`shelve`. The :mod:`!marshal` module exists mainly to support reading and writing the "pseudo-compiled" code for Python modules of :file:`.pyc` files. Therefore, the Python maintainers reserve the right to modify the marshal format in backward incompatible ways should the need arise. @@ -34,7 +34,7 @@ supports a substantially wider range of objects than marshal. .. warning:: - The :mod:`marshal` module is not intended to be secure against erroneous or + The :mod:`!marshal` module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source. diff --git a/Doc/library/math.integer.rst b/Doc/library/math.integer.rst index 0068ae2bdd5d07..c3f34cdfd85410 100644 --- a/Doc/library/math.integer.rst +++ b/Doc/library/math.integer.rst @@ -1,5 +1,5 @@ -:mod:`math.integer` --- integer-specific mathematics functions -============================================================== +:mod:`!math.integer` --- integer-specific mathematics functions +=============================================================== .. module:: math.integer :synopsis: Integer-specific mathematics functions. diff --git a/Doc/library/math.rst b/Doc/library/math.rst index d2ff74822f97ea..4a11aec15dfb73 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -720,7 +720,7 @@ Special functions Number-theoretic functions -------------------------- -For backward compatibility, the :mod:`math` module provides also aliases of +For backward compatibility, the :mod:`!math` module provides also aliases of the following functions from the :mod:`math.integer` module: .. list-table:: @@ -846,7 +846,7 @@ Constants .. impl-detail:: - The :mod:`math` module consists mostly of thin wrappers around the platform C + The :mod:`!math` module consists mostly of thin wrappers around the platform C math library functions. Behavior in exceptional cases follows Annex F of the C99 standard where appropriate. The current implementation will raise :exc:`ValueError` for invalid operations like ``sqrt(-1.0)`` or ``log(0.0)`` diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 13511b16a0ed8c..f489b60af3cb44 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`mimetypes` module converts between a filename or URL and the MIME type +The :mod:`!mimetypes` module converts between a filename or URL and the MIME type associated with the filename extension. Conversions are provided from filename to MIME type and from MIME type to filename extension; encodings are not supported for the latter conversion. @@ -196,7 +196,7 @@ MimeTypes objects The :class:`MimeTypes` class may be useful for applications which may want more than one MIME-type database; it provides an interface similar to the one of the -:mod:`mimetypes` module. +:mod:`!mimetypes` module. .. class:: MimeTypes(filenames=(), strict=True) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index b158ee1d42c774..d3baf2d760f615 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -13,16 +13,16 @@ Introduction ------------ -:mod:`multiprocessing` is a package that supports spawning processes using an -API similar to the :mod:`threading` module. The :mod:`multiprocessing` package +:mod:`!multiprocessing` is a package that supports spawning processes using an +API similar to the :mod:`threading` module. The :mod:`!multiprocessing` package offers both local and remote concurrency, effectively side-stepping the :term:`Global Interpreter Lock ` by using subprocesses instead of threads. Due -to this, the :mod:`multiprocessing` module allows the programmer to fully +to this, the :mod:`!multiprocessing` module allows the programmer to fully leverage multiple processors on a given machine. It runs on both POSIX and Windows. -The :mod:`multiprocessing` module also introduces the +The :mod:`!multiprocessing` module also introduces the :class:`~multiprocessing.pool.Pool` object which offers a convenient means of parallelizing the execution of a function across multiple input values, distributing the input data across processes (data parallelism). The following @@ -43,7 +43,7 @@ will print to standard output :: [1, 4, 9] -The :mod:`multiprocessing` module also introduces APIs which do not have +The :mod:`!multiprocessing` module also introduces APIs which do not have analogs in the :mod:`threading` module, like the ability to :meth:`terminate `, :meth:`interrupt ` or :meth:`kill ` a running process. @@ -61,7 +61,7 @@ analogs in the :mod:`threading` module, like the ability to :meth:`terminate The :class:`Process` class ^^^^^^^^^^^^^^^^^^^^^^^^^^ -In :mod:`multiprocessing`, processes are spawned by creating a :class:`Process` +In :mod:`!multiprocessing`, processes are spawned by creating a :class:`Process` object and then calling its :meth:`~Process.start` method. :class:`Process` follows the API of :class:`threading.Thread`. A trivial example of a multiprocess program is :: @@ -111,7 +111,7 @@ could lead to an :exc:`AttributeError` in the child process trying to locate the Contexts and start methods ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Depending on the platform, :mod:`multiprocessing` supports three ways +Depending on the platform, :mod:`!multiprocessing` supports three ways to start a process. These *start methods* are .. _multiprocessing-start-method-spawn: @@ -240,7 +240,7 @@ processes for a different context. In particular, locks created using the *fork* context cannot be passed to processes started using the *spawn* or *forkserver* start methods. -Libraries using :mod:`multiprocessing` or +Libraries using :mod:`!multiprocessing` or :class:`~concurrent.futures.ProcessPoolExecutor` should be designed to allow their users to provide their own multiprocessing context. Using a specific context of your own within a library can lead to incompatibilities with the @@ -258,7 +258,7 @@ requires a specific start method. Exchanging objects between processes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:mod:`multiprocessing` supports two types of communication channel between +:mod:`!multiprocessing` supports two types of communication channel between processes: **Queues** @@ -313,7 +313,7 @@ processes: Synchronization between processes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:mod:`multiprocessing` contains equivalents of all the synchronization +:mod:`!multiprocessing` contains equivalents of all the synchronization primitives from :mod:`threading`. For instance one can use a lock to ensure that only one process prints to standard output at a time:: @@ -344,7 +344,7 @@ avoid using shared state as far as possible. This is particularly true when using multiple processes. However, if you really do need to use some shared data then -:mod:`multiprocessing` provides a couple of ways of doing so. +:mod:`!multiprocessing` provides a couple of ways of doing so. **Shared memory** @@ -518,7 +518,7 @@ process which created it. Reference --------- -The :mod:`multiprocessing` package mostly replicates the API of the +The :mod:`!multiprocessing` package mostly replicates the API of the :mod:`threading` module. .. _global-start-method: @@ -704,7 +704,7 @@ or creating these objects. The process's authentication key (a byte string). - When :mod:`multiprocessing` is initialized the main process is assigned a + When :mod:`!multiprocessing` is initialized the main process is assigned a random string using :func:`os.urandom`. When a :class:`Process` object is created, it will inherit the @@ -805,7 +805,7 @@ or creating these objects. .. exception:: ProcessError - The base class of all :mod:`multiprocessing` exceptions. + The base class of all :mod:`!multiprocessing` exceptions. .. exception:: BufferTooShort @@ -845,7 +845,7 @@ If you use :class:`JoinableQueue` then you **must** call semaphore used to count the number of unfinished tasks may eventually overflow, raising an exception. -One difference from other Python queue implementations, is that :mod:`multiprocessing` +One difference from other Python queue implementations, is that :mod:`!multiprocessing` queues serializes all objects that are put into them using :mod:`pickle`. The object returned by the get method is a re-created object that does not share memory with the original object. @@ -855,9 +855,9 @@ Note that one can also create a shared queue by using a manager object -- see .. note:: - :mod:`multiprocessing` uses the usual :exc:`queue.Empty` and + :mod:`!multiprocessing` uses the usual :exc:`queue.Empty` and :exc:`queue.Full` exceptions to signal a timeout. They are not available in - the :mod:`multiprocessing` namespace so you need to import them from + the :mod:`!multiprocessing` namespace so you need to import them from :mod:`queue`. .. note:: @@ -1152,7 +1152,7 @@ Miscellaneous .. function:: freeze_support() - Add support for when a program which uses :mod:`multiprocessing` has been + Add support for when a program which uses :mod:`!multiprocessing` has been frozen to produce an executable. (Has been tested with **py2exe**, **PyInstaller** and **cx_Freeze**.) @@ -1188,7 +1188,7 @@ Miscellaneous .. function:: get_context(method=None) Return a context object which has the same attributes as the - :mod:`multiprocessing` module. + :mod:`!multiprocessing` module. If *method* is ``None`` then the default context is returned. Note that if the global start method has not been set, this will set it to the system default @@ -1279,7 +1279,7 @@ Miscellaneous .. note:: - :mod:`multiprocessing` contains no analogues of + :mod:`!multiprocessing` contains no analogues of :func:`threading.active_count`, :func:`threading.enumerate`, :func:`threading.settrace`, :func:`threading.setprofile`, :class:`threading.Timer`, or :class:`threading.local`. @@ -1473,7 +1473,7 @@ object -- see :ref:`multiprocessing-managers`. A condition variable: an alias for :class:`threading.Condition`. If *lock* is specified then it should be a :class:`Lock` or :class:`RLock` - object from :mod:`multiprocessing`. + object from :mod:`!multiprocessing`. Instantiating this class may set the global start method. See :ref:`global-start-method` for more details. @@ -2331,7 +2331,7 @@ demonstrates a level of control over the synchronization. .. note:: - The proxy types in :mod:`multiprocessing` do nothing to support comparisons + The proxy types in :mod:`!multiprocessing` do nothing to support comparisons by value. So, for instance, we have: .. doctest:: @@ -2927,7 +2927,7 @@ handler type) for messages from different processes to get mixed up. .. currentmodule:: multiprocessing .. function:: get_logger() - Returns the logger used by :mod:`multiprocessing`. If necessary, a new one + Returns the logger used by :mod:`!multiprocessing`. If necessary, a new one will be created. When first created the logger has level :const:`logging.NOTSET` and no @@ -2971,7 +2971,7 @@ The :mod:`multiprocessing.dummy` module .. module:: multiprocessing.dummy :synopsis: Dumb wrapper around threading. -:mod:`multiprocessing.dummy` replicates the API of :mod:`multiprocessing` but is +:mod:`multiprocessing.dummy` replicates the API of :mod:`!multiprocessing` but is no more than a wrapper around the :mod:`threading` module. .. currentmodule:: multiprocessing.pool @@ -3021,7 +3021,7 @@ Programming guidelines ---------------------- There are certain guidelines and idioms which should be adhered to when using -:mod:`multiprocessing`. +:mod:`!multiprocessing`. All start methods @@ -3062,7 +3062,7 @@ Joining zombie processes Better to inherit than pickle/unpickle When using the *spawn* or *forkserver* start methods many types - from :mod:`multiprocessing` need to be picklable so that child + from :mod:`!multiprocessing` need to be picklable so that child processes can use them. However, one should generally avoid sending shared objects to other processes using pipes or queues. Instead you should arrange the program so that a process which @@ -3152,7 +3152,7 @@ Explicitly pass resources to child processes Beware of replacing :data:`sys.stdin` with a "file like object" - :mod:`multiprocessing` originally unconditionally called:: + :mod:`!multiprocessing` originally unconditionally called:: os.close(sys.stdin.fileno()) diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index e8e71068dd99eb..c715e977cca6cd 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -15,7 +15,7 @@ -------------- -The :mod:`operator` module exports a set of efficient functions corresponding to +The :mod:`!operator` module exports a set of efficient functions corresponding to the intrinsic operators of Python. For example, ``operator.add(x, y)`` is equivalent to the expression ``x+y``. Many function names are those used for special methods, without the double underscores. For backward compatibility, @@ -275,7 +275,7 @@ The following operation works with callables: .. versionadded:: 3.11 -The :mod:`operator` module also defines tools for generalized attribute and item +The :mod:`!operator` module also defines tools for generalized attribute and item lookups. These are useful for making fast field extractors as arguments for :func:`map`, :func:`sorted`, :meth:`itertools.groupby`, or other functions that expect a function argument. @@ -390,7 +390,7 @@ Mapping Operators to Functions ------------------------------ This table shows how abstract operations correspond to operator symbols in the -Python syntax and the functions in the :mod:`operator` module. +Python syntax and the functions in the :mod:`!operator` module. +-----------------------+-------------------------+---------------------------------------+ | Operation | Syntax | Function | diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index ff327cf9162a8c..51827e1f8da534 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -20,7 +20,7 @@ The standard library includes three argument parsing libraries: * :mod:`getopt`: a module that closely mirrors the procedural C ``getopt`` API. Included in the standard library since before the initial Python 1.0 release. -* :mod:`optparse`: a declarative replacement for ``getopt`` that +* :mod:`!optparse`: a declarative replacement for ``getopt`` that provides equivalent functionality without requiring each application to implement its own procedural option parsing logic. Included in the standard library since the Python 2.3 release. @@ -37,10 +37,10 @@ the highest level of baseline functionality with the least application level cod However, it also serves a niche use case as a tool for prototyping and testing command line argument handling in ``getopt``-based C applications. -:mod:`optparse` should be considered as an alternative to :mod:`argparse` in the +:mod:`!optparse` should be considered as an alternative to :mod:`argparse` in the following cases: -* an application is already using :mod:`optparse` and doesn't want to risk the +* an application is already using :mod:`!optparse` and doesn't want to risk the subtle behavioural changes that may arise when migrating to :mod:`argparse` * the application requires additional control over the way options and positional parameters are interleaved on the command line (including @@ -55,7 +55,7 @@ following cases: behavior which ``argparse`` does not support, but which can be implemented in terms of the lower level interface offered by ``optparse`` -These considerations also mean that :mod:`optparse` is likely to provide a +These considerations also mean that :mod:`!optparse` is likely to provide a better foundation for library authors writing third party command line argument processing libraries. @@ -126,15 +126,15 @@ application use case. Introduction ------------ -:mod:`optparse` is a more convenient, flexible, and powerful library for parsing +:mod:`!optparse` is a more convenient, flexible, and powerful library for parsing command-line options than the minimalist :mod:`getopt` module. -:mod:`optparse` uses a more declarative style of command-line parsing: +:mod:`!optparse` uses a more declarative style of command-line parsing: you create an instance of :class:`OptionParser`, populate it with options, and parse the command line. -:mod:`optparse` allows users to specify options in the conventional +:mod:`!optparse` allows users to specify options in the conventional GNU/POSIX syntax, and additionally generates usage and help messages for you. -Here's an example of using :mod:`optparse` in a simple script:: +Here's an example of using :mod:`!optparse` in a simple script:: from optparse import OptionParser ... @@ -152,11 +152,11 @@ on the command-line, for example:: --file=outfile -q -As it parses the command line, :mod:`optparse` sets attributes of the +As it parses the command line, :mod:`!optparse` sets attributes of the ``options`` object returned by :meth:`~OptionParser.parse_args` based on user-supplied command-line values. When :meth:`~OptionParser.parse_args` returns from parsing this command line, ``options.filename`` will be ``"outfile"`` and ``options.verbose`` will be -``False``. :mod:`optparse` supports both long and short options, allows short +``False``. :mod:`!optparse` supports both long and short options, allows short options to be merged together, and allows options to be associated with their arguments in a variety of ways. Thus, the following command lines are all equivalent to the above example:: @@ -171,7 +171,7 @@ Additionally, users can run one of the following :: -h --help -and :mod:`optparse` will print out a brief summary of your script's options: +and :mod:`!optparse` will print out a brief summary of your script's options: .. code-block:: text @@ -191,7 +191,7 @@ where the value of *yourscript* is determined at runtime (normally from Background ---------- -:mod:`optparse` was explicitly designed to encourage the creation of programs +:mod:`!optparse` was explicitly designed to encourage the creation of programs with straightforward command-line interfaces that follow the conventions established by the :c:func:`!getopt` family of functions available to C developers. To that end, it supports only the most common command-line syntax and semantics @@ -223,7 +223,7 @@ option options to be merged into a single argument, e.g. ``-x -F`` is equivalent to ``-xF``. The GNU project introduced ``--`` followed by a series of hyphen-separated words, e.g. ``--file`` or ``--dry-run``. These are the - only two option syntaxes provided by :mod:`optparse`. + only two option syntaxes provided by :mod:`!optparse`. Some other option syntaxes that the world has seen include: @@ -240,7 +240,7 @@ option * a slash followed by a letter, or a few letters, or a word, e.g. ``/f``, ``/file`` - These option syntaxes are not supported by :mod:`optparse`, and they never + These option syntaxes are not supported by :mod:`!optparse`, and they never will be. This is deliberate: the first three are non-standard on any environment, and the last only makes sense if you're exclusively targeting Windows or certain legacy platforms (e.g. VMS, MS-DOS). @@ -248,7 +248,7 @@ option option argument an argument that follows an option, is closely associated with that option, and is consumed from the argument list when that option is. With - :mod:`optparse`, option arguments may either be in a separate argument from + :mod:`!optparse`, option arguments may either be in a separate argument from their option: .. code-block:: text @@ -268,7 +268,7 @@ option argument will take an argument if they see it, and won't if they don't. This is somewhat controversial, because it makes parsing ambiguous: if ``-a`` takes an optional argument and ``-b`` is another option entirely, how do we - interpret ``-ab``? Because of this ambiguity, :mod:`optparse` does not + interpret ``-ab``? Because of this ambiguity, :mod:`!optparse` does not support this feature. positional argument @@ -278,7 +278,7 @@ positional argument required option an option that must be supplied on the command-line; note that the phrase - "required option" is self-contradictory in English. :mod:`optparse` doesn't + "required option" is self-contradictory in English. :mod:`!optparse` doesn't prevent you from implementing required options, but doesn't give you much help at it either. @@ -357,9 +357,9 @@ too many options can overwhelm users and make your code much harder to maintain. Tutorial -------- -While :mod:`optparse` is quite flexible and powerful, it's also straightforward +While :mod:`!optparse` is quite flexible and powerful, it's also straightforward to use in most cases. This section covers the code patterns that are common to -any :mod:`optparse`\ -based program. +any :mod:`!optparse`\ -based program. First, you need to import the OptionParser class; then, early in the main program, create an OptionParser instance:: @@ -374,7 +374,7 @@ Then you can start defining options. The basic syntax is:: attr=value, ...) Each option has one or more option strings, such as ``-f`` or ``--file``, -and several option attributes that tell :mod:`optparse` what to expect and what +and several option attributes that tell :mod:`!optparse` what to expect and what to do when it encounters that option on the command line. Typically, each option will have one short option string and one long option @@ -389,10 +389,10 @@ string overall. The option strings passed to :meth:`OptionParser.add_option` are effectively labels for the option defined by that call. For brevity, we will frequently refer to -*encountering an option* on the command line; in reality, :mod:`optparse` +*encountering an option* on the command line; in reality, :mod:`!optparse` encounters *option strings* and looks up options from them. -Once all of your options are defined, instruct :mod:`optparse` to parse your +Once all of your options are defined, instruct :mod:`!optparse` to parse your program's command line:: (options, args) = parser.parse_args() @@ -420,14 +420,14 @@ most fundamental. Understanding option actions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Actions tell :mod:`optparse` what to do when it encounters an option on the -command line. There is a fixed set of actions hard-coded into :mod:`optparse`; +Actions tell :mod:`!optparse` what to do when it encounters an option on the +command line. There is a fixed set of actions hard-coded into :mod:`!optparse`; adding new actions is an advanced topic covered in section -:ref:`optparse-extending-optparse`. Most actions tell :mod:`optparse` to store +:ref:`optparse-extending-optparse`. Most actions tell :mod:`!optparse` to store a value in some variable---for example, take a string from the command line and store it in an attribute of ``options``. -If you don't specify an option action, :mod:`optparse` defaults to ``store``. +If you don't specify an option action, :mod:`!optparse` defaults to ``store``. .. _optparse-store-action: @@ -435,7 +435,7 @@ If you don't specify an option action, :mod:`optparse` defaults to ``store``. The store action ^^^^^^^^^^^^^^^^ -The most common option action is ``store``, which tells :mod:`optparse` to take +The most common option action is ``store``, which tells :mod:`!optparse` to take the next argument (or the remainder of the current argument), ensure that it is of the correct type, and store it to your chosen destination. @@ -444,16 +444,16 @@ For example:: parser.add_option("-f", "--file", action="store", type="string", dest="filename") -Now let's make up a fake command line and ask :mod:`optparse` to parse it:: +Now let's make up a fake command line and ask :mod:`!optparse` to parse it:: args = ["-f", "foo.txt"] (options, args) = parser.parse_args(args) -When :mod:`optparse` sees the option string ``-f``, it consumes the next +When :mod:`!optparse` sees the option string ``-f``, it consumes the next argument, ``foo.txt``, and stores it in ``options.filename``. So, after this call to :meth:`~OptionParser.parse_args`, ``options.filename`` is ``"foo.txt"``. -Some other option types supported by :mod:`optparse` are ``int`` and ``float``. +Some other option types supported by :mod:`!optparse` are ``int`` and ``float``. Here's an option that expects an integer argument:: parser.add_option("-n", type="int", dest="num") @@ -470,19 +470,19 @@ right up against the option: since ``-n42`` (one argument) is equivalent to will print ``42``. -If you don't specify a type, :mod:`optparse` assumes ``string``. Combined with +If you don't specify a type, :mod:`!optparse` assumes ``string``. Combined with the fact that the default action is ``store``, that means our first example can be a lot shorter:: parser.add_option("-f", "--file", dest="filename") -If you don't supply a destination, :mod:`optparse` figures out a sensible +If you don't supply a destination, :mod:`!optparse` figures out a sensible default from the option strings: if the first long option string is ``--foo-bar``, then the default destination is ``foo_bar``. If there are no -long option strings, :mod:`optparse` looks at the first short option string: the +long option strings, :mod:`!optparse` looks at the first short option string: the default destination for ``-f`` is ``f``. -:mod:`optparse` also includes the built-in ``complex`` type. Adding +:mod:`!optparse` also includes the built-in ``complex`` type. Adding types is covered in section :ref:`optparse-extending-optparse`. @@ -492,7 +492,7 @@ Handling boolean (flag) options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Flag options---set a variable to true or false when a particular option is -seen---are quite common. :mod:`optparse` supports them with two separate actions, +seen---are quite common. :mod:`!optparse` supports them with two separate actions, ``store_true`` and ``store_false``. For example, you might have a ``verbose`` flag that is turned on with ``-v`` and off with ``-q``:: @@ -503,7 +503,7 @@ Here we have two different options with the same destination, which is perfectly OK. (It just means you have to be a bit careful when setting default values---see below.) -When :mod:`optparse` encounters ``-v`` on the command line, it sets +When :mod:`!optparse` encounters ``-v`` on the command line, it sets ``options.verbose`` to ``True``; when it encounters ``-q``, ``options.verbose`` is set to ``False``. @@ -513,7 +513,7 @@ When :mod:`optparse` encounters ``-v`` on the command line, it sets Other actions ^^^^^^^^^^^^^ -Some other actions supported by :mod:`optparse` are: +Some other actions supported by :mod:`!optparse` are: ``"store_const"`` store a constant value, pre-set via :attr:`Option.const` @@ -539,11 +539,11 @@ Default values All of the above examples involve setting some variable (the "destination") when certain command-line options are seen. What happens if those options are never seen? Since we didn't supply any defaults, they are all set to ``None``. This -is usually fine, but sometimes you want more control. :mod:`optparse` lets you +is usually fine, but sometimes you want more control. :mod:`!optparse` lets you supply a default value for each destination, which is assigned before the command line is parsed. -First, consider the verbose/quiet example. If we want :mod:`optparse` to set +First, consider the verbose/quiet example. If we want :mod:`!optparse` to set ``verbose`` to ``True`` unless ``-q`` is seen, then we can do this:: parser.add_option("-v", action="store_true", dest="verbose", default=True) @@ -582,7 +582,7 @@ values, not both. Generating help ^^^^^^^^^^^^^^^ -:mod:`optparse`'s ability to generate help and usage text automatically is +:mod:`!optparse`'s ability to generate help and usage text automatically is useful for creating user-friendly command-line interfaces. All you have to do is supply a :attr:`~Option.help` value for each option, and optionally a short usage message for your whole program. Here's an OptionParser populated with @@ -603,7 +603,7 @@ user-friendly (documented) options:: help="interaction mode: novice, intermediate, " "or expert [default: %default]") -If :mod:`optparse` encounters either ``-h`` or ``--help`` on the +If :mod:`!optparse` encounters either ``-h`` or ``--help`` on the command-line, or if you just call :meth:`parser.print_help`, it prints the following to standard output: @@ -620,26 +620,26 @@ following to standard output: -m MODE, --mode=MODE interaction mode: novice, intermediate, or expert [default: intermediate] -(If the help output is triggered by a help option, :mod:`optparse` exits after +(If the help output is triggered by a help option, :mod:`!optparse` exits after printing the help text.) -There's a lot going on here to help :mod:`optparse` generate the best possible +There's a lot going on here to help :mod:`!optparse` generate the best possible help message: * the script defines its own usage message:: usage = "usage: %prog [options] arg1 arg2" - :mod:`optparse` expands ``%prog`` in the usage string to the name of the + :mod:`!optparse` expands ``%prog`` in the usage string to the name of the current program, i.e. ``os.path.basename(sys.argv[0])``. The expanded string is then printed before the detailed option help. - If you don't supply a usage string, :mod:`optparse` uses a bland but sensible + If you don't supply a usage string, :mod:`!optparse` uses a bland but sensible default: ``"Usage: %prog [options]"``, which is fine if your script doesn't take any positional arguments. * every option defines a help string, and doesn't worry about - line-wrapping---\ :mod:`optparse` takes care of wrapping lines and making + line-wrapping---\ :mod:`!optparse` takes care of wrapping lines and making the help output look good. * options that take a value indicate this fact in their automatically generated @@ -649,7 +649,7 @@ help message: Here, "MODE" is called the meta-variable: it stands for the argument that the user is expected to supply to ``-m``/``--mode``. By default, - :mod:`optparse` converts the destination variable name to uppercase and uses + :mod:`!optparse` converts the destination variable name to uppercase and uses that for the meta-variable. Sometimes, that's not what you want---for example, the ``--filename`` option explicitly sets ``metavar="FILE"``, resulting in this automatically generated option description:: @@ -663,7 +663,7 @@ help message: way to make your help text a lot clearer and more useful for end users. * options that have a default value can include ``%default`` in the help - string---\ :mod:`optparse` will replace it with :func:`str` of the option's + string---\ :mod:`!optparse` will replace it with :func:`str` of the option's default value. If an option has no default value (or the default value is ``None``), ``%default`` expands to ``none``. @@ -779,14 +779,14 @@ option groups is: Printing a version string ^^^^^^^^^^^^^^^^^^^^^^^^^ -Similar to the brief usage string, :mod:`optparse` can also print a version +Similar to the brief usage string, :mod:`!optparse` can also print a version string for your program. You have to supply the string as the ``version`` argument to OptionParser:: parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0") ``%prog`` is expanded just like it is in ``usage``. Apart from that, -``version`` can contain anything you like. When you supply it, :mod:`optparse` +``version`` can contain anything you like. When you supply it, :mod:`!optparse` automatically adds a ``--version`` option to your parser. If it encounters this option on the command line, it expands your ``version`` string (by replacing ``%prog``), prints it to stdout, and exits. @@ -815,10 +815,10 @@ The following two methods can be used to print and get the ``version`` string: .. _optparse-how-optparse-handles-errors: -How :mod:`optparse` handles errors -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +How :mod:`!optparse` handles errors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -There are two broad classes of errors that :mod:`optparse` has to worry about: +There are two broad classes of errors that :mod:`!optparse` has to worry about: programmer errors and user errors. Programmer errors are usually erroneous calls to :func:`OptionParser.add_option`, e.g. invalid option strings, unknown option attributes, missing option attributes, etc. These are dealt with in the @@ -826,7 +826,7 @@ usual way: raise an exception (either :exc:`optparse.OptionError` or :exc:`TypeError`) and let the program crash. Handling user errors is much more important, since they are guaranteed to happen -no matter how stable your code is. :mod:`optparse` can automatically detect +no matter how stable your code is. :mod:`!optparse` can automatically detect some user errors, such as bad option arguments (passing ``-n 4x`` where ``-n`` takes an integer argument), missing arguments (``-n`` at the end of the command line, where ``-n`` takes an argument of any type). Also, @@ -838,7 +838,7 @@ condition:: if options.a and options.b: parser.error("options -a and -b are mutually exclusive") -In either case, :mod:`optparse` handles the error the same way: it prints the +In either case, :mod:`!optparse` handles the error the same way: it prints the program's usage message and an error message to standard error and exits with error status 2. @@ -861,11 +861,11 @@ Or, where the user fails to pass a value at all: foo: error: -n option requires an argument -:mod:`optparse`\ -generated error messages take care always to mention the +:mod:`!optparse`\ -generated error messages take care always to mention the option involved in the error; be sure to do the same when calling :func:`OptionParser.error` from your application code. -If :mod:`optparse`'s default error-handling behaviour does not suit your needs, +If :mod:`!optparse`'s default error-handling behaviour does not suit your needs, you'll need to subclass OptionParser and override its :meth:`~OptionParser.exit` and/or :meth:`~OptionParser.error` methods. @@ -875,7 +875,7 @@ and/or :meth:`~OptionParser.error` methods. Putting it all together ^^^^^^^^^^^^^^^^^^^^^^^ -Here's what :mod:`optparse`\ -based scripts usually look like:: +Here's what :mod:`!optparse`\ -based scripts usually look like:: from optparse import OptionParser ... @@ -911,7 +911,7 @@ Reference Guide Creating the parser ^^^^^^^^^^^^^^^^^^^ -The first step in using :mod:`optparse` is to create an OptionParser instance. +The first step in using :mod:`!optparse` is to create an OptionParser instance. .. class:: OptionParser(...) @@ -921,7 +921,7 @@ The first step in using :mod:`optparse` is to create an OptionParser instance. ``usage`` (default: ``"%prog [options]"``) The usage summary to print when your program is run incorrectly or with a - help option. When :mod:`optparse` prints the usage string, it expands + help option. When :mod:`!optparse` prints the usage string, it expands ``%prog`` to ``os.path.basename(sys.argv[0])`` (or to ``prog`` if you passed that keyword argument). To suppress a usage message, pass the special value :const:`optparse.SUPPRESS_USAGE`. @@ -938,7 +938,7 @@ The first step in using :mod:`optparse` is to create an OptionParser instance. ``version`` (default: ``None``) A version string to print when the user supplies a version option. If you - supply a true value for ``version``, :mod:`optparse` automatically adds a + supply a true value for ``version``, :mod:`!optparse` automatically adds a version option with the single option string ``--version``. The substring ``%prog`` is expanded the same as for ``usage``. @@ -949,17 +949,17 @@ The first step in using :mod:`optparse` is to create an OptionParser instance. ``description`` (default: ``None``) A paragraph of text giving a brief overview of your program. - :mod:`optparse` reformats this paragraph to fit the current terminal width + :mod:`!optparse` reformats this paragraph to fit the current terminal width and prints it when the user requests help (after ``usage``, but before the list of options). ``formatter`` (default: a new :class:`IndentedHelpFormatter`) An instance of optparse.HelpFormatter that will be used for printing help - text. :mod:`optparse` provides two concrete classes for this purpose: + text. :mod:`!optparse` provides two concrete classes for this purpose: IndentedHelpFormatter and TitledHelpFormatter. ``add_help_option`` (default: ``True``) - If true, :mod:`optparse` will add a help option (with option strings ``-h`` + If true, :mod:`!optparse` will add a help option (with option strings ``-h`` and ``--help``) to the parser. ``prog`` @@ -997,7 +997,7 @@ the OptionParser constructor, as in:: (:func:`make_option` is a factory function for creating Option instances; currently it is an alias for the Option constructor. A future version of -:mod:`optparse` may split Option into several classes, and :func:`make_option` +:mod:`!optparse` may split Option into several classes, and :func:`make_option` will pick the right class to instantiate. Do not instantiate Option directly.) @@ -1027,12 +1027,12 @@ The canonical way to create an :class:`Option` instance is with the The keyword arguments define attributes of the new Option object. The most important option attribute is :attr:`~Option.action`, and it largely determines which other attributes are relevant or required. If you pass - irrelevant option attributes, or fail to pass required ones, :mod:`optparse` + irrelevant option attributes, or fail to pass required ones, :mod:`!optparse` raises an :exc:`OptionError` exception explaining your mistake. - An option's *action* determines what :mod:`optparse` does when it encounters + An option's *action* determines what :mod:`!optparse` does when it encounters this option on the command-line. The standard option actions hard-coded into - :mod:`optparse` are: + :mod:`!optparse` are: ``"store"`` store this option's argument (default) @@ -1066,7 +1066,7 @@ The canonical way to create an :class:`Option` instance is with the attributes; see :ref:`optparse-standard-option-actions`.) As you can see, most actions involve storing or updating a value somewhere. -:mod:`optparse` always creates a special object for this, conventionally called +:mod:`!optparse` always creates a special object for this, conventionally called ``options``, which is an instance of :class:`optparse.Values`. .. class:: Values @@ -1084,7 +1084,7 @@ For example, when you call :: parser.parse_args() -one of the first things :mod:`optparse` does is create the ``options`` object:: +one of the first things :mod:`!optparse` does is create the ``options`` object:: options = Values() @@ -1099,7 +1099,7 @@ and the command-line being parsed includes any of the following:: --file=foo --file foo -then :mod:`optparse`, on seeing this option, will do the equivalent of :: +then :mod:`!optparse`, on seeing this option, will do the equivalent of :: options.filename = "foo" @@ -1124,13 +1124,13 @@ Option attributes The following option attributes may be passed as keyword arguments to :meth:`OptionParser.add_option`. If you pass an option attribute that is not relevant to a particular option, or fail to pass a required option attribute, -:mod:`optparse` raises :exc:`OptionError`. +:mod:`!optparse` raises :exc:`OptionError`. .. attribute:: Option.action (default: ``"store"``) - Determines :mod:`optparse`'s behaviour when this option is seen on the + Determines :mod:`!optparse`'s behaviour when this option is seen on the command line; the available options are documented :ref:`here `. @@ -1147,8 +1147,8 @@ relevant to a particular option, or fail to pass a required option attribute, (default: derived from option strings) If the option's action implies writing or modifying a value somewhere, this - tells :mod:`optparse` where to write it: :attr:`~Option.dest` names an - attribute of the ``options`` object that :mod:`optparse` builds as it parses + tells :mod:`!optparse` where to write it: :attr:`~Option.dest` names an + attribute of the ``options`` object that :mod:`!optparse` builds as it parses the command line. .. attribute:: Option.default @@ -1161,7 +1161,7 @@ relevant to a particular option, or fail to pass a required option attribute, (default: 1) How many arguments of type :attr:`~Option.type` should be consumed when this - option is seen. If > 1, :mod:`optparse` will store a tuple of values to + option is seen. If > 1, :mod:`!optparse` will store a tuple of values to :attr:`~Option.dest`. .. attribute:: Option.const @@ -1207,7 +1207,7 @@ Standard option actions The various option actions all have slightly different requirements and effects. Most actions have several relevant option attributes which you may specify to -guide :mod:`optparse`'s behaviour; a few have required attributes, which you +guide :mod:`!optparse`'s behaviour; a few have required attributes, which you must specify for any option using that action. * ``"store"`` [relevant: :attr:`~Option.type`, :attr:`~Option.dest`, @@ -1225,9 +1225,9 @@ must specify for any option using that action. If :attr:`~Option.type` is not supplied, it defaults to ``"string"``. - If :attr:`~Option.dest` is not supplied, :mod:`optparse` derives a destination + If :attr:`~Option.dest` is not supplied, :mod:`!optparse` derives a destination from the first long option string (e.g., ``--foo-bar`` implies - ``foo_bar``). If there are no long option strings, :mod:`optparse` derives a + ``foo_bar``). If there are no long option strings, :mod:`!optparse` derives a destination from the first short option string (e.g., ``-f`` implies ``f``). Example:: @@ -1239,7 +1239,7 @@ must specify for any option using that action. -f foo.txt -p 1 -3.5 4 -fbar.txt - :mod:`optparse` will set :: + :mod:`!optparse` will set :: options.f = "foo.txt" options.point = (1.0, -3.5, 4.0) @@ -1259,7 +1259,7 @@ must specify for any option using that action. parser.add_option("--noisy", action="store_const", const=2, dest="verbose") - If ``--noisy`` is seen, :mod:`optparse` will set :: + If ``--noisy`` is seen, :mod:`!optparse` will set :: options.verbose = 2 @@ -1282,7 +1282,7 @@ must specify for any option using that action. The option must be followed by an argument, which is appended to the list in :attr:`~Option.dest`. If no default value for :attr:`~Option.dest` is - supplied, an empty list is automatically created when :mod:`optparse` first + supplied, an empty list is automatically created when :mod:`!optparse` first encounters this option on the command-line. If :attr:`~Option.nargs` > 1, multiple arguments are consumed, and a tuple of length :attr:`~Option.nargs` is appended to :attr:`~Option.dest`. @@ -1294,7 +1294,7 @@ must specify for any option using that action. parser.add_option("-t", "--tracks", action="append", type="int") - If ``-t3`` is seen on the command-line, :mod:`optparse` does the equivalent + If ``-t3`` is seen on the command-line, :mod:`!optparse` does the equivalent of:: options.tracks = [] @@ -1333,7 +1333,7 @@ must specify for any option using that action. parser.add_option("-v", action="count", dest="verbosity") - The first time ``-v`` is seen on the command line, :mod:`optparse` does the + The first time ``-v`` is seen on the command line, :mod:`!optparse` does the equivalent of:: options.verbosity = 0 @@ -1364,7 +1364,7 @@ must specify for any option using that action. listed in the help message. To omit an option entirely, use the special value :const:`optparse.SUPPRESS_HELP`. - :mod:`optparse` automatically adds a :attr:`~Option.help` option to all + :mod:`!optparse` automatically adds a :attr:`~Option.help` option to all OptionParsers, so you do not normally need to create one. Example:: @@ -1382,7 +1382,7 @@ must specify for any option using that action. help="Input file to read data from") parser.add_option("--secret", help=SUPPRESS_HELP) - If :mod:`optparse` sees either ``-h`` or ``--help`` on the command line, + If :mod:`!optparse` sees either ``-h`` or ``--help`` on the command line, it will print something like the following help message to stdout (assuming ``sys.argv[0]`` is ``"foo.py"``): @@ -1395,7 +1395,7 @@ must specify for any option using that action. -v Be moderately verbose --file=FILENAME Input file to read data from - After printing the help message, :mod:`optparse` terminates your process with + After printing the help message, :mod:`!optparse` terminates your process with ``sys.exit(0)``. * ``"version"`` @@ -1405,7 +1405,7 @@ must specify for any option using that action. ``print_version()`` method of OptionParser. Generally only relevant if the ``version`` argument is supplied to the OptionParser constructor. As with :attr:`~Option.help` options, you will rarely create ``version`` options, - since :mod:`optparse` automatically adds them when needed. + since :mod:`!optparse` automatically adds them when needed. .. _optparse-standard-option-types: @@ -1413,7 +1413,7 @@ must specify for any option using that action. Standard option types ^^^^^^^^^^^^^^^^^^^^^ -:mod:`optparse` has five built-in option types: ``"string"``, ``"int"``, +:mod:`!optparse` has five built-in option types: ``"string"``, ``"int"``, ``"choice"``, ``"float"`` and ``"complex"``. If you need to add new option types, see section :ref:`optparse-extending-optparse`. @@ -1432,7 +1432,7 @@ Integer arguments (type ``"int"``) are parsed as follows: The conversion is done by calling :func:`int` with the appropriate base (2, 8, -10, or 16). If this fails, so will :mod:`optparse`, although with a more useful +10, or 16). If this fails, so will :mod:`!optparse`, although with a more useful error message. ``"float"`` and ``"complex"`` option arguments are converted directly with @@ -1471,7 +1471,7 @@ The whole point of creating and populating an OptionParser is to call its ``options`` the same object that was passed in as *values*, or the ``optparse.Values`` - instance created by :mod:`optparse` + instance created by :mod:`!optparse` ``args`` the leftover positional arguments after all options have been processed @@ -1499,7 +1499,7 @@ provides several methods to help you out: .. method:: OptionParser.disable_interspersed_args() Set parsing to stop on the first non-option. For example, if ``-a`` and - ``-b`` are both simple options that take no arguments, :mod:`optparse` + ``-b`` are both simple options that take no arguments, :mod:`!optparse` normally accepts this syntax:: prog -a arg1 -b arg2 @@ -1554,7 +1554,7 @@ strings:: (This is particularly true if you've defined your own OptionParser subclass with some standard options.) -Every time you add an option, :mod:`optparse` checks for conflicts with existing +Every time you add an option, :mod:`!optparse` checks for conflicts with existing options. If it finds any, it invokes the current conflict-handling mechanism. You can set the conflict-handling mechanism either in the constructor:: @@ -1581,7 +1581,7 @@ intelligently and add conflicting options to it:: parser.add_option("-n", "--dry-run", ..., help="do no harm") parser.add_option("-n", "--noisy", ..., help="be noisy") -At this point, :mod:`optparse` detects that a previously added option is already +At this point, :mod:`!optparse` detects that a previously added option is already using the ``-n`` option string. Since ``conflict_handler`` is ``"resolve"``, it resolves the situation by removing ``-n`` from the earlier option's list of option strings. Now ``--dry-run`` is the only way for the user to activate @@ -1594,14 +1594,14 @@ that option. If the user asks for help, the help message will reflect that:: It's possible to whittle away the option strings for a previously added option until there are none left, and the user has no way of invoking that option from -the command-line. In that case, :mod:`optparse` removes that option completely, +the command-line. In that case, :mod:`!optparse` removes that option completely, so it doesn't show up in help text or anywhere else. Carrying on with our existing OptionParser:: parser.add_option("--dry-run", ..., help="new dry-run option") At this point, the original ``-n``/``--dry-run`` option is no longer -accessible, so :mod:`optparse` removes it, leaving this help text:: +accessible, so :mod:`!optparse` removes it, leaving this help text:: Options: ... @@ -1676,9 +1676,9 @@ OptionParser supports several other public methods: Option Callbacks ---------------- -When :mod:`optparse`'s built-in actions and types aren't quite enough for your -needs, you have two choices: extend :mod:`optparse` or define a callback option. -Extending :mod:`optparse` is more general, but overkill for a lot of simple +When :mod:`!optparse`'s built-in actions and types aren't quite enough for your +needs, you have two choices: extend :mod:`!optparse` or define a callback option. +Extending :mod:`!optparse` is more general, but overkill for a lot of simple cases. Quite often a simple callback is all you need. There are two steps to defining a callback option: @@ -1702,14 +1702,14 @@ only option attribute you must specify is ``callback``, the function to call:: ``callback`` is a function (or other callable object), so you must have already defined ``my_callback()`` when you create this callback option. In this simple -case, :mod:`optparse` doesn't even know if ``-c`` takes any arguments, +case, :mod:`!optparse` doesn't even know if ``-c`` takes any arguments, which usually means that the option takes no arguments---the mere presence of ``-c`` on the command-line is all it needs to know. In some circumstances, though, you might want your callback to consume an arbitrary number of command-line arguments. This is where writing callbacks gets tricky; it's covered later in this section. -:mod:`optparse` always passes four particular arguments to your callback, and it +:mod:`!optparse` always passes four particular arguments to your callback, and it will only pass additional arguments if you specify them via :attr:`~Option.callback_args` and :attr:`~Option.callback_kwargs`. Thus, the minimal callback function signature is:: @@ -1723,12 +1723,12 @@ callback option: :attr:`~Option.type` has its usual meaning: as with the ``"store"`` or ``"append"`` actions, it - instructs :mod:`optparse` to consume one argument and convert it to + instructs :mod:`!optparse` to consume one argument and convert it to :attr:`~Option.type`. Rather than storing the converted value(s) anywhere, - though, :mod:`optparse` passes it to your callback function. + though, :mod:`!optparse` passes it to your callback function. :attr:`~Option.nargs` - also has its usual meaning: if it is supplied and > 1, :mod:`optparse` will + also has its usual meaning: if it is supplied and > 1, :mod:`!optparse` will consume :attr:`~Option.nargs` arguments, each of which must be convertible to :attr:`~Option.type`. It then passes a tuple of converted values to your callback. @@ -1762,7 +1762,7 @@ where ``"--foobar"``.) ``value`` - is the argument to this option seen on the command-line. :mod:`optparse` will + is the argument to this option seen on the command-line. :mod:`!optparse` will only expect an argument if :attr:`~Option.type` is set; the type of ``value`` will be the type implied by the option's type. If :attr:`~Option.type` for this option is ``None`` (no argument expected), then ``value`` will be ``None``. If :attr:`~Option.nargs` @@ -1787,7 +1787,7 @@ where ``parser.values`` the object where option values are by default stored (an instance of optparse.OptionValues). This lets callbacks use the same mechanism as the - rest of :mod:`optparse` for storing option values; you don't need to mess + rest of :mod:`!optparse` for storing option values; you don't need to mess around with globals or closures. You can also access or modify the value(s) of any options already encountered on the command-line. @@ -1806,7 +1806,7 @@ Raising errors in a callback ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The callback function should raise :exc:`OptionValueError` if there are any -problems with the option or its argument(s). :mod:`optparse` catches this and +problems with the option or its argument(s). :mod:`!optparse` catches this and terminates the program, printing the error message you supply to stderr. Your message should be clear, concise, accurate, and mention the option at fault. Otherwise, the user will have a hard time figuring out what they did wrong. @@ -1906,7 +1906,7 @@ Here's an example that just emulates the standard ``"store"`` action:: action="callback", callback=store_value, type="int", nargs=3, dest="foo") -Note that :mod:`optparse` takes care of consuming 3 arguments and converting +Note that :mod:`!optparse` takes care of consuming 3 arguments and converting them to integers for you; all you have to do is store them. (Or whatever; obviously you don't need a callback for this example.) @@ -1917,9 +1917,9 @@ Callback example 6: variable arguments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Things get hairy when you want an option to take a variable number of arguments. -For this case, you must write a callback, as :mod:`optparse` doesn't provide any +For this case, you must write a callback, as :mod:`!optparse` doesn't provide any built-in capabilities for it. And you have to deal with certain intricacies of -conventional Unix command-line parsing that :mod:`optparse` normally handles for +conventional Unix command-line parsing that :mod:`!optparse` normally handles for you. In particular, callbacks should implement the conventional rules for bare ``--`` and ``-`` arguments: @@ -1934,7 +1934,7 @@ you. In particular, callbacks should implement the conventional rules for bare If you want an option that takes a variable number of arguments, there are several subtle, tricky issues to worry about. The exact implementation you choose will be based on which trade-offs you're willing to make for your -application (which is why :mod:`optparse` doesn't support this sort of thing +application (which is why :mod:`!optparse` doesn't support this sort of thing directly). Nevertheless, here's a stab at a callback for an option with variable @@ -1970,10 +1970,10 @@ arguments:: .. _optparse-extending-optparse: -Extending :mod:`optparse` -------------------------- +Extending :mod:`!optparse` +-------------------------- -Since the two major controlling factors in how :mod:`optparse` interprets +Since the two major controlling factors in how :mod:`!optparse` interprets command-line options are the action and type of each option, the most likely direction of extension is to add new actions and new types. @@ -1983,9 +1983,9 @@ direction of extension is to add new actions and new types. Adding new types ^^^^^^^^^^^^^^^^ -To add new types, you need to define your own subclass of :mod:`optparse`'s +To add new types, you need to define your own subclass of :mod:`!optparse`'s :class:`Option` class. This class has a couple of attributes that define -:mod:`optparse`'s types: :attr:`~Option.TYPES` and :attr:`~Option.TYPE_CHECKER`. +:mod:`!optparse`'s types: :attr:`~Option.TYPES` and :attr:`~Option.TYPE_CHECKER`. .. attribute:: Option.TYPES @@ -2015,7 +2015,7 @@ To add new types, you need to define your own subclass of :mod:`optparse`'s Here's a silly example that demonstrates adding a ``"complex"`` option type to parse Python-style complex numbers on the command line. (This is even sillier -than it used to be, because :mod:`optparse` 1.3 added built-in support for +than it used to be, because :mod:`!optparse` 1.3 added built-in support for complex numbers, but never mind.) First, the necessary imports:: @@ -2041,12 +2041,12 @@ Finally, the Option subclass:: TYPE_CHECKER["complex"] = check_complex (If we didn't make a :func:`copy` of :attr:`Option.TYPE_CHECKER`, we would end -up modifying the :attr:`~Option.TYPE_CHECKER` attribute of :mod:`optparse`'s +up modifying the :attr:`~Option.TYPE_CHECKER` attribute of :mod:`!optparse`'s Option class. This being Python, nothing stops you from doing that except good manners and common sense.) That's it! Now you can write a script that uses the new option type just like -any other :mod:`optparse`\ -based script, except you have to instruct your +any other :mod:`!optparse`\ -based script, except you have to instruct your OptionParser to use MyOption instead of Option:: parser = OptionParser(option_class=MyOption) @@ -2066,10 +2066,10 @@ Adding new actions ^^^^^^^^^^^^^^^^^^ Adding new actions is a bit trickier, because you have to understand that -:mod:`optparse` has a couple of classifications for actions: +:mod:`!optparse` has a couple of classifications for actions: "store" actions - actions that result in :mod:`optparse` storing a value to an attribute of the + actions that result in :mod:`!optparse` storing a value to an attribute of the current OptionValues instance; these options require a :attr:`~Option.dest` attribute to be supplied to the Option constructor. @@ -2101,7 +2101,7 @@ of the following class attributes of Option (all are lists of strings): .. attribute:: Option.ALWAYS_TYPED_ACTIONS Actions that always take a type (i.e. whose options always take a value) are - additionally listed here. The only effect of this is that :mod:`optparse` + additionally listed here. The only effect of this is that :mod:`!optparse` assigns the default type, ``"string"``, to options with no explicit type whose action is listed in :attr:`ALWAYS_TYPED_ACTIONS`. @@ -2144,12 +2144,12 @@ Features of note: somewhere, so it goes in both :attr:`~Option.STORE_ACTIONS` and :attr:`~Option.TYPED_ACTIONS`. -* to ensure that :mod:`optparse` assigns the default type of ``"string"`` to +* to ensure that :mod:`!optparse` assigns the default type of ``"string"`` to ``"extend"`` actions, we put the ``"extend"`` action in :attr:`~Option.ALWAYS_TYPED_ACTIONS` as well. * :meth:`MyOption.take_action` implements just this one new action, and passes - control back to :meth:`Option.take_action` for the standard :mod:`optparse` + control back to :meth:`Option.take_action` for the standard :mod:`!optparse` actions. * ``values`` is an instance of the optparse_parser.Values class, which provides diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 409fcf4adb754b..70ff6256821d7d 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -36,7 +36,7 @@ the :mod:`glob` module.) Since different operating systems have different path name conventions, there are several versions of this module in the standard library. The - :mod:`os.path` module is always the path module suitable for the operating + :mod:`!os.path` module is always the path module suitable for the operating system Python is running on, and therefore usable for local paths. However, you can also import and use the individual modules if you want to manipulate a path that is *always* in one of the different formats. They all have the diff --git a/Doc/library/os.rst b/Doc/library/os.rst index dad54c0e82bbc2..13bbd9d61e947b 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -25,7 +25,7 @@ Notes on the availability of these functions: with the POSIX interface). * Extensions peculiar to a particular operating system are also available - through the :mod:`os` module, but using them is of course a threat to + through the :mod:`!os` module, but using them is of course a threat to portability. * All functions accepting path or file names accept both bytes and string @@ -34,7 +34,7 @@ Notes on the availability of these functions: * On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported. -* On WebAssembly platforms, Android and iOS, large parts of the :mod:`os` module are +* On WebAssembly platforms, Android and iOS, large parts of the :mod:`!os` module are not available or behave differently. APIs related to processes (e.g. :func:`~os.fork`, :func:`~os.execve`) and resources (e.g. :func:`~os.nice`) are not available. Others like :func:`~os.getuid` and :func:`~os.getpid` are @@ -185,7 +185,7 @@ process and user. of your home directory (on some platforms), and is equivalent to ``getenv("HOME")`` in C. - This mapping is captured the first time the :mod:`os` module is imported, + This mapping is captured the first time the :mod:`!os` module is imported, typically during Python startup as part of processing :file:`site.py`. Changes to the environment made after this time are not reflected in :data:`os.environ`, except for changes made by modifying :data:`os.environ` directly. @@ -1279,7 +1279,7 @@ as internal buffering of data. For a description of the flag and mode values, see the C run-time documentation; flag constants (like :const:`O_RDONLY` and :const:`O_WRONLY`) are defined in - the :mod:`os` module. In particular, on Windows adding + the :mod:`!os` module. In particular, on Windows adding :const:`O_BINARY` is needed to open files in binary mode. This function can support :ref:`paths relative to directory descriptors @@ -2024,7 +2024,7 @@ features: .. _path_fd: * **specifying a file descriptor:** - Normally the *path* argument provided to functions in the :mod:`os` module + Normally the *path* argument provided to functions in the :mod:`!os` module must be a string specifying a file path. However, some functions now alternatively accept an open file descriptor for their *path* argument. The function will then operate on the file referred to by the descriptor. @@ -3795,7 +3795,7 @@ features: .. data:: supports_dir_fd - A :class:`set` object indicating which functions in the :mod:`os` + A :class:`set` object indicating which functions in the :mod:`!os` module accept an open file descriptor for their *dir_fd* parameter. Different platforms provide different features, and the underlying functionality Python uses to implement the *dir_fd* parameter is not @@ -3840,7 +3840,7 @@ features: .. data:: supports_fd A :class:`set` object indicating which functions in the - :mod:`os` module permit specifying their *path* parameter as an open file + :mod:`!os` module permit specifying their *path* parameter as an open file descriptor on the local platform. Different platforms provide different features, and the underlying functionality Python uses to accept open file descriptors as *path* arguments is not available on all platforms Python @@ -3859,7 +3859,7 @@ features: .. data:: supports_follow_symlinks - A :class:`set` object indicating which functions in the :mod:`os` module + A :class:`set` object indicating which functions in the :mod:`!os` module accept ``False`` for their *follow_symlinks* parameter on the local platform. Different platforms provide different features, and the underlying functionality Python uses to implement *follow_symlinks* is not available diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 1575de6c6f5935..0c65a61a52e32e 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1883,7 +1883,7 @@ Below is a table mapping various :mod:`os` functions to their corresponding :class:`PurePath`/:class:`Path` equivalent. ===================================== ============================================== -:mod:`os` and :mod:`os.path` :mod:`pathlib` +:mod:`os` and :mod:`os.path` :mod:`!pathlib` ===================================== ============================================== :func:`os.path.dirname` :attr:`PurePath.parent` :func:`os.path.basename` :attr:`PurePath.name` diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 7b0d979d61a36c..d3468cce39b6d2 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -19,7 +19,7 @@ -------------- -The :mod:`pickle` module implements binary protocols for serializing and +The :mod:`!pickle` module implements binary protocols for serializing and de-serializing a Python object structure. *"Pickling"* is the process whereby a Python object hierarchy is converted into a byte stream, and *"unpickling"* is the inverse operation, whereby a byte stream @@ -50,14 +50,14 @@ Comparison with ``marshal`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Python has a more primitive serialization module called :mod:`marshal`, but in -general :mod:`pickle` should always be the preferred way to serialize Python +general :mod:`!pickle` should always be the preferred way to serialize Python objects. :mod:`marshal` exists primarily to support Python's :file:`.pyc` files. -The :mod:`pickle` module differs from :mod:`marshal` in several significant ways: +The :mod:`!pickle` module differs from :mod:`marshal` in several significant ways: * :mod:`marshal` cannot be used to serialize user-defined classes and their - instances. :mod:`pickle` can save and restore class instances transparently, + instances. :mod:`!pickle` can save and restore class instances transparently, however the class definition must be importable and live in the same module as when the object was stored. @@ -65,7 +65,7 @@ The :mod:`pickle` module differs from :mod:`marshal` in several significant ways across Python versions. Because its primary job in life is to support :file:`.pyc` files, the Python implementers reserve the right to change the serialization format in non-backwards compatible ways should the need arise. - The :mod:`pickle` serialization format is guaranteed to be backwards compatible + The :mod:`!pickle` serialization format is guaranteed to be backwards compatible across Python releases provided a compatible pickle protocol is chosen and pickling and unpickling code deals with Python 2 to Python 3 type differences if your data is crossing that unique breaking change language boundary. @@ -110,17 +110,17 @@ Data stream format .. index:: single: External Data Representation -The data format used by :mod:`pickle` is Python-specific. This has the +The data format used by :mod:`!pickle` is Python-specific. This has the advantage that there are no restrictions imposed by external standards such as JSON (which can't represent pointer sharing); however it means that non-Python programs may not be able to reconstruct pickled Python objects. -By default, the :mod:`pickle` data format uses a relatively compact binary +By default, the :mod:`!pickle` data format uses a relatively compact binary representation. If you need optimal size characteristics, you can efficiently :doc:`compress ` pickled data. The module :mod:`pickletools` contains tools for analyzing data streams -generated by :mod:`pickle`. :mod:`pickletools` source code has extensive +generated by :mod:`!pickle`. :mod:`pickletools` source code has extensive comments about opcodes used by pickle protocols. There are currently 6 different protocols which can be used for pickling. @@ -154,9 +154,9 @@ to read the pickle produced. .. note:: Serialization is a more primitive notion than persistence; although - :mod:`pickle` reads and writes file objects, it does not handle the issue of + :mod:`!pickle` reads and writes file objects, it does not handle the issue of naming persistent objects, nor the (even more complicated) issue of concurrent - access to persistent objects. The :mod:`pickle` module can transform a complex + access to persistent objects. The :mod:`!pickle` module can transform a complex object into a byte stream and it can transform the byte stream into an object with the same internal structure. Perhaps the most obvious thing to do with these byte streams is to write them onto a file, but it is also conceivable to @@ -173,7 +173,7 @@ Similarly, to de-serialize a data stream, you call the :func:`loads` function. However, if you want more control over serialization and de-serialization, you can create a :class:`Pickler` or an :class:`Unpickler` object, respectively. -The :mod:`pickle` module provides the following constants: +The :mod:`!pickle` module provides the following constants: .. data:: HIGHEST_PROTOCOL @@ -204,7 +204,7 @@ The :mod:`pickle` module provides the following constants: The default protocol is 5. -The :mod:`pickle` module provides the following functions to make the pickling +The :mod:`!pickle` module provides the following functions to make the pickling process more convenient: .. function:: dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None) @@ -262,7 +262,7 @@ process more convenient: The *buffers* argument was added. -The :mod:`pickle` module defines three exceptions: +The :mod:`!pickle` module defines three exceptions: .. exception:: PickleError @@ -287,7 +287,7 @@ The :mod:`pickle` module defines three exceptions: IndexError. -The :mod:`pickle` module exports three classes, :class:`Pickler`, +The :mod:`!pickle` module exports three classes, :class:`Pickler`, :class:`Unpickler` and :class:`PickleBuffer`: .. class:: Pickler(file, protocol=None, *, fix_imports=True, buffer_callback=None) @@ -760,13 +760,13 @@ Persistence of External Objects single: persistent_id (pickle protocol) single: persistent_load (pickle protocol) -For the benefit of object persistence, the :mod:`pickle` module supports the +For the benefit of object persistence, the :mod:`!pickle` module supports the notion of a reference to an object outside the pickled data stream. Such objects are referenced by a persistent ID, which should be either a string of alphanumeric characters (for protocol 0) [#]_ or just an arbitrary object (for any newer protocol). -The resolution of such persistent IDs is not defined by the :mod:`pickle` +The resolution of such persistent IDs is not defined by the :mod:`!pickle` module; it will delegate this resolution to the user-defined methods on the pickler and unpickler, :meth:`~Pickler.persistent_id` and :meth:`~Unpickler.persistent_load` respectively. @@ -960,10 +960,10 @@ Out-of-band Buffers .. versionadded:: 3.8 -In some contexts, the :mod:`pickle` module is used to transfer massive amounts +In some contexts, the :mod:`!pickle` module is used to transfer massive amounts of data. Therefore, it can be important to minimize the number of memory copies, to preserve performance and resource consumption. However, normal -operation of the :mod:`pickle` module, as it transforms a graph-like structure +operation of the :mod:`!pickle` module, as it transforms a graph-like structure of objects into a sequential stream of bytes, intrinsically involves copying data to and from the pickle stream. @@ -982,8 +982,8 @@ for any large data. A :class:`PickleBuffer` object *signals* that the underlying buffer is eligible for out-of-band data transfer. Those objects remain compatible -with normal usage of the :mod:`pickle` module. However, consumers can also -opt-in to tell :mod:`pickle` that they will handle those buffers by +with normal usage of the :mod:`!pickle` module. However, consumers can also +opt-in to tell :mod:`!pickle` that they will handle those buffers by themselves. Consumer API @@ -1159,7 +1159,7 @@ Performance Recent versions of the pickle protocol (from protocol 2 and upwards) feature efficient binary encodings for several common features and built-in types. -Also, the :mod:`pickle` module has a transparent optimizer written in C. +Also, the :mod:`!pickle` module has a transparent optimizer written in C. .. _pickle-example: @@ -1202,7 +1202,7 @@ The following example reads the resulting pickled data. :: Command-line interface ---------------------- -The :mod:`pickle` module can be invoked as a script from the command line, +The :mod:`!pickle` module can be invoked as a script from the command line, it will display contents of the pickle files. However, when the pickle file that you want to examine comes from an untrusted source, ``-m pickletools`` is a safer option because it does not execute pickle bytecode, see @@ -1230,7 +1230,7 @@ The following option is accepted: Tools for working with and analyzing pickled data. Module :mod:`shelve` - Indexed databases of objects; uses :mod:`pickle`. + Indexed databases of objects; uses :mod:`!pickle`. Module :mod:`copy` Shallow and deep object copying. diff --git a/Doc/library/pickletools.rst b/Doc/library/pickletools.rst index 30fc2962e0bf78..7a771ea3ab93d4 100644 --- a/Doc/library/pickletools.rst +++ b/Doc/library/pickletools.rst @@ -15,7 +15,7 @@ This module contains various constants relating to the intimate details of the few useful functions for analyzing pickled data. The contents of this module are useful for Python core developers who are working on the :mod:`pickle`; ordinary users of the :mod:`pickle` module probably won't find the -:mod:`pickletools` module relevant. +:mod:`!pickletools` module relevant. .. _pickletools-cli: diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index d05c6e5a2aa22c..9950d7ef36f4de 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -357,7 +357,7 @@ Android platform Command-line usage ------------------ -:mod:`platform` can also be invoked directly using the :option:`-m` +:mod:`!platform` can also be invoked directly using the :option:`-m` switch of the interpreter:: python -m platform [--terse] [--nonaliased] [{nonaliased,terse} ...] diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 23f20b00e6dc6d..51ae480338ddb7 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -30,7 +30,7 @@ mailserver supports IMAP, you would be better off using the .. include:: ../includes/wasm-notavail.rst -The :mod:`poplib` module provides two classes: +The :mod:`!poplib` module provides two classes: .. class:: POP3(host, port=POP3_PORT[, timeout]) @@ -86,7 +86,7 @@ The :mod:`poplib` module provides two classes: .. versionchanged:: 3.12 The deprecated *keyfile* and *certfile* parameters have been removed. -One exception is defined as an attribute of the :mod:`poplib` module: +One exception is defined as an attribute of the :mod:`!poplib` module: .. exception:: error_proto diff --git a/Doc/library/posix.rst b/Doc/library/posix.rst index 14ab3e91e8a8e4..c52661ae112541 100644 --- a/Doc/library/posix.rst +++ b/Doc/library/posix.rst @@ -17,10 +17,10 @@ interface). **Do not import this module directly.** Instead, import the module :mod:`os`, which provides a *portable* version of this interface. On Unix, the :mod:`os` -module provides a superset of the :mod:`posix` interface. On non-Unix operating -systems the :mod:`posix` module is not available, but a subset is always +module provides a superset of the :mod:`!posix` interface. On non-Unix operating +systems the :mod:`!posix` module is not available, but a subset is always available through the :mod:`os` interface. Once :mod:`os` is imported, there is -*no* performance penalty in using it instead of :mod:`posix`. In addition, +*no* performance penalty in using it instead of :mod:`!posix`. In addition, :mod:`os` provides some additional functionality, such as automatically calling :func:`~os.putenv` when an entry in ``os.environ`` is changed. @@ -67,7 +67,7 @@ Notable Module Contents ----------------------- In addition to many functions described in the :mod:`os` module documentation, -:mod:`posix` defines the following data item: +:mod:`!posix` defines the following data item: .. data:: environ @@ -91,4 +91,4 @@ In addition to many functions described in the :mod:`os` module documentation, which updates the environment on modification. Note also that updating :data:`os.environ` will render this dictionary obsolete. Use of the :mod:`os` module version of this is recommended over direct access to the - :mod:`posix` module. + :mod:`!posix` module. diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index f51892450798ae..be942949d3ebfe 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`pprint` module provides a capability to "pretty-print" arbitrary +The :mod:`!pprint` module provides a capability to "pretty-print" arbitrary Python data structures in a form which can be used as input to the interpreter. If the formatted structures include objects which are not fundamental Python types, the representation may not be loadable. This may be the case if objects diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 2912c9e16c6149..397cf0ea7cece4 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`pty` module defines operations for handling the pseudo-terminal +The :mod:`!pty` module defines operations for handling the pseudo-terminal concept: starting another process and being able to write to and read from its controlling terminal programmatically. @@ -22,7 +22,7 @@ Pseudo-terminal handling is highly platform dependent. This code is mainly tested on Linux, FreeBSD, and macOS (it is supposed to work on other POSIX platforms but it's not been thoroughly tested). -The :mod:`pty` module defines the following functions: +The :mod:`!pty` module defines the following functions: .. function:: fork() diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 75aa739d1003b8..1cff16b6c1bf97 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -13,7 +13,7 @@ -------------- -The :mod:`py_compile` module provides a function to generate a byte-code file +The :mod:`!py_compile` module provides a function to generate a byte-code file from a source file, and another function used when the module source file is invoked as a script. diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index 5efb11d89dd143..40f93646af2ceb 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`pyclbr` module provides limited information about the +The :mod:`!pyclbr` module provides limited information about the functions, classes, and methods defined in a Python-coded module. The information is sufficient to implement a module browser. The information is extracted from the Python source code rather than by diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index 2f5db81955c235..0910c2d50791e8 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -24,7 +24,7 @@ .. index:: single: Expat -The :mod:`xml.parsers.expat` module is a Python interface to the Expat +The :mod:`!xml.parsers.expat` module is a Python interface to the Expat non-validating XML parser. The module provides a single extension type, :class:`xmlparser`, that represents the current state of an XML parser. After an :class:`xmlparser` object has been created, various attributes of the object @@ -55,7 +55,7 @@ This module provides one exception and one type object: The type of the return values from the :func:`ParserCreate` function. -The :mod:`xml.parsers.expat` module contains two functions: +The :mod:`!xml.parsers.expat` module contains two functions: .. function:: ErrorString(errno) @@ -980,7 +980,7 @@ The ``errors`` module has the following attributes: An operation was requested that requires DTD support to be compiled in, but Expat was configured without DTD support. This should never be reported by a - standard build of the :mod:`xml.parsers.expat` module. + standard build of the :mod:`!xml.parsers.expat` module. .. data:: XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index 1b75582f0cf45b..5ac72ef7604d50 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -8,7 +8,7 @@ -------------- -The :mod:`queue` module implements multi-producer, multi-consumer queues. +The :mod:`!queue` module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The :class:`Queue` class in this module implements all the required locking semantics. @@ -30,7 +30,7 @@ In addition, the module implements a "simple" specific implementation provides additional guarantees in exchange for the smaller functionality. -The :mod:`queue` module defines the following classes and exceptions: +The :mod:`!queue` module defines the following classes and exceptions: .. class:: Queue(maxsize=0) diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 4c37a69079dcd6..73a37e189ddf2a 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -37,7 +37,7 @@ Class :class:`Random` can also be subclassed if you want to use a different basic generator of your own devising: see the documentation on that class for more details. -The :mod:`random` module also provides the :class:`SystemRandom` class which +The :mod:`!random` module also provides the :class:`SystemRandom` class which uses the system function :func:`os.urandom` to generate random numbers from sources provided by the operating system. @@ -410,7 +410,7 @@ Alternative Generator .. class:: Random([seed]) Class that implements the default pseudo-random number generator used by the - :mod:`random` module. + :mod:`!random` module. .. versionchanged:: 3.11 Formerly the *seed* could be any hashable object. Now it is limited to: diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 75ebbf11c8e47c..734301317283fb 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -49,7 +49,7 @@ fine-tuning parameters. .. seealso:: The third-party :pypi:`regex` module, - which has an API compatible with the standard library :mod:`re` module, + which has an API compatible with the standard library :mod:`!re` module, but offers additional functionality and a more thorough Unicode support. diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 199e17595f41ac..1bdfb6ce0ed426 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -9,7 +9,7 @@ -------------- -The :mod:`readline` module defines a number of functions to facilitate +The :mod:`!readline` module defines a number of functions to facilitate completion and reading/writing of history files from the Python interpreter. This module can be used directly, or via the :mod:`rlcompleter` module, which supports completion of Python identifiers at the interactive prompt. Settings @@ -32,7 +32,7 @@ Readline library in general. The underlying Readline library API may be implemented by the ``editline`` (``libedit``) library instead of GNU readline. - On macOS the :mod:`readline` module detects which library is being used + On macOS the :mod:`!readline` module detects which library is being used at run time. The configuration file for ``editline`` is different from that @@ -264,7 +264,7 @@ The following functions relate to implementing a custom word completion function. This is typically operated by the Tab key, and can suggest and automatically complete a word being typed. By default, Readline is set up to be used by :mod:`rlcompleter` to complete Python identifiers for -the interactive interpreter. If the :mod:`readline` module is to be used +the interactive interpreter. If the :mod:`!readline` module is to be used with a custom completer, a different set of word delimiters should be set. @@ -333,7 +333,7 @@ with a custom completer, a different set of word delimiters should be set. Example ------- -The following example demonstrates how to use the :mod:`readline` module's +The following example demonstrates how to use the :mod:`!readline` module's history reading and writing functions to automatically load and save a history file named :file:`.python_history` from the user's home directory. The code below would normally be executed automatically during interactive sessions diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index 64735b5a109e66..bb977e01a61bbf 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`runpy` module is used to locate and run Python modules without +The :mod:`!runpy` module is used to locate and run Python modules without importing them first. Its main use is to implement the :option:`-m` command line switch that allows scripts to be located using the Python module namespace rather than the filesystem. @@ -20,11 +20,11 @@ current process, and any side effects (such as cached imports of other modules) will remain in place after the functions have returned. Furthermore, any functions and classes defined by the executed code are not -guaranteed to work correctly after a :mod:`runpy` function has returned. +guaranteed to work correctly after a :mod:`!runpy` function has returned. If that limitation is not acceptable for a given use case, :mod:`importlib` is likely to be a more suitable choice than this module. -The :mod:`runpy` module provides two functions: +The :mod:`!runpy` module provides two functions: .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 517dbe8c321898..5560478ce15e28 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`sched` module defines a class which implements a general purpose event +The :mod:`!sched` module defines a class which implements a general purpose event scheduler: .. class:: scheduler(timefunc=time.monotonic, delayfunc=time.sleep) diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index 75dafc54d40ca5..e828a3fba22276 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -17,11 +17,11 @@ ------------- -The :mod:`secrets` module is used for generating cryptographically strong +The :mod:`!secrets` module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets. -In particular, :mod:`secrets` should be used in preference to the +In particular, :mod:`!secrets` should be used in preference to the default pseudo-random number generator in the :mod:`random` module, which is designed for modelling and simulation, not security or cryptography. @@ -33,7 +33,7 @@ is designed for modelling and simulation, not security or cryptography. Random numbers -------------- -The :mod:`secrets` module provides access to the most secure source of +The :mod:`!secrets` module provides access to the most secure source of randomness that your operating system provides. .. class:: SystemRandom @@ -58,7 +58,7 @@ randomness that your operating system provides. Generating tokens ----------------- -The :mod:`secrets` module provides functions for generating secure +The :mod:`!secrets` module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar. @@ -107,7 +107,7 @@ tokens need to have sufficient randomness. Unfortunately, what is considered sufficient will necessarily increase as computers get more powerful and able to make more guesses in a shorter period. As of 2015, it is believed that 32 bytes (256 bits) of randomness is sufficient for -the typical use-case expected for the :mod:`secrets` module. +the typical use-case expected for the :mod:`!secrets` module. For those who want to manage their own token length, you can explicitly specify how much randomness is used for tokens by giving an :class:`int` @@ -139,7 +139,7 @@ Other functions Recipes and best practices -------------------------- -This section shows recipes and best practices for using :mod:`secrets` +This section shows recipes and best practices for using :mod:`!secrets` to manage a basic level of security. Generate an eight-character alphanumeric password: diff --git a/Doc/library/select.rst b/Doc/library/select.rst index ce4e92654d5932..9effd9752c68a7 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -18,7 +18,7 @@ it was last read. .. note:: The :mod:`selectors` module allows high-level and efficient I/O - multiplexing, built upon the :mod:`select` module primitives. Users are + multiplexing, built upon the :mod:`!select` module primitives. Users are encouraged to use the :mod:`selectors` module instead, unless they want precise control over the OS-level primitives used. diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index 51bae2fce30138..a8d22f3b8a033d 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -42,7 +42,7 @@ lots of shared sub-objects. The keys are ordinary strings. determine which accessed entries are mutable, nor which ones were actually mutated). - By default, :mod:`shelve` uses :func:`pickle.dumps` and :func:`pickle.loads` + By default, :mod:`!shelve` uses :func:`pickle.dumps` and :func:`pickle.loads` for serializing and deserializing. This can be changed by supplying *serializer* and *deserializer*, respectively. @@ -81,7 +81,7 @@ lots of shared sub-objects. The keys are ordinary strings. .. warning:: - Because the :mod:`shelve` module is backed by :mod:`pickle`, it is insecure + Because the :mod:`!shelve` module is backed by :mod:`pickle`, it is insecure to load a shelf from an untrusted source. Like with pickle, loading a shelf can execute arbitrary code. @@ -133,7 +133,7 @@ Restrictions database should be fairly small, and in rare cases key collisions may cause the database to refuse updates. -* The :mod:`shelve` module does not support *concurrent* read/write access to +* The :mod:`!shelve` module does not support *concurrent* read/write access to shelved objects. (Multiple simultaneous read accesses are safe.) When a program has a shelf open for writing, no other program should have it open for reading or writing. Unix file locking can be used to solve this, but this @@ -283,5 +283,5 @@ Exceptions Generic interface to ``dbm``-style databases. Module :mod:`pickle` - Object serialization used by :mod:`shelve`. + Object serialization used by :mod:`!shelve`. diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index a96f0864dc1260..00f4920a3268a8 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -18,7 +18,7 @@ simple syntaxes resembling that of the Unix shell. This will often be useful for writing minilanguages, (for example, in run control files for Python applications) or for parsing quoted strings. -The :mod:`shlex` module defines the following functions: +The :mod:`!shlex` module defines the following functions: .. function:: split(s, comments=False, posix=True) @@ -98,7 +98,7 @@ The :mod:`shlex` module defines the following functions: .. versionadded:: 3.3 -The :mod:`shlex` module defines the following class: +The :mod:`!shlex` module defines the following class: .. class:: shlex(instream=None, infile=None, posix=False, punctuation_chars=False) @@ -214,7 +214,7 @@ A :class:`~shlex.shlex` instance has the following methods: with the name of the current source file and the ``%d`` with the current input line number (the optional arguments can be used to override these). - This convenience is provided to encourage :mod:`shlex` users to generate error + This convenience is provided to encourage :mod:`!shlex` users to generate error messages in the standard, parseable format understood by Emacs and other Unix tools. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index ec3c8d600ad171..647e9bbd1d46a5 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -15,7 +15,7 @@ -------------- -The :mod:`shutil` module offers a number of high-level operations on files and +The :mod:`!shutil` module offers a number of high-level operations on files and collections of files. In particular, functions are provided which support file copying and removal. For operations on individual files, see also the :mod:`os` module. @@ -676,7 +676,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. Return a list of supported formats for archiving. Each element of the returned sequence is a tuple ``(name, description)``. - By default :mod:`shutil` provides these formats: + By default :mod:`!shutil` provides these formats: - *zip*: ZIP file (if the :mod:`zlib` module is available). - *tar*: Uncompressed tar file. Uses POSIX.1-2001 pax format for new archives. @@ -793,7 +793,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. Each element of the returned sequence is a tuple ``(name, extensions, description)``. - By default :mod:`shutil` provides these formats: + By default :mod:`!shutil` provides these formats: - *zip*: ZIP file (unpacking compressed files works only if the corresponding module is available). diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index cdefcd29ef7fd5..485eb6058c7e20 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -108,7 +108,7 @@ The signal module defines three enums: .. versionadded:: 3.5 -The variables defined in the :mod:`signal` module are: +The variables defined in the :mod:`!signal` module are: .. data:: SIG_DFL @@ -350,7 +350,7 @@ The variables defined in the :mod:`signal` module are: .. versionadded:: 3.3 -The :mod:`signal` module defines one exception: +The :mod:`!signal` module defines one exception: .. exception:: ItimerError @@ -364,7 +364,7 @@ The :mod:`signal` module defines one exception: alias of :exc:`OSError`. -The :mod:`signal` module defines the following functions: +The :mod:`!signal` module defines the following functions: .. function:: alarm(time) diff --git a/Doc/library/site.rst b/Doc/library/site.rst index ca2ac3b0098c46..09a98b4e3b22af 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -51,11 +51,11 @@ added path for configuration files. .. versionchanged:: 3.14 - :mod:`site` is no longer responsible for updating :data:`sys.prefix` and + :mod:`!site` is no longer responsible for updating :data:`sys.prefix` and :data:`sys.exec_prefix` on :ref:`sys-path-init-virtual-environments`. This is now done during the :ref:`path initialization `. As a result, under :ref:`sys-path-init-virtual-environments`, :data:`sys.prefix` and - :data:`sys.exec_prefix` no longer depend on the :mod:`site` initialization, + :data:`sys.exec_prefix` no longer depend on the :mod:`!site` initialization, and are therefore unaffected by :option:`-S`. .. _site-virtual-environments-configuration: @@ -275,7 +275,7 @@ Command-line interface .. program:: site -The :mod:`site` module also provides a way to get the user directories from the +The :mod:`!site` module also provides a way to get the user directories from the command line: .. code-block:: shell-session diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index 3bf5ec6099facb..e1a4cd9c2f50ea 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -14,7 +14,7 @@ -------------- -The :mod:`smtplib` module defines an SMTP client session object that can be used +The :mod:`!smtplib` module defines an SMTP client session object that can be used to send mail to any internet machine with an SMTP or ESMTP listener daemon. For details of SMTP and ESMTP operation, consult :rfc:`821` (Simple Mail Transfer Protocol) and :rfc:`1869` (SMTP Service Extensions). @@ -354,7 +354,7 @@ An :class:`SMTP` instance has the following methods: :exc:`SMTPException` No suitable authentication method was found. - Each of the authentication methods supported by :mod:`smtplib` are tried in + Each of the authentication methods supported by :mod:`!smtplib` are tried in turn if they are advertised as supported by the server. See :meth:`auth` for a list of supported authentication methods. *initial_response_ok* is passed through to :meth:`auth`. @@ -406,7 +406,7 @@ An :class:`SMTP` instance has the following methods: call the :meth:`login` method, which will try each of the above mechanisms in turn, in the order listed. ``auth`` is exposed to facilitate the implementation of authentication methods not (or not yet) supported - directly by :mod:`smtplib`. + directly by :mod:`!smtplib`. .. versionadded:: 3.5 diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index b7115942d1fdd1..ac962f5beeb149 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -83,7 +83,7 @@ created. Socket addresses are represented as follows: - For :const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo, scope_id)`` is used, where *flowinfo* and *scope_id* represent the ``sin6_flowinfo`` and ``sin6_scope_id`` members in :const:`struct sockaddr_in6` in C. For - :mod:`socket` module methods, *flowinfo* and *scope_id* can be omitted just for + :mod:`!socket` module methods, *flowinfo* and *scope_id* can be omitted just for backward compatibility. Note, however, omission of *scope_id* can cause problems in manipulating scoped IPv6 addresses. @@ -302,7 +302,7 @@ generalization of this based on timeouts is supported through Module contents --------------- -The module :mod:`socket` exports the following elements. +The module :mod:`!socket` exports the following elements. Exceptions @@ -1031,7 +1031,7 @@ The following functions all create :ref:`socket objects `. Other functions ''''''''''''''' -The :mod:`socket` module also offers various network-related services: +The :mod:`!socket` module also offers various network-related services: .. function:: close(fd) @@ -2427,7 +2427,7 @@ lead to this error:: This is because the previous execution has left the socket in a ``TIME_WAIT`` state, and can't be immediately reused. -There is a :mod:`socket` flag to set, in order to prevent this, +There is a :mod:`!socket` flag to set, in order to prevent this, :const:`socket.SO_REUSEADDR`:: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 491b8769f44fe2..4c98bb8e3b9c9b 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -8,7 +8,7 @@ -------------- -The :mod:`socketserver` module simplifies the task of writing network servers. +The :mod:`!socketserver` module simplifies the task of writing network servers. .. include:: ../includes/wasm-notavail.rst diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 7d30094963dc95..366ae00efa2fc9 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -130,7 +130,7 @@ purposes. cafile=None, capath=None, cadata=None) Return a new :class:`SSLContext` object with default settings for - the given *purpose*. The settings are chosen by the :mod:`ssl` module, + the given *purpose*. The settings are chosen by the :mod:`!ssl` module, and usually represent a higher security level than when calling the :class:`SSLContext` constructor directly. @@ -1510,7 +1510,7 @@ to speed up repeated connections from the same clients. TLS 1.3. .. seealso:: - :func:`create_default_context` lets the :mod:`ssl` module choose + :func:`create_default_context` lets the :mod:`!ssl` module choose security settings for a given purpose. .. versionchanged:: 3.6 diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 82012b31a00f20..dc852bbb754d9b 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`stat` module defines constants and functions for interpreting the +The :mod:`!stat` module defines constants and functions for interpreting the results of :func:`os.stat`, :func:`os.fstat` and :func:`os.lstat` (if they exist). For complete details about the :c:func:`stat`, :c:func:`!fstat` and :c:func:`!lstat` calls, consult the documentation for your system. @@ -19,7 +19,7 @@ exist). For complete details about the :c:func:`stat`, :c:func:`!fstat` and .. versionchanged:: 3.4 The stat module is backed by a C implementation. -The :mod:`stat` module defines the following functions to test for specific file +The :mod:`!stat` module defines the following functions to test for specific file types: diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e3ad018d1d073b..8096d90317d93f 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -87,7 +87,7 @@ Custom String Formatting The built-in string class provides the ability to do complex variable substitutions and value formatting via the :meth:`~str.format` method described in -:pep:`3101`. The :class:`Formatter` class in the :mod:`string` module allows +:pep:`3101`. The :class:`Formatter` class in the :mod:`!string` module allows you to create and customize your own string formatting behaviors using the same implementation as the built-in :meth:`~str.format` method. @@ -840,7 +840,7 @@ Template strings support ``$``-based substitutions, using the following rules: Any other appearance of ``$`` in the string will result in a :exc:`ValueError` being raised. -The :mod:`string` module provides a :class:`Template` class that implements +The :mod:`!string` module provides a :class:`Template` class that implements these rules. The methods of :class:`Template` are: diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 37d5adf0fa9541..b9caa2aa830e94 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -26,14 +26,14 @@ define which tables it uses, and what other optional parts of the ``stringprep`` procedure are part of the profile. One example of a ``stringprep`` profile is ``nameprep``, which is used for internationalized domain names. -The module :mod:`stringprep` only exposes the tables from :rfc:`3454`. As these +The module :mod:`!stringprep` only exposes the tables from :rfc:`3454`. As these tables would be very large to represent as dictionaries or lists, the module uses the Unicode character database internally. The module source code itself was generated using the ``mkstringprep.py`` utility. As a result, these tables are exposed as functions, not as data structures. There are two kinds of tables in the RFC: sets and mappings. For a set, -:mod:`stringprep` provides the "characteristic function", i.e. a function that +:mod:`!stringprep` provides the "characteristic function", i.e. a function that returns ``True`` if the parameter is part of the set. For mappings, it provides the mapping function: given the key, it returns the associated value. Below is a list of all functions available in the module. diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 17fc479fd0c8c9..c08df5341282e7 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -36,7 +36,7 @@ and the C layer. responsible for defining byte ordering and padding between elements. See :ref:`struct-alignment` for details. -Several :mod:`struct` functions (and methods of :class:`Struct`) take a *buffer* +Several :mod:`!struct` functions (and methods of :class:`Struct`) take a *buffer* argument. This refers to objects that implement the :ref:`bufferobjects` and provide either a readable or read-writable buffer. The most common types used for that purpose are :class:`bytes` and :class:`bytearray`, but many other types @@ -479,7 +479,7 @@ at the end, assuming the platform's longs are aligned on 4-byte boundaries:: Applications ------------ -Two main applications for the :mod:`struct` module exist, data +Two main applications for the :mod:`!struct` module exist, data interchange between Python and C code within an application or another application compiled using the same compiler (:ref:`native formats`), and data interchange between applications using agreed upon data layout @@ -571,7 +571,7 @@ below were executed on a 32-bit machine:: Classes ------- -The :mod:`struct` module also defines the following type: +The :mod:`!struct` module also defines the following type: .. class:: Struct(format) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index cc4f032fb26fd7..020326b78c6b3d 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -11,14 +11,14 @@ -------------- -The :mod:`subprocess` module allows you to spawn new processes, connect to their +The :mod:`!subprocess` module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:: os.system os.spawn* -Information about how the :mod:`subprocess` module can be used to replace these +Information about how the :mod:`!subprocess` module can be used to replace these modules and functions can be found in the following sections. .. seealso:: @@ -27,8 +27,8 @@ modules and functions can be found in the following sections. .. include:: ../includes/wasm-mobile-notavail.rst -Using the :mod:`subprocess` Module ----------------------------------- +Using the :mod:`!subprocess` Module +----------------------------------- The recommended approach to invoking subprocesses is to use the :func:`run` function for all use cases it can handle. For more advanced use cases, the @@ -1056,7 +1056,7 @@ on Windows. Windows Constants ^^^^^^^^^^^^^^^^^ -The :mod:`subprocess` module exposes the following constants. +The :mod:`!subprocess` module exposes the following constants. .. data:: STD_INPUT_HANDLE @@ -1345,8 +1345,8 @@ calls these functions. .. _subprocess-replacements: -Replacing Older Functions with the :mod:`subprocess` Module ------------------------------------------------------------ +Replacing Older Functions with the :mod:`!subprocess` Module +------------------------------------------------------------ In this section, "a becomes b" means that b can be used as a replacement for a. @@ -1362,7 +1362,7 @@ In this section, "a becomes b" means that b can be used as a replacement for a. :attr:`~CalledProcessError.output` attribute of the raised exception. In the following examples, we assume that the relevant functions have already -been imported from the :mod:`subprocess` module. +been imported from the :mod:`!subprocess` module. Replacing :program:`/bin/sh` shell command substitution @@ -1422,7 +1422,7 @@ Notes: * The :func:`os.system` function ignores SIGINT and SIGQUIT signals while the command is running, but the caller must do this separately when - using the :mod:`subprocess` module. + using the :mod:`!subprocess` module. A more realistic example would look like this:: @@ -1606,7 +1606,7 @@ runtime): Disable use of ``posix_spawn()`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -On Linux, :mod:`subprocess` defaults to using the ``vfork()`` system call +On Linux, :mod:`!subprocess` defaults to using the ``vfork()`` system call internally when it is safe to do so rather than ``fork()``. This greatly improves performance. diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 0b722d7d4e35cf..63549f440a5f13 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -14,7 +14,7 @@ Symbol tables are generated by the compiler from AST just before bytecode is generated. The symbol table is responsible for calculating the scope of every -identifier in the code. :mod:`symtable` provides an interface to examine these +identifier in the code. :mod:`!symtable` provides an interface to examine these tables. @@ -373,7 +373,7 @@ Command-Line Usage .. versionadded:: 3.13 -The :mod:`symtable` module can be executed as a script from the command line. +The :mod:`!symtable` module can be executed as a script from the command line. .. code-block:: sh diff --git a/Doc/library/sys.monitoring.rst b/Doc/library/sys.monitoring.rst index 303655fb128b37..4a460479e4afd7 100644 --- a/Doc/library/sys.monitoring.rst +++ b/Doc/library/sys.monitoring.rst @@ -10,7 +10,7 @@ .. note:: - :mod:`sys.monitoring` is a namespace within the :mod:`sys` module, + :mod:`!sys.monitoring` is a namespace within the :mod:`sys` module, not an independent module, so there is no need to ``import sys.monitoring``, simply ``import sys`` and then use ``sys.monitoring``. @@ -20,7 +20,7 @@ This namespace provides access to the functions and constants necessary to activate and control event monitoring. As programs execute, events occur that might be of interest to tools that -monitor execution. The :mod:`sys.monitoring` namespace provides means to +monitor execution. The :mod:`!sys.monitoring` namespace provides means to receive callbacks when events of interest occur. The monitoring API consists of three components: diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index f977f1389b61a5..5ddf88692ece35 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -2281,7 +2281,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only The version number used to form registry keys on Windows platforms. This is stored as string resource 1000 in the Python DLL. The value is normally the - major and minor versions of the running Python interpreter. It is provided in the :mod:`sys` + major and minor versions of the running Python interpreter. It is provided in the :mod:`!sys` module for informational purposes; modifying this value has no effect on the registry keys used by Python. diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 3b0bfb85da72af..5c65d6fd016175 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -16,7 +16,7 @@ -------------- -The :mod:`sysconfig` module provides access to Python's configuration +The :mod:`!sysconfig` module provides access to Python's configuration information like the list of installation paths and the configuration variables relevant for the current platform. @@ -28,7 +28,7 @@ A Python distribution contains a :file:`Makefile` and a :file:`pyconfig.h` header file that are necessary to build both the Python binary itself and third-party C extensions compiled using ``setuptools``. -:mod:`sysconfig` puts all variables found in these files in a dictionary that +:mod:`!sysconfig` puts all variables found in these files in a dictionary that can be accessed using :func:`get_config_vars` or :func:`get_config_var`. Notice that on Windows, it's a much smaller set. @@ -68,7 +68,7 @@ Installation paths ------------------ Python uses an installation scheme that differs depending on the platform and on -the installation options. These schemes are stored in :mod:`sysconfig` under +the installation options. These schemes are stored in :mod:`!sysconfig` under unique identifiers based on the value returned by :const:`os.name`. The schemes are used by package installers to determine where to copy files to. @@ -258,12 +258,12 @@ Path Installation directory Installation path functions --------------------------- -:mod:`sysconfig` provides some functions to determine these installation paths. +:mod:`!sysconfig` provides some functions to determine these installation paths. .. function:: get_scheme_names() Return a tuple containing all schemes currently supported in - :mod:`sysconfig`. + :mod:`!sysconfig`. .. function:: get_default_scheme() @@ -285,7 +285,7 @@ Installation path functions *key* must be either ``"prefix"``, ``"home"``, or ``"user"``. The return value is a scheme name listed in :func:`get_scheme_names`. It - can be passed to :mod:`sysconfig` functions that take a *scheme* argument, + can be passed to :mod:`!sysconfig` functions that take a *scheme* argument, such as :func:`get_paths`. .. versionadded:: 3.10 @@ -313,7 +313,7 @@ Installation path functions .. function:: get_path_names() Return a tuple containing all path names currently supported in - :mod:`sysconfig`. + :mod:`!sysconfig`. .. function:: get_path(name, [scheme, [vars, [expand]]]) @@ -323,7 +323,7 @@ Installation path functions *name* has to be a value from the list returned by :func:`get_path_names`. - :mod:`sysconfig` stores installation paths corresponding to each path name, + :mod:`!sysconfig` stores installation paths corresponding to each path name, for each platform, with variables to be expanded. For instance the *stdlib* path for the *nt* scheme is: ``{base}/Lib``. @@ -434,7 +434,7 @@ Other functions Command-line usage ------------------ -You can use :mod:`sysconfig` as a script with Python's *-m* option: +You can use :mod:`!sysconfig` as a script with Python's *-m* option: .. code-block:: shell-session diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 5ff8502bbe219f..d162070e27a7d2 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`tarfile` module makes it possible to read and write tar +The :mod:`!tarfile` module makes it possible to read and write tar archives, including those using gzip, bz2 and lzma compression. Use the :mod:`zipfile` module to read or write :file:`.zip` files, or the higher-level functions in :ref:`shutil `. @@ -220,25 +220,25 @@ Some facts and figures: .. function:: is_tarfile(name) - Return :const:`True` if *name* is a tar archive file, that the :mod:`tarfile` + Return :const:`True` if *name* is a tar archive file, that the :mod:`!tarfile` module can read. *name* may be a :class:`str`, file, or file-like object. .. versionchanged:: 3.9 Support for file and file-like objects. -The :mod:`tarfile` module defines the following exceptions: +The :mod:`!tarfile` module defines the following exceptions: .. exception:: TarError - Base class for all :mod:`tarfile` exceptions. + Base class for all :mod:`!tarfile` exceptions. .. exception:: ReadError Is raised when a tar archive is opened, that either cannot be handled by the - :mod:`tarfile` module or is somehow invalid. + :mod:`!tarfile` module or is somehow invalid. .. exception:: CompressionError @@ -359,7 +359,7 @@ The following constants are available at the module level: Each of the following constants defines a tar archive format that the -:mod:`tarfile` module is able to create. See section :ref:`tar-formats` for +:mod:`!tarfile` module is able to create. See section :ref:`tar-formats` for details. @@ -1289,7 +1289,7 @@ Command-Line Interface .. versionadded:: 3.4 -The :mod:`tarfile` module provides a simple command-line interface to interact +The :mod:`!tarfile` module provides a simple command-line interface to interact with tar archives. If you want to create a new tar archive, specify its name after the :option:`-c` @@ -1450,7 +1450,7 @@ parameter in :meth:`TarFile.add`:: Supported tar formats --------------------- -There are three tar formats that can be created with the :mod:`tarfile` module: +There are three tar formats that can be created with the :mod:`!tarfile` module: * The POSIX.1-1988 ustar format (:const:`USTAR_FORMAT`). It supports filenames up to a length of at best 256 characters and linknames up to 100 characters. @@ -1459,7 +1459,7 @@ There are three tar formats that can be created with the :mod:`tarfile` module: * The GNU tar format (:const:`GNU_FORMAT`). It supports long filenames and linknames, files bigger than 8 GiB and sparse files. It is the de facto - standard on GNU/Linux systems. :mod:`tarfile` fully supports the GNU tar + standard on GNU/Linux systems. :mod:`!tarfile` fully supports the GNU tar extensions for long names, sparse file support is read-only. * The POSIX.1-2001 pax format (:const:`PAX_FORMAT`). It is the most flexible @@ -1504,7 +1504,7 @@ Unfortunately, there is no way to autodetect the encoding of an archive. The pax format was designed to solve this problem. It stores non-ASCII metadata using the universal character encoding *UTF-8*. -The details of character conversion in :mod:`tarfile` are controlled by the +The details of character conversion in :mod:`!tarfile` are controlled by the *encoding* and *errors* keyword arguments of the :class:`TarFile` class. *encoding* defines the character encoding to use for the metadata in the diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 9d26f47820b134..78d37d8135cc51 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -386,7 +386,7 @@ not surprise other unsuspecting code by changing global API behavior. Examples -------- -Here are some examples of typical usage of the :mod:`tempfile` module:: +Here are some examples of typical usage of the :mod:`!tempfile` module:: >>> import tempfile diff --git a/Doc/library/termios.rst b/Doc/library/termios.rst index 0c6f3059fe71d1..e3ce596d18486f 100644 --- a/Doc/library/termios.rst +++ b/Doc/library/termios.rst @@ -38,7 +38,7 @@ The module defines the following functions: items with indices :const:`VMIN` and :const:`VTIME`, which are integers when these fields are defined). The interpretation of the flags and the speeds as well as the indexing in the *cc* array must be done using the symbolic - constants defined in the :mod:`termios` module. + constants defined in the :mod:`!termios` module. .. function:: tcsetattr(fd, when, attributes) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 44b1d395a27d13..a179ea6df057f1 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -7,7 +7,7 @@ .. sectionauthor:: Brett Cannon .. note:: - The :mod:`test` package is meant for internal use by Python only. It is + The :mod:`!test` package is meant for internal use by Python only. It is documented for the benefit of the core developers of Python. Any use of this package outside of Python's standard library is discouraged as code mentioned here can change or be removed without notice between releases of @@ -15,12 +15,12 @@ -------------- -The :mod:`test` package contains all regression tests for Python as well as the +The :mod:`!test` package contains all regression tests for Python as well as the modules :mod:`test.support` and :mod:`test.regrtest`. :mod:`test.support` is used to enhance your tests while :mod:`test.regrtest` drives the testing suite. -Each module in the :mod:`test` package whose name starts with ``test_`` is a +Each module in the :mod:`!test` package whose name starts with ``test_`` is a testing suite for a specific module or feature. All new tests should be written using the :mod:`unittest` or :mod:`doctest` module. Some older tests are written using a "traditional" testing style that compares output printed to @@ -38,8 +38,8 @@ written using a "traditional" testing style that compares output printed to .. _writing-tests: -Writing Unit Tests for the :mod:`test` package ----------------------------------------------- +Writing Unit Tests for the :mod:`!test` package +----------------------------------------------- It is preferred that tests that use the :mod:`unittest` module follow a few guidelines. One is to name the test module by starting it with ``test_`` and end @@ -162,12 +162,12 @@ Running tests using the command-line interface .. module:: test.regrtest :synopsis: Drives the regression test suite. -The :mod:`test` package can be run as a script to drive Python's regression +The :mod:`!test` package can be run as a script to drive Python's regression test suite, thanks to the :option:`-m` option: :program:`python -m test`. Under the hood, it uses :mod:`test.regrtest`; the call :program:`python -m test.regrtest` used in previous Python versions still works. Running the script by itself automatically starts running all regression tests in the -:mod:`test` package. It does this by finding all modules in the package whose +:mod:`!test` package. It does this by finding all modules in the package whose name starts with ``test_``, importing them, and executing the function :func:`test_main` if present or loading the tests via unittest.TestLoader.loadTestsFromModule if ``test_main`` does not exist. The @@ -175,14 +175,14 @@ names of tests to execute may also be passed to the script. Specifying a single regression test (:program:`python -m test test_spam`) will minimize output and only print whether the test passed or failed. -Running :mod:`test` directly allows what resources are available for +Running :mod:`!test` directly allows what resources are available for tests to use to be set. You do this by using the ``-u`` command-line option. Specifying ``all`` as the value for the ``-u`` option enables all possible resources: :program:`python -m test -uall`. If all but one resource is desired (a more common case), a comma-separated list of resources that are not desired may be listed after ``all``. The command :program:`python -m test -uall,-audio,-largefile` -will run :mod:`test` with all resources except the ``audio`` and +will run :mod:`!test` with all resources except the ``audio`` and ``largefile`` resources. For a list of all resources and more command-line options, run :program:`python -m test -h`. diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 3c96c0e9cc0a38..c9230f7d82705f 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`textwrap` module provides some convenience functions, +The :mod:`!textwrap` module provides some convenience functions, as well as :class:`TextWrapper`, the class that does all the work. If you're just wrapping or filling one or two text strings, the convenience functions should be good enough; otherwise, you should use an instance of diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 548a3ee0540506..bc12061a2aeb2d 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -355,7 +355,7 @@ to test for missing and present object attributes: 0.08588060699912603 -To give the :mod:`timeit` module access to functions you define, you can pass a +To give the :mod:`!timeit` module access to functions you define, you can pass a *setup* parameter which contains an import statement:: def test(): diff --git a/Doc/library/tkinter.colorchooser.rst b/Doc/library/tkinter.colorchooser.rst index df2b324fd5d3a7..a8468a4807357f 100644 --- a/Doc/library/tkinter.colorchooser.rst +++ b/Doc/library/tkinter.colorchooser.rst @@ -9,7 +9,7 @@ -------------- -The :mod:`tkinter.colorchooser` module provides the :class:`Chooser` class +The :mod:`!tkinter.colorchooser` module provides the :class:`Chooser` class as an interface to the native color picker dialog. ``Chooser`` implements a modal color choosing dialog window. The ``Chooser`` class inherits from the :class:`~tkinter.commondialog.Dialog` class. diff --git a/Doc/library/tkinter.dnd.rst b/Doc/library/tkinter.dnd.rst index 62298d96c26459..8c179d9793a855 100644 --- a/Doc/library/tkinter.dnd.rst +++ b/Doc/library/tkinter.dnd.rst @@ -12,7 +12,7 @@ .. note:: This is experimental and due to be deprecated when it is replaced with the Tk DND. -The :mod:`tkinter.dnd` module provides drag-and-drop support for objects within +The :mod:`!tkinter.dnd` module provides drag-and-drop support for objects within a single application, within the same window or between windows. To enable an object to be dragged, you must create an event binding for it that starts the drag-and-drop process. Typically, you bind a ButtonPress event to a callback diff --git a/Doc/library/tkinter.font.rst b/Doc/library/tkinter.font.rst index ed01bd5f483943..9d7b3e0fc227c1 100644 --- a/Doc/library/tkinter.font.rst +++ b/Doc/library/tkinter.font.rst @@ -9,7 +9,7 @@ -------------- -The :mod:`tkinter.font` module provides the :class:`Font` class for creating +The :mod:`!tkinter.font` module provides the :class:`Font` class for creating and using named fonts. The different font weights and slants are: diff --git a/Doc/library/tkinter.messagebox.rst b/Doc/library/tkinter.messagebox.rst index 0dc9632ca73304..4503913d6889b8 100644 --- a/Doc/library/tkinter.messagebox.rst +++ b/Doc/library/tkinter.messagebox.rst @@ -9,7 +9,7 @@ -------------- -The :mod:`tkinter.messagebox` module provides a template base class as well as +The :mod:`!tkinter.messagebox` module provides a template base class as well as a variety of convenience methods for commonly used configurations. The message boxes are modal and will return a subset of (``True``, ``False``, ``None``, :data:`OK`, :data:`CANCEL`, :data:`YES`, :data:`NO`) based on diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 07ce8c40577280..805f619eab8c07 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -10,12 +10,12 @@ -------------- -The :mod:`tkinter` package ("Tk interface") is the standard Python interface to -the Tcl/Tk GUI toolkit. Both Tk and :mod:`tkinter` are available on most Unix +The :mod:`!tkinter` package ("Tk interface") is the standard Python interface to +the Tcl/Tk GUI toolkit. Both Tk and :mod:`!tkinter` are available on most Unix platforms, including macOS, as well as on Windows systems. Running ``python -m tkinter`` from the command line should open a window -demonstrating a simple Tk interface, letting you know that :mod:`tkinter` is +demonstrating a simple Tk interface, letting you know that :mod:`!tkinter` is properly installed on your system, and also showing what version of Tcl/Tk is installed, so you can read the Tcl/Tk documentation specific to that version. @@ -108,7 +108,7 @@ Internally, Tk and Ttk use facilities of the underlying operating system, i.e., Xlib on Unix/X11, Cocoa on macOS, GDI on Windows. When your Python application uses a class in Tkinter, e.g., to create a widget, -the :mod:`tkinter` module first assembles a Tcl/Tk command string. It passes that +the :mod:`!tkinter` module first assembles a Tcl/Tk command string. It passes that Tcl command string to an internal :mod:`_tkinter` binary module, which then calls the Tcl interpreter to evaluate it. The Tcl interpreter will then call into the Tk and/or Ttk packages, which will in turn make calls to Xlib, Cocoa, or GDI. @@ -118,7 +118,7 @@ Tkinter Modules --------------- Support for Tkinter is spread across several modules. Most applications will need the -main :mod:`tkinter` module, as well as the :mod:`tkinter.ttk` module, which provides +main :mod:`!tkinter` module, as well as the :mod:`tkinter.ttk` module, which provides the modern themed widget set and API:: @@ -204,7 +204,7 @@ the modern themed widget set and API:: The modules that provide Tk support include: -:mod:`tkinter` +:mod:`!tkinter` Main Tkinter module. :mod:`tkinter.colorchooser` @@ -230,7 +230,7 @@ The modules that provide Tk support include: :mod:`tkinter.ttk` Themed widget set introduced in Tk 8.5, providing modern alternatives - for many of the classic widgets in the main :mod:`tkinter` module. + for many of the classic widgets in the main :mod:`!tkinter` module. Additional modules: @@ -239,22 +239,22 @@ Additional modules: :mod:`_tkinter` A binary module that contains the low-level interface to Tcl/Tk. - It is automatically imported by the main :mod:`tkinter` module, + It is automatically imported by the main :mod:`!tkinter` module, and should never be used directly by application programmers. It is usually a shared library (or DLL), but might in some cases be statically linked with the Python interpreter. :mod:`idlelib` Python's Integrated Development and Learning Environment (IDLE). Based - on :mod:`tkinter`. + on :mod:`!tkinter`. :mod:`tkinter.constants` Symbolic constants that can be used in place of strings when passing various parameters to Tkinter calls. Automatically imported by the - main :mod:`tkinter` module. + main :mod:`!tkinter` module. :mod:`tkinter.dnd` - (experimental) Drag-and-drop support for :mod:`tkinter`. This will + (experimental) Drag-and-drop support for :mod:`!tkinter`. This will become deprecated when it is replaced with the Tk DND. :mod:`turtle` @@ -504,7 +504,7 @@ documentation for all of these in the Threading model --------------- -Python and Tcl/Tk have very different threading models, which :mod:`tkinter` +Python and Tcl/Tk have very different threading models, which :mod:`!tkinter` tries to bridge. If you use threads, you may need to be aware of this. A Python interpreter may have many threads associated with it. In Tcl, multiple @@ -512,9 +512,9 @@ threads can be created, but each thread has a separate Tcl interpreter instance associated with it. Threads can also create more than one interpreter instance, though each interpreter instance can be used only by the one thread that created it. -Each :class:`Tk` object created by :mod:`tkinter` contains a Tcl interpreter. +Each :class:`Tk` object created by :mod:`!tkinter` contains a Tcl interpreter. It also keeps track of which thread created that interpreter. Calls to -:mod:`tkinter` can be made from any Python thread. Internally, if a call comes +:mod:`!tkinter` can be made from any Python thread. Internally, if a call comes from a thread other than the one that created the :class:`Tk` object, an event is posted to the interpreter's event queue, and when executed, the result is returned to the calling Python thread. @@ -529,17 +529,17 @@ toolkits where the GUI runs in a completely separate thread from all application code including event handlers. If the Tcl interpreter is not running the event loop and processing events, any -:mod:`tkinter` calls made from threads other than the one running the Tcl +:mod:`!tkinter` calls made from threads other than the one running the Tcl interpreter will fail. A number of special cases exist: * Tcl/Tk libraries can be built so they are not thread-aware. In this case, - :mod:`tkinter` calls the library from the originating Python thread, even + :mod:`!tkinter` calls the library from the originating Python thread, even if this is different than the thread that created the Tcl interpreter. A global lock ensures only one call occurs at a time. -* While :mod:`tkinter` allows you to create more than one instance of a :class:`Tk` +* While :mod:`!tkinter` allows you to create more than one instance of a :class:`Tk` object (with its own interpreter), all interpreters that are part of the same thread share a common event queue, which gets ugly fast. In practice, don't create more than one instance of :class:`Tk` at a time. Otherwise, it's best to create @@ -550,7 +550,7 @@ A number of special cases exist: or abandon the event loop entirely. If you're doing anything tricky when it comes to events or threads, be aware of these possibilities. -* There are a few select :mod:`tkinter` functions that presently work only when +* There are a few select :mod:`!tkinter` functions that presently work only when called from the thread that created the Tcl interpreter. @@ -700,11 +700,11 @@ options are ``variable``, ``textvariable``, ``onvalue``, ``offvalue``, and ``value``. This connection works both ways: if the variable changes for any reason, the widget it's connected to will be updated to reflect the new value. -Unfortunately, in the current implementation of :mod:`tkinter` it is not +Unfortunately, in the current implementation of :mod:`!tkinter` it is not possible to hand over an arbitrary Python variable to a widget through a ``variable`` or ``textvariable`` option. The only kinds of variables for which this works are variables that are subclassed from a class called Variable, -defined in :mod:`tkinter`. +defined in :mod:`!tkinter`. There are many useful subclasses of Variable already defined: :class:`StringVar`, :class:`IntVar`, :class:`DoubleVar`, and @@ -752,7 +752,7 @@ The Window Manager In Tk, there is a utility command, ``wm``, for interacting with the window manager. Options to the ``wm`` command allow you to control things like titles, -placement, icon bitmaps, and the like. In :mod:`tkinter`, these commands have +placement, icon bitmaps, and the like. In :mod:`!tkinter`, these commands have been implemented as methods on the :class:`Wm` class. Toplevel widgets are subclassed from the :class:`Wm` class, and so can call the :class:`Wm` methods directly. @@ -934,7 +934,7 @@ Entry widget, or to particular menu items in a Menu widget. Entry widget indexes (index, view index, etc.) Entry widgets have options that refer to character positions in the text being - displayed. You can use these :mod:`tkinter` functions to access these special + displayed. You can use these :mod:`!tkinter` functions to access these special points in text widgets: Text widget indexes diff --git a/Doc/library/tkinter.scrolledtext.rst b/Doc/library/tkinter.scrolledtext.rst index 763e24929d74b5..d2543c524b2532 100644 --- a/Doc/library/tkinter.scrolledtext.rst +++ b/Doc/library/tkinter.scrolledtext.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`tkinter.scrolledtext` module provides a class of the same name which +The :mod:`!tkinter.scrolledtext` module provides a class of the same name which implements a basic text widget which has a vertical scroll bar configured to do the "right thing." Using the :class:`ScrolledText` class is a lot easier than setting up a text widget and scroll bar directly. diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 628e9f945ac365..7db5756469976b 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -12,12 +12,12 @@ -------------- -The :mod:`tkinter.ttk` module provides access to the Tk themed widget set, +The :mod:`!tkinter.ttk` module provides access to the Tk themed widget set, 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). -The basic idea for :mod:`tkinter.ttk` is to separate, to the extent possible, +The basic idea for :mod:`!tkinter.ttk` is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. @@ -40,7 +40,7 @@ To override the basic Tk widgets, the import should follow the Tk import:: from tkinter import * from tkinter.ttk import * -That code causes several :mod:`tkinter.ttk` widgets (:class:`Button`, +That code causes several :mod:`!tkinter.ttk` widgets (:class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`, :class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`, :class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`) to diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index b80917eae66f8b..cf638f0b095bd6 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`tokenize` module provides a lexical scanner for Python source code, +The :mod:`!tokenize` module provides a lexical scanner for Python source code, implemented in Python. The scanner in this module returns comments as tokens as well, making it useful for implementing "pretty-printers", including colorizers for on-screen displays. @@ -78,7 +78,7 @@ The primary entry point is a :term:`generator`: :func:`.tokenize`. It does not yield an :data:`~token.ENCODING` token. All constants from the :mod:`token` module are also exported from -:mod:`tokenize`. +:mod:`!tokenize`. Another function is provided to reverse the tokenization process. This is useful for creating tools that tokenize a script, modify the token stream, and @@ -154,7 +154,7 @@ Command-Line Usage .. versionadded:: 3.3 -The :mod:`tokenize` module can be executed as a script from the command line. +The :mod:`!tokenize` module can be executed as a script from the command line. It is as simple as: .. code-block:: sh diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index cae94ea08e17e5..e0ae55ecc45acc 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -8,7 +8,7 @@ -------------- -The :mod:`trace` module allows you to trace program execution, generate +The :mod:`!trace` module allows you to trace program execution, generate annotated statement coverage listings, print caller/callee relationships and list functions executed during a program run. It can be used in another program or from the command line. @@ -24,7 +24,7 @@ or from the command line. Command-Line Usage ------------------ -The :mod:`trace` module can be invoked from the command line. It can be as +The :mod:`!trace` module can be invoked from the command line. It can be as simple as :: python -m trace --count -C . somefile.py ... @@ -49,7 +49,7 @@ Main options ^^^^^^^^^^^^ At least one of the following options must be specified when invoking -:mod:`trace`. The :option:`--listfuncs <-l>` option is mutually exclusive with +:mod:`!trace`. The :option:`--listfuncs <-l>` option is mutually exclusive with the :option:`--trace <-t>` and :option:`--count <-c>` options. When :option:`--listfuncs <-l>` is provided, neither :option:`--count <-c>` nor :option:`--trace <-t>` are accepted, and vice versa. diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index 2370d927292eb0..d11ad11bbb008b 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -307,7 +307,7 @@ Functions .. function:: get_object_traceback(obj) Get the traceback where the Python object *obj* was allocated. - Return a :class:`Traceback` instance, or ``None`` if the :mod:`tracemalloc` + Return a :class:`Traceback` instance, or ``None`` if the :mod:`!tracemalloc` module is not tracing memory allocations or did not trace the allocation of the object. @@ -318,7 +318,7 @@ Functions Get the maximum number of frames stored in the traceback of a trace. - The :mod:`tracemalloc` module must be tracing memory allocations to + The :mod:`!tracemalloc` module must be tracing memory allocations to get the limit, otherwise an exception is raised. The limit is set by the :func:`start` function. @@ -327,15 +327,15 @@ Functions .. function:: get_traced_memory() Get the current size and peak size of memory blocks traced by the - :mod:`tracemalloc` module as a tuple: ``(current: int, peak: int)``. + :mod:`!tracemalloc` module as a tuple: ``(current: int, peak: int)``. .. function:: reset_peak() - Set the peak size of memory blocks traced by the :mod:`tracemalloc` module + Set the peak size of memory blocks traced by the :mod:`!tracemalloc` module to the current size. - Do nothing if the :mod:`tracemalloc` module is not tracing memory + Do nothing if the :mod:`!tracemalloc` module is not tracing memory allocations. This function only modifies the recorded peak size, and does not modify or @@ -350,14 +350,14 @@ Functions .. function:: get_tracemalloc_memory() - Get the memory usage in bytes of the :mod:`tracemalloc` module used to store + Get the memory usage in bytes of the :mod:`!tracemalloc` module used to store traces of memory blocks. Return an :class:`int`. .. function:: is_tracing() - ``True`` if the :mod:`tracemalloc` module is tracing Python memory + ``True`` if the :mod:`!tracemalloc` module is tracing Python memory allocations, ``False`` otherwise. See also :func:`start` and :func:`stop` functions. @@ -378,8 +378,8 @@ Functions :meth:`Snapshot.compare_to` and :meth:`Snapshot.statistics` methods. Storing more frames increases the memory and CPU overhead of the - :mod:`tracemalloc` module. Use the :func:`get_tracemalloc_memory` function - to measure how much memory is used by the :mod:`tracemalloc` module. + :mod:`!tracemalloc` module. Use the :func:`get_tracemalloc_memory` function + to measure how much memory is used by the :mod:`!tracemalloc` module. The :envvar:`PYTHONTRACEMALLOC` environment variable (``PYTHONTRACEMALLOC=NFRAME``) and the :option:`-X` ``tracemalloc=NFRAME`` @@ -408,12 +408,12 @@ Functions :class:`Snapshot` instance. The snapshot does not include memory blocks allocated before the - :mod:`tracemalloc` module started to trace memory allocations. + :mod:`!tracemalloc` module started to trace memory allocations. Tracebacks of traces are limited to :func:`get_traceback_limit` frames. Use the *nframe* parameter of the :func:`start` function to store more frames. - The :mod:`tracemalloc` module must be tracing memory allocations to take a + The :mod:`!tracemalloc` module must be tracing memory allocations to take a snapshot, see the :func:`start` function. See also the :func:`get_object_traceback` function. @@ -457,7 +457,7 @@ Filter * ``Filter(True, subprocess.__file__)`` only includes traces of the :mod:`subprocess` module * ``Filter(False, tracemalloc.__file__)`` excludes traces of the - :mod:`tracemalloc` module + :mod:`!tracemalloc` module * ``Filter(False, "")`` excludes empty tracebacks diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index 37778bf20bdcc7..b2fe1bac9b0b2f 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -12,14 +12,14 @@ -------------- -The :mod:`tty` module defines functions for putting the tty into cbreak and raw +The :mod:`!tty` module defines functions for putting the tty into cbreak and raw modes. .. availability:: Unix. Because it requires the :mod:`termios` module, it will work only on Unix. -The :mod:`tty` module defines the following functions: +The :mod:`!tty` module defines the following functions: .. function:: cfmakeraw(mode) diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 91f90a0726aa93..549b04997886fa 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -13,11 +13,11 @@ -------------- -:mod:`unittest.mock` is a library for testing in Python. It allows you to +:mod:`!unittest.mock` is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. -:mod:`unittest.mock` provides a core :class:`Mock` class removing the need to +:mod:`!unittest.mock` provides a core :class:`Mock` class removing the need to create a host of stubs throughout your test suite. After performing an action, you can make assertions about which methods / attributes were used and arguments they were called with. You can also specify return values and @@ -33,7 +33,7 @@ Mock is designed for use with :mod:`unittest` and is based on the 'action -> assertion' pattern instead of 'record -> replay' used by many mocking frameworks. -There is a backport of :mod:`unittest.mock` for earlier versions of Python, +There is a backport of :mod:`!unittest.mock` for earlier versions of Python, available as :pypi:`mock` on PyPI. @@ -2638,7 +2638,7 @@ unit tests. Testing everything in isolation is all fine and dandy, but if you don't test how your units are "wired together" there is still lots of room for bugs that tests might have caught. -:mod:`unittest.mock` already provides a feature to help with this, called speccing. If you +:mod:`!unittest.mock` already provides a feature to help with this, called speccing. If you use a class or instance as the :attr:`!spec` for a mock then you can only access attributes on the mock that exist on the real class: diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 0bc0a953fd921c..9677612823df40 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -16,13 +16,13 @@ (If you are already familiar with the basic concepts of testing, you might want to skip to :ref:`the list of assert methods `.) -The :mod:`unittest` unit testing framework was originally inspired by JUnit +The :mod:`!unittest` unit testing framework was originally inspired by JUnit and has a similar flavor as major unit testing frameworks in other languages. It supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework. -To achieve this, :mod:`unittest` supports some important concepts in an +To achieve this, :mod:`!unittest` supports some important concepts in an object-oriented way: test fixture @@ -33,7 +33,7 @@ test fixture test case A :dfn:`test case` is the individual unit of testing. It checks for a specific - response to a particular set of inputs. :mod:`unittest` provides a base class, + response to a particular set of inputs. :mod:`!unittest` provides a base class, :class:`TestCase`, which may be used to create new test cases. test suite @@ -53,7 +53,7 @@ test runner `Simple Smalltalk Testing: With Patterns `_ Kent Beck's original paper on testing frameworks using the pattern shared - by :mod:`unittest`. + by :mod:`!unittest`. `pytest `_ Third-party unittest framework with a lighter-weight syntax for writing @@ -81,7 +81,7 @@ test runner Basic example ------------- -The :mod:`unittest` module provides a rich set of tools for constructing and +The :mod:`!unittest` module provides a rich set of tools for constructing and running tests. This section demonstrates that a small subset of the tools suffice to meet the needs of most users. @@ -147,7 +147,7 @@ to enable a higher level of verbosity, and produce the following output:: OK -The above examples show the most commonly used :mod:`unittest` features which +The above examples show the most commonly used :mod:`!unittest` features which are sufficient to meet many everyday testing needs. The remainder of the documentation explores the full feature set from first principles. @@ -365,7 +365,7 @@ Organizing test code -------------------- The basic building blocks of unit testing are :dfn:`test cases` --- single -scenarios that must be set up and checked for correctness. In :mod:`unittest`, +scenarios that must be set up and checked for correctness. In :mod:`!unittest`, test cases are represented by :class:`unittest.TestCase` instances. To make your own test cases you must write subclasses of :class:`TestCase` or use :class:`FunctionTestCase`. @@ -387,7 +387,7 @@ testing code:: Note that in order to test something, we use one of the :ref:`assert\* methods ` provided by the :class:`TestCase` base class. If the test fails, an -exception will be raised with an explanatory message, and :mod:`unittest` +exception will be raised with an explanatory message, and :mod:`!unittest` will identify the test case as a :dfn:`failure`. Any other exceptions will be treated as :dfn:`errors`. @@ -442,8 +442,8 @@ test fixture used to execute each individual test method. Thus will be called once per test. It is recommended that you use TestCase implementations to group tests together -according to the features they test. :mod:`unittest` provides a mechanism for -this: the :dfn:`test suite`, represented by :mod:`unittest`'s +according to the features they test. :mod:`!unittest` provides a mechanism for +this: the :dfn:`test suite`, represented by :mod:`!unittest`'s :class:`TestSuite` class. In most cases, calling :func:`unittest.main` will do the right thing and collect all the module's test cases for you and execute them. @@ -489,10 +489,10 @@ Re-using old test code ---------------------- Some users will find that they have existing test code that they would like to -run from :mod:`unittest`, without converting every old test function to a +run from :mod:`!unittest`, without converting every old test function to a :class:`TestCase` subclass. -For this reason, :mod:`unittest` provides a :class:`FunctionTestCase` class. +For this reason, :mod:`!unittest` provides a :class:`FunctionTestCase` class. This subclass of :class:`TestCase` can be used to wrap an existing test function. Set-up and tear-down functions can also be provided. @@ -513,7 +513,7 @@ set-up and tear-down methods:: .. note:: Even though :class:`FunctionTestCase` can be used to quickly convert an - existing test base over to a :mod:`unittest`\ -based system, this approach is + existing test base over to a :mod:`!unittest`\ -based system, this approach is not recommended. Taking the time to set up proper :class:`TestCase` subclasses will make future test refactorings infinitely easier. @@ -709,7 +709,7 @@ wouldn't be displayed:: Classes and functions --------------------- -This section describes in depth the API of :mod:`unittest`. +This section describes in depth the API of :mod:`!unittest`. .. _testcase-objects: @@ -720,7 +720,7 @@ Test cases .. class:: TestCase(methodName='runTest') Instances of the :class:`TestCase` class represent the logical test units - in the :mod:`unittest` universe. This class is intended to be used as a base + in the :mod:`!unittest` universe. This class is intended to be used as a base class, with specific tests being implemented by concrete subclasses. This class implements the interface needed by the test runner to allow it to drive the tests, and methods that the test code can use to check for and report various @@ -1734,7 +1734,7 @@ Test cases allows the test runner to drive the test, but does not provide the methods which test code can use to check and report errors. This is used to create test cases using legacy test code, allowing it to be integrated into a - :mod:`unittest`-based test framework. + :mod:`!unittest`-based test framework. .. _testsuite-objects: @@ -1829,7 +1829,7 @@ Loading and running tests The :class:`TestLoader` class is used to create test suites from classes and modules. Normally, there is no need to create an instance of this class; the - :mod:`unittest` module provides an instance that can be shared as + :mod:`!unittest` module provides an instance that can be shared as :data:`unittest.defaultTestLoader`. Using a subclass or instance, however, allows customization of some configurable properties. @@ -2055,7 +2055,7 @@ Loading and running tests properly recorded; test authors do not need to worry about recording the outcome of tests. - Testing frameworks built on top of :mod:`unittest` may want access to the + Testing frameworks built on top of :mod:`!unittest` may want access to the :class:`TestResult` object generated by running a set of tests for reporting purposes; a :class:`TestResult` instance is returned by the :meth:`!TestRunner.run` method for this purpose. diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index 1686ddd09caa48..dd2c9858eaad69 100644 --- a/Doc/library/urllib.error.rst +++ b/Doc/library/urllib.error.rst @@ -11,10 +11,10 @@ -------------- -The :mod:`urllib.error` module defines the exception classes for exceptions +The :mod:`!urllib.error` module defines the exception classes for exceptions raised by :mod:`urllib.request`. The base exception class is :exc:`URLError`. -The following exceptions are raised by :mod:`urllib.error` as appropriate: +The following exceptions are raised by :mod:`!urllib.error` as appropriate: .. exception:: URLError diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 95b6c2bb4da026..0fd307068effa5 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -35,7 +35,7 @@ Resource Locators. It supports the following URL schemes: ``file``, ``ftp``, macOS, it *may* be removed if CPython has been built with the :option:`--with-app-store-compliance` option. -The :mod:`urllib.parse` module defines functions that fall into two broad +The :mod:`!urllib.parse` module defines functions that fall into two broad categories: URL parsing and URL quoting. These are covered in detail in the following sections. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 5f796578eaa64e..83d2c8704e35d9 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`urllib.request` module defines functions and classes which help in +The :mod:`!urllib.request` module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world --- basic and digest authentication, redirections, cookies and more. @@ -31,7 +31,7 @@ authentication, redirections, cookies and more. .. include:: ../includes/wasm-notavail.rst -The :mod:`urllib.request` module defines the following functions: +The :mod:`!urllib.request` module defines the following functions: .. function:: urlopen(url, data=None[, timeout], *, context=None) @@ -1485,8 +1485,8 @@ some point in the future. calls to :func:`urlretrieve`. -:mod:`urllib.request` Restrictions ----------------------------------- +:mod:`!urllib.request` Restrictions +----------------------------------- .. index:: pair: HTTP; protocol @@ -1547,7 +1547,7 @@ some point in the future. The :mod:`urllib.response` module defines functions and classes which define a minimal file-like interface, including ``read()`` and ``readline()``. -Functions defined by this module are used internally by the :mod:`urllib.request` module. +Functions defined by this module are used internally by the :mod:`!urllib.request` module. The typical response object is a :class:`urllib.response.addinfourl` instance: .. class:: addinfourl diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index aa4f1bf940bc5c..fe3a3a8e510bd8 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -168,7 +168,7 @@ which relays any information about the UUID's safety, using this enumeration: .. versionadded:: 3.7 -The :mod:`uuid` module defines the following functions: +The :mod:`!uuid` module defines the following functions: .. function:: getnode() @@ -273,7 +273,7 @@ The :mod:`uuid` module defines the following functions: .. versionadded:: 3.14 -The :mod:`uuid` module defines the following namespace identifiers for use with +The :mod:`!uuid` module defines the following namespace identifiers for use with :func:`uuid3` or :func:`uuid5`. @@ -298,7 +298,7 @@ The :mod:`uuid` module defines the following namespace identifiers for use with When this namespace is specified, the *name* string is an X.500 DN in DER or a text output format. -The :mod:`uuid` module defines the following constants for the possible values +The :mod:`!uuid` module defines the following constants for the possible values of the :attr:`~UUID.variant` attribute: @@ -324,7 +324,7 @@ of the :attr:`~UUID.variant` attribute: Reserved for future definition. -The :mod:`uuid` module defines the special Nil and Max UUID values: +The :mod:`!uuid` module defines the special Nil and Max UUID values: .. data:: NIL @@ -357,7 +357,7 @@ Command-Line Usage .. versionadded:: 3.12 -The :mod:`uuid` module can be executed as a script from the command line. +The :mod:`!uuid` module can be executed as a script from the command line. .. code-block:: sh @@ -406,7 +406,7 @@ The following options are accepted: Example ------- -Here are some examples of typical usage of the :mod:`uuid` module:: +Here are some examples of typical usage of the :mod:`!uuid` module:: >>> import uuid @@ -473,7 +473,7 @@ Here are some examples of typical usage of the :mod:`uuid` module:: Command-Line Example -------------------- -Here are some examples of typical usage of the :mod:`uuid` command-line interface: +Here are some examples of typical usage of the :mod:`!uuid` command-line interface: .. code-block:: shell diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index 0de7a90bfcb60e..b25384dbfce54b 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -207,7 +207,7 @@ Describing Warning Filters The warnings filter is initialized by :option:`-W` options passed to the Python interpreter command line and the :envvar:`PYTHONWARNINGS` environment variable. The interpreter saves the arguments for all supplied entries without -interpretation in :data:`sys.warnoptions`; the :mod:`warnings` module parses these +interpretation in :data:`sys.warnoptions`; the :mod:`!warnings` module parses these when it is first imported (invalid options are ignored, after printing a message to :data:`sys.stderr`). @@ -631,8 +631,8 @@ Available Context Managers :func:`showwarning`. The *module* argument takes a module that will be used instead of the - module returned when you import :mod:`warnings` whose filter will be - protected. This argument exists primarily for testing the :mod:`warnings` + module returned when you import :mod:`!warnings` whose filter will be + protected. This argument exists primarily for testing the :mod:`!warnings` module itself. If the *action* argument is not ``None``, the remaining arguments are @@ -669,7 +669,7 @@ to true for free-threaded builds and false otherwise. If the :data:`~sys.flags.context_aware_warnings` flag is false, then :class:`catch_warnings` will modify the global attributes of the -:mod:`warnings` module. This is not safe if used within a concurrent program +:mod:`!warnings` module. This is not safe if used within a concurrent program (using multiple threads or using asyncio coroutines). For example, if two or more threads use the :class:`catch_warnings` class at the same time, the behavior is undefined. diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index 7ff2c97992c4e3..da793a64c45f0d 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`wave` module provides a convenient interface to the Waveform Audio +The :mod:`!wave` module provides a convenient interface to the Waveform Audio "WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are supported. @@ -20,7 +20,7 @@ supported. Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the extended format is ``KSDATAFORMAT_SUBTYPE_PCM``. -The :mod:`wave` module defines the following function and exception: +The :mod:`!wave` module defines the following function and exception: .. function:: open(file, mode=None) @@ -77,7 +77,7 @@ Wave_read Objects .. method:: close() - Close the stream if it was opened by :mod:`wave`, and make the instance + Close the stream if it was opened by :mod:`!wave`, and make the instance unusable. This is called automatically on object collection. @@ -174,7 +174,7 @@ Wave_write Objects .. method:: close() Make sure *nframes* is correct, and close the file if it was opened by - :mod:`wave`. This method is called upon object collection. It will raise + :mod:`!wave`. This method is called upon object collection. It will raise an exception if the output stream is not seekable and *nframes* does not match the number of frames actually written. diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index a2103d8fdd8efe..7b37b270e75343 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`webbrowser` module provides a high-level interface to allow displaying +The :mod:`!webbrowser` module provides a high-level interface to allow displaying web-based documents to users. Under most circumstances, simply calling the :func:`.open` function from this module will do the right thing. @@ -46,7 +46,7 @@ On iOS, the :envvar:`BROWSER` environment variable, as well as any arguments controlling autoraise, browser preference, and new tab/window creation will be ignored. Web pages will *always* be opened in the user's preferred browser, in a new tab, with the browser being brought to the foreground. The use of the -:mod:`webbrowser` module on iOS requires the :mod:`ctypes` module. If +:mod:`!webbrowser` module on iOS requires the :mod:`ctypes` module. If :mod:`ctypes` isn't available, calls to :func:`.open` will fail. .. _webbrowser-cli: diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index d167c41ab72c34..99137db4496c55 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -558,7 +558,7 @@ This module offers the following functions: Constants --------- -The following constants are defined for use in many :mod:`winreg` functions. +The following constants are defined for use in many :mod:`!winreg` functions. .. _hkey-constants: diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst index 755b94fc0fbe1e..8efe4b1ee643e7 100644 --- a/Doc/library/winsound.rst +++ b/Doc/library/winsound.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`winsound` module provides access to the basic sound-playing machinery +The :mod:`!winsound` module provides access to the basic sound-playing machinery provided by Windows platforms. It includes functions and several constants. .. availability:: Windows. diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 157d7058931c16..8e9b9ada93842f 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -26,7 +26,7 @@ and corner case of the WSGI design. You don't need to understand every detail of WSGI just to install a WSGI application or to write a web application using an existing framework. -:mod:`wsgiref` is a reference implementation of the WSGI specification that can +:mod:`!wsgiref` is a reference implementation of the WSGI specification that can be used to add WSGI support to a web server or framework. It provides utilities for manipulating WSGI environment variables and response headers, base classes for implementing WSGI servers, a demo HTTP server that serves WSGI applications, diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 9ffedf7366a7b8..f68a78e47f6aa5 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -12,7 +12,7 @@ -------------- -:mod:`xml.dom.minidom` is a minimal implementation of the Document Object +:mod:`!xml.dom.minidom` is a minimal implementation of the Document Object Model interface, with an API similar to that in other languages. It is intended to be simpler than the full DOM and also significantly smaller. Users who are not already proficient with the DOM should consider using the @@ -26,7 +26,7 @@ not already proficient with the DOM should consider using the DOM applications typically start by parsing some XML into a DOM. With -:mod:`xml.dom.minidom`, this is done through the parse functions:: +:mod:`!xml.dom.minidom`, this is done through the parse functions:: from xml.dom.minidom import parse, parseString @@ -70,7 +70,7 @@ functions do not provide a parser implementation themselves. You can also create a :class:`Document` by calling a method on a "DOM Implementation" object. You can get this object either by calling the :func:`getDOMImplementation` function in the :mod:`xml.dom` package or the -:mod:`xml.dom.minidom` module. Once you have a :class:`Document`, you +:mod:`!xml.dom.minidom` module. Once you have a :class:`Document`, you can add child nodes to it to populate the DOM:: from xml.dom.minidom import getDOMImplementation @@ -93,7 +93,7 @@ document: the one that holds all others. Here is an example program:: When you are finished with a DOM tree, you may optionally call the :meth:`unlink` method to encourage early cleanup of the now-unneeded -objects. :meth:`unlink` is an :mod:`xml.dom.minidom`\ -specific +objects. :meth:`unlink` is an :mod:`!xml.dom.minidom`\ -specific extension to the DOM API that renders the node and its descendants essentially useless. Otherwise, Python's garbage collector will eventually take care of the objects in the tree. @@ -101,7 +101,7 @@ eventually take care of the objects in the tree. .. seealso:: `Document Object Model (DOM) Level 1 Specification `_ - The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`. + The W3C recommendation for the DOM supported by :mod:`!xml.dom.minidom`. .. _minidom-objects: @@ -111,7 +111,7 @@ DOM Objects The definition of the DOM API for Python is given as part of the :mod:`xml.dom` module documentation. This section lists the differences between the API and -:mod:`xml.dom.minidom`. +:mod:`!xml.dom.minidom`. .. method:: Node.unlink() @@ -214,7 +214,7 @@ particular case, we do not take much advantage of the flexibility of the DOM. minidom and the DOM standard ---------------------------- -The :mod:`xml.dom.minidom` module is essentially a DOM 1.0-compatible DOM with +The :mod:`!xml.dom.minidom` module is essentially a DOM 1.0-compatible DOM with some DOM 2 features (primarily namespace features). Usage of the DOM interface in Python is straight-forward. The following mapping @@ -237,7 +237,7 @@ rules apply: * The types ``short int``, ``unsigned int``, ``unsigned long long``, and ``boolean`` all map to Python integer objects. -* The type ``DOMString`` maps to Python strings. :mod:`xml.dom.minidom` supports +* The type ``DOMString`` maps to Python strings. :mod:`!xml.dom.minidom` supports either bytes or strings, but will normally produce strings. Values of type ``DOMString`` may also be ``None`` where allowed to have the IDL ``null`` value by the DOM specification from the W3C. @@ -245,8 +245,8 @@ rules apply: * ``const`` declarations map to variables in their respective scope (e.g. ``xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE``); they must not be changed. -* ``DOMException`` is currently not supported in :mod:`xml.dom.minidom`. - Instead, :mod:`xml.dom.minidom` uses standard Python exceptions such as +* ``DOMException`` is currently not supported in :mod:`!xml.dom.minidom`. + Instead, :mod:`!xml.dom.minidom` uses standard Python exceptions such as :exc:`TypeError` and :exc:`AttributeError`. * :class:`NodeList` objects are implemented using Python's built-in list type. @@ -255,7 +255,7 @@ rules apply: however, much more "Pythonic" than the interface defined in the W3C recommendations. -The following interfaces have no implementation in :mod:`xml.dom.minidom`: +The following interfaces have no implementation in :mod:`!xml.dom.minidom`: * :class:`DOMTimeStamp` diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst index a21cfaa4645419..5027596ed96ad5 100644 --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`xml.dom.pulldom` module provides a "pull parser" which can also be +The :mod:`!xml.dom.pulldom` module provides a "pull parser" which can also be asked to produce DOM-accessible fragments of the document where necessary. The basic concept involves pulling "events" from a stream of incoming XML and processing them. In contrast to SAX which also employs an event-driven diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index f33b19bc2724d0..8e5a3c13cfd860 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -80,7 +80,7 @@ implementations are free to support the strict mapping from IDL). See section Module Contents --------------- -The :mod:`xml.dom` contains the following functions: +The :mod:`!xml.dom` contains the following functions: .. function:: registerDOMImplementation(name, factory) @@ -135,7 +135,7 @@ Some convenience constants are also provided: HyperText Markup Language `_ (section 3.1.1). -In addition, :mod:`xml.dom` contains a base :class:`Node` class and the DOM +In addition, :mod:`!xml.dom` contains a base :class:`Node` class and the DOM exception classes. The :class:`Node` class provided by this module does not implement any of the methods or attributes defined by the DOM specification; concrete DOM implementations must provide those. The :class:`Node` class diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index e59759683a6d4c..177be9ff4bad25 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`xml.etree.ElementTree` module implements a simple and efficient API +The :mod:`!xml.etree.ElementTree` module implements a simple and efficient API for parsing and creating XML data. .. versionchanged:: 3.3 @@ -28,7 +28,7 @@ for parsing and creating XML data. Tutorial -------- -This is a short tutorial for using :mod:`xml.etree.ElementTree` (``ET`` in +This is a short tutorial for using :mod:`!xml.etree.ElementTree` (``ET`` in short). The goal is to demonstrate some of the building blocks and basic concepts of the module. @@ -795,7 +795,7 @@ Here's an example that demonstrates use of the XInclude module. To include an XM By default, the **href** attribute is treated as a file name. You can use custom loaders to override this behaviour. Also note that the standard helper does not support XPointer syntax. -To process this file, load it as usual, and pass the root element to the :mod:`xml.etree.ElementTree` module: +To process this file, load it as usual, and pass the root element to the :mod:`!xml.etree.ElementTree` module: .. code-block:: python diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index f1af7253e437b4..5079fc0f19ea96 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -16,7 +16,7 @@ error handlers, entity resolvers and lexical handlers. Applications normally only need to implement those interfaces whose events they are interested in; they can implement the interfaces in a single object or in multiple objects. Handler implementations should inherit from the base classes provided in the -module :mod:`xml.sax.handler`, so that all methods get default implementations. +module :mod:`!xml.sax.handler`, so that all methods get default implementations. .. class:: ContentHandler @@ -53,7 +53,7 @@ module :mod:`xml.sax.handler`, so that all methods get default implementations. Interface used by the parser to represent low frequency events which may not be of interest to many applications. -In addition to these classes, :mod:`xml.sax.handler` provides symbolic constants +In addition to these classes, :mod:`!xml.sax.handler` provides symbolic constants for the feature and property names. diff --git a/Doc/library/xml.sax.rst b/Doc/library/xml.sax.rst index 5fa92645a440ce..148cb863aca277 100644 --- a/Doc/library/xml.sax.rst +++ b/Doc/library/xml.sax.rst @@ -12,7 +12,7 @@ -------------- -The :mod:`xml.sax` package provides a number of modules which implement the +The :mod:`!xml.sax` package provides a number of modules which implement the Simple API for XML (SAX) interface for Python. The package itself provides the SAX exceptions and the convenience functions which will be most used by users of the SAX API. @@ -89,9 +89,9 @@ module :mod:`xml.sax.xmlreader`. The handler interfaces are defined in :mod:`xml.sax.handler`. For convenience, :class:`~xml.sax.xmlreader.InputSource` (which is often instantiated directly) and the handler classes are also available from -:mod:`xml.sax`. These interfaces are described below. +:mod:`!xml.sax`. These interfaces are described below. -In addition to these classes, :mod:`xml.sax` provides the following exception +In addition to these classes, :mod:`!xml.sax` provides the following exception classes. diff --git a/Doc/library/xml.sax.utils.rst b/Doc/library/xml.sax.utils.rst index 7731f03d875efc..f93fe374e1c862 100644 --- a/Doc/library/xml.sax.utils.rst +++ b/Doc/library/xml.sax.utils.rst @@ -11,7 +11,7 @@ -------------- -The module :mod:`xml.sax.saxutils` contains a number of classes and functions +The module :mod:`!xml.sax.saxutils` contains a number of classes and functions that are commonly useful when creating SAX applications, either in direct use, or as base classes. diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 7e511237a6abef..75de47d9595628 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -23,13 +23,13 @@ between conformable Python objects and XML on the wire. .. warning:: - The :mod:`xmlrpc.client` module is not secure against maliciously + The :mod:`!xmlrpc.client` module is not secure against maliciously constructed data. If you need to parse untrusted or unauthenticated data, see :ref:`xml-security`. .. versionchanged:: 3.5 - For HTTPS URIs, :mod:`xmlrpc.client` now performs all the necessary + For HTTPS URIs, :mod:`!xmlrpc.client` now performs all the necessary certificate and hostname checks by default. .. include:: ../includes/wasm-notavail.rst diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 2a8f6f8d5fc0de..8da8208331b8c2 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -11,7 +11,7 @@ -------------- -The :mod:`xmlrpc.server` module provides a basic server framework for XML-RPC +The :mod:`!xmlrpc.server` module provides a basic server framework for XML-RPC servers written in Python. Servers can either be free standing, using :class:`SimpleXMLRPCServer`, or embedded in a CGI environment, using :class:`CGIXMLRPCRequestHandler`. @@ -19,7 +19,7 @@ servers written in Python. Servers can either be free standing, using .. warning:: - The :mod:`xmlrpc.server` module is not secure against maliciously + The :mod:`!xmlrpc.server` module is not secure against maliciously constructed data. If you need to parse untrusted or unauthenticated data, see :ref:`xml-security`. diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst index cdaba07ab46c8f..2083857312f5e1 100644 --- a/Doc/library/zipapp.rst +++ b/Doc/library/zipapp.rst @@ -258,7 +258,7 @@ depending on whether your code is written for Python 2 or 3. Creating Standalone Applications with zipapp -------------------------------------------- -Using the :mod:`zipapp` module, it is possible to create self-contained Python +Using the :mod:`!zipapp` module, it is possible to create self-contained Python programs, which can be distributed to end users who only need to have a suitable version of Python installed on their system. The key to doing this is to bundle all of the application's dependencies into the archive, along diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index ae4e25b13b92cd..082c4f8d3b40c3 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -82,7 +82,7 @@ The module defines the following items: Class used to represent information about a member of an archive. Instances of this class are returned by the :meth:`.getinfo` and :meth:`.infolist` - methods of :class:`ZipFile` objects. Most users of the :mod:`zipfile` module + methods of :class:`ZipFile` objects. Most users of the :mod:`!zipfile` module will not need to create these, but only use those created by this module. *filename* should be the full name of the archive member, and *date_time* should be a tuple containing six fields which describe the time @@ -209,7 +209,7 @@ ZipFile objects If *allowZip64* is ``True`` (the default) zipfile will create ZIP files that use the ZIP64 extensions when the zipfile is larger than 4 GiB. If it is - ``false`` :mod:`zipfile` will raise an exception when the ZIP file would + ``false`` :mod:`!zipfile` will raise an exception when the ZIP file would require ZIP64 extensions. The *compresslevel* parameter controls the compression level to use when @@ -957,7 +957,7 @@ Instances have the following methods and attributes: Command-line interface ---------------------- -The :mod:`zipfile` module provides a simple command-line interface to interact +The :mod:`!zipfile` module provides a simple command-line interface to interact with ZIP archives. If you want to create a new ZIP archive, specify its name after the :option:`-c` diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 444c3d631a485d..97f3ede21525cf 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -12,7 +12,7 @@ This module adds the ability to import Python modules (:file:`\*.py`, :file:`\*.pyc`) and packages from ZIP-format archives. It is usually not -needed to use the :mod:`zipimport` module explicitly; it is automatically used +needed to use the :mod:`!zipimport` module explicitly; it is automatically used by the built-in :keyword:`import` mechanism for :data:`sys.path` items that are paths to ZIP archives. @@ -176,7 +176,7 @@ Examples -------- Here is an example that imports a module from a ZIP archive - note that the -:mod:`zipimport` module is not explicitly used. +:mod:`!zipimport` module is not explicitly used. .. code-block:: shell-session diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index 759ec4277b8b7d..099b50b0747504 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -13,9 +13,9 @@ -------------- -The :mod:`zoneinfo` module provides a concrete time zone implementation to +The :mod:`!zoneinfo` module provides a concrete time zone implementation to support the IANA time zone database as originally specified in :pep:`615`. By -default, :mod:`zoneinfo` uses the system's time zone data if available; if no +default, :mod:`!zoneinfo` uses the system's time zone data if available; if no system time zone data is available, the library will fall back to using the first-party :pypi:`tzdata` package available on PyPI. From d891b2bbd16c25995df853121d2f134d3e357cd1 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 6 Feb 2026 09:43:05 -0500 Subject: [PATCH 016/498] gh-139103: Improve namedtuple scaling in free-threaded build (gh-144332) Add `_Py_type_getattro_stackref`, a variant of type attribute lookup that returns `_PyStackRef` instead of `PyObject*`. This allows returning deferred references in the free-threaded build, reducing reference count contention when accessing type attributes. This significantly improves scaling of namedtuple instantiation across multiple threads. * Add blurb * Rename PyObject_GetAttrStackRef to _PyObject_GetAttrStackRef * Apply suggestion from @vstinner Co-authored-by: Victor Stinner * Apply suggestion from @vstinner Co-authored-by: Victor Stinner * format * Update Include/internal/pycore_function.h Co-authored-by: Victor Stinner --------- Co-authored-by: Victor Stinner --- Include/internal/pycore_function.h | 6 + Include/internal/pycore_object.h | 4 + Include/internal/pycore_typeobject.h | 3 + ...-01-29-16-57-11.gh-issue-139103.icXIEQ.rst | 2 + Modules/_testinternalcapi/test_cases.c.h | 10 +- Objects/funcobject.c | 10 ++ Objects/object.c | 49 ++++++ Objects/typeobject.c | 151 ++++++++++++------ Python/bytecodes.c | 5 +- Python/executor_cases.c.h | 10 +- Python/generated_cases.c.h | 10 +- Tools/ftscalingbench/ftscalingbench.py | 20 +++ 12 files changed, 214 insertions(+), 66 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h index e89f4b5c8a4ec1..522e03c6696993 100644 --- a/Include/internal/pycore_function.h +++ b/Include/internal/pycore_function.h @@ -47,6 +47,12 @@ static inline PyObject* _PyFunction_GET_BUILTINS(PyObject *func) { #define _PyFunction_GET_BUILTINS(func) _PyFunction_GET_BUILTINS(_PyObject_CAST(func)) +/* Get the callable wrapped by a staticmethod. + Returns a borrowed reference. + The caller must ensure 'sm' is a staticmethod object. */ +extern PyObject *_PyStaticMethod_GetFunc(PyObject *sm); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index d14cee6af66103..8c241c7707d074 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -898,6 +898,10 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef PyAPI_FUNC(int) _PyObject_GetMethodStackRef(PyThreadState *ts, PyObject *obj, PyObject *name, _PyStackRef *method); +// Like PyObject_GetAttr but returns a _PyStackRef. For types, this can +// return a deferred reference to reduce reference count contention. +PyAPI_FUNC(_PyStackRef) _PyObject_GetAttrStackRef(PyObject *obj, PyObject *name); + // Cache the provided init method in the specialization cache of type if the // provided type version matches the current version of the type. // diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index abaa60890b55c8..dfd355d5012066 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -10,6 +10,7 @@ extern "C" { #include "pycore_interp_structs.h" // managed_static_type_state #include "pycore_moduleobject.h" // PyModuleObject +#include "pycore_structs.h" // _PyStackRef /* state */ @@ -112,6 +113,8 @@ _PyType_IsReady(PyTypeObject *type) extern PyObject* _Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute); extern PyObject* _Py_type_getattro(PyObject *type, PyObject *name); +extern _PyStackRef _Py_type_getattro_stackref(PyTypeObject *type, PyObject *name, + int *suppress_missing_attribute); extern PyObject* _Py_BaseObject_RichCompare(PyObject* self, PyObject* other, int op); diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst new file mode 100644 index 00000000000000..de3391dfcea708 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst @@ -0,0 +1,2 @@ +Improve scaling of :func:`~collections.namedtuple` instantiation in the +free-threaded build. diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index c89c790988c52d..2a73a554eda2cc 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -7925,18 +7925,18 @@ } else { _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); + attr = _PyObject_GetAttrStackRef(PyStackRef_AsPyObjectBorrow(owner), name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; + stack_pointer[-1] = attr; + stack_pointer += (oparg&1); ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); stack_pointer = _PyFrame_GetStackPointer(frame); - if (attr_o == NULL) { + if (PyStackRef_IsNull(attr)) { JUMP_TO_LABEL(error); } - attr = PyStackRef_FromPyObjectSteal(attr_o); - stack_pointer += 1; + stack_pointer += -(oparg&1); } } stack_pointer[-1] = attr; diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 2bf21fa045e3f1..8f4ff4e42392c2 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -7,6 +7,7 @@ #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_object_deferred.h" // _PyObject_SetDeferredRefcount() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_stats.h" @@ -1760,6 +1761,7 @@ sm_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (sm == NULL) { return NULL; } + _PyObject_SetDeferredRefcount((PyObject *)sm); if (sm_set_callable(sm, callable) < 0) { Py_DECREF(sm); return NULL; @@ -1926,9 +1928,17 @@ PyStaticMethod_New(PyObject *callable) if (sm == NULL) { return NULL; } + _PyObject_SetDeferredRefcount((PyObject *)sm); if (sm_set_callable(sm, callable) < 0) { Py_DECREF(sm); return NULL; } return (PyObject *)sm; } + +PyObject * +_PyStaticMethod_GetFunc(PyObject *self) +{ + staticmethod *sm = _PyStaticMethod_CAST(self); + return sm->sm_callable; +} diff --git a/Objects/object.c b/Objects/object.c index 38717def24239f..a4f8ddf54b9484 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -31,6 +31,7 @@ #include "pycore_tuple.h" // _PyTuple_DebugMallocStats() #include "pycore_typeobject.h" // _PyBufferWrapper_Type #include "pycore_typevarobject.h" // _PyTypeAlias_Type +#include "pycore_stackref.h" // PyStackRef_FromPyObjectSteal #include "pycore_unionobject.h" // _PyUnion_Type @@ -1334,6 +1335,54 @@ PyObject_GetAttr(PyObject *v, PyObject *name) return result; } +/* Like PyObject_GetAttr but returns a _PyStackRef. + For types (tp_getattro == _Py_type_getattro), this can return + a deferred reference to reduce reference count contention. */ +_PyStackRef +_PyObject_GetAttrStackRef(PyObject *v, PyObject *name) +{ + PyTypeObject *tp = Py_TYPE(v); + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + Py_TYPE(name)->tp_name); + return PyStackRef_NULL; + } + + /* Fast path for types - can return deferred references */ + if (tp->tp_getattro == _Py_type_getattro) { + _PyStackRef result = _Py_type_getattro_stackref((PyTypeObject *)v, name, NULL); + if (PyStackRef_IsNull(result)) { + _PyObject_SetAttributeErrorContext(v, name); + } + return result; + } + + /* Fall back to regular PyObject_GetAttr and convert to stackref */ + PyObject *result = NULL; + if (tp->tp_getattro != NULL) { + result = (*tp->tp_getattro)(v, name); + } + else if (tp->tp_getattr != NULL) { + const char *name_str = PyUnicode_AsUTF8(name); + if (name_str == NULL) { + return PyStackRef_NULL; + } + result = (*tp->tp_getattr)(v, (char *)name_str); + } + else { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); + } + + if (result == NULL) { + _PyObject_SetAttributeErrorContext(v, name); + return PyStackRef_NULL; + } + return PyStackRef_FromPyObjectSteal(result); +} + int PyObject_GetOptionalAttr(PyObject *v, PyObject *name, PyObject **result) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ac52fe4002dc69..ad26339c9c34df 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6375,102 +6375,153 @@ _PyType_SetFlagsRecursive(PyTypeObject *self, unsigned long mask, unsigned long */ PyObject * -_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int * suppress_missing_attribute) +_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute) +{ + _PyStackRef ref = _Py_type_getattro_stackref(type, name, suppress_missing_attribute); + if (PyStackRef_IsNull(ref)) { + return NULL; + } + return PyStackRef_AsPyObjectSteal(ref); +} + +/* This is similar to PyObject_GenericGetAttr(), + but uses _PyType_LookupRef() instead of just looking in type->tp_dict. */ +PyObject * +_Py_type_getattro(PyObject *tp, PyObject *name) +{ + PyTypeObject *type = PyTypeObject_CAST(tp); + return _Py_type_getattro_impl(type, name, NULL); +} + +/* Like _Py_type_getattro but returns a _PyStackRef. + This can return a deferred reference in the free-threaded build + when the attribute is found without going through a descriptor. + + suppress_missing_attribute (optional): + * NULL: do not suppress the exception + * Non-zero pointer: suppress the PyExc_AttributeError and + set *suppress_missing_attribute to 1 to signal we are returning NULL while + having suppressed the exception (other exceptions are not suppressed) +*/ +_PyStackRef +_Py_type_getattro_stackref(PyTypeObject *type, PyObject *name, + int *suppress_missing_attribute) { PyTypeObject *metatype = Py_TYPE(type); - PyObject *meta_attribute, *attribute; - descrgetfunc meta_get; - PyObject* res; + descrgetfunc meta_get = NULL; if (!PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", Py_TYPE(name)->tp_name); - return NULL; + return PyStackRef_NULL; } /* Initialize this type (we'll assume the metatype is initialized) */ if (!_PyType_IsReady(type)) { if (PyType_Ready(type) < 0) - return NULL; + return PyStackRef_NULL; } - /* No readable descriptor found yet */ - meta_get = NULL; + /* Set up GC-visible stack refs */ + _PyCStackRef result_ref, meta_attribute_ref, attribute_ref; + PyThreadState *tstate = _PyThreadState_GET(); + _PyThreadState_PushCStackRef(tstate, &result_ref); + _PyThreadState_PushCStackRef(tstate, &meta_attribute_ref); + _PyThreadState_PushCStackRef(tstate, &attribute_ref); /* Look for the attribute in the metatype */ - meta_attribute = _PyType_LookupRef(metatype, name); + _PyType_LookupStackRefAndVersion(metatype, name, &meta_attribute_ref.ref); - if (meta_attribute != NULL) { - meta_get = Py_TYPE(meta_attribute)->tp_descr_get; + if (!PyStackRef_IsNull(meta_attribute_ref.ref)) { + PyObject *meta_attr_obj = PyStackRef_AsPyObjectBorrow(meta_attribute_ref.ref); + meta_get = Py_TYPE(meta_attr_obj)->tp_descr_get; - if (meta_get != NULL && PyDescr_IsData(meta_attribute)) { + if (meta_get != NULL && PyDescr_IsData(meta_attr_obj)) { /* Data descriptors implement tp_descr_set to intercept * writes. Assume the attribute is not overridden in * type's tp_dict (and bases): call the descriptor now. */ - res = meta_get(meta_attribute, (PyObject *)type, - (PyObject *)metatype); - Py_DECREF(meta_attribute); - return res; + PyObject *res = meta_get(meta_attr_obj, (PyObject *)type, + (PyObject *)metatype); + if (res != NULL) { + result_ref.ref = PyStackRef_FromPyObjectSteal(res); + } + goto done; } } /* No data descriptor found on metatype. Look in tp_dict of this * type and its bases */ - attribute = _PyType_LookupRef(type, name); - if (attribute != NULL) { + _PyType_LookupStackRefAndVersion(type, name, &attribute_ref.ref); + if (!PyStackRef_IsNull(attribute_ref.ref)) { /* Implement descriptor functionality, if any */ - descrgetfunc local_get = Py_TYPE(attribute)->tp_descr_get; + PyObject *attr_obj = PyStackRef_AsPyObjectBorrow(attribute_ref.ref); + descrgetfunc local_get = Py_TYPE(attr_obj)->tp_descr_get; - Py_XDECREF(meta_attribute); + /* Release meta_attribute early since we found in local dict */ + PyStackRef_CLEAR(meta_attribute_ref.ref); if (local_get != NULL) { + /* Special case staticmethod to avoid descriptor call overhead. + * staticmethod.__get__ just returns the wrapped callable. */ + if (Py_TYPE(attr_obj) == &PyStaticMethod_Type) { + PyObject *callable = _PyStaticMethod_GetFunc(attr_obj); + if (callable) { + result_ref.ref = PyStackRef_FromPyObjectNew(callable); + goto done; + } + } /* NULL 2nd argument indicates the descriptor was * found on the target object itself (or a base) */ - res = local_get(attribute, (PyObject *)NULL, - (PyObject *)type); - Py_DECREF(attribute); - return res; + PyObject *res = local_get(attr_obj, (PyObject *)NULL, + (PyObject *)type); + if (res != NULL) { + result_ref.ref = PyStackRef_FromPyObjectSteal(res); + } + goto done; } - return attribute; + /* No descriptor, return the attribute directly */ + result_ref.ref = attribute_ref.ref; + attribute_ref.ref = PyStackRef_NULL; + goto done; } /* No attribute found in local __dict__ (or bases): use the * descriptor from the metatype, if any */ if (meta_get != NULL) { - PyObject *res; - res = meta_get(meta_attribute, (PyObject *)type, - (PyObject *)metatype); - Py_DECREF(meta_attribute); - return res; + PyObject *meta_attr_obj = PyStackRef_AsPyObjectBorrow(meta_attribute_ref.ref); + PyObject *res = meta_get(meta_attr_obj, (PyObject *)type, + (PyObject *)metatype); + if (res != NULL) { + result_ref.ref = PyStackRef_FromPyObjectSteal(res); + } + goto done; } /* If an ordinary attribute was found on the metatype, return it now */ - if (meta_attribute != NULL) { - return meta_attribute; + if (!PyStackRef_IsNull(meta_attribute_ref.ref)) { + result_ref.ref = meta_attribute_ref.ref; + meta_attribute_ref.ref = PyStackRef_NULL; + goto done; } /* Give up */ if (suppress_missing_attribute == NULL) { PyErr_Format(PyExc_AttributeError, - "type object '%.100s' has no attribute '%U'", - type->tp_name, name); - } else { + "type object '%.100s' has no attribute '%U'", + type->tp_name, name); + } + else { // signal the caller we have not set an PyExc_AttributeError and gave up *suppress_missing_attribute = 1; } - return NULL; -} -/* This is similar to PyObject_GenericGetAttr(), - but uses _PyType_LookupRef() instead of just looking in type->tp_dict. */ -PyObject * -_Py_type_getattro(PyObject *tp, PyObject *name) -{ - PyTypeObject *type = PyTypeObject_CAST(tp); - return _Py_type_getattro_impl(type, name, NULL); +done: + _PyThreadState_PopCStackRef(tstate, &attribute_ref); + _PyThreadState_PopCStackRef(tstate, &meta_attribute_ref); + return _PyThreadState_PopCStackRefSteal(tstate, &result_ref); } // Called by type_setattro(). Updates both the type dict and @@ -10937,15 +10988,19 @@ static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *func, *result; + PyObject *result; - func = PyObject_GetAttr((PyObject *)type, &_Py_ID(__new__)); - if (func == NULL) { + _PyCStackRef func_ref; + _PyThreadState_PushCStackRef(tstate, &func_ref); + func_ref.ref = _PyObject_GetAttrStackRef((PyObject *)type, &_Py_ID(__new__)); + if (PyStackRef_IsNull(func_ref.ref)) { + _PyThreadState_PopCStackRef(tstate, &func_ref); return NULL; } + PyObject *func = PyStackRef_AsPyObjectBorrow(func_ref.ref); result = _PyObject_Call_Prepend(tstate, func, (PyObject *)type, args, kwds); - Py_DECREF(func); + _PyThreadState_PopCStackRef(tstate, &func_ref); return result; } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index a014f56deb202e..818b4fbc3801c0 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2392,10 +2392,9 @@ dummy_func( } else { /* Classic, pushes one value. */ - PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); + attr = _PyObject_GetAttrStackRef(PyStackRef_AsPyObjectBorrow(owner), name); PyStackRef_CLOSE(owner); - ERROR_IF(attr_o == NULL); - attr = PyStackRef_FromPyObjectSteal(attr_o); + ERROR_IF(PyStackRef_IsNull(attr)); } } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 08c547c4a0a3b4..a98ec2200485d2 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -8703,19 +8703,19 @@ stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); + attr = _PyObject_GetAttrStackRef(PyStackRef_AsPyObjectBorrow(owner), name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; + stack_pointer[-1] = attr; + stack_pointer += (oparg&1); ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); stack_pointer = _PyFrame_GetStackPointer(frame); - if (attr_o == NULL) { + if (PyStackRef_IsNull(attr)) { SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } - attr = PyStackRef_FromPyObjectSteal(attr_o); - stack_pointer += 1; + stack_pointer += -(oparg&1); } _tos_cache0 = PyStackRef_ZERO_BITS; _tos_cache1 = PyStackRef_ZERO_BITS; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index be5dbfcc747935..fc1144a88d70cc 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -7924,18 +7924,18 @@ } else { _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); + attr = _PyObject_GetAttrStackRef(PyStackRef_AsPyObjectBorrow(owner), name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; + stack_pointer[-1] = attr; + stack_pointer += (oparg&1); ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); stack_pointer = _PyFrame_GetStackPointer(frame); - if (attr_o == NULL) { + if (PyStackRef_IsNull(attr)) { JUMP_TO_LABEL(error); } - attr = PyStackRef_FromPyObjectSteal(attr_o); - stack_pointer += 1; + stack_pointer += -(oparg&1); } } stack_pointer[-1] = attr; diff --git a/Tools/ftscalingbench/ftscalingbench.py b/Tools/ftscalingbench/ftscalingbench.py index c2bd7c3880bc90..50d0e4c04fc319 100644 --- a/Tools/ftscalingbench/ftscalingbench.py +++ b/Tools/ftscalingbench/ftscalingbench.py @@ -28,8 +28,10 @@ import sys import threading import time +from collections import namedtuple from dataclasses import dataclass from operator import methodcaller +from typing import NamedTuple # The iterations in individual benchmarks are scaled by this factor. WORK_SCALE = 100 @@ -215,6 +217,24 @@ def instantiate_dataclass(): for _ in range(1000 * WORK_SCALE): obj = MyDataClass(x=1, y=2, z=3) +MyNamedTuple = namedtuple("MyNamedTuple", ["x", "y", "z"]) + +@register_benchmark +def instantiate_namedtuple(): + for _ in range(1000 * WORK_SCALE): + obj = MyNamedTuple(x=1, y=2, z=3) + + +class MyTypingNamedTuple(NamedTuple): + x: int + y: int + z: int + +@register_benchmark +def instantiate_typing_namedtuple(): + for _ in range(1000 * WORK_SCALE): + obj = MyTypingNamedTuple(x=1, y=2, z=3) + @register_benchmark def deepcopy(): From 45d4a347205ede4568d912edf820e4de80213392 Mon Sep 17 00:00:00 2001 From: kangtastic <942136+kangtastic@users.noreply.github.com> Date: Fri, 6 Feb 2026 06:43:16 -0800 Subject: [PATCH 017/498] gh-101178: Add Ascii85, Base85, and Z85 support to binascii (GH-102753) Add Ascii85, Base85, and Z85 encoders and decoders to binascii, replacing the existing pure Python implementations in base64. This makes the codecs two orders of magnitude faster and consume two orders of magnitude less memory. Note that attempting to decode Ascii85 or Base85 data of length 1 mod 5 (after accounting for Ascii85 quirks) now produces an error, as no encoder would emit such data. This should be the only significant externally visible difference compared to the old implementation. Co-authored-by: Serhiy Storchaka --- Doc/library/base64.rst | 10 +- Doc/library/binascii.rst | 106 ++++ Doc/whatsnew/3.15.rst | 13 + .../pycore_global_objects_fini_generated.h | 3 + Include/internal/pycore_global_strings.h | 3 + .../internal/pycore_runtime_init_generated.h | 3 + .../internal/pycore_unicodeobject_generated.h | 12 + Lib/base64.py | 186 +----- Lib/test/test_base64.py | 23 +- Lib/test/test_binascii.py | 361 ++++++++++- Misc/ACKS | 1 + ...-12-28-15-55-53.gh-issue-101178.26jYPs.rst | 2 + Modules/binascii.c | 586 ++++++++++++++++++ Modules/clinic/binascii.c.h | 441 ++++++++++++- 14 files changed, 1558 insertions(+), 192 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 554d6e7d04ded2..975c488813722e 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -247,8 +247,9 @@ Refer to the documentation of the individual functions for more information. after at most every *wrapcol* characters. If *wrapcol* is zero (default), do not insert any newlines. - *pad* controls whether the input is padded to a multiple of 4 - before encoding. Note that the ``btoa`` implementation always pads. + If *pad* is true, the input is padded with ``b'\0'`` so its length is a + multiple of 4 bytes before encoding. + Note that the ``btoa`` implementation always pads. *adobe* controls whether the encoded byte sequence is framed with ``<~`` and ``~>``, which is used by the Adobe implementation. @@ -268,8 +269,9 @@ Refer to the documentation of the individual functions for more information. *adobe* controls whether the input sequence is in Adobe Ascii85 format (i.e. is framed with <~ and ~>). - *ignorechars* should be a byte string containing characters to ignore - from the input. This should only contain whitespace characters, and by + *ignorechars* should be a :term:`bytes-like object` containing characters + to ignore from the input. + This should only contain whitespace characters, and by default contains all whitespace characters in ASCII. .. versionadded:: 3.4 diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 4693ff6336ef7c..39320da93a8ad7 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -98,6 +98,112 @@ The :mod:`!binascii` module defines the following functions: Added the *wrapcol* parameter. +.. function:: a2b_ascii85(string, /, *, foldspaces=False, adobe=False, ignorechars=b"") + + Convert Ascii85 data back to binary and return the binary data. + + Valid Ascii85 data contains characters from the Ascii85 alphabet in groups + of five (except for the final group, which may have from two to five + characters). Each group encodes 32 bits of binary data in the range from + ``0`` to ``2 ** 32 - 1``, inclusive. The special character ``z`` is + accepted as a short form of the group ``!!!!!``, which encodes four + consecutive null bytes. + + *foldspaces* is a flag that specifies whether the 'y' short sequence + should be accepted as shorthand for 4 consecutive spaces (ASCII 0x20). + This feature is not supported by the "standard" Ascii85 encoding. + + *adobe* controls whether the input sequence is in Adobe Ascii85 format + (i.e. is framed with <~ and ~>). + + *ignorechars* should be a :term:`bytes-like object` containing characters + to ignore from the input. + This should only contain whitespace characters. + + Invalid Ascii85 data will raise :exc:`binascii.Error`. + + .. versionadded:: next + + +.. function:: b2a_ascii85(data, /, *, foldspaces=False, wrapcol=0, pad=False, adobe=False) + + Convert binary data to a formatted sequence of ASCII characters in Ascii85 + coding. The return value is the converted data. + + *foldspaces* is an optional flag that uses the special short sequence 'y' + instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This + feature is not supported by the "standard" Ascii85 encoding. + + If *wrapcol* is non-zero, insert a newline (``b'\n'``) character + after at most every *wrapcol* characters. + If *wrapcol* is zero (default), do not insert any newlines. + + If *pad* is true, the input is padded with ``b'\0'`` so its length is a + multiple of 4 bytes before encoding. + Note that the ``btoa`` implementation always pads. + + *adobe* controls whether the encoded byte sequence is framed with ``<~`` + and ``~>``, which is used by the Adobe implementation. + + .. versionadded:: next + + +.. function:: a2b_base85(string, /) + + Convert Base85 data back to binary and return the binary data. + More than one line may be passed at a time. + + Valid Base85 data contains characters from the Base85 alphabet in groups + of five (except for the final group, which may have from two to five + characters). Each group encodes 32 bits of binary data in the range from + ``0`` to ``2 ** 32 - 1``, inclusive. + + Invalid Base85 data will raise :exc:`binascii.Error`. + + .. versionadded:: next + + +.. function:: b2a_base85(data, /, *, pad=False) + + Convert binary data to a line of ASCII characters in Base85 coding. + The return value is the converted line. + + If *pad* is true, the input is padded with ``b'\0'`` so its length is a + multiple of 4 bytes before encoding. + + .. versionadded:: next + + +.. function:: a2b_z85(string, /) + + Convert Z85 data back to binary and return the binary data. + More than one line may be passed at a time. + + Valid Z85 data contains characters from the Z85 alphabet in groups + of five (except for the final group, which may have from two to five + characters). Each group encodes 32 bits of binary data in the range from + ``0`` to ``2 ** 32 - 1``, inclusive. + + See `Z85 specification `_ for more information. + + Invalid Z85 data will raise :exc:`binascii.Error`. + + .. versionadded:: next + + +.. function:: b2a_z85(data, /, *, pad=False) + + Convert binary data to a line of ASCII characters in Z85 coding. + The return value is the converted line. + + If *pad* is true, the input is padded with ``b'\0'`` so its length is a + multiple of 4 bytes before encoding. + + See `Z85 specification `_ for more information. + + .. versionadded:: next + + .. function:: a2b_qp(data, header=False) Convert a block of quoted-printable data back to binary and return the binary diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 20250003dca34e..68fa10b0c08d17 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -491,6 +491,14 @@ base64 binascii -------- +* Added functions for Ascii85, Base85, and Z85 encoding: + + - :func:`~binascii.b2a_ascii85` and :func:`~binascii.a2b_ascii85` + - :func:`~binascii.b2a_base85` and :func:`~binascii.a2b_base85` + - :func:`~binascii.b2a_z85` and :func:`~binascii.a2b_z85` + + (Contributed by James Seo and Serhiy Storchaka in :gh:`101178`.) + * Added the *wrapcol* parameter in :func:`~binascii.b2a_base64`. (Contributed by Serhiy Storchaka in :gh:`143214`.) @@ -1059,6 +1067,11 @@ base64 & binascii faster thanks to simple CPU pipelining optimizations. (Contributed by Gregory P. Smith and Serhiy Storchaka in :gh:`143262`.) +* Implementation for Ascii85, Base85, and Z85 encoding has been rewritten in C. + Encoding and decoding is now two orders of magnitude faster and consumes + two orders of magnitude less memory. + (Contributed by James Seo and Serhiy Storchaka in :gh:`101178`.) + csv --- diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index cb62d9424a86b0..09b8762ee2de35 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -1574,6 +1574,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aclose)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add_done_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(adobe)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_child)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_parent)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(alias)); @@ -1769,6 +1770,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flags)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flush)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fold)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(foldspaces)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(follow_symlinks)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format_spec)); @@ -1968,6 +1970,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(outpath)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(overlapped)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(owner)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pad)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pages)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(parameter)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(parent)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 92de92079379ea..040f79afeebb11 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -297,6 +297,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(aclose) STRUCT_FOR_ID(add) STRUCT_FOR_ID(add_done_callback) + STRUCT_FOR_ID(adobe) STRUCT_FOR_ID(after_in_child) STRUCT_FOR_ID(after_in_parent) STRUCT_FOR_ID(alias) @@ -492,6 +493,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(flags) STRUCT_FOR_ID(flush) STRUCT_FOR_ID(fold) + STRUCT_FOR_ID(foldspaces) STRUCT_FOR_ID(follow_symlinks) STRUCT_FOR_ID(format) STRUCT_FOR_ID(format_spec) @@ -691,6 +693,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(outpath) STRUCT_FOR_ID(overlapped) STRUCT_FOR_ID(owner) + STRUCT_FOR_ID(pad) STRUCT_FOR_ID(pages) STRUCT_FOR_ID(parameter) STRUCT_FOR_ID(parent) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index dc05495e20d69d..f4ea7b7954bb84 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -1572,6 +1572,7 @@ extern "C" { INIT_ID(aclose), \ INIT_ID(add), \ INIT_ID(add_done_callback), \ + INIT_ID(adobe), \ INIT_ID(after_in_child), \ INIT_ID(after_in_parent), \ INIT_ID(alias), \ @@ -1767,6 +1768,7 @@ extern "C" { INIT_ID(flags), \ INIT_ID(flush), \ INIT_ID(fold), \ + INIT_ID(foldspaces), \ INIT_ID(follow_symlinks), \ INIT_ID(format), \ INIT_ID(format_spec), \ @@ -1966,6 +1968,7 @@ extern "C" { INIT_ID(outpath), \ INIT_ID(overlapped), \ INIT_ID(owner), \ + INIT_ID(pad), \ INIT_ID(pages), \ INIT_ID(parameter), \ INIT_ID(parent), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 10085149f09b6c..f9677d01228dce 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -968,6 +968,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(adobe); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(after_in_child); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -1748,6 +1752,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(foldspaces); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(follow_symlinks); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2544,6 +2552,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(pad); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(pages); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Lib/base64.py b/Lib/base64.py index 7cb22e3efc1714..36688ce43917ce 100644 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -4,7 +4,6 @@ # Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support # Modified 22-May-2007 by Guido van Rossum to use bytes everywhere -import struct import binascii @@ -339,36 +338,6 @@ def b16decode(s, casefold=False): # # Ascii85 encoding/decoding # - -_a85chars = None -_a85chars2 = None -_A85START = b"<~" -_A85END = b"~>" - -def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): - # Helper function for a85encode and b85encode - if not isinstance(b, bytes_types): - b = memoryview(b).tobytes() - - padding = (-len(b)) % 4 - if padding: - b = b + b'\0' * padding - words = struct.Struct('!%dI' % (len(b) // 4)).unpack(b) - - chunks = [b'z' if foldnuls and not word else - b'y' if foldspaces and word == 0x20202020 else - (chars2[word // 614125] + - chars2[word // 85 % 7225] + - chars[word % 85]) - for word in words] - - if padding and not pad: - if chunks[-1] == b'z': - chunks[-1] = chars[0] * 5 - chunks[-1] = chunks[-1][:-padding] - - return b''.join(chunks) - def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): """Encode bytes-like object b using Ascii85 and return a bytes object. @@ -385,29 +354,8 @@ def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): adobe controls whether the encoded byte sequence is framed with <~ and ~>, which is used by the Adobe implementation. """ - global _a85chars, _a85chars2 - # Delay the initialization of tables to not waste memory - # if the function is never called - if _a85chars2 is None: - _a85chars = [bytes((i,)) for i in range(33, 118)] - _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] - - result = _85encode(b, _a85chars, _a85chars2, pad, True, foldspaces) - - if adobe: - result = _A85START + result - if wrapcol: - wrapcol = max(2 if adobe else 1, wrapcol) - chunks = [result[i: i + wrapcol] - for i in range(0, len(result), wrapcol)] - if adobe: - if len(chunks[-1]) + 2 > wrapcol: - chunks.append(b'') - result = b'\n'.join(chunks) - if adobe: - result += _A85END - - return result + return binascii.b2a_ascii85(b, foldspaces=foldspaces, + adobe=adobe, wrapcol=wrapcol, pad=pad) def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): """Decode the Ascii85 encoded bytes-like object or ASCII string b. @@ -425,67 +373,8 @@ def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): The result is returned as a bytes object. """ - b = _bytes_from_decode_data(b) - if adobe: - if not b.endswith(_A85END): - raise ValueError( - "Ascii85 encoded byte sequences must end " - "with {!r}".format(_A85END) - ) - if b.startswith(_A85START): - b = b[2:-2] # Strip off start/end markers - else: - b = b[:-2] - # - # We have to go through this stepwise, so as to ignore spaces and handle - # special short sequences - # - packI = struct.Struct('!I').pack - decoded = [] - decoded_append = decoded.append - curr = [] - curr_append = curr.append - curr_clear = curr.clear - for x in b + b'u' * 4: - if b'!'[0] <= x <= b'u'[0]: - curr_append(x) - if len(curr) == 5: - acc = 0 - for x in curr: - acc = 85 * acc + (x - 33) - try: - decoded_append(packI(acc)) - except struct.error: - raise ValueError('Ascii85 overflow') from None - curr_clear() - elif x == b'z'[0]: - if curr: - raise ValueError('z inside Ascii85 5-tuple') - decoded_append(b'\0\0\0\0') - elif foldspaces and x == b'y'[0]: - if curr: - raise ValueError('y inside Ascii85 5-tuple') - decoded_append(b'\x20\x20\x20\x20') - elif x in ignorechars: - # Skip whitespace - continue - else: - raise ValueError('Non-Ascii85 digit found: %c' % x) - - result = b''.join(decoded) - padding = 4 - len(curr) - if padding: - # Throw away the extra padding - result = result[:-padding] - return result - -# The following code is originally taken (with permission) from Mercurial - -_b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~") -_b85chars = None -_b85chars2 = None -_b85dec = None + return binascii.a2b_ascii85(b, foldspaces=foldspaces, + adobe=adobe, ignorechars=ignorechars) def b85encode(b, pad=False): """Encode bytes-like object b in base85 format and return a bytes object. @@ -493,84 +382,25 @@ def b85encode(b, pad=False): If pad is true, the input is padded with b'\\0' so its length is a multiple of 4 bytes before encoding. """ - global _b85chars, _b85chars2 - # Delay the initialization of tables to not waste memory - # if the function is never called - if _b85chars2 is None: - _b85chars = [bytes((i,)) for i in _b85alphabet] - _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] - return _85encode(b, _b85chars, _b85chars2, pad) + return binascii.b2a_base85(b, pad=pad) def b85decode(b): """Decode the base85-encoded bytes-like object or ASCII string b The result is returned as a bytes object. """ - global _b85dec - # Delay the initialization of tables to not waste memory - # if the function is never called - if _b85dec is None: - # we don't assign to _b85dec directly to avoid issues when - # multiple threads call this function simultaneously - b85dec_tmp = [None] * 256 - for i, c in enumerate(_b85alphabet): - b85dec_tmp[c] = i - _b85dec = b85dec_tmp - - b = _bytes_from_decode_data(b) - padding = (-len(b)) % 5 - b = b + b'~' * padding - out = [] - packI = struct.Struct('!I').pack - for i in range(0, len(b), 5): - chunk = b[i:i + 5] - acc = 0 - try: - for c in chunk: - acc = acc * 85 + _b85dec[c] - except TypeError: - for j, c in enumerate(chunk): - if _b85dec[c] is None: - raise ValueError('bad base85 character at position %d' - % (i + j)) from None - raise - try: - out.append(packI(acc)) - except struct.error: - raise ValueError('base85 overflow in hunk starting at byte %d' - % i) from None - - result = b''.join(out) - if padding: - result = result[:-padding] - return result - -_z85alphabet = (b'0123456789abcdefghijklmnopqrstuvwxyz' - b'ABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#') -# Translating b85 valid but z85 invalid chars to b'\x00' is required -# to prevent them from being decoded as b85 valid chars. -_z85_b85_decode_diff = b';_`|~' -_z85_decode_translation = bytes.maketrans( - _z85alphabet + _z85_b85_decode_diff, - _b85alphabet + b'\x00' * len(_z85_b85_decode_diff) -) -_z85_encode_translation = bytes.maketrans(_b85alphabet, _z85alphabet) + return binascii.a2b_base85(b) def z85encode(s, pad=False): """Encode bytes-like object b in z85 format and return a bytes object.""" - return b85encode(s, pad).translate(_z85_encode_translation) + return binascii.b2a_z85(s, pad=pad) def z85decode(s): """Decode the z85-encoded bytes-like object or ASCII string b The result is returned as a bytes object. """ - s = _bytes_from_decode_data(s) - s = s.translate(_z85_decode_translation) - try: - return b85decode(s) - except ValueError as e: - raise ValueError(e.args[0].replace('base85', 'z85')) from None + return binascii.a2b_z85(s) # Legacy interface. This code could be cleaned up since I don't believe # binascii has any line length limitations. It just doesn't seem worth it diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index fef18a1b757c08..69aa628db7c34c 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -745,17 +745,20 @@ def test_a85encode_wrapcol(self): b'<~\nGB\n\\6\n`E\n-Z\nP=\nDf\n.1\nGE\nb>\n~>') eq(base64.a85encode(b, wrapcol=sys.maxsize), b'GB\\6`E-ZP=Df.1GEb>') if check_impl_detail(): - eq(base64.a85encode(b, wrapcol=2**1000), b'GB\\6`E-ZP=Df.1GEb>') - eq(base64.a85encode(b, wrapcol=-7), - b'G\nB\n\\\n6\n`\nE\n-\nZ\nP\n=\nD\nf\n.\n1\nG\nE\nb\n>') - eq(base64.a85encode(b, wrapcol=-7, adobe=True), - b'<~\nGB\n\\6\n`E\n-Z\nP=\nDf\n.1\nGE\nb>\n~>') + eq(base64.a85encode(b, wrapcol=sys.maxsize*2), + b'GB\\6`E-ZP=Df.1GEb>') + with self.assertRaises(OverflowError): + base64.a85encode(b, wrapcol=2**1000) + with self.assertRaises(ValueError): + base64.a85encode(b, wrapcol=-7) + with self.assertRaises(ValueError): + base64.a85encode(b, wrapcol=-7, adobe=True) with self.assertRaises(TypeError): base64.a85encode(b, wrapcol=7.0) with self.assertRaises(TypeError): base64.a85encode(b, wrapcol='7') - if check_impl_detail(): - eq(base64.a85encode(b, wrapcol=None), b'GB\\6`E-ZP=Df.1GEb>') + with self.assertRaises(TypeError): + base64.a85encode(b, wrapcol=None) eq(base64.a85encode(b'', wrapcol=0), b'') eq(base64.a85encode(b'', wrapcol=7), b'') eq(base64.a85encode(b'', wrapcol=1, adobe=True), b'<~\n~>') @@ -962,6 +965,12 @@ def test_a85_padding(self): eq(base64.a85decode(b'G^+IX'), b"xxxx") eq(base64.a85decode(b'G^+IXGQ7^D'), b"xxxxx\x00\x00\x00") + eq(base64.a85encode(b"\x00", pad=True), b'z') + eq(base64.a85encode(b"\x00"*2, pad=True), b'z') + eq(base64.a85encode(b"\x00"*3, pad=True), b'z') + eq(base64.a85encode(b"\x00"*4, pad=True), b'z') + eq(base64.a85encode(b"\x00"*5, pad=True), b'zz') + def test_b85_padding(self): eq = self.assertEqual diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index a4928794e0acfb..9f0d15fe538810 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -10,9 +10,11 @@ # Note: "*_hex" functions are aliases for "(un)hexlify" -b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_qp', 'b2a_uu', +b2a_functions = ['b2a_ascii85', 'b2a_base64', 'b2a_base85', 'b2a_z85', + 'b2a_hex', 'b2a_qp', 'b2a_uu', 'hexlify'] -a2b_functions = ['a2b_base64', 'a2b_hex', 'a2b_qp', 'a2b_uu', +a2b_functions = ['a2b_ascii85', 'a2b_base64', 'a2b_base85', 'a2b_z85', + 'a2b_hex', 'a2b_qp', 'a2b_uu', 'unhexlify'] all_functions = a2b_functions + b2a_functions + ['crc32', 'crc_hqx'] @@ -24,6 +26,8 @@ class BinASCIITest(unittest.TestCase): rawdata = b"The quick brown fox jumps over the lazy dog.\r\n" # Be slow so we don't depend on other modules rawdata += bytes(range(256)) + rawdata += b'\0'*32 + rawdata += b' '*32 rawdata += b"\r\nHello world.\n" def setUp(self): @@ -298,6 +302,359 @@ def assertInvalidLength(data, strict_mode=True): assertInvalidLength(b'A\tB\nC ??DE', # only 5 valid characters strict_mode=False) + def test_ascii85_valid(self): + # Test Ascii85 with valid data + ASCII85_PREFIX = b"<~" + ASCII85_SUFFIX = b"~>" + + # Interleave blocks of 4 null bytes and 4 spaces into test data + rawdata = bytearray() + rawlines, i = [], 0 + for k in range(1, len(self.rawdata) + 1): + b = b"\0\0\0\0" if k & 1 else b" " + b = b + self.rawdata[i:i + k] + b = b" " if k & 1 else b"\0\0\0\0" + rawdata += b + rawlines.append(b) + i += k + if i >= len(self.rawdata): + break + + # Test core parameter combinations + params = (False, False), (False, True), (True, False), (True, True) + for foldspaces, adobe in params: + lines = [] + for rawline in rawlines: + b = self.type2test(rawline) + a = binascii.b2a_ascii85(b, foldspaces=foldspaces, adobe=adobe) + lines.append(a) + res = bytearray() + for line in lines: + a = self.type2test(line) + b = binascii.a2b_ascii85(a, foldspaces=foldspaces, adobe=adobe) + res += b + self.assertEqual(res, rawdata) + + # Test decoding inputs with length 1 mod 5 + params = [ + (b"a", False, False, b"", b""), + (b"xbw", False, False, b"wx", b""), + (b"<~c~>", False, True, b"", b""), + (b"{d ~>", False, True, b" {", b""), + (b"ye", True, False, b"", b" "), + (b"z\x01y\x00f", True, False, b"\x00\x01", b"\x00\x00\x00\x00 "), + (b"<~FCfN8yg~>", True, True, b"", b"test "), + (b"FE;\x03#8zFCf\x02N8yh~>", True, True, b"\x02\x03", b"tset\x00\x00\x00\x00test "), + ] + for a, foldspaces, adobe, ignorechars, b in params: + kwargs = {"foldspaces": foldspaces, "adobe": adobe, "ignorechars": ignorechars} + self.assertEqual(binascii.a2b_ascii85(self.type2test(a), **kwargs), b) + + def test_ascii85_invalid(self): + # Test Ascii85 with invalid characters interleaved + lines, i = [], 0 + for k in range(1, len(self.rawdata) + 1): + b = self.type2test(self.rawdata[i:i + k]) + a = binascii.b2a_ascii85(b) + lines.append(a) + i += k + if i >= len(self.rawdata): + break + + fillers = bytearray() + valid = b"!\"#$%&'()*+,-./0123456789:;<=>?@" \ + b"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu" + b"z" + for i in range(256): + if i not in valid: + fillers.append(i) + def addnoise(line): + res = bytearray() + for i in range(len(line)): + res.append(line[i]) + for j in range(i, len(fillers), len(line)): + res.append(fillers[j]) + return res + res = bytearray() + for line in map(addnoise, lines): + a = self.type2test(line) + b = binascii.a2b_ascii85(a, ignorechars=fillers) + res += b + self.assertEqual(res, self.rawdata) + + # Test Ascii85 with only invalid characters + fillers = self.type2test(fillers) + b = binascii.a2b_ascii85(fillers, ignorechars=fillers) + self.assertEqual(b, b"") + + def test_ascii85_errors(self): + def _assertRegexTemplate(assert_regex, data, **kwargs): + with self.assertRaisesRegex(binascii.Error, assert_regex): + binascii.a2b_ascii85(self.type2test(data), **kwargs) + + def assertMissingDelimiter(data): + _assertRegexTemplate(r"(?i)end with b'~>'", data, adobe=True) + + def assertOverflow(data): + _assertRegexTemplate(r"(?i)Ascii85 overflow", data) + + def assertInvalidSpecial(data): + _assertRegexTemplate(r"(?i)'[yz]'.+5-tuple", data, foldspaces=True) + + def assertInvalidChar(data, **kwargs): + _assertRegexTemplate(r"(?i)Non-Ascii85 digit", data, **kwargs) + + # Test Ascii85 with missing delimiters + assertMissingDelimiter(b"") + assertMissingDelimiter(b"a") + assertMissingDelimiter(b"<~") + assertMissingDelimiter(b"<~!~") + assertMissingDelimiter(b"<~abc>") + assertMissingDelimiter(b"<~has delimiter but not terminal~> !") + + # Test Ascii85 with out-of-range encoded value + assertOverflow(b"t") + assertOverflow(b"s9") + assertOverflow(b"s8X") + assertOverflow(b"s8W.") + assertOverflow(b's8W-"') + assertOverflow(b"s8W-!u") + assertOverflow(b"s8W-!s8W-!zs8X") + + # Test Ascii85 with misplaced short form groups + assertInvalidSpecial(b"ay") + assertInvalidSpecial(b"az") + assertInvalidSpecial(b"aby") + assertInvalidSpecial(b"ayz") + assertInvalidSpecial(b"abcz") + assertInvalidSpecial(b"abcdy") + assertInvalidSpecial(b"y!and!z!then!!y") + + # Test Ascii85 with non-ignored invalid characters + assertInvalidChar(b"j\n") + assertInvalidChar(b" ", ignorechars=b"") + assertInvalidChar(b" valid\x02until\x03", ignorechars=b"\x00\x01\x02\x04") + assertInvalidChar(b"\tFCb", ignorechars=b"\n") + assertInvalidChar(b"xxxB\nP\thU'D v/F+", ignorechars=b" \n\tv") + + def test_ascii85_wrapcol(self): + # Test Ascii85 splitting lines + def assertEncode(a_expected, data, n, adobe=False): + b = self.type2test(data) + a = binascii.b2a_ascii85(b, adobe=adobe, wrapcol=n) + self.assertEqual(a, a_expected) + + def assertDecode(data, b_expected, adobe=False): + a = self.type2test(data) + b = binascii.a2b_ascii85(a, adobe=adobe, ignorechars=b"\n") + self.assertEqual(b, b_expected) + + tests = [ + (b"", 0, b"", b"<~~>"), + (b"", 1, b"", b"<~\n~>"), + (b"a", 0, b"@/", b"<~@/~>"), + (b"a", 1, b"@\n/", b"<~\n@/\n~>"), + (b"a", 2, b"@/", b"<~\n@/\n~>"), + (b"a", 3, b"@/", b"<~@\n/~>"), + (b"a", 4, b"@/", b"<~@/\n~>"), + (b"a", 5, b"@/", b"<~@/\n~>"), + (b"a", 6, b"@/", b"<~@/~>"), + (b"a", 7, b"@/", b"<~@/~>"), + (b"a", 123, b"@/", b"<~@/~>"), + (b"this is a test", 7, b"FD,B0+D\nGm>@3BZ\n'F*%", + b"<~FD,B0\n+DGm>@3\nBZ'F*%\n~>"), + (b"a test!!!!!!! ", 11, b"@3BZ'F*&QK+\nX&!P+WqmM+9", + b"<~@3BZ'F*&Q\nK+X&!P+WqmM\n+9~>"), + (b"\0" * 56, 7, b"zzzzzzz\nzzzzzzz", b"<~zzzzz\nzzzzzzz\nzz~>"), + ] + for b, n, a, a_wrap in tests: + assertEncode(a, b, n) + assertEncode(a_wrap, b, n, adobe=True) + assertDecode(a, b) + assertDecode(a_wrap, b, adobe=True) + + def test_ascii85_pad(self): + # Test Ascii85 with encode padding + rawdata = b"n1n3tee\n ch@rAcTer$" + for i in range(1, len(rawdata) + 1): + padding = -i % 4 + b = rawdata[:i] + a_pad = binascii.b2a_ascii85(self.type2test(b), pad=True) + b_pad = binascii.a2b_ascii85(self.type2test(a_pad)) + b_pad_expected = b + b"\0" * padding + self.assertEqual(b_pad, b_pad_expected) + + # Test Ascii85 short form groups with encode padding + def assertShortPad(data, expected, **kwargs): + data = self.type2test(data) + res = binascii.b2a_ascii85(data, **kwargs) + self.assertEqual(res, expected) + + assertShortPad(b"\0", b"!!", pad=False) + assertShortPad(b"\0", b"z", pad=True) + assertShortPad(b"\0" * 2, b"z", pad=True) + assertShortPad(b"\0" * 3, b"z", pad=True) + assertShortPad(b"\0" * 4, b"z", pad=True) + assertShortPad(b"\0" * 5, b"zz", pad=True) + assertShortPad(b"\0" * 6, b"z!!!") + assertShortPad(b" " * 7, b"y+", + foldspaces=True, adobe=True, pad=True) + assertShortPad(b"\0\0\0\0abcd \0\0", b"<~z@:E_Wy\nz~>", + foldspaces=True, adobe=True, wrapcol=9, pad=True) + + def test_ascii85_ignorechars(self): + # Test Ascii85 with ignored characters + def assertIgnore(data, expected, ignorechars=b"", **kwargs): + data = self.type2test(data) + ignore = self.type2test(ignorechars) + with self.assertRaisesRegex(binascii.Error, r"(?i)Non-Ascii85 digit"): + binascii.a2b_ascii85(data, **kwargs) + res = binascii.a2b_ascii85(data, ignorechars=ignorechars, **kwargs) + self.assertEqual(res, expected) + + assertIgnore(b"\n", b"", ignorechars=b"\n") + assertIgnore(b"<~ ~>", b"", ignorechars=b" ", adobe=True) + assertIgnore(b"z|z", b"\0" * 8, ignorechars=b"|||") # repeats don't matter + assertIgnore(b"zz!!|", b"\0" * 9, ignorechars=b"|!z") # ignore only if invalid + assertIgnore(b"<~B P~@~>", b"hi", ignorechars=b" <~>", adobe=True) + assertIgnore(b"zy}", b"\0\0\0\0", ignorechars=b"zy}") + assertIgnore(b"zy}", b"\0\0\0\0 ", ignorechars=b"zy}", foldspaces=True) + + def test_base85_valid(self): + # Test base85 with valid data + lines, i = [], 0 + for k in range(1, len(self.rawdata) + 1): + b = self.type2test(self.rawdata[i:i + k]) + a = binascii.b2a_base85(b) + lines.append(a) + i += k + if i >= len(self.rawdata): + break + res = bytes() + for line in lines: + a = self.type2test(line) + b = binascii.a2b_base85(a) + res += b + self.assertEqual(res, self.rawdata) + + # Test decoding inputs with different length + self.assertEqual(binascii.a2b_base85(self.type2test(b'a')), b'') + self.assertEqual(binascii.a2b_base85(self.type2test(b'a')), b'') + self.assertEqual(binascii.a2b_base85(self.type2test(b'ab')), b'q') + self.assertEqual(binascii.a2b_base85(self.type2test(b'abc')), b'qa') + self.assertEqual(binascii.a2b_base85(self.type2test(b'abcd')), + b'qa\x9e') + self.assertEqual(binascii.a2b_base85(self.type2test(b'abcde')), + b'qa\x9e\xb6') + self.assertEqual(binascii.a2b_base85(self.type2test(b'abcdef')), + b'qa\x9e\xb6') + self.assertEqual(binascii.a2b_base85(self.type2test(b'abcdefg')), + b'qa\x9e\xb6\x81') + + def test_base85_errors(self): + def _assertRegexTemplate(assert_regex, data, **kwargs): + with self.assertRaisesRegex(binascii.Error, assert_regex): + binascii.a2b_base85(self.type2test(data), **kwargs) + + def assertNonBase85Data(data): + _assertRegexTemplate(r"(?i)bad base85 character", data) + + def assertOverflow(data): + _assertRegexTemplate(r"(?i)base85 overflow", data) + + assertNonBase85Data(b"\xda") + assertNonBase85Data(b"00\0\0") + assertNonBase85Data(b"Z )*") + assertNonBase85Data(b"bY*jNb0Hyq\n") + + # Test base85 with out-of-range encoded value + assertOverflow(b"}") + assertOverflow(b"|O") + assertOverflow(b"|Nt") + assertOverflow(b"|NsD") + assertOverflow(b"|NsC1") + assertOverflow(b"|NsC0~") + assertOverflow(b"|NsC0|NsC0|NsD0") + + def test_base85_pad(self): + # Test base85 with encode padding + rawdata = b"n1n3Tee\n ch@rAc\te\r$" + for i in range(1, len(rawdata) + 1): + padding = -i % 4 + b = rawdata[:i] + a_pad = binascii.b2a_base85(self.type2test(b), pad=True) + b_pad = binascii.a2b_base85(self.type2test(a_pad)) + b_pad_expected = b + b"\0" * padding + self.assertEqual(b_pad, b_pad_expected) + + def test_z85_valid(self): + # Test Z85 with valid data + lines, i = [], 0 + for k in range(1, len(self.rawdata) + 1): + b = self.type2test(self.rawdata[i:i + k]) + a = binascii.b2a_z85(b) + lines.append(a) + i += k + if i >= len(self.rawdata): + break + res = bytes() + for line in lines: + a = self.type2test(line) + b = binascii.a2b_z85(a) + res += b + self.assertEqual(res, self.rawdata) + + # Test decoding inputs with different length + self.assertEqual(binascii.a2b_z85(self.type2test(b'')), b'') + self.assertEqual(binascii.a2b_z85(self.type2test(b'a')), b'') + self.assertEqual(binascii.a2b_z85(self.type2test(b'ab')), b'\x1f') + self.assertEqual(binascii.a2b_z85(self.type2test(b'abc')), + b'\x1f\x85') + self.assertEqual(binascii.a2b_z85(self.type2test(b'abcd')), + b'\x1f\x85\x9a') + self.assertEqual(binascii.a2b_z85(self.type2test(b'abcde')), + b'\x1f\x85\x9a$') + self.assertEqual(binascii.a2b_z85(self.type2test(b'abcdef')), + b'\x1f\x85\x9a$') + self.assertEqual(binascii.a2b_z85(self.type2test(b'abcdefg')), + b'\x1f\x85\x9a$/') + + def test_z85_errors(self): + def _assertRegexTemplate(assert_regex, data, **kwargs): + with self.assertRaisesRegex(binascii.Error, assert_regex): + binascii.a2b_z85(self.type2test(data), **kwargs) + + def assertNonZ85Data(data): + _assertRegexTemplate(r"(?i)bad z85 character", data) + + def assertOverflow(data): + _assertRegexTemplate(r"(?i)z85 overflow", data) + + assertNonZ85Data(b"\xda") + assertNonZ85Data(b"00\0\0") + assertNonZ85Data(b"z !/") + assertNonZ85Data(b"By/JnB0hYQ\n") + + # Test Z85 with out-of-range encoded value + assertOverflow(b"%") + assertOverflow(b"%n") + assertOverflow(b"%nS") + assertOverflow(b"%nSc") + assertOverflow(b"%nSc1") + assertOverflow(b"%nSc0$") + assertOverflow(b"%nSc0%nSc0%nSD0") + + def test_z85_pad(self): + # Test Z85 with encode padding + rawdata = b"n1n3Tee\n ch@rAc\te\r$" + for i in range(1, len(rawdata) + 1): + padding = -i % 4 + b = rawdata[:i] + a_pad = binascii.b2a_z85(self.type2test(b), pad=True) + b_pad = binascii.a2b_z85(self.type2test(a_pad)) + b_pad_expected = b + b"\0" * padding + self.assertEqual(b_pad, b_pad_expected) + def test_uu(self): MAX_UU = 45 for backtick in (True, False): diff --git a/Misc/ACKS b/Misc/ACKS index 3fe9dcfcc9e7d0..4295eff8c1e225 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1718,6 +1718,7 @@ Jendrik Seipp Michael Selik Yury Selivanov Fred Sells +James Seo Jiwon Seo Iñigo Serna Joakim Sernbrant diff --git a/Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst b/Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst new file mode 100644 index 00000000000000..1859538896932d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst @@ -0,0 +1,2 @@ +Add Ascii85, Base85, and Z85 support to :mod:`binascii` and improve the +performance of the base-85 converters in :mod:`base64`. diff --git a/Modules/binascii.c b/Modules/binascii.c index 6d3d4e1a6d6daa..3abb90ab38bb7f 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -188,6 +188,84 @@ base64_decode_fast(const unsigned char *in, Py_ssize_t in_len, } +static const unsigned char table_a2b_base85[] Py_ALIGNED(64) = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,62,-1,63, 64,65,66,-1, 67,68,69,70, -1,71,-1,-1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,72, 73,74,75,76, + 77,10,11,12, 13,14,15,16, 17,18,19,20, 21,22,23,24, + 25,26,27,28, 29,30,31,32, 33,34,35,-1, -1,-1,78,79, + 80,36,37,38, 39,40,41,42, 43,44,45,46, 47,48,49,50, + 51,52,53,54, 55,56,57,58, 59,60,61,81, 82,83,84,-1, + + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, +}; + +static const unsigned char table_a2b_base85_a85[] Py_ALIGNED(64) = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,26, 27,28,29,30, + 31,32,33,34, 35,36,37,38, 39,40,41,42, 43,44,45,46, + 47,48,49,50, 51,52,53,54, 55,56,57,58, 59,60,61,62, + 63,64,65,66, 67,68,69,70, 71,72,73,74, 75,76,77,78, + 79,80,81,82, 83,84,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, +}; + +static const unsigned char table_a2b_base85_z85[] Py_ALIGNED(64) = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,68,-1,84, 83,82,72,-1, 75,76,70,65, -1,63,62,69, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,64,-1, 73,66,74,71, + 81,36,37,38, 39,40,41,42, 43,44,45,46, 47,48,49,50, + 51,52,53,54, 55,56,57,58, 59,60,61,77, -1,78,67,-1, + -1,10,11,12, 13,14,15,16, 17,18,19,20, 21,22,23,24, + 25,26,27,28, 29,30,31,32, 33,34,35,79, -1,80,-1,-1, + + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, +}; + +static const unsigned char table_b2a_base85[] Py_ALIGNED(64) = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"; + +static const unsigned char table_b2a_base85_a85[] Py_ALIGNED(64) = + "!\"#$%&\'()*+,-./0123456789:;<=>?@" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu"; + +static const unsigned char table_b2a_base85_z85[] Py_ALIGNED(64) = + "0123456789abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/\x2a?&<>()[]{}@%$#"; /* clinic doesn't like '/' followed by '*' */ + +#define BASE85_A85_PREFIX '<' +#define BASE85_A85_AFFIX '~' +#define BASE85_A85_SUFFIX '>' +#define BASE85_A85_Z 0x00000000 +#define BASE85_A85_Y 0x20202020 + static const unsigned short crctab_hqx[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, @@ -773,6 +851,508 @@ toolong:; return NULL; } +/*[clinic input] +binascii.a2b_ascii85 + + data: ascii_buffer + / + * + foldspaces: bool = False + Allow 'y' as a short form encoding four spaces. + adobe: bool = False + Expect data to be wrapped in '<~' and '~>' as in Adobe Ascii85. + ignorechars: Py_buffer(c_default="NULL", py_default="b''") = None + A byte string containing characters to ignore from the input. + +Decode Ascii85 data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, + int adobe, Py_buffer *ignorechars) +/*[clinic end generated code: output=599aa3e41095a651 input=20796c9b23cec213]*/ +{ + const unsigned char *ascii_data = data->buf; + Py_ssize_t ascii_len = data->len; + binascii_state *state = NULL; + + assert(ascii_len >= 0); + + /* Consume Ascii85 prefix and suffix if present. */ + if (adobe) { + if (ascii_len < 2 + || ascii_data[ascii_len - 2] != BASE85_A85_AFFIX + || ascii_data[ascii_len - 1] != BASE85_A85_SUFFIX) + { + state = get_binascii_state(module); + if (state != NULL) { + PyErr_SetString(state->Error, + "Ascii85 encoded byte sequences must end with b'~>'"); + } + return NULL; + } + ascii_len -= 2; + if (ascii_len >= 2 + && ascii_data[0] == BASE85_A85_PREFIX + && ascii_data[1] == BASE85_A85_AFFIX) + { + ascii_data += 2; + ascii_len -= 2; + } + } + + ignorecache_t ignorecache; + if (ignorechars != NULL) { + memset(ignorecache, 0, sizeof(ignorecache)); + } + + /* Allocate output buffer. */ + size_t bin_len = ascii_len; + unsigned char this_ch = 0; + size_t count_yz = 0; + for (Py_ssize_t i = 0; i < ascii_len; i++) { + this_ch = ascii_data[i]; + if (this_ch == 'y' || this_ch == 'z') { + count_yz++; + } + } + bin_len = (bin_len - count_yz + 4) / 5 * 4; + if (count_yz > (PY_SSIZE_T_MAX - bin_len) / 4) { + binascii_state *state = get_binascii_state(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Too much Ascii85 data"); + return NULL; + } + bin_len += count_yz * 4; + + PyBytesWriter *writer = PyBytesWriter_Create(bin_len); + if (writer == NULL) { + return NULL; + } + unsigned char *bin_data = PyBytesWriter_GetData(writer); + if (bin_data == NULL) { + return NULL; + } + + uint32_t leftchar = 0; + int group_pos = 0; + for (; ascii_len > 0 || group_pos != 0; ascii_len--, ascii_data++) { + /* Shift (in radix-85) data or padding into our buffer. */ + unsigned char this_digit; + if (ascii_len > 0) { + this_ch = *ascii_data; + this_digit = table_a2b_base85_a85[this_ch]; + } + else { + /* Pad with largest radix-85 digit when decoding. */ + this_digit = 84; + } + if (this_digit < 85) { + if (group_pos == 4 + && (leftchar > UINT32_MAX / 85 + || leftchar * 85 > UINT32_MAX - this_digit)) + { + state = get_binascii_state(module); + if (state != NULL) { + PyErr_SetString(state->Error, "Ascii85 overflow"); + } + goto error; + } + leftchar = leftchar * 85 + this_digit; + group_pos++; + } + else if ((this_ch == 'y' && foldspaces) || this_ch == 'z') { + if (group_pos != 0) { + state = get_binascii_state(module); + if (state != NULL) { + PyErr_Format(state->Error, + "'%c' inside Ascii85 5-tuple", this_ch); + } + goto error; + } + leftchar = this_ch == 'y' ? BASE85_A85_Y : BASE85_A85_Z; + group_pos = 5; + } + else if (!ignorechar(this_ch, ignorechars, ignorecache)) { + state = get_binascii_state(module); + if (state != NULL) { + PyErr_Format(state->Error, + "Non-Ascii85 digit found: %c", this_ch); + } + goto error; + } + + /* Wait until buffer is full. */ + if (group_pos != 5) { + continue; + } + + /* Write current chunk. */ + Py_ssize_t chunk_len = ascii_len < 1 ? 3 + ascii_len : 4; + for (Py_ssize_t i = 0; i < chunk_len; i++) { + *bin_data++ = (leftchar >> (24 - 8 * i)) & 0xff; + } + + group_pos = 0; + leftchar = 0; + } + + return PyBytesWriter_FinishWithPointer(writer, bin_data); + +error: + PyBytesWriter_Discard(writer); + return NULL; +} + +/*[clinic input] +binascii.b2a_ascii85 + + data: Py_buffer + / + * + foldspaces: bool = False + Emit 'y' as a short form encoding four spaces. + wrapcol: size_t = 0 + Split result into lines of provided width. + pad: bool = False + Pad input to a multiple of 4 before encoding. + adobe: bool = False + Wrap result in '<~' and '~>' as in Adobe Ascii85. + +Ascii85-encode data. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, + size_t wrapcol, int pad, int adobe) +/*[clinic end generated code: output=5ce8fdee843073f4 input=791da754508c7d17]*/ +{ + const unsigned char *bin_data = data->buf; + Py_ssize_t bin_len = data->len; + + assert(bin_len >= 0); + + if (adobe && wrapcol == 1) { + wrapcol = 2; + } + + /* Allocate output buffer. */ + size_t out_len = ((size_t)bin_len + 3) / 4 * 5; + if (adobe) { + out_len += 4; + } + if (!pad && (bin_len % 4)) { + out_len -= 4 - (bin_len % 4); + } + if (wrapcol && out_len) { + out_len += (out_len - 1) / wrapcol; + } + if (out_len > PY_SSIZE_T_MAX) { + binascii_state *state = get_binascii_state(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Too much data for Ascii85"); + return NULL; + } + + PyBytesWriter *writer = PyBytesWriter_Create(out_len); + if (writer == NULL) { + return NULL; + } + unsigned char *ascii_data = PyBytesWriter_GetData(writer); + + if (adobe) { + *ascii_data++ = BASE85_A85_PREFIX; + *ascii_data++ = BASE85_A85_AFFIX; + } + + /* Encode all full-length chunks. */ + for (; bin_len >= 4; bin_len -= 4, bin_data += 4) { + uint32_t leftchar = (bin_data[0] << 24) | (bin_data[1] << 16) | + (bin_data[2] << 8) | bin_data[3]; + if (leftchar == BASE85_A85_Z) { + *ascii_data++ = 'z'; + } + else if (foldspaces && leftchar == BASE85_A85_Y) { + *ascii_data++ = 'y'; + } + else { + ascii_data[4] = table_b2a_base85_a85[leftchar % 85]; + leftchar /= 85; + ascii_data[3] = table_b2a_base85_a85[leftchar % 85]; + leftchar /= 85; + ascii_data[2] = table_b2a_base85_a85[leftchar % 85]; + leftchar /= 85; + ascii_data[1] = table_b2a_base85_a85[leftchar % 85]; + leftchar /= 85; + ascii_data[0] = table_b2a_base85_a85[leftchar]; + + ascii_data += 5; + } + } + + /* Encode partial-length final chunk. */ + if (bin_len > 0) { + uint32_t leftchar = 0; + for (Py_ssize_t i = 0; i < 4; i++) { + leftchar <<= 8; /* Pad with zero when encoding. */ + if (i < bin_len) { + leftchar |= *bin_data++; + } + } + if (pad && leftchar == BASE85_A85_Z) { + *ascii_data++ = 'z'; + } + else { + Py_ssize_t group_len = pad ? 5 : bin_len + 1; + for (Py_ssize_t i = 4; i >= 0; i--) { + if (i < group_len) { + ascii_data[i] = table_b2a_base85_a85[leftchar % 85]; + } + leftchar /= 85; + } + ascii_data += group_len; + } + } + + if (adobe) { + *ascii_data++ = BASE85_A85_AFFIX; + *ascii_data++ = BASE85_A85_SUFFIX; + } + + if (wrapcol && out_len) { + unsigned char *start = PyBytesWriter_GetData(writer); + ascii_data = start + wraplines(start, ascii_data - start, wrapcol); + if (adobe && ascii_data[-2] == '\n') { + assert(ascii_data[-1] == BASE85_A85_SUFFIX); + assert(ascii_data[-3] == BASE85_A85_AFFIX); + ascii_data[-3] = '\n'; + ascii_data[-2] = BASE85_A85_AFFIX; + } + } + + return PyBytesWriter_FinishWithPointer(writer, ascii_data); +} + +static PyObject * +base85_decode_impl(PyObject *module, Py_buffer *data, + const unsigned char table_a2b[], const char *name) +{ + const unsigned char *ascii_data = data->buf; + Py_ssize_t ascii_len = data->len; + binascii_state *state = NULL; + + assert(ascii_len >= 0); + + /* Allocate output buffer. */ + size_t bin_len = ((size_t)ascii_len + 4) / 5 * 4; + PyBytesWriter *writer = PyBytesWriter_Create(bin_len); + if (writer == NULL) { + return NULL; + } + unsigned char *bin_data = PyBytesWriter_GetData(writer); + + uint32_t leftchar = 0; + int group_pos = 0; + for (; ascii_len > 0 || group_pos != 0; ascii_len--, ascii_data++) { + /* Shift (in radix-85) data or padding into our buffer. */ + unsigned char this_digit; + if (ascii_len > 0) { + unsigned char this_ch = *ascii_data; + this_digit = table_a2b[this_ch]; + } + else { + /* Pad with largest radix-85 digit when decoding. */ + this_digit = 84; + } + if (this_digit < 85) { + if (group_pos == 4 + && (leftchar > UINT32_MAX / 85 + || leftchar * 85 > UINT32_MAX - this_digit)) + { + state = get_binascii_state(module); + if (state != NULL) { + PyErr_Format(state->Error, + "%s overflow in hunk starting at byte %d", + name, (data->len - ascii_len) / 5 * 5); + } + goto error; + } + leftchar = leftchar * 85 + this_digit; + group_pos++; + } + else { + state = get_binascii_state(module); + if (state != NULL) { + PyErr_Format(state->Error, "bad %s character at position %d", + name, data->len - ascii_len); + } + goto error; + } + + /* Wait until buffer is full. */ + if (group_pos != 5) { + continue; + } + + /* Write current chunk. */ + Py_ssize_t chunk_len = ascii_len < 1 ? 3 + ascii_len : 4; + for (Py_ssize_t i = 0; i < chunk_len; i++) { + *bin_data++ = (leftchar >> (24 - 8 * i)) & 0xff; + } + + group_pos = 0; + leftchar = 0; + } + + return PyBytesWriter_FinishWithPointer(writer, bin_data); + +error: + PyBytesWriter_Discard(writer); + return NULL; +} + +static PyObject * +base85_encode_impl(PyObject *module, Py_buffer *data, int pad, + const unsigned char table_b2a[], const char *name) +{ + const unsigned char *bin_data = data->buf; + Py_ssize_t bin_len = data->len; + + assert(bin_len >= 0); + + /* Allocate output buffer. */ + size_t out_len = ((size_t)bin_len + 3) / 4 * 5; + if (!pad && (bin_len % 4)) { + out_len -= 4 - (bin_len % 4); + } + if (out_len > PY_SSIZE_T_MAX) { + binascii_state *state = get_binascii_state(module); + if (state == NULL) { + return NULL; + } + PyErr_Format(state->Error, "Too much data for %s", name); + return NULL; + } + + PyBytesWriter *writer = PyBytesWriter_Create(out_len); + if (writer == NULL) { + return NULL; + } + unsigned char *ascii_data = PyBytesWriter_GetData(writer); + + /* Encode all full-length chunks. */ + for (; bin_len >= 4; bin_len -= 4, bin_data += 4) { + uint32_t leftchar = (bin_data[0] << 24) | (bin_data[1] << 16) | + (bin_data[2] << 8) | bin_data[3]; + + ascii_data[4] = table_b2a[leftchar % 85]; + leftchar /= 85; + ascii_data[3] = table_b2a[leftchar % 85]; + leftchar /= 85; + ascii_data[2] = table_b2a[leftchar % 85]; + leftchar /= 85; + ascii_data[1] = table_b2a[leftchar % 85]; + leftchar /= 85; + ascii_data[0] = table_b2a[leftchar]; + + ascii_data += 5; + } + + /* Encode partial-length final chunk. */ + if (bin_len > 0) { + uint32_t leftchar = 0; + for (Py_ssize_t i = 0; i < 4; i++) { + leftchar <<= 8; /* Pad with zero when encoding. */ + if (i < bin_len) { + leftchar |= *bin_data++; + } + } + Py_ssize_t group_len = pad ? 5 : bin_len + 1; + for (Py_ssize_t i = 4; i >= 0; i--) { + if (i < group_len) { + ascii_data[i] = table_b2a[leftchar % 85]; + } + leftchar /= 85; + } + ascii_data += group_len; + } + + return PyBytesWriter_FinishWithPointer(writer, ascii_data); +} + +/*[clinic input] +binascii.a2b_base85 + + data: ascii_buffer + / + +Decode a line of Base85 data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_base85_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=c2db6ab9181b0089 input=06c9d595352b5a2b]*/ +{ + return base85_decode_impl(module, data, table_a2b_base85, "Base85"); +} + +/*[clinic input] +binascii.b2a_base85 + + data: Py_buffer + / + * + pad: bool = False + Pad input to a multiple of 4 before encoding. + +Base85-code line of data. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_base85_impl(PyObject *module, Py_buffer *data, int pad) +/*[clinic end generated code: output=b317adb36a57740d input=89fde81b96dcec06]*/ +{ + return base85_encode_impl(module, data, pad, table_b2a_base85, "Base85"); +} + +/*[clinic input] +binascii.a2b_z85 + + data: ascii_buffer + / + +Decode a line of Z85 data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_z85_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=57d8260bb5267a98 input=c54baff4d81510a4]*/ +{ + return base85_decode_impl(module, data, table_a2b_base85_z85, "Z85"); +} + +/*[clinic input] +binascii.b2a_z85 + + data: Py_buffer + / + * + pad: bool = False + Pad input to a multiple of 4 before encoding. + +Z85-code line of data. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_z85_impl(PyObject *module, Py_buffer *data, int pad) +/*[clinic end generated code: output=88284835e332c9cf input=51d070a5a6cf82d8]*/ +{ + return base85_encode_impl(module, data, pad, table_b2a_base85_z85, "Z85"); +} /*[clinic input] binascii.crc_hqx @@ -1431,6 +2011,12 @@ static struct PyMethodDef binascii_module_methods[] = { BINASCII_B2A_UU_METHODDEF BINASCII_A2B_BASE64_METHODDEF BINASCII_B2A_BASE64_METHODDEF + BINASCII_B2A_ASCII85_METHODDEF + BINASCII_A2B_ASCII85_METHODDEF + BINASCII_A2B_BASE85_METHODDEF + BINASCII_B2A_BASE85_METHODDEF + BINASCII_A2B_Z85_METHODDEF + BINASCII_B2A_Z85_METHODDEF BINASCII_A2B_HEX_METHODDEF BINASCII_B2A_HEX_METHODDEF BINASCII_HEXLIFY_METHODDEF diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index 91325b1bdddf89..68ab9c999b2894 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -297,6 +297,445 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P return return_value; } +PyDoc_STRVAR(binascii_a2b_ascii85__doc__, +"a2b_ascii85($module, data, /, *, foldspaces=False, adobe=False,\n" +" ignorechars=b\'\')\n" +"--\n" +"\n" +"Decode Ascii85 data.\n" +"\n" +" foldspaces\n" +" Allow \'y\' as a short form encoding four spaces.\n" +" adobe\n" +" Expect data to be wrapped in \'<~\' and \'~>\' as in Adobe Ascii85.\n" +" ignorechars\n" +" A byte string containing characters to ignore from the input."); + +#define BINASCII_A2B_ASCII85_METHODDEF \ + {"a2b_ascii85", _PyCFunction_CAST(binascii_a2b_ascii85), METH_FASTCALL|METH_KEYWORDS, binascii_a2b_ascii85__doc__}, + +static PyObject * +binascii_a2b_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, + int adobe, Py_buffer *ignorechars); + +static PyObject * +binascii_a2b_ascii85(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(foldspaces), &_Py_ID(adobe), &_Py_ID(ignorechars), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "foldspaces", "adobe", "ignorechars", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_ascii85", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + int foldspaces = 0; + int adobe = 0; + Py_buffer ignorechars = {NULL, NULL}; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!ascii_buffer_converter(args[0], &data)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + foldspaces = PyObject_IsTrue(args[1]); + if (foldspaces < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + adobe = PyObject_IsTrue(args[2]); + if (adobe < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyObject_GetBuffer(args[3], &ignorechars, PyBUF_SIMPLE) != 0) { + goto exit; + } +skip_optional_kwonly: + return_value = binascii_a2b_ascii85_impl(module, &data, foldspaces, adobe, &ignorechars); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + /* Cleanup for ignorechars */ + if (ignorechars.obj) { + PyBuffer_Release(&ignorechars); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_ascii85__doc__, +"b2a_ascii85($module, data, /, *, foldspaces=False, wrapcol=0,\n" +" pad=False, adobe=False)\n" +"--\n" +"\n" +"Ascii85-encode data.\n" +"\n" +" foldspaces\n" +" Emit \'y\' as a short form encoding four spaces.\n" +" wrapcol\n" +" Split result into lines of provided width.\n" +" pad\n" +" Pad input to a multiple of 4 before encoding.\n" +" adobe\n" +" Wrap result in \'<~\' and \'~>\' as in Adobe Ascii85."); + +#define BINASCII_B2A_ASCII85_METHODDEF \ + {"b2a_ascii85", _PyCFunction_CAST(binascii_b2a_ascii85), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_ascii85__doc__}, + +static PyObject * +binascii_b2a_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, + size_t wrapcol, int pad, int adobe); + +static PyObject * +binascii_b2a_ascii85(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(foldspaces), &_Py_ID(wrapcol), &_Py_ID(pad), &_Py_ID(adobe), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "foldspaces", "wrapcol", "pad", "adobe", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_ascii85", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + int foldspaces = 0; + size_t wrapcol = 0; + int pad = 0; + int adobe = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + foldspaces = PyObject_IsTrue(args[1]); + if (foldspaces < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (!_PyLong_Size_t_Converter(args[2], &wrapcol)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + pad = PyObject_IsTrue(args[3]); + if (pad < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + adobe = PyObject_IsTrue(args[4]); + if (adobe < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = binascii_b2a_ascii85_impl(module, &data, foldspaces, wrapcol, pad, adobe); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_base85__doc__, +"a2b_base85($module, data, /)\n" +"--\n" +"\n" +"Decode a line of Base85 data."); + +#define BINASCII_A2B_BASE85_METHODDEF \ + {"a2b_base85", (PyCFunction)binascii_a2b_base85, METH_O, binascii_a2b_base85__doc__}, + +static PyObject * +binascii_a2b_base85_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_a2b_base85(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!ascii_buffer_converter(arg, &data)) { + goto exit; + } + return_value = binascii_a2b_base85_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_base85__doc__, +"b2a_base85($module, data, /, *, pad=False)\n" +"--\n" +"\n" +"Base85-code line of data.\n" +"\n" +" pad\n" +" Pad input to a multiple of 4 before encoding."); + +#define BINASCII_B2A_BASE85_METHODDEF \ + {"b2a_base85", _PyCFunction_CAST(binascii_b2a_base85), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_base85__doc__}, + +static PyObject * +binascii_b2a_base85_impl(PyObject *module, Py_buffer *data, int pad); + +static PyObject * +binascii_b2a_base85(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(pad), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "pad", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_base85", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + int pad = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + pad = PyObject_IsTrue(args[1]); + if (pad < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = binascii_b2a_base85_impl(module, &data, pad); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_z85__doc__, +"a2b_z85($module, data, /)\n" +"--\n" +"\n" +"Decode a line of Z85 data."); + +#define BINASCII_A2B_Z85_METHODDEF \ + {"a2b_z85", (PyCFunction)binascii_a2b_z85, METH_O, binascii_a2b_z85__doc__}, + +static PyObject * +binascii_a2b_z85_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_a2b_z85(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!ascii_buffer_converter(arg, &data)) { + goto exit; + } + return_value = binascii_a2b_z85_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_z85__doc__, +"b2a_z85($module, data, /, *, pad=False)\n" +"--\n" +"\n" +"Z85-code line of data.\n" +"\n" +" pad\n" +" Pad input to a multiple of 4 before encoding."); + +#define BINASCII_B2A_Z85_METHODDEF \ + {"b2a_z85", _PyCFunction_CAST(binascii_b2a_z85), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_z85__doc__}, + +static PyObject * +binascii_b2a_z85_impl(PyObject *module, Py_buffer *data, int pad); + +static PyObject * +binascii_b2a_z85(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(pad), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "pad", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_z85", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + int pad = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + pad = PyObject_IsTrue(args[1]); + if (pad < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = binascii_b2a_z85_impl(module, &data, pad); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + PyDoc_STRVAR(binascii_crc_hqx__doc__, "crc_hqx($module, data, crc, /)\n" "--\n" @@ -842,4 +1281,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=13f0a4b0f5d3fcb4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=28de2d0774a0a4d7 input=a9049054013a1b77]*/ From 5bb3bbb9c6a7c9043a04d0cc2e82c83747040788 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 6 Feb 2026 09:43:36 -0500 Subject: [PATCH 018/498] gh-144446: Fix some frame object thread-safety issues (gh-144479) Fix thread-safety issues when accessing frame attributes while another thread is executing the frame: - Add critical section to frame_repr() to prevent races when accessing the frame's code object and line number - Add _Py_NO_SANITIZE_THREAD to PyUnstable_InterpreterFrame_GetLasti() to allow intentional racy reads of instr_ptr. - Fix take_ownership() to not write to the original frame's f_executable --- Lib/test/test_free_threading/test_frame.py | 151 ++++++++++++++++++ ...-02-03-17-08-13.gh-issue-144446.db5619.rst | 2 + Objects/frameobject.c | 10 +- Python/frame.c | 8 +- 4 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 Lib/test/test_free_threading/test_frame.py create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst diff --git a/Lib/test/test_free_threading/test_frame.py b/Lib/test/test_free_threading/test_frame.py new file mode 100644 index 00000000000000..bea49df557aa2c --- /dev/null +++ b/Lib/test/test_free_threading/test_frame.py @@ -0,0 +1,151 @@ +import functools +import sys +import threading +import unittest + +from test.support import threading_helper + +threading_helper.requires_working_threading(module=True) + + +def run_with_frame(funcs, runner=None, iters=10): + """Run funcs with a frame from another thread that is currently executing. + + Args: + funcs: A function or list of functions that take a frame argument + runner: Optional function to run in the executor thread. If provided, + it will be called and should return eventually. The frame + passed to funcs will be the runner's frame. + iters: Number of iterations each func should run + """ + if not isinstance(funcs, list): + funcs = [funcs] + + frame_var = None + e = threading.Event() + b = threading.Barrier(len(funcs) + 1) + + if runner is None: + def runner(): + j = 0 + for i in range(100): + j += i + + def executor(): + nonlocal frame_var + frame_var = sys._getframe() + e.set() + b.wait() + runner() + + def func_wrapper(func): + e.wait() + frame = frame_var + b.wait() + for _ in range(iters): + func(frame) + + test_funcs = [functools.partial(func_wrapper, f) for f in funcs] + threading_helper.run_concurrently([executor] + test_funcs) + + +class TestFrameRaces(unittest.TestCase): + def test_concurrent_f_lasti(self): + run_with_frame(lambda frame: frame.f_lasti) + + def test_concurrent_f_lineno(self): + run_with_frame(lambda frame: frame.f_lineno) + + def test_concurrent_f_code(self): + run_with_frame(lambda frame: frame.f_code) + + def test_concurrent_f_back(self): + run_with_frame(lambda frame: frame.f_back) + + def test_concurrent_f_globals(self): + run_with_frame(lambda frame: frame.f_globals) + + def test_concurrent_f_builtins(self): + run_with_frame(lambda frame: frame.f_builtins) + + def test_concurrent_f_locals(self): + run_with_frame(lambda frame: frame.f_locals) + + def test_concurrent_f_trace_read(self): + run_with_frame(lambda frame: frame.f_trace) + + def test_concurrent_f_trace_opcodes_read(self): + run_with_frame(lambda frame: frame.f_trace_opcodes) + + def test_concurrent_repr(self): + run_with_frame(lambda frame: repr(frame)) + + def test_concurrent_f_trace_write(self): + def trace_func(frame, event, arg): + return trace_func + + def writer(frame): + frame.f_trace = trace_func + frame.f_trace = None + + run_with_frame(writer) + + def test_concurrent_f_trace_read_write(self): + # Test concurrent reads and writes of f_trace on a live frame. + def trace_func(frame, event, arg): + return trace_func + + def reader(frame): + _ = frame.f_trace + + def writer(frame): + frame.f_trace = trace_func + frame.f_trace = None + + run_with_frame([reader, writer, reader, writer]) + + def test_concurrent_f_trace_opcodes_write(self): + def writer(frame): + frame.f_trace_opcodes = True + frame.f_trace_opcodes = False + + run_with_frame(writer) + + def test_concurrent_f_trace_opcodes_read_write(self): + # Test concurrent reads and writes of f_trace_opcodes on a live frame. + def reader(frame): + _ = frame.f_trace_opcodes + + def writer(frame): + frame.f_trace_opcodes = True + frame.f_trace_opcodes = False + + run_with_frame([reader, writer, reader, writer]) + + def test_concurrent_frame_clear(self): + # Test race between frame.clear() and attribute reads. + def create_frame(): + x = 1 + y = 2 + return sys._getframe() + + frame = create_frame() + + def reader(): + for _ in range(10): + try: + _ = frame.f_locals + _ = frame.f_code + _ = frame.f_lineno + except ValueError: + # Frame may be cleared + pass + + def clearer(): + frame.clear() + + threading_helper.run_concurrently([reader, reader, clearer]) + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst new file mode 100644 index 00000000000000..71cf49366287ae --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst @@ -0,0 +1,2 @@ +Fix data races in the free-threaded build when reading frame object attributes +while another thread is executing the frame. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 1d4c0f6785c4b8..9d774a71edb797 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1049,11 +1049,11 @@ static PyObject * frame_lasti_get_impl(PyFrameObject *self) /*[clinic end generated code: output=03275b4f0327d1a2 input=0225ed49cb1fbeeb]*/ { - int lasti = _PyInterpreterFrame_LASTI(self->f_frame); + int lasti = PyUnstable_InterpreterFrame_GetLasti(self->f_frame); if (lasti < 0) { return PyLong_FromLong(-1); } - return PyLong_FromLong(lasti * sizeof(_Py_CODEUNIT)); + return PyLong_FromLong(lasti); } /*[clinic input] @@ -2053,11 +2053,15 @@ static PyObject * frame_repr(PyObject *op) { PyFrameObject *f = PyFrameObject_CAST(op); + PyObject *result; + Py_BEGIN_CRITICAL_SECTION(f); int lineno = PyFrame_GetLineNumber(f); PyCodeObject *code = _PyFrame_GetCode(f->f_frame); - return PyUnicode_FromFormat( + result = PyUnicode_FromFormat( "", f, code->co_filename, lineno, code->co_name); + Py_END_CRITICAL_SECTION(); + return result; } static PyMethodDef frame_methods[] = { diff --git a/Python/frame.c b/Python/frame.c index da8f9037e8287a..ff81eb0b3020c7 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -54,7 +54,7 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) _PyFrame_Copy(frame, new_frame); // _PyFrame_Copy takes the reference to the executable, // so we need to restore it. - frame->f_executable = PyStackRef_DUP(new_frame->f_executable); + new_frame->f_executable = PyStackRef_DUP(new_frame->f_executable); f->f_frame = new_frame; new_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; if (_PyFrame_IsIncomplete(new_frame)) { @@ -135,14 +135,14 @@ PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame) return PyStackRef_AsPyObjectNew(frame->f_executable); } -int +// NOTE: We allow racy accesses to the instruction pointer from other threads +// for sys._current_frames() and similar APIs. +int _Py_NO_SANITIZE_THREAD PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame) { return _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); } -// NOTE: We allow racy accesses to the instruction pointer from other threads -// for sys._current_frames() and similar APIs. int _Py_NO_SANITIZE_THREAD PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame) { From 0fdf6a9a71f9b3c9adc0406542902e028431e7ca Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 6 Feb 2026 10:14:08 -0500 Subject: [PATCH 019/498] gh-144513: Skip critical section locking during stop-the-world (gh-144524) When the interpreter is in a stop-the-world pause, critical sections don't need to acquire locks since no other threads can be running. This avoids a potential deadlock where lock fairness hands off ownership to a thread that has already suspended for stop-the-world. --- ...-02-05-13-30-00.gh-issue-144513.IjSTd7.rst | 2 + .../test_critical_sections.c | 84 +++++++++++++++++++ Python/critical_section.c | 18 +++- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst new file mode 100644 index 00000000000000..f97160172735e1 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst @@ -0,0 +1,2 @@ +Fix potential deadlock when using critical sections during stop-the-world +pauses in the free-threaded build. diff --git a/Modules/_testinternalcapi/test_critical_sections.c b/Modules/_testinternalcapi/test_critical_sections.c index e3b2fe716d48d3..72a1fa2cdc7224 100644 --- a/Modules/_testinternalcapi/test_critical_sections.c +++ b/Modules/_testinternalcapi/test_critical_sections.c @@ -4,6 +4,8 @@ #include "parts.h" #include "pycore_critical_section.h" +#include "pycore_pystate.h" +#include "pycore_pythread.h" #ifdef MS_WINDOWS # include // Sleep() @@ -381,6 +383,87 @@ test_critical_section2_reacquisition(PyObject *self, PyObject *Py_UNUSED(args)) #endif // Py_GIL_DISABLED +#ifdef Py_CAN_START_THREADS + +// gh-144513: Test that critical sections don't deadlock with stop-the-world. +// This test is designed to deadlock (timeout) on builds without the fix. +struct test_data_stw { + PyObject *obj; + Py_ssize_t num_threads; + Py_ssize_t started; + PyEvent ready; +}; + +static void +thread_stw(void *arg) +{ + struct test_data_stw *test_data = arg; + PyGILState_STATE gil = PyGILState_Ensure(); + + if (_Py_atomic_add_ssize(&test_data->started, 1) == test_data->num_threads - 1) { + _PyEvent_Notify(&test_data->ready); + } + + // All threads: acquire critical section and hold it long enough to + // trigger TIME_TO_BE_FAIR_NS (1 ms), which causes direct handoff on unlock. + Py_BEGIN_CRITICAL_SECTION(test_data->obj); + pysleep(10); // 10 ms = 10 x TIME_TO_BE_FAIR_NS + Py_END_CRITICAL_SECTION(); + + PyGILState_Release(gil); +} + +static PyObject * +test_critical_sections_stw(PyObject *self, PyObject *Py_UNUSED(args)) +{ + // gh-144513: Test that critical sections don't deadlock during STW. + // + // The deadlock occurs when lock ownership is handed off (due to fairness + // after TIME_TO_BE_FAIR_NS) to a thread that has already suspended for + // stop-the-world. The STW requester then cannot acquire the lock. + // + // With the fix, the STW requester detects world_stopped and skips locking. + + #define STW_NUM_THREADS 2 + struct test_data_stw test_data = { + .obj = PyDict_New(), + .num_threads = STW_NUM_THREADS, + }; + if (test_data.obj == NULL) { + return NULL; + } + + PyThread_handle_t handles[STW_NUM_THREADS]; + PyThread_ident_t idents[STW_NUM_THREADS]; + for (Py_ssize_t i = 0; i < STW_NUM_THREADS; i++) { + PyThread_start_joinable_thread(&thread_stw, &test_data, + &idents[i], &handles[i]); + } + + // Wait for threads to start, then let them compete for the lock + PyEvent_Wait(&test_data.ready); + pysleep(5); + + // Request stop-the-world and try to acquire the critical section. + // Without the fix, this may deadlock. + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyEval_StopTheWorld(interp); + + Py_BEGIN_CRITICAL_SECTION(test_data.obj); + Py_END_CRITICAL_SECTION(); + + _PyEval_StartTheWorld(interp); + + for (Py_ssize_t i = 0; i < STW_NUM_THREADS; i++) { + PyThread_join_thread(handles[i]); + } + #undef STW_NUM_THREADS + Py_DECREF(test_data.obj); + Py_RETURN_NONE; +} + +#endif // Py_CAN_START_THREADS + static PyMethodDef test_methods[] = { {"test_critical_sections", test_critical_sections, METH_NOARGS}, {"test_critical_sections_nest", test_critical_sections_nest, METH_NOARGS}, @@ -392,6 +475,7 @@ static PyMethodDef test_methods[] = { #ifdef Py_CAN_START_THREADS {"test_critical_sections_threads", test_critical_sections_threads, METH_NOARGS}, {"test_critical_sections_gc", test_critical_sections_gc, METH_NOARGS}, + {"test_critical_sections_stw", test_critical_sections_stw, METH_NOARGS}, #endif {NULL, NULL} /* sentinel */ }; diff --git a/Python/critical_section.c b/Python/critical_section.c index 2c2152f5de4716..98e23eda7cdd77 100644 --- a/Python/critical_section.c +++ b/Python/critical_section.c @@ -1,7 +1,8 @@ #include "Python.h" -#include "pycore_lock.h" #include "pycore_critical_section.h" +#include "pycore_interp.h" +#include "pycore_lock.h" #ifdef Py_GIL_DISABLED static_assert(_Alignof(PyCriticalSection) >= 4, @@ -42,6 +43,15 @@ _PyCriticalSection_BeginSlow(PyThreadState *tstate, PyCriticalSection *c, PyMute } } } + // If the world is stopped, we don't need to acquire the lock because + // there are no other threads that could be accessing the object. + // Without this check, acquiring a critical section while the world is + // stopped could lead to a deadlock. + if (tstate->interp->stoptheworld.world_stopped) { + c->_cs_mutex = NULL; + c->_cs_prev = 0; + return; + } c->_cs_mutex = NULL; c->_cs_prev = (uintptr_t)tstate->critical_section; tstate->critical_section = (uintptr_t)c; @@ -56,6 +66,12 @@ _PyCriticalSection2_BeginSlow(PyThreadState *tstate, PyCriticalSection2 *c, PyMu int is_m1_locked) { #ifdef Py_GIL_DISABLED + if (tstate->interp->stoptheworld.world_stopped) { + c->_cs_base._cs_mutex = NULL; + c->_cs_mutex2 = NULL; + c->_cs_base._cs_prev = 0; + return; + } c->_cs_base._cs_mutex = NULL; c->_cs_mutex2 = NULL; c->_cs_base._cs_prev = tstate->critical_section; From 172135cc424a51492175aac6c515ad4c96ba26a2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Feb 2026 16:42:42 +0100 Subject: [PATCH 020/498] gh-144490: Fix test_cppext: test the internal C API (#144536) Add missing TEST_INTERNAL_C_API env var. --- Lib/test/test_cppext/__init__.py | 35 ++++++++++++++++-------------- Lib/test/test_cppext/extension.cpp | 11 ++++++++-- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py index 2f54b3ccb35cc4..9013503995bdce 100644 --- a/Lib/test/test_cppext/__init__.py +++ b/Lib/test/test_cppext/__init__.py @@ -25,25 +25,11 @@ @support.requires_subprocess() @support.requires_resource('cpu') class BaseTests: + TEST_INTERNAL_C_API = False + def test_build(self): self.check_build('_testcppext') - def test_build_cpp03(self): - # In public docs, we say C API is compatible with C++11. However, - # in practice we do maintain C++03 compatibility in public headers. - # Please ask the C API WG before adding a new C++11-only feature. - self.check_build('_testcpp03ext', std='c++03') - - @unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c++11") - def test_build_cpp11(self): - self.check_build('_testcpp11ext', std='c++11') - - # Only test C++14 on MSVC. - # On s390x RHEL7, GCC 4.8.5 doesn't support C++14. - @unittest.skipIf(not support.MS_WINDOWS, "need Windows") - def test_build_cpp14(self): - self.check_build('_testcpp14ext', std='c++14') - def check_build(self, extension_name, std=None, limited=False): venv_dir = 'env' with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: @@ -63,6 +49,7 @@ def run_cmd(operation, cmd): if limited: env['CPYTHON_TEST_LIMITED'] = '1' env['CPYTHON_TEST_EXT_NAME'] = extension_name + env['TEST_INTERNAL_C_API'] = str(int(self.TEST_INTERNAL_C_API)) if support.verbose: print('Run:', ' '.join(map(shlex.quote, cmd))) subprocess.run(cmd, check=True, env=env) @@ -112,6 +99,22 @@ def test_build_limited_cpp03(self): def test_build_limited(self): self.check_build('_testcppext_limited', limited=True) + def test_build_cpp03(self): + # In public docs, we say C API is compatible with C++11. However, + # in practice we do maintain C++03 compatibility in public headers. + # Please ask the C API WG before adding a new C++11-only feature. + self.check_build('_testcpp03ext', std='c++03') + + @unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c++11") + def test_build_cpp11(self): + self.check_build('_testcpp11ext', std='c++11') + + # Only test C++14 on MSVC. + # On s390x RHEL7, GCC 4.8.5 doesn't support C++14. + @unittest.skipIf(not support.MS_WINDOWS, "need Windows") + def test_build_cpp14(self): + self.check_build('_testcpp14ext', std='c++14') + class TestInteralCAPI(BaseTests, unittest.TestCase): TEST_INTERNAL_C_API = True diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index f95655eccded61..038f67bbbe3f74 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -7,15 +7,22 @@ #undef NDEBUG #ifdef TEST_INTERNAL_C_API -# define Py_BUILD_CORE 1 +# define Py_BUILD_CORE_MODULE 1 #endif #include "Python.h" #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API -# include "internal/pycore_backoff.h" # include "internal/pycore_frame.h" + // mimalloc emits many compiler warnings when Python is built in debug + // mode (when MI_DEBUG is not zero) + // mimalloc emits compiler warnings when Python is built on Windows + // in free-threaded mode. +# if !defined(Py_DEBUG) && !(defined(MS_WINDOWS) && defined(Py_GIL_DISABLED)) +# include "internal/pycore_backoff.h" +# include "internal/pycore_cell.h" +# endif #endif #ifndef MODULE_NAME From fb196c6f32b3b5e1d2cf1780a7595298d0d011f1 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:08:26 +0000 Subject: [PATCH 021/498] gh-140715: Update `datetime.*.str*time` format code tables (GH-140716) --- Doc/library/datetime.rst | 171 ++++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 67 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 48e7080da6c525..3ab3450032abe4 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2495,79 +2495,105 @@ These methods accept format codes that can be used to parse and format dates:: >>> _.strftime('%a %d %b %Y, %I:%M%p') 'Mon 31 Jan 2022, 11:59PM' -The following is a list of all the format codes that the 1989 C standard -requires, and these work on all platforms with a standard C implementation. +The following is a list of all the format codes that the 2011 C standard +requires, and these work on all supported platforms. +-----------+--------------------------------+------------------------+-------+ -| Directive | Meaning | Example | Notes | +| Directive | Meaning | Example | Notes | +| | | | | +===========+================================+========================+=======+ -| ``%a`` | Weekday as locale's || Sun, Mon, ..., Sat | \(1) | +| ``%a`` | Weekday as locale's || Sun, Mon, ..., Sat | \(1) | | | abbreviated name. | (en_US); | | | | || So, Mo, ..., Sa | | | | | (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%A`` | Weekday as locale's full name. || Sunday, Monday, ..., | \(1) | +| ``%A`` | Weekday as locale's full name. || Sunday, Monday, ..., | \(1) | | | | Saturday (en_US); | | | | || Sonntag, Montag, ..., | | | | | Samstag (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%w`` | Weekday as a decimal number, | 0, 1, ..., 6 | | -| | where 0 is Sunday and 6 is | | | -| | Saturday. | | | -+-----------+--------------------------------+------------------------+-------+ -| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) | -| | zero-padded decimal number. | | | -+-----------+--------------------------------+------------------------+-------+ -| ``%b`` | Month as locale's abbreviated || Jan, Feb, ..., Dec | \(1) | +| ``%b`` | Month as locale's abbreviated || Jan, Feb, ..., Dec | \(1) | | | name. | (en_US); | | | | || Jan, Feb, ..., Dez | | | | | (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%B`` | Month as locale's full name. || January, February, | \(1) | +| ``%B`` | Month as locale's full name. || January, February, | \(1) | | | | ..., December (en_US);| | | | || Januar, Februar, ..., | | | | | Dezember (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%m`` | Month as a zero-padded | 01, 02, ..., 12 | \(9) | -| | decimal number. | | | +| ``%c`` | Locale's appropriate date and || Tue Aug 16 21:30:00 | \(1) | +| | time representation. | 1988 (en_US); | | +| | || Di 16 Aug 21:30:00 | | +| | | 1988 (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%y`` | Year without century as a | 00, 01, ..., 99 | \(9) | +| ``%C`` | The year divided by 100 and | 01, 02, ..., 99 | \(0) | +| | truncated to an integer as a | | | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%Y`` | Year with century as a decimal | 0001, 0002, ..., 2013, | \(2) | -| | number. | 2014, ..., 9998, 9999 | | +| ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) | +| | zero-padded decimal number. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/10/2025 | \(9), | +| | | | \(0) | ++-----------+--------------------------------+------------------------+-------+ +| ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | | +| | space-padded decimal number. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%F`` | Equivalent to ``%Y-%m-%d``, | 2025-10-11, | \(0) | +| | the ISO 8601 format. | 1001-12-30 | | ++-----------+--------------------------------+------------------------+-------+ +| ``%g`` | Last 2 digits of ISO 8601 year | 00, 01, ..., 99 | \(0) | +| | representing the year that | | | +| | contains the greater part of | | | +| | the ISO week (``%V``). | | | +-----------+--------------------------------+------------------------+-------+ -| ``%H`` | Hour (24-hour clock) as a | 00, 01, ..., 23 | \(9) | +| ``%G`` | ISO 8601 year with century | 0001, 0002, ..., 2013, | \(8) | +| | representing the year that | 2014, ..., 9998, 9999 | | +| | contains the greater part of | | | +| | the ISO week (``%V``). | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%h`` | Equivalent to ``%b``. | See ``%b``. | \(0) | ++-----------+--------------------------------+------------------------+-------+ +| ``%H`` | Hour (24-hour clock) as a | 00, 01, ..., 23 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%I`` | Hour (12-hour clock) as a | 01, 02, ..., 12 | \(9) | +| ``%I`` | Hour (12-hour clock) as a | 01, 02, ..., 12 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), | -| | AM or PM. || am, pm (de_DE) | \(3) | +| ``%j`` | Day of the year as a | 001, 002, ..., 366 | \(9) | +| | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) | +| ``%m`` | Month as a zero-padded | 01, 02, ..., 12 | \(9) | | | decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), | -| | decimal number. | | \(9) | +| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) | +| | decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%f`` | Microsecond as a decimal | 000000, 000001, ..., | \(5) | -| | number, zero-padded to 6 | 999999 | | -| | digits. | | | +| ``%n`` | The newline character | ``\n`` | \(0) | +| | (``'\n'``). | | | +-----------+--------------------------------+------------------------+-------+ -| ``%z`` | UTC offset in the form | (empty), +0000, | \(6) | -| | ``±HHMM[SS[.ffffff]]`` (empty | -0400, +1030, | | -| | string if the object is | +063415, | | -| | naive). | -030712.345216 | | +| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), | +| | AM or PM. || am, pm (de_DE) | \(3) | +-----------+--------------------------------+------------------------+-------+ -| ``%Z`` | Time zone name (empty string | (empty), UTC, GMT | \(6) | -| | if the object is naive). | | | +| ``%r`` | Locale's 12-hour clock time. | 12:00:00 AM | \(1), | +| | | | \(0) | +-----------+--------------------------------+------------------------+-------+ -| ``%j`` | Day of the year as a | 001, 002, ..., 366 | \(9) | -| | zero-padded decimal number. | | | +| ``%R`` | Equivalent to ``%H:%M``. | 10:01 | | ++-----------+--------------------------------+------------------------+-------+ +| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), | +| | decimal number. | | \(9) | ++-----------+--------------------------------+------------------------+-------+ +| ``%t`` | The tab character | ``\t`` | \(0) | +| | (``'\t'``). | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%T`` | ISO 8601 time format, | 10:01:59 | | +| | equivalent to ``%H:%M:%S``. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%u`` | ISO 8601 weekday as a decimal | 1, 2, ..., 7 | | +| | number where 1 is Monday. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7), | +| ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7), | | | (Sunday as the first day of | | \(9) | | | the week) as a zero-padded | | | | | decimal number. All days in a | | | @@ -2575,7 +2601,17 @@ requires, and these work on all platforms with a standard C implementation. | | Sunday are considered to be in | | | | | week 0. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7), | +| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8), | +| | number with Monday as | | \(9) | +| | the first day of the week. | | | +| | Week 01 is the week containing | | | +| | Jan 4. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%w`` | Weekday as a decimal number, | 0, 1, ..., 6 | | +| | where 0 is Sunday and 6 is | | | +| | Saturday. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7), | | | (Monday as the first day of | | \(9) | | | the week) as a zero-padded | | | | | decimal number. All days in a | | | @@ -2583,40 +2619,43 @@ requires, and these work on all platforms with a standard C implementation. | | Monday are considered to be in | | | | | week 0. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%c`` | Locale's appropriate date and || Tue Aug 16 21:30:00 | \(1) | -| | time representation. | 1988 (en_US); | | -| | || Di 16 Aug 21:30:00 | | -| | | 1988 (de_DE) | | -+-----------+--------------------------------+------------------------+-------+ -| ``%x`` | Locale's appropriate date || 08/16/88 (None); | \(1) | +| ``%x`` | Locale's appropriate date || 08/16/88 (None); | \(1) | | | representation. || 08/16/1988 (en_US); | | | | || 16.08.1988 (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%X`` | Locale's appropriate time || 21:30:00 (en_US); | \(1) | +| ``%X`` | Locale's appropriate time || 21:30:00 (en_US); | \(1) | | | representation. || 21:30:00 (de_DE) | | +-----------+--------------------------------+------------------------+-------+ -| ``%%`` | A literal ``'%'`` character. | % | | +| ``%y`` | Year without century as a | 00, 01, ..., 99 | \(9) | +| | zero-padded decimal number. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%Y`` | Year with century as a decimal | 0001, 0002, ..., 2013, | \(2) | +| | number. | 2014, ..., 9998, 9999 | | ++-----------+--------------------------------+------------------------+-------+ +| ``%z`` | UTC offset in the form | (empty), +0000, | \(6) | +| | ``±HHMM[SS[.ffffff]]`` (empty | -0400, +1030, | | +| | string if the object is | +063415, | | +| | naive). | -030712.345216 | | ++-----------+--------------------------------+------------------------+-------+ +| ``%Z`` | Time zone name (empty string | (empty), UTC, GMT | \(6) | +| | if the object is naive). | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%%`` | A literal ``'%'`` character. | % | | +-----------+--------------------------------+------------------------+-------+ -Several additional directives not required by the C89 standard are included for -convenience. These parameters all correspond to ISO 8601 date values. +The ISO 8601 year and ISO 8601 week directives are not interchangeable +with the year and week number directives above. Calling :meth:`~.datetime.strptime` with +incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`. + +Several additional directives not required by the C11 standard are included for +convenience. +-----------+--------------------------------+------------------------+-------+ | Directive | Meaning | Example | Notes | +===========+================================+========================+=======+ -| ``%G`` | ISO 8601 year with century | 0001, 0002, ..., 2013, | \(8) | -| | representing the year that | 2014, ..., 9998, 9999 | | -| | contains the greater part of | | | -| | the ISO week (``%V``). | | | -+-----------+--------------------------------+------------------------+-------+ -| ``%u`` | ISO 8601 weekday as a decimal | 1, 2, ..., 7 | | -| | number where 1 is Monday. | | | -+-----------+--------------------------------+------------------------+-------+ -| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8), | -| | number with Monday as | | \(9) | -| | the first day of the week. | | | -| | Week 01 is the week containing | | | -| | Jan 4. | | | +| ``%f`` | Microsecond as a decimal | 000000, 000001, ..., | \(5) | +| | number, zero-padded to 6 | 999999 | | +| | digits. | | | +-----------+--------------------------------+------------------------+-------+ | ``%:z`` | UTC offset in the form | (empty), +00:00, | \(6) | | | ``±HH:MM[:SS[.ffffff]]`` | -04:00, +10:30, | | @@ -2624,11 +2663,6 @@ convenience. These parameters all correspond to ISO 8601 date values. | | naive). | -03:07:12.345216 | | +-----------+--------------------------------+------------------------+-------+ -These may not be available on all platforms when used with the :meth:`~.datetime.strftime` -method. The ISO 8601 year and ISO 8601 week directives are not interchangeable -with the year and week number directives above. Calling :meth:`~.datetime.strptime` with -incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`. - The full set of format codes supported varies across platforms, because Python calls the platform C library's :c:func:`strftime` function, and platform variations are common. To see the full set of format codes supported on your @@ -2712,6 +2746,9 @@ an empty string instead. Notes: +(0) + This format code is currently unsupported by :meth:`~.datetime.strptime`. + (1) Because the format depends on the current locale, care should be taken when making assumptions about the output value. Field orderings will vary (for From 25e99b375d959d2a2eb78d25f592a68455532c9a Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Sat, 7 Feb 2026 00:36:51 +0800 Subject: [PATCH 022/498] gh-132132: Upgrade to VS 2026 on Windows tailcall CI (GH-144544) Upgrade to VS 2026 on Windows tailcall CI --- .github/actionlint.yaml | 5 ++--- .github/workflows/tail-call.yml | 4 +--- Lib/test/test_dtrace.py | 3 ++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 267ff6b42a8655..675712d65d4c95 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -1,7 +1,6 @@ self-hosted-runner: - # Pending https://github.com/rhysd/actionlint/issues/533 - # and https://github.com/rhysd/actionlint/issues/571 - labels: ["windows-11-arm", "macos-15-intel"] + # Pending https://github.com/rhysd/actionlint/pull/615 + labels: ["windows-2025-vs2026"] config-variables: null diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml index 335e1a93dce4ea..853d149d20640c 100644 --- a/.github/workflows/tail-call.yml +++ b/.github/workflows/tail-call.yml @@ -52,7 +52,7 @@ jobs: # runner: windows-2022 - target: x86_64-pc-windows-msvc/msvc architecture: x64 - runner: windows-2022 + runner: windows-2025-vs2026 # - target: aarch64-pc-windows-msvc/msvc # architecture: ARM64 # runner: windows-2022 @@ -83,8 +83,6 @@ jobs: if: runner.os == 'Windows' && matrix.architecture != 'ARM64' shell: pwsh run: | - choco install visualstudio2026buildtools --no-progress -y --force --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --locale en-US --passive" - $env:PATH = "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\bin;$env:PATH" $env:PlatformToolset = "v145" ./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3 diff --git a/Lib/test/test_dtrace.py b/Lib/test/test_dtrace.py index e1adf8e9748506..ba2fa99707cd46 100644 --- a/Lib/test/test_dtrace.py +++ b/Lib/test/test_dtrace.py @@ -8,7 +8,7 @@ import unittest from test import support -from test.support import findfile +from test.support import findfile, MS_WINDOWS if not support.has_subprocess_support: @@ -103,6 +103,7 @@ class SystemTapBackend(TraceBackend): COMMAND = ["stap", "-g"] +@unittest.skipIf(MS_WINDOWS, "Tests not compliant with trace on Windows.") class TraceTests: # unittest.TestCase options maxDiff = None From 28fb13cb33d569720938258db68956b5f9c9eb40 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 6 Feb 2026 19:38:58 +0200 Subject: [PATCH 023/498] gh-143658: Use `str.lower` and `replace` to further improve performance of `importlib.metadata.Prepared.normalized` (#144083) Co-authored-by: Henry Schreiner --- Lib/importlib/metadata/__init__.py | 13 ++----------- .../2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst | 4 ++++ 2 files changed, 6 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index 9b723b4ec15e12..7cf4d29d330c91 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -890,14 +890,6 @@ def search(self, prepared: Prepared): return itertools.chain(infos, eggs) -# Translation table for Prepared.normalize: lowercase and -# replace "-" (hyphen) and "." (dot) with "_" (underscore). -_normalize_table = str.maketrans( - "ABCDEFGHIJKLMNOPQRSTUVWXYZ-.", - "abcdefghijklmnopqrstuvwxyz__", -) - - class Prepared: """ A prepared search query for metadata on a possibly-named package. @@ -933,9 +925,8 @@ def normalize(name): """ PEP 503 normalization plus dashes as underscores. """ - # Emulates ``re.sub(r"[-_.]+", "-", name).lower()`` from PEP 503 - # About 3x faster, safe since packages only support alphanumeric characters - value = name.translate(_normalize_table) + # Much faster than re.sub, and even faster than str.translate + value = name.lower().replace("-", "_").replace(".", "_") # Condense repeats (faster than regex) while "__" in value: value = value.replace("__", "_") diff --git a/Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst b/Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst new file mode 100644 index 00000000000000..8935b4c655023a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst @@ -0,0 +1,4 @@ +:mod:`importlib.metadata`: Use :meth:`str.lower` and :meth:`str.replace` to +further improve performance of +:meth:`!importlib.metadata.Prepared.normalize`. Patch by Hugo van Kemenade +and Henry Schreiner. From 895e83727d6d686ab7dd5494f3ccd52b0726502e Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Sat, 7 Feb 2026 03:20:28 +0800 Subject: [PATCH 024/498] gh-144549: Fix tail calling interpreter on Windows for FT (GH-144550) --- .github/workflows/tail-call.yml | 14 +++++++++- Include/internal/pycore_ceval.h | 5 ++++ ...-02-06-17-59-47.gh-issue-144549.5BhPlY.rst | 1 + Modules/_testinternalcapi/test_cases.c.h | 23 ++------------- Python/bytecodes.c | 28 ++----------------- Python/ceval.c | 28 +++++++++++++++++++ Python/executor_cases.c.h | 26 ++++------------- Python/generated_cases.c.h | 23 ++------------- 8 files changed, 62 insertions(+), 86 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml index 853d149d20640c..a47e532d396bc0 100644 --- a/.github/workflows/tail-call.yml +++ b/.github/workflows/tail-call.yml @@ -38,6 +38,7 @@ jobs: # Un-comment as we add support for more platforms for tail-calling interpreters. # - i686-pc-windows-msvc/msvc - x86_64-pc-windows-msvc/msvc + - free-threading-msvc # - aarch64-pc-windows-msvc/msvc - x86_64-apple-darwin/clang - aarch64-apple-darwin/clang @@ -53,6 +54,9 @@ jobs: - target: x86_64-pc-windows-msvc/msvc architecture: x64 runner: windows-2025-vs2026 + - target: free-threading-msvc + architecture: x64 + runner: windows-2025-vs2026 # - target: aarch64-pc-windows-msvc/msvc # architecture: ARM64 # runner: windows-2022 @@ -80,13 +84,21 @@ jobs: python-version: '3.11' - name: Native Windows MSVC (release) - if: runner.os == 'Windows' && matrix.architecture != 'ARM64' + if: runner.os == 'Windows' && matrix.architecture != 'ARM64' && matrix.target != 'free-threading-msvc' shell: pwsh run: | $env:PlatformToolset = "v145" ./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3 + # No tests: + - name: Native Windows MSVC with free-threading (release) + if: matrix.target == 'free-threading-msvc' + shell: pwsh + run: | + $env:PlatformToolset = "v145" + ./PCbuild/build.bat --tail-call-interp --disable-gil -c Release -p ${{ matrix.architecture }} + # No tests (yet): - name: Emulated Windows Clang (release) if: runner.os == 'Windows' && matrix.architecture == 'ARM64' diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index f6bdba3e9916c0..e9f1f65e53cec1 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -474,6 +474,11 @@ _Py_assert_within_stack_bounds( _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, const char *filename, int lineno); +PyAPI_FUNC(_PyStackRef) +_Py_LoadAttr_StackRefSteal( + PyThreadState *tstate, _PyStackRef owner, + PyObject *name, _PyStackRef *self_or_null); + // Like PyMapping_GetOptionalItem, but returns the PyObject* instead of taking // it as an out parameter. This helps MSVC's escape analysis when used with // tail calling. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst new file mode 100644 index 00000000000000..9679e2cf6af426 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst @@ -0,0 +1 @@ +Fix building the tail calling interpreter on Visual Studio 2026 with free-threading. diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 2a73a554eda2cc..dda3bc53dc5e0d 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -7899,28 +7899,11 @@ self_or_null = &stack_pointer[0]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { - _PyCStackRef method; _PyFrame_SetStackPointer(frame, stack_pointer); - _PyThreadState_PushCStackRef(tstate, &method); - int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, &method.ref); + attr = _Py_LoadAttr_StackRefSteal(tstate, owner, name, self_or_null); stack_pointer = _PyFrame_GetStackPointer(frame); - if (is_meth) { - assert(!PyStackRef_IsNull(method.ref)); - self_or_null[0] = owner; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - } - else { - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); - self_or_null[0] = PyStackRef_NULL; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - if (PyStackRef_IsNull(attr)) { - JUMP_TO_LABEL(error); - } - stack_pointer += 1; + if (PyStackRef_IsNull(attr)) { + JUMP_TO_LABEL(pop_1_error); } } else { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 818b4fbc3801c0..bd22599aef725d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2364,31 +2364,9 @@ dummy_func( PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ - _PyCStackRef method; - _PyThreadState_PushCStackRef(tstate, &method); - int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, &method.ref); - if (is_meth) { - /* We can bypass temporary bound method object. - meth is unbound method and obj is self. - meth | self | arg1 | ... | argN - */ - assert(!PyStackRef_IsNull(method.ref)); // No errors on this branch - self_or_null[0] = owner; // Transfer ownership - DEAD(owner); - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - CALL that it's not a method call. - meth | NULL | arg1 | ... | argN - */ - PyStackRef_CLOSE(owner); - self_or_null[0] = PyStackRef_NULL; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - ERROR_IF(PyStackRef_IsNull(attr)); - } + attr = _Py_LoadAttr_StackRefSteal(tstate, owner, name, self_or_null); + DEAD(owner); + ERROR_IF(PyStackRef_IsNull(attr)); } else { /* Classic, pushes one value. */ diff --git a/Python/ceval.c b/Python/ceval.c index 590b315ab65c2c..61644d35b5e473 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1007,6 +1007,34 @@ _Py_BuildMap_StackRefSteal( return res; } +_PyStackRef +_Py_LoadAttr_StackRefSteal( + PyThreadState *tstate, _PyStackRef owner, + PyObject *name, _PyStackRef *self_or_null) +{ + _PyCStackRef method; + _PyThreadState_PushCStackRef(tstate, &method); + int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, &method.ref); + if (is_meth) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + meth | self | arg1 | ... | argN + */ + assert(!PyStackRef_IsNull(method.ref)); // No errors on this branch + self_or_null[0] = owner; // Transfer ownership + return _PyThreadState_PopCStackRefSteal(tstate, &method); + } + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + meth | NULL | arg1 | ... | argN + */ + PyStackRef_CLOSE(owner); + self_or_null[0] = PyStackRef_NULL; + return _PyThreadState_PopCStackRefSteal(tstate, &method); +} + #ifdef Py_DEBUG void _Py_assert_within_stack_bounds( diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index a98ec2200485d2..f8de66cbce3a9f 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -8670,32 +8670,18 @@ self_or_null = &stack_pointer[1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { - _PyCStackRef method; stack_pointer[0] = owner; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); - _PyThreadState_PushCStackRef(tstate, &method); - int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, &method.ref); + attr = _Py_LoadAttr_StackRefSteal(tstate, owner, name, self_or_null); stack_pointer = _PyFrame_GetStackPointer(frame); - if (is_meth) { - assert(!PyStackRef_IsNull(method.ref)); - self_or_null[0] = owner; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - } - else { - stack_pointer += -1; + if (PyStackRef_IsNull(attr)) { + stack_pointer[-1] = attr; + stack_pointer += (oparg&1); ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); - self_or_null[0] = PyStackRef_NULL; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - if (PyStackRef_IsNull(attr)) { - SET_CURRENT_CACHED_VALUES(0); - JUMP_TO_ERROR(); - } - stack_pointer += 1; + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_ERROR(); } } else { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index fc1144a88d70cc..4cc9d9e03a545d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -7898,28 +7898,11 @@ self_or_null = &stack_pointer[0]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { - _PyCStackRef method; _PyFrame_SetStackPointer(frame, stack_pointer); - _PyThreadState_PushCStackRef(tstate, &method); - int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, &method.ref); + attr = _Py_LoadAttr_StackRefSteal(tstate, owner, name, self_or_null); stack_pointer = _PyFrame_GetStackPointer(frame); - if (is_meth) { - assert(!PyStackRef_IsNull(method.ref)); - self_or_null[0] = owner; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - } - else { - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); - self_or_null[0] = PyStackRef_NULL; - attr = _PyThreadState_PopCStackRefSteal(tstate, &method); - if (PyStackRef_IsNull(attr)) { - JUMP_TO_LABEL(error); - } - stack_pointer += 1; + if (PyStackRef_IsNull(attr)) { + JUMP_TO_LABEL(pop_1_error); } } else { From 74db4404eaa9b4448b50ab7be7d50487dc0585fd Mon Sep 17 00:00:00 2001 From: Krishna-web-hub Date: Sat, 7 Feb 2026 02:56:44 +0530 Subject: [PATCH 025/498] gh-84116: Docs: Document help and aliases for argparse.add_parser() (#140574) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gh-140281: Doc: Update free-threading how-to * gh-140281: Doc: Update free-threading how-to * Fix trailing whitespace * doc fixing of the cpython fixes#84116 * Docs: Document help and aliases for argparse.add_parser() (gh-84116) * Docs: Document help and aliases for argparse.add_parser() (gh-84116) * Fix trailing whitespace * Fix trailing whitespace * Fix trailing whitespace * Fix trailing whitespace * Fix trailing whitespace * Fix trailing whitespace * Fix trailing errors * Fix trailing errors and spaces * Fix docutils formatting, NEWS ref, and trailing whitespace * Docs: Update argparse.rst and add NEWS entry * Delete Doc/howto/free-threading-python.rst * Delete Misc/NEWS.d/next/Documentation/2025-10-25-00-49-43.gh-issue-140281.tuMQUe.rst * adding the depreceated tag * The error indexing was fixed * Fix trailing whitespace * Restore missing free-threading documentation * fixing some minor error * fixing some minor error part 2 * fixing some minor error part 3 * Fix NEWS entry format * Final cleanup of NEWS entry format 2 * changes in the argparse.rst * Remove unnecessary NEWS entry * Fixing the issue as requested * Added the Changes done before. * done the changes * done the changes#1 * Apply suggestion from @picnixz Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * Apply suggestion from @picnixz Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * Done the changes * Done the new changes * The versionadded is rectified * Update Doc/library/argparse.rst Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> * Docs editing * Docs fixing whitespace * Docs rectifiying * little bit rectification * Indentation rectification * Indentation rectification 1 * Apply suggestion from @picnixz Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * deprecated rectification * Remove mistakenly added NEWS entry * Update Doc/library/argparse.rst Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * changes #1 Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * Update Doc/library/argparse.rst 2 Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * removed useless thing Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * changed according to the request Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> * Updated the test part --------- Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/argparse.rst | 73 +++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index c7532ecd629b02..81e5d3470c3e57 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1771,7 +1771,7 @@ Subcommands >>> parser.parse_args(['--foo', 'b', '--baz', 'Z']) Namespace(baz='Z', foo=True) - Note that the object returned by :meth:`parse_args` will only contain + Note that the object returned by :meth:`~ArgumentParser.parse_args` will only contain attributes for the main parser and the subparser that was selected by the command line (and not any other subparsers). So in the example above, when the ``a`` command is specified, only the ``foo`` and ``bar`` attributes are @@ -1814,7 +1814,7 @@ Subcommands -h, --help show this help message and exit --baz {X,Y,Z} baz help - The :meth:`add_subparsers` method also supports ``title`` and ``description`` + The :meth:`~ArgumentParser.add_subparsers` method also supports ``title`` and ``description`` keyword arguments. When either is present, the subparser's commands will appear in their own group in the help output. For example:: @@ -1835,34 +1835,8 @@ Subcommands {foo,bar} additional help - Furthermore, :meth:`~_SubParsersAction.add_parser` supports an additional - *aliases* argument, - which allows multiple strings to refer to the same subparser. This example, - like ``svn``, aliases ``co`` as a shorthand for ``checkout``:: - - >>> parser = argparse.ArgumentParser() - >>> subparsers = parser.add_subparsers() - >>> checkout = subparsers.add_parser('checkout', aliases=['co']) - >>> checkout.add_argument('foo') - >>> parser.parse_args(['co', 'bar']) - Namespace(foo='bar') - - :meth:`~_SubParsersAction.add_parser` supports also an additional - *deprecated* argument, which allows to deprecate the subparser. - - >>> import argparse - >>> parser = argparse.ArgumentParser(prog='chicken.py') - >>> subparsers = parser.add_subparsers() - >>> run = subparsers.add_parser('run') - >>> fly = subparsers.add_parser('fly', deprecated=True) - >>> parser.parse_args(['fly']) # doctest: +SKIP - chicken.py: warning: command 'fly' is deprecated - Namespace() - - .. versionadded:: 3.13 - One particularly effective way of handling subcommands is to combine the use - of the :meth:`add_subparsers` method with calls to :meth:`set_defaults` so + of the :meth:`~ArgumentParser.add_subparsers` method with calls to :meth:`~ArgumentParser.set_defaults` so that each subparser knows which Python function it should execute. For example:: @@ -1898,12 +1872,12 @@ Subcommands >>> args.func(args) ((XYZYX)) - This way, you can let :meth:`parse_args` do the job of calling the + This way, you can let :meth:`~ArgumentParser.parse_args` do the job of calling the appropriate function after argument parsing is complete. Associating functions with actions like this is typically the easiest way to handle the different actions for each of your subparsers. However, if it is necessary to check the name of the subparser that was invoked, the ``dest`` keyword - argument to the :meth:`add_subparsers` call will work:: + argument to the :meth:`~ArgumentParser.add_subparsers` call will work:: >>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers(dest='subparser_name') @@ -1922,6 +1896,43 @@ Subcommands the main parser. +.. method:: _SubParsersAction.add_parser(name, *, help=None, aliases=None, + deprecated=False, **kwargs) + + Create and return a new :class:`ArgumentParser` object for the + subcommand *name*. + + The *name* argument is the name of the sub-command. + + The *help* argument provides a short description for this sub-command. + + The *aliases* argument allows providing alternative names for this + sub-command. For example:: + + >>> parser = argparse.ArgumentParser() + >>> subparsers = parser.add_subparsers() + >>> checkout = subparsers.add_parser('checkout', aliases=['co']) + >>> checkout.add_argument('foo') + >>> parser.parse_args(['co', 'bar']) + Namespace(foo='bar') + + The *deprecated* argument, if ``True``, marks the sub-command as + deprecated and will issue a warning when used. For example:: + + >>> parser = argparse.ArgumentParser(prog='chicken.py') + >>> subparsers = parser.add_subparsers() + >>> fly = subparsers.add_parser('fly', deprecated=True) + >>> args = parser.parse_args(['fly']) + chicken.py: warning: command 'fly' is deprecated + Namespace() + + All other keyword arguments are passed directly to the + :class:`!ArgumentParser` constructor. + + .. versionadded:: 3.13 + Added the *deprecated* parameter. + + FileType objects ^^^^^^^^^^^^^^^^ From a2495ff1e7b370c26128aa41298edb9ff06b5666 Mon Sep 17 00:00:00 2001 From: Alper Date: Fri, 6 Feb 2026 19:11:58 -0800 Subject: [PATCH 026/498] gh-144490: Fix C++ compatibility in pycore_cell.h (GH-144482) --- Include/internal/pycore_cell.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/internal/pycore_cell.h b/Include/internal/pycore_cell.h index cef01e80514f4b..d0d45a2343654f 100644 --- a/Include/internal/pycore_cell.h +++ b/Include/internal/pycore_cell.h @@ -53,7 +53,7 @@ _PyCell_GetStackRef(PyCellObject *cell) { PyObject *value; #ifdef Py_GIL_DISABLED - value = _Py_atomic_load_ptr(&cell->ob_ref); + value = _PyObject_CAST(_Py_atomic_load_ptr(&cell->ob_ref)); if (value == NULL) { return PyStackRef_NULL; } From f4364a51c1a8ce682fe9e4e96c6aba9f1b590422 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Sat, 7 Feb 2026 05:59:54 -0500 Subject: [PATCH 027/498] gh-144538: Upgrade bundled pip to 26.0.1 (gh-144556) Upgrade bundled pip to 26.0.1 --- Lib/ensurepip/__init__.py | 2 +- ...ne-any.whl => pip-26.0.1-py3-none-any.whl} | Bin 1778622 -> 1787723 bytes ...-02-06-23-58-54.gh-issue-144538.5_OvGv.rst | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) rename Lib/ensurepip/_bundled/{pip-25.3-py3-none-any.whl => pip-26.0.1-py3-none-any.whl} (70%) create mode 100644 Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index f9f905f46ff09a..9239e42b9ca8e1 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] -_PIP_VERSION = "25.3" +_PIP_VERSION = "26.0.1" # Directory of system wheel packages. Some Linux distribution packaging # policies recommend against bundling dependencies. For example, Fedora diff --git a/Lib/ensurepip/_bundled/pip-25.3-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-26.0.1-py3-none-any.whl similarity index 70% rename from Lib/ensurepip/_bundled/pip-25.3-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-26.0.1-py3-none-any.whl index 755e1aa0c3dc5a90defba25ab35f4b8877ca95ab..580d09a920422fcabbd462c937d08c96dd7f08bc 100644 GIT binary patch delta 514263 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 $J~?}lOgBPm+FiI7V?iQdyZ@{PABa41R!#$Sznu zP6Q1pu_zAZCA9hyKYjy7P}aJkOcK9Uo!^d~72YJ3hMY&CPV=(oM}31vciIQ-$Uz!K zp9~fciueBjW4p3#&g#^9Z~l{!P8Dy;bIGl2c(WUMdbfw-u{r%9V-TqGXCa1Kb%)WI zz-5H~hWQTNV%MC5gT)l1^}hh(yXj`t$e}|5IYE|q87RlpL*_j-2_dhbt)LXvqLU6& z=r!NpD}AoXdb$Hk(lVdf<7XZUS!6PqCUCI5l})Q*9#NTA=_{ECW<8BXO17Hvwhjl) z62$1pUR}fl@EGp_7tHo|{ROuf+9ta%Z1P(lTnI=+r^;(^eLxVbJxc)G+Bi)f=$(0A zbo1zqdneE$1EJtT!s8+0NA?w$DgQnzoI9Y*SA@qd@lb{Np8ycib>z@|Z-$Xo*4QW$ z#A{S_Ip$8{r&=2!^VL?M6Ikz^R?k6W>RBWs)+g1qhZ3i7md4lI>VYWwk*NhX*sO4K zN*fV07^8ee24ZWXdJh2Nw`@{tDad00N`VVj1|tzS7)3o$ODfe31qe8oQ9gP2F1FJCHU8=PT{G>yBXi`OxIdVT&l z27uq!u@}02x98XM@%!4*MONEDv?wxkFDPvipjKUD&d;YK(jK5*SDUM^H^$MYTeA&< zxQ&>BCLLV0a>I)Ur=h{1UbnBWU#-q?5M_?Zpx!ICQU#c>ouO>Ieb#&{#`P$OlrZ@4 zVoV1eTPKMMG_1$6kn%8?p_g~gM6)FqLp~@m#XRi>?CfRHXr(9p3-tJqUZ33%;B4%K zJ{9>1z?YyGodKDt29X07w$k*4O1EG{gS6lfQVkZ;P*gA#u98TabBG}PDli~QMMJ-N z@xli}ZJ8YYm>f!nmA;QT{hk}n&`SeP(Lrwxz-Omw^6PzpE%A`z-QC8i596{uZO%x_ zOYAOf@=HSGt?0*=8$h&A9nQ}#3Ur=NqvLfAM*9F&eg@c!5kn>grVGCem(yUa9RzR# z&HsK%t*0u%S~ces7P`^-(-C|K;)w4Bb9eE-Nt7tmdzx_)~3J8SC;QE`URmT+Qw?cWl9FNUy!H%-2eDtA!bjh zedVBkI;{8svC)FojF|3l#h9C}ZL;KXLQnGtw-A84&7G8pwJ=H)_)TRbs@+&4C6-*i z47PyEqM^h;EQd|01wqD1O3;iLoaZ;=!&sJ6vu#`sX#{r^cA?~GG;QVtAvox@7G-vQ z%p)B}1rTGuLS$_M`xALjfvQ!D#a(qqgs%!F(hy7BZzP9DlXS0&Bb87s;Oq55icpG$y3`!Lb=lHB*lqBE(fk_>YySE;7f6H zp1K|gJg+(LSAbd!1>@SHI5R9z0xx%j&;|5I!%QgOY2#N}%v@lhHRhM~<|>{#x2h)z zKq)z%l3F2zN{;+$IOy>!?kGqkK}nk+)%;t+05KM~(z`b{$&;o&%Ej?|!xZdwAFigB zi79hs46hq`+m$yx8Aif@+Tw1&{uYPi$cX*=mjSG`TBaYU03n?v{abw&n)r^aD-|&B z(#OC#vS_#;6wh8MSrHw_T`=HuKu}VP(8Fm9;cp14kIPj=9NP&Ti#U(DEg5kB2Rt73 z!4xLFMzS76l#I8=l0^kJRFg!;%+_))2|&0HN!vTH5h$n30Xv_(u8gmtPYZTCN)Q&K zvx`Zs{~CV_QkYU;kM!Gr8jX5+84EBE#7?_q6#=q^S^o4Gm6b(<@_Kh$ysB(CW(iM# z3zFj$BX-`K3mae#Y}9}`lIj2#2X#P1QIvfpmV794mx-Uga%BfMW&}LhsOX?1p_w4w zC=LrX?&yXT$Q=mLI9H9HQs>Y<2&F6(k2i`?3@;MqxGkf_TDDM_ONpdE{tU>a>H?b( zIyD1*mKUF}_%!X0`bDd-G|`%du{Do+4^p1Jl;DCdpsYJH%u5n)M=3W{rb~bXr!Iu@ z@$JSQDdvqKhbd@9sB8555$WVC!;xKk^MYB${MeVxeTsoucS?W!MIf;t$T%>Rcp!G< zc5FAG`Iq*UGyPFUY_QYv#2(R%E2QMP!Bjy(&j+TOPRE&z49ydHN4E6SUQh&cfvs^1b_e#tR4=n@HdCuCjGKedE^embX{M-{;E8A6BLJ5GVege{Rqjx0# zy6qZD5p9<63VgR7s8(^{y0|oh$IFwX7T^LGYb5a@vO2^bj$S9eoYYhA9;EcMr01k; zif@n0H7D-m%WWD@L~0p0OOndJ#?O;VI70&0)Wqu5XuQx(NjYC2+9&z&3=4%vDW1^=k(nbvvW*&(tz4;xi*}Mk01P4o@vg@v zZWN1#UTR65%NKFkTz-(T`)NVggu!g=*krx1u#sU}Ew~t~1?w#Ojv&BxJJ#)}I>bEH z(Cg~IBIwyRMg&y{=~ja3Vaiu%Wgz}|BD!e;K{I-@C#+#d z>fWz&%QF`ZI|-1+HPYKTBlqIuh|F(NOW(`*djH(w((@a ziSy7O+rdOGdF(wkYr~%lx0D|iE@E3?!4Z9B`npeP?*^37`_tXxz+bnez?1EzAL2_m z$h)dxWIR%dM-4{({oR1Km0+Wop$82sYra#H4zFD!Zh5#V+b2Wc%e>NNAuPbY+REgB z6G1R4SJ_5EHdJFUL9!8s6qIYljjLV>WIF^?#_ZO865@lOyLHhch$i@h^sABd#4bwz z?+=a}=wCnryAAG2^8kV)K0K_>Y@`9b(b|G`Aouo}d?v}e1%uUDCech+g0=RNk}QEd zfw?x}+j~`l-m@=s*zD2bw7dU$a2`Ll&ZFfT z$E@bLYWzO&tX~dJ040jAjw2I&BHn2Q+hOhYCy^V9a$U|gyprM?#(c}ykePXFgjR%b zs5XO=?90?1!Wu{oQ4&#SQsvlhxjrYzc->dVTT*!tIh|0nu)~eb>Zxs&MfD?(e}jdc_U;C|^`QAqXln=3ju zdz(o3>_;{#FeQ4e@l*W}5cDnnL8P1wxq*i9Nx|(Qtpi$@GLH!-`e?pV=BJP*r$;@p zyyyNkWTOC_zIC0o(3X)~i`po{IQ&a4u4lkpgkx7D^tN=z7a8I$=644Vj+Epm`~D9s zk#c44nf<48=Ln@h#%_&YH$qjk@D`|wZ>+m zw+45wLUPf+NOl)m2dETF(C$ad#!R%JFGH9W`up1dlxjJAqy-cFLF)3}`8IBiqo6yF z+0HPRe@64yz6Prn#2^x%%nG7sSP`;Y|y#DeGgxt;I(d4g0^s)}MI;Vf5^Pr0~M zCJC`)xM@`E+l5N``GV6hC3WDc+@#7GUD4)q*fC_OZgabjPYx2{xff1$(TEO^7+F5$ z8u>Le`a%OJYt^Mh=UWVs!k2|~~6za8$P`XgDHUG#9GzRZm=-ghI zicUTFt^M01K~)7_Wi-}vVK{@WHVB-xibn&XU`aU7qu^v$f|?y zzQTkrjs-^au)OmNV7o{wUAflpS8UIphcnJ5UIxN_5#>$Ko*p!PS{?T8=`PMe0=FCN z{DMMIEc4BtWB-q+m1@b?f%X%F=x<`vj{>EpVuhu3b+IVEgs)S*qk39SB(Awf5?1$o?|4Mb6vi8-W|JS4TiY!U66c?XxRvxj&IbIX@;f-d2IsxEA9z7w_@7njjjbWz(T*^Y zwk@6faR|Aa-d8xWR12LNS}U>1T844JP6jb~LSpvVRTv*=1f7!^C&R4FS}j_Nk#Mf* zd)ofa--5`gCRcJd+2qP-nu(0HFZb+~-{*X;v`t1!m)&s>yn08Uvi7N3*y36R9%{p$ z>4#c?_DJ$Ll!lEFv2~KOF%>H1k;+v6WT&-!pV!Z~l{r+mhq{*=fz8cm!}}X(1~m$p zHJ)P;wFs-h+NMOmn7!p+Q##GAsm`9skvH;zp&hF>v~)J@?_e~atalD+6UBT&s$H65 z%pVM=bd;j(H{q{Js>3`4VgqYyT8U%Iftg7FI*$9-W1jRJrdN+#iJd;Q#={7sa`V+# z4!k$cw9EPRBY|0&fz6rAV<6ZO-q_%yYh7*?OjNS~Y-8v%x zkH7tV#`7q@k(Ndl0%CWPseu%iKgI3FMqf&UFi%fcPe@K+4N#b^Q-jf`x0WNd5}TArs~~})x2i&$q2#aTS+CC?F!1>aZSnXLu2(Y1p20qP|I_wVvNlK zbEiqvnd*gK@9MI_2sD=9;ImuDWq}odt`VcHO|H{POzJIj#1aSEH^pb-!L`5iW)(f% zV0r(*Dg6>kJ`_K2M;PgEsFMAD^%(TvEMFtQ9`U+6)0@hfH4+wX)D?k<%*&o-Es}Q6 z>6)W!nx*m%1k-8i!RdPI7OxJj6Wqf=i$f!6gh$E7EV`U=CmTDS6w3?0V|N;$1}irE zYZ~UYE?Tcpj{JNPz~{(@=_0)|XglqRezo7I;+08mMT{<5M=?u}!HuCXPUm3Xksa@t zIyK9SuHmXy&$EKFYr8GW0@OfJ7=<)YScQ$K>i`v2#V2@}4@?$>E!l0)r+5_(U+?Dy zl#SOEPznjZ8L;J^S#=)B%5Df4wKT6@Q2K4VTk#j|3~k@3j7sLhLFkNg11Z(AiH#=M zDi%uTXa;ZAl@XDP0%s@a)tbZ-)sA|UD92TIp4@<$CXr&>4270{VcPN(9Kq07NjeB$ zg<(|zkN%lH=(e0eEl>XsPzRk4gC2t={C*AjAt(qZ&%fnJ1ti-sE*#96e-uX ztDLbFXM&-Ou$qJhK1LI4Ov_^oti_FXcLp6#t1J9sDh_RGv_QT-0S<94NxPQqul(h& zoT|_4s9kZFTTBoqt_T(Y704C$F;MQZ*#baa%bS!IFC!H@$T(MEYJTHHk|7g9WCZ2&V?6@vIzBYIrt|~1cy><1E0VzsH+u=U& zA?mL)sBEM!vJ<}dqW8vVn2_3vx8IIg^fa=bF!Y=#1~n)P-@mi=QSl-HVahH`#nH=} z{1jPV8-#;|^nuu2xC!6ifD*X%U zYL09%gG?S#7!VG;JY|1-4G6Yk1kFk-eXM_%WQSbrq;pZASfrR8(hz0j$H(LCcOaZ$ z4TU$dZUQ#7WkDSwXh3d(0pn5^OHA|7Fk;O<74$AlsGpLCuA!^+Sjd1(x0PVmWR0uO zFOznrFbM}3EoCDPd_m0dJ)4+~py#NLA;SZR|K3;hJ+J;5-ta!&QL2WgMaG}$=IGHV znAbJ`p_T_8j9n^97YQ=hjE$+tGoBc$UNsl$N|@=dxBl+y{FZBb3txiS|)Nq-Lxj^Tqm z9|8{W_(ST93!i@u()ndiIT&W>H&>Mszxl$S1*#`)Kgf;N7878l-#H+?O!GS$A!9vK z8~cNAS^udsnsT0vpI??$!FsS$|G0dlN&&6jNCkXCVVrTU1uovw5UxGNu)Re zF^Sr^9%C>CoWGrH%T%%G3-Zn}CmA9HRHzA{g*0%s6}!O)%t=GoH`q!pEM>2PVU@wU z^Ox;IC}=BZokupo8pQq{SgWxseLzQG7$}G-?a@+>)C1n?164DgCfyr`U&_4Xz!~`Q zImph-9~2}F2``O5h0RdN#Jqp}yPEmh-kG?#lFD6oO4geY`_E-oAiWb0xpsyp8W^Ym zxn5ROhrY$>7WD6ME)puDibND-IZqVNxXe2da03x=-$@OQ$BXPH3sqODRx!yxj|)i| z7dcqb?il)lUfSBsy!?+#1YE}b0u6{eK^kB&Rf=a!SgTLnnXy-t4GTkO-RhoO6}ENZ zd&k(Im4Sr0u_v)((fMvi5h&?!Hg`n;3FqtI6Ckcl)gy>|Pu?B!Y81tJ^$AjwISJy) z%b{0ga);GGkKl!Q^nW%ktL&G-B$i737wiq{1b#OW?tHs~C|Q{)_0Q>M8jf{VT5>Y? z1X20diQRmi;j`nN`QE;q>3Rmkg?8Qj3i>f6py55|=e2o=%@xBw|EE7SItW|>ycyw~ z9I=PaW@#v@UP%ef3~wI;)grf@qERU#1dxm@LM;M2q(PPMW)KRIt=+ZfrvZ;SMKOS$ zg2U|`U{Oe&Pm(n6Tl@6*Y(RV9#yWkoEPEz%U$*VGE|eU5NXW6dKYi80%NQhe*%(B^sQHyYf!p;Lpu9h!>Lse zP@(4&1`Sn92g~krVd$fr|Bf@F4RFnb4}qyKZV&Gnawlpn0&ncJ9B zgE))lMg`4QBH5z<{nS*7(^=sBjF#r->gwjjLnwIOS5(cKO1@!`(UblZ=J17&Pos0< zsIu_WW!xcM=97ip{v$GG%bozKx%4qKEGxmknNM#krG5|~pkb*0ttHbG zGjO1q&_5u4F@`7DG^b~;s8Cpq61+^`e%Q3PvO79<=(g_d508gP*1umS??#R79bZr!mRZYx5}@i&UdZ4O0RjEw#K^+3zzXKZ zGyE82`;JLb1*a&b8X&w6cbDd!83({01iQtB+b`>q_>gZ0M0qOvr^8MbJ%WG7DP#CK zL$WVAwg`Kz$<=9j%8^HdEt1c|8Cwzj^!#}89V~ig>}q;;((@-YE(U~uMc{ZGC>@$e zIlN4~+%U;GlurLq07P%}x1)Z*G=HZ;IQVxzj$J2}8bLv%&=4SutZagTO=9^rIxQ#$ zcx|yEUjBw+>geQ}`Bw03yV-^CJ>jHj12j@YTaGPPt@Z3sF+{;1>-4!GPzf)_OtV30FywSz-n z@lZi_P(JVT{=yjKFGLq+5W1G8QLJc^(sdF9i>X5*i*IZuWZI9s?dUI?3?uleVPk{l zt{|52V(`jgiPzOmIC(|FT7$rIX&T%agcHF`$6-j&pFj}VftNl>?fVOj^SuLB1H?se zz~$TqMNATC17O$#JD~HeZ10+|@~)M{QjAetkijNZ&A^Hw*u&Eh{S>miO|pYoKu-!A zsb&R}FQAUW=(VzHN?9az%?pvO2=K261E$b*b7?C=tmQeSS&Ch0Wqxlr1l|H6xY`PS zLx*sv)&M=dfjW@fR@MYjpA|}1Qbxxp{>xxZS}Wh{3qS>ib&lmm&7?FUnxzg13-eEp zQX6ihvD2M>j5B0mW9q(cOc{)~L|miB>5GI|d;;I=&yn8IJ89t2uEDt8I;3{0XeQxN zY?VkJ2Klb6n4i+2Pd)6u;4g_ZV*4{1qsU2e97{A;@lVxRUIm4(QaxV%Vy1{#NZ6_C zI~=r}1Q5FF8nJ&4@NEqMcY(09yIOif?Zj1s@rAyJpYLkdm{z&RS%ws8JB4UU6qdM-6WL*a6g;{!L93@v z!j9b6yKe3L6cn#K{9&+?S;dhUdb&@05q%~#lW_w$({ z-e*`lxfKM%@&b#PesneN$#O3yE$wu~+rHKiN<*6tne9UY_6QYBBwHVvPDU=#13IxP^(*qv%T zMk)h`y6_6dc{LW4MRQeERkaW zAe+rwMRnNPgw#wfhV#ij0p&ThxLNqjBg8&mp^8gRH67lRcf;(4lefrPiFkdeJ*J!e7v+*

8l1~=-LJhJSOqeubUcwGv( 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 z zIYsLYdHwLonet&Ek!TyQ3KXPZ3QGS8RF?TP!`b2$zR-YQUhZ_6-3f|+6bilJ1AT1vg2NV3jk}u_{Oru2x;Qn zt|yaKUC?f3B7-gSUNtvRee8W#gqE@+VBsmuio_!hr z90pOeG51}FA_jfC#vQpByx@RP^kf$a&{Y)=JPN-IAv~N;;62u*B|QFos&tKN-9MOP z&>00GE{n~c;KK3`D!-o{Hvk*#H7`S`WpN9o$Phh)Rr6%1(Z~&xj;xBV2U84EYZsPT zcsPr1uj^{gh`>8wv<`u=ux6+J%kXes1o-xEl;=SCIS;y35@=^2g`9*}cSCIitpJOZ z0Fdhh1@e%+CFM?oy#K#NaO|F@H)}U^qas4TM^>-`z+)mIZ!7>2Psuu)9uDzs zdSZYEb6okW-YGzou8_6R9NIz8jGGQ*EvrP+&H2$|%~8(=w(wKG9d;h?Cn6z}u5ITG=u2%#x(Lnr4$$FJCAWc72N`;)1ubDO_GT)#UErA{hOCxDtRIkQ)D-i2 zN*P$bZX8&-lJQ(b!M17;)u=Nf`?25H0AtWqiG7PG9hpcTM2a1-or)-Zl~kJr8x*8B zw*M2o#peA&@Xf_$Pa^XZ&3xI_?A_U2{0Ymf`WKP>2G0pt@+L1HjE)377YuxR_pd$x z^?e&}v>xw0&bgkPY`PVE_5@!@I7t>>np#ADOEaBKwKzwoQ%4NIx0ssv&yqeh$uHn-VciFY21zwqq;S=xDu6r}pQ%eJl6m4!M1o6}e0 z`iA#7=JJxs@&F%C2~%_4l?!g2G7-=DId8FNi@6k5MCVI!)e-Nt45P3|U<+L{f;=}0 z2QP}`i}G#MOiUe1ab~p+y)ngDE?pVaT#6Vmiss{z2iDHgW?fQzs2P6_x&WcAC&&oB znhKGe5&R_vi#)Tlny{2zflfofjr2Tqu8YQnI)m7_U;6_}ag}&>Ca|zgw16}BwKlf2 zS_4^5xv*H)UW0O&&R_bb2(vVgWK+;TZ`-xrx!V((%6ty(3-ai7?`Ntx31s_u{mzdK z;cKNgt=sl{{BDAzO1qbVE*TpX2#J|7MNEk)TnRKYOm*#^mO{iTk`Rr6gvZr>6BU!q zZcaXA1Vxdm!K}cx^;|?I*E;>QrzqH)i9W!PcTl@C9q6X|%DX~t^VN3I6no50Z#E?h`+~!dQVGL!_T}mxL3>g9|z9r9W<8EDI zhY!;z5;B=XKFHrdQB+2XhsmjW%%L?=cudJ*IjV;HVt^A;c`v{;z@r2CQ&H+UTay>o zw~NUZ;LGQ9bYEwLE0~x{s?Bn`wQnO>`YPtLufPr%J)_;>cYlBir+hg+W>crhz>Kos znGzr7I~!=5Ucu^#{BGp!|)Jy{;&Jz6s8@C8E}bmXDtr8YbC_9*3V zJth?^5}#U@gZ9lie;X|6Qj`hYf#zuw0q@s+_NjsnnA=>@p<0N{I(fP>HBy!0Z|%e+ z@e8`jZH}T2C+b|Zzj%2xDX@6b7eBc7*d!RS2o=_6s9XZ@7wqa7=~FDthC83nIkT3( zITq0B7|8XiG@Xo|&Ftyhlr&l%?JfomOOJ;hz{02b-*^kj-El0SBKK^vc=sa}72>zY zPa@Ye0GVBP!2YS+qgQ~w$VbsajQ^2bcAvwkZMof)6Dq%(eDdUX+o#_R^+n1)oQu5} z_PH;&8`=fX{icLL_tEWMGB%BVLB=`5pTdC!y%`??WkOBFZh+FJb+`_uV7zWV)bxg)iqQ1*!;Rz?*l z#O!ori6x6PXm#t5-Uo&B%LtFs5leJe!8O_hmW~oIN=(ABleSa?dg%(W1*BY~84)82VcBNG3iIub9qzzh>3+?!C=2#@DIkpTU!r();=wsaWbMh;R!2lR3%%ofP7pyV;u%fTf82%MzQGdVFKpl6lh!%p;z zk6bC-!qh=l)L1-tAgbczOP-A$w@Jz}y0&wI8rGh%?Vp*0sBJW+nBYw9Y+Q|(!keI= zIBMkjURBDAFi5e{fF9ej-Yt-1_}3m_Q49QNg59d$ynhvFExIGBi_9$o>>A~%D)IH* zs&Ih0XbzvvQ~NldZXJ4C%xgRBrt09lZnC5lf7ctsgoqS`zII1&e4$G`>z`KR-#hmf zU~o1non>Tn`RW^6!r^rC?D;1H4lRR=`|Q!%KijC^awxdRxDiA#F#mg)L{$@zXN;lK z!$5Rv3~b~I7gPkRRSEE48Z*_l|E(vfV@FEg;Q#HEfjA)g6KYiD-sgx2*_9@+vLW>m z{GPQPITG%W0|~NA>;%e8BkWl_MR9m~lRTyt$6&msz&qx$AbSbc=!RFB^5MbaoX+u8 z38QD>L$v6INOa=ISEl_d$BhMWP)oL{0}r=6n9szaw$l3n?N2fQD^k|lU{qTG z!kI~I)dD#DGd@=VIml<}(hd(xp1@1jQi+fITOPIMJhc);{-@7314+KF&fCS%(g9XMPk3YLEy{#0V^u2!@;(?JsrUV7Y?W z7kZ}LQCSy7o#&i9Ox6m2X8a*xx(&&}Vl5lSzL5dCYoshk99h zl5Fm|&X1?`+FdU~C}1#GLlw2>cgmLp+UJQ4GtOK##G)0puQjgg14xq>>IJT3rR8dE z#(`iC^6f?P_jGiNY@Iz1;w@%|VUZnbzn+h00(K9R%#C`HLtt}7)AJMUE)973q>7-K zuUT_uAQbGOp!Fc2ffvId7$q}nXby_HjF*hjt!;Uw1kKD??s)7{RX_?Jxel{fqIk%x zYu;N7Gw)dOt)`rR4i)0+hT>Ne!dePL_Vn zd#L4Z(-_G1vC-eR0^uw)h)o5SV;B-MhehbW8_b^wAz+1yp}*ckKonjxhQd81 zC6ESC<3kFSJiN{sy_r6x!YakuYkRdEtV}%wSMF}Rb!2ePt|7V+7U zcovRofE*T&>!q)3QIq0Gc(J*BMVi?ijHh+SHy)Nb4UVp|#I-vm8hlU*$hVtHRzxSK zDo}jyK!`5S!cD(6fEQJENpC|vhxiGMU+bgrAEO`jxaI>?Twd+rZ{dl4p3)4bz)1m; zErZoA8w-1N18BhZL_vExcl(j4w6A1isS({?!DJppbqc_!BdzIAkrlL|M>j-I@5IBL zjEqAqhHU9JZ*v|^DfBf&t#J^gqF45;3Tg_pG zb@=y>X@_;V{PVYU#JfPBb-GELbHo4?xF$iX$8Ntaxb8Y%?-^ebc1xy6GkY-UGUfl- zI1Mb7yfmrNVdmsEa|OU^G%G?2_%|oQR zfJ*kI2N>zozY@GStT!d}Id0isY&f!;9oPJHW!={$lf;fOA5$jZ<7fy|=WJk=v<+!p zrD?=>0`C*ryr2s?tuelkdD!J5@{}oW4brfbaHh^F628^dsT~lYa)6>Jcf>RV7g6-s zm%lK?XZ$=M1l2ulZ}rp75y1e3=r=2<^#-U*-)gxyqm5P}<*vptP`ea9mve4F`)Oav zVk3!x`Y^@nn94R1Ej(T}9)N#g@TMv>P_^VitHUAbU$)?~nq3jp7N|XhIeNg5 z#Lw(n>jLx4aWUDJUQ+w}u`Xw#%C}WI%F4IeO7ZO;V*S-{QhkFEGn9aavKmQV$z(3d-dvh+*;6Uy0u<~L?j&B*G};JxH~J+c5L6RhY<$i^byN z^@7{yS^d^z6dbfa?>?u?eP8GVv8g=U_^r)5b7%f%ZpG$S#lRGh=8JS-8OR@hPMvcE zRHq^`;9-2^<$c8QzC~Kp^^cRu)a#{70f!c54gXuys^DHeq33rZKQ;;D4pz1iq!*Y; z>TeoZX`5}zF|z60mD`#G@ame=8?4c%%*(@PQHCTW_eeb5T(1Be9?vMMS^XvxM9o^& z3kWTns7l0}xvvNSA~x6`+FBy1pu;3H?yyh?yzl~o#Y|@HX-M=?W!5{Kgpg>EsQtC6 zT&?zJ@`Rym%HgQldVYnrn!~>%%MmlK}2iOCKMe{gVH(UH_X7ARnYBz919KfXLhKVp6wHTpm#~9ItC%GMxM=ti{W^M@a0vb73y<| z|9goZ1mGG6aEZXdi5H=o;df9Gz2mLWxvC=j)J#hyWE=PFiTC`t$D}jKPE+lKpfc1n=$T~ar ztkiOf)XTZF7flHu92gg5T#~wJi4^QOw)_p4Ke*%|#on4hY?^)vri5{E-rQ<~jn8VP za>FJkm@sWRFcz9Qn>V-z&y>$3{s$@Um}9?Ejuc;4YB1p^)ehFLB~ZECTtG%@k9KvwB^6_S-({H2ng2 zy;2f}Z*~zPl|rFGP=kdPw6@+;T4Q(nhAvTSZH3aOgWCgBo$6g>B4TaB6i3AkVhhaf-E_90h5kM)Ql`GMK^uB?7z_o7I?pgw} z1Mcv^sQ{4V+Bv4J*_`$f8OCQ5cXm}l0y4amG2%;+`a4SDXU;XM11JLK*-DoW`z z7XTMGzZ&8tMEAZRSy{Eu#vdN1M`@Xt#hGg}bmk#9gcC;v z0qfAQ7euw_m`VBQnddVlB^3Z>iC+`ljyaAY=n~m)i^j?X1csjTH0v8&V2@PUyndy78=< zBk~}>vh4TBh%geuj(pbl7zs;QJ|CM6R^Q1{2qMQ|H`a@7_o+2dfqWXR`0L9v-5ce7 z$A<363Jjpk6ZawEU1(27T!tC>mAMs0sc0KU3?~Ro{KcLp4n#><@*`$m&lXGZdBC!* z&U|~ra8PJ*`ej@JyuJybeUA7flknJZjK$Q-L$}pNbN_5<+g_?-Yy7N;Jx5F{WNWT! zm#*{NNW-Tyd;J!5{xF6;<3#ip?F@%4{|r2i^&u2aq6=94tMlT-@>)+27w0#aMt@!` z{lId0IDrMu(Go_M@e8jeITMo}VgXt^&A6UvP^^tYC|49~q(vKWf`yJi>4C*1|Dj4~ zc_7EWx1CU5QBdlei-qg;L`K$}%?-XtzbD6mm8&3hFH<`5!ODQe8JZ||zSkjp*JLq> z|N9IIyr6gbJ;G57fjGX1bcV}6QrvD&g?H^0j8Eu+rJmV0Z1YSzE?3``*tr44ax+hr zeJ6-glLdS1z%~d_$KKH;W>$8b->QOr(8fvGmq(t6=;>fn%=~xPIrC=PcHmv0vzNdB z^>dTE;Jp=ARwL6upjM1q%pkjJD)IV0zfzi zBQyxG_9EdQECusdIB`%aU5F{X*Z~d{87YVwNe9;u1X2mGzmSjfI827L>13nf0=Bb6 zCE0;|$LD=O&_cYOI#BQQID-$Dy&BBTv{k4f+R~16af2Q>_R`Zx>vMd1te1b&lysSc z5~!jhE{*UF!Gh`_a`)6kKM-cK+HPdjk<=A;6+s9IYG8$H%Q9edOz^PE9qNa!=$ zoCP%Nd>YG$C{QJyZn01O>iWwlLoscigqw7%#dh zh=vWKmx&NV3zC5i=D=nLvYsW@Axxthh`ajHf@_0Zaz|@v5FR3RPIXKu2`sD}vWzLP zjywa-Jqi#sUW5nskMFxcz4NO0+OaBIrH%=mV5EbN9-Z+5@W3A$l^>N&*%xj zUb-kdm|Bm`2wj6kp9`kkMsC^C_@aP$OKvg3J3N86Kx1YF$XLI2DS`MisL&5@2WqAG zj;WOapEtC6^rx*x~p4mB;Q@e=bQkXYYaP41x(EZ`fHzl5!@y}M8#u^ zkTJ+sI(2nRpL1svtGTh91IYlee&y3WxKhy>;xP+SMt#|R5mCud(3Qm)9hSbo$=F(? zl)s0!Ikp%kUw3oa##GI#$*HA|()dvx&-S#NiJG5Hm_w_zo#GeLzM^Di(PF2BxyH0KG{iOfW?-$JNAr8OinS!;Nhy9I*x5nEE87Uxfi_`BubLQAcyW$VnNBieSV2%2X zZ6HI8Z9}N!v(ntub4&U48GYlr(O9RPP6rRl-b49F`EK~e;QOcZwToO`bB3hpFp zghR{I<+A1o0lF++E*z_(Xq^z$${q6w7Qt}lIlT2UAxKQZYaEd|sVw#3sxjg(oP21A ztW*q9xm8fHY3aHREg?AIQa;jsxHyji)TJ(T^g0Sajd=0}JhB7wZ zkR$Y%ucI$qS`M0yNI8?Y)zdRjo^-r7DXyf6ICDb>XXeF-0&tur2>W&MwsYfeqNSyF zEWE$>PT?fZbGmW>#9j>N5#SQLYm>L=Rd$cw+&)~LCZ266DnfZc)}5{ESPR`bF8Rmz z8VlSBtjv$>$#)^(gtO-Pq9D&Y-3Th!2t=G3N<^^4@CKh(eLQJjhvKru7SQm207gK$ zzr{G?kF=tX@NK+pmVu%Ni1?I(<Ypon-`ivex?+K7;WpIC`+3ujO}#K*`XWynXMNqYy9O6$wS9i{!an@2p$CF!2iCg9GtS;4V#ldJn3y4AFC**%;1=_5L!G8tQV zSfw6$HjEAGWe;>dI3&I3XD&mk-GHTll?LeI`0y}D=2aGsw|}QS)83TU&@Ozb;$!84 zC63W@(Q%7*)H$qYR}^Bh`SRU8qoa+0e)CG>a zx>#p>^wH?ic|r%ZzNEGMcnak-0!k;F=u>Z7y5lE-K+fKX@`h?Yuf4jXP=sEA*`Mng z>|e{NK1!FPq<^^f{*2tFWdOG|C{JEy8p(#b zlZHF!XZhuZskjU%DO4)6mOLC@Vz>wtdzR`X>*dPrV`Q9~L!&1d4Z9akE6Y)r!HkPT zBeNgLZhuS~eFCceb){I7bGzd91xlS}-%nG|8(MyeLkQ{Hy3EdmzBpasg%qBpB~!^N z=0%~$(Ojzo)Dxfl22(7-3eMn>``dc9o;}nqX}-|+=sJJ-zt}b!hIdi!|NTYyf1e

_hkxRS(nziu!H*9TVOnufQ@S7Z7quw(vv$sd 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

MXMN?;BkDyJ2a6AOPq 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≦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ⅆ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%0Dfiea0QA^>{@IB-kvkkaZU^ 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

Gg3Z(6kOw}5IN|U zQJ^ti=V8T~d64~Wo1sSU)TO4%am2-@Bfq$EE|nuWWGL$=EO}VfpBi|t8TU1g6OQb; zn<>~fBWi~nSbGl3R0|F3P6c9C^Dv0uL5-mcsjNlJK8}t-`=>9)po5=tDfq za8z15w{_CpYDtwgN&Ph1IaTte_;YJ(yNBM#qd<^&cHBJ{!x7W3@#CBF?88$_LuUYd zMBG+O+xqeE>{f$)B=9?chFEZT+7D|FbOLC+esT9pG51j_kx%$?m&hy0{X=joa2co} zGQ22@Rd5v_&Tn5D#Y^gd!eQs^Dn`{&KCCIL| zGdkf)sNSYdDUfyV(2#lKIih}3P?)m9*)slmrr66X=L~|ZgLv~Qiw@eD$l@kq?W^e; z4RY+&f{S=k$INs)>v%2Wry)xeZ4AKed6+*NIIK}{<=|$gV%#z1&BTm0h|(}Wy47Qs z0;6`{*uurazG^O*bYds>88nysc=(n+YU!kx5!lvd4Tha_z?DONd!fGNKAf*b%7Y{)8;c@IuLwIwbgXeUlQ8ZmiC7M6GCw1&N#QrlJ}+BqA*EU zYR#c7TwEVk&DCP?f`Z_+j_A+UUyS(xpKZ+msDr-<+!L~&G?cAFO!Hq53Q=ebH@lyv z9aH7x%#paL4f9_%d)9Jb{zcRI7ft>!65=JhBbZgR`Owk)`?l+xum2GT7cM?ZP4C0I# z6<)b=B%M~FrB{QTN!4~`&X;RuOp5k?dks1!wsLRqR(O9aLsnjRT-eU3RhX!4nAuj0 zQ?5L!ZrF0BLwU!=gh>nx>;p#0hq&_Ig4Xs=-evL$y~E-=G@YgacHAo$!Zh zFDBwZQSiJsCI=&;yRkPXM}bfCvsJf2Wta`_8)_#!~o3I-G&hr)7E?ntX| zj=1^X+P{pW5sB103+~5|$;9CH`y)&)&f+Gu`I ztm9mc&q@65L@L8(Ydl8iO)|T=6&a7=Q7L~Vbb0UH)-$c|xIMK3bncc+sE&#HcVZxT z8Tb&lLxHA^;=!Bcai(AO^@CAW+~TEM-?&zpJSlb>o6@ge9AauWHK(i1Xd9fEyEFvF zERN3DX)BJKmtkp_e{q@&!JR4L*#{3CxA;Qhl+##S63H_*r}0HR!_=azBv}c+S2Ke~&#!?-m;Xnn zhSD8l|IsBtI)KHW2j#>6<6oPuLrh6z`AEHTL;7;fK0sU@!>LK5oX5I1#u!pv`3Oa^ zqQsM+Bn*)Bm<^J+p`<{NRQI=g!_E}c(g{IZpBPqDUnA&eXA6ahK}cL2gyx`-D-vQoPrY z#MiHt>U=$@f+_aDG4>WvadgYtFz!xpCpZLmm*5aAgg|g7Bsjro+#SN;gplAt0)gNf zB)D5(aCaM=zj@zt?m6dv|Gn$3ReM*}Q%}|I-8~F5J>9!sXC`rX1f_)Fzsh5XsXSva z3-KsdCS4A&BTx`F$q2!ZgD{zejDJ-INSB=+u{V!cDu^Y21!<;_kY0uwrLE@+bM%EF zWsbZ_kx0ff5$388rcH*_k>xBf=J-OKx_J;h22~>9F%V#;j!)eH_faaikN6+GIM5p% z%JLNVP6rR0E8EKPmYTdc_50$8o_uB^ko1L~8i;pz39_Q1JjJgy@#7Tt#N!6?%iT|-w0Z8h3B&C6*18tCG@JLbtNji@tmd8q8KoaDU zltfQG+}Q8#>K0Ew6gQ>SHCyiw(3C66;p=V8Lp#rHQC5mPOQVF}c5YXT7=NU9h=6^G zpjcsKT?zA)i~4DnOlsLgEH93C_#7X%%U-n$yp)~bSh}h5xj3F9I|!AkfKU#>ahtrs zr~NK{MTSkzF@*QbFGT1adQE=pb&V=8EN~VfKqF6MlnRW#Sk1o3vIL$}{#5V(o-N!N zVLA7z|GT2<@v1PaoN$vqaY*sh3YyJg=5d%`MZ|_WxVZpzk;G!GQMo@N*RJ&f|EhJukp{)nvsLkNjbN$ zmmXD-FOY3ZKgNUAHx zU)#H)Pt*Pm;I=1u`r0|2uV7iP9OH3B_CNp>J+3%YCNL$WS=cw-)7J{`Vr9l^<@lq_ zOf(`SvPTcaj4RFnB#?mw%YP6&L4xjeY{`(!<7i)@MLS*ay`!t~#OpoI8HUV5x=d9s z$vy`NYo&K-zmGsz;jki5{UNguJ)WY>F^K|zYZkP6{Ah9hxUq_O z3*QB_ap?1vSoFprM@DO%?fv5CD<9B#_O~+w9C}CZ9zH8?t^0YuxN_|iz57?%qxVJ>+LwK)PdcG<=%IW)!kr693h5NO3hp94pFz9q&_zS%b0Uk{8?}Ozpy=5DeT`=n(4McOvCR&HFcAz#W=ZAd3*RXV%yPJWT z5YT>rrB|UtZ9vZJT(Zm~KkHsp>XK*2mjem7zMw71w}zNYb`m&@ebu)4Scrl=Xc!y2 zeKRa<$yHA7s6LPG^3MpKuY)a`q!2&SV>rA`Mf{)kUsMRh2$vd?Y6Ko#@t3bwjzhtm z4lu{e7OjPwA4v+#`@c5a`c%(baJ+vt2#zs$=xV~8Y7C^}#_v0($#+6L!bF#|^Imw` z6cH|x?SzDrtC{zK+M_!fd6A4f$OGK=<~%x2M_aT-aC>3@tNT~-f3jNm`H@V>$%DAS z{Qv=zRplTN#<*mfa@dc5UH^{D9eo7n`Wu|96*yO3Fby2O0t>rc4@_eRci+E-so!!R z|0flKWdgqCPJ>i?kUH`%vge=n53uSSSk(fo%EONYB_$7X1gpwb-!U&hM&xSlT1)D@ zq_5ty09KgpaG!|a}MCCWwr@r|* z`VRII7d9l9*<2_JV&n%oI{*~SsP`%H0W-D_iWm3cV{5^4UUjJab6|9ydW19<_Hz0n zpxf!zAlrv*#1>jHSqy>yHdqyPaVMJN=~d$`6-P+Y2~!xpGRXcyHnJsRQtHZ&NG`Ey z?;d3>oxkb(ZD<6`_AIMn5yrJZAd7P*=`n0TNA z%bXjNujmm#t>(5@pAMu2u_zEz>fjjogbtEeK%fK!dLIEy5a0%Z-$&CsTQdO)n7kh0 zxBY*puDM)2(AowT^5FP9!jT64P>~)?-Jv|7bmSbO(>t z0f7fs-V)f+Ek9b19o@>K_1Mv^K3c2auSy2WC=F$QTa_a|gNUGZ8D0ld^kb#lbqrvP z@>a{%43yzL&hrpWkTb6+d&9ve? zZXG$Zg0K!X>`*1_y?irM0&C4g{WKW`Ycmw8^iZ-8%haS#4ArIqDFZ=y+}Kz=>Bxu^ zmc&>I$@<*V8rJP_G9Umvu>z445YYh5ARq|> zcWFZ*LmX|ibbQl+VFOu+^t?Cinu+OTS$48EVMTm$6X|q219dJ22LOZoB-kD1VG^BBM=G#B-ZVk`cL%G zt-wi4m~0#*0N^AZtPXJCNe}$pw45kWKZXH^zi!nK&{udd8H)Pdn92tBa01gs7@t^g zeE9fPD`h0DI8c4FXmF|Gf0gj1fuL5w;D5^gd|Ep+ZIaB*CY79=Pk`V0t?j_XNWuiI zCSL#rDEMuE9WE@{944ThcFm69(fV%&=6Kux3qB%nUKz-UYj)rq3-!4<)K1hQdb<`v z)ztnN^>%eFkfb8%Vx*^CGFX~}M=cVZFk``~uKk879UlJ)$b8W_dh=d_@n;{ zu>BRte+;}Pdy2FGiPf}-9qAy?n^D8tH&lbS+!yVdHqA;=k9~TX5LQs+@Dg%K6yk7dN%H;{3v^Vx^t-f3V*Axzg73& z3T59<*8-Ve0aPF*>~GZ#s$67#l!L#N!U5o?+XMzd7gXJ#$^nZW{-qQS5q0O0`NKd( za>1u0kNff&1^E7t3f`J#TLXe%!W=A+Z4r@t|3-T9JACYg-=`>8fWnQW<}V-Vd_Nj- z^+)<9Iv8Kl4^p_fzaaX-iRQ$A)Y_~zV!MP2K_|xsZkHH?6c8WgpFQ>pRGW*#vQzPRh|=0kokl1Jvx~mqI)*<6f=wIIq3E zT+A7skH56z9iFan*r|SQl)QdM8VKpO#-#?D)E}=1=|h#w`4uBIysWQzeebn$3SRor z`AQ1>(dYEC>y)y5#T#6`{JnclXDOP8PIuaRU{;P59}bZKq$jclFNA{F68p)2yzNj#Crgz z-9B*l?6n2qyEZ7}rR>rneiPB<4bmY}d4Cppa~wjsYC3tQ6=HdGx@hvn^txKM^385g z!O)jGcV!)$vHOOiVm>>-Xlf$8rj_&Ej@q0FM9`gSzrr#yK=o#KrSOq>^+@#gd+b$m z(0+o%Pk#|L-I?|Pz^Eca(?nYsg@l%_k&Cd>?YaqhVCQLI@D_HH|mFMFS*I-af6Xn>C!aZtFFf6k7)%)2%UDuxJK z?H#V)0_Hy!hSj;$C%D1TaQ$|!>$ntQ>Fr{A&bHdHTcq=c0-J{COwI+<^&#$A+wPHb z6&`=v>6=EM%U!L*G+t&l3-L7x-9ef6RtB*S2|pZLPk2_Ro?7pD@(ue8jh`(J94*Gs zIw~XxJuTwr^R?^N0wujt@6oUZF2@FrzLMEn(NC%HO{rA3unk7A4_=q7#n_o-eAMmp zs%YVz*8fQ60Sb}64b`{0_*Fb`S6dtEZHSihPCI`jyZKvm>G>>RBAG($d>8*E_Iwxr z5LaZqOtMdceA4f&1Lg+ce$)?@42o-JdI6sVPo=ZdyeRnC9wqtCmS9iOLP7oCB{?Fa zJLW$mluQ7V?=7+Q1jj&;ewtP_cfPfm!eB>C#(xADJ~QQ^og*$>@iTld$F9!uzXxy3 zU*|5hQ^T%ia+cD25(T@(?&_fnmz0t@fDjm35=P9r#6;;~UFyO`$0FM5GT|k?xMxS{T$D2B-n+8^4Pel8 z=EjlUx5ij1?o_Ljq%-+GRf0r(`;Zh%z{fE? zW1KAi&?^m8+~>XJq12?T{cO;NlH$-x%8OT8LgoTDzTb+N=I}t(=5})kS1=EtaxdJA z1#DkH;nnIMa7-KSJpM(oRhz^T`Dcup_g#YSV8Uavgyjr%X$IZ@mJ0k^d7s`&)(edp zLiynP0C3qG^;`0@llU1th0Ob-@V)$e-G|gJLOp0W79|w7*TgJ%3AcAOX!{1<8C3(O zh)p)N17&X4KF#2=XYmoUlvr4hTGQNxX!ut7%D!*F@_24yobw0gAyLfbPhP4td_m1p zLVk#W6rkKf!Z@+hOoC3?>gK*ohR`EykfUv>9bmz*?>}@e+C8@OO%IJS-_BKM{}RI~ zvh@{334-Bri$AemGIOq-d79?ih{1Df%2Pyi#3hpxqg^P4?@yjo`DpYUbI&mI}~gi*HW;7g%+PK3vR?AEvO5D-?k>Y#`Sk6j zRDwLyFq#WeW*F=xDuwvwRamEW_w_yRv3U4?QSV)RjhG9dIJ-qx#pkcI=SD*yHXYsx zft=q(X74VGKHRdY{u%c0#nSzp`t8yoC{N{5PM1+Kw^g6#Wh8lx0mA{X*>tFREX32{ zelYBAE>6+o^@r)$hvI%?U?e5-roLQ^Uw6g7oGffNOVrljU|3z%;~qyH;+eyFeB}rJ zSPXvc5?6gju-aO5gS zS&ARG_~T}_hJnhgsn_}Z>`XonzbE4qG9J2srpP>h_m&NO@IWQ1xL?0{NY#d~Z-Y1a z^48l@=7RMTw0tHB5hH;(?zdw)8Iu4tW{u?Tc*Nf0JjJpR6=O_RAaz7s zxb90qC3WT|l`;cxY(#|?N`*Q`*ZQN^IvImy%<-_gclx%8L-0{7z7qRCHH2frK}50e zvTJZ5HG6%#y=~wdBC)g`^&!OUs4!B#-Lx!+2_FMMu{a-av*i+@vv+Uc5#D?XRM%Yj&vi#iHMyDPI!SL@u=8u9 z90x~ov)3=R>aILWn+{FQd6alc`@25Ub(a}4oWoC~O@6dH4Z#nSF`>T*qpog{l_d=t zP!UifH6uM+-A9!M&w1>(Tj1uTMP6n6Y%a zk3Y(qv9y$7c~w4eQkTHOR`0uavL$X4x6@I#d{Xsjm8E;Ep9q$J?112w{&(+aQc6cW zTR+PXGpF(daoe4b=v))(Ys>TM+u7Gc2e6V`)!Eo< zxbzpYE>_9R(r%|x9BItBLn{bueyO7M>lHex#B`?7OEF zybDNC@LV@Nhrd~_+(xyWIT~xA|^{Oti`cu9Cr7Hod=c<`|ri575wqW|s(MIQvAUa{wb>+2NNkSaA@3xLP z_;AC@CeigVMbeftR#x=mq>ddD2KVJ>p+u`RM;RSE)x{C%Ku;&NBrr#@*T?g;$t#r< zdH)3BSZUT7b0os5c>KF#$CaSn)5h#vq`35GtYZgLdtl{TXs}0)pYiGpX4Q4j7r~~V zPDdMjmTbTJ(KB5`ezwn}mvZ&}TtN<57tjt^!VU?x*GP0BKBT4mbBUhLaZKE?1KFF$ zFKT6|3V`9IPAm0A3Idm<6*C^4Z(Hg0;bM>UTIt=XM3*c4<%Kb7I!tmI^5Z<{QcJ$| zqRCDKMR7^wr8-m?xhO1?P$a9U}2Ao4>pbU_0q2N*hl{V61%In;x zs$5NMRg#Lo1)JEb{9PLA!57nEp;A!WJi%^ZWZjZ`{ZN!lfl#%!s1>vrZ(o_#S z;clU_akm)Z?y03pyV>rpjq;cx#oalwxzpLGl;)mJH?`7of)}MV3lUBSt#|$}EPzBXq z#VG#v+^VHu*YfTziSmn{?cH6yKHuQg>1i&)4y$@i1`vd*8?AFeTqZAXj1^CuYT+#}$M$}SC)b|Lxg9$X1#GL82F z7Q!QyfL|yBbIqQK2^|q@#zlq6Q#+#fH`5ir*83BYmE5s5>*Gvf*zV_$lioP7wVg<; z*a?%E-s$irE?Wki?=pBSy$d*}=+bi%ZM#;#m>yXve~<6F8WC`wX-WKx4t}>Z#PAmn zJg{5W>lPS{kb0Or5uA@ORgyb{)(LS)*y?eH-^~oUZ3~3o_2_*U_!JSRytzY?s&Cb% zD{*uIxN`ljrU*QoH+Bu@?a~v~RPwYvy)6PI7q~uY?|W@vs|@<`;wr zH#NVvto6jdw+tm8C@Z!Ym2|zU$|;bC4V=H1z>VHW-<|iyrt`KbcibhAsTneaPVs%+ z%BsJAzKJ(0d^*=7$`#$6z8f##!EtR}4&>R}jS9NnrE~f}pB`B6@veWCVOFcccD3|M@ z^NEvYH;mfG1ZQ;LIeY1O^}srFS2|tHVe!J$)0pg5jV)Odx8Hw!f-W0oW;NKJ%rc+u ze6`D+!H*Y&ipe$U*Yx@BDg)V9@|gq8)eXK$M!Zn(SEqQNRW}wzBn~5((tS2-I834k z?=*IhUt!zbE`5Wz&FafhKz&s7!USrLC4NW&A^4k)MrOF-Yxh&S5?qs-J+PtOKSpv? zP@mM063@hA*XCD6d2xplsxdh3zE>iBP6@5BS|#d$+h%ZCE}SbLM?kd#+rAg-GfWsx zNO8%P^tv78ejUPqN0)PGG{zoDK6lmrMrztp7W>%ukRaV1!)z?x&0RnG*)5kXXALLA zcu905`Oej%YFBn%4o%bf$MWR2y_@jNuR{I(o$k<|F-+r)Kw8HprLp1tV9o?;cq1@l z#&L3_v*6vrl>s+55x@nDxi1cy740}hWQ^^6zjSTa99Eh)gqk%_oUjQiPe@0sK-e>) z6ATw`g^@dZ^qw}pn+g(dRZLkUKe;_1v{VTZZ}mwUFmPSw8s0`$#`g0+#O9@u%Z2*r zRKF28yK1(_>dyJCV>##CQN(5UwJ1!w)g$|spZVQ&6w^<87T^qZ+JsRVgWzrvTYYUJ zVGHJvq>M{&cVMTzBJ&yAC||(Ha^_PP(IcG)ZTv-zt-NyWPO$!h^p47?b{cOP=C2SX z9C6gR!_tpWtiR;P%R90JlcdGL#P&Z#9Hg8WS@IZ8RD^XD(If_jqP5nkCy713Tqvw5 zH;@Z~&NF?)0-j$szh4;!D@j_%hfM%??1J1ZD-P8fJvZLN3F~=Zr+Emm{xC9LF6qxwKik=)ZO>4Jau{$?6a8W0%8Pj0xDMijPBXWVFKEH3{!Xi8 z+IZ4x(3_}~2)uEa|1U`ia=%ky3K7yf@Za|r+5#Hj&(G&&I0AmBNY1Y#wo!#Rs}pIC zHov45ce(6~r_az99vaiiA&U69CaL{S7#AuO2z@R00_qnx;PdE3PKIRN~>Xk8pDI42*%$ZJ{ z*X@|Yw96WCoM|(ItN1CGIS_-#|CB?&T`mSH-g!@s0;Jv@*&YoduMFU=3cWGNE28Um z93s>UBW4fOWk^Fg>t)6KfR(RO!00!OlXP2XIj0|IX=-{I2tqEqf`N>ypc~LfV)fx zx*ZniVFa6<>h5@k`-wUsHgkfP^$nKkv6T&9@OvS#2>sH zp~D0-aQm;w(uZg-92c3d(9It<trRQBZ)<(9X|9G(I;FR5m za!;baeP|!#>g%9(d1#+3{o)q9*m{-nQg7r&C^vxs+52Hb2hgs-)V*gr)hjy5Z+Np?|-$&(2`*ssAvS z=~XyqD-d^gW_x~DsGJeN+4@j3)ndPOa-%_zFAIT!%h1ufUEOUeRZ6EydEOu6LhASas&^$WjqBfXnC{URL#ZkR4bbKp@6 zpgYYID_nb$`j(%61#Qi~LEG+A(_u>~U_X!Y`=;e>pkPPk4z`4ukme%H@$Ki5#}pk6 zZ|o4*0t6GgHbjd1}6%DiUYKY5E?gKZlpUijZn& zD-;+jzm0!DR0bXdc_I?dpd#{;R7v*-wL@jGp0ju0jio9S&PW?#n=?HY@K*qi86SDX z^-bA!--$V8a+cR4xIQ$<&su#9L1zfYZa$%mE zj4LrU&lD4F3AHVMJxy0$$R(;t)J!D7oO<;omx`L~&gATTx%bZE5yEXKFO zW&r=ap8WA#Pb3M9lvyAW>US3Z;CVT`w*}se@W2sw@9KY+d$1*SHwvUGKIl{3*+_WB zY+I=3uxEZT5R#r&V%cKT|wJJ%=k-+(eS9uJ3d`d9$B+7^3kv;??4N z;(N7r71ei2l)TAa5SA@&!sFFqe&YM;mv=S!YVN@NvVHGi_3}c`r6g+zSEE3_{_t4FLElfm>~b< zs^?T>2#cEtc(qhzU1mf5_NpF^X5t_2!-2Eh7Ivz8U?&Rdvj+nnU=O>8w^Ev_h)7T1 z;NZ~Utl{Mi>l6UoW_YB(Ow>SJ3WUE+reNGHc>G6{aY+&8g#rg>ObiD{4jGBYC8-k( z#f?P4c?>d8wp$5Oz`=$2L+}G}$su!ND1D# zDyU$tT*fxtc6k3Dq9YTX*0$Pza5P6<9w=%yL^`xsg&02NX}+4eB}9taoc>K#A)z-2 zNU4bWyqosgY`PsWr7B&6CyBa0;)Z*;W}@=oezn^^D{z$DPS_@t#e~#)yf!*rH?uI zcERh24mlT;B`d?WlFR9nV=C%;V}6dRi&oFF;)}~>G0~Wh8)j@ZEYAEI6?Ue_wW@Be z53OijZ0TP?{m-LVA3G9NfdmH^4T)>OWd~g51@Zhg^=Jn$XM1bhBX{0vYq(bRWL%T` zh-R~qW6+ZjFfsJPx5W@mKP)0EDSu%V@nWH7NcbZm+?KNty4x_c{fo>@96m{>SQ;hH zwRJ6OjrXS8LNg?ZB~K-B7VFvYh?C$`Z)JD8cqlRt-VvNu-Zo|6Pif{~Iysu#PI-U~ zFFE`unfYz!DZx|PX?lG+0z7nnrZ-}SS%qE*tV^Y&SEQGWa{-izU#IHHsi;*<*}|2O z(Mf(G_G94d4D#Vyx;Ueuiy4lH&@_p}qz1#OY?>C2cR4%v<0R{=bR-ZpB;bWvH>4*JZ&x^frpY)Z^rC!NfKk*vFu*o_Y@Au(_RewJi(-(35j8NULp5)styIu-^o`h!5P#VM9=-RIU&5E?SVC;gGJM z$70o6iBbG8T&_{})-*V23^_glh+Igp`No{z?xq@2{dKL60nZc$F&|LbT^8 zznDm-q#d6nXxX{Pq&Zkxgkr>qY#2t?NWH8;58;^1zl#a7x$x>Yma!zN1BP>YaEsXR z^Km|+Q?1f>Pp8d~v_Hh~AU6cR6>wCqe+kW`O*Jn}(pmJCb`nqO32P=Zu9IuHkMKNb zJUy)<+uYoA2>*H5J=unOh!!hqxpYG%_X8@{HqK1qK@*hiDG}{4)+KgDx48bI$v7Lj zzyCfK`i+W+dan7~QCKj^C2+oT`__|Ls>}Y^C&Lr__(KN4S>f>MrN-;*`*%2XX?z23 z(Y0#vZpFGRlX(^`g1eG6oC3eK(NJXN_}0NU6(ikzg<2DQFsRt0x6_~8Pd5`WcEPr4 zAVaT{t3tG9A<;Ia{oK^{?6rTj@{IVyL*{cL$v37`KcXD z8z*0P;Q9)sBK;=n1J&;*9u7OTfe9};+U&b#92Lx)b&!uH?Rztu?Chg%wass^V_v1s zRdcJC=cO31+g=}zs8MkJJ{qINu=Q=r4A8gHw&zIB-<~kUx_-*8wxO0hh+aF{N?7B} z@a*!yZO+o9m_-L(hbN57n8uSamsl1T{}#@p-*x!T5b&SxXrxqg1u`>?C^IsoKOXz=5?(zi^w>gMfhAnGeXb*Z)GH2MQca@Ag4+k+| z$(!a9#hX8)c4x7DtJ|Yz>kNi4a!Eb7+?* zyR{90H_x{}G?~br**uVPgzU@ zdSuFIu_rEZ8V_wbjt3+GSKm924_ylJHa1UBOPfvsF~3Gfjzgj2fl5!*UU+5u0y>B=6Fg+C32-fv#G)9fh)Lg533tQjf zX+=+FFrI=HXd@pE?)SVXJdIgk{N1?XE$|Vx64zc3Q_Wbci}K}N`}f!V2}bYF*dk}k zVJ>YiJ5o~HCCFA}c8D5vM4J(xm8Th_H@;5RxnvmN%3@34SAgRZbexRc=q zKXW&&@;sDMzHuyI| z-!Wbqe&NthW40sKNfQ>`<8EoxuLv^ zg~+-bF452(HWXGbM>cMvUTmJ-N&W^?K${HU-6?8W=3zKSXxRvyp!ndH5}xPrUCd5D z67I#u+B<8;U&TVY)!-vcu=T5lLMuG76rQn@(3!AZVB2?J;M+exBia8J3e&oY4$=hr z1=iZ5gNHr4AHtsvd6-bX+cogpc5`H+1lPY9~QTU07UY} zE=u7xs&zXk>TqeGTDH>4UR=@>V0Y?cI1t4PNz7@ukt^qDTipMq92H8x^leX7iiRgV z#Gh)9>QT*0n~0LX)p*yg6FMepiW~F`VOE-XPx1xzOee;6kPF;ifecHMb3Ns`PI^kL z5mUA$0c+H&2#2kp0YI;#>%h$FG32*XEAEE z*`hVgwHmERgYdLx?t3G?RpBnKR;iNWcP*ugkC44sq=kJ;ENp*Qo8$UyK+Dx`2}whU z)*>h%XYSda#8=abRgL%x=v74_cyHaM;}91olse4NASz6j28(Kyi=2rbGZ^jHKuSL?;1hn}#+Ck0k_wQo1#C}{ly+p%$h$H#A zN0$35l-(rNvTk1B!T2k0P!ZA#S^UVE6?R^A3iVXh>*(wK2p<9SVKzsW+lSu_DZgj2 zKIpe;Em@FDb|bJ&|Mn5c_J-2}pdGYyO^giD;cZCE-CDtQ?Qzxo^(3aOp-U=cIxSDx zSMX-u)#oMiB5#H`CKqeEtcXOB+YV~;<}=pf)Q3qu=TOrp%NCZ;=Ii#z03n25S#vzH*16cm~sXR_z;G{|NT@cw8S5lCj& zS)9aRWklgm=y=<-OSHSIB2`9;>#tk#b6TSQ!o=iuheGQ4_D{*yrmYK1-Xjk9wpnho zHwG7|@@iB9Q$EE8;o7jBqqUiYZZ=f)I052e-fX##2rV_{sU^8>5@xf+G928#!&XX> zapx?-Rb;vIqH;^~RG&7d=}`4qU6pY@JK_U$5Ex*ohODF+Jb%%5@1*vPj-VxYd0}O>XIZyz4ec zlh&|}SL3&g22WD~pOC&n!O+9`8_AuUr|?NB>3eEYr}t)`%#e=3CxzvNTZi^FvTJF| zSt3w#>QK8I9Z4Rk8&hlIy<<&0mf-CY=kdT*_SQf*rGwZa=qK4J?wc`c^{CA-=x21k zc%{DE4aeEGP!2_o=6!;fY)6^Tq+cdan>d45?zExu<-%Ft?9_8PZp0T+ptmi{LO4f{ zSZrCTgaNH>0g<)u8WD)Y#hyo0j7(vm7P)#dX8KMwIVnLVGh>3`lpV%U&| zdu=;`lw!d^_UTJ+f^YB(W?C&44g&G8==FQW4Q>be4H1rXGj?TV>aHKeqXs_n_&dJ+ z%sqMmr78Y(=4IqXFSaz0>|*bEhi<=)_zOfXMSQbpt__`Z-QBKxMm%JtO0yU4NVs-r>4WC!NEEs>xb`pno30o6(WL&wd@x?T|Ms9UEKc8kqPQS4 z34fzo7|#~WE_89W^?7vALxX1e1MN$g^f;}$nr1uvYLhE)HgIgaO5oQk`EuxfD=g^h z@R|A!{c)p2!#z$F>7Q_0_0D|ds{*K+{P~8Rjku}Us)32237pbIbdyzv<*xBG_xwIg zefpJ`+MiV(uN#eDXET`N1GvIXZOGh7>Jo4{E|=azp7bZKr7uYc=h(*D^!jeoFKg}| z$Ud%@jP+KRSwBnaDNv3o%6nHVM>S7zW(4Q$Vul_ zo8w2wN%BWH9Okte1;0;KSic~+O$|J!i3YCIVYTe44{y5eI0v5(Jw&m$h1cjMAscd* zvy<;#l)AknemkaCHD*7bJilx0_NM60+Si_0$BHxn8&Iqoo10V|jC1|2F6q|W4&BM3VpfXtze&b+i+*S5-xJ*mTmWRz z!>y^mnjaE>H9sRR6+CbQf6U)qO_sV9>LCHthPnLjP|M5zAeDBv1WMNZBB2kV;k{iK z@EM{GD+96&D|3|TxJ>3c=lGpw5-P=tbi|9avV^0Cdo;AN_*vsJp1?|wpnJ1#yJBb1>C(Huog?P`D#QLM&j7$z$(_9rL?e`6ed+O&!r|36Da5_B z9TD5Uzm_HUi%cp;N<(8c`rbiY(y466H*9*)Ga)`a*lBwIO-Q1NY%QZ0sj!FjISS`A zeJ<-eyOOzY18fTqbTg%;ICBgGRSBffH*14lynb^c!lL?ZWXkVm zkK!Wla&EUp!naH?7Q)lHOV?b9n7pQgC02fM^VLggcqV7PpR5{O4aFV$Lk6{RR5Io= z-%*m0vMQ6jc;01CZlU!?T+{w;>D=z~NgPme(JUtr-pSTCCJjf7$)ybG)UUmTV980o zEM05w$tK}gk9YCspB0;tC>qT67lcZB9=9V>_OnFquo#TK>^Nijz>tbN&euFtL$T1M ztfo^q2O(7L8hG_~Y%{-PjZToxxEe)ffp%cvNn}JCKAr4~G4K)g2rO$Z^2y#K$X|i8 z$Ra(l!D=oKQq3ad&mYml7v5)Zyso>NT`Q2itF7;wo#Hc^Y0~qE{oO5d{$!K-4YW}u zwM158?B?3peTji&-JY5Gt*=qug_j@AU7H4-mn*77`Fp&!pYsfRs8u0h0^j^IP^~3M z6Fn6_n!a1Lu`zT!RLM?54$Wilm=7xlXvetS7Cx+VlrFq|0dentKbrLIeeWlK1x(zt z>W4Sak)wc1+lO86m;65u{PdnC2k*QxAD-b_?-G9Qk0WT67tlW)pmg`4LR-;bt-1^C zO{H8^JhABp9qL8P^EK@~d6=9sscf<>O=I>0+<$%#t5TiY?L|U`gG zC=B8mV*Y5VZdz)f*L8u~mrti)zZmVI@ixp|%+A`@;#Wkn-hD<1V@; z#a+u8?B>n}r7?c>r0xvj-`}_W9IH4)u%cqsejIm<`$HHy4aawXQ{?{qL%G1K;$e`x6)J4h}*5VRWVh1DKDT+XM9Oy;Ec(c&b(3o$Q z#PE?|NahNa@l0?dIh%4l8fj}fsx`(aU_uh-D|NWCwgsXUb6IDS3@fT8@AyqQ4AW_G zgZp891?dvim?Cym1U?ogwQ_8P6ced1OpU~nxsgL^P(D0#H|4CIso$0Ji!rLuS%IdF z8Dn_vGI=j|%qyufJs_II{?ZzqH9W1`^~xqO>WdsV4_{QL`6!0TK3`_svbDxJ>`Dip zdi&jx_m82T;NtHi{tLU@Ep5Wm4Gd`2wKMwT9<#bR!}K*IDF6Z@LHqbD89P+- zm1TzEAKx()Z$A0$Q3ETISLL;|8l6JRDY&kcA=Wa|ZWT&?YV|xe)tv$jCFu*L9iA;+ z_opCsrkF({Cur8Zix}G2I(Un2@U|}Y8;psXEtqdc(xFq8QUO8O#K%9c5~%zeSRIYm z#>XO7be)Y1HL3xw@HOhPS^d$DQm0!qXHRb*ap$$*GaqiM9Ed$i@j`(J8tR~(&4`kE z7bSnDfR_xC%shTY*wZ6TvrW32)4^{){$NtaQ{hxNhVHET+`C78_kN2KZSz`0i#2fe zi-az)kTU;7-sA0SWG$vQ#oiLpHLn-Z*I7h1(eWF_=P#Xr2Pf5!?ZGCJbJVApKYa5F zD~<3M*5r1#Q;yW~#-g+PL%v-&@VK`UIh#{mN`2_#=Hq$rm=KT6`}4g29&QhXZTv%* zG8?+<;a)*n9ED}&C)(nf;W*^+ti~nXK7#z4HX_2f__f-^)C1zMKl`ED1AR^zyf}7d z!iEXOnk4=~z^kx@Cx}Xw(*u4MBz zH|f-FdS}l}qR)Phr)sCheZ~m7CD2akTKnJ=c6J*wf@WPN4u3@6s=T@se#6~h;a45Oh>!Tb zOq4Z+bQ}2DX=PXDuA=wmw`Z7{=+7U%!(ZQh|Mcc#?$s57O%LXS{s1QX2J)M{atP~} ztCvY5y`1yNM&}c;Tc1scP6cMatm7%({_Y(UiLE%9%sRNPj_OLjb?Q!zt9F}c{m*wW zloR!?2y{3&VpcdfTJU!dCp#xD6Udbr9zI~=Wai>(<-+OYHEHn1abA?bA68*H8?IFR zcF(+uOJ<=wxuLMT!FlS#9CDDfu9YZ0y(*hL^I+`)w52msNjZh9eOu%;VkBcCU)I%z z%5TzDm{zUtCv*!2Ir-VT27R zjCg+h3`0(aoH~D!DOx|thGmG4m{C7cp>XrixI;cs^ZRoleuIjqQ7o)1tjgU18u9Sc zmPTJJv2p2NEFPN0_%ss@PPh5~Frxs^ifjC4mD5UHcQKyb-L_#&9-p;nx6+AcR_;T% z97c;BgUeR5|8Drsv>0x%ZyMVcO>d_iutK4n{CtJl8vlD@%z9%&I%R1NQDBOflL7Gom?~qvkkgKS`)ee}O61pJneKuUygCe_=0vOnx zc;&nS+*p7&6dP)DR`@_paj^7UIR!z`XfOW@!zU&R`~2kfh_OG?S3C$fCfX~`YJR9i z_wc2xq@*7S%jBgmpw6L__{5)XyA&tM$5%*-kLW&oguFP(WQfx?Ei}BvkP}~pTh3as z7eH?dLGNg+;I9mvFxDXB`yM7j58#!vmB4l3YPy#)A1?Z@Q{CGW?83i z>$E?vQE{?fG2j4#INE`TN+g+_d`RmWVvG&L;s|ejIHl@u(wcFybY=rRK;_=O!>J-g zB-_9gauwG7s^D$9T!wVL{fxCHqxvs4X}9Dg7tQ`}k}$`_uX9)>WxnPFM}k_OWQp{; zh)cn_8;&EF`&+&|{zBA)UEj{Io$Us(AxI^!4W>MGdC&5CKV}LX9~FwcTILwbPlMl0 zOJAdyiSg2XZc#1%vxSneAAslle975B7la)}y7INk5&cvj72t+brUlGS0?lCyTMS(Yns40gbGJSc571_+fEP+pSN;dK8 z<`3D@cascWke-E5@FvR8Ng^=Z|KRO)FErT^fU8+XFdAa&z2UD=PXM%Aj-f9dCT?%J zRnYY==GLMN&h&nqq3*Kf!7;k(=xc9C-LvS=4mqi=h~eUr%m^X(W9bk)lYsIpInn?4 zz(Tc%lS|J%uv_zn4nz zzFu1SO^uey^8K>MB1V0Y#Jw8I@W{aZwM$c#O_DLiC>iL4=S{>dciw%kWHi=aPrnl1;}x`{I+o4GIx$H_+(|BEI#ccx6}d|$6RH61{w*JjtiKVA@waV(eql_`@7si<{F z#g$yfM*7nj64bf?#<9tw&(X#KX5VZB5C0gTcE_-8I~sNFjK-(Lpc>p!eCG-lks=HukDH5p7~wQ<$PlHj#qR-hIK;6;M6&H&$`q0p4(XQN`%SiiO0Gpx|Ox*rkE z+J}`pAqtnED>)p|pvt~a$Qd0g>u4{S#01#X4>>iL%&WZI%D#GWVT7o~+Ua5adiT0Dd#SSah4WKdCr_23VzTwrMErP*!nq{Y93Xu8MKYW8i!hdp12;p^#@k zNr_LhhscFqCm!nY+G{$4FdI|0fOR;jkWuf{(Z3cYADwaK^G25VqL26F3ESBZ`<@0Y zSedt4{f(%dAS%c%-+IyERz|h49 zz*|o3;A?SexPs2^>2?BTa7}3<%nD4~9cxb40jv*=jn>LwjCjd$a90?P8K;ugP{h)D!S=E>MOvx(Rr#8GKM! zQw~ch-eP_4)-JcCcqpwuk$**Qb$lFT);emD_YuV?Gh2x_#^M5lBUMdNHsA|F#GK02 zMM#y+$LCmvkL?$>mEW_T-W+t$4Tv=Y;*UT$wRH=&C?47Sec;Tnz8#_cO&Hqn^5Vf3 zo_t$7abxzuoyBave|MZ=EeCigRzl%ZB7@JELWx>U-durf{X^8lv_=D!^Z(HeMf&8C z(W_oD+iEhqA9rxwrSYh_j2`~x-C?Ig-boDNu8MTS+p8v&znguzqBt{sz*IWb)7EW) zPWa%EkNW{0je;_3CF}AI>{nk{*lYJG!ZMno`>-OqWvIRUSv2didz?m@E ztE>7ylmPnB(rWT24XZ-I2z1<9t&#<24r0O0o84W(0$2^o!dTCuo|pyB7){Gzy_tK~ zu@R5z9v^&$ibC@-2o&HN7{VLgg6d^o{gb@Fva?D5#(`3qx^l@h6(i`#684&J7OM7i zv$pt-Rgr86n#osG3GuD)&H}ZSg}$!ULje1r7g*l02llOfF$(>nx8E^NfRwN`lf3`0 zyWo({Q@7uLmXXVh0cvEl45b}Jn2e4sL`1-p%@7lk`0GbB@dnp^=AwB)X+0VUadxOf zm`Q>?y0}ZJ^8mnbL!m#x&3IG%??OnYC7Cl{geU`ki3;%>Gj$jUx#=?z*O{RWevjYnz!!1Q= znQ~Jd^d*M9c71b^D-YOF{$O1{o*;m^48ns=BF^eog!`KKZVu|}PjsS!jiksJ7F!h3 zrPr|c<6F)vLzaB+@j!YHs71;x7n#-cY@~rl+mKx1*JvF>GqSzbNp81XkKB$O{i-@) zJ^KeHV+JS5>D@@VFE`nCPI@t+Wmg92Fr!I4`-Kn>4npe#f(TnTOvREjDKY5cKZs>?EwWy$ z4a#f^wi3YSZi=1kPjU_JKjfO%g{9B3@`S(W3-MmN9{D%mk9;WChf*b>E(E1)@FaOH zIveX0ht$4OLq@p?P^+7Ve)(l?sEcIA(scz`Dv?h}kY5y-0Y*8{fIkvNvJ6(S$qb#b zWpH-;^y~xDCT-Adz^Gx9+5(F^&KPzBN zuk+@5st1;Pa(+)|C0MH?_T^h*LJ~Iybv8A0PX_wCNj_ZZ=;Sy>;`}4`86D z%^hffJDeKC0>V@7kDH?3I|Jb;F)>4`I&>p{JMyM?UU%&T@bv?zhTP5@*Q4$mWffhH zpAVO=)X&_zDY*X|vxh0Ims;jE0l_O>5}UaRH&1pfuFaEk*LiyC{!O3XKgd6TD?-EP zgubT)$Aix|jjPM4gI5Q6F6ATi6y^E1ljGCz$3$VyQcLz^9`LkgD03Ke zW^Be>>qVhb5|D~H2QudQ*Q1>o&&z;R`54QwT$N%YXcX1 zjtT&si~M-cuFFi_{@huK6xmyw%e;i2hts72KtS)S=(RCc8<;`1`Hf0A* zU4Y5&rf!aptfhKvOY5MZ?TnZ5%R-Nzq4-zeV0o~(6by==c~JqJ=t!ml>S&UOAMjux zmNZJ>6W3+rUzHM)AXH45O+_HFbiGpxK%AtBk!U_e_N&pou)J4r?QfE-|yQn?PGq87e+^iOG1;1CMG$ zz^_nfoL>G|=>V37vLx}cVK&~_aN*z4oniF^QtAutewQ1HNzXbod=N$YitgX&f z_#j6V_Si2Xw(Xd;>n;lnx+5MUY0kCLGG9K8NR$R&0xd4&s7=YU-isq8s-L|SU;wr= zAINI~)&lKB8B{G=8tQ~R?bR-#)V8W*;K!0Mfc+48;7y*_6&iki1PlU|cCWSY2J>!O zSEjE|;NH){5&aj|R{xQgV8^w%%4ftST>;8B65L5keO6}(B#9P2C7S>V=VqLEYu#h# z;l(ODt?JY=h&sc1w8DHOOO;6l&_r=1Za>^r|59Ds7N-ZH_1Roz7Gtb`&JV0GU|;2| zN`?IRY`{?$tj*nlB1*L(#8IFTn>bYqyip(=iMjkq)B~bZ678R+L0 zmQ#-GQ=*L;~bUgfQv<-S!D$*apq!Xc33?(~todwA>lpJpgV zLcw5&pC>AYNhSKx&aDypIGTfrDo{r&DZSPv!oV#XojL}v5{V_Ly z|HMqtGj#|=#1pv}nv~3-Dl=I|8Odmq?+mM{hbSjaqToQO;CFkiKGn=3hEoUDz3%*0 zeeN1m0&%`tohJwl3#}|Q(ehnXAbi4G+t3>l9|Yrrerc5DCk(YviLH9^AaWA4UkB_}UP!Pu_e;K&;C^F&+Ba+HnjoYWGi@mh#@{?R}YTTn#-JJR7e|bGC_&=hy z5P^V>m@{sSk?=C+juBx2xcaW!ZTH^+;3E8y89CNt3Mz9e53!e2_^oZ%IxgE;*|;zy z&O8!)!NgM1nCibh-LQdRQh6m=96onR`zDR+xBC6Q*LJzoZIdno`<(V(vk!F0VJOtL z(Q0Zn2Cy12HpQ8G3sc4usBhl&0~Xhs%9U~$Df}-iKFp?nrJ%0?j^%>7nUT3L!XdW_ zd-%CI1X<$G5D5YxJ^wsqHx)aglE~=+R7>VAVDGDiy`~ zO>e#O9%Jxcz63x4>34pk0(U3_me+Q=(NAY|zzvMx^Gv4Dnythf(Xs~AMr8vZL7JLH zJT)g47I}M?FctxHLAiX6iPe86oob!Io-iD(XpW*sZUS>vrf8MT0B+3!$ni_|%8y&c zRmm7CX(SUG*y9T#1ej}lbBn5<#-p2(tmT!$SQvZevKS-K zs_ch9kgOPhW0uZnM4q@# zjG@DZTixM`U8o)h$qW$vvmCdpNRdKzCc~`gLu?ITz1VcCD~AC7CcrTI1)GS)*$X77 zC*#V+wne)v(wU-A93ZcmhnIf2I7j`wAGxX+G0nhR2&bg4=>fG1Ts?KC=P-wlM}*)K zbuL;uWS1>f8WDJlEF*KDyM(kluiOC*Wok*?U2K?v4f<5 z9Z?1x5i29m8($T`Ve{t->72r;ZIW<`>|?ZQNt0;L!K~kPj-uzFU72}r@;R*hpn>b5 z8mLtJH^-)EApS4i2OjOSL!D#%B+4cZfmZ5=YZ=Ng2xCi&{-E&!$WA4LigxFe6YisT z_`P6Sn&iLIt@_024%`?P`&{msn&$vzLpe|ALAy;);URm%Ho27_$Cx>Ui=QtArBUU$ z^>$1_$bi=}eEgD?hwvT?#^?i2kC1yT%X02fC#Yl$hh=mqOr zOyKmu2nA{m2Y{X0M*_BpK&NWmLS2CW>-?2DE>LF&v-Vb<&w+v=yy79Y*fTOgoXGE* zlnIIV!54AwiC0%8Q}d^)v>Yr^GbwbYwxMqn8JB2uidI;#`0|zGU{425YW>@w-i7Qy z?3}BSOdUPwms>Onxb?>~()z3QL6>i1C#txx6y?#C6z>>8;0?g9s-XhY*f%E3QqBo6 z^r{P8or1qC-H?hfGH0v7ccy~VLi(m?CMhxRk_K^#SA+t6(Ffqf%Y`W4ns~MjWwb?N zWJ9&^lG?&Tc5Cabov4^AWn#>kp=|A9bcCQy^6ca{$j6qdeqjQylkMr1=zZecvAVh_ zTCFk_3{cTrg8^0y@$WeC&EyK0|0D9!{gOCnWy2J7UB43 zH{o_zQ(ar{oT&i3+ct+$7tGtU`Hhd{OUQLug<2YrG7A{f3g6SZ zBU}(BX5Ht8DKmH*3=^qtUJ}NGxBoF&-WR^t-MESrYpbcX^&50?_+sIx2=MtP^&RcP zFKk~MzyzRzi5aHUnOHlOZ+K<1!mO|!-4epO`~^7T^FL7LJ13^ zq+AG$zjD~7-9#dGu{WYi!hvv`98uD>fY?m+&IU***G|fhptNwktnZPLJz{+mIf=U6 zu+ZkZg;b^O8`)N%&<-rw@A>o4usAe1Jgz{?4&k9((`2JDr|_RBIUmWNpl#;|xpnJZNV@j-j$J;f=!_bIGsIq9F0SF^gyaC<$l)=SR9+;6wc{yZT*?=zp%V*n`#p{cpscE;7%WJr0I zknWhoSne^B>O+JN#cf{9w($`Q(91G0Owu>nb$ALBRJHn!roBWc7)xte*jYXI=~%I=Q&$bTM1y63U=})wq~YDhoVGG zkQoMZR!B_|E+>T>eOYpfNMauBq9ak#K0 zW-ni{%l_;_XRn=Yw}IzzF1Pj!jBS~r5JK)u_p-N{llwFY+&xk$zd&Xh9+2R1wRT>r zDC*s?rID|bMe$>gI#BzV7j;qhh$)`1`6^jzNGw~8G3QA5EbXnJCiiSZcfj?+{ZNiS zI$h9lg9K+CGK=>;ZU@dKnrJ+%wszjtHRgkKMZ6nql+QW>$JJFbZ2RpTh&rcDk}& z>Z5uimB;V`EJ2T!W$@}6{QxpP`2__H=IqIS6$AkuCLQ;3@wbSY_`{?cgl0y{Is{rh z&mv6BZ-#QutPzi@ufPsTO69++D=9{282>u?I|D(8gA%$ltZx~e*L@ZPISj6r7QGRx z+p)j2&$|gN)j;#c(Mp2<4Q17l@ZOc?qyBroJ2Z~yIKjQtT2v05b_IAB%d%5-pyPu+ zQ@pQ&wrbzed{Fm4hBv%I7c=>bM&b5JhR7%FKrBH@4@E=2$Hi8e=ZA~m;{OhEa_qpp z`is1jJ6c}PjInG3stMgceF?2XJjYIX%|3-5e%2!z)AGAM1_o3!C{fJVWrP9jL+iOy zM9t2*$ZGumoOb0IEdfsKun8p}X@n zxZRx#`@G;bXuMp@nTL<7kFfF*4W0c6Z<3JIa@$^qhsGZu1Z%t85uathDy4ue8gp4^I|`!9w5#h69iH*9UY;BJ$3 zgBDmx--tCd5o~mrqx0#G`1P#*Ea~uM=!FKR09xwzU z9c~Y2-8+Pv7Y78Iy|fjZaM~KYdRs9ppJRpLQ`jW57RfQI=WPrXn}CNSPL?QdSnH3$ zmYKc);r7SlY}gMYptg9qQJ?a~@AGgsD((4(3G=?JVU$i>m-l3cp1<~Nh0;xvAX~R7 zr%0N+7c-72;BSy5_!K#leaw(I(@^}^D-$k{mm7;8z;jafq^YeR6fqn# z&@HPsgw+Lz(ga%Np}Ak>x@$R%AT&Ud_+SLb&YNBOPm0Q0`FcQMTkPQco14PZPIl*M zc2yS+w)~+Vt8qH@Qek{-3-%*synzj|2d;q8gq!Uk66e>1@d*(gVC%Uxnzr{$t8^J6#TYgmog%+coag>6<&Pt{ zs*&6*Sq&;OtRw;tLI)&cq5s-`>pz1EBrcd7=Yt~)bUK^M>v`jAk?!6aoov==&DkoG zOl4SG-4(akRI}MKQ{BYPm1t>`b}If?jYhZJz1ZgWy;Y|9ZbOD$-ly~{!ar^epq|9o z_OYSc+EaTe_uHwkbw$#*4B*(3_}z3^^Y(Uc7-qh^#reG#1`|Y_`j;Buor)puqfPa5 z1*u-eV|Yg>cv@Sv6#UDzRj2;KW!Um{Mq zd_q=PsR`0i*d=ku0~y=>6qVJ^h?XWx|j@RG>x zbhGM&ko>XwJe@y8zm0Kv5S0QWP>IfgU6-04Aksx&^jfXc+b-S!XD#a$lNPL3b8ptM*+iQcjaN%XY2wMEj76YHG>#Wjj zZa3GdTN|3$tyNp+-F9h-=xVsGv~)e|JLjP|;%I_>hy8VfZ3)k+lfEA(GWb{Z@L z7v`UQ%Hh96P+EVfTOe-DZW9S6 zu|#D{ZRfJPhFJa5NyC01p-bDk!n+f0Z3_1W?^VzRgwa`_K%wR^6B%tEGh9NSfY?Ey zVizHcL?j`Dy&lyUADyqHXf8~Ie9AF-r$v%92P0ZL{$Bnyz_gCBm95703UKZ(vTg+t z*<2)X0Dm*EU>{S7jbUKBN- z*cWO7T(;3wvB`3@E+O6%>-rgkHp21FnTvboX=cc)SF8dS#J|OgfA)0`?sHP(U93#< z!`v36$g$m+L$z;ZLkwszNzkbT%Y!wRH%IVMb)PIu@9uxaE1+@foB%g*L?jVjQ~btM zx<`{&9>J(S^oHMeNet!d$0Yl0Wc-_M_bw=*5P7!}@M~ln!bOXIqJB_sUoi;m3VF9& zSskX{-m&`f7Ci^_K#?H>b}Po?+G_J;PRsfML-{-b--n|kPNSk;%buYJZ#H+puSsP| zKKJy>3=G#UZcz@DVqDW2_N)Bg1>J6Ua-Zz!GYE zQUx~%r_R5)mk)fSw|OwpEXu0;Juh7mK3lC?$NvWFF%@@ii-6)34d8YI#Jd8FWbvIw zJ#g%=$_OMFIoY|WH1|6TYp9h5gB?P9F&x_$*rTk`)(S#|A`5Uq;t^>UYg_^ovmv9a z|8`ME$38K0gH^W(F(@AzZfPj^x}`gzOM->Od7r2F!Jea@g87R7dPG|#mlP*7$>czW zs|H6AAxtbhQHdzFQ6YfBMKNh)5L)y0${A69KnfF`paD$qmxRZHB}NR5s5;VVc< zrcx^cLnjJj$Rl$ji=eK_b)_1l=3S_YooA7ulwQDTsz?0{4dmyE#=W`L@A-*Ll>0MtEl!tj5?I@ z;Ez4j%KP&!LmS}PFcSYns;ov^`3~lcnVX0?gw`_>3}++%S}9=F*{SG#=#It}%MUIc zH*gxIfGT7#IKM;AIM0ioUnEOMv~iC_&fkZ#f+Hv zK#xi&Q)Ur|h6C~1_KFVif+1(NP~XH82d7Smf*(I6dAyf>Xqv{Idin~A_o(({Y6run z>{8~Nn@`;az`0O<0g-`D>hCfy!iiFug^`jTEbkgJ*|MxWB%|sp|kg{M8C+aiWH8eKRKo|&8jHz%%eDNf4aP%?%{C((d3$}OKI{^4wwV&fCr2!cPBaXuE}4sQ>5 zwOD8DC6pN<7FRCwz)il#pO>?YArdZ~4WClgGP|xcquAY;@-3Q*%4_}E4y9PP8f=3F zVz~&;Zkeryr{Zbi%kTC3{yNZZ*-nL>g>66vK>kYpW||O~kg^pVOyT7YwE!zgC^qd* z*@8g%Cxg&1X+@PGpoX3z_|M_2Qo-26je{alN)Zy`kpvqVo?#D7<1YIUbqF!&8>?g- z_q5RoqmsyYZzb13;8U;iUS5eJGic;qwPZzJufnMcth*2iM`%&e#85yYq%AX_DBGO^ zC}kY?cFWu;ASflXyx{ug@1&DaTvde#BRxZ!@`@0Qb}#SlqS@RgVFMgOc3pwQ6b@67 zNmaAQpm{2YC#EX#-ykIdqbbMGVnj?4TZK)Ja3U5S-Rwyfc%Tg4pA_@>0B_f0$Jgc$ z9|w#Rj}i3-L34Y~FP7g9zs#SD%|A?lKzGmk7=g33DAeg27+gHr_5I92h~{rmm@zDs z%;yNKmQVgGuR|<9uCo218cLJ_hAU=qXp8Q@o2ExA;d|DK83L;c>^cT`h@$s^Dke##MlQ41LGylPa;HjzsOguD= z!1~T%lMA2=v&f(r&lS1iS#aYkvCupqwBxzQS-M%TS#S{sGV?q}&En#a2aNUD zk0v0M0Yr)1{5j3wVFcutachbILVtiuQCy3}S>nY7EsY^gcdOhz>Q{*2IvdNkFNKR? zIdjCH8SXizxV zuoY-(KhnC03CtpO5I6D1h#!dJt12L3APP~CIcix3#$9qK0bta97$gBeTyL8>qJC;A z(BLt8d2D*zV5`wUHB(-gp!|TjGa_!rpd#yLQ?rDnhH z?jGvLGoipORtbbEQ%)cRe;5_(^9OjQ=I>?<=?Bhi7XIcIjg1CYj7~qCq479jF+WR0 zK|3@ZHXK95toQ2UDsu~f$|SfBH!A}18-+q#Uv8>^{j8^gB zb--mU;lDPL{ub#DUf5tRh&#WCZO9vSb@V^r<;X+X-p`@TL*STjNkNYHgu#+nD1PJhrzomizu*IFzhrGVofv41I6%gbpEkLnaHJG=tA`egBj)qob(xL$66D_3?D^Z zG>t$iTh$aWTQkOhAm+}3&Y0rzTo^z?jwu(LYm z;SnROf>h>4IcXgn5)&zNm`pL4v>1~VX(T@S_Wogfp0Nc$b9yerH@knOY9pGS7~Vhy z7`CY-s6Y{t_TqnWdh!XVe@vIN@rWDU&Bxd!atOjt0#+D?RT$TgPY zkJ&Pr1`;NCve2l$CVygK8C&45rs(kBb`X6H*F&S?lV^R_@BnM50SD$d5QdS#zdp_Fq$8`C;eTvs1kmX$`+*}^AAf^hnR96tTx=4~up z8OJI<)~sS#EpRlC;eI40!gJ;nh+-RcwFGEm*m+}s`8O(msmC?E>mkL&k4#fC4yr@} zgmxwq9OVsMOzhD|DZ?v8F9QrGx!3`yP4yIa=RD&WOrlgNJlCSeyVComb)dJL(5S+G zW*NNYP^`{_+NFf@j%CLKQ-f6`JbXC<6@N2Xhy$}&SQ(|w3Ap%d6u*>nf%PK@v)MUM z;&ngZP>VOi<5;U3Du%a@M)^3zT(z9+l*(if*f&LXnHz%At0rx=@>H5%tBu|`@eGqe zTB%>=zOsV9ZoeE#acDI~tWykhYdHxNVwrH0{_&b&6ORWyfXXcIaA{6Tn^i-m6??B^;zwaL&qw zRYrIbb|Fngh7RnR2WdI|oww?t^QL*MWzQ+#;OV|as-DbM`dZsjMp^G9{V_N$J4FaE zKBzzy$-w}Pv#&_hl0@}JuNXVnWt9vpsUwZ&?RBDU61){pT6QwW&XMLYv^>i?tpQSv zP6gpg4G@o!lv9vVZ6p_+3VUP=_c1n+NJf+(xj(~$IZLdBA~ZrcIkW5ncFpW+>~^L) zHPGJTR*{luT5gqDyIEFnuP_|!$;kwicsZu4$lx9g+5^EwCA>T30qdco2SZkuJtceK z0ndK>`~YE8$5hKSX;-m<2MX=~L(t-goc^LZShW9gfOVf5=7&@(%UN^|BA{FzBHPRr(T49M%FvxZ!11 z)X-h{eSl)3gki&85hB%vA*ku_u}lKv9G`$JpO{96Egj-Kn0z>5N*m-M-!Rv*A8Mt5 ztKbSC`S(kBctx2w9#YB|b69FJl?|JeWsEr%ZxK?%(TNV#JKQQ7b`E6UIm^0YO)9j?${TXbHNW z3zj4hdyZ{evLuj>J*~LZU^%j{Md$AFKwCS3p>=2;Xf&r+CM410{LHiV3Sl{fOMKgT zSiFr-egPmq<8EFeWf8C?2KV*j#2K3tr;CZc1T%l@fZ$e!KnA)%4c>I@4k1&tqofr^ z*NEFz%aJ)CHklH9?)0y)R@6&Zqg`(U%t(`l9yh7^$9JSuk3KAav8i~T``fN<*9d%G z!TmM-a;Jmmq#~|^i@^rnMP>p*fG308n^tvg8(8&HqO*+;lnszJe~4eW*xOYm3`{4Y z&~~X58Pm5cfQ)iZwOrKBQ#`FOP$l9Bxg(RkHg940^{yw1k$!4O7DR_dk2;LLw1SD| zDRE+n57r)kHje?anRcQ~WDygeOA4C8L0Hw$53>Ua!*Ys;U_(bmFX)Ad7lzSNEOK9) zGdYZ>rPd$~e)V6ilv9md!!5Vg3kRb)EIxy0&k>S1@B{qHj4_Am01_rcn)!e73v-o~ zLWjj}s>DTNBf~~7xm63^4^}Jj`X#qxios0z|LRWe9DS^qD*5F#W6cAyo3dRn)C43mzwKxOgbU> zM~!M!u%|}4=zwpG%^nH7PvBHKU_YB?zXuU9OEb`+ZQPb{{w4fTL34C}LlgONd7-%; zkXER73>60uly)%RI;ylIg=)y*_t+KM+o`BVScG)+j)&B3mXT>jQCx(VbW_IinHcAG zUE_@A3Q_6eX<5CF0wD7(YLc?KdWAGPM>v~iFjGY0cTVI@8GON77MsnhyqjZKMxwSLkx~m1~$CO-4O(PewZ_f+9O?lFOZwMfsp|>_3H#%LVa>Dt|dEG!x~^KBv<4@ zD8uT=smhZoG6AIY*3Hj<+=ke1yIe^;R8-BY63uTrz$xvY3AR$@gDaPpi&=D*FKo;o zv4C|uGs7f>IzCP@sbA)>AV%mtn3IPD*o5esUAtVeCf**py(X&-@4YM5c=3$r9Bre? z=5_!Uhgg@F+YH;hav0lJXaA0bcv(d&FIRgGU-(s;^f07cOJ_J7!B>q`T*y#L%?w-b zVNQzcsYD3PfXuURnf@eo!j?K$7l$U;GylnsI2z)#>nsBTogz95j-M0){*o7^yrJUe zJGNsM%`LsCE>F8d7Kva@lzP)|~~ z?3uR%zn93VC-m7p*J}R9v?xzXsWnk(TB*edmmr3CDn&54#)J+I$g@gV$d;viAXNMI zP;u7V<|URWf^W$2f}=d3{mG<;0}}yQC4&>akkmNhJuGpJ*&E8gCT*BLrf|ef1=dj zLz1^TG~rDbZbY`6M`98W+$0Y&Ro?&rdih`dmGB7#o{Q+^%FH{CqbTSh_z8^bQNLi^ znbm9@v#>Z*ST2Q-&Jny`ekSu!co|m~M`*@}{}!UU*I;}Xz;t4AzEQl3j7DZNg(|Kg zHP;hPtj?=^1KI)MlqB699mDn?Fdc%+tbBF-H7p{e8>WMjkqCubc z%LBLr0YBkRLZ3wQZGd0?FZTdI;jJF^dyVsJ4)o`2YhgsV=swl{9Y|II^V2L5a^i~e z_j{>%O_6{Sac+D#EXd(d?ZfFDi$=imAT_9C2UK?E6xwM_SR%*-qPgRF9#Q+8uE|-Lsh;;Bp z8yWC&dIwe*7BYFD^NKcGN1y5v&#L_lCJ(PepU`)FkQu9~0oae+Lq8V|En{rUzE5f; zrc^2lX!E38DTQe2CP?>dVz0M1M76BVJgY2&YP66B9ri%9UhCqaaS=mL;!0AxMTAXjie@oqTt?8+cPs@l9rW*aq?ZAyNgkQmt7Faz`EudE&~TzZog%IP@pVS3Z^X1@+UWdRCsW7x zC~t-MP)TBJ?|pjaQw}}Bj$sJ7zTUW0KOS>Sk&NP3um{9v$Q~xuM%mbn;(ztC9H6H; zPO1K}B^Ti-3yQS2M)KLJ+Z72|)93t+{g4PrINp#mD~LwIF2=G9{*nu5n2F!B>$a zL{jad^6@zbQ_Hm);a1YKZB=F;3->dUJ4C2>UfF}S+^a(UDPWDiX_Qd!6RF_&liL^S zAD>yhH-E?TTKO^XGH()McQEj%bQj;vI>;yUen?RPlDtU|4@;DeVcaB~)v-Hn;4?@^ z@b=+5ro%U9Zbb7H>bINq{Vy{U?#N6*qS0r(e!#h5@wfSw7IoqeRf3~k&ffJS+fJ7ROX=5r?j>t5?$RxErXJuN7Fjl}f221$Z^{_&)~ zYPA~b?|A=Jn&kPdi=ujm&?5tlbO4G_!|&h763=r;jYn}$iKc1arwkU)x9jf|An)gj znd)QCK-gH8?^1!^edRV3UdPpT4tr0eu;K(nG_oOBjgfjq_aB^rd;Ojh9AOo5i*K9( zg|1V>c+_zmyndrs3fZv&&qgvlGrOLH!Ap7guY?~UD}=1*a;>ihuXS;B-CN^!sR_d` z>y#?D2{O8m{^|~WFI-Q|gr5k)Z=#v?mJpvc0f4PvB_+mV3Q9N0xplX;4Do{JYo@FX zja28A7{jr}M$qT^|(93uA)-SQJPZsrjP z<5Rt(8ZT}heNSsg-$CHPjUW9JM_j;~MYrehNO>K`t4PLM>-Ug0^WB6%HJHFwqZCr4 z0hXx$Va$!pU2i(H3yyylb+AIfvw0BNdDiGn6x(;T@z^t`XFZgEMm%G@PuC5=kfaUh zz_W+sFR8D<;#N^?rg)Y>H#|VXYfe1M5@Mel zQ@v-zp5F^hNZs{#uTk=bMZn4IHQ+Po9?dF2>OtU>XzQP9-F&p6z0Gr#&4XwC{s30K z!r@WQ5^V15l1?L?Fp86g;gN?1NiV;~MzKr1$6kPk)J8BMk`Fmijk#4=R5t}A>I#cb{ z7X;~Kxr6B|(~=;#HWej5-kJ-VjpXZThi3vkMt?|eT1e}WGNPso-AWq(q^u1PIuNIr z@16DC9Xl%sAIWCzz#?t7*N%?XE~hefPPclAIfB; zcW&zbD-_oFTMid;r-`zzYhJA&+9XqkOKrC z(5D!aD}4?T;q6hHuD>fRYkqkRhkDWY-us(SKuZO!n@O3?{fyUn>5sx?KJp(d{||iu z45lL1yewpW|LY+*!R!<{zo$9Rc4JL5CsU-3P0}G?+lR@FH_ zJ*Ls0#8#({VI+#vG9(YNV$i$5H#f!VR%4h@zTL5qGR0;Mn+u9f3cBedE+SnQvgA+% zQ;uK2l=2>Ab7-yQ)y?k>?IRTGg-#J_SZvs)BZe8pAA&=*H}^v%9eZ7gIyDEr0XNA} z<%jY-+ms$R-Qi_sH>!*~z9DDZV-Xl_)8p;-lPo;a1yd?=5eGXKAadIg9gplFP>=Pw zfQ}Y~sF;SVH_JbEDNU*a6m6zi8OLPvy#o(`+`Pxt2&p#Ru6H+>a^zl>iX+BQ%gVZ6 zV;MA;3UU6op~6bZyT4&fHoMuw{fA(8Uw`lP+6BM;uy_li{hY3lk||{4lH1NIW@>8~ zvP)6Z&a#$NwF9^iU%*^}H>>>{9Hc2>*sctQbhY$t8B&;haQbHkQUAI~)XH_kO5-X6 z4BQchy7#Om1P$Ena-jKc${_;v>V_)4<2Gr$5N{c3=K%#lu|b_e-k3$7#w}R4WOI54 zr>Ic8YbIFMd&-fExxCQrqbi6P#Rq7BfvjsABd_e8?{wNXip`D*HrSmqOf|~ux^`g& ze51=?o6~m-cE4WQMN7woLu^n6YTg{cTpsb|vNm@doGya+Jfa6$zv^1y93OsrDwjOh z@Za{HK+iRaqeek|=6Oz{C*>&-K7u8!J+#oLSkkshwkNm9pBWqBxly;wa6W<=P6OA6 z;%ja$chL`NkxPVIk%`po*jJh0gV^fc0MY9K!B;eP)edq!SJJ_|d``MOJzrFS%L-^` zV}a28Ss=rzSye1F<-hc zpGPq6z}2KLtib1KTfp%-d9<{A6@JS3`qszA(-lFn^l09@FODB+1=0d zFON9Y>oe<@a}Yhw*c3XW9TNDIN}K`L428N$7bk%EK}XVu zLOk7JG{=c++4Tkd(&j|0`o|LG5a$$&CtL1;9Nubh+st$fWLM39fpbE$xe?!4xhAi8 zIKpSs;B#r#6SOKPZjt)gH{bUhT>prtKmPDq-b}4=FZ-$9+|@WUe}Aq{d{;odxo=>@ zZ4G^sL%-U;UhTFw*R?uRQNC3(@7-5Rqo&5KPP1T%QS`qhG;np=TIeyLb-`42a6 zJDR7|cFrgaurO0k<;u0^6xfa?=tXK*3g<7N&(sc5BO6ruI zFS8WQ_GAF~1ZfISffFZnP2-(n&8T8s@ygg=hyQ&Y7Ca-auYP8Yp|G)h-b2PVIrO-A zbHdy0UD*~&QnQyHHlLd{8qvcK5_TIezWDS9I0e4_tGPj@@y1&hNY0C{>#cIF*#c4v z%kg-;7I~E&)x&Ol8~d?aFbSgvV;n!S!l3axLM)YDo95nE2S15#MxbJI#EFET)?9Ob z8HO_V?vVMemo#adK0CZ;>f5U;juUz;&V<}SRS92E`mXiCI$RI4q_J9Z@V*HDZ_o38 zYM!Y8Y$UG#qi5MPq`qzbw+4mQ00JWXKX^ufgQtzXvGqTw*)^WE{TAE9=MPMdSJ-Cv zLq zl#n)lr)!LfkNk>)Gn=|#HsKj3PxvL_w`KobM+ny?ojWOX&$Z(~jGZ@f$174rb=PBP z@AT{xGweRm9x>PFcl*&^$jU3rewa``fks-6nJz~!NmLhT@Zj8{^Q1O`2~Som(4$Fe z0#;8g8t#qavw}6ZbaLs;uUt#-K??+6d%?2!JsatiY;u0n8pCmI+ ziUj^m*`w(AGE#%Ay(0;@l zXE(aD;lvrX(9>&3Z*X=Qxh!2`iwR%nfZ!cwq(IX#ABhQfxg$>3Co$)NsvZT59)Iz4 zyJ-I=rtDFQw!3cV(=AlEZRkx?mmc??W|?=`W}-jBex8?hZB!|e^u$r|&`cII1?UBQ zU>;qmk*}SgcptC|4wp%vaRZ0P3TT{D9TM@ukj*`f*?EIS7b0^qM)pG3O5dvgu&DuL zI%MC_^J_hP^=Qfr`%`Je7KZ_mE_$)2n&=I~D&Q-Qs;U2dypIRt`$&pqHBdzOBN9Tk zAo2MVnUoHb=}-A|Q|NsioR;$Qyz~8hbe4wQKaS2K91vyTv&v1B$ictk+7Acpcgdr( zxxbJ7!Z<{tyd|Eh|yw6;XM0xEZTgBXoGks_fS z{SwpoS`R&S!N?m%2viA+({`Ux0s3I7IGYdb=!@2dlO;zATJYfaESh`9B05qmztA62j1rZv&k2& z21tSu93|FOWN+-@pR>9z$cHIH5w*`B_AU%Lguw_j1V;aXp!7s1X|{l?c)C`a>R&Cz zR-8z&`FNl$*u;kOC|ZWbL^U!BS>~dAaasa{f;QXLx?rYmYDwyuu6DPo0Ezv6`SxMj z&Vk(p@;|JnI*ounL0s!9>d0^iQ{u*skAJm0_{SZ%>q>62Yy#+uaOpdrv}z1@mU3fh zQP*EF^qW%#u`7>i8L^0vWWOXC-`UmynZHYwSyCn7hI6XzOISK z>4;Q?3ltuc$oodQjM4xQxNZlqZ-U-V=5N7F76X>+)+Oi=^Cmb zl^U)1sm75ix`(u>e;n9fcpbYs1A}p&nbl_h|9XgrFS8$uP#0X=ZC!D6(x1@)kuvqd zABdRllEYfqYq#}%vB8aj3)8l?el?SWD<+gB#g&67#x+9(cQbg1eh60At{BJAd zNF2TG^6H5h5N0tCA-r=9E1bPX9_z6jK-P7`YVtwntv{3;BOcxLX-z}Q@9=kFdQ{cl z*+BqZ?^_NrKTOggmQwKJ(!^t}cTk^K9!o)FAzKQP1iLO!7Sv9RI~l#I3I;MVa?u zoC)rOzUT~7f0lLhg0J!}wM;$u;XaggGf}uDB_O+^kxZt<&F;1V^l~bbIV(1aXbMz` zaEndMZD2wq<2VxFd_gK8xRwq7+H9v5y2wcvL8UgG9P(w(+L43an&}s{%Hgsh{1L#8 zaoM5=h)qCS@VW5<5kkoRng-z?2qr=p`GKs`42D~1HDZ`rD;{i%?>+4!VIoVn;7iq( zeQ@9Ji$Qrg^MUY}OG3vdaBt@s=X>huRor_rg?F5rFuc9U5E|KsjIGQ%(?FJQaFn(j zdV^{WQgh-4v1#ihj_F0Nn9OPa2y?)s**&j3o7L)ZESWR=H-K4ydlZu)=22=9o2;;2 zsJAA|7G8klOagvmLq&j5g}!cn=c|e3sb(y0TYvCI~MTDh#p zm(3A|-L}>T#1cfxxyeGZZtaClp&!(X(a-lGC4XaF2IqJBepNO^tCD2=;+l}JNE-W* zT#u!>M3)A9H=eHh56vbgY6c*z2vcwCp?x=vh;kJaO3@0iS_}blpx##1nilodvX#TU zKyQm(+w(C!`a^5Ic!b$@ejCTd!sF(DW+ugQj0nGaiQdYr?>Evj*?)WCOp)`8%XC*3b^uay zVvud-9@K)!XtUS28wF@vTJwspVP#~*(%7$wZh0K;p5|rIchczR0IKy_;?(ggkAvF9v2v`CXe$0t|D2w4-#Wbu8U3U6tx&b zbzJOBB0;CA&#xM@mftnYMjt00NlaKgfiuOO>1+tmC%;TFXY1+2WPS_0J&Ej zAC5u2YUbt@F#hcK3KlCBx|x)F;snx60eKw6BGSv2Lo*@oUs3D7XvX9%uwuP+FokIY zvudr(O&m5$B8-tBl*~O=J*%y6jk~*#;&96jVT@02gJ8J{Ysrl&_8vTb16Mt)C9<~Kc-*L)wG zov>%n`1kx8mn``xr-otctC>z@mzX>qY?F(ghw#2*4yd5x`_Q{w$Sx`G+FZJCfl$#J zww8iXzI;i9^y|OBLzq3KBqQ*3D?aWaC)k?wWM$pqd@p1F1iP6jgVd@KDw$D>hhzdz z*>#)YY9g**At#_NvjeyxV6 zneD&A1Q>&MR|$3$S7I|gy=OAcD3n?&KzQnb?i~A#r~ncX+44F$3i|JLyXQTexrRvj zOJGDkypX7B2?I&+2pxt9h4nRX6p41#aA<}9rYQoWO^pgR96UQjMF|>Xe+G@5>`ng- z?-;2eHibeFl|+iLz*fl%zq}>(2qpSE2Ml*V3Lui~atsReZ7%(DteLJfK2v`$(7eJK_Zwus$Ki4zHnEp|i(ToRwCy;SwzOb;KxIfGi?k5Jl`Y+8*OEvXwTG+35;)Bd?u;LW~3;Pjz~Nj#RJ63uhL5 zuua0ND5mGwok=qwwLBSuV-Lqm*j_n@j;^Z~DnJs<@bWR9=LzpQ6Nh~L7-v=qY~tT!0U%VA(4?ctj1d+drJScQE+lvYC6ZAs#4e!h zfrL|iNt?w3*QfprzZ)*z?RIm*gz_7xLbhI;y0N86%X_46m7b3+l%c|y$a8% z_ML3|$L8%NP~{3VZ(eb?`RDZh(o@DE?{cd<#m9W@ z)Ldz#WEkrr+cCh!g>UKab5; zo0|xkGHtTL6&rh^EHGk&KMP27UVBV*{3h7lk`s6;=bEDu1nQPC zxn+qWze>&PFusHCcNJ1*LT8c^pbv^;KR1$+Z;T>Nj`z<9uFM?qY(^J>`DMqbZcl@a zr6aOd?~3?e`P!Q3nJC_it2@QR*3Z+!E7MaYT#fb?8BrZtz>3q_{u>?$y)WMA}VbJh3$sf2a*A=5Zo!e%toYHsp z7m0)^*@+MCY|6kS6YM~il2VtIV*5{JEWGJaKZyT-4)C42aQNq+_md442#ECmvCUK8 z43SV$=~rJtsOD^Feyg<{3ItTZH41Q83?9ziHRC}6H1G#C-cTTc@i9g%Oy>zI zc&(3s-T%rftL?n%L>{9yR~e>Xg`A&zpYH}dbK=LOMKXh!xHoQlO%Oz+4v1JYl1v%PDgX zBhr8UZ*ur`l3Ml0IvKIaEyJhCACc80p5I132Qb7u5f46Ml`ADV5zI=by)xCe^gePt z&M8yLCdNGbvbybBCPrwG*pH71Q3?Vgm9QeNrxLcR;;fC=emfor3<|kD3hwje@NS53 z+aBC~i6UITL4@86QP}ddAI+vRq=F%Ya;w)iUH>{6O2bo`U}9MKqChb!)$2BRjY9XW z1R$GAHyMl0b}OZM)ZKAmfpe#;yS;IH7CV|nh#a;mG; zjCJ|=c>6eJ8Y=Efz)_Jf#FmCrJGMEagRRf%Oe?wjpxvSf&*$nI{+OfRI`ppd9~NOJ zJ8iNgkEG|kA;Vb|1sbJls*Ea^`)>wp5rF11YPbZ=S;}-;{~BlmEA~;%Shk|t_jUMv zmG1&%619mZ9qdH`&uO8f;KQJ)^isaOh7j;nrsQ%a zFVjCnH7@W?MApcyB$YfzI7ysYl;oDOZLsObpMa?5Md$m%fb^&-3CL%1iydZuazF;k z)xvRPO*ewiU++Xj5X-s{U@ix@w6yqUI~@n>dIMP_45ZnEt40(iMwYaC35bUCwdK63 zsN3G$1w6t7=Wky>at)p07{znWAnFlG*gf~R9padKsD%kOS4OT&N~1Ie52>Q%H|s(M zgP3~F7~1KUa^`Zj8*fLnHP>#7hD09hZ!e^#`uA-OYM8uZzJIh~ITdxs&=7-qNA@RQ2j- z*%DE663}Y&K-*@(Bpxa~Bks=V`8X6@%ML}S6QB(bB=T%2*@Wa#e`L^zQOxmX8p4 z!4=@_U}|h>W@+l={J)b$-fw5zQM=yDS`KAqbW3IRb;nZW6_pE;nM!U?H?o(=(!#Q% z_|_ykz8yw)@$snRuWRtST|)P-y6vOq5dJmd_Au}|AdE=xzQeO;S2giS8gt~Y+?qt5 ziAGLps}!+IVpG*6oyIc5<%XCE@NUlzDZt6yuDj0~!$-WTs~U#*=zQUu4Hl`W)L@U- zb2J{Rcr8{TVz2klb0cPLPB=8|M-|m%=pY0fRSVT+6=fxSpLUWe3w>&37AuXEW}=BF zKH;-hcOeHv)J0TbDIk#4WIVuN}T{5TmV$e3vp5qy%#sq@cQzTZFEYh{HX3d0nltfgKO%inQ zqVUiAx((g$l>erz=1KEco)Ml>qh@~;%EYQ<4tXOU#@=R?gi{}0&LQEPe&3+slUJh= zKiS>rF3eEGVE8ILgVI1cxu~XzGl1wroeg>EuOotOAZwsV_nkO^T1^rhUblN`JcmX9Ztb>D_&6E7fN^q4jBJ%a@4sY9$+)s4^QX? z#t~>plrNfcP#Yeww+bULFRXwA_Ji4^?Z3TO?Wdkft2q%b0GS6?Z#7j@(zV!)u;1S} z6N@psT1{k9*};@b2-Y&nLV)Km3ImlS3vpUuc_3S~UE>K(PdP0r(1J*;9(mi3K_^sL zT4v7UqqD8pM|anhePYRI>a#0&@Jyec$Tz71R2NX@U#rxha@mWKxHOKKf4`jj5xN!P z35YoJiY^1Ce2O}8JfAQaGRAFS+ETf({WnAMy&oU7cL4$>Oy!Ra<$!*j=)xZXpC*}% z_h*vwnxWHf=(|F8Jcoy0W7Xumi0ROsc>liD?~G&E1aObSaImTzOoO~WGtmdmh9@tC zcAwBQ3J)W(A@214((x`}tC~rb+33U|lV-WvpPvAO)h5_}qAedPwZV%xM>X$+gH6kv zZc|0h&-CfcG&ec$3P2Ctswd8L8u(G@xU6zN&|}QsVGJSeIhX9ERWe1*c^A}Vkv9pK zpbo*W>pW9^lQnvfWJ47YS0WEQB*Rb)cU&uuP|^@Hj0=o1N{~n(^`?d+kF6Ah2^g$g zWPeo}qh9|*Vi#onKMbeiN(V1EK*@Mayuu%VX@Nh9m0+}t3bL%rO z8j(?%G1Lryz-9e$W79C*Sv9e(Wg+2W*fnoVRZ@Ml>0ptZ`A%NAGWDqq%H*`)%qs8* zWSGDN>3`I_U3o)Wup&pHsZKb1=cA zSd--uIJw8E<{l^&95}SeN?C=6t$@gLTgqm0ryXPsqT8$oiJt@(iX@W=;Ek>u_XtyP z7c#L5AWlIX_zfVQ!=6OE2e{Lc4h(?&PSCx>egHrMApZFu?81{`1t z08#*8i1eFn@)4-6sc8RJ;H0QmN-o(&=;*;lfWwa20ig))*b{FEULC%KxIgII|I&_S z6Ckq7|Hvqr2zx>PB z)FmT$F4XS}Nciexg9nC|1rDMjr8?`w@-KD(PZwVm(xgGD!qK&?2Bm^zv> zLcT)iXCyYLT3*FG42KOc^ACT`_WR<{Ue&}7GhQ?iy>8c)k4ZHg~0;GBi(^K~7?qVm=bG8%w1!2dr7@2>DUm7h4oDOA~VsqyeJKDv~`NayMpmkvqU$nNiyZzwUSQ z+g~*qhzOxF(u5^mNPbr84W4&}nRfoJRKd3h#i@TbN6l~jr#h{O_zo;W0pm8K$~g9BJNgpQudokKqaX}k~WXQq?l8N!kG_5lG7=h;#Wr zh0Ynern0nCjzAfCsBr7cC~Q4->mSoCnu?Pv*nJo7%sPlP7X?4KhI@%;0WMaGorx4g zf`*PeH7&Xku4x@^f;Nha0ROYwqMXjNQ}IhPtoCcJ_57qy>N#Zxb5RC~>q8fZBLq

6Oznh}dY(Ts=Ti`|_H&G*ya^?1ExYdoQUQ#a3Bm^&1^-;qbl#Z$ zVpfv(EbaNrg2O$du{Tswwsx+HMq;a`>70Ee%5hK;gISJBRA zGjj(^%`BFIy}ph5H^c)}@I1)--$jqF{OB;>xl?jquKmOFoZ+@+Q_e-hh6>1qm7r-7 zG)oVp2oxTq*|S4}zVG{WME!1`XE+}XkH;^1dcB{!tIN{boO?z)nnHs6NIik`Zn4)^ zM|-sAryXmVIow5efJxC*?Ct!hK`hyhy8KyX*77r03}XoYUKWJT{ITXT(@8k^px1`) z+DM8)Wn<&p&0su?njD#CJnO{?uq;}LPQah;9Xm&LdXFzWA~Tm)_>$eWBIMUjzo#^_ z=AkpzUS6TdOMN2j)xX3MV!-J5G69Q`;P6r333vUIBz2u|0C~0g$PmfOAQ=c;s7YtX z%3{iayK*>aGH00oEGWDl$1yOvOhPcB9!`LQ$;iA+=LjiOT0uoL8tkOtK&KgF14iAq z;FCrhr|(LMYX&~Gegjv@?%T03*r8NX8x;8?HSwlVJQHx&>UG}PcjZRVo?_Z-Mj~Bv z7EgVHtF8mv0Pm%>S)U$5>%ED3Pavy}xA(W+%aGV*LzubQu+EKo$5(-N$PC`V!nrFt zEWR>fdw%jbp*uuk_u9{pgD?G5LKm^D4xBN1tQ1Z=vRR(aYg8i5!ik=>EG;AHs8n@a zYHaKzVvXhn4{&g7;gP}8rze7&QPe9M@{`)6(6D(;fD&)008eNK;78Kl7RaMeEGv>y zS=ON=x&gGaFKd7Pi6uO-ui6T0&%QL>X`1&s=DST0I+!Oiu``! z5^LodfQ!po?m_|!O$Xa0&@fS{=DM#t zUwuQ}n&C-w@J)6$3R=cwPj}r~2>#E8A@1p2HhpL*>Q06;oro>S1zkL64K1n3tM`Mk z;Q{r8WDzdBU!?7}$|1IF2`ikV2k>bW>RKQJV9c&B<5)9(K*_*=A!eG2m!%&^#mzz^ zlCiK3%1-Xgy=qj>_TU?hCsxoXO&hgS=~O=% zz=(mHtJVYpKEgj;e{3Q?^vOrT>8xQ$ds`jd+bGBL+*H{s%WiYF$5b%;7Jdz8!3K^t!18rhR z*fe@;`5YyG=W>|gKcl;XGv)t}!eO|#9w>SXo$Jh$pOrig_Cu9GnkmEgv|GudC~(Lt z^JeIp>*h&ELa3Vuva#a* zyZ;@g*VV@$yx3ctT+5rPt_n5BG0l70RKa=v{%6w{x#zfWu?QhBd$T)lBy*g@J(y>A z&r{H|_d-*)9s;Q%vCef6Op0b)4fUK&*3VRx^G3U8)&6iNPk4dVmVm1SAmL610jt1K zGRtW|f6^D+q_1|HsoUVnZ<|u%xRubJnU@|=Bo70ji*9;MX=1S`wBN`VdlvaNr9to@ zEhF#^R21h0;_$44H>wB~DomQ&Tbd7en~%2Y1lyqCI&O9}?OvC)wAMJ2RRb!9!qxdMvSwp3JjE?gZBm^)*CH zYvR+;O)MWnIt#o1eLi7>N?>??4kdzpp(w(KrBPXqcl-~DLF3HR;3XMF| z2?1h?K6N^C&HR?{N5*WSe-2A;ax)#^!>fO01U5f3{sDIgBnI8nw|fV;-yO{JXct%5 zQ{k>X)_n=dy&blkk7+Aux;-=C!U=sS;QfHgGM&MC*4_YSl-5cfI>FR|D3GM2OSOn# zCxdk_y9JC44mMDHfc;Q(O?=8<&h$6D6_#+D=Yc45ILqK37`A$HW&GvKVPbFcM8&8? zlHQ9Ejba}3UmdfVlT35hMfKuD#+)hp+WQ4N5J>s1tAn{P95MK?)zGka$e_r1N<6-% zB%C!~S>?k4-h}4NF~KjaE;JqLy*38|-6leRO9;pk(P`RZ!0>0Y;BK59-4f^@BAZyk zLyt(rl|i|fKB7GBCQ3lCRyXnk2`a?H16Af9dx}$CM_Dpbjed5IqQ!A;2;pgC6c15V zIvoQuqky>oa-@)_%oo_LQG@2PdANPrNs}R>1lKkj-FbR|*gUcP#6F^=`ICia5s5`G z=y^=c;A*0o06pr#k_CTW&YtE?Av@?oYZW9_@R$asj@QXDNYP3l@?|DVPR~mOz=d~fVl{q@%ki!E&bIW2*z}KVaV={8TpnBR14f4mK>yw`MyF zjPH^I2*7QiMUXIUVoEuX8(BZl{f+qT9uuE?d*zM12ui8x(eifesfL4v23%s9QO6vY z|2FlYbK3)wl8_?`!+6BG;jhBJh1F;%ijJiH_m(ufwXr%hAEf<_kyb$rp(IUizq>Ms z21mOH;l4%Jn-!X`IXc9h5&jLjvCsbSdZgt zsyY&`H;-o~f_4(OYqWZz_>dCPgvu>_t$A%eQP*|Is5&>~ncQ7?i0OrmUyp{NAq}8VVGpWhbGbM*G!{cVs<(iTd&-&X zp2$ta+9vW7gnd&go~)ZOT;}Lut3z>0`2f1@{O`nm6b}k;9#jFefwhN8+gbO_?GhUC z`q}g9ppo4#juJQSFWEJ$!QA6kye&~ppW_-Eu(;XZwCWn~E*yO)w2V-sWf)__s_SuK z8VexC<=p6n5gKxld$Ur~;J&;HLARi+ugzbZLPW$|XWk!`Hgv`2yHC{~mk4*I>41bv z(zb_Jqw<+wpp*%UsV$=lIIR5AmwHtQ3cKc+=H&*PWz8t%km%(Q56D~79u+&d0tVa#|tVd+LV#)XL$@>8W* z&?fC)b6uz@*PKh!byhB*jj%ieuY+Cd%4Ow=yAxz{BVqw4twTOLs}GK@oNzBA(}UA@ z38Fxi9d z2K|+8tDAdV1(KOIEZ$c-v2Jax{uMuYz3LnId~r{r&C-`zxBYQ?2F*vHrdHmKq%r~+EfJ)I7;{yBPT9+{I!&GXQ+D9wLlPCwyku=YtivJ+=)7H(Ux1}A-U)eQpli{ zf&bXEg|PtKn&~J3)ka7U1ptp+23VaobF6jK3RJD6inwN@HL<_wl)Y+=LO^)VEjY4- z{Ct@aYKRD0!pQyA9=j}a%6_htx(P3ENTf?zOR{-q+aTjXTp8%^T zvW>Td%LX*v+%=5Of%7`F)AD&z&6iCv8W_H2#A1SjD|JY|AP7xPU9myKaX z)pxtS{!F?!DJKVDJpitD9;~ZB&{)6Ba2tm^ec2Gsongq+>`^&m^>;t_<9lBYa6)MP z=3#Rt4`s}=H$n>at17^MZ4+;qk`sMtf#sLZz3_C;=3!-ca?nio(da!&i|nf+Cz({* zf-tv*V4oag5uNio#kr(sw4J&<^;$EjYG(b(8koq1NIgA@kpOxVX{w^erhVmHFxD`J zKBVgKp=u}Tv^J{ky6iRVtr!X@^q4n6)x+GQYRUg$+uA9+Ory9Fawb1Ypxyu{q`&$l zG|Q1c%w`f``J7jo`Al>_D_&yR)isZ6irfm0n4LI^$`_^E8Sew8B;L zNVC7=!89>&{s9bLg>2o55f{2*aJf-r;+%YVp_qwe4ru+%+GQQO^bTboVO-9h*6ABA zG(lqxd#bWwAr1`DMA%k=esfx&<4wCx#DRLrs*%ZHCJ6dJ4 zIZTqIj3?n%#0N0L)u<6!o!w94E=~`&tPzRl z{62~J=l@HyQF9zotW=erKMJ;`dVh~4nj?^NpH=<Fh~k|=FS z@3&x_LDrKRBnQj>KtwO<$KMzNtHnpmMFscEDySJt5ab?V2dBk4lB5bf-Hdiu8Xfg0 zg<2)+DgwmOHdBiu&1I0#EuF!J1%kcqA8T48T^R{wtE(0$u{NXO7D_KU8%u~aUR*lt zX@B(Vaa!i$&G2>`&bh4^S)#~<@s>p@68LNUf5@!IraQ=IMDgO5aJ~xNQM=H6oO!5paI@t)~oCtQcJ#rrT5BVHZV^z2Qs6* zZpU#b-p@wZQBANd{=2{6!Xatt1te;kMda<)q(`WLM~IaiJTH!is#IdMH1tZ=oWvBF zxA&OfIhV!!vfb2y=CO*6xMz!ScQN9{s9GI;7AtYeojE~>lB$MxfhN6V@b;Rj2*Z{r zXaHvieUStr`+DbDcc~-cO*enIywL$QAH&;RB2Vi-<2i9VC7J{qNcR5p5NpqvTqbN_aZV&5Rp_UAk6W6#7Z6HI zDHg;SZw>+a(|6X~I2Z(h@Gu^*>-U3hjc_B7JN6Sg!68ND1PZ8$(0-qW-~&NCRVx{H z@#6a-=F60u|La-37q6sQSg>DN8v44o8}>vK;yNYw!+W2DD%YiEb@e%H*Ai?z&yDhpvKUUmh?QHjA&f^q9PT zSU2pqH!+|5I1Mhn`I7#r;&3?`wC3LQ7E^!UyD?`g{OyCEV+r_l7s!-jCFw{s`Iw^; z?maMzQ0Ffwf(qUI!THuu+k+IjGhMZ~z!nb4Xs7`>Nk=$0w=hGO-Vys}vQ7#jp0;E9 z$QS&>51!3>r4kjbJg1BY0YhA7CJKbiZpLGahD&gm^DtY%C-ypQUx|)^HY#FS~JEXlPS~S8{{xVARX|D+xU}i7Kg>01I85%-F^j~iQ3qz|9NPRwYr*L3J zq4?GN;vK`=F*SZ3o>!8a7vQ4KVCjbdeiG+6ySPNw;cg3_(AcWC7mpKU#4&Bvsd9vS zDG~zgZx~G(buWSePM<;3Ztx6sH9OP^9?e?#OEcd5Hwqk zrliPO4K*f%+QO*(j;mBLy!Q3fR7ULa`1S2AioM(}lqJ*MxL)f$6j)naLf~Yhq$G6Rxi&XDF5QS;WvzZPDO`;Xw?<3&)pUSs}&L-$;eN_{rt|! z1aKnf!neNizyxkA{FI@4mBBC6jT#%Vs)?5@F%%I5U)Q)+Z2=m$5yA{W{HK>}8;!G- zZ&ZM0zBrPSPqIif^dS4U#XvKW>rm#1a-vKfXj`e<-;;iDiJ;!4c&*WWn{> z8SUOo5FfF!)*)^S<_#O%Mh^X7SR0h1S;=n|joVJDeNCrEUoNQ%qr;is`v_5p6k(VwDjJh%V5V2i;?XXlcyAhdQBZ9hcgVM=ErQ?_1Wjo3S zyN3&H4?iR7e6Bur*Ls#Jl~*Lj>u(1I6>U@x^& z>IIAMygNJ;rWNmt!F}7T%vz1s&92IBF1k7!p2;7rSCz^v=4*4E7xxI;frSI(p|w<0 zFpN2XR39E9mAlONM%zoGS0*FhVCo_xlGQJ5rrIM&xb|tQ{RgNzm0Kd_@X|@$G4c(* zu+@gSWdp#bpJuBuEO18_N^5I6`0gK=En!E^uU+AqWpc!S>FQRqy1ts>o^o>qTQw?v z1!}w+m;^htta^6)^IuLm{$^{xES znhMtrn{QH(2tA@yNe<@}AhP6tu7Ye@xZy`RUIt()YNk*4Q0+VR%efSEmERP=R|07U z_1c8n=Bsm~kJ?zLi^b=77$;{)BwsS0Z+3=UJaxm%o?Fih6TkwVsezTR><}xV^ zE##jo`Ww&HaK$FKj77#5^kbv&X+H<`g*~17FroJ|*^i z6#AIHNL0m$LH|^eGz5IIx{6S4unPBU+!|nWaoxmRPl8|%zx#j(ep=-`X+i*bf^0}l z%KY8u!p1cj?bbm8HMGS2s2!M28@KGqe=bIn$T8_b_uhV{!IB0w{oWhct zx)giSrO3u))J<-`KJ2&I49pV8 zJXs3PzF4EtVtVx?+hripJgrO<_>$YrFI##ty>7EOmvn}o4tj=LiemVECWL2#K;DT5 zFscmA2{MWBxY&4s0=R$0NAdQ~{zta(KO;PGyq#DL93UVG%~XNXf3Agh0VEW_UI)rq zTpfj%t+=_TdP}lMb4+zZlB^RKIuweql?{>rgTIYf>F4$8_G90kprl-vy1Qzrlm(BO zmzUQEFRw@63|)wcbi4z^?}%zrod}HwmFH9i%LzC&JtwtieF}~C!n7d)?OrZ>#rogx zAWWryu{ZE0teZHEl(E&z!&5WB617fw=6pZ%P+i zXorbnw~S#6FXc4BB;M%Y=s6cRaFz62QFRXR8w)F&r(f{G>;e(^!r~PN*!M_ zWt$^H3Z$F)8JJ0}iLqSJnw&4cP_lCpm}q){g!@5Qoc>D}6R0VL$SJ<>mGQJp4fU4K5P?FRsq1NfU($(rw$e zZQHhO+kRWqwr$&*wryL}w%vPTFE--azff0MRhduj_6Wl65&U?$bujo}At$IdRqXelR-zF(5_y{R)XA6u)61sXIAc%9 z`r$Mb?+Gc0cN!CgN5_xvK_Qk<%9ue+XCECtay4)*iepWZ(UL<=1M|KPS}_Dp8blbK zgQNjsF_~cBN_|P`cK=)uK9ct%RZ(zGJez}98x4avdr%3~U(Hlx@INFDH6i9skaw8sD? zYK=-Q7%coJ!&z^=e{5x-EVBZ@qL_R-sEnGnO7OzA?g@ttEN}6*o>)d|_4gI6IYWhq z1AV{}+>Dd4|D?(Vg~=2^`D`RYJk=9D-tBS4uzmy*3N|>PATB=x8!09dnSZiV8{jm+ z%xJR#`_V~4GtG3B#*yTp)sRh$EgXRR$}uSS) zrS*y};>HDXs;qkvv}l=>tGlN=F=i6RG$6*Len??Z0vfhH`bvyC{cC%FsSkVCj;+n6 zLQOlwQ|leqvm}G_P@jW>v9v!!X%327ChewsQH(v82p*hAw!ECa_E648ouq(**iPSw zQ?R43?^yk4E%sjTg+S0vXs^=aw23o^{8Y0+W!ZQ!1gWF%z4JnT4^^C&&HJatpPrebR^d@S`0Q&lUhF#xWhxBE5;Rv~1mF$A zBkuyyf^O0I+x=XrSoD4voU`OguKv?a86LD`vn6x;xkhp~C^H1ok6pmJs=gDjeqo5a zTVcjY&}j|TyBN`;m9=rqE=O4|w!rWzMtZIObW1Q*oIg?Bo)L&n0IYL`g%Q~}9V|m1 zn;dd*I37*AV0RP@VXoQrnO{_tTmCYO(h0BAK*s{!m0%e3K1Q7 zQ_fkFAH%Dd5nuv=&O*mHa2$C2hezoyvHWE~FsWpML1%S|=@(#Y7Rf$rFJ%zr7zDy* zooPw^W_k z0o807LM2dUa0QO)W&N7U$D}1lW%$b#fp%DFBW9f>U!m*?BzHd;@)-0398CTf8E^!N z7@mi6{r2#k-t#QO2GJ-~08>kwu+RkU=5}F%tVVwebU1AEBQg%A8HixcP`>zQd z=l-A6QY;s^=6UZ_>AQv~`$D{!TA7c!LY%_-(}pP$x|};&)9~B6mrz7o7&H7!@Ck~C zM)v;spIFwSYyxG(v%@Ou5ZaBL&x9T$RP>#~nd@GDqaT3V@JrY-1Z3kdbIOWb9Gb+W zL+J&^wOOf%ayvxerv8!IQOGDk2~m(#R7#_DbQt(D^qY5(F{)YOBW&pAdt7JWlnpWAkYH8=)_!Q2x-PpfW%k|k!c>0m>+%)4pA%Gn zkPbr=j2eLP9da^pJ<$3QNF*~=*#yTb`z7!jE;!qNu=Ipwhk61I_ikUvj01$S2}=RU zS7BV)h@7aQ*+nPVTsWzQxK5_u6lu~r!*zdxZfse&V9OxQoZ*#_UuQtA+8Zc=;9oYM zPfGMxVnWm5!-Cs~-A7>E0X@s3*MnQv>+yNA<164Q#aN0=7Yp*8f&%$kTE?1uUkRP! zh_}72=N>mDG|VTX&@^af(W_D25+U6BCQlCC_qBHKbNFVIa1v;A=NJsX=hyeup7rsAOGf~~3!|Db>tJr9cx!v!UX|j^zuQDaM#2J@ zuV&E#iXMF-eGoAOuTv3rr6)6}g(HKp#0IG4R)4x8R8j|Jny4)DT*$iX*1-@0^SyWI zlQKMj{3il@+13(K9z{b}64$E90S-lz~?OGF?`Xx*=CT)&Oqb19qS=#yU1onhg zfUY)EHlj=8rbYh3`TF1^l?yDfi|$ied*dCj{3B*#QJKIZ96g#q(}I~t3TA_te87;| z!P@k{k(V^9*xQu^kmla7ek(3SqdHzAQruoyr}~ofXsOA_!rzFvKMEfVy7O9T6u8rs z^usDf3|M@(h;fnh)F}{cxLe~WcxsVNmDdzr4_x8+esOt!C)7mBI|$q%6L*CZ=W7?} z*@u!)L+Ob~3V;tRO@Zy5qzhwbi2#GV%1q=rF&?%^iboY^Z?3bN!7QoxeHgf{UfYwV z(QIgF;G>>M=PaTC<9P(-Li|Y6u_>pZ#B$>YYLiO6)VSGI1i7uhF2L6Owt7zjV{suR zSd>ztVgT9B$Iaf$XQ3u;SdctF5{x3SG@#LFW=c4{u)*LSr8K!{CCJ&{a6ljvjtG?l zmL5iSnF<9u1P#;Q!(Q03Htes*;8XHX$S_w)@kI2`2%D^Lj35FYpWmI`n-=R`p(BK> z&5`NWfPIMDl9Mp^(f-JvZ0n#Or#^1NLs<_^C&9Chblni~KbYh2BlPPJX>TLYT6S3G zU8`O+c-ESA*|)V3L2nFVvMS)i@s0Sq1~P2wm%Lyx-Pg)y!4~SslBRE?OJnL(&v~;| zgjV?CnIO{>QR{YY%L3G-SIol_G011atoz*u>TH(FzJjb5|~yTdGz$S zmOFncx(7^t!MJwIF9DeFbP_sHdmM#Mvd^2H^8|ApN<(c>O>kjN{%cCKDTtaRNw~R&UjM&#M@h*RDF@y@D{+en3r9JSM=J9mO#Ks z!nJAG!6Oz2f%q${3pvt5y?j6w1(^W7;0snF`nHk^2TY3+;zCK}?~DA)nX4fh42vr7 zMkuJ2atJ0rVqn-E){*R98b6#qneYN>A1O@TZScV=$?G~NMBL0mHZc{<@3cLgR#s^v&>vA3A<+>AE zm5Yv=%=R6p0aa`gr;&0Gnd1UfeO_a=>@u?x8i~O5W9jexU+(_g<=mcciC#LHg3%M7 zeP-%Bo#pYMY57m$89p#8FEOy@{b$CY&k#Ya)Fy^>nN83E`Sh`j zS!zvqISPO!q73&ua95v%Qx);RlJX5md^R25FzMV)0*yd*Lc>bn1@U~jJPsm+HUs*ajc2jvJUYWZfGp*_*O0Ler zI1}ch!h5II!+i{Et#-k4>ztqOA@I#CX*GH0R=8U2yysb<~4Zyftp_u4delYq6# zCViRX*INVAw7^aU($|-J?S{>5A~tLbfT2vmOWs?kpJF&#XJ^S`EJ>L zKvy+-J^TZ^F8%Ll8}ZzViEi6^lGX0;(ymY_18#y&?z_ujg)=VIJU&jB+*NSeGX07@ z0%vkjqQ*-fK;^F?OGCO%>rZbwQG>@}2zPVd+$l}Xi3IGnn_DDK{l3W@&l_ z>!?(Mf7P2*+`xiGP`?goYsFPXt}WQW&y3km5~Wf`h$g%B~SR|qK59&&=^ z>vtjaVkD-jC6=x^im57Lv*y;SBAJ2>>QSdoGm!H6TM-3vxdG3v$AaT4>mz{2&7zb( zceH4*0pcTx#`Bl5m457zs`r$E?+%bvMXN2@sW>K<)0hhe|6V*~oPQRimvkk+Irtj* z9h0rm5e>JyL^DW+*0D}kEYIEQQ(ph;V7onzKb9;ZUbz>%n8{~7AV$UapED^gSW1ayOHm?tw+bscZuiY$q}&Me;^%t z^I*cSg_sb1LrUXQcxCvCuUL;z*Ry1(I2RWH_v`$WM_W*=Hlw@<2hzbbXLVGe*m9|v_1NLvSN?9Y zgUvG>>0N?StQWfUFQ<91Di(8c{?H}FBB#@>3H&R(*KAs|?(eexrz+qnaN$s?+Y=IW zziEnRtACTsSE;^J#|>u6-T_#@k?petC;}^}nI@h&^WaX%G!aoN8XO02(HIzRCGq?> zAG|jZ{Ho{(A;e`zX{W^%7!1!=+zNNyB96_Gt*RJdA-lyrlIp79X1S1|>ODj5ZoF<- zM8obccnjz}+~AvKL?$4oFo#3XEdNd@cQUNgpo*f|1HaPYlBMhLBPIA^`>A#M1~&D8 zsOiEA8f5ip03OY>h}}yS2hcy89Do9ygxrVq@D^E zpheIdCWpl}1E2bfPgdGBlI7gjD^O4%ZT5f&E^mAHJt9cy0s>HJ2QBx9;lrE0iAWP8 z)o5~-&waZb<*ZldBb6626~Ta1+dn)++OMH3`3Sq9Z_*W^;b=R1d(PCX$ru8~VSO6C zMh50tzz_A9&g8K&2A-xeLlj3S1fM>S9G~n#nFp|mu_Y5C_X&HxIO$J35IaZ#VMe8l1+8o_urXm_WAr3fQC9WX+$K(Q z^PSk?$d#RlJ(3jFx5_KP3Zw*N9Y{@JtX*9YxQbBKD0}4n}FJD_t%tUf^}sCVklgL;soC} z5o)|*t2;x`SuR|}b=q%n;4o>`vt^tdsTKb0;de+}NvUi?HD7u9KVBL8^YtLL>5?hYRePDBUcN&pWMK?(sIMKC} zB#S@;f|20dBQ_>FICWIzN`o|6s>B&M{ZTVjR4c0l5pkiJvh!48#vz3`<7hTPP3+k# zDM1orV#>3Hm28kB4POHD;^twYDQO8M@|(J;P=FfrU+hsX4rutE#o7dTXLbkdjcX+|PQoe<8w6N<3<>IZx@u^rI7LNp#MJ@}H71I#uMzEt~pz(J~9oV)YfN zdNPVy4b;;0<+TiY@Qj5AK{NI_r56jP7eK#;rbR;q)3<8qpL`!8<;}csX@WqAWV1!{ zP_n7S9KCXWwyQ0(!04?BSXP@`Xzg^9m;j6LF=_N!v^G}JG?lwDuQZ0k6tfz_MI3#4 z;7CGOv&VsjM%(nJ$kIm5fyCkF0*OlRt`cJI7;jnPC?R1jjS|uWa@t>_m)6sgS-_WV z{oRE&ScrqW(>0&d{0o^4qU$PMU`q{10$}|Z33FXwJ+{AiHzQqz*b+ccjc+Lm7 zBiIuWU$=;QxF2+gMqVCUG55E5+Q>Fu?moWDz1^X*?J$BSeArET~sfCdms+!Q@ z70TC77#;;1(=#S@VB&c#2BcK9)wvF`akfTT>Euh@K8oGq?Yv4{MLOaR9q_!S#do7* zcnfh}6}@SF7<@+REZyNy`=S9Wc=i zh35#ZEa_k*nkyewmoSvBSb$fsImrq6^>h1x*ctXVI3(N0O0$?SjHJb$sQ#qJ1v9klvZ%sRJvmK(yyvf(|fO+Hj~u2n?d$%!an zD_gZrQWJXqh+(UW+b}z$$@``BWZizdqTdgi@uL2gZL0I;u2eyd8L-*rhQTfGMn)`M z^x^hh3xSw<$d2E1w`nX_JvmTGcMAz>tcNMVdhSUHXKLHUu7;oftf1xSB>gvmM`s-9 zg4*r&2q<~xN==s2W-x24XgNwbw{^p?emVWRtM#ZHD}$4jR>cv|=xr*Rc3Q(oh2?-; zLr3h9`$n%qk-4e{4bUY97PC!qZL(kxtjf1=jGzy;o4ndcIJh9T@lYw7WcT5N=p(gU zDNB7#_J-IVP<5mM!{dvi8+rCp>uQ?&$nRcQOVh(%?soz5^5M%*ag5uAElnfrn0ot? zAGoktvaw8&@pokFni0bLqZ^XqzQS#!z*K0cK_4dsSRDl0*5J*3DhR&)G!!qQ=6G`xo32@dI z2*6z}R*M)J)e|k^TbpJJq?H{Lo4>uhNlkQP20KN-DALRK2Kl~TlLXreuHZ-A`+;jU zCg5oA5$REuN~zfC1?6~b>8#);b_5J3cA@E*8g!xUdR2NUy99V+;lvFrtR{+%c`Gc; z+W;pA3`0HrmpVtEStIM!5~R%w2}H7d*i>8MTjf11DXhqi?)@y$QT8cVbl+XADD0B+ zj>XhtYnXRCh7yUP(s{XJ+R4Z5tYZzGy}3sh6g$%V zEO|BhfGG;%=}a}g5pzl>%i=oox=CJ*V?gHA2n#iFNjppajMqyRW)Ag@w_3ZqXh@zP}c%ak@E|_Gz zhy2uk;JOI*<8MDte1dj$xyN0$^AKq#2~s*PF)Pr*fNW^0NQU_0pkW5l;4XhTvjIv1 z(hwBtdG}tG-ZOtZRcE75wQgKA4KZ4Vh(g=?gNX&eO_;Y27pr$^xwwC;v)}5gf7(H}84L&>aV>@Efr)#%GR8R;P zoB@Ht9cG@1oLq3wlS&%R#1eefOqMdNc46Xm<^4!%$$Dc3Hp3O}9DnD%|2tUl+zaoc z2Cxc@O3;aC#>ebcR^oi0qYR63K@}>fV}^;KRorsZq9GFTgnQ_&!<-)dLjVjZNTD{Q z-FWGtkHnlWEN8gP7Z6UkjOc!|y};8X)ZiI(-7(hsQ3@J^wOAthl!`cjXrM7+4Tl6Z z@?w>^g;~BN^y7`{G^r#iH-EUMPgd$yfQGtwI9(=>dw;Gd%K4;2%KF zN&NR!=z{!cX>YK9m8xbG>ua-Xm}Q=ri<6UAPJl9_utEQUA(W-Pu?U9R*9T?Db#WoiP*g{vyg0Z*obLw58V-5NClCo z^LDy-xY+_I&ts+en*lZR!=7h{t~1-A67<%}Mr8yVM1I~c+KOW${Rz@v{uST)`Znr} zl>d2-A50@VdaKJpMNF5#bapurX{khvxUg1uLrSrJnGPSH--~NUfbr~G+v{uU<*8-4 zAACh^f=n%pE2lX^aucS{b5||P?ZZAMSUN`9If@njMrw|h`2b{KBCiP|4BZF`lg*^h zm!nz_Gtx7QR3SI4nd!gmzjg>Dbfj@UHM39S5q=961X2g^oJA2n&CCRacI!(cKGQEi z>e1OX>U*y}i<5`Dr!%rhPC4uEglc3;TC*;hL?}grNQ^xcM7X}og6K>7>)giLnZTDX zT$Qm4)%#Yu#{sc>#@9|@V;m4Z`HK)KoSz@zk-Y3@A^kHb7BDP?AnHMXndkIkGcwm^ zjL1g}{YtLy)yhW|Rb8XlF#h9E<)_t^{#yQiANpgIPYk@?0I{oB2>7`AyT3nZ&)so5 zzbjDNH+5Xh>C|OaFz?TZ#yAg^Hm%&m>+V=wQ8nstz5uxIza4&Vp(4BGW48v3!jW!j zji0aJ6mS7o`)eTm&P^|?YH)`2ijj3Gu~A_U^V=7@lICAYYAs8RJo6@JvG&Z6h)`ED zoWUFe+W~wNxt;S@4zBI*H`X10#kcY)ufwu97gz$YhLgk9Ehs9{C`YuTiHHaPqQ4K9 z8b@!2`}O`+AkDEGw}qv@z8#^DZGMUDxKC&xzCvZcPPXS`{$h9koon^Ii~DIBZjwZZ*9{$oEm_)=502rhKT6zwyZItak;y{(mIo_gVLb_2FQttC>UHz+N`EK8UZ1*n|!_ON%!K@^r zNOCHWjC_*B``ksEgG!JIGfs;S^ZcSLhb^H>}pI3Qm9JhVUH?MYz(>)lC|Kou}Cdn$r>Hg9m zt|=Df{)j~9Zeqozl1H#MEuxT1QFg)TN#8!r?}33}D(_bzXxLyZJqFBJ`J|fpL4}HE zcF8(t^j}$dA8{PP-+fjirAJ{?QSJeqEr)NPxy5+&vFOTnM{9|+qa}j+?KbymA1}|kX zRv~x*?P>E6YFcc-!I275HH6$7*A(eGfqsrLm2uAg+q=OM^7g-lrUK<&@L;V*$BD-7Bd@t41c z=htZozq`=*0{RInu22Q;_Vu8HeCr$VN9$K zMYBY8j=Bd=BOc=Wf+NeBRA~@?_6E6UbuwbmX4i;Cx!>4G9N}oUdPR!uV!azo8S~IF zz6f}5$&(Lc_$OOe4_?Vn@dJWLy8aAkV99kxK{x6ri;MTm6f@ne?S`Zs=p!EkMEBRc zo9KqX63m5MtT5tlu~!LH@}A$uYMI!=HSA^B4X(wu zftib(D7Sj>SoKKh|6R;hJ5hC^(*nT+L>i$vO$$M)l$n48N+J@sy-!R;4z~jYp+0~U znAb7Oj$4Nnpd~md0>n$r$GNocz!B9x;81LlRXfK(MoM*+1H%Zl{0MX*BVc&M8^BC;wiuxH@8`^SWQu<@|%_B zN*cD&TD0X?1KrC4wzYX|R~Q9)l+X@E%lZLu?v?k?sIWgRftZH03Plbp{MYP{Sce>3 z?K;WF^nd^;O@ljg2Xc*d_cSFILJDq!F>0KVQ4dTUDoE{_c~KHRUW4>#v|AroIdlAK zpalrru;~MqQ8i%Kz<~%(&iY|$=3kf|@L~r|NuO}_I<)P9pjVF`IQ%6ieqqq>&!pfD00QR&u~Bw_g((`*2xxXPQvJVZ>s7%OTJ$n&K7@B`0L(G;7Z(WX3!H z>sQq|JbO>j7tj?xSs&5}MnYnvAu&c=xe+OBL;-O?7!mvx9hl$ZY!4hn2vArzJKz=Z ze2zAPnRybo){c(jVkn4UVDGbn!HPttzp45%?^!t$B7XS$*NTziv zfl3n$h^0AWvoEKz?>sIDzG1-NH2vpPk$_%;Jba5}?3Dx(U*k~>^Pz(#49WkJyX~jl zi@)d6yv-M7ch@wy3PVBE(6zB&ceHeoU!~`i1B_2%TnHkNUz8vuLZv0xkJfu+RGnd2Z5AwzM?naLxWSSj zqtekc;|&!2c`#JoyroN$oi+O#aDQ;Lu?0}IyOv9~(g^gV5r!B7?||ZftPkiIwezED z!=gHlr=r)fq9-#O-&`N>+*Apm^!q)yKKET3c@#=opW*Lm#@EGvDH1PXtfo28K^hQ! znA8_8s)O%qNaha?vWA9Psj2q}L2f`sLJ#yqW?mqQF#C*+X^aBH7=gP};0NyR&jH{J z=Ubc`(@c4n;IP7hTNX$dLfuum1KNeJL z<)H9JX0;es1aHVtp~x%Bsc@s9DGjQw+={~OwDSee3>Fy%6 zoj;^>pnJ;fBS+>irXjVUly+F^RRfg9%@d&Vx{(^z+UN%v%ts1QI$DX~+XxMDgRS(j zFP;}*2(|r}19tj^Cp_(W?8%-p>mY*>_ktXpL~S>lg3)PhzJ+2&H_y>8ZzMkvKS|#h z32$Fd_$ZQ45&t*0AM>*-8S1Z*C!W6JXwh_nm4d zujQSg9rdq;X~7oBgJsO-9`Hlk#sVTny{x#A|IM)wj7Y!9!op$qE;5)s{Dv7hYgn>Hg5!=Qk0@;_b?`w9B0%Ug)ZOTP)zG zeJID@T?s*iA^&MS4|PJZFy}$^zq-$h%7St zGQnT=DrAz&i;z6uvh0N(^TLh{NbH*DwBF~3qd2QyHl;3QDuE|BT<8-)fH{0Vo&XD+ zd-Lay`04bzX#~}ng90FCoE0(Yg#8v&JZEIxt$Jv7xcmNzzplS)gvSu*8X8=sm*~;y z74@#ObB{)0$Sb)daX3O+ZJTarIt3yKG5&;?FH#e-z745j(dAWcokZ8{>W_LyG_#_Z{jO#Ka50hkZm^T3 zzgpGJd$>yK@mU$mV3OfHWRuBx8U6DoelMO|U6cJI!K-IpmwQthY! zwR1Z;dGHwu0LcTlholS!h;ftu(a#EjD66TX0S$$5UYKW+v5Vm6il#sa0(hcTwdXw7v5TgU05p6ItQnBdGOcCMz^c zs`4sU-(l4Hzxg!UtI?2LJYU14t9j6(YN{5Krs5rHasuX6iIaI8D8q5^$pcXc1002+ z^l^%p)d95GDsNP#C}(%oxVTSNW;)`w&=De3XsShMg4u?n zG;S;34Ib@EHnKGsf%D3$6&me}U0I7# z#5e^-bG>;>-C3k2ESC}84#>C@%mG;ztayxR5t|^@LgEK)rK;#mx?RE`gfY~8=v=c8bgbWiSaNNKmxc(9J5?ci@J#+%f5G?d2^ZsZvi z)&UV1>fig4>E)c@`lvO;$f9Lsa67!}EVV23M87|fj|{YuqBCWr@D0TR!H8Eqx`@YM za{iZD%rSvXo_W{Uf5p_Xm zk5_g5CVdRIM!}eP+%wonYpRY%;mkTKAX#3E4@C=;gi52lS81*HVy=54nFbh5&xl z+tMSRsKGcLhIr-d6N4F7AV02+zy%IiFVY@=hHciravaZ4FVO_%kBOffByqPPM6bY zadXs;u5lEPYi?`0RjN#y=h)mXVgOK&@C%89hBw+a{5kLTGjaVIX5cahTwoPxxU2Nl z>hKqF@Jz@N)7a^sLt@ld$x=-ue;@~x?~)u^)^)blb-(8Xz-Q$q&Tm|_Vfd3IL=^d$NV;FQ_Fz z4({FbCbV0yo{r z8Rl=Eko-Zo@!IuXD5xMsyl5Z1*Ltq^07=7>Eg9zTi)vK^NTD2l+r7Y=kz4Ng+Bz5 za#`4~2*H&UJNgW%KU@-k=${s7bL8)&e_O0u);Yz2vb{n}T!0vvJL2}FGTr5=t*xJH z`mB6)oLXYTB1>1oMA(_n&@;JN$##))H{WHJbT3hh0)^%+t=Oe8E&4aEA>Yzp69Z=x zc$a06ZJ?`Lx)kBRN^u0}lU#Fcu;4GkKak^KCo4pZ?GwXb+xire*DT(Z=0$an`v2}t z1}F(j?HlR`I{^fqfa42ld5_%vPu79%d8a^Zh~Qb4nQ>+!oanTEi1CDHBg&f2IgEHV8)%9& zvFEphw$Es+PAwNw;`Xk~D~kAR9T%oQFNyR=AN-!@qJY&mV4oS-Fk=ZpCJ*$wR1_X}k(La<6>+`*TxqCWdasxZlC|}o@dCiOl<7zLLK_(6w4{)o>>8%hCfRbU* z?+p--aNYU4zQYo%Sogvflb@kiI5ty=QXn76O)frmi%U6J_}PMpFY~?JJ>yzL0?{6n z&#(xUx&R^lrZL<5J)ENJP*Nl#jKBl#wWQ(s4MN!%%mR^`X0Wq2O@1oloEBoxE5ou% zv*hKfxK#&>&6_AnJ8kIeXY|O}2|+FUN1;~?GUwm8=#Xycn#Cb?cB!T$O#i%R<;`HI ztR9a1zEzoy%ryg_$gF6q$ALBV7C+C4Qln)l7yvLj?z3Jrg|V<9z7M%{4G(W;K%kBZ zv8FyD5d7&F>B9QoXvSJu%HXwnn(_BV`ST>%MnZ6^M(uu`kzU~nWQD$J+G+YyNf!!L ztd>EthCah*bzP{n*qnsQ79$k&#lEZm2I!35YEBChHLJq8X*|d%HB!q=4MjpiQ5ZAQ zumMz#-^!i&_wQVD_18j|FuF(LV!8yXN+%aIAJfbb>E*@JU)Z7SIFKO)-ADh$qFYEu z{`59&JU58Un}!fPf*}o~Vk~N5+-;9(sDK=zl$dASWlFX}uk0w;L`O^WMNidrYe$NV zczpI^uTGs+N-HgBbWVyW)@GdWriBgL?E(ZV9i(5$IzH1{&URd&bwKPo!FG}bnxBhW zfvh^ocP`oL4z40SxpvM^fs7_nIWCnZm?U9nFn-cz-^GC?i<bbIg)$P~-%~idaCCm~gUWZswWF|~of%4X}uwx-lVo7G# zBJE|NU8pCLl5-5*$+*&9S{02JB!GLN<2fx<^Hdx&rz$|%=jqILx)f!#`lS{`4~~?S zs~-C#Vd7ivM~{}?OHgVH7G_2D-T^E*S_m?u$H4U*FRJ@66&GnpKZ>Hj=mE>K^#%v51Zw8=I~y^fl8F@j^ko2Zg) zj!0n}+*C4l~IjY$hCZ)^lL#I~i7vv#k#a}dBs;6S$Edi!So=wC? z`BXkxnmSvXvP8KuHmZ8X#loRXOm3AjZR2AiMpKuswCjyB_UVUHRI?0*JuHhc{0-6N zZ?l-lp(Cb$x*IxbJ#Y8~4qorMvi~i(Fc^HB#&$c!C1&8v=byaM>D1+WG*ihnxmmpI zRHh@F$i+y0L(n_}LHEVa^C+&YDhPTT|ABuC?K*vL{Rr~0%l#5*f2TQIuO~3|+;wC# z#F{r;%$GoAI85$Z22<;tJG|{!rNE~UHH;@`>UL5n@e2bOS7CTsCrw+k< ze;p|T>PsbbGR>BwkMZ4)`M*_lKN(}&Kh$>noX0*Er&C*HC`;&ON)nUNcW@E|MbXJh z$ncf9P){^8sF%o+&`TG!@aB`{D!?d`3Xm?eS+c2NwW^ElsAEFkQbJpK0BXTKEGq{l z2-#wzIHc&Zvj6NTCU7w*yQ5TDQ%NXNk#1|-1OJAiK9i6#O~t@qm%=nM8OUwKJ$uxg zRLu_n%`&DLV`9*)uhPsstBF_B2%Rn_%3>yKZD^;KMGa6!!$qfI=B8IqmlncnV~@oY z8vQlxZk?YHLKITmxqC?(Qlp=9XXQ# z2@@pM>MTR}SbHjw^Uija8^@pvnjcL34B7K4{GV-Y4d-yDdeNMT2XLt$1BDWz;rSHg zQ@(r=Pym43@kssJ`v3)SmFxxvKL$|VZQ-RB_%3!@LGE}yVNm|%FYyg5fxN0XRl_g} z5;W^@1vt5ct*veqpvDNOowH%NV?U!c(9b@t8lmOrx#@sj7{Yz@6e6N-0^LCDECD~g zod$TSg&Wi){t_^<0r+g)c@(rSLEs=}N0SYHhlsp9IY7>|>z7^{zgENDYuoV!H6d*% zb2Xd{N1to&?2q# z+@-(=Ca99;pTUhOXjlhp&dScjL9tgHq~w*4XjG(rXejah_158x{;K$EYPYuK6-RD& zxb19l@UY8R0QEVyeF^htf3n4nEs*G9aT6qGxi$^qWnA+_(5FVRyAe_5)~YygjM!*0 zNLHt8MFEZd_dgeCJAX2!Klt@HeC4JZq8S7ndWQcrsNuvP$WZyoYmyHhflu^AthC$( z{q|pHSFcu|eCpeuAia_0V?c`+p`!CtIxn=3x@cZ?sp-_?V#n&UDgV|B$JLji;dfqr zzgDS###i`%G`__9Tz`c3`J}3xV_$RWa}|DdC;kT;1XQSC9my1wzoqR(dlCDawp6mY z8su>zO%BfflPgkH7A|Zn9i3;O!swYkNZVfcFDf;!*{$*tg<3EnDIpP>RBu8v*ZQv^ z+%Gz8o58%8~q zFURW0Bx{bSBLHPv{EnSLemgZIXSw`qHoX1K1NA^|!q*I50%!Z4#UN4MG}SzZiia8~ zoi$ZD8fua+E&RmA9q*qqCrhkz!&PeHHbLq{HNb9-#-Ub3TnBxu^TJ6$1u^j111GP& z93KS(B){DuNjcYcC53k8+x01mv)&{#1<_5d!n-FZ!l~LcmGP5QFUNK=HI_}qSke-| zIdFmwQ7c?$RpkAE@lwgYDV7qOa*$uer6X+-oO<;m4&!_iZz}<@Q0}oV+w`s#=sj|^ z5ikrKYb;^5sde~X**DmczTDwRe3$&z2}NM6r> zT(RXHt9wGm9M?A6)W2H9W$5n!y)hYu@f}USM+}&ehLg+g#Hs(oZRr3BtrLosvtIET z8qdkqNyeR;29SwY{@fqpRAZ%Bt*-I$S^!z+Yi3+|fwL=(39Vz4xAKEkPlWd!FWbCH zN1U<(3IQbeBy3-U*O;NVqTAF_tYQ6w*fE)#twWb*_RLPs)T>MI)5cO*HB{R@Vp~3- z%ck1PuniIsZB;z$P_^oc+hdob*1TK!;lmyH9R&~T0ji|i(*{=i<%MIt-Zx?H7GSUv z&=n9Iu<_Z%t$Tpn)2*&^k5HHgG-qFPmHY$na9gW0SYK%;Xng=Tc5)Oa#sKkEze&{m ztx#9l<;|_0n6{}l=D)-X?4P@`g&v9yJmrrJqxEYO=x97v?19=b#F*Db?YxmBbsk&6 zqRyLBC8(Wu9LgL98(L|Tx+my zmB2oSr@2lN);KKY2}Tj9e;%bZlSJ5QGZ+gQ?17BlJYDVI72cKK5AcUrq~+%b zIQ_bjI<&V;+GOS#(epiCDi=5vY)SQWipM)W%~XNJE9wPxW_$Vav(?oTR4nVi>GoTGh6f@szyj0NwR0r%3#z!5@xr}b^^GhDHHy*`}@!!6IyA+ggS(&vlMSiaD zApkMHaR5}#XC=Y@(Yv1Fk_XdxgVr7sr7qt7uV^qzhdWOq0s?9p0|KJ_f1&{yP^+&U zkIUH>@cMtqddr}=nqXmg3GVJ1f(8lh?(Xgc5-hkwU~z&43oP#L!4`K3?(QzZLvVR{ z!ruGUt?$QHbgI1I@MJJ2?`BNcIG#t|>U>c-uJ#N$ zj^?&hJ3;9@F4lZ4#NLRFo`L5) zMN5I9Jh?n)$iwDK98nSvH@qE$(SPJZv@`o{?3)Z)p89`h-r0M#w>91#%#<#;@ECcR zor34yZr##~KN~7+wx} zhzLt~_5dyEnm(x-#ynzPFgq~>pGv=RU`c{HTx#(Mb9mXm6-!ERCo0E^G$qm#@>G@Z z=FBBR^>lX^AJGSo&rdwgBKA3;n&ZQTUtHOEkyO-Rc(F%aIP|%Y*8m#PoDa3DA4oC< z)3{rB`lBBONX~v+v=zeLer9-no2z!(fle_8AG#rtUouK9oU%Y9io=#bVP>wq>xccK z_9cH?&gm1b&ye=zN;~C6cMKJ!=)0fYn;6tLII-p5(xUa=!i?q&gJMe;tO1>QH2k4@ zUr2yI(P*L{%s+IGssS=?)hq;!Q3U{TIGB>jJXolBsS8BqeiKEoIqBq*`ocU!1k9#@ z8Du$UN(_gA$yB~hl@P0-O%BGL*piKyz~i7~a+0dW!4G2GXXS_}e?Qk5jp48_2YxQo zjxSlTW`VLvSxtAn{EWmX?)f2JO;;YEQy~r9d>q1H_3@A3i3^Ml^R%=ll=o97s zgT$;q8T=2R3H`S$5Mk&p4`fqDBLplpLYt{O#PVmZnAD#%x6#fSiAJ8IEmcl;ugbj*>h91bf6>@ZD~IEU{vy-Yy#6+c zLQ6L)gMS|vI;QQ{Dw;DqGm7bs`}>psc0 z|Iyp;vsv1%V&(|9dcvk6P|%1meLWZ`Q`h1-wT2?Z*w5lmUj4EcilW+z;dgDctXH^0 zL;p`9AvBl~{~SbV=YwY5F;LKoS^oG?O@;$&lXV%@0Gj%$mV;{5G#T!R6?ThdplDZQ z0W2Dd;N~F~Aa2`gV7JFI0(ea&>v44~lb4ueG3}U-Hdz(u@Jrkz1=P~Pia31`?4H=H zo~8c$W73Qk*Xu}FYXgvP4cqL@8el6wg5Y+&{t;%$msYn@&-;a|G~GGaqTG3^0o3gMiB_0$eWQ zPVZAyY(vLQ5y-K-L(7_3T%1lso8;?zpe93rU$ItZNZ`n1z7#CfVq4KCb_sVN&krTo zW5TQ~+^XQGFMfxv^C*(OR${qOCeUSwcOmA1sZkbm#PkZ59P>Qb`(c#`2H4Sg6_;Wx zZ=|M>p%x0ILJkC3a)8Ekd9sheP$^@^2!qQqXMiKe85nz1$(z}71nimj#<}?7b9$LY zcxUYXW-FBlmxsofJaqsmlalVpj-NzxFa=&3&OBPwQfBWF`ZkR4z7));l6?8RV?-HQ zkgGxv<=v>k(U((fX&@gu;evya>-Zrzr64!Sn&vvr`j>*@a~E)T9%|Z!^iw;5q3S~; zSE;3y0H`roWJ>iRvaj{VCgnRyW%4q6%iASY#bHb&N)fVsSXh)*f5>$Z!9;1zqgIFn*H9NS#GZV{xsam z{`+L0;;@g8@8#AYvclYE$5R_VKB8-*g66lzGvN#=`j<@XQ_DHgeokwGG`A_`nWl@2)ccrLZ=9JjSG2Z?Y&(1mkbiT;TpfkgP_H~m&X$`Ni z$PeVlRRWQJ9b|F}$@3J8Nk@REnq;#SNE8$UeBQad~>f~_4f1GvLp2B z;W$67NfvarRJc{ZWMGEoZ&*EFhru#-(J=)8Nf z;+t5#z7!d-#G~ZnX%T6Dbh10d#^{ytHWh#Pb$6CyPOBU?tH@l)oNi9k|49sq3&{Jc>T?huyq7J7NMaDZW^-%= z2EgJ2<|-~-=NN30=ex0Wg>3D~6}^Lw>4_ln{m4myy}g-vD*V&@%Cc??+nfHG8?vn7 zOT}*qQ_Mkb)n5Bf)qKAuk!W2fN_WZ<7qU4Nje6dZbn5~9FCKnOs`PQP0q){(t$Zo@ zt>BDgTVM7Ycm4@LL=xta#%uqM3o<{CRj)gXL;~rX-CU?{(%+{Gb*Yrd<@{i zWl)>=vL;tng>hV~*oB$W@C7@h44Z`{m?$dryL7f#^-^zJZRc0K1%FI^$%AJ8FC_v* z{I+M)Fl(%eQ8>o^zw@EPI4&a-J6ghv?WZokb%_DLyvgNg*qWSxYj~dQa_0Kc-{#+0 z3cV~-!k+*iiHto#Jsx(X+k`S%{ng(tD99>ys~rnbPyUFdM02iA{!{*8P<;p#sZUa9 z&h5wTC_t*DPTt224dG)y+PL6mogNM>1{8Q}uEB6Q+dTY2)+ zS`8(jfm*TQF-fz*agTQzhND5(bwUSP_}A{J*q;=2-SGiYrypaZiNi<}2lgcTN)IsR zHG3BK+1&^|dCCeq*H3d)3+j_tqqNX$;c8fC)=Fk}C~E_U#y>m=Qh%i7^(Cki1C;Ge z1gg^{-1Q6b_}HKx9f+8q1JCAyG$i6-znC_=v@Zg#hBoVMJq#;7%FQhf%ke1^y*szc zYT^&Y2;^e_T1x&ioOBqKzf(x_HE`X^Mkl&MVU3=y(PoZ4je8pmZyz#3m*}Af^%Hv7 z4CW~LRT$^Jvm_QMzS9$XWg@dus#=Gh0y&oMAM?7en3Xj3NGJ#5$4+^08xMW5b|y5^ zu&A|+9(I@nUvc;#EQYu`GW7YH*E94ZFEykO%#hDH}VY5ql zsDG6s3|re_HcV6I{zKkqFOqB>{a<8bi~Z*593caYrf~IuHJQJJsBSz~E z_EUu3^r^x%E`4482rH+#Hr@5;ss76x{BIsp^1ZG-EF;@BX6z{KvUWR^458pqk{rNK zNfJ-i%6qxYZ(vHuw6t6!t)LEzUqK(IiAT*^1vq62bndj$>|c0{>%E_J9R*!24nDV; z?Nk=D7XsbKcAA0SyQe3-K=;b~X74#)ch_gK+fT7t;9$i$HoaA5MbK$^m426Yg9%Pa z3OjH|faT9Zdk2p~$>{mfWS(EHN^RQ0wJ0Ed4Lwxb;kxb)wGq!o#rpB2dD=cun$11b z91mzd*Z9sRZ21tZIJM*58Tb2HWI#33n|`p4(~7}eCjz)zoOv#)AwXDjofxReR2vxa zZmkg`HmV1WA!1%R@6?`3YrbRdU0J@fS$!Xf^|8=2`1UE?Rb*emI|Pywm3o`WAi}O;9&v-4snSTGOM9 z)jQ%H{B@c6X8LB8oNg^B!&xEo(!Nw<2VJ0)PfFrEgYzxBGx4s>jB1tIysL)Dgj|U> zsD>Iyd9|agEumH1jhVQ(4t3jOX|m$;+&$iS|6#L;B72(Y%Wlnx%Vj93Og-!1FRe%~ zFYZc7Hxml7k11&W4E-?h340-jFrQLP>~=aoQJwr!?(ZH97I*cnRwWc3252{Jr_NI= z3%^-mQLi-2{goy4IrO4j@=7>1ZBdK(`yV|dU?=jyJan@58vstMt#Wt;*1YHdv*cP> zLqG3MPNlj@YJ62^;02i)tBeA}ZBDE>j@9=FweJG5t#WW8JDn4z24xfp(9F1@aN?G7 z!<{a__YNf^i>bisG8LJHF-sOX$qfa}{bV}IRAK^I`lg5bi1Bn6`RZvXp+ew~44vG@ zK!doim;Qf$ai7Q~yw}{#&8#HKCQTCxlNvZIB<;9RS-E-smWSeNw1 z^Ogxz5JTR&(}l)!=P8=M_*@(ds5-5NzEG~~K$DZRlYRe{H7xV}h66hQi|F=nbm7ao z14Ti|U(Td9^_&i*hh^-cFS9ZRCPi7kalk+1U!D@HgG>B>WtkQB5vJY^**$)?NG2^w z{bIq)we-uRHl0`3HW#htczDH*SQiCc^P3TjI#WJsves3Gj6%lt?wL$H>CXC`V(8eteoPn6>}wjn+nyG zaOa!_CqzccoHDl3#PGjP^+bj}0Dr!@jK<+QVjbmvQS97djBNeL#q3=;1kPXu{^@1F zO5EbLt2udz6)Fdd2$a0%k3u!_U%*AEPaDM(bJnZHg* z%yTYn64CH}ZWhsghNGYwEOP0-V|>}@t`MiJXrUviVHlFXgKrq4a=MiKN5*EzYtgW^HP)N zsmuPMccG)F;Yh#;Vix_TL7lC>yd3HM4jN-zf>+|~zSOT5BZlUi`4BlRfmGH?Wk6p( zQW`XzI$F2vCPRZ9%p3Qcto4Q-s6_m2Sud10Gum19dBjz0lMz6AV5rB$HPKm>oP3s_Xv_ao?^{)%!WThA_GeF z&%H1#tbMGWS}%7=?@fI;qwnEinoN8A@aE-}m9!x^=v-`7-go`$4?z8E8fK?Y)O`5> z6o#zB{(uQHK;%%v_JmD60$3Nexcn&t&t^8KacHIuu1~oygZ8kXTM$(@lnf`h_F%gz zlyHwOPAO11@lg9?G67Jy%!qjmzap~XFL%E(Fe`uj zS$oTz22T1tWHDj%%R#guUbTAyCj97!bVC+a8Rmk&cd_e-lkC3qBYM2{;wRhCm@Ji* zL8gN4s6hS3pgG@0>oZ^px>gj?XRlwio&0TPdYC_FD!ll!KAx+A7~aVKD5(&}ugMQw z8bg|&@^=_X^uC3i@25Rb_3H3aeT1W!9GZ!szI5W$Pv0!Zfq%9Q-G2;Ich5oniww#Z z8fZX&Y{MdV&qi+&lFQq$gFxUkK zLPFqi6La4-c{>75-6Yb~7-{3_tI(7=;VIhM zK68T_Kt&&|$5yfsuZ~pPI5+8dIOBIu!!o~6a4$yWm3U2Tc_f=Vu6_M-*2+YO>0Vjz z6^e>U{-W4D939KEUA8@{$~td7QOOT^*x-o#U?R4XM7~a-qKR}-#*iS`;Inm~$BG$O z|1nXsQJ)}~?Syc!VNb75m^iB=(F^&p7XZr~P&;mnI&Qp@b&8_0esICDSX`KxSQFO$ zGhbtoS4XUEvO$t{Y1dkp?ci|KnNG1FY3LCv-os=}qg%!3Ms{D?D!>(v6@$u~vhmBu zO{z?rw}4q-0VZ?2E!tG`MS_`jM#3GH&0mK-Ec@@bE-J@%Ev%VXd@ejGJC+9@IVO!4 zoV-3V%nU2Y<0Gr1s+&3A)wkgh>kuT9htIfk5q~;myQ*fe_@JKZP!}vZ!W1BI)d;#`+f)9!x5Da? zu$o>5FA2w#T~52|g2q9+!$hO0eHHOa5Lscb!6tvu1Izw@jEnxs_8S{o^s= zM__O%a^Qu+yfjiG@Jev}`-RVyRzSI51)H#hjPK+8J&Sk&C|a>fpA`NR$^<%;2bCKy zTnx6S?7m_rtSPMOks>ZiJ@!Z+A8OrSwaZ%Sc`(1^9ihQ9D$1 zqkGdEH4+5W^9UUdVrHUtK(IOq9kHE{9!}c>RRWd?ZCJ8Kq}M2L=`HdxJD zD64=x#PR+yMMz(zs{?D0 z8LXsv+d@IP{0<$m?=LL}D$F+9hBp<4ozGE3A z$popmH(~!y&1F=~W$udzNZ0sXkY*%GZ{=S!y(C=5Z7B$yLG4TVk^M%&PwVW*F03N; zugRq{P{$CJa>~GQO+@c8)e7C$BWOF`B)%q}=ckpC%1KHYWTJw9GhUBIQlEm3s!Ub@o@W;iIXj1@GBY(K3S95_>*cJ<>mj` z`uv6|U3pUE7jR)FQ<(~JDxSxRUr?BfZHaH=Rx8c-Ya{F~sY1H<-}iLwywNtNFUvP^ z90RECQEd%Hftb6rLVrVOZT}r)o;U&d2>GX>iVSk<`$haygoW9R_CmGxm*-+ewXyp^bWrTRuWKoBa=Hjm2syWPeSRAQb9lKccV zvcnon(vj!CAGzrlD{m z@)u>PPF#Prv?tCv9e0GV>k9c42`P%|_V`I_-cosQ=C&hgyj-bm6Lq<3m;cw>|9!tn zHJ;3v;-DpHcULJ&y|S^-{J^uKxI!t-<&%@^#df$rAIF7mt8B!u-awi4EP~t9!8d1# zp*#v!t~h0&bwXXiN80a5e?&NvZH0K_dvd;i{{p8S1c3R0Q@hu@a{p&la6RA+;OQBzU z7_PAeyA`$t!B85@BW9z@Z4$A34IPv#7e__UKOpj5uYu8+S<#vSiC1W8 z-Y_tDyWSfqM1RfpZBTu4Y+lCu6*>A_`GP}Blu=Vy@@D@;A+sb)Tp{DniryyIvT0or z$1#}(qKbY&ixdv8fv=0KBP_v-2PK8tH4dTEyiX&?mE5Oxy*8-~(Z4IC;*|_-H11~L zw}7hiBJAJIr>Q7YC;F^*r2V5`8SpHs$0v zqO^joEX$t#t(wo7EL-XU(uWFbEb$8Lo#%{tAgFgrybBzXJq)yVtS}v4IL=YP`eOIs zm6U!cF--o<(;AS|jh0l7{0@cRd8MrImA=BbYHTSXtIY(Y{db z`up%R)c@W106t2=2!8|f8A{Rs?3Ip@5PoxOP^XaLV%CP>?OmLNfMx^L?9=M!LR*g7XB6WjY+}YQKr9 zNIZ|#eE#!R&D}9OAlrICOSq|1cgZm8aM6A(6mNz4x6xxCk)H8-8jpLSU;A?(4E#I$ zBUE^hDbWmK_N{e~!?1$~s_na+!?4xp{7&@$8)hlPzs%%F0Du=AsGR|m9O!OkXKwHA z%sVwE4A!@KUG4XMYVGdAE9IEIAJ5~rqHc1F@FIG}Oi9iNf0msaj6#3b?Mc2Bhzar{ z18MLrV+RK`_DSBzG6sDn83PLHJDr5bjG^u(Djw5MUGH?cx5#?@*>$e8UMh7YT5UskbA4ZejF}(PZ zXRNX6QXyHRx$II;XHj+Us_@=v7_zoo)2*Q}gh!0-{D7CUW;Rl+Y#`U6pa|!^LCN1l z;z<|%>}<_39Ud<(xjhB6pu@%g12aqO?G%K=TSw!uilR8JIkOcCyoI{frNBR|#3VL* z{|0%=)_*w8NCtXBf$JMwavA zyY7t-;KwW1)290h=ZU9JEIikbc;5(6m>U#VI@dE*!!Ioq{yNA2<@{tne$=I*S<|O7 zvbp$@oZX^py;Ex%Y<#l2ibS3LJ8_I zJ(9S>nu0PozI2L7wE)J%K51Di#t-EaZ)X=7SyDaU4Hf$1P;WEi=WJ8kQ~F3A2y{Pa z{;I_NcsSsdb&^&*1l$I0hkK(8cNza4fYWuMS-%2RPSlONVs}xW4=R${Y$62cdP~0* zlhu1*m8jHiTsJltAj;$_D=}oYDsXz6O37T-V(m!DoZb1Jd79XYA7!8kT9y-0*2e1x z)s#fNZ1_}SjrG3p^0@|~h!>}Ka*VdglksKbrQIqy*%R5%L*ScDAtjU~OynUnf`s94 z6`Mn={FAefTFn?}7xuRJx`tv3Rsf$(yKJwZam6<=%L2qGUQn4Y|G4cs_!ZU7L0gX^ zlDaZ9bfOtFZrGVP!41`5W)a7Zlj31Egu{bSOwlc&t<*ru%`IBTYBt91l3X{gfmy?; zij`bXQ^W<2s|_qRER6lQh@r2h7eGeALK%(r109F#qElvkCZ~dr%)ofo;FcP0!6XZ( z6E^U4gJmXjC7h4f)oJc>P{YGeqaK%C-cWn|s?3~bOSecFab;}{&J8vBz4=?knh{Jk z$$RiMoaFXJOB56xuty>-kjH52Onqp|!K0J*%{Y9FvpG;sOI-kwzH1?cFTcj(GbSfq zjWo^EL(tD+pY^M+eFF3sqoXmt>c;FUdIz%QF|J8k6uh02HpbV@+I#p2@gu&1Ud)BL z559zV9%34CF=JYojjLLIlyni!n_9_TUaKi z^)oxwRq}WwTO9sfh87`msD_uj5smBQI=7-0;+UBijJgW!@4rlx7AO-K<@ zza7lIBjrMVN9D%oP=8oKGjYoj_XB18!ItoJ8*`G7K7^d1l!GCaKF-L%g!)>MzOsg@ z6qyG&9h?_(s`*VkB?2+Eb0Y6$uK|>FU$4G$`W9Ax%sz>azT7=o>6^n2scTH|mK(-d z77XR!KqSCK;pB&^BeEK0=BF4xCm9AP7Di^)LaQ)?f*I?KCfVt7USs(mAEJY>N!hP8Yj&x=|_o9tDX|LqIex&SOpgmeM9HtxQmcK7O?CX{i{ z>TuDM)N%0^>rTE*>RX0Coi6Tw+r2jMLYT);CW%!u2&cDe2(M*m`tK0Bs2Ngy7cv3d zRc7nZSA3df_A#5_+%=+dx5wIgppLK?5WL1C#JegiC}4F&p3X&F_;<@~Ya0w+n+xul zK-+1cz*JI~LB+yN?@}R(g$kpb+-d#PS3$d5h^9B)0EkJ^4%j9KIQ*5v`vOPcG-ikq z{S))ZLnp2#xV-~3qf(>(c@5gZq+E*OQYG#iUTQRfUAUODIDL})5W}v4<3jQ+khz<+ zQ)-aeHqKWZRSV$pv2{I1*M@}52BC!#OtJA8dS#)m1lk+9PA{!z!y<|MQvZy=%X${l zsxiT3Us<`N&5h?qCK=wm*LIeC9J%p!41)o6%Ddi=&W53cJ|!+{;#_OJ2(5H;*>Pnt zEGUGz?3jE$C&-I|itg%GN2tpVDA<5voPn-D06)T8i>&NBEu9*86@Pl+2OB7qh~`#{e)itLhCGR3M4rC`T9RvB0As)S8nOO6xC<_LUKl`X#815-wcI8f?qMlX#%swY2v;8s? zwRm?tWA+BasXE`LFYtEiF2Bi#n>>(3{pW6s`w8#-C1V432>flgUTZc}w-c013B3G! zD2bHH952S@uv0#Jn>zIyabP7{2w5|O&-y3=7`^J(-r4wx01Ikr-Di?1UClaAjmoPv z=tURh{mwU6#V>_Hu7 z`y36+(h(C|3{}_ah&-i-oRLn|MsMY$E>QiHm{xt0rGF%i9-~u8iS(GIFlNxM=`+wu zmSl<>0b1>iwQWdf8dNNT$OL3bD14l$imnvH@Z=HW6< z32x>lftQhuX*B5>_d>oxm4DgVy=k%Mty;J~aYL6R*+pCnDmAuGawSKua@Xw#@A5Vp zbvb1+is5PsPdv2k4_-7W6KF#lb6x+x3gWXS<~5`;FxA0ig8etgw@dHAI0OIyrcnRQ z@h8kN2|z6?M982nL(I$9BB99$a}+`rX^P1KjrQN{{}ZRv&eqFur!<(LH83VID3c8f z5qx2ec?PLBc5N^_s9)(zVlm%C=;z}xYaw7vB4#MeD*|yUW+Mcg&%{JP{3qbp!aeZr zMF0*V=*;FtfI~ADEEugA6CP5p5LRI}K)@L==Dor{qNT7}ustdO@PQWOpovKgzJObvp8HFkO&nv0vHJk+Y}NLdjjk#GehGLZ6eu(L9u_a2*CJ)*h#Nx6cF0L8S+wu?w|nx zB(D$W#jrsz|HPI1OA}bUh+BE{PaHT&8ru`<-xJvGB0o%80N^?tH2w=42ZSMr4G-p% z#ipYDCo+j#3%2ov@a@0y_Mga52kcRZmby;Z)o)*&g#H720b=D*%8S_7*3e9Be)?Ci z?-w>U#9u3e*ccEF=R??Uk^Uio@Mf|3Ur{w@u`wXVTPPP8V4UNd4tpQ8i+bn+(?LW=`gra5Jxei;~GK&6^(~` zhxIBuiXL|a!rF)dcL0LGz>b@t{faOWj*AOXZZ{J55u(vv9PS+icP9nc3<4_T;G(|b z78>T^LR2s|BZ{- zU=s=apJcD{aLw>%Auc?%#V>&%Iarn%y@^0hs%OK7!PQdSfZFEV* zw?X_T<9~@?7?6Pc6Y=pu@LB&u%bSH?_vW8L=$y_)x-ZL-bg&?$A$&5>3L-HQm?{_F z45EKTKE5|3x=26qr?6keZ1mu3Kpe_DfDaGBl^DVo!1#v%3R=SF|HnUtppfIo3x9nW zkZKws5qNJ2zxY+Mav%kr^@|f=QD2`ltl|S9vE|>!KY#5LAeIY!&sUk{7x>}$uOL4X z!5qUYh{r`h1M#|u2!S>POqC-5L&hyFC4wbLo^XC5`29LqsZccVnNa`$Kiywt%h(Zk zP`qm1^PNEaA5@4OO#m?rJ(i&0bs7L}Oectk^dyx$0&Lt@Ei4)dU};`KhcyDw>pKI4 zyicI~+Ni@s_&*E9XCDaH;Qle+4Np#)e|h5uzT`3$D0}rK(5E7Vu;2$S!edD09rF+_ zLdL`)5yE7MRhHs}+))2maDTTwFMSC`IywOG?*C%}GQxXFhFJ;1I!IiiXYB}4#E`Vzt-zUsdeN+=3>pHjpSzJs__ zI*m{Tl2@sfgtzcy|4ocm*p3!CUs6}&l=0R8{P>HI*11BxLeMh4oZ$VYF@dxl&;;2JE7l(2$$u8wk=T#A`XO6aYcmPuhc zV?E>qB*UeJsPYS9f{%NC(MVxXqylu!G3+Bv0R7m+qDRS!o_>rrzG4^h7cHS0e|a2p z<@rvf!}qQXS5NsLrVeH~BOY3><0p)l?>@1y1s8|&aUWO`4$uCO5d-c_A{*n^a|~E! zG!K56EY?kliA3wK6y_ysRkF8}u9;Be6MXqU4DDwl;NBy;(47*S-n_a#XGQG*9ee2| z9e2gz-(y`t1Pj}uFZ)aG%dPSX^-j2Nj92e3y<(?kcF)=GMgwXz`OZ6MGKdpx)0386 zI?HUQ2&ozw_)nZQTmJ&H2R_89njQ+I!+}{{&A1F06cgI&FAYa+E%(z4x82y+1E&)A zlID%j*fN!Trj&DPCDY036GF5X`2-QsKbzrWP8SRYSh!FlQ_05b$G0&)&W7mS*m_wv z4Tffuk^v2O+6?|We5uJNwQIg?W44`x{%iv(uvaFo`Sm!PO!*PWSNpcLZfLe?z5Q*< zt|I=!=MRWnf)|=Bx;XR9t>?c@xFo+GYG?YI;pNLqF)(cp=6^73{q?R$VJ6w-qrnyo zk+IvsF!M#9_V?JLA--0Yy1%CMGQgv#cwdAhzSb|qs4Bnm3uhUx=IYC2^-q?jT5`qt z*O>*)n~~egk*^u8fJ6E89GqucW4|xw6R#`6$4(|eojJLhv$+w~hH^j0SI@Z<@|?0q z*f<`>r}YK~vnknYQffMJ*$Kg4xf?5++=-1jS2ej>rwy|``{L^>d?YlzT6Il`%4A5= zskjRe1Dzxv`V#9Gja`LE6NtMjJh+5478?zL#qu9)k7_zkfRW;|^Tj3Ud-J4Yk-w)t zSIAa+y(?P`y_~j?!uxwZ^OsiItd@qmG~p9<03mU)OO@rPhcf<`O1lIsv-a7OSf$=? zA|Ko))>~_x{jsMq3bD+`lF^!IF`POTe1KbegjZmtQ^Y5&K7ksgZ&@0elu!)*yn{7m zsh~LWzTuLO9VlPeZ_9#__|O%!{7ZvtUYICFKf{k(uAOrb{lwtU@g;}5=_dmx%h{+> z;@PDc8~w?tw@P8Y%BZRA(Z~5I--z||=7z?Z+>V&|mw8a0aD9VyX+j&K#WNSIcLpb~ zZghk{49%0>SA<0&GHCYCmRJ6M8V#NaaJLpBV497x9S44m`uxH3Q%QUj>N(k%f?XP_ zzv+SsOD}Ots4kKwjrskl%j|$C%CDCjR;TaL^_GU5R@gjaS9w!)%fwq@e_*BC5isy| za_D?$}mT>UjcZh9p$(Q{Z|Gmrd2b}OdzZ$qe8a=muUg#VZ(5J^9M>HzPkxgxAi>% zqHrgNT=U28f4I&_;23gyRTg3qZIbxaY5$a86N(Q4<9gxAsigNO1)^HfY~AuY*WCk( z?D-5EY2bs{(sgDTxdgwDCMPVmnRh!B&Zr@9%38pbc#scClJxkPR>C%?ekX!OG0%3< z5}fhuItga-4xHbC-)f3djhNVG#CzwgnH?(0VYd+1=4m&PHHZh@VrgrHW}BhUGsN!h z-MKjr)NV7}g>GZjhfRkHI=Q`d?=f8h=dzL}6hy_(BlpdgA92IZ+0wwC!uqDm%cng4 zp)wI%jq<`!DE%(dH7qWDDUXL9aq4@sf{yKl3@f#?F%RqTRY>qUXoe?Ya@_|{`cp(Q z>1|mA`OPtNpZ`19txGiSo+s#_I}cn|J)+6qK(CX)7-M!M0sB__H8*d9ZvypA?)Af7 zF8IrA77v{bpS(K%5Q*WspJ#Nh9M8x|BG+m;hh>zWdW~a)oc47Q(~uHV zD)76if-SnQKcZ}(_F|<{Yp7W~=;t1pr2_No?tCmnzAM41=aw^_y zB>jZYxDhrrsTF$}rrjYqjNsbM-^nhC8%BgOfKpY>dKUVaxAR>zLqK%-{?|a0Vt?Do zB2H^j$zA^?E!XH#*64W`T`Kxz?ySebUSK^sVcXd8Pew0GGV!r`Hvp|mBXE&m%Q^+h zU{ECVD$1C7#o7D%q?nuODHdRGdfH-Jy3;1u?Yi(df1>j(o4mcVj#if@CpWd+FjcHn zF)y;{-QD{V&M21qXz^a7g*f}D?*(((v}-55Ts|u_$%b2(!^_;jzO~H2ZmyL3pTKh4 zsn2)=A>W#3RV?YhfEoVWQ>1V1IjzWg1dfpMH(%jdwu-+zND~oT8Ku21USO4{LAW8UhoThp+K+7`|%>?WwDcEj+AHSg_jg zBTa*s%#)*s6)HVobaq3yx=t+%V0EUp7qeFDJuynO#ES&N!aKUC z-^sXAZVY5>Fd@~{I=eD;eX@zNT$}vPoye%pmTFZo=Rxn3Y!R8=f4L3(BoescS9DnH zFFnu-K6H;}Q^ahW$0Aj7%#=fvKOjlw$~C;o78SkFU~q@$&Dl9UO$bzENd0tx8s$Vg@WoKQx3Df=vN07E z=arBL?|Ry$VxQ09oaGl_d|~|drI%az@b@4N-5mbD*j1+Zokd)f;IibuXS!3|r#Rj?m0;llAj@%pMCt$O6<^ALm`5Wp! z@*>@dgu85LaX4yxblD%(3Ht7epxY)LvVMfc4F0VYSKrBjV6v?MWXf|>Fw!IadfJWt z6y%*HOCcQ)8)+LHw>wO@WiHW`UY1bS6wcF=(l^o?yvmHdU`tymGuVI?O%QR_rr1}< z?&KkV@N(v-$DX`_Kt=>XNe^xKH(M2Ag&qvJnDtT>og~ZnNJpJuFJ?k^FSOs~-FFn- zZR>9>CcpeDy;Qa(0Adf&H!)^SYpqT7m7U8xJsZ%BsJ>52W6J)Fe~eaWxJRebqb`gd zdzFa`+b5wm!03@?&4)r$;Ar82irp%3&;acQhZJ**6>WY359Rq0ANvnGjfKo_fzMw< zus=*$AaUQW7@IOY|BVh5;A_3Rb#j^|2yScha%Dk=gEnik!vhLjo+v~}SB){Ir?q1& z(QAmSCw{fV^Cg?fv&UQ>N~w?EO}3V<=}2Ao()96Uf&HmygyA@Jy4YJ$3g1CFTLSlY zUsKyV#{ykOmQ`4Fxw}b;Y$+~itmPiQlZEn@^%c2@`hS8 zyf;YuT~YQV2RlG$iQ+-3vbvhs6}0s$SpH+}KTygKPxn4VK?eZAtrX3#Dffx_IzOkn z;7=!E;0B-W4%cTHR@1T9YLlIkfBJkO`9A)4ee{!Fr*kbiSM+^l%k#?K0QAw`G5n>R zfR5|I(Buh&VPKGE`DUK?P2X~;N32QQYS+2B&0bGkORpVpf2dr8aVXa%VKB4rZo9G6 zE%GKxl4;bCF++!FG7__-d%5N5+k@ePwSG&KC%81pm$*8!j3@2dhXV?scyEcif0xHS8D07^9623J&Q`a$~3Mxn*6Oaqy4 zcf|2#0{qyUBQoKgpXQ~WWy<4>W;!&Cmi^u?)~Nz`K%*c{mTCs{PU7)eQ>@1k2^j6| zL46U|<0{Pu4TGeNKen5Pu^GZ&K)|##@r10Ja+1U;L;U|o*E@z+)@=>iaVoYewr#s& z+qTUe+pJVvM zjmQQo5yooj$mQ?}f-znBJbNJXr%xl=x6$a}fDlaqx?*^jx^6!}I%C^n)AoRd{>QDz zeNBSKLMZ?#$7$U@44I8PV?;Lx))!Lo2DB4$=xoi$#R%v+W??jC0?4kgR5<*+x6|gk z1o7O%0)h9CsKs=(%vGmN%glNey||j0_+C)*TplSnFd$wVOhMswGR<~DIAz;&$g}^a zaqVvkZ>R7ui~TD6)ntw{aM`eOjQ-5X%BcS0K|}yDR`BCOSd!i!Pc_dBM;(0auuBLL zS_>26n4j>no5MUFN9_v9kfw&YTd5k?UN@rY$coCuW`rvk`yY)RN;OeE zH}=$dl@{sxuZBeOkKI+mg-v384t-`*4_*QJ5j)uS@6UC=xe=}httA&$yIFgb^}s($ z@(1}Sx&nuqiFzA1YiI}dj`Tj%Ihxk)*Ts&s#Lum%gAqSA`d~_KQxG>1-~nFd=<>0h zK2(Q4wNRAK?Fd}sL6c=-FO`ww+_XzEEt(X{V&t@wBP}m)q|Q9$+A;cJCE8u-{R#jF zjlLmf`y99FUOXsr{kENi=4wta{v874x^FueBF*dqbKD-9ZM}wl1UM+mS?3Y1U)%$TGO(oCQ1gcSBk*H zkJWa1A+UHUq<6#o>@0o!wjswWc}(4eC>SkOuQ&?%7S~MJ{u`d(pXFGaN&_6w{yv$k zZR?`{cI|hU=FNlyVCvw-$(9xy+MBs>_I7nik)2a;1Yg)FaC`h4bve54uw2gBlJ`7_ zwn|TB>wUb&o=b181E-*ONVz$)r~c~2`1>K5^t9lJL4$X=j3g%mbjd}O?P;s)1xgTA z(KnHLUO3n#FIcMDKTXusd!O;UEEGO4604?mtf{TaJ!_RZW0I`UFHiks=$$M<(Mnwj z)iZaqpwy5gDIgg|eNs7L${t;nJs4FaNm$*cWGcaN9~<>W>ZOu;)};B$VJfQwtBN3U z@dZdzT9@WqOo;}b=i~e*3+fyu*Qh=+H4y@-%@tCWwrxE{n_3x1A9prDTPLmzzeMF# z?s$Jt|5mwd`^|`pM1rLLU)Wjqb|mKv$}E-~r}Bg~JQ)$Fm1y8ehS~M4x*FtT^SvY< zO5;usa>Qb4e=d_|8Q`oc?=$x`fh{U- zpIkZ!Rxjn+k-r-Ipl8PcFHOdvBdisHv`W7^7$d!L#+ukiDVNu+4zqT$1KLiRD1h%}?ie^`3ND?&QgVVyAHv=@0dNjH?3Zjy5@tL*OiOkJ}%xh~XH@HHozFrB=AE7-Ctc@(q>(K|UbcdVXz zr0%o-bdeSvaAWRam_jmDjZ%JnLsMjCh`8oiZjVvB6K5P-bhDTzRh0tiDFsRL-Aa!E zERztwedI!mRmE>Ln-tEzmc!+a^OQq>0adz2yx{K?JDABs>BZP2()^8?hDjTLZxw}A z=YuCgf!S)4WI_#(%*xsF-ZVXyO2~{$;Qq4OxSH(`znM7lo`v8uNSaL13r9{}ia=E=jdNJCdUyo5R<8>g z38ZAK_y{aVedQ=eWs@pfh|&YG+pq;KS&YOa6M62^Gp+E^IXqL}{5c!yK>0GeH-eQO7~Yd)1U+DlgpOtrR{@*1FN z%t;z`1ofH)SyQ<9-LE>XpxZAHez`2M(EEH@CgPnPd_HI@K~A5sQg>|UChk+#CwKT9 z?6%=6ndqJ%iIn24vcop3=-_t+chcVfZC)mIIqV4g+ZcL! z3}AkuV%C~vC!IXT7IWQ75+EzFdqO#j@)NNV+830x6+dC$UT+!LOIbhv1K$$yMB?|= znrf7{nTsV3sj3H}=VR0>JA?WxYon@Ud(BCcEZj}!i!1h4RVn1jmH(bP`SBWtFOD8l zcv#^%!GafqOTk@@Jsmzwm02t{?qU(p_gHZCxn1uBhK)(bzUk$r$`!m?Mt}#UP~^U@8kBY>+N+&PS5uvzj%x1WA`ML zGVja%)eVf_`*mRsL+_#R?Nnx#o|*;q`h;r`XLM4}@@X8|rh`{23s&w1r)vX?!!wBFU)9{QGi zXI~8mCJapAcAjNNeuL@PTjMbuqaDL1a zQoqpJX443)-FV;NjLLMCULn2DZ@?L_rI3n)NsCK)nBIv}Q>bMw2C$biu4P9c)HIA9 zr|d+aw zV#Kq!MB1o(2%A-*_e1)j_3?BJcrWwlIP> zvlcU~6MItvXe}f2JOY10mj2HA``4^hIZJLdc&3{fF!OrQ&f>`J>-Auc%GwC z1?I#FKlj>g3A%T|FJI}FU;?UVkRlC7GhNb7Ea1}YwS_vb47}bFdgBO+$+6H=JNgo( zj%8)UZfMd9m*PDyYu??>udYa^8N2(*wdx~XN}LlxyggUY!#9~Ud#m^3G`ibTcpFrf z$hPohWQ*|0w%8dXJzn0+_Mae^w&o6+bkVcgZ32Qd+wo+?82`qXMgS_>7Y!Qt0z7`{ zmN$p=g;lBe>l>fcFtxJv z@N{QtpuWCcdyU{&^{;I0(^*c{^iEGA$*7H_M{k@Q@GSdCJ0w>57W8h!aH!MD+}=;g z>G6G_SKW)g-XpMdJxjjYJ@QfZ$b6ihH0gbHRDR6O(RY6CECC{k-;g@bBKHCRSJnhX zpenWhx5H5M+nx1)Idx{RaPXUKXRsnc{^kA|To=$W`F4EKebZw9;r<~>)lLA1Yg$(Y z_XPeIjuJ%8#P^MEd`ATF{wLnJh^6+A+;FP1#ei>6>RSV;e+Pkaa0Hv`m$9P$A^#%G zXI6as_4+uz^Ev*5Bu%9o|Bei>r})u>_%99M_q2k{zg=v+G(bQ+|A~Kp<%b6#{ENK% z_3}ymtta?*XwZMrHTAnvJTky`jRUdsjuL{G)$gao@(rB=ixLCaJPcsXFT5^Tfrq3y;|Q(suiC?Wv8v zY0LI&c-xL$Xoim)CnwYM_#M^k$v(mt9%e8UcvjhO1%jJ@&9~=wZ3h76i0-JEMNHc^ zU|Y_~Y%Ud&z2T1f=Lb&+tgf~<7=Q8CC+f&3k}>9cWV&yB`{s;%4k6p>Gr7?g#&uf((C2ee;ax}Y4Jy%hy<b7Vus?Xi5<#}pq*nkls5p? zs{G1K)wUI_5pXpIbD*aJ_3RtFbxS=zPpH@P3M%wdyfvW=qimrmKyD%AzN-3}DC}c0 zcrUw;jE@;2z^sj13sZ#7k8Rycgz7!EbbN6)^lKX#D*qS2p4=n9KZV5zzE#7LSjGsf z;;i+TpjGar3EjP({32K3f_Xe);Eu>RB1nEO(<2=Yt&({ylTfLtnX%5sw(k=rjO9Lu zW`Xk=mBv7jrHg>P7*@eG^RgY7uNtbkWP}nJHp&>Bb_3yeJ+exkTFDBj7IYQ55>1p* zT}y|+wuBN@YneEawxi({lCgSXWfxz`iA_2-sdTUw5Z!gD1RsmR4J(h9L{yE=mi`X? zFQ9)<+EH(y;0pV;9j4#s{J$KqrtvSV+<(l**5zzF;QO!+d_VmEerUg)%p|DnNi;(48~^&Y5C091#lt~s!c9li_y_+#^UZ|*i}X)C9Mq;tbnNJV za2O!`v7T?~%-_oJ{TJLv9SN!_QUz)DA6z`LU&QAd=lr&nqW=ZwIlxA2TIxiO`3Fxp z%pTkRo}R4l>G@CTq^aF50a(*Jj0%zxY+|JqkwL^vo- z4BXgR|42vh2CGy0R#)-+!Txu(PkFIz0RIy+QE@ww(C|N-2pI?n_um*gV+$u|S_@lK zJ9-&WWkC@^Wx>B{3U+I3h`viz1l6IyS|qF&i@AfVv<-=a0)H?aYIEh_X){ULl1k#0 ztwBF-+K3O-BNA7!(Fww3Hr<{!ZZ6&5VN;6NZ?Ea6#Y!Bz5p~78z*5`&fXhYDtW&qd zs#3T4ut@=^wJqPLJJBo4KRh528^ierIL7RmpfF7^WL%k$)A^G!rj{0=jJe38*#WAE zq#1sI)pIdAw)AlW{Br1%U7lOd59vHnlXwdb<-*|E5cV@@pX%z`8>;z12n-_sSpoOf zGWo!#)4OLfOv#unbdY<$XdW2nq1w`eMmB2({VqUloJ_ssSrAQsGh^y>PxJ_x=yriD zcoGz%_5HD;_@kH#QSL{n<}&HhbWOw=z7?Sos!}bC2z1(^sGvf}wu!0{kHqFsUMPi+ z=bT#Br*^XA21e-69EQVt8UKDW|Go?0*Hww=P}hA>RHP(GAxN=te)0~0Yg>m`z4B~` ziUWXxJhr$0c=&$miM^8SQ|rWtm!&H!m%YNs6<%Yww*p$!KI_n%_|r?kq9MTn0nnYSHBj(ZIvJUG}K?QIIHlBM=(&WyIS~?9Wyog15v$LD5sz+E; zr(OCctnghqg8>qUu!*$s+(z~SG>n8_e!ffyPZL$vwUI|zbLluw1sfi09^3BvC0%wy z+S|Er?F`0Rn$s1py``2oMN2D9Q2P1Dl%KfJfc)T~PO<}(6pC97aq@iZ#)*cv+9yC8 zP2M2UYg1Xx^)$heIt?m)>F&o7>L`NjFhNc(vGpM45;M84P*2AYz$a znW`6(pVG%DPk?sWmVHq)UX%=jKuK6xg2UJTd_owVVGtta4E7vdkcj1~Uxuzt$ss{o zb7^P@r?21JX!WOQo2K2q4goyrbOS&RB_2VGnb1?HR8pGb$O58Go8@}`P=Ls0BS!R` z;RYYB?rE948ZY~3aiTh5C^6f+>)C(2=r zp;%+pbuxZrq1NX2JgYZ^;5AB{Rl*AJrD?sR)ij?k>?cIVMn`F@BxTeyZ#n6bqfdW| zI=0i*PGM3^XJx6!Zb40fTuEqK6Jx?W$RG|=e*03qm9grQO zChQxhGpnA=RD*Asu}V&6`fN;LPg6wh(6AZSAW z**YTM2xFXPX)ntRW6_|16%T6CUAdkwSa+2F7nfEKT}*nS+~l{eH3r5JA0(I-Jgqjr}AR! z!))`n<)}K%0*;mGbT)vu_kQc~wvHHdHucE{-l@o%$+ID~6`j;f!b6Dm$Ymhsh-})0 z@burG2aR#K=1MVM*tYAEOU)L<2A~hhnj>t_mon15^kjwz*nHEO5ucSi%O;sOkJ;!S z=;3z$1#Cr`SR-r(f9`HN3}9L@qzIjN&y%Zb!%(#{*Qbuo-0itXve)$g{)a_Z zfv+50<~y;w7zhaG|7F`1MTO-QMe09BYV(I%OClcuQ*~htrICX+@)88l{sJH~Jtb$@ zV7n*u5n)lKxw-LHYc(ERSZVR5+1!_ai>|iSiVyzE^o5n<)~`7}SK-qh%+D|3XXVvC zOo>^(plCGa3aC&9+LGR9d+jhQ%Wh|dwhcH!w;v%N{1^1n2PO{~Q4O!9`stlLdr(e+ zC6X$DQfS=jK~Z~YzKx0Wc;|3@Cdw{i#(Mn1|e6(OQz;PdDwSREBr5JzEz5M$X@29Hy!Tu2AuGV2+`l2F%US9 z5i-Y4zqDDQIdP)ZxvHB3CElN+YCWS~SE=~{f0G1_QPq^Pb}(}sf%MC}#DBRLO4rOT zw&@yqWHrto%Q80i5gfxE%V}V>D);~hS8W`TrIb<=(Pl0)pq517%gZkwmpX{+cKtD- z@ZtMdaugrFY6XFDRtg;`-i_L@8k!D6hvbUq0_s3M&tAFY-j3+b|ZfBtrY+0 z+|Cg=z9rnO>!^)Ig1|XyfI`1>hXNM`*q%$hb&nd=UD2(O4Gq7+u8FU)d!R;Dp@2cm zovL@oKuXA|mIb_vm#fE+h3)D8C@*O(LkmBmQgNjS>6o$$8(p?3V!R)uaBhl*j=*>x zmFN>zEpn%qZg&c_KjRT(XfX3G0ynqS#7iM6Gf%Nh@9ZXdg~*USk3o>|1|dj5>L2c29h@E;YUrF(AcAax=Zy17bS{%#Qp|t>uOvDK zusAzI%9g-MXhlZKIS?$#uf>q~ z*=bT_!NIV0heA-(XGnppWCEoFaDf$uAsesY;@f(ttKjv9pGSxoCO9gB1uoSQ)CY41 z%`xWx(4wS7!WX*zfZw^&dV+cPYFw*m>eA5-t}G!7YWm4<`kkVNJz0JV=$k3nh{QN3 zEh$e-=sRyvJcnA3N4)XRTrjBjR*wbN_)%faxyBV^-Q(_GN{lPhk-#dO+s}t{}JrXJbz*ioqy(peYb)){U23d@2(S0VD=YvBcP2)-d?TZ{?C#}1F zCuO%nr~E`p@(N_n!O9D)*(8hCC!vq0a3PG+@Z*@QkL2B=F+KX%t2w4NAiwK06x;$t zwa@Es8$*$pwlQv-O!vF|0*VQ~?Jp1uGEY@9)Qw!Q=S!=sW4=>9zVHS6)6J-CoVO7FhMI zzI&KYle(WhmZ6mld8CNd()l5-|2BSUKD%rm+W~_oDZ;yMvwLd(*2YNGrHM$+kUlPL zF;~VT+mAw17R=aqz~0=1lkgV$?h^=Xwsl;wSVfiGN6+Xi$HMow0iG3fuE@C_SR}!F zW5fZX9h=fCdBjhok4xr@b&`m8F+A8A`3M7g*jrxq5+!7_<)S~99xdzs*R$&9bJ96m zi@Wqs6Wzs2y!qngF%_Jn{Jn#>Po9^aHLey~CM2GxB{K(bfDrm;8^~{0ip$&BhcWBH zyDvJfc9(I6PZH8i!8tL!eJm0$I!agQ7Ci#DH`l(5bz5_< zpIGetzbaxs0P#NS=3d&W@}h1WFZAoCm1Bcm3urHSx;TKM1+N_%>f5t$OkuxHb&FTo)n)W228$n?>ov(7-z&O^;LxMjHBe{uIQwFY!0fWD%} z1c!Cx`c1C|BVM60JcVBacr!{KD~ReQdV?=n-Jpo20dk#;l73+a?#L9+L1*t#ThB5o z_Pb`*%8m5urlR`tOE$aeAq@+Rb=%0tj&Mt|hylt6p%Q+HBvJY1x; z+qy@g+|Zr+>)Bd!JuqPV7P<=0X3=f%9pWRcG&NzlVFSBF(Z6=!FP1pUC8+KVk#AcF zeH0KX0Fl7qSa3$3!?|jLk74=6Gcv=``L!)byXgkLgt59Boe^NR!a5;}M{^52)6!g1 zFsTetX$J?T9gEF2_G+Qiw7*t`r0vK2eT7n2uDOh`%KutC9!?%(x%^IfCLFF$?WZ=t zXGO->C`&<1Yc<(LMm=1n*VM=4xY7hM zRQj|ox^X;jh<*g(5>+ASn%F!f_qf{C$L|Hp>@^OPkhwvA1O^F?0qa+VJ(pw}b%XZ6 z6L+@7cWu|F>AA^v;tiL1htyA$nd)?E~h?#~iDyRvlC15%2WWNq^g?tgVJ`KJilJuTpTJO$g z4iwyfJXXdP{EmhO7h2eePfQUGkQGsMWY=qGEF>6l31Dbe(`ZtR|(7vLq_4a7Djce;Uy45+|ZIb4i z-K|*77*S#M-BECbLaAF5#_QJLiQ)m-ui0p^x-#bRVLVqtr+>I3$1!Q_hai4t%6b*I z-xBXy_}IoUb#_16i1%EfpHKsSbe)dBu$|@c)Be5hmh%|lpuruGD!1321H-_D13VdF zXTX3cg16B%QJjaBG`E^AH-Nw~QmxY{uTajZ`OjR>+`aHtK;YK?A`CQr`1?~@eEjl&Q0pxksppQW*_=iIc{Z7F-T zwV~al;#*LTp10gox_OQBWu?@0eH(LemmyEWzd)gAMm zkt#4eI}$xL{PI9n&}+a%Vnv{=^-|s=FYhjpP<6JPAYXx#q4e=aWt&!_94ky8@?)%Lf0YwUX>AOytN}-YD=oLzbJK!N z&ytt=yIP`W^iMXVzxxVAT(FMG(vZ>xz)bK%X&l)P_p=_26P8dzz|TQ@Lv2W>?RJLr zY_&)(Q+j<8Z5~9nW%08O1X5xS`|92#?cgn3l#jDgu5_nUW9%njC)c&P!hDoQxVoH2{``VWLWiJgZy+kQ{xxaV=;E8<{bJo82%D9lRIwO%Y3>j9DlC zPnKq(T&+bVky??Lzs%D@NpC5t5+R(oIj}Rclax)ObL6wx(g=IL(y!d9=Fc?$HuNDy zL}Y1z0RIxIJ;BB&J(5kX_eB@<)F4^T_P(r~;J(#++%*X+=>&Ae5D;vrG&Wtu{q?Ha zAZMpK$AmHhtoME@^PXa_)4Ae+-I#{6OCe)hf*8)z}67HRi$v zavkg=o&A+rENww=wALs@XBk{l1~Gh4OKk^w?LrttD6p0ZCH-7xs6c&W=iW>->s3(X zwIs?{jTEr8w020K?B3j%p&02BqPa`q{3rj$P2{gnm;=1zSPHm5!fmy1XKLf;btpk} zncB--dmeHOG;(}#q6x}d@hd}8PM7*ZORFU&OnF=5Lhu>`*^kQU^)lP6xFZOey?eDoGxxU&H%05M)jwOIyi^JdlD(i**9Sefj%~1+%kA8vq zQiOQM84o|x#Ul(^VYRv|B8GjP>632(IT|KRksLhdTp#mO5KO#EE^o#L-{^IKFkHW$ z-H+lf&QSJkju&gy`6`NPqI=hxJ84GAAu^IPKbIR-44{7fZgrFJ}qp4 zP@fE11s&AtMuuE3?1|)d+$R6k_fT}h`f<1D1CvXH#zXT*H_`+_4^93%b+5$7MO0g* zDfFR6!?9zfhv4O}zzf1-hpVcxnbzzZ=m4PaIWOA@GoTSHn!jFq7yIBs$bl6VA6PTI zu_a;a{DglQVc@4@^Q55w<>ES?q-a~s02EURO!d*P#E@bKu^mRpp4{PNT(G_8w&{;R zx{imPPP@%O$;tslJPqQigXczg+hF@97~Yg$*v;V8=d3YMlysbM+#uor&1gdGkSc%) zvtjZNzFCdE_Ni4Um&In9+c~)nt z^x)nFJTf74Ix)Gj@F(-Y#De@;VEgr#l5_bu&!sp(wUo-E&GjEP;GPGmh}TET!MZF7<}5Toxc<))s&7Y9!&ox8ocI`S6Xts2D;h@es%wWk&jh+!w#3 zbtzrlOu)Qo<;v~#;#}Kj&N##{(Sm0chKJUP;L`-uO;KP4W;u5HarR7epI!k7AIa}c zcQwB!qG`{i*4LoegJR> z$X1K}NHO-6prh>{3MiAOnb>pC$=GvY=oqRY^iyg%2anV;w7Et91^tXG=?#O~8GR?m z@@!eF(i2(hM?pUJ5u0F*I{WnmMz!O^f5$++*N77)XKfb^5^%zawVA=IQ&= zN*~P{JSu;LP;V`Jc_Tl5 zW_Ah1u?(ExPkwK^-pKN*Cvu)mxT$7U6-g?+RMw=ydG5-QQR(f1JUAxG8*kEf7>3CL zXW1>)Sm*%;-sN@1cM9N>S%bEnm$d(-7m)yW!aj>T#mb9myC&l6$`O<=do6xmV)uyv zJmco?so3p-$P=0sT4D7%k--efewf)zB)NC40dLpj!#{z8_>@O~+p zHGbq^h}kfMp1Rc2C-Z9R$x8x+-#)3^jxtz*7qf*3Z&k9#3Bj$pvCjm$M+imjl z9)2)auFf|G(M(T-K}cU*JR+aGO^jpk2hSvADN4skVHxIylYw0kwf1T|{zG&C2;;kjte6|H*JoPsvd)hy4PdFCf}5G-Cr`A&0TunsI$4{TklU+!s}%+jp494!(!) z(Cx=9E$nL_UHTFV7y-sU%GIBMqYBJAgymL7x1RUt4^=~e zDWyhrY`yY$y#O?;qSZj_go@CstWjPf_3FS0P}LdYDK}=|=EVRt>s=ia4*umaY1Q2! z(?VRE>nZu$t_q|NAFjce0p7YG8$wp50(p1L2(6$1+r&T@sZ^J^`=3C@H$^h)qCLtG zsz@IFJ&&s0mV*ZaOl+V9tW7LoNvP599uEpKM~!d3MemR}HY+;Un~cQTb8mY=E-N1R zKYuAoW!Ab#(|jbBi33ZudFbt+zZ@ znu+psUKXp6w)PTr+M*uOzxV$1v+|H}gF*0DNhFb6YK`2P4hUbVIZO|!&Ym;@AbtPz zd%Hg;VUEck^}0FZvhnL5>>e`JxQTxC{T=$8VOvqdVY1--U{E~S51sgZ_Ht9(*b(zI zoVUd}lSbd9j>r}IePhlg*@a4X%}fzExx*SMcf^(Fms{*Z>*Ru?CEX)w<_+*ZkB&mG zKo|)$ur3}3@+79?%KB2zec$N-Ypk!;?jrXeD;_$&dIaP!@hDPyjtKt0QJjG328}7O zow^8O-!Yzv*;k}>u7lGOj`kEfv36c;UGJe-gUgF%x+k_PnL@FNOj!K7mZwcZ5w|p# ze1)?&g!N3ZiLOP1@+QRixy;~jKRUH54Sq7p1kGkNAoeatLPIZewF*-LPU{%#R4GPI z)ue(_#ia~x{OoxrC#DIddFXF}>x7`oJ4p3Uy)Mx}WF0?v@`M1>msB{qYB@4bdGyNm z3dw2RE8+}_4Wyjr6j2-(8y2V%*s*bE>)$(UGiCeE_k-{HlWPMQXHBXhyX*xTdVYps z>2oHM{hs3tdc`v|o`DKLqN4ah!_> zOGhB%)>F}eOD7JwjJvXF?ke?R@r?$=z5Kj^U59)q;aFCIhqC+8o*utsOBh->=^9Bv zubNA#6%qr;I%Rm#0z($*E2p@p=yt!P6(Ad0T!T%TUR*(_I5`FAn6D4<8shuYI?mC? zZpNd&WZ{00*+DP1rh|L3_9+WE2D!|>9y${tKvr6%nLA-4mf$@uDC2iSu%$Ch4UEMI zb*g*xObG>W>8R$V8!BAKn{8Jkubg zXL{>^+g*u4u_go5f4xGt^@kYHcp@Tnm-2>mGH!B-o8wi3WxiyK?qoge?I-J9StzsF z&)_i^m`ic#p;JC^kJUn5hgk*4;NP7!@Y_YkD=whBE&QVB>!Ue90be?x-iauOZ#Ks55Sn=_DPWw_exX^BiMS_ zhWZr#@Fgg5ugu{Xf55{Mb#9~AwZF=vtb!4~e~bfU(jV#*jQ{*OLi-j_1E2zbDuGY` z{L1k7qxAfB5_(frnoMG9`qxkmCY@jI~jY7Ed22-UtL$DV;AFA41KF!Gw7&0JG@4frfiHUb3(9dh%uN(foTQ^Te zZ8$H$3UI)DqsUMk4VdCVpKwjt40z>DAf~N4#d<9njHtJ<=0455E>GADQNI`=oJcryN76&~5<00CM3>P%QRNBITxdixX#Ch zN%(M@FstDJS*>iVB$n2V1aa4_8pHEq$$16@42D9G!lPQa1GO0P%ngQ-ro+VwQ}47z zkg8HmXF$a_)aXmw|E=Gb|CxK`E^~Q_fp;n4kH?8Z$=%JRgd^@|)$IoOB8q&>LGme} z|40zymVSQ=kfKM{$*|cE@z0RZ>~-{M~(;bB`Tf8 zxVdhZHj@h6>};^HNdd&4AOvVGyvc0&_NZc5mx&__+B-#qa5W`F;6~^lPrb9OR!lRP z_LP%Lat(CGG5v$gMs=efgH&e2FT) zL2--7&87Kpejwi?qK_#;G8!yIlvgYt;$>M^jC$}M{Wdgc8@qAb)hu2%K>VcldiCj; z+d)KxD#dr61DpQ+GZ8Hpts*^|py!D^j!|fZBlNwagQxB7Q*;#YF(f{P5#s~cVn-gF zXK@RGSDoZSJmB1J#!q_gG!xTUqMx2_-8?Mn{!S0w66PTt^1*nI%UJb!uwPm+DxYn7 zrdAq#OhDXXsc2XfFj}?B!vcY| z-`Ax!wpqk~(ie}P7vB#xDYmDILLDHW6a3S_yPPpS&Ci_r#tBOPFt|wI@E1PL>~Z9B zV(mTj^@590nZR1kz|BgA|TRvr%39s~aTV&w(!jMPSJd4G-> zQP$-@q$zYc`uOxPn%&LfK%(vICnP;l6DhER7?S|(mojf{iGV`zQ2G4jmrgIcsfaE8SYP;g+$Q(d_kKnB`c^Y_J)(l==`vfZ zdI=xl!lFbAep>J&v>6{@VSh95a7^v7kl1Hv4Gq-^j=LrPOn^b-xGJZW#o$yPGg@56 zB@4tST%>F~R}hGY0?(k6PwCQ2W~O|$+B(JOEB18K?$BE0M`-e3OdI2DiKn^3zO#Z2MYHh`ewq{8o`$+ z?MlXD9nps%J2KJ&e!|kxjD6{bC3p%p&tCYjt}Uc_{Hiz>Xom+Y&C${s=#P7(cR|ud zG=ZWJqK+})DB+V5SDBw!@0+XN#XEaFo#SjgesRUgx^hGTeENO0^f~x(UNl5-wslwI zDSKeO5a}(Dwvi5gDjHn})CI5#8}soZN1))>WNYRftSm(k0$CiFJY(4|C8AS}e`h_W z>(^UUX=b`^lOh#o(au~6Uh(e}9@jlesmOOVflVq60U;$0+1#ErqLeNZ&jLj82XlOU0S)L zkPcJn0&FYZ*_z9b)RP zz$Dim2|@{5r9O9f+`I(usHsWLtp}8eQy4GZ;Eq2vrLAu#S1S8XSn7%O-%3BvcVBYa zaP9&{{fr2=K*ci5pWbu1|y#%*?!OUG5BI%zvvgw0iP_AgF`wTKxbROK`7mu}h5yld*>MIZBfvOPjcF ztHp#gt?^ItLI|b_WD6gT#~uSd=;;dkZM4fJU%Y3T!3|GK&T0UE;>zw!uRjwkoD+}$ zEpS@v#s>=Ir0>QCx|YSe=v8=)n{0o3H+dfD4?}qs>tzp&hnm^~i$flTuI4J%tdOhL zUcipZvTA2QA*+u|-jBwQlV942zcgXh^!M~jMHren0=qp)(-4#fFg~_L*m-AmIO~v7 zx%W)^>~4r|#?-FSCk^N6(62nNP$Jwlg=KfXlX zk!LL#E?1Yt87PZDGj}AD3693~)WFLx53xP@jD`@7JpK1=2$3*91iU}@{#H$K#Ce?J zy2Fkz!JEmK;qJJyU0ohbrU;te_(kMSVA;-$#pKvyz6fk2kXOleK2uh;Mv49gY=V3U zaPfAtMeL$4)nU+xx|$JEYbXy7AxS_tsize1RUGlNpKKnU)nZ)vYGQXi;-3O>g3XxCl#fIaY<&U(ds-CNPn4lWDf!lY!y++i-WbH|7(SM0o*G9g|{S%^W zBUWaH`#@{>75a8Vn;Xaamx8#j@iR?BQfJ z{zhec&klCde)kE#p3*10cYz&&NR~Vq@=(t$88^&*S#>CuYO5tTdvOEI2VyVmQMblG z1SdKIXqjb**%g;UKuJ(#VP;6bixW!Euh8Kzkf5N$?19*9k^MI-UX0YcTYtT6tG-q* z)Y#}VGzm@#lfPnJXqr244uo={gxsr8JD32`IN894d__JnQ3qiALqcr z*V*SofGN%n0Mpjwj6X9==?&5XkB9XS(w?0)dk&}(ABrOBeQq0F+1M759itnbbs=Bm zR(#KSmf%9#n0sXt7%O0J$0Q2rwD8VV1~G#8Kt2|+#&R@~Y`J$Newnuy0ts|8y9+k2 zW>bIfMha&@qw5vrB|PDgJ(??pc!!$ntgPpar*12+dz67jROHK6qFK4xQL5AvP?&d2yHoD zN}j+CzyOlSPpO|~!+Cez;%qnBNW)RVizCsTJyqMN&haDN-NblC8OKYoXD`JXCDL72 zEYz3D>kG@!yiaY;jF6sc8lyK>Np9oB#XXbFS~_^8261L-Kk*U*r9Hzh1BRIOpEOFLJ|= ztKj})UJdYmKN>wp&%SjpH}VQ2^U%Xn^6d66hbh;iTpaQmfAJFgwlmRaH~X-g(i5Q! zw*Jv2yhy1|DPbC_WqKW*F6{Exs6LB%0;6^GBkP?4ni~)J)km)%yA)W{u<~I}p>i{J zQ>wBdLHPY@K&$k*5z5}=V{sKKCNGAx>|XH&*y@wtF$|1wUMMT{-=JHX%5yB}_|wTZ z67=`mr>YgQ(SP%oVkB*@@68Xkvn5*>dhVCz5kEZ3?#08X&HA zxb;!cY+x{KkBy+m?Lbq8AcMK)VwY8!ky%W8D08oIH2pQ{Fc#t8qeI_Cy3AdqO7rqY z83u=<9du2Orq5E%S$=Y8d|Ub0vZJe_@RkXm^taoJt8Vg_jr;o8*hPQTQXLEmI6``P z@`Y4NM5`ahvSE#K^SHNr?wv!^N5`ejBZft;OF7f1-!?Vs5No*Bd_!}KuaxA<4+H01 z2y-K2#1+ml$$%6XgR!^~2W8~%Kz{#dF^YNO9N zSEy>ZAyDP@=$Kwxg~&kRjP-Xx$6nL4kLRyqN`oXCX}ww_w0-)R(Yb!tG|p6+2J@1z zsJ-Z6y4%ztW7$;x-AAG6#!Y3Tgh}eyOYtI27LFcLkypxwlBh$QL;P-rVpPYMSc?q` z@2#AdtK#@@BI|;Cwbt-`^;EgwQ)BK$5rJ{1^r+L6?|N|w74&e?w!k9)nvNb&Jo7+a!pKZ=_8r^Zqtd z`AhTr;gmr959V>{O}b~io_Esst7i00#!dT`;7D}%{`&aPK&PPYWwfq(TFumZc(MV~+ zY~&SH(zVq%#(S9zGEWOIRZ#6W&9$lVx{;tBS9+u5_PfV!Vo!7izDksnKWF;;QD^-? z)e@siNT$=L3KyC(p=X}bKwPfK{p%0IKXq3Y=AI&GWSq~R*nhSoie4whBQ{%Uu zg=X~$DqRyLUA;fG@fr$_%m1`CIi4tupJ=sO{ifTuZp-NHWL5e1?=XqfcaAs*liyFC zFJ)hj`v#5@T%PvDA2L$%RJnID^$c0pvu}Tn_8M`FF>bA`4qS8Tx4avVI-A6wbKk2p z)w=byP8!BPT#otEz7c2fm~MgbUJkjkKU-z4zcUO@d4}mQFj~v6>#<*;5*uRBIFXge z_`v*BRco?Fyu=>kYy1V?KPu0j?C;`lzaI9;JR*9A{lf2$UB#&szxiC_>-r{mG<#!7 z^{GwKc_BRvTVqmvb4_s%JIV$q{`Q?b8}Y}#`o4EsAtqlfSw@0iiuDO!y}SwEiQ<8P zKV>9Fg0s}ZldGqmOXVrzY^?&ify64piUa)kJfQ0X)H1)3hTiMzTi;P~n(S+)7Aho+4K ze+pK523ra-vaIy|AJ5Bw>t37GI6~|4j&AKs&mEWiOD{5iqFQwTkp+o2~-QOTQn+@^>A-BzV`WeY&c6)SYK z?GRd_kVikoX0M0SMvk?oREsF@FFsb1?8;j@Ti&knPGbRMN4r71Vbou|X7MbGeZyq& zrjkHj*G2S$e_a(c;hy(8q{Z?(uPLgOxQmYJW4?_uuB&-f5amnhI%H; zYrk9DLQL+{sSj}Xo%!ObI7U+X`O+MRu(4WX<<-|Y!>9H|aCN+j&(1hF>mfD1jAkFb zGMa2NT%Tf_cmc!Uzp1RHjk)aY74o8!wX^ewv#io1mQri2gz)%hz79Xc<)y}B?Ot0| zk4>$wxo%Qgd$=`}OREbyT@!roeUREM{U&i-1fTN0y$Jy)UGudigKT3;|1CxROm!Tu z*z&DNc{!DD891iu(*Bc)?Z~NBrUvvs&+4XRwW;so6z5$QF=V$;$=UpBwN80rm;XIa zpLxX{dD}DmWg@Ac`Y>s^lV#Z2SIg7sBRyBOS;`jaK6wY#cV3v9<6NKL^T2=1q1@~? z*=dTOmd01Vi^`u&B~5K(6q>sF(l=V<(~4)E?xmq%#maKAC&_zdGDPOoKMnr86Ds>V zYK&;`Miy7oe(7s}FgIQ2Dtyi7+<9qMh*#en&yAh7yGNIxF8rOn^b>Jir^hWp=KS$) z>+sW4Jn_&7L(KfUz`9z-=Kfii@-bnH1c=&OElo8~l-2HDXh}b(g}g+|kOiehO=(z` z(4TuAo5}R^{&5?MEPNHB0gd@Oe~zP2C(X07(RL&0c_l!BJh8%O5O8)~sAI?}JyjehE* ze`xGBYrl^_nd9!o2WQ@dS8(w~e7912xq0|8iRe91=Z5*eUlwY3#tawOG&(K1?7I%F z3a?diGkETapgh#nwG=l@$^Z+UsXIa#3%y z07LtebAfEGW|}VS!Oee|yi}c+ZvU$K4F9xp4Nr~mEe9BSkdd{_hRg-)P^kuSlIe?6 zVRCI6D!VDF9W7QEIKKs~eX3`CDF4vYoTRPDDWx)c0kc17oUuvgO~ucYv%(i&UARZ% zNM>^OSJvSyZLNLd&g@s1`u!|lmZUiD%ehyf7+CRYEm*@(wdd`itr+GFo%lF-diTWP zA0CY=xs9GOjM@w)y2nV*HHq7Eebkn7jQSTx9=)|D%Fkw&JG{Ce;A^Y5BJi`8Jabr)g&yRu6 ziiyjvdpi%N-I1lK>`9b7j_Ge8meUyF>wpZ@c;#yfPt7sCEcg*o*KJf>k)fwcMx^JJ zURkfW$-6ws^3DCL7PsvB#v+B={dlx4|Go!ef7$mOF&9eV`x={2_?UItX|A_$E6DrR zJMEl1*LavpVke%>Kv}TIMJU?<{Fuvk< zFGv5eh?^stf|l+}B~^P5p7?amHq(^*5?Vasg19^Xo}A|?!Dk(L6)V4*{21v{$c!;; zKAmB+g?c-aUny_q&D-k2ozxWNq4UA>=p*p}%CFQ4gPI!4D)HVLj@lW2{bbZ!DA+U( zGOS`2FYjeJe`;Yj+TjPoL-HyEBnC7}R=l7MgV!4@5hQ_KM zR(#O@a_-Qm#oG08mq&Z=J-=gPDtU~3!tRVSWv|=g$SD4nE2fpadY!_$6Bbpvf3j2B zlj?j%KDm-T;A>)rPT6TmL3CjrL|qSrHm#+S4MZ1hbuum~h6Uy4K@t_sYM9?|e$$zl zTU;queC_Yba%NJtmS<)8wB7m}mwrshu&11c!SzA^%hxQd6}9fL{h4ZKPP^CWd{GAV zOiZ%v*@0U+gZ!t{?2>g79T{6S>ov&^p`5!vzZaYyyc;d+dZ35bhO~Za^bpP+v&}$y~^W=Rh7_PV7+!vo45;qlFY3bj{cQLl5^9fBpL#eIW@FrP4 z_U^Bl)c5}1k47+yQaR-wKkNDW$lEXyiiwBA-6V0UP64mKsz*&fU8*ar%+EfnJ=}5U zzMpJ~rp`s@s^N0|42jsHqXq5P&-LrwDxX&TLiw4wZ|L|f9Un)9Uz^5-GG6R0m?!8H z7q#kCzFc>~FwZQwUj4Nn&HeA-{rkeUWydX>7Um1IR#JQ_ErvVdzI`_Db3T>uPydP{^;~}Yu@9Yu5mp0VQ%?R{P~leUkJ@16(tv}GWKP-= z#L=lL$w}Mj5RQOxLbz z@Uh=o@>ZNzxYcMw=2ppXV_(gFha)y2N~_RKB2TWVpj}M4ow(PPivC)O*o;&O?>J^$ z@vyJg`S#g;QG5qHl58)%8{B6g(N|tmWJ5bg5!2@BZ}wo`^QJU&26^(U)myon>RT_S zIyzoceUFN|Hgt|YOQP`kdE)5(imZcG65%o4?RCd5MVMHs%6yGV3HasSH4*qu=3#1< zY#+s_t%h*)qIz?%abdo)oBY6i6I(qob&QYKnx`u9`qR^W(2}X4conJP4KC}E$dMw* z?wrQK(q6EYbiQ@)v&$rxB=JFt;`n9%h{bP`?uVMJNSNB_lW4T!>S)zuf0}tGvfpWD zov%%OKo%4$JRLace(>K?YNAYS!$>76dX4C-pJPDvuYo(H_}|dR=?Y)Uo1UEp*8o ze`BcUAInsZnY!N*ar&63K4PHpb?q|upPAa~wr`!8b$vV$neP_;4;d#*|1D?uL#C=3 zdN%9Pz4F@q>V_xd>>~j5*obp~tU^^x& zy%1X$Vkk4M_pbOinY;3}pu#VV)5Jftob+rNGv>yRFpqe=8pTBZ?!3{|Z|tE3WmyF1 zY&lpztbamOQW3&#f4XLkowjZyqu^|?kl_s@EzHKxk2(vcULgU2Vf4DbCrt(gvbf1G zpEFX#9B6L*JQvOAznD{f^4{J`w~=t4$cREO1p(pFY{LsrVtF z>F&Q_kH4NEuTrJiq$Ga40vg;*br7rVu+%FL?fw+)DyMsf|GRJBxc=Q=H%IOk@qG*! zHzZy3(k1)UhKc4MN*Y%gd${tWk5W45@r5`H6Q2Vwc+<(V_!w4;Pm)dA=eM>x+<1G! z#lO03R%reG_*jriko4$XGFA>Mi89uwxsHc#J1$0rzO=Zp_+Hb%EnTj**6F>l_&4Ur z4Wc)xB|k55y&Fp3(v8e-J9K)StP3smvr#W|v583J4b=nXaLR|&S|?*xUo$Y26xC;& z?{C6*GnII?E2@c$rx+9ju9N;dK{dD|**Ih6 zlFQLgIx6p%>@1%+sVAbYag*Mgpy@nbc*JNiS_;E$#@N5W{IkBI@td4~hWlvtXL0I5 z$HF5LDM{#BmzmChQ=Ue9gar(n|D1f4RMXP*m{{_0Nm^z^$NcG2;VInVZyvNV+-Rpr zXFK3hpaQ-U$l3M5!!>z+GoQk0<0S{Bo6;^1+jGJh3v$m|knD3m*_D4XE%-!|)}hYs zKqlhgLCoZd3GYlT@WSJE$t>rYqtA77czzrX8R{CU$=yJEWJ(c5kIvqB(c2qXeyXo| zAu7>5?d;gF;k^#BBoclO8e7fs!YiHw6%Q-ixk{s#dQ+9f?j*YGvwoLxLz_k9s7VnA zm5HnIwKKk9tnaG(B)+Q=t=ZhWn64b_`QD}WS><9PM%sjt{drNMxM6oS$$MJ)Pe+El zTh^~hwob=pi;BBs7GSK(%QMAw?i?A`m^nQ2rKrm1pBtCkvHa36L#G7nK1QJEFI;zd zI?#PPX>SCl@Ml3U-L`!_%vL=;{RQ0=(Hf!=&kceG2A`@?PZ=6zt{O^9b&rHjS~6iC zqQjr~8^>X`?BbIonKg(`-LaHs;Uuo}w_0tNy))Pto28Ie_^Q|~Z1bCA(0tCGtQ#Ri zUwTeoc39^wpYa;EW=VGqKU%fWs69{hgV_8(Y+ath;8zEZLVD`WAMVWE*APsi4EV(xeLTbKp1Uy%wmZLxL+T1W1h=qJ}a zIik4da(dBCC9=-w-;%8rW;)Jpwcu?RC*N0Wt@gWLxpS9EOT0Uy}tPEp~b;;i=-!CoXR)_12uJ^@k2U-i@pQxcb{hp4~Y_C z@-Jnc<)kg40r&rXT<8%kElvnQ(Tc z>$?_f8jDkevo4v@MKczmtA!#Sp0YPB?;7#z{VnGoCE{+xs7i$!ODJu5B+iZ3KlS!6 zG^NbpibZd#mZcQy+faVBV2SkpD>J0RVZ`&A`J-K&hU;m~l zg-JP^sP#*=fzD2&Yj%E9g*JJGUIl-`xa{ZOED?8+CGm)3+I|UC<@hZvlbNm>^d~3J zoh&miRY=_YY)z)wa+>!}=DYjeXB_SaC5-F3cB{^I?su)DNRE^X_z-?VVZvjro^oJ~ zN?_*oud5f29^*7BDvO;uB604AXVEX?&>umJ@tV%}*!F$A7~k4|pk0mW@xXK926588 zomuykStdLyRAkR$PDgx8JDhy}z&OL1pN(}?TbmYwrQhh_M{&07y7RO^0!OMQ8;$G(O( z!QxqC;#*3U?CAUz@&@agts5jCzkghT5FiHBwxz)yAXM zgoiV*`ua`Nf2gf{Oo}RFGWEC^GD#BNMk)u!iX+m=0l2qwhR6FyM1`#s{ z-#w=@OorLypZOzGE)0@hkW5}1yPpx_pL+VLAavvfv2gUm&C`XKzgvsM`L_7BjQ@F< z-I?Z=cqO38>PFRq&b3+$kwBh?m8eyJAp3LLwcjOo_!}nuG<)bu)5WzX!+z{J^JY_Z z=|kh84+4$jGoObjkM>-6WJ4SCIcV9MflXhSjJi?bo^X5ITNNiM^~8%g%4R6}lH#oM z%{)#22E`=#xG!FIeth_EyJ3!w#AZ2Mj=pU-mVe5}RXc(# z+kOA3Il+vLT6&*0&V)LD^vK5ZE)0{U1>1utkw;CPL#hpBUS9CP{-$$fh zUu+Z8mh!)lfyvFzzvWongDLGm-yC}&?DOJT@Y{XwMty~>bncuN677jn`$cVEzcwJz z-YRc6WJ~+RpmzM_E3?|Wnre?WsIz9g8V)|Ac_s3C{(*=*%ZpVGu?SAXsbKoW-?ydg z4pkaoU39(rHcj>K`l;r(I(sjXD)yh=An$wi;VrFGtY_cU+em)BGXvS~Lm0{-U4s|i zzyEQI@ee6QKev}r*7S}J-yj}z&&ockuCS+x;#H{C4Vixp-s|M6b&vICkGhq_aD(7)BSWi=0c=wbY zlEM%veO&tG`Nh0NsWytW=c3NB*|5X=s2@2_JU%vH-?)DqZGli6M(?XKlH`Z&d^(&g0S zika>lJHI6_6;>|hIQ1#fl?j~}9<$Lu*#|_;VO z*asE`j*Na(J8;CuHRTxp>_MG8Wefk$Bp1INE-O;>`r?I2JKdQO*~t9mRKG8CpZ>Qh zE)Uusi{#etYsK;j2CpaOZ|KK2Rm;$;rbOK+etom2X>%cl*mUJq;`*DtO591|ni%0h z4-V>UCZ{ioWrd9U81iJK>fIa3mfqyP7qs!>lI!nZ!WT?#v@{QR#gY$-2om*^mJX4i ziUdr4r((uz?i>gSZ&Y_4tXSD_*g9W(bK>Kt3zF_4N>!yn95kq}!;Hhr%xG{^n zZNOT{T1V1+@$UyVX+KtSUbwRhC%JAPOS0)_4uUwJve!YCa z;ZC|(=};-qL1>5%^Uzg8Qa4{PjQ z>=e2@R;^o}-=-W^zcE%OxZiJ;-iE{U+SU!kddO4?6BO}rI=3&U;B;oPv(ZpZ)z8J}8!S2< zzG^g_{qho1cLr!ft}yS_%G0kmOoW~d=l8jGeHJMj4Qw;Wu})4-?A0LqdC)eKw5DU( zU)VmUp^ZK;8-u~nu8NJbR-_JGRY#Y0>0f=u(aY`D$swJw??Lv(yPN?NrKFc0lwK5} zlg7wg+7eBjC|I9y3N?#Q3~>Kvu#oV*-15wlru7H5)7nhW5~%Oeg@>G7`Wfk9OlP6? z7&CmfE%(l~`bMid#bn7$5?$3{hjs%udNV8j<;|o6Yklb%Ylq3JsAa%(~RuON|4h!c6~Y_H-P7Bl{r@)0g$O zto*M*sqRtov7+?pCpuPVz37g94@#AS*gyC7>~%fCD{XI_e8g4L=X(nKOxZ>lW_isE z8f#G1I9Vop^=Sv2&aW%t`+1MIoTC@jF`Vr>S7x$u=qp|EH|oN?&`dc=`oP-N*u@JW zW{QU~W^;E>Fddi+vAU#Vx`&C+J*l@Oa^z%)0q;6R_gUe*RuwfOU^E^ zdQx{o_N$p&pD-gM4ydx*R_uL+nk>x^_h^!YtYJKjdarbpr2I)Xz3BDzG zr?Mb$OXEA!J8RYe!*_c;EW#du&%qp+K3bFZQlGE(OE8W4@scCgd(K21zdph=PcvZP zm9D_$m$P1Unm=2+C%By#1~zTb)Cccqi>p6*!)$&)lm z`^T7N!p}XgAFdzyjp)qP2TvTBrWD5JWu`4X12?ilBQHKOF7ha8v@(A{&p06YFLaWF z%VpXm&(zQP;Pb8&ZP}X}Z0qEkO1xD4ArWB)x^!y~z8=*5^0M*8bm!eXH9nt5c`je1 z40$BACnzj1exLd^WuktLqvU#)x<#{kj(k7&bS8T0(QEqVA}!cG8l4I9}W`9;Vdk+!|9PeK@N@lU$uj%eK0(%O z+u*RYiaa|78*Q`KceA8{*f`!>6+nmo1dy)LD55Ww-kJ|6{t^nJ%WnszdOoLWCpx_zp-_rcb#vMg|d$2!b z5BHp#GbZ=bF*}73$A5EWZ8ziECsI@-7F&LQ_A0G8a9BxwkEcjKy<%eJ>fw_OvVHl% z-nPd@hC)XuK8N&6p6arfp(*WJ@2>>kfK5!oM#=`h){Tk?`$e9S*)$ug;IAtXV-!l3 zA4_sv%Izov--3DueCsRt3hC`D-FF{k5ru-^K@9msp-{w3(Bml79voLgP1T_)faL?6 z;9bMpSGq43)E9+9<6g@OZ2&G363Q4JN;Fj8iK4@?s&PK7ROBKef=@_q_#K zMx)@Dv_lV~0qc-J%rqAlR27Ya-{=Z8W2wAS&~!9PQUGiHb5737ynBd+9|3@p69&E_Ko#7EEFPgG zVMm2O0{vp}iHip>m#uh&;>7XRoIW)F5WMu38@#F+uy0@KzWF$0%u6?B2o;Oi6HpZ4 zav!`syBRp=mi1OO~Ffag$Puj%W&wjY$nJWZ+dw`u2%y1 zdRYw+Nq}MdO7|W7gfl%p4#kQyo$>tG^ZQ_U4uIhi*v4Tyng0!k?2kjCaL9an-Gvw6 z8`MeVcLv6t793IvLb2oGvBjtVLM+gJ8GN}dp{?hjEdYvXXk^;uj>FQ{I-4L}F01b} zL}~)p!LaWP|Lb4@$xUTGY9gW!U?j2MpNqfJeXW-P8h+z6BomK9k$xa1hKR9Ya0&bc z2ZuNKABhn#{>!cjD$grTGfDELL^5IO-!$Y6%a#(<1- zQTmgof;ph$KY%j{hx8d641JP-;)ZP~!Agih!Q|Nl6c0>hOax>l5ttm#NK6IkCn6!h z%PUz`52P!B>O<&OXBikDm5730^bEbmit#=KlLr$~@XN2ERV?|nB21QfjKshj^{4X# zAQDZ%0rwilh4*XkU$7A zFBF`N;uOS|>5Ny&Yd=Vch(v(RAYQkxbYK4`2=-?(;*x(F3I$1Ed{aTC5#2^&b3EZG z#F&DT$4R{SB8?#v7&QzE24V1eq#+Xd!$3TSrQqj|$0@+Ht650nj}*MgGk{Jq@Cu@S ziju;)?MmPqO9xgWA||z+&Q*R5oq39q#u;$pPWKzhec+X39betWBmY$*{aop5op}E7LJQ*nLbcok1F+{&g%ne;kMVvQxRr5tJD5hsY zjO@j$0l(9IQ;A4m?7$c?Jye>CqQePSxtGVa2FCpg7<590YHFAvZVuoX((vZ-r2*G$ zvEteUpbOh{TRtER!Z6_ed zXCT-dX-IZQa)O=cvnDWY$%+vX0dHAo*ju?i01hQwXtW{wqT3kE;n9T(eIx^IOp z)SM2!Eq_*)ga(rNhJ>uQWhS`?s1JWZft1)rV_jyg2jex<@m0n=9rQ-Z7$#fDlThu- zHhQX4@>?L*et=R2%-p`xeFM*9*%aUuqJ0j$SZ757nH(qKfM#__XrYRDWJv1zZI9@H zpq>XwAh<06Ymnw;9D@)P{~W=B$0OVxfkb({Yx4Yh1ra`Tf`lHLz%y*^G0r*(vLzFY zxd?&qC$Sb4ya1kyN7!Y8$Jn%Df9VSfxbjuQ+Cq2pw4;aIq!`V5o+ zF3hq*d#A>MjT2xY2PU@dE8VyJHlkKI6UB8V7RqKv^Ul=Dr9ROX+;g?wXa$ zHE4eZGQ;(c#4YIppQ!<#5tc8SSV;W^iVG^qM5Z#D!IJuOV1yp;n#v;MuuyJ@68wV; zCE@*=!v}z~vOz`>S|a`g3q6FhS0wT35+9hoVnB`(rcl~bq;IcZ;Ag@57r>>Y83=vr z1&R$P;|kL-@qXYH><{6XbG;;in8!#sA-yal$A|rhsTRO2rERivg>WB_P0T{E!b6y! z1@skFAu>j@5Pj))*ol7pEFXyKAR&cP zU!nHnED2)`eRl$60R^afguOwN;$SF<{xza;T!BZ*8l<{6h<>5%IK*bxGa3ZDF-JlT zO@YM;PWZm3zE#)2N-WuFXZh7IF zd}ZXz2DL=_08FmuCS`(bv++gN1KY-_1h+Beps1j#Y!o9-#bb(wTOL5iD2TWN1S-mu zxA6iv=$v}!#ym(0Cy-2p;d@^V3x(@ta?q1E$AG{uK%gvvzzPj43d~J8C@!2U8klld z!8(OV4*U?7R^wxcEBJCz{5Y&%3A^|^Fc_@%I}2gsf3Q@LPcD*|O*QAdCP1QS7>SjX9xT`kHp`TpEzH8+x@CWwm%kfvb zZxIH^cF5_PlY-m@O~^> z2udtK-2bq&_5cl-z1J`9Ec{(Ks3NS2p%5@juEMH(dPzBOb1vLwi*57xUmGoyU5NPO z>&(H9Q(#FoW(1eR|Bceb*0wBKNN1Roe%F-r@kM=wGYGor0PsdGJR|s>?i4a^ z*$!SG6IO&`#HGQVH>t^~V78GF*qN@r#t6ee5&jHh3oFRwEJ9aTBBO=$-{J?<{4H=< z=uJrDJ&FSge~XMofVF!|2gqCwFj)!{Sojrz_PoW5U&Trobbuu!n~?2ZVV#PezZeNJ zBnnteIE~IZ!ED*5$Y>x;G2W<%Vj!~21#YV@#;=pQvE(mzVKUu2lpwAiy=(ghy#V#- zDu`pkVo%}&Ln|+XE<3!#OZR>U#EkpGZF%4i*x!v2_9s#|SKn6XLx^w);fm-+B5Xa*+DdAnHMQZC~lWOOIgd z{=Ua=f0;{wbw^TQ@?i`a9b{C3?~o<7t>!7*7FB{&J_A+@p;6%RAQ1J0m5(|ThW3=8 z*l{kr8spXS8qC|*cWoENa$u-PDKZxsl${=(1>#^a=Wq2n#VcSgS;Wo265HZ=H4QJhvi$$aM zz_Qn1h9c~U>IRITEyGtr+H#O=leFZ}Ej==JXm*s0a#uOI)24Zg7g&n{$wfHq9E^ak z9NFGouSp|Q2Cj2u-q|r{Hbnf7a(vHbuxckzMZ2^yDAz_>)~Ywpoms_ zXPOkNLNb*|nmlOxvUC(oUpnV@R+Y;JkY^=oKWtHcB^Zg(YfwWaY7fr;B+*Rwtbsui zAdbAW6AlUjcTO)D`YVHcz~5kvhL39 zmQ^?oi-s6(lGE)PrmstG9Ynwm5)e{^OE-aMkk1EX=OOVsz3~m`6*F+R2!XZNULw}c zeZbcx`j5cEi}?us*hhRonq%q7czVo7e17C&>CNvD{Mbii+Kl@I$p1=k#tTBKpAaWk zt@=b}fmC4!n;cy zp+R~ocIXod4et_PyfkP78z3SJ@IzSdXTKoWu+NBbG6LCy$pE*t3+q*bU_0^H5z(`c zPiT@5*$9#C$f1!JqHOu{+N<$9Gm?RVNrqQ-^puK-ZmRstk17n|Md5 z_X&ofXX@~4Z~HnBR?m)6LmGe^dJ6u5{aJ#gOZ(Hn^qD#o3ohJV8klET0SoSt?G(Lg zM2p3;Lx<||vi0kMj7RYZ-5bzxgCcc|wtG9}rS;}8rt?joE}!!TH=m=Jca{@>Tz5~99f7>FR1 zb#64|!-IyCnUr(BlpolNUAht`v$#J4Bo)ZOi@RxwQ-83H{gMvAIe=9Im`1iQaDW{E z88o5x;ZWsQs3vPbn=+6JR+ZaVx-ap4=us0&6o(R7A17G`TfT||L_}ad-oDa(i9(>C zO(+o@${;o+oAd|~5v2n04(p_2A)#iJI2<{~&A?l>&5&I)N`eaOg4&aZhoO{a6bDIN z8&uqkEN8Gv@a`kDUjW>w;{CyZf&^NS1=ozt`@PKBL`3xONOvp;&AvnWE%@729xWi= zp8GOFf`N?eP<9IvZ{k#kWrsljPlMGDVRByghXz_uQn203t$;f)5Xa34>H9O%LdLE5 z*t&#mycLXVL__g_jtkN~Jk{6a!LSB-?-VT*j+oKiij>j+zFn1YO&gm9F}LA6q231E zXY>+F;fE@DktqJ}i&F)+#|OKZx%Uo+HngFbaKq%KaMyc3=_CjSfqzCMThQSFY zp+%R*VYa3bMjFVt9Z|#a%Dm47SYMT})0yr|FrM)*aApd?!%>&p4gyO;kO|t~%E$=~ zw9ikkMd_wy$*G3;Pj0G94&1E`aSt z-|6QI5fR-^+3A+*LkQNd138J+;pvMw2a3pXvz?o=!gC0=tpi!%&Wy|$zXvmR9#}IH zR$Xlu1k2Zn^fjVN$(9V1oxkUI`uNB_1Z&fY40~SoerjrPPF@OD^y1q+!{&ikH1xC+ zbr{#HOAy^;v;YxN0VsX@2vCiQOwgbQlj!cH_5Lof5O`k7L<9}6f+dYp7k-3%unh+) z;06@*t_#WM|GsS)=-R&0ee2bs!ESKyMaz#y&c_A2K~g`|gvlF1%264Me#s} zJt$@zG(VO{s0Bny0r0-yb_cND47~vBPVB)i;IRvPlEh0ed2*Xf{1cFS5c1)lNXea& zv0_mLovH#Ap3u^08(2cnPh>>3FD^>+gVJzMbSISA4u*CBD4ZOx^tunl z2=}TIw2{s~K(z3yv5-Sc+l@5+ps}a`X>5uDp>w<+u^Geg(Ag8{zOqaA@Ee3-BZirJ zm(33|h)4~5C;E&?e27sBv zRS11E1(@kQfX|?CY~$=#Tq7F#GJxz_PYZty^aZA$1kp!0A?|5G%va50-o15UWMAy6 z(g%0>{_Tv~flf$$5G8|)?VgY~#g1T_lG(R&E!Dpl8XN*=a2bR6g=+aA7@hkEVDj7` ziXSK8P`6rSBM1j-Fl9&(gijzyB&>uKITjAw9aVTB?S_Dur1MDI5K0IqhRDxcN(UHn z3LNbMTeh!sUviK(L#RVAGin$xN7-X3{LtxPe8@Xu$;+>?WIiZs7+HJzIf$fT7m2ID zeS|WzJ7M)sr69(didkrI_Tdci*qr7?1Ex7JpoC0ker_|dK;|R(akCo%y5IIgKBGW) z#>lp}uw>UEn7lNC6es>``*Y-g$zaeC?14F4pTLh^B9<(zg(Y)Ajev}c4WY&qj53G~ zKHw6nE@jZs__XemuRgfa9lTH+bXWWZNyWE zzHDC|t{cFWy}(a|x$k`whU!frJ8<%kFMODRAD2RRnkHZaL*u6KWhi$FD6@}($wO24 zecc9@d^H9p%l^WX^?m^|st6`~|H9wEc!DJ_mBQraU-&qh!IGn^V6wn8VqJAsc3ltX z$Smjxq2pR6A&nW}Ci`im&+^~jSbYbf#tWcA1R*!^3xE6uJW?0n-Pk9h$10U9L<*yu>upwwv)Y8z9mG`MF4ky`m1%n3TA z|82A%Vx`?Bxq$lf;71^J0z|zOfn-IB|1w*SveNBd)CtaFwNU>Tcxe_tpkCO>5i?Bf^kJ(ruqd61@ zZaL9vf8|sNSbukdm>}HA|B^%`VXKx zHX?MrKgfQeT(qt58Au~%P%{bBsICdYM*qQ|8RuYSylg?}eSeVi*U7ox`h&oKnLrK* z-|Z{i*QOo8iv7ixLG`~thF=FlclwL$MZWCMHnjvdE}9H>)}<4D2=-Dr+wL$OGhuE0 z2{c*)-Gt{X!_x>K=^}oZ(2GF#(hNdpXkeq-74{7Li(ai@Y8pPbvsSRpB772!Y`dQV z*5~j_Dg$vF2y&QkbVNuYjSUnlq&&n%3(YLzM|lI-Lc&7=aP)624bCOF;RHy|9!DGIokxYvA66 zcU$5>ISsgNLKrNHvM`$wBRdr&zKj>Cvd5RdQ&Rzl9=dSxe>?7D++A+b;hLq%5+LyyUuo!SSW8Ui~*ajq1G zQaongeQvMjrWDr!3?&A`Mi_}_Kf-MGY3#I6{VLwjpR2&oo1ft}?{xOv0V8x=ux$n; znI8yn!X&f%3bUPD!>EH9HxU4BBw>YDTF_ha#}*4VYUAEj!<^ji=o` zyu|B3WJ3!Kkp+LisbYvF8}!0tuXQA14_BY74Z|t{5liUcY;YSIn^hmz@oW5Etb|+R zSTY+#5B|ZK*(LC~F$)|4=^xpd9?&8dDgvvw-2lbJjhq8YonU8$9*(fnL$rU84Pu6m zqO=XDW^cg#7D6MQP~#YQ{*PX60(t6O91!0oY9DSc+j`AKW(UIUJxCQoDK$bIP#rM` z&#vs+x?z;w4p<~X2_s~&6OFxuW`jO#;s>e+=p*rv#!+dv@ZKX*wJZhRI|df|g#3GD zaY$uG4r=Ja7Cv@tw}24tL%1ecHjdqooXGy68?gtw*nQzULkCg=TtA>yW<`!9)vvZBCJ*CGaz+h^gbjKh=G`x45*11^e2fJ+32(? zvhi|&p)dmXcnPbldL|Ysf*a##Yf^hHfLh&!dhnV9iVWl6hGa<4$eE=Y2~b2?09_zK z!*?0f4sGU~1QsfQMH*pG3*JI$BxvN(f=0kcs{EbHHYJIP02AE6yb#EU@~(G@6vcG;Z#xzI0~zJzjL@&Hj^=_Q$Z82!Kvfppk;(Ndfp)!=XVcG%Lj9z)1x~3Zmf$W15tV=B9yGB~bSXC#M%t zFuuZxlMdRXz;}Rw63A+bhTBvq(eTI2-0%DtWCW4$4Af4-khRZ-p}~~+lhtIbgn|N? z+(3zjpOBRhBU;9mc5L?vU65A@Lpi9>$Y*+FsDK2rH&`+U#2dp&37zjq znWzhZOnR)E6C!@b35Jszc?5y+kjo1*kX)j`BZNV;@ezj=#u>!qYYzm=s z(xQ2Ac9?9^2N8ihKB2wSW}|5YYfp=pf!({3f_DSL{VtY=V9DCxu@VMAeoBW%c0!d{@)1^;Jim>mqX*=7 z2-%W`iv~JQkFO9Hux;8BFbim7hLY*=@tcEf6FdvI4bY>J&!%l)$$C~WS%v`(uRDTY zRX+0u)c|{ki?Bl(wlK6(my34STnauOAD;rs8HeFcUs^e0*<^9aOJtV(pb*>`5eDH- z7<%eK5HTY@^!76X%VZ+36fWo*BR&VbvE-&)*or(xG<*Om?mx+11X8&i7!B@!ZC~lW z9C_PNYKVae4L=D^^E)QwD#%$LiJhO5LKSS|sUSNhH2jnwyY-~PNib#Pfk|iIwsdTH z{8aHD{0Aodp!PBWGcSDpPn%~t*X~0Mg$>t3<$J-C13^0<`El<453fBl8u=`71T&E9 zK?IqwgJ1#Or-G9Dx&Ds@{vZ|y79MyUH556)#RN&RAcaf1Ny^|i2>XF!JD*i?*ujK` zp0MD9D4PXHEkNy*y3B&O3F{e<2e=E&4BJ<_?`27tX@(U|4H>cG-DJZG1it)l+jCZA zsR5N@+n5cv`H-9TXf{B;f{+c^&+1^hV+a-A?B#$Ld@tDI=~lhqp>@dw7R zr!^qI2)i$lkEr3o*I^qj(5I8-Fxe@Id-taK%=a@tDuH4&xFbT?zl>&>?Kc;iRTBHq zN3Yy;_aV?PQ}6>)ar*)vfa&BWa1`w-~}H|L>Dbggq_fCE&%m>cl$eD)zx99PhazQKkF9&DhVy5b`Pt z?&huE0=$!W-v2%~qefse518!!6G=F|0(@v@NVW|H>&+{E#y1JlxdMbg;qWg1-@GhP z6)&0vXY+p_xzQxht0nh;>J`MX@tx8NH3Hq-0s%qDW_4&cTLd2(X8Z5c1V;(9F(2N| zw#kPUz-gl;;;*X)+75uarAol|S7|q!*Ewct+--9luTI#fV_tw4dlsTaz{{+N6* z|DMY$5%69&*~u#lG0x!+2%ZX}Q4C_HJ0W`@S_e*g+y(|`+QoCX{q6vl$O4xT#_7tL z-MmwRXf%%PGb2qN)|0A$jj%^`X1m!oK5^3GmiIW`|1NV0b2`I(H*cj7njgo;=t)+1 z3OL{-_#xckBv=x#Q3<1Ya2&4}8ltfuiqHh#D#1(Ox;>W&I1Gi+{HL%r+`>fl6^8*4 zQFrFf9XZ?e|8huQwRUlpvUa%cD05Ov)9Bby*imP4PF@Ck|qS?1Oqj{|?kXeXi5Cj9~_H6wW@O=-$NyfO6{fGTQ*_&ZXYp8FN{|8G+x8}KnO*#B){$l%h z^I>dbbvdmi8JDeCp`inroY6F?CPJB#X`2S!i#MhM5}5r* z1I<`P4{c}3PJ>olPGg`=Modyyc^Oq^2AZ$>3P&&|Ii^W8%N{dSU}2%`s*Pldt=GIe z-J}Gd-8NGWNozGa&iQ>lo}e-#6F1F_0N2j1S!GM@c!TFbsc!$(&L8DUaLc_(Rr*9$ zwO)t8V1?%zW~Kf>H$4(sMryS^fE%N#@G^p$sNQm0=T0d5vZ|JDXS_E`*2#m6*FiZ%zM>N>4phKNnLYK>o(cC`<% zzWkoK7`g2CCP=}4jQ^>w?{>u$(52t1o5;e)#8|4D96k713e#fSSa1bl8+htoXTXqQ zhl%O~Z{Nshs++fNqvNWLhx|501nKaS=RPFhyyvKKAQRn_8uW?O*K=sW!ny976F3j5EbZ;=z%{ElmN4S$B#dn6?w89M!IHue|^haQ7CeO z`%;k=f_WqX!7Dk+B-ccRSURAp$!|%`cC}IFE3 zB2k0%`Q1(W_6LMu>_}il*A_+h-&r^qBK7@Eh$1ft*WtNrNSSC_a#qf9H>GWZ1s97_ z!0Tf@WPLK&KhaF@-EU|L?WvhpHp^qk-=e%yw?)nRg@o|S$twg&ALI+LyptVYm)i=w zZ-7jB1t~3*L+TS9q9^s-bJ zMqyB_GQp?D3rdkRcga~vr0#Z|cV<~4_s=Y{ydl`S;|8b-z;ziLf*o8zfC6;~+?5~~ zk&8owrZn^_aJSogK~=Xlf!jwpdo-HnQCfw1olf8xa+~%W)b<`gIj{o24}*La4ELv~ zA=P$3VJ)NS5^nnw<^U?4F8)h@5ei_?|INo&f5OXibQyRmGkxdyhzG)%(uodq&`EFV zGNomzjNwDxCK+0+_=Q;iGgyeJ#jjSF`xA!>T4V7x<&Cr{ca5`Kn7yfC4Bc`Az79kb zVg%Ch6p5ZNaK=rm^=}@)IJVJK;@(tcq9G1OOe7aj-KP}S<1Z=*FR{ZMMPkz3C$C+4xQ+k zM_;cnng1pAeCD+z3U9k5BM2|vj{iiVt4U>^60;z#Pq(~ZI57cO1;E;d>0g}mh)Hjy zSZueB1#3u!?iM($GJ^ln++edP?LPRXCo|>~&132N(_m(RWYAET92gw*5X&9?a(_Lc z7@WqL;b2?&Zai2FE2o$tp+lux_C&D22D;7uP}=`E8MP)A=86?8VY1L|u}?L?JTeb& z64PUyAP2RGIR*;Q%ubczrmE9V)-Gfqa8nU}o3{`i?Ho;+kJWQvE^1p~6(>TM#-M14 zX6(TS7(L{ZTrz=m4lG$PCn5=C4bPPtj7mr>u;RaYGQZt)XFb1{FT`QL1RS4awExi+ z10^&bgxd@$>khT2(bj77TzJz;h&zs>7XDC@+EG&gO~(U(a=>bFH5k~*wE))!Eh8uP zqqTL~WlWF(@m+46RVTI=mn{0G%a(!monxIHEkCQ9eX!0DJqXefXmfS)0zX82Mara_ zwU`G-=e9yoMUT$>+**dd1CO1&(Rq7&IXQa%e7qec%uPd7cJ%kqb?*O-?~8@$N5lX7 zR-gq;N$Lp@xrO}R8b2pz<}P*Jujb67YmfSjD}klm+2HP{`sINbG<$_|Jc|Eg<6?f; z!o*+CUO(hf!{rZ54yUsbG*$v%{)z;Izc`Nus%Krw>Rc4%s(IG0xU(efuHbYL2u;l? zU+_wKU+`@C&eNesqMOU8 zw*I+%IXQb;X}UKHt4DCK2fxPPv0!?45qn`~Zy z8ClMgDL-M#7o)5Il9hR99j=Nd>emu}9Y7hEL3{%DoF4r%^Ky3`VXs}Kh)vg)NNppN*5nS*3|F{bysu`^Ye6zV?x-^1Q`WNWwwE?+7`2uC zstYO&K#0v%-qzNV=H7O2Q{^jIV7wtlUJeI)*#8relRv5gGwTn;7_inpzgqC>V=Y77 zsLVPnM^8J#ESjVO^D*Ug^EiYaAV)!<8o0I2oW%`7h)50HHk3gDi(6x<(ZvDS&%;Ku zM$|x-YM5|-q5omC2+XU4@Y5A%aXA56v1!b5Jzx?F#tLsPnJ%oB3SoY}v>?xm_08gq z#P{)W&NU1o$g&-!3Gw^LLjclY3Wd&QyKH)V!-4RZiOR$_{R#95z9=wS9J*=6L<;pZ zH4QuCrx?#E4WF$L(JPw?ON<5BdGjEdG<-%jqpF-mw`Fgq3k57Mo4hjbM_-r;o#AGX z;5iLu3Ci3lT$vO2&0*No7+MUe%{serR=Scd8WGl?j-QmsbMl9pxG3CEhx-nJ?7ZEd z_m;85?>A_E^B@!2Gu;MOqz&|Tq*DvleR7nTeUjTIuZCa*xW4f!YZU^NP~+}p_2+MZ zNOaHI@maVjUH0%XNESiN$u#;TLYC+5!x@%h__MNdYOB1iLHq*=14~O4nR5PVBMe}) z=}xXesPzGLK%BPe6`)N~XHzrtp45G^4u_PPM2o_;E^ev& zT6g~{xdIn-S8wIdzNzJaIgBe4VS6visjt*Q&VuLHjWrkDr?iHr0N1@>A+Qc1XW2JrtNf# z9ZU%e4u(q*5M^U^OY%ZERY_5TqY5l*C{@+XPdsKw7M;p^XgV6Ftc0@puAgWvd+RM@ zxL*Uue|jrArFeq-{-B|l2P5e66}dNE+)t4_(152B9b&iyRD~9%V~4OGGCaYtT#>=p zo35z*Oe|4nSX==}^TD1H3+-jK>zv_8bUv)hbhE7xiM6*#ESRT{lfkcCr?Y3^lR8f6 zKM{X@-uJYtGeVn41llZ>7i0_(i699&sCZvMuU=qt+PoB$Z!td}#TvHSGitV&baMa$ zd%P(qt~-0KrKWR{vJaG#+XbInO?v3-B@YgE7k{R|i<EqqV)z8tV9cPqmC~QC~Df-tzsOVZ0r;Hzus4bn-*I-)_);q~Nj29(8nguN4>JC<3eZr^8FMc}kz1p2$d zMb11IhaqTWJvbd0{yfkv|Jh86sWQO5L5(lkKJjHuw-a4ZMAT0Iib&bqa>lha$V+dEfY>EAb2b?%qvN@XReQKUk-Urr zURuP!7_a`eQE`FlDW;Ho(YM8GvzVGWupdQ5@rsruhb(!3hP);8uhsvhpr4vuaL}G* zau(fY;LE*u;1ounz1>ph^#&s}l&4CJPiHHk019Hy0EWKuiuW}`c-MDRzHHW`5(8jT zECmnXf9oIcJJ;t!cy6L*W*pmHmxfBX0^ZWqi?9;MvLZk~;l!TQ@Dvnu6$)FDp2EA_ z>OnszX|7c`n~Cic@PP#9Zi#ak|6&gzpNO{w@ zd23kOHU7LU;$_12W^K&o7E7cTrfsl4Jl%IHNUw9o~b8*`hZ{m2K#bP z7;1MpHMnH^8Si&yfB!YJ!KWv7=CmBT$9SO18jDa}Wy3dt{{{YET*Ms_2i*S<547}w z$p0lC6eby%B8Y*2(wtL);lR-nXZa8Tn@)#guD2f%>=fn1wkVCAJxP(_Emg}FZY6FE z5k;Dt#i~?D7729%Kw?1)4%lkN5Abrw91n=^r~t{C;?DUt#U+nQr5G!B5s>Xt`CLBV zo9zdl+bdp%@XJ=N}wDl7Ot|Y^qv8n2SgYQsU zMGRa;GZMXHO~nY$_-c_jy9v`Qh9Tjo-eFsU(;rqjY0V-*C)nxO1|1ARYF|O7eg1dq zRKsvmb0Z42HUkJ!>^R0iGUP|j_=!IH)CY-ba~wen)abo+t>|EosYHn)O=^<#NmdkW zHvM<;oKt*!lm>Wn4JNOSLHKJiH$oE3OABMx-ap-q*|zkB;_+-MB#FF;OI&@o>!%DrEX`MmY< z{6)c>6UV?*s!l|}gIc1Yx>;!tAXCLUYAB^=Hq23x`dmPGo7LX5te(|}W1 zhGC((S^w$RWtq0&q3!hQK^_v?`!QoZ-tN!-_6L3QiC_nAe*30?aAEuDjd^}qMl66( zpaPG8g20gO(?kLWfyJLB9=C^_@OZzuevLR2E7(965uuEON3lRphax0WLzv2uyKx@4 zzlim?F(L?nl*d*8w9&9tzz=U|5ZGn=@zOCd7*U53CUuu5k}nQd!;!4CMI30oXIA!* z+1~s`+BtJGmuK?up+C6|ocKh6Jrjv-ctDgUh>MyiMed{O!&(TA*@I*XQdy(#nu;dF zeKhF2zDV8b($r>k8)HsFMzpzL4L2Wu5DZjQNAkgq_*9qxa!NPh1AJ7Du4vHZV{Ref z8Ro+gWLz|8abIOCFuCOte<4jd!{o_9n6*pyl}wzE4mj})5z`ZHfY(ghnT45nEK;js z#RB@Oii?yb#~6sLx`r;vRFkV5@=MjtTHR{WEO&G!<=$) zSZpjHoOw3@1zu6cJZ=9dhG7pnf)t`|5e11L;xqXpw}q%+oGAswlKS9!AfP{BVaR8| zJYAAS(pYbZCUP-#8i_#nSYR5U?-|~4cEHm$PJLI4SgMtHvn!4uU#^##$$w-jDdllP za_4`7WwBEiEr%neC?4a#Umh=Y8ebA@HZY$HC^Wj%1{}Za~DU){2ngHf09ANo7}oDBwsnQFk_!_M8h~?m+opY{uVH zl>wCi9Q;L^&zF8hy6X-Ioodza6_RE`dJn?r>8A3nPAxJ|d31h=2MsnQU~A24|bHtgk>W*H)3Fu^*~r_VQa7e4f}&DQl-B^8-X{tc6)3Y8;-HK9$!^! z{SE9|)>@Y>AKK>9vToZ-fJ+<8@!HLe+wAIVsk4@#gtfo}-kLv*6cjHrzk(s2d?V}n68S8P-9MQl-#9G}nM~svpT)stw{l~m709Z(>t?J>eg^ZHzuLjm&n^IuG~>`Ij^9Up z0p5MrR&y1r>)(&m-?MY3FG&h>o7h}{i4)*^_V?#f|L6O%bQ&p#fOW6~{=0SR-Cj@O z7UyM4Q2IRl8`WAqg7WC#z16An^tsCcc)7)1xRT2lYHkw#-%6xlsmU4S_VRn4Yju!~ za;LlKwN;J(guzQAoQMS3*I$epE!8heR;-p2Po{W;+*0s&u17eIz3@3Q)5g8Y!&RR%o9DmGDlQi0|4O}%gyHe0<#9Gw>Ji8r-H#v`2 ztus)3X(6(Fv1LQb4kBX#bat|2*!Ctj{cdawc2J1JDaI3^@B}N(3@Fj=fjNHKR^CmR zGB+US=y@UqSe}U)Y0q~6iOr9U1ItwgQ9CemStjMdqD3omGc6I%L_KaBLJR_$vO&MWBD#MxLHNFobAv|%9G8`$ zfUPwVe4IJ^l4Mc{-wtuj9$Cg?VIsHP&>*MEnC%H0G{+dwB-aN8tA_I-nO(IWh1Id% z!i*y2p!BugCHI_8hCyT&rx+~?nZ^Z#^IShTcPo+t2O@%gg!W?v!HwTVb#(6I4h^q- z6^+h^N*K?D^w%jUk%y^%DIE^9?%ZNOUgLb=h7dAhCd{B+kXU!ofh^%IrdlykUrZVE z@wN#(Q*jc|E`D>~!aJNjxHmS~)J|#+91R*c>z0g+h)Sp9ty`Jv%l;LP6+0h;&R$#* zJOeLHBkO;hbndHTLM=s|psV2}=&Pb5)!TphnIa&+CCtOMiV^SzFZph5FC$Hl?I}y{ zg>6J}%BnqmkYu*NT|J7NKF-BJa5fZw#~BcoK577vNJ5C?4eJrCS6EHFPvsbVImlL$ zglM82PT9Y<=x$Y&KWhV(tdHwM{g)|KrM3`OF8p1UHv)NPNQ_dqpQb24M-7yJLNufE zx#{|x#o8_;=@|n~M)!>7)EJ(&kBW3#t<4@I&^%_>BQjqw6R1G5Gf z=s|X*7vdQH!(agajMN-)Mcf?TherOJ`w<)O1hQr+yW}Dcr2ow~vl3A?k?QDpr!b3N zeAvbTj+4Mi=Xkzm*wndzf6a?&mt|%-@hkxF9qjJu_$!{*fjxUBi4*Vjp9yW>f_ukX zC+Sc9F}1Iy6#W22N#1dvO>t$y4p0O$R1Tr(?9zISajj^9lAv818|RLeK$Xoh!La#9 z+-%jQ9S*z)#;BRm^JPxHuN97fVPZ60qo393H&1u`OH|dWcb-0&juFul7W2&TEWWBiT zl8=lbyG9)u_7$IloHm4J&=H9{loIGUqt9BRX#LD&K5Siq`t%};SmeuN)$utUxwwEU zcSWOBniSrVS>!c!NXBv@y_(g1pV(T1#YH&=kpPm0YAuu^x~N-&bS3O28-jz%4$^@b5|qmE z#WYeXv$8FN*|@6e3HN4dm1~SHj67=1-Z;^3gPe3sDDFC+UHDQ2dJ_Q72+DeoF?p-4mgS_Y}*#V2};06PcLK9CTA`0A`Mq$lN2K$YU>Q((PTFOM`J#q=M z=2V2_Dp73oV;tI(!k+-pJPHYI?baR#vu%&jTpGU(%>CsWb7V#)0-(t8QsyjKPLvJ) z!M3Pr61O6nJl?wf2zalE&X;MMH7fs0BBtf7<{b8-oP1&_zQ_0R1^dm=0l7MneQ4WD z;hT*SWb?>+%2I?}viA!vW_ZW0I-*fJaDMrs^k7o)=H;KWQ$xV!2sh|-*9a=O0FhZi zD0v7K+{7M)dVpt+91D_tT4zoflLo@)S{BGlR#ZtC0f#-v@3=CgyldnYO@tNtKV8vj zZjY8=Yy6iDtjnS(XQCQghACh$rj&aNWV6jlnLKB{QWz~4uR4d0Rh08aW=^2mBFKWFb7}rU$=;{%f&4Bx*7nJn=lZa=#0tyOVPkSfwT!6jJ@dY=i_x zvX{U>aQMPog(Z7#h=&;^8)Ow8BZgLcoDICqAT(vwR4`Cl@6eHiII4kjMkD`Z!L&bU zkxGUBV6mFSkeLX4%08U}W0izvPzz^m%ZbOz2)VWE%Lw2+5OMn)aTBj2R`C24+L1%8 z9F#JU7DM@MiC{-N?@%qGlhs>dG?K2cZd8e8#1&-+vMkhKnBoA8w_J(p#L((=X%9)S z53UiOYVVx~!O-0wlEeK3?SMKp8cRViM6QVr)F>3$zxhk*J8pkMi z=Q4&5#FUZd&fsXeCqTt4oid`*EG+VXUqQTR=p=QnKe&;j1fYGk%<7|LVc39WnR%(l~rDqK30c7MuroE_OHA*(GwbLcu{!6 zmj}=eQ{(eFU6ao+s6Fj33$Qx`BF}LC)qFo|IPi?Us%fdvDbY=oNxLd^63C_jlABzG z9!@jJJdlAcZvb;6uR2`n5<%RvV{)l;3hG!98f5&S3)F@atsmOIDfeVCz9&9+=P&yD zH|zwjW?eR_-qlUeETLeWS#=aJITHpNzyi>izG23Z7Fv&S>CPAzx+brQ-Uf-vr@tCv z0?j4VC?%_n-m8R5y%qkK(GOjRK=Xae`AF7D7bSWuQmT0udVIK&(=dr9xwCu-2*Hmf88oocR@Muc^ey)C5LA#TIa! zlq`%99+8kUa!S1B@DE&OjcnoRN}{5&4U7X;rGwA$oa~Ql&Y5xi*Y@1gC zf=~}uSGut|F6%s{gZ7hCIBHSwd>G!dWI^VJ56EeWo>tF4_FR6azSZpbZEV2acx)Ja3}bO$V=zVSaw)vdA9Z!}Z}i zG?GKzd~uaBwU$=bcxA6G2L<5DD)XqYhCB1TM=VdaIU3n&I}ZNRSf5{}lRc;g&2A^4 ztW;9MSFS4#yz`boS4UJm3|!$73rg)Qedub45lN;o%QR_x=<6P%%HOCKUwoPdxif80 zB6^}&nJz5Euckawv>b6J*(8!LL1JeiW;0EB*mH1tjX(zKv~lmov3|poyXY1qXJuro zv#5l<%;mha!D44Hsz^cDT)SE=tJ4i^q%@gSu@iB`V~Gnx6u$_i0%wCy9k3A5QElzF zUTD4ZbdfC9qIe%~sRTHsd%`C!3sr?+UO*WgJuAw0IMuPt4LQE#`Wq(HYwa4}G`xmz zz)HV~1tyr;b)~$5=)?+3K7G;BB@JPB+PpCKet?b+kCuS8ER39*fS8f@bM?aBzS2BJ z1KccB7*UC7?HVmxyFj;I>y>hK@w|SV&dJa9eRH(gD1H9`stYK2x;eUdYW8;rNk_@) z?RdM3>Cw;no*d=CG{2qM(bw&We7Tt3WYM?Smb~nkA$6+K!AUR1hrYveSal}FR4_$& zI{=O74aJJ&J1RB!w-X2}yLxH#QyrHy|3-43f+ji&<~jK6;Hj}!Yc`6BU=NmKbSZ#u zf`NDDA|G`qQ{aMQMoT1B)zGvr!m<1EG56BwT2iSeq6^@|3@fL~JaZR`I+V->79ONX zlZmk!D&goT)Pm6e{@^gU4~^$}%1y~}1_;Rbye~5Xo-c)e&%s{k9Rhy(flot!l-=*L z^Y*i-SiwuAN;R4D7**j>YCy6n3wc+YM)dlV1acb!_fe6FX?YJ!HePzMg?|Irvj-{= z6Rt=VegNaDg7W)t~^IJZ8aHI@~X@rczE zljX{)7la{s8qG_r;$0(f>t&Q6%ExHd!viyh`g9yT!$D=YjSsl*DOu%$pG1!TR&Fav zj9eDDkP8|!&LSNZ-L3_gp)V=XkN=u?GcDk4Si_m~ghgc~9d6yM^uXw5dpX}SJ#h(o zXaLIX+zl-b-)IhHOdH?wf1GNpQBSWIt8!J7O}21DHoZG^v`v-MSVB$%-VJwcDs#9? zKk{@T3TsK6>aHqxZKDryr$^ZoZf436*qS_sc4mdmcUl-!D#+4$c)VR7?yr}ht`ODD zF>mE}dcF^zw#U7h@b%?p85sC<=GJmv2LZ@h<6iu2lu~PYYZcKCniUGl}VnZf@LA`t$CAGIppYKxz-!YUlxgHIX31t73`>)Nrl@)O@^H2!J>> zY>HAXC8AS$0=lnhdp~b(az^Q`9W_{<6<8ndO(Yr*&uyg;_meGOobb~};r#^hL=T+ew7l=h z15Aw-7VYoAzhUd<#bhE{DY&$B5|8nX=@ayH<2$%Mp59paRsPe=Y*m;a55Y z`P@T)OO0>o)$k!BZA-9|`$G$UdJYqcbVxxLeQ8EOmWY@$L1OB2)NMu4nDsYoO+wy@`j(oGuysy%Z7gnx!tACcg{k}F|C?@K4XAKOBx z4Kxt^%br#Iij7XodjFmt;LA0H1hea5vdx+fo^5e{L_AKmH#s{U)arNRu5S@|)|*wP zU}rrIdlt|VNuuHmdPqVB*Wv3?){(&NRFvQ4Su0xS8A!X%JHX|1fNbK_PWR9E`Y;ER z7Vj3Ah0J|be9vFpknm+}Q=UR~P3AdYoF86}CHEbKEZnd$sZa4^>?v`KpZfPXr}g-> zDb3{Cn&e8kG<^w|mQVQejQUpg>`_a0hO*PNu3g{PtR?wP4o35{Kc7$M2SU3B1{ohO z|7c$&O4kWA_W^E@NrwAfA6{ZUk_oNV{S1MSJxqIVZ9hWdxq!R_T^F0s!$G!kDGbAj=O4nXVQY4)VNX zf{AsQFe<`JDK4u;G4=i2v*H?CIh8b&f%U}MHZ}x8#udfsZJgZS4)+PX05TodUlGJp ze5+mtYsi?2>TflMK!>2r$fHDr9$rstafrS(hUYe#?|~TpdA?tMtpyI9bJ8mw{FIef z)cDS50Kh~`q71-*Bs50^x6EkdqgZ30wsnFX@Heuic}v#XIIxT0_v@+lI56JO_Vxe zqVsQK1l7NEwWi$HrMi%?KOoCU5NexfpPIn`4F5a#0Qbbxu|^NUurKrx7BHnMpt7X@veZ+T+ac** zL18sSP2;O}lwBk}@4r>cV5Y4mLKVMG@C03~MXlA!$wW$i$F95ls0Po{8)^?v{J>K% z&}CG-iJ#Vjo`D7Q50AEHbAc=xMF{3MTLIABfLA#|;phYkZdFiuac=ZnI0o$pH;`Q) zq1|$9!EXdLCsg%XW?|7YVH(>x1c|(7Y~MUOUn=>tJN*SQ_!G6RLurf zRgQZ{Cb6($Bo0({Zl;I!a4z@_Mb<`C$%0@-3f1)1vJ+OLsr1TY@1^j&F9tMIa{*$@ zXLBT{X}SM2zkS16Y_h#EocWe1TNs?UNl!g!-bPoRO04vB?uf!2rl5`LZ0nZn);>VN z-kj5<&bscmpvK!@?+>nr3?ZvHz;ePsWccJ)MHjkQ8fKA(bHx#LE_yXh8QD5wCuMgf zrM<^fCQup>YZ|VKlitn4IGsPNi~+HE3Q<6)zdnu^r5?>AK};T>7~A)Bk522P<1mqP zZBujK3Gd1X8U!ga9_s@C`PZXZb8zReP;+>x{~>%s7X5jtq7b3)KF(1BywsefLTy( zrAnrRzMFI*2UJY+t%HZ0tKE9}ekOhgeh=EaoBn1x6Sr92b)6rw*Ns*?U(rwgQBTBV zjLUzNC3tgu5h`Is(_Q~8n0nw;VWg>usXX?*hf}c)9$$8ZjJ@~8s2D{cVhN~u&*z>Z zSSMxkGaF|ssf>E!Z4n?ezR-N7wY({nw%uSG&`tKr^~M*zB(X~*7P^-Wb7l`jkay9Q zR_J|AwVrq;b&X@z)V0^Rla+B9!ht8I7<3RBUNAtD1N&8M2K{dQ1^-_H5J+RJ|7S)a zHK~C3uK=Vo4rCY?76=HFIC0a87NDhVe>j5fw_2MvK_%4uXCDjrKMSA?mqXS_o5o0w zL~tXlp)@=x9c8=}mZmDZ@7>Sr_BgzV9UCRys^NVu^O^4wdaZVIOD&fUYtf7br`<6% z7QIy^XWa=cdW;*oQ>`;6#xLjj<@A&Wr5}UQ)-B#O5#-1krwzl&%x}=J%<6-54QS?^v4}uK+BYyBLwe+l*bmJrNKG}c>D3C$C{@| z0o#6vB~OdT3h@nNcN8SG8GvCsUD;OUd=CXtA=Rf<9STrgd1d_CfAmoEiN|3tcscc9Ty zG#8pyEdR$h_CjE?v}R#Hak7y!MeN!!G@ZURh{-$Bnac0;__6)`2-rg^E#j7|R8{<-5V?{)agugoYMr&8#$K?UDkeSAV=t;4upy2OEQZnG@N5BGaoFnt z?>=4&F&W#A%&XJU3h;laE<-;iyA#D^TyR%c-)$_C7iRtj)t~2?cvmC`0K*kyw^<%M z%ECSO{4rO|Sn-L4gDeBri7zhl{D(&=!F^)t!We^F;?ik!s=u%sy$@P?zO6_KPX2_C zF}qhdKhZ_TlhwI|S&84<^+j@_sCF;Mb8?J<;RaPLP*M$_12_d+2R;Wy1~Ds8lKkMl zo1eVw)u>6CJcf-7HJR4a>os%8<)d)f4KEhF>35n=aS&jQAI&%{vqn3oKbD}JR5!D3> zqVZ9G>P+_<4q$ckKOBzDo)n$bPqA+KdK?};IWTG`IZQv256|-uym6MLXrf`B2-Z*e zD@#fiXEgl>fshmv=jlDD3ZKUpimt`4&d@Xc9JjB!JZ@{CiZJH{D0)x<4mhxk-Ybvg zrG+=)f_B`w(CS`;Ms|ZWjn_akO5;+V-zl~-?%vxZ13)Ff6mVoIs4mh6hJnU$dUOK9 zc}A0m!be+;b*E+uI+X=vhcm-Z}$b6@F7#KHH z%H#*jGytJ%h3OcMUa*yE-SQ79_Ig<^awi()*ijeF;~Q9Ge$8-}-*S_JNo8#J?f{Wk zwc$m6EG!<`dzzHtd)ryOf$r_8?q-IK{QExZ7?0}9ZuqA%2C+V|B++{ee_m<61b?VU zaQ5dLJ43X%UUT5-=-McoufI*gAXN&;em0b06#&RGTw$f$RZTd*3IG`oL7#Wq>qnW+ z@)A9#@@%!wst7w4ArLaMPs?q5!W0a-v)^urK&b1-l5+2MXVxHP#lrv(6%9W=Bc2*1 znj`*`kdE>Wec+Xf(}->Hp9<#X&o!)pqD6V<&bj@WwaI~zwE84x&cvfUTU-g#ZZ~ER z0A>Db3iXe`@E7UNN@+gVIb=WNTF)l-v04^9wv&)Mn;Qo1pFQ{4+kK2Pr9DEbvN%}X z^SSf>-8XDB3+`f`t~4d&Z38K`=EN#xi#Mp^iZ!*Ev3q_3{21C^;)vf4K)3t_ zBOe$2KA%25J1n;+9RBk1F{m#~bF~V~(S3m>tKM2)(Kjvg!?gw{K3O!K%baNuTF}(O zWY=9vzD$B@)dArX^e5m%VR5uYpwcwAA{zTp@@S2rA&k0iwGrER&i|4@$C(-Zgz#)X zooWy5Z`V-D^RW7$*+5GfKieh-fcz2uV^d7q>MTw6q^U57b1hWyQOdd7T2JXFvkGI%lmt{V;?ird*px{CU-E-QoyR!pT&OxTmWHO zgDOvGcV{bKwX@m&lN6-QRUVYKh7Wsx&@6QYZ_&Sqg+;W;&E08(K$!XkutWL6R*sLU zB0(1@hA~0mK>6ce9@-*?+mh7}8Toz`@(9#XQ1%I}LaPDvDachFB ztlb~6&E?s<)3&pYt z90Rpd)VfSqSEc6Iei)8AsB zu5 z(9Jl1Jq#k(Y3P-$0jSw^7$_ROhXqR(KUWjo-%>5wy9)5;T<*|D)~7q`lkD0vf+_ya z+gOB=`QVkap)sWMcz-YSQWO_noS52m{+X1N0W92^ntXYphnBJI(#CA=21^sS8h^co0gM7@(3-8%Z2bt_ozcn} zguH=%Q3t1|uf5QmTdi^b2_7RJFq0*rSQ)jKvZ6+(>v|r~>`hU5gxpY{&d*)>kQi3t zZ{&@%w_Uc(KR})%1(_(0)y$+Ca&WbH-DZoa;n2w2Bc6^g8;Kdm(Y$q=hD=yFPCUk@ z7|IW&e8Ybh0)!IrmC^?NM0XqmZR$a19qE)wa@FLS__S4QHKuhwV*IoUDmbVM0Ijbx z+w;6S#&mHXE^^Q1fk#Rj&Av|r#PDI`ja&rv9sO%G(#z-%%;SHf=5rNqL zBkn#-e?Eo(2*T;bqTp!cm|uuI5Q&iXktIb6S=W@S17uEkY?$ZsrPYca7k$vbOaAh$ zr$52|ZQ5))Yt7E{#DTl7*h+1Q!mNIC54~_DOcZ&7i(9Hd`RYR?Bzl zt0-Xg)wWcXbeS_r##*0)IFC_33&r|&u~5ft66-VhS$tlOJ&&x__i<15dwdYb*$|Y( za3j572PBKgb)dE-Ol&mFn{A@L7z7pmyx7^G3C=tVTPZJUV~-AAIP(j)+nkRK#C~VF zI)!?=1q63kUkE%{4_D2`N@|Q1_;ufAmbLL?v)vvZrDy%jC`}5ZeYw35a%yg!+lY|d z{gN#e)=q&wS^7$T{GuWamb#8tIyAf|x43V+^TqP z8{0-l9UC3nw(X>2TW@UJX2-Uzj&0jUC;L0&T2=qEMg0qXKjr7 zHRx3`DV%Vu zM7{VpevIvG@zd9o7LB8z-;*cmyXoCy|70jRP)Zf3iJ1dNYIUjW<(sF~T*?}j-+6~i z4Do}Tn!DoPy?@5!Rsb^2x+Ct#t`W|PD zap>O68%2CHmb9uuGe-ZnF=4!+jN7mD3VB)?*toSmS5!UK4N4(4^v=1s-MJ0Ps(Iyr z)ab(9LK`4FVxpF{OzI~B5ud>RG3rZkbELhtc{$EFF>Q7BQD1}JjR9L`R^?Q#Ts3Y{ z3HcxwJu`6_B5C@r+v%22ih{s6uZg#P87H1S2!hgYerckJCx2_n`crBk%-ppru*q(7 zJ^ew|2KAAmXl`tHd}4P5oS&P^SzSeQb1yo;HXjfLDPe<561`=;Zv|s1=6vuON!6wV z@uWn95P`;;#Qa$;t@ihAb;1^zyMtKNR{Yx~4fXS9(I@pN-${Ke=Z&yh zWV#yTw41@aZzKPOH_}I|3ZbbqkhwsavZZCt(IIKvfl1p4Kgl-9F_GH4hIhtO8D~64 zf2%wl?^6B5gqAU($4Ok_jkuma$vTe{@fX;)NeLDCk6hRzXtgm~FJZSd*!_WUf*+w6 zOhuI#`GyB}ftf+!7^-upl^S_~V&JplZ#qCe zh$1PRa!23z*pUr;(8{VANg%voI`_x ze7GcO3_^@zIXyOao_(XJU4Qr^xfno82QILKo1nz>zb%MyzWDWDcG7_6i@Gg%xYse*w=5`5vc<5>Wm9J~0;9P*cNb+(~6)BJ>?sPdL zE7cNI{LioZ;9@4gIB|l&#tru#Qj? zo?5rz!f&3gJWreKROvZHy}qS2-!Ev|)s-55pRh@|Q+Ook{PFL|Et6@HZ>TK~pg6oX z*Uw#%uNL#|QTB^bl*QxQEeLqf(_KD(32X4I(mA{L8en)%{z_+%9Z$&Ox$Ns2+8|_Y z5mtKp+cK|QEx9Cz95$`Aircd&Fo{3PUXOr02!wG2jBCZ)W~GJJi!jgDLg;Wb*fQJmrn zP9^6Ni2rn>+40~GF8#0S9z$7+4YN6SsSXvSCS*3_rqajbX4%pVxKYt=?2JbMR!(GUePx}s@j|a+^8I!y zgkkm?H%qwzt*?&H8;Qt4Y%x~Gb`QgKqrfSWrJJGM&H>%T_ep;u3^FJ zs8x9U^97?2x()bVuP{OGgu~+(OiX2j94L~J#f*8z%9_?Bj?{(L^BSz9o3#{t^t$}y zGy&YuK>MsPqqP%?b7kY^PDHuq%+>d5u<%SS4vVzh*;lJ`tkxSDXuFlhm=pDwq)9|W zJ5AO5jg1^$NfL8bbr@7w*3)Z?^X*}`8}6mSjhc1)<$%?^&9C~{@6Y4GHvz)er~S|U zS~y3>WU^F0BJoqYc8~iVfy)4yUxu0+b!3lT|5$8Tn^7ilb7Z1n zqO}6wne56$@d{b39E-;Df5ToGs7g#=r^M;KEz~EDZdB@6ala%}EYGjOs!Bt0QU^5f zJQ&RCt~)$_Epy)x{oyFT50D!$JR`1S8^|}n&lw{0^l;dWDV}|_UfqGynp%EPZYeHZ z1h^rIRXpI~pnoIUZ6{%NJGC0^n+U$^Yzn)&E5!9v!gT_$P)b7T?5(<@VJQ|wJ5M_& z$Z^P@pZAV_owt&-I|M`Qyp)zRpIdt4xw;U9?^LtauE#LCQ#rvHGJS0s)hV!8cA~B$ ziN-1kBLqMEe+G{7MDd*S0;0qL3%dg|@)6ZHj0chZQmYpX+@ai$m=2mQ zsQcl?Gh%}gE!(AW*f}%W2jKBR{IPZm-|QR?m*p<8$1q;mlNxFpx!t}dJ1ne7aLaKt zk%7*Qu)}DKLm*&tOx)ZT{pBiH)yf<+(Ss6ioTj47cYX+{|Cx1?sZVv%?1kOVfaq~C zLd%v3?H8$jOaU@<8rnEw=k~H5Ny!l!15?#DVj-icRvNLYGMm~c8i^nM$J(BKJ@Rh$&fMXfEr%LbIOmGFk56x>r&CQ`TsHPgFVfB(d=R zE%VAbYb#Gcc~#TMXALc^3`P$2@~fhZY{+M}zJ|OS`m)Sg@N{|8K2a(HBv1mt$L&l>O0V)6!a`q5p5N zk#eEt>)_BnYo%s3Or~?BP47~ore0a9s=_x3XZw*nEQ-7|4Rk003=_vQG_>aw^qF+F zO;%W5o=h{7S*$Z0^G&##=1$Hj#Q+vManu0G{jf!Uwy+5Akm!z>5ax;q|KMmCI zArPc;W1Dd3>#B#UNYh(OYHZ{&7jb@gI zi>W8O)LUF3FVY`$`a)rB_4Pk}+}!+}922^@J$>0#?P0YZUdUMz-kd_W{uI2EPp@>C zTbP@I+x{sNWb$m)B0)WxRsyAUN3c%VK79Ar>H9M}PQWCoHC*Z9l(lbj;F`p>8Q?ha zGppG189>g#IAb}rO8=RAs3qI@N4EE%A>GWG=&r`^eM=Pn_p09{`R$67T1pPzy;C9- zfnN_NmqKh@tU(T$Kz1&2fNxfD4aNAMz<*CQ@IwvR=UuVC&6;JiAUK;VCN}*)5^@P2 z2BE!v5B~?V=lo^=U54CbI}cZ{ZJP;siGJoRg$&G`YH1i~hj=6`!`q&C{U>yJo}N5h znj5Z6irUIa)#78;Gel-RLUcIj2X*>IH(OwIfinWg&Ah|X+a@9)At4DeRM1RY<=l=) zvDS#?rMYkJi`lWX*mPE%G~Ga1J?40+V0roE?+R>gy}ta|8&FU3BXf$Eu!LzYo#9oS zDgu!9!OuNZr>&t%lKUb0UdO_Rvi(7J-Jm!&>?$FRq7s8fN2f8MUxmT*SLnQE>i8W7 z>%EW}`CsLx_@jRl@4hEQ?(Yb(Jnfn3*4|g0Awva$hjmRM>ElN-F6hWOC=>X;yH}MG z57hVxvY!+BPv#`%EYrPGAIp*5l*81 zDbmOp#S;6ylwjRuc2A|x=Hmb0DUVEVKGI(sA?7_#VUiGW(<)&`qiQl7>hus-{M*u? z0>xZxJxGHI%N8n7ni&C8T$<9*9Zf9bhS{VIQ@9D*3RY{Bm2SeQM*?Y{?RAq79suE3 z7|%TG1rUw#Pd^|l#bdufjN&^aC zaC^w_0%f|Fp0$prsp`LgR@cxg&LdiU6Q&xyg=U!z>8e&Yi$)6Z3fZWe!&l~;_G7$S zoS^X%To3$%;84^ZpG0WuA9we-8_)%+lxEF}A^EF~edW=zZ?SVcvT2>nEWzHPz=wG! z%<>Uhs!O)4c}!|Z-ZM(6@;_h%5zGxex*Aehuck7h6nIvHf+}TG zx*IRoKa*mgq&W905Yh^0S1*#>L;(k50%b7(=LyKHHwMLI)(qmr(iFkP!JMM)lg_ab z7C(@W?D!}1hmr~Wy}wYRZ!jc_g9f3|)d5C1B>!X2fJGSJUxPK&TnWaC)wt&eZcnhD zVgBB4!*-HHKUS-HP5k)37JyESxENR9*|;)Dis3OBXuILi4@XHG^Nl7$Tw_$G>s|F! zp+EfokD-0!mO{ALRQ^!)-gMb1)4~~sJA?3fLS=pJOC5F5^X>V5(DhEGT5L#)Z>xc5 z9i#cbP*yXif?_CC*7-+8CS={Un+YX%1q7CVkUN{``i}Q2?~i!E^f`#hJSG zVGL2I02PtvEf-Xwe(g@tR~3O) zrv%hJ`BB0y!Clo?6`}Uyw9m~JpookA8wiDLzsy#ka%Cx7f>7;5+d$f8|;N9(GQ%gHn&VI!gPr%tgB!@E$Z-7 zulxuSw5Fh+%~sM>JA$CF=9!n~gnNW8hYc3onw>3}U8aqFrW7?0z zJ4q0zRKBNe^|Eo_Goq zOQpSA?=%qZh(NbHdQl?>F?qN4BqX};@fVMWIpka8?pwd`Nu{X`IHrcGaD8JD0^215t5<4;iD`^@$1YMYo4`GX$iNVex9KJ!o za)Ryxji#fs^=Us*-W3zxxyAc;RV;;(UOMiZ(N!Rl`?^yDWcNl*Nlq|5$pehw|;qd|_MaV7Q$UZm>yJQQ& z1x=BPk}cqOf?QEhDj@JX!R%xodC;Zg`&>ZgShnJ{Ia1{9C7z%>+_})G)u4+#4aee? zBE^IS5e&0!LSwVJ-)1J09ylaw4ZgYG&rYZ3CV?cP#f+h6-m;hy7#^ID>G%&Q6*xlX z#LyW_RENr_YJ@Jk`Ud`lF?Ql9Ijx&kZ@y9tCeYBmUn09w?F^Y%*nVd-`(|#?!f@)K zCCgS@L+s|zosQhocpfv9$R5c?RikXxQ}9csGJ2Dnk!V$sKZ;yFW`7_kofAxr`)|4f zVgU99<}A@7Z$N+2&)i}?M3#nUq1QA+w)3iC#=XY4Ivz{GGoj*ET zdQz5FHY!mY)9|==_%46)L>%vvAAi#J3XIEjP^#d;kou!Uf+II|S+LV0vg#(U4OKA! z709)PE?dbKY(FLXdK+=SD&{{J7eE0!Y4xj7*_X6IQFow!8rwF(Y|7ptG#a*bl1yY<>YPhKU!G%k#Tkj$e{U2 zwpyS*J<#}kDgyC0>C3H$eW*Va&gWiQ79WWGIu<`jDpAFBCyycrh}{e`W~#UIF;fMj zcoY}C?T`alSQG=bn!;AwDNCcT01Safjkvr%Q!I%$mFF=jA@tE|=898EEQc^xI(wmK zLshsP7;~B#I~s(0vtKP-5rSm>WS=+Ay&Jx3rl1Jypvc6PvfpTpQ1 zlFiJeB%2D~|1$ALZV!=&1~x;M`aUaI^lq#(R8IcGB?S)NOm!kJtO0I;lADGjuZnpn zn`Jc-OJWfCx^XL}e6@m`rOL_4U(q!fna?_#?ZPaiyrnX^oXo-XCVu>{W%5Y{Mle_h zW7OojeNOvlLP((%d|Tnez)_@|JieN1dm2peoAhtW0Z6xt5X}F$D+p28EM_)yfA=iH z8Sp?|!*D|S2PdZ}BHVC2Eglib!GNoPXK=Zc0VTuWCApls*DLR^E+K!ZKnb_s0>4sG zhGCSp{5e76EIW++hX%mTXfB7Q+Cyr zQ3f*DlK_{eR{vp5C9(ode%P77O3v>6wEVP6^NVwj-kGsK#}fkuit zFdH9%BN3pu7N%V-Ws3yUo-Ge0see}q`xI8@PrCX~45|kzKuhCIAC1YmFb*UJB;LDe zy^7@~0^)ee-!}B~?b9{NE*%DQ#YHocz{klqFVGW=k7*)&A$fHO7uv2*s?X;SeFSIS z`z~4|uM`TufcphRkb1szmx@71RO&5NOJk`g3of~R><+u?&>{fdWs4kROPQBSw3Cd1 zaRwGC@IvJPOo~%(F293)nLHG9yfQQdJ~rFeE^-O7Hc{>YqfpHnu6nui-E%%g7ulo7 z9U;ui-uu_}UYYl=vSLEv`Evdc$+^1GoE-Muxxc&90M$(7M&>y6+>>CLNmlT>4_MJu zS4i}yV+-d__3f!&0y2!#*0O>51{&ThIDUYP;Obt6B{I(6tFzt3 zAcvt8fE0tCyJ4D-3&g^xrFiG1Ib)V_6uVr6IU-g=r@@>m9h3sx%RaW+@ho7;iuXt} z+4X^1S@=DsZf800Ly)NX*v;3VySvTD`Eg;qD0oQ0(sj~ugA-*Q|2vj^oU4+`JzNQw z#y2c%ff()>K820{sg!&cH=;@MrYYO;01X2lxc6gNCwutCM5s_N)u#6&p8ou;9Zg}2 zQQv=T?rIgmu&|PX2$st>m!x1F7W6;s*LBjNgg|^d1na4GKn(C1y2H|FXVrzqH z%QJn5T5Rq8&pV+p1^GC9(i73oYmGADElJYW8&SA$((#9OZ=UcCjj1~F1lHa^RDR@6 zK>D2Iq=$3;4g6b)_fLPO;L{gu@jOWdLa=S4ls<2cWVvq7sbVm_IIF2lwKzyFtEOTf ze)bejx%%Lux{nCiVUIrR@I#Q3SalI-t^blE*wSf7auc$)e7D|ax`Q8xe)#Exo)nW@ zNlx#+@>FZ$q~0HVHt1hdhySrpY+r0z0R1Y2xm1Q_;+-F*=R&l2v^81L&j$b9?JvSd zS3(5J&X(Rd!5nu!6HKDj2oLw6=IyJPPWDjufh@{@LKYUrEtiO^u@ql)2FTsya3&`s zUv+1?r%{@2Xy$_6CDha6mwMbQe4LFd!vs*tMfS`x{y3+djPW-0=eF*m&f$z%K*qym zCXd3hT8JHktX{`Uwp5m)yhc3u^yco-R2ZEkovW&i&HbUw6pdOnuT@V0N>;K2D!j8% z4N{HO13%7Jw%Fw7LzAt;>^d}tvM{Fes+7O{_Q@5hY5r*7g;Pvr%Bg#j52CXpSST^) zok?iS)gkwGfi+r}t;&e??RNq@pz{EPJB6~x>a?&bM=`tW{>&HXCr?7Um@s#<@3iYD zCiqiHF2QXk1+Bqr>KS5U2dOTTl|jFDO0hI8LZ#FY}BtQJ*0#`%WGr$D) zrr`26aSKatS`|x?KB-PC^(RdRcXj=&JvZB7PRkL#x?tR|jNb#SevcRep!hqeddpoI zgrPK5J=M?jL-CKF)-3bzy!$iro08q~e$FCB?bt2k`fP#jJ_wXHf_DJJ&HCh@Kw_?l zbQxfBzFW73N%WLwRIt^oV^7q;;-`})njfDGZROeo&A7E*%QP(z2FUw8GjRA2#$Inu z0x$}bSLxr@yj#K-pt&u8?8V*V!CP9}h^SG}?2i`lBoQ|a58v<`$D2cWWgUovdA?Ac$wm~0kTCVhls=c|9EvLP7 zk7kC`VE-gMlPBlupe@1%W7>T6Nv(EUQ_I~zrSs6W5#6T;bZ}3AZ#91~>Xqs8zk`(p zvX>lEd=Q@|=6K^OW79zkTkDqUbS=;MV~m7O*fBThV{(xxj}CV6>=^L9mjW; zQ8S3<+XYFF`nO!mkgG?`Q+k0@E&}-<5*=l%Vfxu;NJ5sLSBgS8)b8-!2m?{mpCZtB z5K=MQz3uLUEVflZ?4ky#-7Iz=Y_1X_R~cJ>R)>hL?W$_;nnW+C&IY9a6_;=@b6n8% z263EeQ{61AR7U7aPV4o3zNGQJX1*?Jz)PnrYo(qf-w`KX-o6rqHbg8WF-xaHmn=j| z7HeCH)vESpE+e%>y)FreY2WWtm8^hw`EDG0P|+=v0COF{n5<4qReJ-|Xm%TNd2EaC zp^uR8&q;L#md7Z0$%7C-{GbS_CbOo7{;d5^4z`0Jw6;pd+ADb6&>We*FHaB9;i=C^ zJV6O&+uGc?+FIPX()Bieet}&z`@=;3Ta;-N!4D9Dxjo8h*(!tN*UR_Wr*Z-^vVVIj zfAueAxSZXA8d?#71?EFVt;N13d)tl~!!7(CUomi}*`U}&wGZ`@nZ(kSSiaDj0THJ` zr?QKLJ1mFrJ>YoTPu;<#9lxaBO9A*+_4SX#I)tWFbzc@@`kFAJ9t!pg^T{#LoO)xg zo}6hr=~^R7|8aLnZP{1-7Sh24(p!Skxy{dRG3N?Yduy0$$YeQ{pedAz&jE93GVYw0 z2FGlRNkwBBe1t!}FSAXOp2EHF;qa=n18kBm++EA#ay!KJE+)~8~ z5`6>u>P2Si$tk@_Fe$9HXLjtP)=~%I^GqW@3=c-0Msb5bR4)B**B^4ze8F&x%!O8H zCo_1s`Ip$yx9@KRAi*o_2XA%)e1yH8)GN0YpZs=qd(l5HPn5t2yx0C>*p zB{yXZ%>-6z#186Mgb)9qWdZlDlta#d!?FPi-AM(cPavsGy>kRuFY1B^{Gwp^f>J~z zub!N2`IFS>X~SOndqaTD0UPzKL&h2JtHHgv>L3Lli1lJ;30LIB(dk?I4g9l%j4i^t zEvz=L@sw77m@KDh26Ylh>?shVbJ0qw0D~@nT9~FLLN1GA$*M^?_%%pGxT<`#MMeP4 zR`Z2Y=1;XU{;vR%@NI_V!8CP_}!l!ihU^W+7U^Qp4R@9u}8&p+cXo>yo=QJ^BcuD;(!R#J^1(i7g zMO%)<*KM?D82(o<5VlAAuf~Iuqh~-o0qYlTzkL`ub)zFsuJ9S`Wv;E-F3g6Ld{|Gb ze1i>Y!BIa1orjz&=#}N(m=#O(B*d_%Ojh^)1W2Uj*NJEBGr~VVPJeWW)8}yt_ zogYGM9DL_yH1s8+w5gd9LTZZRt&W4COBVnFGkJs*z`A#jlU^FahS*>{P>d}W7{TO1 z8CDqN#>%9;M0=YRU>^onUQZP8;xIuK z^7qDl<=o$pFoGp1!mGA^LthZ)y5Y2KFvMRKZdwF5#N0a#W=lUo`z|8x?1Xc z27mZR%gw3AIdheg=Rnkxe-^nVt#w%Ygh?0%eD}3p-R83CF=m4GImH5{ge5x5)H+yP z`km!{8vY?#LHV7n`Mmmx-S)^Cj(WgoThLvMb#4-!bp=BJK^w0nK#@E8D@5mlzq-_Q za%q3RIA3s_WDPQr%!@8x9=?YIDGAg=ll75*Yth9#iLK>{y;Vml;Xe$p=)a`!A4ay; z2mwPoX$yw!L9vQg*EcY{ClPTs`o7$=iTDfL%Do){zpXPs)62^Kvfg>o%MiUnxYf4P zZEaht*@t>An>hUej>siVzTt*LneGlyV06SC6eQ6zWNJ<=LV_$bol{I^#gni}mocJh zBt30SGf)v*>suwM|D>Bpq}(^jz7xieg9A6Vl>RR0C%*gffUggi_M_+XD9wB?5ipNWOV0JOD`O_) zG^d#VOa`7RNw4jlP%ucY4KKev^-TEUFP6zzyZN^P?Xf3y`A2)X6przNWi#CsZ^taN7z zNe`9_qrDi*ed~BFh6s*@KA#R(1`T5M;XTNx5CDO1i=Xwwp5pf)pD!TE#O4(sNbt(}{(=dCQ*#MOrVADu?Zn znQuO6cUizrN?s%0`2Iji z?E|Ez;Wx;;mvp9HA7Cl>S69EVm~H4q0-%HD;*3`bHA%M$iGy^=*~VQvdaVk#6&`zF zpa``iEil0QrNnQgo~uC{+{t@SoAN~sT*CYEK`^Y{xDO*Cpz9C0)v9`Sa3qg)83wXW zlY@g+NUYVI_q(nJR6e@5R~Y(oy%nzMQ-I2behtOz-SOX$e_3Rh6eTUHzW;RJN zr0ETdOS+V=GNgIb3a8{{q>>1b2+A$23qJa>Wox?eZF|kR+Z24&IQqlrzqf=hs|uZ66h!>OTqk zVvI^3##JsG0<}8=Z}#huKD1e)n7Rd{Zpq&FcY~2?yR&K2KLL~f&Toa;OUBi=z3sIYMtr^l;H$_z7I(w%f;YqzkO-k!6JYi~4}y@% z?0f^{dsn2!3b;w|UEqFb-^hm)$R%!ubEXETeT3TqEUCU0C}>!Acd2p{ngFM}J2m2g z+*zCGE*b2-dm>fUqO4Y42=!_V_J^y%y=!q7v(W3%Ys1EKbr(IIM7n%gEuFPSg+FEZ z@sw4W8&d6~7c5%hjUrcSeA4HS*OPx-a(|+RHlYR!W47f}Qym_)bjkIiJrj4 zd{)ge%ZFU-NRL|Wvo5W>vkI=GQmo*8*)CfW>i)sK0_1lX{ica0Aq2kjgX^R9iU$~r zCXHBXe)fAFk97SSefYPv5))L2|3jwk0U5xtSh45!7j4qQRh5BrYdAwo>Y?9?`!&m_ zH*1CMwWT1Dlj}>RW zbT5X`;fFJWkC>5sgZ6pl$d1+jzB*lrIy{`7d#P3Mll0@|>Ht39vi&r6rFqrq)`e7} zVa#}f59xfK(q3upEbSR$Us1e7+r4}q+ly|ZUf=rJBv$&O70h`n{$XJT*?|#jihHV4 zIZ`REOy+s`B_G=%y@klf_*?l@Id$koQLrGYEX7suQkd$ic5Q&Qo2d2CVrZ%pVV{Vzes|JYT}Eezujq(kPanOlKv81iR1~pAy16e zN0Ke5NZQA3iNy)ROMt%%AqWus{R|EE#`<&$^zQoC2mxFZO!B_yMIu2X4{VCiEME2; zA8q#xh?70n^w)7lS&f@EEbZ>`JvVILc`YGx^kacl&U^EosvC0!&XJMB^St?cEY}dGtIdjFO6RHN#N1 zi+qkDV`#k5-_ZZNpwalJ!~6gLWwpFwZ&w8k0-}bM<_HFgnIzeT1F&QLt1%Gr;E#@J zPO*%#t?&1m`~BvV>|Oe-Jtw2Ps@n}1uZS>3_Xuzr%Bg9m@sc6yt#Xz+5lm) zpKQ{hff_XtWYRJdDS)WCs*fp0ohlpkZ7TGMCOaRDX1i6R#eC} z7b~pBNPln?K!mswaIsY(I+&kMZ|{YP;GWRwdbrEV`37`Bzu9jZACw7!!fJ2GoERLTeWGs?G1uFYeCw zz4!Ax4*MMlT5GMcHFO&d?!+T7oy{@+0G^e|G)w)7#{hg(Wa@j}x4aWgFt)bar?uF& zn$H!YqX#+2QNSiNRG$JN4&6o;SL^254qRux8W~ffE5kuPppmDYjN}H~_re3=Onp`7 z#WvRrbLZd|ODfT4qrD3SKlMl(ge+qzrhbGbo0%>uD~oaUoQUsZ)&8>jPw);DdsvWM zUN8l?;e~j8Z{wSW%=2(%2xYbBtE0w$H#np!l2_Q8uMB@_H&FF!;}z z>0uH7_z6=$TKOi*2`Q_jUiiK9mK`$)!Z+xq;KXIdd$0IBJJv8Jd^v?}Njuuz#suP1 zGTqRQdNdNyGswl~K(cR<(BhIq89^E|!1yt~2o1n@t$V)d{NB(9IT0)Sk&xMbp2*e_ zyd&LMtSTwrg}^ntCffd0RR6v}j5KJ@?=k9RfVxPrNSk;H3S)YzR=t!&S1#`HX6aG} zpSui&^Y2dO#dk3N3U}&o`P|b`uR*J%Ypap`BR5U_aUhpaGB97IMIHIof+z|UyUECs z$`Y{9o4CLWU>)@y#hc<^g8H=Bez=KHuAN0-du|dEoHgez#l9557M68ZHIKQUst9GN zuf3Wh7~`7MX%)?#`Z zQS56euIyp5M5xQfI7u2MHE^W{eAaOLImJxPx{ygUOQ`qV-!GO&UR7039}N#K0ysn)3Vf4D`TtloZUuEIY8qvxLxbG>*i}O=7e#l{UICJ<@wpy3IZe-M_&jJqeRV*H_mc{4$xO>;)+D>YD{J_6*N&GUHzx!ih$w>l#DYbXbVoR(UDBvQ{f7mm1 z9cs#!J{2l6y`UYZ_0U&;iSd|jDh_xSsi}m`{fxz#tavlwwdT#gCREN*ej4s0oLq{N@yYMR3y|@v&>15;RyD>a( z-bE`M>ppm}@HO4kE;Vg)LSWe4Vu-C53}49xXoHK5)Q5ec%dNx;NYU&B=(H!KxNX{+ z+YG=zlLAAtF|1C1%YbMT#HCGQH*S&w_f8_&O7vdOAw_M)vw9E#Q2 z)ZL{s<*{39)4Df*4VqZB(iz<%`sFvF{PTVUi6Fu?*#8m#?#D& z7$cXk{hTi?iL%Dw;sIdwB|R$@HU|uH~1Ge!92+bHi`Vbp>KTf`EL( zfq>v98KqzXwnmnA|NZspt8Qz*!H)7(W6)2HLxJ29=!duqDz;$+8d!76eJO$h)8vxa zHd`#H?ADd`-E$&29=YHGnkaeL&Hu8QbI<#IxTxQe6hD}+MjzB59uIrXs%a*iapIZU z{P$W+t=R;JKrKb_qrZc=n3-J^G0$uvqosMVsmnD7VA=Y#`uBOLa57rt0>$Fz^sBs} zYBwW0p`)sq<_O2e_9dtkXY&x`btkIERv>a<~;P(%Ujq<7qx657SD5<+B!w zZ;4eD!#qd9>UB5UwN~ms>tv&$NKg@kS1Pk6j0;bZx*NvzzLt`j_;tW1&13`Z-8LLZ zuWA7*P(;~3jzv31rHSzVnDe?d7_PYILzax)fOIbS4)H7IzL_BBvK+M&J?t$gP94l| z{7u>COsej{mCjl;uluSz4caWHj(#eb(0pTVv4UIw)$xV$Gr~}8OJ+f6>p;ospER!| z1Un~c`$F(-_7fqRtqc2@$wS9E=7` z|7;JBziS|um%8IaNJ!j^<_Q{bVsIPrRzOli1FS~Z4je0Kz7hvh;O-=62-@ewoBY=B!FUG zbkf)e2FKbqt_q$!msB^P2%AsjVPFRgOyX}}za%~1mZ^rvK9Ovba>up*SN9A_dMz#? zS+Gbi7T@V7Q-pXU`Iox)Ms#MRRIWnXR*R?F@SNIFrNws{uq=LP0WbV$4 z`!LU=gU`hG`}mk7DotabgJ~RKMnX**tr>v7l^~ocyX>;1D1o^QNx{rEu!9z(X}{$YCm4UKYBR@JF{{XD?X1EUs^feXFl0@l-{=jBjjXSvqicH z?!mgg5B2voy9R+V2@{Nz^6xFn4?n55xZ;-F#EoM{<;kM~`+W?HfW&$71I;hnlwFC#%}GafpOA zdD}c8KcfK&9})dXIvc;CcKiJ)25-w-*i0Vq&xiCYbhG#Ed?Rr=ZCAh(k0GQDHj3l- zB|jQlIjzFYBf${u4?{yBtzg^KYO?XqD{dA@G;}oYC8eHSR;>WWgch|Qq#EL0OwWkr z{V{cMnK5^pw?=n&r%n`aufIiyo}o6KUPL2m-S{m=YFBuDwKb*hOgER_FKY=^%uY?K zCv3Kvfjycu#H*2-G5d@h$G_shj*0)1>8iq}_Bh^{4E0Dw9n~Y>QJF@4ypU(5r=xw8 zPh*CGQ>a7fxYeHsQlEy*HS9-{C^^5LV4dJ1f)`hMTx?Zr3^_v?6^xL{5&dOLug9y7(KYV?!1wgO8k^& z#SY6%XeosxO;Ih57sg-0gn|f;OspGKFT`SQjb=@TpI0u)kWMsZuS~X)%+<&_!n5o>-jlU471z^_#6k@~3d6%iQv{K`8I?4zmH&umtwvTyLb~7bb z<)FWk%*_@AcOQ3yy=P?f(--xH9zy@K5$Us-r$h#>5o%qR9rT9w zz;ZrwsS#7(2T7j8*63y|^+ZP4O|vi}l?I(;?XDBE5{LLbv6HrJ*lD%I^v@YmO`rUJ zx?JD}5cM5S+09|eMS?2tN>ds(%z`VNWM=zz)y)n}%eQ6J_0++=Ua<1j$=$cUBH4@k zITH3#>ZE<>B_d5U(LDe?cjjbm6pltJ9U126Tg1Lin8j6eszri-Km;Vvt)` z48&U}q-*G-ZNFULzcn*dTxX-qd_JbgkqaFXh-VFJW+R zV#f8Z7(reV4lH{!bp$4?2hX3AX#8cv5r-MOwX|Pvk3bK{&~DT53E8c=$Ek@{+E`f`Nmdn5$l9-N8Xx zbGQ&*099>1I>=S#M%Bx>-tTroVWJ8L#Mth|Q{)}zI}w1ffngKoD?QN~U-t^aL40TV zYrpVu79OjooODgb*?K{mgcU6|RD0kzqGTudDgiRGu4z$>1q$L|jTl;&;JlBgkJEl@ z$QUZ|-i?LQ+(ns%+nca2jXAoy2^|46HFzNY1roPMac#q|wI%X^7DNwJzAVvn(mn;q zT25M%p`XCv4}FPg;{dvrmXr=ihif`%xs_!Eg9YN%>QPpKCEc!|w0RIV&LyzSG>Td# zi*r~>X2i#s2)0&TZ|Q)mU=i#@hx$x>cRf2!Vgkh7ts{(*M82TQUl^W+7tgtwmu(P- z2mxZD17jc3JgxBsh(mqY)MrIaIkoDc9I|fa4+{V)$09-Uz1kItvJmim$JP`YY$Bz2@#$`%%lTAT{9 z-j22jfgN3aeci7F1Kr~lj$S?AFPG=NckX(@;CrxD9(7n0KN0>$Ozao5KjOneJd=m;C^PRBqR^GYhg=H1!DShyyq+uB{H;rPcQAL2g3P zrQ{%0wC{M*7N~ilGbKo7Jf`Cy!>UebErvx04%>zy5oevoZ}|aE(b@Ay)Xf_ABD3;F z@$JS1;xB2F5FCcIeRF5xko@adg|v29}D|x1v}?bWS#^FGeKiR9}2= zd3H7_Liq*$8M~x^=C!>+F`dw|lqWVAlTIQtHTy^i^*qu$|T|DYsU) z`peZ#vlZN17wW1S@mGnBv+7tQR`A(&gPD5T+to%0!KcU4*A z92L%0;AZN#J73#wf=RC?GQ!^Eg7f_IC)JS1< zMe>ozSTfJ|JxW4Xnfb%s!SFe%I9np@18d`=^sHKL)^u zhxkaFvA_Fj4cO1Ja|(K$zHV8+k5xZ5luD2k5+RiyK=#8a)AYOq-$5ks*05J^5J2}@ zxgd@GlmNfMio+lqjj;!0U~Q>pNl**X)3=J)OcLNUZ(P=sw^!bserjPC6rnH=Z|xx& zOwPSEZ|AK@iw5SB6rXo<1CW0Ln$Z67kV2Vpq+$Jt|FkVkQw;wa3eX1vg+T^KP;_>H zYH+0nOv6A^SCT-MQjHTmhL|@E8bUI%28e2~;^j{E$mz(0Q%Vxt(dwY2-l~)F^{wSH zPP~tVD2;n^oSddvl{IrTEly9@q6=Qp5Rp#PV^0VQUCt2kyI)Sj(lcg?BfvNpIc>C7 zS1eM~w;OVd!KeL|G|P3Ft}=s1nTY-?%V7QnxP#!pOws2-96wnpIb%;6fv@p~%1r-9 z44BCV2P5r8I!GB%E>e?{xSDyKly8G36>hzCW3*v~P_EisXW}}SrbgkWg45RDr;xqh z2I}z13VY01fPWhpukM@+rt=7t52M7JBau^-o1jz;&+()V!GGnFRqbY)kVr9}$7*o{ zo^DZWbb#?+uss;BSc#Fj2 ziS$mJk_e9wl1A)jC`qrk`RJzB#mw2Ws+CYOcvOMSM$0NNpbxl#YqdC5FqrZzsN%;j zs6C7lR{_n3aw%>Q1%mbl$G&>j)r%2;OsF+>5e!jiMb+}Scz}ti3pkBo()F}7yll`2 z9+iEfQu3bK60Lesr@ld>4NZn9S#|1FfDj`j_kp9iXe20U3YBl>_92fWC7%J|nR$(5;9`z`okHFyF zlo9SMhmpVEK5NS|YfA)d7rbu%@wBlY?^0HW@;5E^&@DDVlHcG4)8Dy3GCg3eXE`yWanJ^q&_%eO>GalHvf{38 zY{JktJ&2YTsMx|_0P1r~cz6#2*d9?vaH+ne<0(3B-o+osE&x`u^)jC#$RrMCU1uw< z9X1Mq_54vAMyCO(S~Hx%G2duFd-_k>BE4OGK5}vWgD-t~%MhHdpo};`5a=(xWE!!0 z`Utu%h@et4wN|!iS!8Sw2hl8SkxLr^w$tSHkd58TSbpY&(`mc$eFDT*=(@{95JC*8 z?K|@#Kovw2Kh|tS_7{j+xB|bgPnN7(jbI5grry}BjcyWp?I9&F+UR9;cYsu~66PO< z4ze~lzP37A;X2u-LXtj!@gED)6>p|WBRXalFF~v9eI=tfu#xtVG%P{p>tqcJ@}FO~ znmR)_se|RmHs(OP(|byD1E*w3n!@h#5{_m$KIp|-E=n2@H#`e%ha~YDc^ZOc1XMR+ zB=&5(jN?p!+4fJt2HYr$NRb>n_qb~@di%LyNJ_9Lg@Nj7bay@g-)r^wux1u}F(^ng zC>wgvDg8{(vdY!CnWetw9DffLi8|#e_^%58qpHW?6?lHFIJD-7p6bo7T3+nm$v%lUE)NTkps_%p_pvhz#N71l|Au&FqWVrujL$UuOJEBtUMN zOGwpM&J)_~xo?D$HCc7_CdCny76pxp=Nz60T&k!MjaR_Ws>K%#XW{sel?r!G#hdnFwl`ZPn7M4xRxdz{M!gK`d+NV+x z8>v|R@lv0F(MX|u60jX^&$w5dYj|?b!q-@h>G9}aT8&jB=ru{ldt{28)kH?>QuR|g z35aL2?HwB~!JEKnFFsu%TEKc)!^qWbc+2%5oyr+v7j$gePY_vE?g^c87B!qaGUt;0 zHkc8&=eL+j^0duUPt#=_#_3y{WIFp+IQNix35az7{@z}n4-qzICx^jbuOjl9C8x~m zt8-Ah>^R2E`7m;M9PtD|nj zX@U5}{y}6_8mt#u2vdNQ?5`6VY@8$(X~@_F*xwpY-{(Hs7m4e_;P@t{^l?K$<*hgN zOcroP?Dzdxjo4i=Tmpf^#)JdK(o+OazlFQ72t5}Pp3^1z{G@pClH&a5KESlwTnpy z_}?+1C$+wKNg}n5lhr-wA%M+TY}|_yCvy ztm$tdqYo_+m`1ne>+wzKe3|mG{0i@Y1i+5Ue4#MwdXAuZrbT>YiNh67;&MR=W%c8A z`XT*}~`ow|FP#h)wku9=ybBxdylg zlkmm5{}P1rCB4rUbnTfM%3sq1GPZwTl>t+>>I0&>|#IJ2K>h>ps<+TQ@IoZs1ICF;a_wG@a z7kAjz>q1g&VwFWt;ft>A>Fvx`d2$Gb4h<9!NfljsTP^R24@=TMPy@8ME;k+}V6{nNlh9kWWb#YaF~sVdPq z3DWIBs5?RpZnT}3tqG2mV8rc zvkZ%~NEXUmI=}KjTs56NRW=OL1!V5W@JcM=EK>_W1Vfk+-1nG7_mO%qU=$QzR|yBs zK#v%6+B79H2q?38zTQ5byl5b&T_$~68;vOlg`)B8j;ueL<%{6>lFkuW-ke5!^|-AR zFIqD{SB|KhD`?ofWZ6y${5AZ4dcJY?`u?w;y1XJb_WO4g;YIn6+aYbQ0|!-bL{r9o zivy|mQUmEi?2<|thlmeL5z#e^O%Mm|r7&$qIKLzz4L(g(a&j}~@Mot$@}i?Q2S{l3 zP8%n2$kS&xY3+as&9v5bXB*H~obtE;_&>Tn(B6|^qlPT`<@4<2 zRS==*RgQS+{aDbGO^HpizhFNEb(KMH*LFhhmr=m;t{7pO2lB(z?6)t;eXKG9`JkMw z9IdfdvC}v?i?+7?sindEo6nmVWmVgIhZNCjqzIHVhA%zPL#XtPScC!w@8iE_DDq94 zcI+UB*V>=}D%Q_?E{F+obYj_wnky||MQ6l2;!3JQaxkz7g%9hDAnK9UY=u$GkDuAE zZ(F*A@MkqL0~wz|OR&S#vkzIn8pNNnQQ=_Tg?D83OVTBVsBSrN=LCzkhtWO1ANvv7 z%r8beZ?8SeqO9Pt*6aWMI}UR6Zqq5eD0TFasoxR+x}cWGTJ6}(zlhHGY&(d(wS+Jv zW*ak!%5v6o`u*S1&T*eJDbH)wp#$L zQU;m|nu3Gq*Y!E=NqJ_`@1It_4t8;Vt}{ zUe|76g0_5JOS|c2teD7%Gm=JIrdmgbFBb;INTmTBI~mr{X@*RFSS(i3RC|Q`L<^Yz z^K}%Mh~*}vRV|w`-S*y_o>&nC6*#h)5N5Cf%GiazwK%j|5&F;It+HS)?GNPSplj?Z zsEG5b96u1JuRdCWTD57EZ?x|h8ao-)lJM|s8@Gxh{wj%Zg%|6zYV+BBu?T9CjgqhA zktkHvPq9K+|IL__(qPc@y_))t0B3+Hqk1LE$A>Fr;-9E8#bhGTyATlDN@=V6g|N^I zSonv-ycvh*M*q!Q%%{DL(=?u#nJ1U1lRrf~a#vqxUC#yPQ@xg727_vv!$+sQz~_w8Y7Wu`O;}v~_{Kus|f)ByftfS=CZdc0t61KZ-uY zzSos@8v6sTrs6ckCNg|fN1eKhtfqJgNG4yK;GIUc9)en+#wOMJb00R7a~%q{J@myv z;D$fQV~Q)UfA-pZ!GTpSgt)uq?DKOnnCYQtAy-E~&`cW*D07`2lRs=;G`!5SRGC;Y z$w@4Z1x=pFS#?%0k-Onxe6qj_ zu+1MJ8w$R6+!M6WYO(Q8vF}7h>_DZz0SN&9tpHpwwAVfI%H>`==J*%liZ5yWvhV&T zoE^eiHR84)WkmYu$_2m1-H59MpexS^%vd|P($Lt)>sAT(WihoGFIL6GPqi_uRZoL-lJ-)A9^7yR%s)i_{{2~sDnF2ugw z9P#W+VBphXm4my0a6;jU@&C@>bj$GXr+@pbQ}+KHRMHqbaZmswI@@uFt;m4a-$G{u zMvOKEzU=uNX?&DzXTCPCTVMl*#PcY&th7-y)HQQ*kA3c;#r#xC`k#p;ep(UP*a<_s zJ`UsXfqUvl%6mh+?}|JlrhuV!<)t`Q7I%TepWqxiw< zW~;x!#I=C&v^55w8Mm+)0ZAov3`Gq`Kw!rJCH)6u(m1U*#Ucc?#!&#jm#3zv0!j+Ts zG(-=GFo`Oijlu-T+E7P2-Ts$%%|nZ&w-Aghu1y87&6wDB7C{}*#5X)Fgc%X7ZjQM9 z5_A9|=L<5ZTJ$utjAsS?{BBM_9QOI5Tke53Up2C@kN>{^^&DkW12L)6VYB=_0({w_ zAsPVp$xEXLqvaUedHvTR@04ZOZf1kuHP!B1wW#`jV+fDUauoa=;@b1oZ`wV<@J12j zGTlzvmQZyjIa{N$_j+jj6VOe^`RZ$NZXyalkSXQz3+PSkf&vw&M z#2tMDiKImE7u33c;FJ3ub3uwx=JR-X=r0Hj1nHnP7%&UQVJ~m|OIaC-YO@`dNMiUR z)+yw9NloE9{KcU#|9XGT*~NP7ZohcA;3K3Mr2x zZvSwIruXY@f9YfYc{}X6%s{*_91H+Xodl>>f355DZi`&4dVRIOAvk!Rd#zHahsXt%ikLtYYSqf3xjPjNJ%*Jp=Jm5TkJ&BQ7$w2A8*tJ zcQ7$IoH~dH?bNM#S{?;Dd4J5GguX3K&%n)0o543oS^V{kqJ2PLsNlhYL^kVT%@xFu z7^qGvPCRNi@0eX4xRpGFmf9z9yWIAEZ%0hdG2U9D`+Yg`3~$o4)-@`R7n^a;VW8GfMzZwR>R^ z;bg);s%bI>oyHQzWISABScwV9n?16(%Z>e5Fea@OW}6!f)nmoUMF8+VMH6kt0)x>M zSNH+3$!@~&;*kL_tzXdqvzI3*u=-Uw946smkp)?@E}_Y)5D>jbl*H`bvtErGoOe4S zx$Meocr#5Q44BO&@l}+#2ov=)=3MGg5d9%?8Z!i4UHgr%T%!eny}5AITrLKF=E~y* z>|badZA+%w5EG=I)C3p|RR44hL(jX9x&EszQc{)&>g%Ljxkgdtv;if{!fr1|=!}Udh5C_K%1UY&SvOe$~7F+**1X(P1dtQL<(AXe`-k;z$W&Z*!! z$;fxRs$VZnrcKQ0uF>~H$3}}I$t8XC%Z$i$ON3~Ow`v3`r=Xagv!N5 z@WNZvV>k*fSIpBc=>bXZ3`B|btRU%p77UG@!Qw$E#&q~Q;IDK7Im1I!0g>!arE*+q z4=73>8LWtTi~l%B#h|XbxCK@gXfb`;Q3O z6AdwQ^9Twz8z&OF{JkfiJ0{q=v=g8(ZU8dY((El)s+OPk)B*)_$j)U`lo%G&&r|o} zBt)R**(da0)>#AISZOpmw6?EbyB3f0!Y1lGz-Wfs)cFyI0*vZ*>Ewp@i-)F`WOHDvGvxlF|vPCJ+zl~h*X*sLSGuLxu=z1?iJlkZ9Qr=ae^DhOzVGYm3H>` zo45#JI|IUNY#AM5YCYL3JTof#hC#7?K{Sr0edX#g6d4h)gp2C@!W0ZSRwQP1>@DS@ z<5UG!4iVY9K$|N(L^elmIXaKTYZ4T?IA$USqF<|Xf;X=kxzijb z*%cn0dzmhJUMY(zK}R=G+{be!T(VAmH+j=QGXZtcN4~Dw?N94ZBNOWu+U0-HFFU^* zRTcUc*NDwe?dzDr^*n6Zso`} zLRZL8W58^MZRBE*%*hK$43%Lm*F~GJN0L)lkr?L-Z7_YN zOaRKnrOO!Lf*Q)iYXQG>c-)|DJ?jVTw~>t3`(SrJ&JoA?8=8R{w42Q}HHH6BD`*>D z3u=^leAA&^pSxlVYg$dJ?TO@Zm)DZsd{y*E%ehN$!3r5^=E9V2lcrivNX$3zI#pAN z9OS#lMsT5FoB4WBtWClYWZD+2Z`fmFTFc(ARK=%@g?>ZvCI3D<-i)Uf0bd~Ua=K3jPvkx?04$06 zcMyg-g9j2`{fLn$$G0vf5Att6$d}r|?UeK`Ec+ZBJ^~u|I5Zu)vkeO!F-O`b%p*3& zBjF-32K?pcuu${VxNjgpU7gih6(lV0<;cCdmoNoW1};5Pwkq+%vS_l~;<$UwsB^v1S9xT%{@-9oREfV8;&4^ytBrTI6*$CBm#-D8*I!{#~`XY9i#}DQ3;K z=9?oQ%t;;a19=tO@a?KW8-c2C)hP|psw`&Ud!m+JRgC~C%ek8&VW6

*LKY>L7rVT-U|)9@pIi1rOZ7;xLK$-lie74z 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 z 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 uTj-62mhB*mHM|))wa%<5n|*^kh4}T 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

NL_FE{6|2~NqGz5sTvQU%n1k4v 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%0Aii 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�~KP{`!xaI%{EEC|pILfiT;`y1pRpt-dk7 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 diff --git a/Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst b/Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst new file mode 100644 index 00000000000000..fbded72d92551b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst @@ -0,0 +1 @@ +Bump the version of pip bundled in ensurepip to version 26.0.1 From 16efaa225cbe53345b482daddee85b5ebfe3cb98 Mon Sep 17 00:00:00 2001 From: kovan Date: Sat, 7 Feb 2026 13:19:20 +0100 Subject: [PATCH 028/498] gh-140490: Document changes for `PurePath.stem` in Python 3.14 (#144450) --- Doc/library/pathlib.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 0c65a61a52e32e..4814f5f86b2907 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -486,6 +486,10 @@ Pure paths provide the following methods and properties: >>> PurePosixPath('my/library').stem 'library' + .. versionchanged:: 3.14 + + A single dot ("``.``") is considered a valid suffix. + .. method:: PurePath.as_posix() From 0e7c06a85880ba790fac4239b0ff1052399a36ae Mon Sep 17 00:00:00 2001 From: kovan Date: Sat, 7 Feb 2026 13:22:51 +0100 Subject: [PATCH 029/498] gh-142044: Add note to prefer `asyncio.timeout[_at]` over `asyncio.Timeout` (#144449) --- Doc/library/asyncio-task.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 863b3e336572aa..1b7c8ff0c762a6 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -771,6 +771,9 @@ Timeouts An :ref:`asynchronous context manager ` for cancelling overdue coroutines. + Prefer using :func:`asyncio.timeout` or :func:`asyncio.timeout_at` + rather than instantiating :class:`!Timeout` directly. + ``when`` should be an absolute time at which the context should time out, as measured by the event loop's clock: From 6665115679e77ff823ed400fd7276ae5991cc823 Mon Sep 17 00:00:00 2001 From: Guo Ci Date: Sat, 7 Feb 2026 13:02:01 -0500 Subject: [PATCH 030/498] gh-84116: Add missing backslash to `_SubParsersAction.add_parser` signature (#144572) --- Doc/library/argparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 81e5d3470c3e57..60411b0a0c9748 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -1896,7 +1896,7 @@ Subcommands the main parser. -.. method:: _SubParsersAction.add_parser(name, *, help=None, aliases=None, +.. method:: _SubParsersAction.add_parser(name, *, help=None, aliases=None, \ deprecated=False, **kwargs) Create and return a new :class:`ArgumentParser` object for the From 934997218e55714003276a70090a710cb3beeb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 7 Feb 2026 23:36:42 +0100 Subject: [PATCH 031/498] gh-143700: document `secrets.DEFAULT_ENTROPY` as an opaque value (#144568) --- Doc/library/secrets.rst | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index e828a3fba22276..997d1f32cccd75 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -62,39 +62,44 @@ The :mod:`!secrets` module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar. -.. function:: token_bytes([nbytes=None]) +.. function:: token_bytes(nbytes=None) Return a random byte string containing *nbytes* number of bytes. - If *nbytes* is ``None`` or not supplied, a reasonable default is - used. + + If *nbytes* is not specified or ``None``, :const:`DEFAULT_ENTROPY` + is used instead. .. doctest:: - >>> token_bytes(16) #doctest:+SKIP + >>> token_bytes(16) # doctest: +SKIP b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b' -.. function:: token_hex([nbytes=None]) +.. function:: token_hex(nbytes=None) Return a random text string, in hexadecimal. The string has *nbytes* - random bytes, each byte converted to two hex digits. If *nbytes* is - ``None`` or not supplied, a reasonable default is used. + random bytes, each byte converted to two hex digits. + + If *nbytes* is not specified or ``None``, :const:`DEFAULT_ENTROPY` + is used instead. .. doctest:: - >>> token_hex(16) #doctest:+SKIP + >>> token_hex(16) # doctest: +SKIP 'f9bf78b9a18ce6d46a0cd2b0b86df9da' -.. function:: token_urlsafe([nbytes=None]) +.. function:: token_urlsafe(nbytes=None) Return a random URL-safe text string, containing *nbytes* random bytes. The text is Base64 encoded, so on average each byte results - in approximately 1.3 characters. If *nbytes* is ``None`` or not - supplied, a reasonable default is used. + in approximately 1.3 characters. + + If *nbytes* is not specified or ``None``, :const:`DEFAULT_ENTROPY` + is used instead. .. doctest:: - >>> token_urlsafe(16) #doctest:+SKIP + >>> token_urlsafe(16) # doctest: +SKIP 'Drmhze6EPcv0fN_81Bj-nA' @@ -115,11 +120,13 @@ argument to the various ``token_*`` functions. That argument is taken as the number of bytes of randomness to use. Otherwise, if no argument is provided, or if the argument is ``None``, -the ``token_*`` functions will use a reasonable default instead. +the ``token_*`` functions uses :const:`DEFAULT_ENTROPY` instead. -.. note:: +.. data:: DEFAULT_ENTROPY + + Default number of bytes of randomness used by the ``token_*`` functions. - That default is subject to change at any time, including during + The exact value is subject to change at any time, including during maintenance releases. From e682141c495c2e52368c4341ae54eea041070356 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sat, 7 Feb 2026 15:14:18 -0800 Subject: [PATCH 032/498] Bump pre-commit hooks (#144576) --- .pre-commit-config.yaml | 12 ++++++------ Tools/jit/_llvm.py | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed88e9ca81b49c..1dcb50e31d9a68 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.10 + rev: v0.15.0 hooks: - id: ruff-check name: Run Ruff (lint) on Apple/ @@ -52,14 +52,14 @@ repos: files: ^Tools/wasm/ - repo: https://github.com/psf/black-pre-commit-mirror - rev: 25.12.0 + rev: 26.1.0 hooks: - id: black name: Run Black on Tools/jit/ files: ^Tools/jit/ - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.5.5 + rev: v1.5.6 hooks: - id: remove-tabs types: [python] @@ -83,19 +83,19 @@ repos: files: '^\.github/CODEOWNERS|\.(gram)$' - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.36.0 + rev: 0.36.1 hooks: - id: check-dependabot - id: check-github-workflows - id: check-readthedocs - repo: https://github.com/rhysd/actionlint - rev: v1.7.9 + rev: v1.7.10 hooks: - id: actionlint - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: v1.19.0 + rev: v1.22.0 hooks: - id: zizmor diff --git a/Tools/jit/_llvm.py b/Tools/jit/_llvm.py index 0b9cb5192f1b75..8b68c1e8636af7 100644 --- a/Tools/jit/_llvm.py +++ b/Tools/jit/_llvm.py @@ -10,7 +10,6 @@ import _targets - _LLVM_VERSION = "21" _EXTERNALS_LLVM_TAG = "llvm-21.1.4.0" From d73634935cb9ce00a57dcacbd2e56371e4c18451 Mon Sep 17 00:00:00 2001 From: Guo Ci Date: Sun, 8 Feb 2026 02:35:02 -0500 Subject: [PATCH 033/498] For `enum.bin`, update versionadded directive from 3.10 to 3.11 (#144574) --- Doc/library/enum.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index b39164e54753a7..ec7cbfb52b6e99 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -1053,7 +1053,7 @@ Utilities and Decorators >>> enum.bin(~10) # ~10 is -11 '0b1 0101' - .. versionadded:: 3.10 + .. versionadded:: 3.11 --------------- From cfeede85a79de3347168dba9a683363769209a86 Mon Sep 17 00:00:00 2001 From: Sacul <183588943+Sacul0457@users.noreply.github.com> Date: Mon, 9 Feb 2026 02:08:26 +0800 Subject: [PATCH 034/498] GH-131798: Optimize `_GUARD_TOS_SLICE` (GH-144470) --- Lib/test/test_capi/test_opt.py | 17 +++++++++++++++++ ...26-02-04-12-19-48.gh-issue-131798.My5jLy.rst | 1 + Python/optimizer_bytecodes.c | 7 +++++++ Python/optimizer_cases.c.h | 6 ++++++ 4 files changed, 31 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 43b268b0206a46..765cb69dc04df1 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1986,6 +1986,23 @@ def f(n): self.assertNotIn("_GUARD_NOS_TUPLE", uops) self.assertIn("_BINARY_OP_SUBSCR_TUPLE_INT", uops) + def test_remove_guard_for_known_type_slice(self): + def f(n): + x = 0 + for _ in range(n): + l = [1, 2, 3] + slice_obj = slice(0, 1) + x += l[slice_obj][0] # guarded + x += l[slice_obj][0] # unguarded + return x + res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD * 2) + uops = get_opnames(ex) + + count = count_ops(ex, "_GUARD_TOS_SLICE") + self.assertEqual(count, 1) + self.assertIn("_BINARY_OP_SUBSCR_LIST_INT", uops) + def test_remove_guard_for_tuple_bounds_check(self): def f(n): x = 0 diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst new file mode 100644 index 00000000000000..849889f81fc323 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst @@ -0,0 +1 @@ +Optimise ``_GUARD_TOS_SLICE`` in the JIT. diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 0863d5dd8f8df7..e82770742a356c 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1374,6 +1374,13 @@ dummy_func(void) { } } + op(_GUARD_TOS_SLICE, (tos -- tos)) { + if (sym_matches_type(tos, &PySlice_Type)) { + ADD_OP(_NOP, 0, 0); + } + sym_set_type(tos, &PySlice_Type); + } + op(_GUARD_NOS_NULL, (null, unused -- null, unused)) { if (sym_is_null(null)) { ADD_OP(_NOP, 0, 0); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 9a51d2fa366661..cc1d28f49442b4 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -370,6 +370,12 @@ } case _GUARD_TOS_SLICE: { + JitOptRef tos; + tos = stack_pointer[-1]; + if (sym_matches_type(tos, &PySlice_Type)) { + ADD_OP(_NOP, 0, 0); + } + sym_set_type(tos, &PySlice_Type); break; } From 3dd7a3c65ad4ac330ad44a519efa017484530e1a Mon Sep 17 00:00:00 2001 From: Adorilson Bezerra Date: Sun, 8 Feb 2026 22:08:18 +0000 Subject: [PATCH 035/498] gh-106318: Add example for str.isalnum() (#137550) --- Doc/library/stdtypes.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 0f20163e69509c..4fc6f3b9652165 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2180,7 +2180,18 @@ expression support in the :mod:`re` module). Return ``True`` if all characters in the string are alphanumeric and there is at least one character, ``False`` otherwise. A character ``c`` is alphanumeric if one of the following returns ``True``: ``c.isalpha()``, ``c.isdecimal()``, - ``c.isdigit()``, or ``c.isnumeric()``. + ``c.isdigit()``, or ``c.isnumeric()``. For example:: + + .. doctest:: + + >>> 'abc123'.isalnum() + True + >>> 'abc123!@#'.isalnum() + False + >>> ''.isalnum() + False + >>> ' '.isalnum() + False .. method:: str.isalpha() From 432ddd99e2b06a75a4f47bd99c0fd0c911bdb19c Mon Sep 17 00:00:00 2001 From: Adorilson Bezerra Date: Sun, 8 Feb 2026 22:10:43 +0000 Subject: [PATCH 036/498] gh-106318: Add examples for str.partition() method (#142823) --- Doc/library/stdtypes.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 4fc6f3b9652165..b8c079faa93d6d 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2483,6 +2483,19 @@ expression support in the :mod:`re` module). after the separator. If the separator is not found, return a 3-tuple containing the string itself, followed by two empty strings. + For example: + + .. doctest:: + + >>> 'Monty Python'.partition(' ') + ('Monty', ' ', 'Python') + >>> "Monty Python's Flying Circus".partition(' ') + ('Monty', ' ', "Python's Flying Circus") + >>> 'Monty Python'.partition('-') + ('Monty Python', '', '') + + See also :meth:`rpartition`. + .. method:: str.removeprefix(prefix, /) From b22ff1e543a458fff7b11225bf743d1730bbcc71 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 9 Feb 2026 11:35:43 +0100 Subject: [PATCH 037/498] gh-140550: allow slots that repeat information from PyModuleDef (GH-144340) When integrating slots-based module creation is with the inittab, which currently requires PyModuleDef, it would be convenient to reuse the the same slots array for the MethodDef. Allow slots that match what's already present in the PyModuleDef. --- Doc/c-api/module.rst | 9 +- Lib/test/test_capi/test_module.py | 8 +- ...-01-30-10-38-07.gh-issue-140550.Us9vPD.rst | 2 + Modules/_testcapi/module.c | 45 +++++++ Objects/moduleobject.c | 120 ++++++++++++------ 5 files changed, 136 insertions(+), 48 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index e8a6e09f5554ec..5c8b0511492c1e 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -725,10 +725,11 @@ remove it. An array of additional slots, terminated by a ``{0, NULL}`` entry. - This array may not contain slots corresponding to :c:type:`PyModuleDef` - members. - For example, you cannot use :c:macro:`Py_mod_name` in :c:member:`!m_slots`; - the module name must be given as :c:member:`PyModuleDef.m_name`. + If the array contains slots corresponding to :c:type:`PyModuleDef` + members, the values must match. + For example, if you use :c:macro:`Py_mod_name` in :c:member:`!m_slots`, + :c:member:`PyModuleDef.m_name` must be set to the same pointer + (not just an equal string). .. versionchanged:: 3.5 diff --git a/Lib/test/test_capi/test_module.py b/Lib/test/test_capi/test_module.py index 823e2ab6b2ef0d..053e6709cda42e 100644 --- a/Lib/test/test_capi/test_module.py +++ b/Lib/test/test_capi/test_module.py @@ -122,8 +122,7 @@ def test_create(self): _testcapi.pymodule_get_token(mod) def test_def_slot(self): - """Slots that replace PyModuleDef fields can't be used with PyModuleDef - """ + """Slots cannot contradict PyModuleDef fields""" for name in DEF_SLOTS: with self.subTest(name): spec = FakeSpec() @@ -133,6 +132,11 @@ def test_def_slot(self): self.assertIn(name, str(cm.exception)) self.assertIn("PyModuleDef", str(cm.exception)) + def test_def_slot_parrot(self): + """Slots with same value as PyModuleDef fields are allowed""" + spec = FakeSpec() + _testcapi.module_from_def_slot_parrot(spec) + def test_repeated_def_slot(self): """Slots that replace PyModuleDef fields can't be repeated""" for name in (*DEF_SLOTS, 'Py_mod_exec'): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst new file mode 100644 index 00000000000000..7815176ec85d2d --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst @@ -0,0 +1,2 @@ +In :c:member:`PyModuleDef.m_slots`, allow slots that repeat information +present in :c:type:`PyModuleDef`. diff --git a/Modules/_testcapi/module.c b/Modules/_testcapi/module.c index ef657842e77494..3411b21e942a19 100644 --- a/Modules/_testcapi/module.c +++ b/Modules/_testcapi/module.c @@ -1,5 +1,6 @@ #include "parts.h" #include "util.h" +#include // Test PyModule_* API @@ -270,6 +271,49 @@ module_from_def_slot(PyObject *self, PyObject *spec) return result; } +static const char parrot_name[] = "test_capi/parrot"; +static const char parrot_doc[] = "created from redundant information"; +static PyModuleDef parrot_def = { + PyModuleDef_HEAD_INIT, + .m_name = (void*)parrot_name, + .m_doc = (void*)parrot_doc, + .m_size = 123, + .m_methods = a_methoddef_array, + .m_traverse = noop_traverse, + .m_clear = noop_clear, + .m_free = (void*)noop_free, + .m_slots = NULL /* set below */, +}; +static PyModuleDef_Slot parrot_slots[] = { + {Py_mod_name, (void*)parrot_name}, + {Py_mod_doc, (void*)parrot_doc}, + {Py_mod_state_size, (void*)123}, + {Py_mod_methods, a_methoddef_array}, + {Py_mod_state_traverse, noop_traverse}, + {Py_mod_state_clear, noop_clear}, + {Py_mod_state_free, (void*)noop_free}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {Py_mod_token, &parrot_def}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0}, +}; + +static PyObject * +module_from_def_slot_parrot(PyObject *self, PyObject *spec) +{ + parrot_def.m_slots = parrot_slots; + PyObject *module = PyModule_FromDefAndSpec(&parrot_def, spec); + if (!module || (PyModule_Exec(module) < 0)) { + return NULL; + } + Py_ssize_t size; + assert(PyModule_GetStateSize(module, &size) == 0); + assert(size == 123); + PyModuleDef *def = PyModule_GetDef(module); + assert(def == &parrot_def); + return module; +} + static int another_exec(PyObject *module) { @@ -368,6 +412,7 @@ static PyMethodDef test_methods[] = { {"module_from_slots_null_slot", module_from_slots_null_slot, METH_O}, {"module_from_def_multiple_exec", module_from_def_multiple_exec, METH_O}, {"module_from_def_slot", module_from_def_slot, METH_O}, + {"module_from_def_slot_parrot", module_from_def_slot_parrot, METH_O}, {"pymodule_get_token", pymodule_get_token, METH_O}, {"pymodule_get_def", pymodule_get_def, METH_O}, {"pymodule_get_state_size", pymodule_get_state_size, METH_O}, diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 5a0b16ba57242d..b72700770281fb 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -410,35 +410,78 @@ module_from_def_and_spec( goto error; } + bool seen_m_name_slot = false; + bool seen_m_doc_slot = false; + bool seen_m_size_slot = false; + bool seen_m_methods_slot = false; + bool seen_m_traverse_slot = false; + bool seen_m_clear_slot = false; + bool seen_m_free_slot = false; for (cur_slot = def_like->m_slots; cur_slot && cur_slot->slot; cur_slot++) { - // Macro to copy a non-NULL, non-repeatable slot that's unusable with - // PyModuleDef. The destination must be initially NULL. -#define COPY_COMMON_SLOT(SLOT, TYPE, DEST) \ + + // Macro to copy a non-NULL, non-repeatable slot. +#define COPY_NONNULL_SLOT(SLOTNAME, TYPE, DEST) \ do { \ if (!(TYPE)(cur_slot->value)) { \ PyErr_Format( \ PyExc_SystemError, \ - "module %s: " #SLOT " must not be NULL", \ - name); \ + "module %s: %s must not be NULL", \ + name, SLOTNAME); \ goto error; \ } \ - if (original_def) { \ + DEST = (TYPE)(cur_slot->value); \ + } while (0); \ + ///////////////////////////////////////////////////////////////// + + // Macro to copy a non-NULL, non-repeatable slot to def_like. +#define COPY_DEF_SLOT(SLOTNAME, TYPE, MEMBER) \ + do { \ + if (seen_ ## MEMBER ## _slot) { \ PyErr_Format( \ PyExc_SystemError, \ - "module %s: " #SLOT " used with PyModuleDef", \ - name); \ + "module %s has more than one %s slot", \ + name, SLOTNAME); \ goto error; \ } \ + seen_ ## MEMBER ## _slot = true; \ + if (original_def) { \ + TYPE orig_value = (TYPE)original_def->MEMBER; \ + TYPE new_value = (TYPE)cur_slot->value; \ + if (orig_value != new_value) { \ + PyErr_Format( \ + PyExc_SystemError, \ + "module %s: %s conflicts with " \ + "PyModuleDef." #MEMBER, \ + name, SLOTNAME); \ + goto error; \ + } \ + } \ + COPY_NONNULL_SLOT(SLOTNAME, TYPE, (def_like->MEMBER)) \ + } while (0); \ + ///////////////////////////////////////////////////////////////// + + // Macro to copy a non-NULL, non-repeatable slot without a + // corresponding PyModuleDef member. + // DEST must be initially NULL (so we don't need a seen_* flag). +#define COPY_NONDEF_SLOT(SLOTNAME, TYPE, DEST) \ + do { \ if (DEST) { \ PyErr_Format( \ PyExc_SystemError, \ - "module %s has more than one " #SLOT " slot", \ - name); \ + "module %s has more than one %s slot", \ + name, SLOTNAME); \ goto error; \ } \ - DEST = (TYPE)(cur_slot->value); \ + COPY_NONNULL_SLOT(SLOTNAME, TYPE, DEST) \ } while (0); \ ///////////////////////////////////////////////////////////////// + + // Define the whole common case +#define DEF_SLOT_CASE(SLOT, TYPE, MEMBER) \ + case SLOT: \ + COPY_DEF_SLOT(#SLOT, TYPE, MEMBER); \ + break; \ + ///////////////////////////////////////////////////////////////// switch (cur_slot->slot) { case Py_mod_create: if (create) { @@ -453,14 +496,15 @@ module_from_def_and_spec( case Py_mod_exec: has_execution_slots = 1; if (!original_def) { - COPY_COMMON_SLOT(Py_mod_exec, _Py_modexecfunc, m_exec); + COPY_NONDEF_SLOT("Py_mod_exec", _Py_modexecfunc, m_exec); } break; case Py_mod_multiple_interpreters: if (has_multiple_interpreters_slot) { PyErr_Format( PyExc_SystemError, - "module %s has more than one 'multiple interpreters' slots", + "module %s has more than one 'multiple interpreters' " + "slots", name); goto error; } @@ -483,34 +527,23 @@ module_from_def_and_spec( goto error; } break; - case Py_mod_name: - COPY_COMMON_SLOT(Py_mod_name, char*, def_like->m_name); - break; - case Py_mod_doc: - COPY_COMMON_SLOT(Py_mod_doc, char*, def_like->m_doc); - break; - case Py_mod_state_size: - COPY_COMMON_SLOT(Py_mod_state_size, Py_ssize_t, - def_like->m_size); - break; - case Py_mod_methods: - COPY_COMMON_SLOT(Py_mod_methods, PyMethodDef*, - def_like->m_methods); - break; - case Py_mod_state_traverse: - COPY_COMMON_SLOT(Py_mod_state_traverse, traverseproc, - def_like->m_traverse); - break; - case Py_mod_state_clear: - COPY_COMMON_SLOT(Py_mod_state_clear, inquiry, - def_like->m_clear); - break; - case Py_mod_state_free: - COPY_COMMON_SLOT(Py_mod_state_free, freefunc, - def_like->m_free); - break; + DEF_SLOT_CASE(Py_mod_name, char*, m_name) + DEF_SLOT_CASE(Py_mod_doc, char*, m_doc) + DEF_SLOT_CASE(Py_mod_state_size, Py_ssize_t, m_size) + DEF_SLOT_CASE(Py_mod_methods, PyMethodDef*, m_methods) + DEF_SLOT_CASE(Py_mod_state_traverse, traverseproc, m_traverse) + DEF_SLOT_CASE(Py_mod_state_clear, inquiry, m_clear) + DEF_SLOT_CASE(Py_mod_state_free, freefunc, m_free) case Py_mod_token: - COPY_COMMON_SLOT(Py_mod_token, void*, token); + if (original_def && original_def != cur_slot->value) { + PyErr_Format( + PyExc_SystemError, + "module %s: arbitrary Py_mod_token not " + "allowed with PyModuleDef", + name); + goto error; + } + COPY_NONDEF_SLOT("Py_mod_token", void*, token); break; default: assert(cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT); @@ -520,7 +553,10 @@ module_from_def_and_spec( name, cur_slot->slot); goto error; } -#undef COPY_COMMON_SLOT +#undef DEF_SLOT_CASE +#undef COPY_DEF_SLOT +#undef COPY_NONDEF_SLOT +#undef COPY_NONNULL_SLOT } #ifdef Py_GIL_DISABLED @@ -590,7 +626,7 @@ module_from_def_and_spec( mod->md_state = NULL; module_copy_members_from_deflike(mod, def_like); if (original_def) { - assert (!token); + assert (!token || token == original_def); mod->md_token = original_def; mod->md_token_is_def = 1; } From aa6ed802f20c1ddadf45942d350422d3d4e0bbea Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 9 Feb 2026 14:41:05 +0300 Subject: [PATCH 038/498] gh-119740: Remove obsoleted removal announce for trunc delegation (GH-144622) This was done in GH-119743 (3.14). --- Doc/deprecations/pending-removal-in-future.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/deprecations/pending-removal-in-future.rst b/Doc/deprecations/pending-removal-in-future.rst index a54f98d6866e9f..e8306b8efee1c8 100644 --- a/Doc/deprecations/pending-removal-in-future.rst +++ b/Doc/deprecations/pending-removal-in-future.rst @@ -35,7 +35,6 @@ although there is currently no date scheduled for their removal. * Support for ``__complex__()`` method returning a strict subclass of :class:`complex`: these methods will be required to return an instance of :class:`complex`. - * Delegation of ``int()`` to ``__trunc__()`` method. * Passing a complex number as the *real* or *imag* argument in the :func:`complex` constructor is now deprecated; it should only be passed as a single positional argument. From d99f3fc474f34db4176ac67611efec18bde66c7e Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:24:15 -0700 Subject: [PATCH 039/498] gh-140715: Add `%F` format code support to `strptime()` (GH-140647) Also: add tests for the `%T` format code Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/datetime.rst | 6 +++--- Lib/_strptime.py | 1 + Lib/test/datetimetester.py | 14 ++++++++++++++ Lib/test/test_strptime.py | 14 ++++++++++++++ Lib/test/test_time.py | 4 ++-- .../2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst | 1 + 6 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 3ab3450032abe4..7c172471b195d6 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2540,7 +2540,7 @@ requires, and these work on all supported platforms. | ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | | | | space-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%F`` | Equivalent to ``%Y-%m-%d``, | 2025-10-11, | \(0) | +| ``%F`` | Equivalent to ``%Y-%m-%d``, | 2025-10-11, | | | | the ISO 8601 format. | 1001-12-30 | | +-----------+--------------------------------+------------------------+-------+ | ``%g`` | Last 2 digits of ISO 8601 year | 00, 01, ..., 99 | \(0) | @@ -2673,10 +2673,10 @@ differences between platforms in handling of unsupported format specifiers. ``%G``, ``%u`` and ``%V`` were added. .. versionadded:: 3.12 - ``%:z`` was added for :meth:`~.datetime.strftime` + ``%:z`` was added for :meth:`~.datetime.strftime`. .. versionadded:: 3.15 - ``%:z`` was added for :meth:`~.datetime.strptime` + ``%:z`` and ``%F`` were added for :meth:`~.datetime.strptime`. Technical Detail ^^^^^^^^^^^^^^^^ diff --git a/Lib/_strptime.py b/Lib/_strptime.py index d011ddf8b181c3..8b62ea734b7d11 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -418,6 +418,7 @@ def __init__(self, locale_time=None): mapping['W'] = mapping['U'].replace('U', 'W') base.__init__(mapping) + base.__setitem__('F', self.pattern('%Y-%m-%d')) base.__setitem__('T', self.pattern('%H:%M:%S')) base.__setitem__('R', self.pattern('%H:%M')) base.__setitem__('r', self.pattern(self.locale_time.LC_time_ampm)) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 8d39299b3ff442..3784909ee77839 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2193,6 +2193,13 @@ def test_fromisocalendar_type_errors(self): with self.assertRaises(TypeError): self.theclass.fromisocalendar(*isocal) + def test_strptime_F_format(self): + test_date = "2025-10-26" + self.assertEqual( + self.theclass.strptime(test_date, "%F"), + self.theclass.strptime(test_date, "%Y-%m-%d") + ) + ############################################################################# # datetime tests @@ -3780,6 +3787,13 @@ def test_repr_subclass(self): td = SubclassDatetime(2010, 10, 2, second=3) self.assertEqual(repr(td), "SubclassDatetime(2010, 10, 2, 0, 0, 3)") + def test_strptime_T_format(self): + test_time = "15:00:00" + self.assertEqual( + self.theclass.strptime(test_time, "%T"), + self.theclass.strptime(test_time, "%H:%M:%S") + ) + class TestSubclassDateTime(TestDateTime): theclass = SubclassDatetime diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 40e114aada67eb..0784ea6a4cf5d4 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -649,6 +649,20 @@ def test_mar1_comes_after_feb29_even_when_omitting_the_year(self): time.strptime("Feb 29", "%b %d"), time.strptime("Mar 1", "%b %d")) + def test_strptime_F_format(self): + test_date = "2025-10-26" + self.assertEqual( + time.strptime(test_date, "%F"), + time.strptime(test_date, "%Y-%m-%d") + ) + + def test_strptime_T_format(self): + test_time = "15:00:00" + self.assertEqual( + time.strptime(test_time, "%T"), + time.strptime(test_time, "%H:%M:%S") + ) + class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index c360f4a64c266b..da0cf494bfa8ad 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -358,8 +358,8 @@ def test_strptime(self): # Should be able to go round-trip from strftime to strptime without # raising an exception. tt = time.gmtime(self.t) - for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', - 'j', 'm', 'M', 'p', 'S', + for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'F', 'H', 'I', + 'j', 'm', 'M', 'p', 'S', 'T', 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): format = '%' + directive if directive == 'd': diff --git a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst new file mode 100644 index 00000000000000..c2bb69b894c1dd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst @@ -0,0 +1 @@ +Add ``'%F'`` support to :meth:`~datetime.datetime.strptime`. From dd30f16ac0834aef9b3992e614ea3237c37ea71e Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Mon, 9 Feb 2026 18:50:35 +0530 Subject: [PATCH 040/498] gh-141563: make `PyDateTime_IMPORT` thread-safe (#144210) --- Include/datetime.h | 19 +++++++++++++++++-- ...-02-02-17-07-34.gh-issue-141563.GheXjr.rst | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst diff --git a/Include/datetime.h b/Include/datetime.h index ed36e6e48c87d2..ed7e55009d2208 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -196,8 +196,23 @@ typedef struct { /* Define global variable for the C API and a macro for setting it. */ static PyDateTime_CAPI *PyDateTimeAPI = NULL; -#define PyDateTime_IMPORT \ - PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) +static inline PyDateTime_CAPI * +_PyDateTime_IMPORT(void) { + PyDateTime_CAPI *val = _Py_atomic_load_ptr(&PyDateTimeAPI); + if (val == NULL) { + PyDateTime_CAPI *capi = (PyDateTime_CAPI *)PyCapsule_Import( + PyDateTime_CAPSULE_NAME, 0); + if (capi != NULL) { + /* if the compare exchange fails then in that case + another thread would have initialized it */ + _Py_atomic_compare_exchange_ptr(&PyDateTimeAPI, &val, (void *)capi); + return capi; + } + } + return val; +} + +#define PyDateTime_IMPORT _PyDateTime_IMPORT() /* Macro for access to the UTC singleton */ #define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst new file mode 100644 index 00000000000000..4059525f090c50 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst @@ -0,0 +1 @@ +Fix thread safety of :c:macro:`! PyDateTime_IMPORT`. From 988286e51001aa1960c9893b3c11edde5e6cb895 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Mon, 9 Feb 2026 21:23:02 +0800 Subject: [PATCH 041/498] gh-144623: Fix missing output uops in optimizer debug output (GH-144617) --- Python/optimizer_analysis.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 381b2500158ef0..7bd6970e5fd2dc 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -83,7 +83,7 @@ dump_abstract_stack(_Py_UOpsAbstractFrame *frame, JitOptRef *stack_pointer) static void dump_uop(JitOptContext *ctx, const char *label, int index, - const _PyUOpInstruction *instr, JitOptRef *stack_pointer) + const _PyUOpInstruction *instr, JitOptRef *stack_pointer) { if (get_lltrace() >= 3) { printf("%4d %s: ", index, label); @@ -95,11 +95,24 @@ dump_uop(JitOptContext *ctx, const char *label, int index, } } +static void +dump_uops(JitOptContext *ctx, const char *label, + _PyUOpInstruction *start, JitOptRef *stack_pointer) +{ + int current_len = uop_buffer_length(&ctx->out_buffer); + int added_count = (int)(ctx->out_buffer.next - start); + for (int j = 0; j < added_count; j++) { + dump_uop(ctx, label, current_len - added_count + j, &start[j], stack_pointer); + } +} + #define DUMP_UOP dump_uop +#define DUMP_UOPS dump_uops #else #define DPRINTF(level, ...) #define DUMP_UOP(ctx, label, index, instr, stack_pointer) + #define DUMP_UOPS(ctx, label, start, stack_pointer) #endif static int @@ -508,7 +521,7 @@ optimize_uops( *(ctx->out_buffer.next++) = *this_instr; } assert(ctx->frame != NULL); - DUMP_UOP(ctx, "out", uop_buffer_length(&ctx->out_buffer) - 1, out_ptr, stack_pointer); + DUMP_UOPS(ctx, "out", out_ptr, stack_pointer); if (!CURRENT_FRAME_IS_INIT_SHIM() && !ctx->done) { DPRINTF(3, " stack_level %d\n", STACK_LEVEL()); ctx->frame->stack_pointer = stack_pointer; From a91b5c3fb5aeaeda6a8e016378beb0e4a8b329e6 Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> Date: Mon, 9 Feb 2026 19:42:25 +0530 Subject: [PATCH 042/498] gh-143543: Fix re-entrant use-after-free in itertools.groupby (GH-143738) Co-authored-by: Sergey B Kirpichev Co-authored-by: Petr Viktorin --- Lib/test/test_itertools.py | 21 +++++++++++++++++++ ...-01-13-10-38-43.gh-issue-143543.DeQRCO.rst | 2 ++ Modules/itertoolsmodule.c | 14 +++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 61bea9dba07fec..dc64288085fa74 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -733,6 +733,27 @@ def keyfunc(obj): keyfunc.skip = 1 self.assertRaises(ExpectedError, gulp, [None, None], keyfunc) + def test_groupby_reentrant_eq_does_not_crash(self): + # regression test for gh-143543 + class Key: + def __init__(self, do_advance): + self.do_advance = do_advance + + def __eq__(self, other): + if self.do_advance: + self.do_advance = False + next(g) + return NotImplemented + return False + + def keys(): + yield Key(True) + yield Key(False) + + g = itertools.groupby([None, None], keys().send) + next(g) + next(g) # must pass with address sanitizer + def test_filter(self): self.assertEqual(list(filter(isEven, range(6))), [0,2,4]) self.assertEqual(list(filter(None, [0,1,0,2,0])), [1,2]) diff --git a/Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst b/Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst new file mode 100644 index 00000000000000..14622a395ec22e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst @@ -0,0 +1,2 @@ +Fix a crash in itertools.groupby that could occur when a user-defined +:meth:`~object.__eq__` method re-enters the iterator during key comparison. diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 7e73f76bc20b58..ff0e2fd2b3569d 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -544,9 +544,19 @@ groupby_next(PyObject *op) else if (gbo->tgtkey == NULL) break; else { - int rcmp; + /* A user-defined __eq__ can re-enter groupby and advance the iterator, + mutating gbo->tgtkey / gbo->currkey while we are comparing them. + Take local snapshots and hold strong references so INCREF/DECREF + apply to the same objects even under re-entrancy. */ + PyObject *tgtkey = gbo->tgtkey; + PyObject *currkey = gbo->currkey; + + Py_INCREF(tgtkey); + Py_INCREF(currkey); + int rcmp = PyObject_RichCompareBool(tgtkey, currkey, Py_EQ); + Py_DECREF(tgtkey); + Py_DECREF(currkey); - rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); if (rcmp == -1) return NULL; else if (rcmp == 0) From ff531f9005d508cbac31ffdd696ef45bc4944d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Mon, 9 Feb 2026 15:13:47 +0100 Subject: [PATCH 043/498] gh-132604: Deprecate inherited runtime checkability of protocols (GH-143806) Co-authored-by: Jelle Zijlstra --- Doc/library/typing.rst | 23 ++++++ Lib/test/test_typing.py | 70 ++++++++++++++++++- Lib/typing.py | 31 ++++++++ ...-01-13-15-56-03.gh-issue-132604.lvjNTr.rst | 4 ++ 4 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index eaa0ba54af18e7..7b62b9208412e9 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2527,6 +2527,12 @@ types. .. versionadded:: 3.8 + .. deprecated-removed:: 3.15 3.20 + It is deprecated to call :func:`isinstance` and :func:`issubclass` checks on + protocol classes that were not explicitly decorated with :func:`!runtime_checkable` + but that inherit from a runtime-checkable protocol class. This will throw + a :exc:`TypeError` in Python 3.20. + .. decorator:: runtime_checkable Mark a protocol class as a runtime protocol. @@ -2548,6 +2554,18 @@ types. import threading assert isinstance(threading.Thread(name='Bob'), Named) + Runtime checkability of protocols is not inherited. A subclass of a runtime-checkable protocol + is only runtime-checkable if it is explicitly marked as such, regardless of class hierarchy:: + + @runtime_checkable + class Iterable(Protocol): + def __iter__(self): ... + + # Without @runtime_checkable, Reversible would no longer be runtime-checkable. + @runtime_checkable + class Reversible(Iterable, Protocol): + def __reversed__(self): ... + This decorator raises :exc:`TypeError` when applied to a non-protocol class. .. note:: @@ -2588,6 +2606,11 @@ types. protocol. See :ref:`What's new in Python 3.12 ` for more details. + .. deprecated-removed:: 3.15 3.20 + It is deprecated to call :func:`isinstance` and :func:`issubclass` checks on + protocol classes that were not explicitly decorated with :func:`!runtime_checkable` + but that inherit from a runtime-checkable protocol class. This will throw + a :exc:`TypeError` in Python 3.20. .. class:: TypedDict(dict) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index e896df518447c5..72ae7776ab9062 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -51,7 +51,7 @@ from test.support import ( captured_stderr, cpython_only, requires_docstrings, import_helper, run_code, - EqualToForwardRef, + subTests, EqualToForwardRef, ) from test.typinganndata import ( ann_module695, mod_generics_cache, _typed_dict_helper, @@ -3885,8 +3885,8 @@ def meth(self): pass self.assertIsNot(get_protocol_members(PR), P.__protocol_attrs__) acceptable_extra_attrs = { - '_is_protocol', '_is_runtime_protocol', '__parameters__', - '__init__', '__annotations__', '__subclasshook__', '__annotate__', + '_is_protocol', '_is_runtime_protocol', '__typing_is_deprecated_inherited_runtime_protocol__', + '__parameters__', '__init__', '__annotations__', '__subclasshook__', '__annotate__', '__annotations_cache__', '__annotate_func__', } self.assertLessEqual(vars(NonP).keys(), vars(C).keys() | acceptable_extra_attrs) @@ -4458,6 +4458,70 @@ class P(Protocol): with self.assertRaisesRegex(TypeError, "@runtime_checkable"): isinstance(1, P) + @subTests(['check_obj', 'check_func'], ([42, isinstance], [frozenset, issubclass])) + def test_inherited_runtime_protocol_deprecated(self, check_obj, check_func): + """See GH-132604.""" + + class BareProto(Protocol): + """I am not runtime-checkable.""" + + @runtime_checkable + class RCProto1(Protocol): + """I am runtime-checkable.""" + + class InheritedRCProto1(RCProto1, Protocol): + """I am accidentally runtime-checkable (by inheritance).""" + + @runtime_checkable + class RCProto2(InheritedRCProto1, Protocol): + """Explicit RC -> inherited RC -> explicit RC.""" + def spam(self): ... + + @runtime_checkable + class RCProto3(BareProto, Protocol): + """Not RC -> explicit RC.""" + + class InheritedRCProto2(RCProto3, Protocol): + """Not RC -> explicit RC -> inherited RC.""" + def eggs(self): ... + + class InheritedRCProto3(RCProto2, Protocol): + """Explicit RC -> inherited RC -> explicit RC -> inherited RC.""" + + class Concrete1(BareProto): + pass + + class Concrete2(InheritedRCProto2): + pass + + class Concrete3(InheritedRCProto3): + pass + + depr_message_re = ( + r" isn't explicitly decorated " + r"with @runtime_checkable but it is used in issubclass\(\) or " + r"isinstance\(\). Instance and class checks can only be used with " + r"@runtime_checkable protocols. This will raise a TypeError in Python 3.20." + ) + + for inherited_runtime_proto in InheritedRCProto1, InheritedRCProto2, InheritedRCProto3: + with self.assertWarnsRegex(DeprecationWarning, depr_message_re): + check_func(check_obj, inherited_runtime_proto) + + # Don't warn for explicitly checkable protocols and concrete implementations. + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + + for checkable in RCProto1, RCProto2, RCProto3, Concrete1, Concrete2, Concrete3: + check_func(check_obj, checkable) + + # Don't warn for uncheckable protocols. + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + + with self.assertRaises(TypeError): # Self-test. Protocol below can't be runtime-checkable. + check_func(check_obj, BareProto) + def test_super_call_init(self): class P(Protocol): x: int diff --git a/Lib/typing.py b/Lib/typing.py index 1a2ef8c086f772..71a08a5f1df811 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1826,6 +1826,7 @@ class _TypingEllipsis: _TYPING_INTERNALS = frozenset({ '__parameters__', '__orig_bases__', '__orig_class__', '_is_protocol', '_is_runtime_protocol', '__protocol_attrs__', + '__typing_is_deprecated_inherited_runtime_protocol__', '__non_callable_proto_members__', '__type_params__', }) @@ -2015,6 +2016,16 @@ def __subclasscheck__(cls, other): "Instance and class checks can only be used with " "@runtime_checkable protocols" ) + if getattr(cls, '__typing_is_deprecated_inherited_runtime_protocol__', False): + # See GH-132604. + import warnings + depr_message = ( + f"{cls!r} isn't explicitly decorated with @runtime_checkable but " + "it is used in issubclass() or isinstance(). Instance and class " + "checks can only be used with @runtime_checkable protocols. " + "This will raise a TypeError in Python 3.20." + ) + warnings.warn(depr_message, category=DeprecationWarning, stacklevel=2) if ( # this attribute is set by @runtime_checkable: cls.__non_callable_proto_members__ @@ -2044,6 +2055,18 @@ def __instancecheck__(cls, instance): raise TypeError("Instance and class checks can only be used with" " @runtime_checkable protocols") + if getattr(cls, '__typing_is_deprecated_inherited_runtime_protocol__', False): + # See GH-132604. + import warnings + + depr_message = ( + f"{cls!r} isn't explicitly decorated with @runtime_checkable but " + "it is used in issubclass() or isinstance(). Instance and class " + "checks can only be used with @runtime_checkable protocols. " + "This will raise a TypeError in Python 3.20." + ) + warnings.warn(depr_message, category=DeprecationWarning, stacklevel=2) + if _abc_instancecheck(cls, instance): return True @@ -2136,6 +2159,11 @@ def __init_subclass__(cls, *args, **kwargs): if not cls.__dict__.get('_is_protocol', False): cls._is_protocol = any(b is Protocol for b in cls.__bases__) + # Mark inherited runtime checkability (deprecated). See GH-132604. + if cls._is_protocol and getattr(cls, '_is_runtime_protocol', False): + # This flag is set to False by @runtime_checkable. + cls.__typing_is_deprecated_inherited_runtime_protocol__ = True + # Set (or override) the protocol subclass hook. if '__subclasshook__' not in cls.__dict__: cls.__subclasshook__ = _proto_hook @@ -2282,6 +2310,9 @@ def close(self): ... raise TypeError('@runtime_checkable can be only applied to protocol classes,' ' got %r' % cls) cls._is_runtime_protocol = True + # See GH-132604. + if hasattr(cls, '__typing_is_deprecated_inherited_runtime_protocol__'): + cls.__typing_is_deprecated_inherited_runtime_protocol__ = False # PEP 544 prohibits using issubclass() # with protocols that have non-method members. # See gh-113320 for why we compute this attribute here, diff --git a/Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst b/Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst new file mode 100644 index 00000000000000..92c4dbb536cdf6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst @@ -0,0 +1,4 @@ +Previously, :class:`~typing.Protocol` classes that were not decorated with :deco:`~typing.runtime_checkable`, +but that inherited from another ``Protocol`` class that did have this decorator, could be used in :func:`isinstance` +and :func:`issubclass` checks. This behavior is now deprecated and such checks will throw a :exc:`TypeError` +in Python 3.20. Patch by Bartosz Sławecki. From dd2da42ea479c32a4260463b47e1b58877d07bdc Mon Sep 17 00:00:00 2001 From: alexey semenyuk Date: Mon, 9 Feb 2026 19:40:17 +0500 Subject: [PATCH 044/498] gh-134179: Use sys._clear_internal_caches() at test_cmd_line (#134180) Use sys._clear_internal_caches() instead of deprecated sys._clear_type_cache() at test_cmd_line. --- Lib/test/test_cmd_line.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 3ed7a360d64e3c..55e5f06c8071ea 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -9,7 +9,6 @@ import tempfile import textwrap import unittest -import warnings from test import support from test.support import os_helper from test.support import force_not_colorized @@ -943,21 +942,15 @@ def test_python_asyncio_debug(self): @unittest.skipUnless(sysconfig.get_config_var('Py_TRACE_REFS'), "Requires --with-trace-refs build option") def test_python_dump_refs(self): - code = 'import sys; sys._clear_type_cache()' - # TODO: Remove warnings context manager once sys._clear_type_cache is removed - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - rc, out, err = assert_python_ok('-c', code, PYTHONDUMPREFS='1') + code = 'import sys; sys._clear_internal_caches()' + rc, out, err = assert_python_ok('-c', code, PYTHONDUMPREFS='1') self.assertEqual(rc, 0) @unittest.skipUnless(sysconfig.get_config_var('Py_TRACE_REFS'), "Requires --with-trace-refs build option") def test_python_dump_refs_file(self): with tempfile.NamedTemporaryFile() as dump_file: - code = 'import sys; sys._clear_type_cache()' - # TODO: Remove warnings context manager once sys._clear_type_cache is removed - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - rc, out, err = assert_python_ok('-c', code, PYTHONDUMPREFSFILE=dump_file.name) + code = 'import sys; sys._clear_internal_caches()' + rc, out, err = assert_python_ok('-c', code, PYTHONDUMPREFSFILE=dump_file.name) self.assertEqual(rc, 0) with open(dump_file.name, 'r') as file: contents = file.read() From fd6b639a49dd1143c6fd8729fc49f17b3114a965 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 9 Feb 2026 10:57:03 -0500 Subject: [PATCH 045/498] gh-144601: Avoid sharing exception objects raised in a `PyInit` function across multiple interpreters (GH-144602) --- Lib/test/test_import/__init__.py | 27 +++++++++++++++++++ ...-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst | 2 ++ Modules/_testsinglephase.c | 8 ++++++ Python/import.c | 17 +++++++++++- 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 59c6dc4587c93d..f66e2987d34850 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -45,6 +45,7 @@ Py_GIL_DISABLED, no_rerun, force_not_colorized_test_class, + catch_unraisable_exception ) from test.support.import_helper import ( forget, make_legacy_pyc, unlink, unload, ready_to_import, @@ -2517,6 +2518,32 @@ def test_disallowed_reimport(self): excsnap = _interpreters.run_string(interpid, script) self.assertIsNot(excsnap, None) + @requires_subinterpreters + def test_pyinit_function_raises_exception(self): + # gh-144601: PyInit functions that raised exceptions would cause a + # crash when imported from a subinterpreter. + import _testsinglephase + filename = _testsinglephase.__file__ + script = f"""if True: + from test.test_import import import_extension_from_file + + import_extension_from_file('_testsinglephase_raise_exception', {filename!r})""" + + interp = _interpreters.create() + try: + with catch_unraisable_exception() as cm: + exception = _interpreters.run_string(interp, script) + unraisable = cm.unraisable + finally: + _interpreters.destroy(interp) + + self.assertIsNotNone(exception) + self.assertIsNotNone(exception.type.__name__, "ImportError") + self.assertIsNotNone(exception.msg, "failed to import from subinterpreter due to exception") + self.assertIsNotNone(unraisable) + self.assertIs(unraisable.exc_type, RuntimeError) + self.assertEqual(str(unraisable.exc_value), "evil") + class TestSinglePhaseSnapshot(ModuleSnapshot): """A representation of a single-phase init module for testing. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst new file mode 100644 index 00000000000000..1c7772e2f3ca26 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst @@ -0,0 +1,2 @@ +Fix crash when importing a module whose ``PyInit`` function raises an +exception from a subinterpreter. diff --git a/Modules/_testsinglephase.c b/Modules/_testsinglephase.c index ee38d61b43a82a..7ea77c6312c59e 100644 --- a/Modules/_testsinglephase.c +++ b/Modules/_testsinglephase.c @@ -801,3 +801,11 @@ PyInit__testsinglephase_circular(void) } return Py_NewRef(static_module_circular); } + + +PyMODINIT_FUNC +PyInit__testsinglephase_raise_exception(void) +{ + PyErr_SetString(PyExc_RuntimeError, "evil"); + return NULL; +} diff --git a/Python/import.c b/Python/import.c index 466c5868ab7ee8..e7f803d84f1367 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2176,13 +2176,29 @@ import_run_extension(PyThreadState *tstate, PyModInitFunction p0, } main_finally: + if (rc < 0) { + _Py_ext_module_loader_result_apply_error(&res, name_buf); + } + /* Switch back to the subinterpreter. */ if (switched) { + // gh-144601: The exception object can't be transferred across + // interpreters. Instead, we print out an unraisable exception, and + // then raise a different exception for the calling interpreter. + if (rc < 0) { + assert(PyErr_Occurred()); + PyErr_FormatUnraisable("Exception while importing from subinterpreter"); + } assert(main_tstate != tstate); switch_back_from_main_interpreter(tstate, main_tstate, mod); /* Any module we got from the init function will have to be * reloaded in the subinterpreter. */ mod = NULL; + if (rc < 0) { + PyErr_SetString(PyExc_ImportError, + "failed to import from subinterpreter due to exception"); + goto error; + } } /*****************************************************************/ @@ -2191,7 +2207,6 @@ import_run_extension(PyThreadState *tstate, PyModInitFunction p0, /* Finally we handle the error return from _PyImport_RunModInitFunc(). */ if (rc < 0) { - _Py_ext_module_loader_result_apply_error(&res, name_buf); goto error; } From 245ba3d6cbef9fa0c0d55ab5e53f21a918e7b898 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 9 Feb 2026 17:17:00 +0100 Subject: [PATCH 046/498] gh-144490: Fix test_cppext on Windows (#144628) Don't include pycore_backoff.h and pycore_cell.h on Windows, since they emit C++ compiler warnings. --- Lib/test/test_cppext/extension.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index 038f67bbbe3f74..a8cd70aacbc805 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -16,10 +16,9 @@ // gh-135906: Check for compiler warnings in the internal C API # include "internal/pycore_frame.h" // mimalloc emits many compiler warnings when Python is built in debug - // mode (when MI_DEBUG is not zero) - // mimalloc emits compiler warnings when Python is built on Windows - // in free-threaded mode. -# if !defined(Py_DEBUG) && !(defined(MS_WINDOWS) && defined(Py_GIL_DISABLED)) + // mode (when MI_DEBUG is not zero). + // mimalloc emits compiler warnings when Python is built on Windows. +# if !defined(Py_DEBUG) && !defined(MS_WINDOWS) # include "internal/pycore_backoff.h" # include "internal/pycore_cell.h" # endif From fd190d1fa1a34bb8d533d05263ea744a051b7529 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:30:19 +0000 Subject: [PATCH 047/498] gh-144492: Fix `process_changed_files` outputs for `reusable-{macos, wasi}.yml` (#144518) Fix `process_changed_files` double-processing reusable-{macos, wasi] ending up with incorrect outputs --- Tools/build/compute-changes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tools/build/compute-changes.py b/Tools/build/compute-changes.py index 08aba5ef5423fe..00fd0edd8537bf 100644 --- a/Tools/build/compute-changes.py +++ b/Tools/build/compute-changes.py @@ -232,9 +232,12 @@ def process_changed_files(changed_files: Set[Path]) -> Outputs: if file.name == "reusable-windows-msi.yml": run_windows_msi = True if file.name == "reusable-macos.yml": + run_tests = True platforms_changed.add("macos") if file.name == "reusable-wasi.yml": + run_tests = True platforms_changed.add("wasi") + continue if not doc_file and file not in RUN_TESTS_IGNORE: run_tests = True From 30cfe6ee23a8974625c9860bc401f60ed75b2dea Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 9 Feb 2026 14:52:45 -0800 Subject: [PATCH 048/498] GH-144552: Clean up `tail-call.yml ` CI (#144553) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/workflows/tail-call.yml | 157 +++++++++++++++----------------- 1 file changed, 72 insertions(+), 85 deletions(-) diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml index a47e532d396bc0..1ab225656d694d 100644 --- a/.github/workflows/tail-call.yml +++ b/.github/workflows/tail-call.yml @@ -1,19 +1,14 @@ name: Tail calling interpreter on: pull_request: - paths: + paths: &paths - '.github/workflows/tail-call.yml' - 'Python/bytecodes.c' - 'Python/ceval.c' - 'Python/ceval_macros.h' - 'Python/generated_cases.c.h' push: - paths: - - '.github/workflows/tail-call.yml' - - 'Python/bytecodes.c' - - 'Python/ceval.c' - - 'Python/ceval_macros.h' - - 'Python/generated_cases.c.h' + paths: *paths workflow_dispatch: permissions: @@ -25,56 +20,27 @@ concurrency: env: FORCE_COLOR: 1 + LLVM_VERSION: 21 jobs: - tail-call: + windows: name: ${{ matrix.target }} runs-on: ${{ matrix.runner }} - timeout-minutes: 90 + timeout-minutes: 60 strategy: fail-fast: false matrix: - target: -# Un-comment as we add support for more platforms for tail-calling interpreters. -# - i686-pc-windows-msvc/msvc - - x86_64-pc-windows-msvc/msvc - - free-threading-msvc -# - aarch64-pc-windows-msvc/msvc - - x86_64-apple-darwin/clang - - aarch64-apple-darwin/clang - - x86_64-unknown-linux-gnu/gcc - - aarch64-unknown-linux-gnu/gcc - - free-threading - llvm: - - 20 include: -# - target: i686-pc-windows-msvc/msvc -# architecture: Win32 -# runner: windows-2022 - target: x86_64-pc-windows-msvc/msvc architecture: x64 runner: windows-2025-vs2026 - - target: free-threading-msvc + build_flags: "" + run_tests: true + - target: x86_64-pc-windows-msvc/msvc-free-threading architecture: x64 runner: windows-2025-vs2026 -# - target: aarch64-pc-windows-msvc/msvc -# architecture: ARM64 -# runner: windows-2022 - - target: x86_64-apple-darwin/clang - architecture: x86_64 - runner: macos-15-intel - - target: aarch64-apple-darwin/clang - architecture: aarch64 - runner: macos-14 - - target: x86_64-unknown-linux-gnu/gcc - architecture: x86_64 - runner: ubuntu-24.04 - - target: aarch64-unknown-linux-gnu/gcc - architecture: aarch64 - runner: ubuntu-24.04-arm - - target: free-threading - architecture: x86_64 - runner: ubuntu-24.04 + build_flags: --disable-gil + run_tests: false steps: - uses: actions/checkout@v6 with: @@ -82,60 +48,81 @@ jobs: - uses: actions/setup-python@v6 with: python-version: '3.11' - - - name: Native Windows MSVC (release) - if: runner.os == 'Windows' && matrix.architecture != 'ARM64' && matrix.target != 'free-threading-msvc' + - name: Build shell: pwsh run: | $env:PlatformToolset = "v145" - ./PCbuild/build.bat --tail-call-interp -c Release -p ${{ matrix.architecture }} - ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - - # No tests: - - name: Native Windows MSVC with free-threading (release) - if: matrix.target == 'free-threading-msvc' - shell: pwsh - run: | - $env:PlatformToolset = "v145" - ./PCbuild/build.bat --tail-call-interp --disable-gil -c Release -p ${{ matrix.architecture }} - - # No tests (yet): - - name: Emulated Windows Clang (release) - if: runner.os == 'Windows' && matrix.architecture == 'ARM64' + ./PCbuild/build.bat --tail-call-interp ${{ matrix.build_flags }} -c Release -p ${{ matrix.architecture }} + - name: Test + if: matrix.run_tests shell: pwsh run: | - choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}.1.0 - $env:PlatformToolset = "clangcl" - $env:LLVMToolsVersion = "${{ matrix.llvm }}.1.0" - $env:LLVMInstallDir = "C:\Program Files\LLVM" - ./PCbuild/build.bat --tail-call-interp -p ${{ matrix.architecture }} + ./PCbuild/rt.bat -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - - name: Native macOS (release) - if: runner.os == 'macOS' + macos: + name: ${{ matrix.target }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-apple-darwin/clang + runner: macos-15-intel + - target: aarch64-apple-darwin/clang + runner: macos-14 + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 + with: + python-version: '3.11' + - name: Install dependencies run: | brew update - brew install llvm@${{ matrix.llvm }} + brew install llvm@${{ env.LLVM_VERSION }} + - name: Build + run: | export SDKROOT="$(xcrun --show-sdk-path)" - export PATH="/usr/local/opt/llvm@${{ matrix.llvm }}/bin:$PATH" - export PATH="/opt/homebrew/opt/llvm@${{ matrix.llvm }}/bin:$PATH" - CC=clang-20 ./configure --with-tail-call-interp + export PATH="/usr/local/opt/llvm@${{ env.LLVM_VERSION }}/bin:$PATH" + export PATH="/opt/homebrew/opt/llvm@${{ env.LLVM_VERSION }}/bin:$PATH" + CC=clang-${{ env.LLVM_VERSION }} ./configure --with-tail-call-interp make all --jobs 4 + - name: Test + run: | ./python.exe -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - - name: Native Linux (debug) - if: runner.os == 'Linux' && matrix.target != 'free-threading' + linux: + name: ${{ matrix.target }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu/gcc + runner: ubuntu-24.04 + configure_flags: --with-pydebug + - target: x86_64-unknown-linux-gnu/gcc-free-threading + runner: ubuntu-24.04 + configure_flags: --disable-gil + - target: aarch64-unknown-linux-gnu/gcc + runner: ubuntu-24.04-arm + configure_flags: --with-pydebug + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 + with: + python-version: '3.11' + - name: Build run: | - sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }} - export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH" - CC=clang-20 ./configure --with-tail-call-interp --with-pydebug + sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ env.LLVM_VERSION }} + export PATH="$(llvm-config-${{ env.LLVM_VERSION }} --bindir):$PATH" + CC=clang-${{ env.LLVM_VERSION }} ./configure --with-tail-call-interp ${{ matrix.configure_flags }} make all --jobs 4 - ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - - - name: Native Linux with free-threading (release) - if: matrix.target == 'free-threading' + - name: Test run: | - sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }} - export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH" - CC=clang-20 ./configure --with-tail-call-interp --disable-gil - make all --jobs 4 ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 From a9b6788ae6f045d83e899bd303c92704692c3dc3 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 10 Feb 2026 00:01:17 +0000 Subject: [PATCH 049/498] gh-144278: Enable overriding sys.implementation's name and cache_tag when building sysmodule.c (GH-144293) Changing the values requires forking and patching, which is intentional. Simply rebuilding from source does not change the implementation enough to justify changing these values - they would still be `cpython` and compatible with existing `.pyc` files. But people who maintain forks are better served by being able to easily override these values in a place that can be forward-ported reliably. --- Lib/compileall.py | 8 ++ Lib/ensurepip/__init__.py | 2 + Lib/py_compile.py | 4 +- Lib/test/support/import_helper.py | 22 +++- Lib/test/test_argparse.py | 4 +- Lib/test/test_capi/test_import.py | 5 +- Lib/test/test_cmd_line_script.py | 21 ++- Lib/test/test_compileall.py | 4 + Lib/test/test_ensurepip.py | 22 ++-- Lib/test/test_import/__init__.py | 28 ++-- .../test_importlib/source/test_file_loader.py | 19 ++- Lib/test/test_importlib/source/test_finder.py | 2 + Lib/test/test_importlib/test_abc.py | 12 +- Lib/test/test_importlib/test_api.py | 4 - Lib/test/test_importlib/test_pkg_import.py | 9 +- Lib/test/test_importlib/test_spec.py | 17 ++- Lib/test/test_importlib/test_util.py | 30 +++++ Lib/test/test_importlib/util.py | 3 + Lib/test/test_inspect/test_inspect.py | 3 +- .../test_multiprocessing_main_handling.py | 12 +- Lib/test/test_py_compile.py | 68 +++++++--- Lib/test/test_pydoc/test_pydoc.py | 6 +- Lib/test/test_reprlib.py | 7 +- Lib/test/test_runpy.py | 27 ++-- Lib/test/test_zipimport.py | 1 - Lib/zipfile/__init__.py | 122 ++++++------------ ...-01-27-23-39-26.gh-issue-144278.tejFwL.rst | 5 + Modules/_testlimitedcapi/import.c | 2 +- Python/sysmodule.c | 25 ++-- 29 files changed, 305 insertions(+), 189 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst diff --git a/Lib/compileall.py b/Lib/compileall.py index 9519a5ac16f024..c452aed135838f 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -165,6 +165,14 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, stripdir = os.fspath(stripdir) if stripdir is not None else None name = os.path.basename(fullname) + # Without a cache_tag, we can only create legacy .pyc files. None of our + # callers seem to expect this, so the best we can do is fail without raising + if not legacy and sys.implementation.cache_tag is None: + if not quiet: + print("No cache tag is available to generate .pyc path for", + repr(fullname)) + return False + dfile = None if ddir is not None: diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 9239e42b9ca8e1..6164ea62324cce 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -177,6 +177,8 @@ def _bootstrap(*, root=None, upgrade=False, user=False, args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] + if sys.implementation.cache_tag is None: + args += ["--no-compile"] return _run_pip([*args, "pip"], [os.fsdecode(tmp_wheel_path)]) diff --git a/Lib/py_compile.py b/Lib/py_compile.py index 43d8ec90ffb6b1..694ea9304da9f9 100644 --- a/Lib/py_compile.py +++ b/Lib/py_compile.py @@ -194,8 +194,10 @@ def main(): else: filenames = args.filenames for filename in filenames: + cfilename = (None if sys.implementation.cache_tag + else f"{filename.rpartition('.')[0]}.pyc") try: - compile(filename, doraise=True) + compile(filename, cfilename, doraise=True) except PyCompileError as error: if args.quiet: parser.exit(1) diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 4c7eac0b7eb674..093de6a82d8ca7 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -4,6 +4,7 @@ import importlib.machinery import importlib.util import os +import py_compile import shutil import sys import textwrap @@ -49,20 +50,31 @@ def forget(modname): # combinations of PEP 3147/488 and legacy pyc files. unlink(source + 'c') for opt in ('', 1, 2): - unlink(importlib.util.cache_from_source(source, optimization=opt)) + try: + unlink(importlib.util.cache_from_source(source, optimization=opt)) + except NotImplementedError: + pass -def make_legacy_pyc(source): +def make_legacy_pyc(source, allow_compile=False): """Move a PEP 3147/488 pyc file to its legacy pyc location. :param source: The file system path to the source file. The source file - does not need to exist, however the PEP 3147/488 pyc file must exist. + does not need to exist, however the PEP 3147/488 pyc file must exist or + allow_compile must be set. + :param allow_compile: If True, uses py_compile to create a .pyc if it does + not exist. This should be passed as True if cache_tag may be None. :return: The file system path to the legacy pyc file. """ - pyc_file = importlib.util.cache_from_source(source) assert source.endswith('.py') legacy_pyc = source + 'c' - shutil.move(pyc_file, legacy_pyc) + try: + pyc_file = importlib.util.cache_from_source(source) + shutil.move(pyc_file, legacy_pyc) + except (FileNotFoundError, NotImplementedError): + if not allow_compile: + raise + py_compile.compile(source, legacy_pyc, doraise=True) return legacy_pyc diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 77170244675474..78f02f70b9f0fc 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -7,7 +7,6 @@ import io import operator import os -import py_compile import shutil import stat import sys @@ -7162,9 +7161,8 @@ def make_script(self, dirname, basename, *, compiled=False): script_name = script_helper.make_script(dirname, basename, self.source) if not compiled: return script_name - py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) return pyc_file def make_zip_script(self, script_name, name_in_zip=None): diff --git a/Lib/test/test_capi/test_import.py b/Lib/test/test_capi/test_import.py index 57e0316fda8a52..ea845df75ef3a7 100644 --- a/Lib/test/test_capi/test_import.py +++ b/Lib/test/test_capi/test_import.py @@ -289,7 +289,10 @@ def check_executecode_pathnames(self, execute_code_func, object=False): self.check_executecodemodule(execute_code_func, NULL, pathname) # Test NULL pathname and non-NULL cpathname - pyc_filename = importlib.util.cache_from_source(__file__) + try: + pyc_filename = importlib.util.cache_from_source(__file__) + except NotImplementedError: + return py_filename = importlib.util.source_from_cache(pyc_filename) origin = self.check_executecodemodule(execute_code_func, NULL, pyc_filename) if not object: diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 8695df9eb0c294..73b1f671c58555 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -240,9 +240,8 @@ def test_script_abspath(self): def test_script_compiled(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') - py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) self._check_script(pyc_file, pyc_file, pyc_file, script_dir, None, importlib.machinery.SourcelessFileLoader) @@ -257,9 +256,8 @@ def test_directory(self): def test_directory_compiled(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) self._check_script(script_dir, pyc_file, script_dir, script_dir, '', importlib.machinery.SourcelessFileLoader) @@ -279,8 +277,8 @@ def test_zipfile(self): def test_zipfile_compiled_timestamp(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = py_compile.compile( - script_name, doraise=True, + compiled_name = script_name + 'c' + py_compile.compile(script_name, compiled_name, doraise=True, invalidation_mode=py_compile.PycInvalidationMode.TIMESTAMP) zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, run_name, zip_name, zip_name, '', @@ -289,8 +287,8 @@ def test_zipfile_compiled_timestamp(self): def test_zipfile_compiled_checked_hash(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = py_compile.compile( - script_name, doraise=True, + compiled_name = script_name + 'c' + py_compile.compile(script_name, compiled_name, doraise=True, invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH) zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, run_name, zip_name, zip_name, '', @@ -299,8 +297,8 @@ def test_zipfile_compiled_checked_hash(self): def test_zipfile_compiled_unchecked_hash(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = py_compile.compile( - script_name, doraise=True, + compiled_name = script_name + 'c' + py_compile.compile(script_name, compiled_name, doraise=True, invalidation_mode=py_compile.PycInvalidationMode.UNCHECKED_HASH) zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, run_name, zip_name, zip_name, '', @@ -353,9 +351,8 @@ def test_package_compiled(self): pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') - compiled_name = py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) self._check_script(["-m", "test_pkg"], pyc_file, pyc_file, script_dir, 'test_pkg', importlib.machinery.SourcelessFileLoader, diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 8384c183dd92dd..b2150b621516ba 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -33,6 +33,10 @@ from test.support.os_helper import FakePath +if sys.implementation.cache_tag is None: + raise unittest.SkipTest('requires sys.implementation.cache_tag is not None') + + def get_pyc(script, opt): if not opt: # Replace None and 0 with '' diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py index f6743d57ca28dd..c62b340f6a340f 100644 --- a/Lib/test/test_ensurepip.py +++ b/Lib/test/test_ensurepip.py @@ -12,6 +12,12 @@ import ensurepip._uninstall +if sys.implementation.cache_tag is None: + COMPILE_OPT = ["--no-compile"] +else: + COMPILE_OPT = [] + + class TestPackages(unittest.TestCase): def touch(self, directory, filename): fullname = os.path.join(directory, filename) @@ -85,7 +91,7 @@ def test_basic_bootstrapping(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "pip", + unittest.mock.ANY, *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) @@ -99,7 +105,7 @@ def test_bootstrapping_with_root(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "--root", "/foo/bar/", + unittest.mock.ANY, "--root", "/foo/bar/", *COMPILE_OPT, "pip", ], unittest.mock.ANY, @@ -111,7 +117,7 @@ def test_bootstrapping_with_user(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "--user", "pip", + unittest.mock.ANY, "--user", *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) @@ -122,7 +128,7 @@ def test_bootstrapping_with_upgrade(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "--upgrade", "pip", + unittest.mock.ANY, "--upgrade", *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) @@ -133,7 +139,7 @@ def test_bootstrapping_with_verbosity_1(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "-v", "pip", + unittest.mock.ANY, "-v", *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) @@ -144,7 +150,7 @@ def test_bootstrapping_with_verbosity_2(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "-vv", "pip", + unittest.mock.ANY, "-vv", *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) @@ -155,7 +161,7 @@ def test_bootstrapping_with_verbosity_3(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "-vvv", "pip", + unittest.mock.ANY, "-vvv", *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) @@ -312,7 +318,7 @@ def test_basic_bootstrapping(self): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "pip", + unittest.mock.ANY, *COMPILE_OPT, "pip", ], unittest.mock.ANY, ) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index f66e2987d34850..437ab7031356b1 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -77,7 +77,7 @@ skip_if_dont_write_bytecode = unittest.skipIf( - sys.dont_write_bytecode, + sys.dont_write_bytecode or sys.implementation.cache_tag is None, "test meaningful only when writing bytecode") @@ -505,7 +505,7 @@ def test_module_with_large_stack(self, module='longlist'): try: # Compile & remove .py file; we only need .pyc. # Bytecode must be relocated from the PEP 3147 bytecode-only location. - py_compile.compile(filename) + make_legacy_pyc(filename, allow_compile=True) finally: unlink(filename) @@ -515,7 +515,6 @@ def test_module_with_large_stack(self, module='longlist'): namespace = {} try: - make_legacy_pyc(filename) # This used to crash. exec('import ' + module, None, namespace) finally: @@ -1400,7 +1399,10 @@ def func(): """ dir_name = os.path.abspath(TESTFN) file_name = os.path.join(dir_name, module_name) + os.extsep + "py" - compiled_name = importlib.util.cache_from_source(file_name) + try: + compiled_name = importlib.util.cache_from_source(file_name) + except NotImplementedError: + compiled_name = None def setUp(self): self.sys_path = sys.path[:] @@ -1418,7 +1420,8 @@ def tearDown(self): else: unload(self.module_name) unlink(self.file_name) - unlink(self.compiled_name) + if self.compiled_name: + unlink(self.compiled_name) rmtree(self.dir_name) def import_module(self): @@ -1437,6 +1440,8 @@ def test_basics(self): self.assertEqual(mod.code_filename, self.file_name) self.assertEqual(mod.func_filename, self.file_name) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag is not None') def test_incorrect_code_name(self): py_compile.compile(self.file_name, dfile="another_module.py") mod = self.import_module() @@ -1446,9 +1451,9 @@ def test_incorrect_code_name(self): def test_module_without_source(self): target = "another_module.py" - py_compile.compile(self.file_name, dfile=target) + pyc_file = self.file_name + 'c' + py_compile.compile(self.file_name, pyc_file, dfile=target) os.remove(self.file_name) - pyc_file = make_legacy_pyc(self.file_name) importlib.invalidate_caches() mod = self.import_module() self.assertEqual(mod.module_filename, pyc_file) @@ -1456,8 +1461,9 @@ def test_module_without_source(self): self.assertEqual(mod.func_filename, target) def test_foreign_code(self): - py_compile.compile(self.file_name) - with open(self.compiled_name, "rb") as f: + compiled_name = self.compiled_name or (self.file_name + 'c') + py_compile.compile(self.file_name, compiled_name) + with open(compiled_name, "rb") as f: header = f.read(16) code = marshal.load(f) constants = list(code.co_consts) @@ -1465,9 +1471,11 @@ def test_foreign_code(self): pos = constants.index(1000) constants[pos] = foreign_code code = code.replace(co_consts=tuple(constants)) - with open(self.compiled_name, "wb") as f: + with open(compiled_name, "wb") as f: f.write(header) marshal.dump(code, f) + if not self.compiled_name: + os.remove(self.file_name) mod = self.import_module() self.assertEqual(mod.constant.co_filename, foreign_code.co_filename) diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index 5d5d4722171a8e..e4bd850f3514ff 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -213,12 +213,21 @@ def manipulate_bytecode(self, del sys.modules['_temp'] except KeyError: pass - py_compile.compile(mapping[name], invalidation_mode=invalidation_mode) - if not del_source: - bytecode_path = self.util.cache_from_source(mapping[name]) + if sys.implementation.cache_tag is None: + if del_source: + bytecode_path = mapping[name] + 'c' + py_compile.compile(mapping[name], bytecode_path, + invalidation_mode=invalidation_mode) + os.unlink(mapping[name]) + else: + raise unittest.SkipTest('requires sys.implementation.cache_tag') else: - os.unlink(mapping[name]) - bytecode_path = make_legacy_pyc(mapping[name]) + py_compile.compile(mapping[name], invalidation_mode=invalidation_mode) + if not del_source: + bytecode_path = self.util.cache_from_source(mapping[name]) + else: + os.unlink(mapping[name]) + bytecode_path = make_legacy_pyc(mapping[name]) if manipulator: with open(bytecode_path, 'rb') as file: bc = file.read() diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index c33e90232b36e6..91865b997ad364 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -57,6 +57,8 @@ def run_test(self, test, create=None, *, compile_=None, unlink=None): """ if create is None: create = {test} + if (compile_ or unlink) and sys.implementation.cache_tag is None: + raise unittest.SkipTest('requires sys.implementation.cache_tag') with util.create_modules(*create) as mapping: if compile_: for name in compile_: diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index 7c146ea853b0d9..b24c576646842f 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -533,7 +533,10 @@ class SourceLoader(SourceOnlyLoader): def __init__(self, path, magic=None): super().__init__(path) - self.bytecode_path = self.util.cache_from_source(self.path) + try: + self.bytecode_path = self.util.cache_from_source(self.path) + except NotImplementedError: + self.bytecode_path = None self.source_size = len(self.source) if magic is None: magic = self.util.MAGIC_NUMBER @@ -579,7 +582,10 @@ def setUp(self, *, is_package=True, **kwargs): module_name = 'mod' self.path = os.path.join(self.package, '.'.join(['mod', 'py'])) self.name = '.'.join([self.package, module_name]) - self.cached = self.util.cache_from_source(self.path) + try: + self.cached = self.util.cache_from_source(self.path) + except NotImplementedError: + self.cached = None self.loader = self.loader_mock(self.path, **kwargs) def verify_module(self, module): @@ -656,6 +662,8 @@ def test_get_source_encoding(self): @unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true") +@unittest.skipIf(sys.implementation.cache_tag is None, + "sys.implementation.cache_tag is None") class SourceLoaderBytecodeTests(SourceLoaderTestHarness): """Test importlib.abc.SourceLoader's use of bytecode. diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 4de0cf029a81e0..70d93d693ae593 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -231,7 +231,6 @@ def test_reload_location_changed(self): # Start as a plain module. self.init.invalidate_caches() path = os.path.join(cwd, name + '.py') - cached = self.util.cache_from_source(path) expected = {'__name__': name, '__package__': '', '__file__': path, @@ -251,7 +250,6 @@ def test_reload_location_changed(self): # Change to a package. self.init.invalidate_caches() init_path = os.path.join(cwd, name, '__init__.py') - cached = self.util.cache_from_source(init_path) expected = {'__name__': name, '__package__': name, '__file__': init_path, @@ -281,7 +279,6 @@ def test_reload_namespace_changed(self): # Start as a namespace package. self.init.invalidate_caches() bad_path = os.path.join(cwd, name, '__init.py') - cached = self.util.cache_from_source(bad_path) expected = {'__name__': name, '__package__': name, '__doc__': None, @@ -310,7 +307,6 @@ def test_reload_namespace_changed(self): # Change to a regular package. self.init.invalidate_caches() init_path = os.path.join(cwd, name, '__init__.py') - cached = self.util.cache_from_source(init_path) expected = {'__name__': name, '__package__': name, '__file__': init_path, diff --git a/Lib/test/test_importlib/test_pkg_import.py b/Lib/test/test_importlib/test_pkg_import.py index 5ffae6222bacb8..287684efc85a91 100644 --- a/Lib/test/test_importlib/test_pkg_import.py +++ b/Lib/test/test_importlib/test_pkg_import.py @@ -39,9 +39,12 @@ def tearDown(self): self.remove_modules() def rewrite_file(self, contents): - compiled_path = cache_from_source(self.module_path) - if os.path.exists(compiled_path): - os.remove(compiled_path) + try: + compiled_path = cache_from_source(self.module_path) + if os.path.exists(compiled_path): + os.remove(compiled_path) + except NotImplementedError: + pass with open(self.module_path, 'w', encoding='utf-8') as f: f.write(contents) diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py index b48d0a101ca9e7..77b6228940c3b9 100644 --- a/Lib/test/test_importlib/test_spec.py +++ b/Lib/test/test_importlib/test_spec.py @@ -52,7 +52,10 @@ class ModuleSpecTests: def setUp(self): self.name = 'spam' self.path = 'spam.py' - self.cached = self.util.cache_from_source(self.path) + try: + self.cached = self.util.cache_from_source(self.path) + except NotImplementedError: + self.cached = None self.loader = TestLoader() self.spec = self.machinery.ModuleSpec(self.name, self.loader) self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader, @@ -184,6 +187,8 @@ def test_cached_with_origin_not_location(self): self.assertIs(spec.cached, None) + @unittest.skipIf(sys.implementation.cache_tag is None, + "sys.implementation.cache_tag is None") def test_cached_source(self): expected = self.util.cache_from_source(self.path) @@ -224,7 +229,10 @@ def bootstrap(self): def setUp(self): self.name = 'spam' self.path = 'spam.py' - self.cached = self.util.cache_from_source(self.path) + try: + self.cached = self.util.cache_from_source(self.path) + except NotImplementedError: + self.cached = None self.loader = TestLoader() self.spec = self.machinery.ModuleSpec(self.name, self.loader) self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader, @@ -349,7 +357,10 @@ class FactoryTests: def setUp(self): self.name = 'spam' self.path = os.path.abspath('spam.py') - self.cached = self.util.cache_from_source(self.path) + try: + self.cached = self.util.cache_from_source(self.path) + except NotImplementedError: + self.cached = None self.loader = TestLoader() self.fileloader = TestLoader(self.path) self.pkgloader = TestLoader(self.path, True) diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 17a211f10fa0ac..a926a7a4d408af 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -345,6 +345,8 @@ def test_cache_from_source_no_cache_tag(self): with self.assertRaises(NotImplementedError): self.util.cache_from_source('whatever.py') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_cache_from_source_no_dot(self): # Directory with a dot, filename without dot. path = os.path.join('foo.bar', 'file') @@ -353,12 +355,16 @@ def test_cache_from_source_no_dot(self): self.assertEqual(self.util.cache_from_source(path, optimization=''), expect) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_cache_from_source_cwd(self): path = 'foo.py' expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag)) self.assertEqual(self.util.cache_from_source(path, optimization=''), expect) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_cache_from_source_optimization_empty_string(self): # Setting 'optimization' to '' leads to no optimization tag (PEP 488). path = 'foo.py' @@ -366,6 +372,8 @@ def test_cache_from_source_optimization_empty_string(self): self.assertEqual(self.util.cache_from_source(path, optimization=''), expect) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_cache_from_source_optimization_None(self): # Setting 'optimization' to None uses the interpreter's optimization. # (PEP 488) @@ -382,6 +390,8 @@ def test_cache_from_source_optimization_None(self): self.assertEqual(self.util.cache_from_source(path, optimization=None), expect) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_cache_from_source_optimization_set(self): # The 'optimization' parameter accepts anything that has a string repr # that passes str.alnum(). @@ -399,6 +409,8 @@ def test_cache_from_source_optimization_set(self): with self.assertRaises(ValueError): self.util.cache_from_source(path, optimization='path/is/bad') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_cache_from_source_debug_override_optimization_both_set(self): # Can only set one of the optimization-related parameters. with warnings.catch_warnings(): @@ -408,6 +420,8 @@ def test_cache_from_source_debug_override_optimization_both_set(self): @unittest.skipUnless(os.sep == '\\' and os.altsep == '/', 'test meaningful only where os.altsep is defined') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_sep_altsep_and_sep_cache_from_source(self): # Windows path and PEP 3147 where sep is right of altsep. self.assertEqual( @@ -440,44 +454,60 @@ def test_source_from_cache_no_cache_tag(self): with self.assertRaises(NotImplementedError): self.util.source_from_cache(path) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_bad_path(self): # When the path to a pyc file is not in PEP 3147 format, a ValueError # is raised. self.assertRaises( ValueError, self.util.source_from_cache, '/foo/bar/bazqux.pyc') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_no_slash(self): # No slashes at all in path -> ValueError self.assertRaises( ValueError, self.util.source_from_cache, 'foo.cpython-32.pyc') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_too_few_dots(self): # Too few dots in final path component -> ValueError self.assertRaises( ValueError, self.util.source_from_cache, '__pycache__/foo.pyc') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_too_many_dots(self): with self.assertRaises(ValueError): self.util.source_from_cache( '__pycache__/foo.cpython-32.opt-1.foo.pyc') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_not_opt(self): # Non-`opt-` path component -> ValueError self.assertRaises( ValueError, self.util.source_from_cache, '__pycache__/foo.cpython-32.foo.pyc') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_no__pycache__(self): # Another problem with the path -> ValueError self.assertRaises( ValueError, self.util.source_from_cache, '/foo/bar/foo.cpython-32.foo.pyc') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_optimized_bytecode(self): # Optimized bytecode is not an issue. path = os.path.join('__pycache__', 'foo.{}.opt-1.pyc'.format(self.tag)) self.assertEqual(self.util.source_from_cache(path), 'foo.py') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag to not be None') def test_source_from_cache_missing_optimization(self): # An empty optimization level is a no-no. path = os.path.join('__pycache__', 'foo.{}.opt-.pyc'.format(self.tag)) diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index efbec667317d5f..6399f952f9e912 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -292,6 +292,9 @@ def writes_bytecode_files(fxn): tests that require it to be set to False.""" if sys.dont_write_bytecode: return unittest.skip("relies on writing bytecode")(fxn) + if sys.implementation.cache_tag is None: + return unittest.skip("requires sys.implementation.cache_tag to not be None")(fxn) + @functools.wraps(fxn) def wrapper(*args, **kwargs): original = sys.dont_write_bytecode diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 1999aa770ecc56..e4a3a7d9add2c2 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -6527,7 +6527,8 @@ def test_details(self): self.assertIn(module.__name__, output) self.assertIn(module.__spec__.origin, output) self.assertIn(module.__file__, output) - self.assertIn(module.__spec__.cached, output) + if module.__spec__.cached: + self.assertIn(module.__spec__.cached, output) self.assertEqual(err, b'') diff --git a/Lib/test/test_multiprocessing_main_handling.py b/Lib/test/test_multiprocessing_main_handling.py index 6b30a89316703b..fbd44fb0d3d5eb 100644 --- a/Lib/test/test_multiprocessing_main_handling.py +++ b/Lib/test/test_multiprocessing_main_handling.py @@ -196,9 +196,8 @@ def test_ipython_workaround(self): def test_script_compiled(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') - py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) self._check_script(pyc_file) def test_directory(self): @@ -213,9 +212,8 @@ def test_directory_compiled(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__', source=source) - py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) self._check_script(script_dir) def test_zipfile(self): @@ -231,7 +229,8 @@ def test_zipfile_compiled(self): with os_helper.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__', source=source) - compiled_name = py_compile.compile(script_name, doraise=True) + compiled_name = script_name + 'c' + py_compile.compile(script_name, compiled_name, doraise=True) zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name) @@ -273,9 +272,8 @@ def test_package_compiled(self): make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__', source=source) - compiled_name = py_compile.compile(script_name, doraise=True) + pyc_file = import_helper.make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - pyc_file = import_helper.make_legacy_pyc(script_name) launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name) diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 64387296e84621..66de61930968e4 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -56,7 +56,10 @@ def setUp(self): self.directory = tempfile.mkdtemp(dir=os.getcwd()) self.source_path = os.path.join(self.directory, '_test.py') self.pyc_path = self.source_path + 'c' - self.cache_path = importlib.util.cache_from_source(self.source_path) + try: + self.cache_path = importlib.util.cache_from_source(self.source_path) + except NotImplementedError: + self.cache_path = None self.cwd_drive = os.path.splitdrive(os.getcwd())[0] # In these tests we compute relative paths. When using Windows, the # current working directory path and the 'self.source_path' might be @@ -73,10 +76,31 @@ def tearDown(self): if self.cwd_drive: os.chdir(self.cwd_drive) + def assert_cache_path_exists(self, should_exist=True): + if self.cache_path: + if should_exist: + self.assertTrue(os.path.exists(self.cache_path)) + else: + self.assertFalse(os.path.exists(self.cache_path)) + return + cache_dir = os.path.join(self.directory, '__pycache__') + if not os.path.isdir(cache_dir): + if should_exist: + self.fail('no __pycache__ directory exists') + return + for f in os.listdir(cache_dir): + if f.startswith('_test.') and f.endswith('.pyc'): + if should_exist: + return + self.fail(f'__pycache__/{f} was created') + else: + if should_exist: + self.fail('no __pycache__/_test.*.pyc file exists') + def test_absolute_path(self): py_compile.compile(self.source_path, self.pyc_path) self.assertTrue(os.path.exists(self.pyc_path)) - self.assertFalse(os.path.exists(self.cache_path)) + self.assert_cache_path_exists(False) def test_do_not_overwrite_symlinks(self): # In the face of a cfile argument being a symlink, bail out. @@ -98,22 +122,24 @@ def test_do_not_overwrite_nonregular_files(self): with self.assertRaises(FileExistsError): py_compile.compile(self.source_path, os.devnull) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag is not None') def test_cache_path(self): py_compile.compile(self.source_path) - self.assertTrue(os.path.exists(self.cache_path)) + self.assert_cache_path_exists(True) def test_cwd(self): with os_helper.change_cwd(self.directory): py_compile.compile(os.path.basename(self.source_path), os.path.basename(self.pyc_path)) self.assertTrue(os.path.exists(self.pyc_path)) - self.assertFalse(os.path.exists(self.cache_path)) + self.assert_cache_path_exists(False) def test_relative_path(self): py_compile.compile(os.path.relpath(self.source_path), os.path.relpath(self.pyc_path)) self.assertTrue(os.path.exists(self.pyc_path)) - self.assertFalse(os.path.exists(self.cache_path)) + self.assert_cache_path_exists(False) @os_helper.skip_if_dac_override @unittest.skipIf(os.name == 'nt', @@ -136,14 +162,14 @@ def test_bad_coding(self): 'tokenizedata', 'bad_coding2.py') with support.captured_stderr(): - self.assertIsNone(py_compile.compile(bad_coding, doraise=False)) - self.assertFalse(os.path.exists( - importlib.util.cache_from_source(bad_coding))) + self.assertIsNone(py_compile.compile(bad_coding, self.pyc_path, + doraise=False)) + self.assertFalse(os.path.exists(self.pyc_path)) def test_source_date_epoch(self): py_compile.compile(self.source_path, self.pyc_path) self.assertTrue(os.path.exists(self.pyc_path)) - self.assertFalse(os.path.exists(self.cache_path)) + self.assert_cache_path_exists(False) with open(self.pyc_path, 'rb') as fp: flags = importlib._bootstrap_external._classify_pyc( fp.read(), 'test', {}) @@ -155,6 +181,8 @@ def test_source_date_epoch(self): self.assertEqual(flags, expected_flags) @unittest.skipIf(sys.flags.optimize > 0, 'test does not work with -O') + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag is not None') def test_double_dot_no_clobber(self): # http://bugs.python.org/issue22966 # py_compile foo.bar.py -> __pycache__/foo.cpython-34.pyc @@ -174,6 +202,8 @@ def test_double_dot_no_clobber(self): self.assertTrue(os.path.exists(cache_path)) self.assertFalse(os.path.exists(pyc_path)) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag is not None') def test_optimization_path(self): # Specifying optimized bytecode should lead to a path reflecting that. self.assertIn('opt-2', py_compile.compile(self.source_path, optimize=2)) @@ -181,17 +211,19 @@ def test_optimization_path(self): def test_invalidation_mode(self): py_compile.compile( self.source_path, + self.pyc_path, invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH, ) - with open(self.cache_path, 'rb') as fp: + with open(self.pyc_path, 'rb') as fp: flags = importlib._bootstrap_external._classify_pyc( fp.read(), 'test', {}) self.assertEqual(flags, 0b11) py_compile.compile( self.source_path, + self.pyc_path, invalidation_mode=py_compile.PycInvalidationMode.UNCHECKED_HASH, ) - with open(self.cache_path, 'rb') as fp: + with open(self.pyc_path, 'rb') as fp: flags = importlib._bootstrap_external._classify_pyc( fp.read(), 'test', {}) self.assertEqual(flags, 0b1) @@ -201,11 +233,11 @@ def test_quiet(self): 'tokenizedata', 'bad_coding2.py') with support.captured_stderr() as stderr: - self.assertIsNone(py_compile.compile(bad_coding, doraise=False, quiet=2)) - self.assertIsNone(py_compile.compile(bad_coding, doraise=True, quiet=2)) + self.assertIsNone(py_compile.compile(bad_coding, self.pyc_path, doraise=False, quiet=2)) + self.assertIsNone(py_compile.compile(bad_coding, self.pyc_path, doraise=True, quiet=2)) self.assertEqual(stderr.getvalue(), '') with self.assertRaises(py_compile.PyCompileError): - py_compile.compile(bad_coding, doraise=True, quiet=1) + py_compile.compile(bad_coding, self.pyc_path, doraise=True, quiet=1) class PyCompileTestsWithSourceEpoch(PyCompileTestsBase, @@ -227,8 +259,12 @@ class PyCompileCLITestCase(unittest.TestCase): def setUp(self): self.directory = tempfile.mkdtemp() self.source_path = os.path.join(self.directory, '_test.py') - self.cache_path = importlib.util.cache_from_source(self.source_path, - optimization='' if __debug__ else 1) + try: + self.cache_path = importlib.util.cache_from_source(self.source_path, + optimization='' if __debug__ else 1) + except NotImplementedError: + # py_compile.main() assumes legacy pyc path if there is no cache_tag + self.cache_path = self.source_path + 'c' with open(self.source_path, 'w') as file: file.write('x = 123\n') diff --git a/Lib/test/test_pydoc/test_pydoc.py b/Lib/test/test_pydoc/test_pydoc.py index 0e113006cfa156..2e190d1b81be8e 100644 --- a/Lib/test/test_pydoc/test_pydoc.py +++ b/Lib/test/test_pydoc/test_pydoc.py @@ -1006,6 +1006,8 @@ def test_synopsis_sourceless(self): os = import_helper.import_fresh_module('os') expected = os.__doc__.splitlines()[0] filename = os.__spec__.cached + if not filename: + raise unittest.SkipTest('requires .pyc files') synopsis = pydoc.synopsis(filename) self.assertEqual(synopsis, expected) @@ -1013,10 +1015,10 @@ def test_synopsis_sourceless(self): def test_synopsis_sourceless_empty_doc(self): with os_helper.temp_cwd() as test_dir: init_path = os.path.join(test_dir, 'foomod42.py') - cached_path = importlib.util.cache_from_source(init_path) + cached_path = init_path + 'c' with open(init_path, 'w') as fobj: fobj.write("foo = 1") - py_compile.compile(init_path) + py_compile.compile(init_path, cached_path) synopsis = pydoc.synopsis(init_path, {}) self.assertIsNone(synopsis) synopsis_cached = pydoc.synopsis(cached_path, {}) diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index 22a55b57c076eb..5a95a05c6496a2 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -695,8 +695,11 @@ def _check_path_limitations(self, module_name): source_path_len += 2 * (len(self.longname) + 1) # a path separator + `module_name` + ".py" source_path_len += len(module_name) + 1 + len(".py") - cached_path_len = (source_path_len + - len(importlib.util.cache_from_source("x.py")) - len("x.py")) + try: + cached_path_len = (source_path_len + + len(importlib.util.cache_from_source("x.py")) - len("x.py")) + except NotImplementedError: + cached_path_len = source_path_len if os.name == 'nt' and cached_path_len >= 258: # Under Windows, the max path len is 260 including C's terminating # NUL character. diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 254a009a69718b..9f3bc8973eb8ac 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -320,14 +320,16 @@ def create_ns(init_globals): self.check_code_execution(create_ns, expected_ns) importlib.invalidate_caches() __import__(mod_name) - os.remove(mod_fname) if not sys.dont_write_bytecode: - make_legacy_pyc(mod_fname) + make_legacy_pyc(mod_fname, allow_compile=True) unload(mod_name) # In case loader caches paths + os.remove(mod_fname) importlib.invalidate_caches() if verbose > 1: print("Running from compiled:", mod_name) self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) self.check_code_execution(create_ns, expected_ns) + else: + os.remove(mod_fname) finally: self._del_pkg(pkg_dir) if verbose > 1: print("Module executed successfully") @@ -360,14 +362,16 @@ def create_ns(init_globals): self.check_code_execution(create_ns, expected_ns) importlib.invalidate_caches() __import__(mod_name) - os.remove(mod_fname) if not sys.dont_write_bytecode: - make_legacy_pyc(mod_fname) + make_legacy_pyc(mod_fname, allow_compile=True) unload(mod_name) # In case loader caches paths + os.remove(mod_fname) if verbose > 1: print("Running from compiled:", pkg_name) importlib.invalidate_caches() self._fix_ns_for_legacy_pyc(expected_ns, alter_sys) self.check_code_execution(create_ns, expected_ns) + else: + os.remove(mod_fname) finally: self._del_pkg(pkg_dir) if verbose > 1: print("Package executed successfully") @@ -420,7 +424,7 @@ def _check_relative_imports(self, depth, run_name=None): importlib.invalidate_caches() __import__(mod_name) os.remove(mod_fname) - if not sys.dont_write_bytecode: + if not sys.dont_write_bytecode and sys.implementation.cache_tag: make_legacy_pyc(mod_fname) unload(mod_name) # In case the loader caches paths if verbose > 1: print("Running from compiled:", mod_name) @@ -676,6 +680,8 @@ def test_basic_script_no_suffix(self): self._check_script(script_name, "", script_name, script_name, expect_spec=False) + @unittest.skipIf(sys.implementation.cache_tag is None, + 'requires sys.implementation.cache_tag') def test_script_compiled(self): with temp_dir() as script_dir: mod_name = 'script' @@ -696,12 +702,10 @@ def test_directory_compiled(self): with temp_dir() as script_dir: mod_name = '__main__' script_name = self._make_test_script(script_dir, mod_name) - compiled_name = py_compile.compile(script_name, doraise=True) + legacy_pyc = make_legacy_pyc(script_name, allow_compile=True) os.remove(script_name) - if not sys.dont_write_bytecode: - legacy_pyc = make_legacy_pyc(script_name) - self._check_script(script_dir, "", legacy_pyc, - script_dir, mod_name=mod_name) + self._check_script(script_dir, "", legacy_pyc, + script_dir, mod_name=mod_name) def test_directory_error(self): with temp_dir() as script_dir: @@ -722,7 +726,8 @@ def test_zipfile_compiled(self): with temp_dir() as script_dir: mod_name = '__main__' script_name = self._make_test_script(script_dir, mod_name) - compiled_name = py_compile.compile(script_name, doraise=True) + compiled_name = script_name + 'c' + py_compile.compile(script_name, compiled_name, doraise=True) zip_name, fname = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, "", fname, zip_name, diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index dce3e1d9d38e7a..76cd85709a63af 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -60,7 +60,6 @@ def module_path_to_dotted_name(path): TEMP_ZIP = os.path.abspath("junk95142.zip") TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "zipimport_data") -pyc_file = importlib.util.cache_from_source(TESTMOD + '.py') pyc_ext = '.pyc' diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index ac2332e58468a2..8234bf52d39c5f 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -2223,10 +2223,10 @@ def writepy(self, pathname, basename="", filterfunc=None): basename = name if self.debug: print("Adding package in", pathname, "as", basename) - fname, arcname = self._get_codename(initname[0:-3], basename) + arcname, bytecode = self._get_code(initname[0:-3], basename) if self.debug: print("Adding", arcname) - self.write(fname, arcname) + self.writestr(arcname, bytecode) dirlist = sorted(os.listdir(pathname)) dirlist.remove("__init__.py") # Add all *.py files and package subdirectories @@ -2243,11 +2243,10 @@ def writepy(self, pathname, basename="", filterfunc=None): if self.debug: print('file %r skipped by filterfunc' % path) continue - fname, arcname = self._get_codename(path[0:-3], - basename) + arcname, bytecode = self._get_code(path[0:-3], basename) if self.debug: print("Adding", arcname) - self.write(fname, arcname) + self.writestr(arcname, bytecode) else: # This is NOT a package directory, add its files at top level if self.debug: @@ -2260,101 +2259,58 @@ def writepy(self, pathname, basename="", filterfunc=None): if self.debug: print('file %r skipped by filterfunc' % path) continue - fname, arcname = self._get_codename(path[0:-3], - basename) + arcname, bytecode = self._get_code(path[0:-3], basename) if self.debug: print("Adding", arcname) - self.write(fname, arcname) + self.writestr(arcname, bytecode) else: if pathname[-3:] != ".py": raise RuntimeError( 'Files added with writepy() must end with ".py"') - fname, arcname = self._get_codename(pathname[0:-3], basename) + arcname, bytecode = self._get_code(pathname[0:-3], basename) if self.debug: print("Adding file", arcname) - self.write(fname, arcname) + self.writestr(arcname, bytecode) - def _get_codename(self, pathname, basename): - """Return (filename, archivename) for the path. + def _get_code(self, pathname, basename): + """Return (arcname, bytecode) for the path. - Given a module name path, return the correct file path and - archive name, compiling if necessary. For example, given - /python/lib/string, return (/python/lib/string.pyc, string). + Given a module name path, return the bytecode and archive + name. For example, given /python/lib/string, return + ('string', b''). """ - def _compile(file, optimize=-1): - import py_compile - if self.debug: - print("Compiling", file) - try: - py_compile.compile(file, doraise=True, optimize=optimize) - except py_compile.PyCompileError as err: - print(err.msg) - return False - return True + import importlib._bootstrap_external + import importlib.machinery file_py = pathname + ".py" file_pyc = pathname + ".pyc" - pycache_opt0 = importlib.util.cache_from_source(file_py, optimization='') - pycache_opt1 = importlib.util.cache_from_source(file_py, optimization=1) - pycache_opt2 = importlib.util.cache_from_source(file_py, optimization=2) - if self._optimize == -1: - # legacy mode: use whatever file is present - if (os.path.isfile(file_pyc) and - os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime): - # Use .pyc file. - arcname = fname = file_pyc - elif (os.path.isfile(pycache_opt0) and - os.stat(pycache_opt0).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_opt0 - arcname = file_pyc - elif (os.path.isfile(pycache_opt1) and - os.stat(pycache_opt1).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_opt1 - arcname = file_pyc - elif (os.path.isfile(pycache_opt2) and - os.stat(pycache_opt2).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_opt2 - arcname = file_pyc - else: - # Compile py into PEP 3147 pyc file. - if _compile(file_py): - if sys.flags.optimize == 0: - fname = pycache_opt0 - elif sys.flags.optimize == 1: - fname = pycache_opt1 - else: - fname = pycache_opt2 - arcname = file_pyc - else: - fname = arcname = file_py + archivename = os.path.split(file_pyc)[1] + + loader = importlib.machinery.SourceFileLoader('', file_py) + source_bytes = loader.get_data(file_py) + try: + if self.debug: + print("Compiling", file_py) + code = loader.source_to_code(source_bytes, archivename) + except Exception as err: + # Historically, this function prints messages here rather than raising + # (see test_zipfile.test_write_filtered_python_package) + from py_compile import PyCompileError + print(PyCompileError(type(err), err, file_py).msg) + + archivename = os.path.split(file_py)[1] + bytecode = source_bytes else: - # new mode: use given optimization level - if self._optimize == 0: - fname = pycache_opt0 - arcname = file_pyc - else: - arcname = file_pyc - if self._optimize == 1: - fname = pycache_opt1 - elif self._optimize == 2: - fname = pycache_opt2 - else: - msg = "invalid value for 'optimize': {!r}".format(self._optimize) - raise ValueError(msg) - if not (os.path.isfile(fname) and - os.stat(fname).st_mtime >= os.stat(file_py).st_mtime): - if not _compile(file_py, optimize=self._optimize): - fname = arcname = file_py - archivename = os.path.split(arcname)[1] + # Historically this function has used timestamp comparisons, so we + # keep using it until someone makes that specific improvement. + source_stats = loader.path_stats(file_py) + bytecode = importlib._bootstrap_external._code_to_timestamp_pyc( + code, source_stats['mtime'], source_stats['size']) + if basename: archivename = "%s/%s" % (basename, archivename) - return (fname, archivename) + + return archivename, bytecode def main(args=None): diff --git a/Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst b/Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst new file mode 100644 index 00000000000000..49dbdd621851f6 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst @@ -0,0 +1,5 @@ +Enables defining the ``_PY_IMPL_NAME`` and ``_PY_IMPL_CACHE_TAG`` preprocessor +definitions to override :data:`sys.implementation` at build time. Definitions +need to include quotes when setting to a string literal. Setting the cache tag +to ``NULL`` has the effect of completely disabling automatic creation and use of +``.pyc`` files. diff --git a/Modules/_testlimitedcapi/import.c b/Modules/_testlimitedcapi/import.c index f85daee57d712e..f572212ba88b76 100644 --- a/Modules/_testlimitedcapi/import.c +++ b/Modules/_testlimitedcapi/import.c @@ -22,7 +22,7 @@ static PyObject * pyimport_getmagictag(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) { const char *tag = PyImport_GetMagicTag(); - return PyUnicode_FromString(tag); + return tag ? PyUnicode_FromString(tag) : Py_NewRef(Py_None); } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 94eb3164ecad58..61dbe5edb87186 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -3568,16 +3568,22 @@ make_version_info(PyThreadState *tstate) } /* sys.implementation values */ -#define NAME "cpython" -const char *_PySys_ImplName = NAME; +#ifndef _PY_IMPL_NAME +#define _PY_IMPL_NAME "cpython" +#endif +const char *_PySys_ImplName = _PY_IMPL_NAME; +#ifndef _PY_IMPL_CACHE_TAG #define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION) #define MINOR Py_STRINGIFY(PY_MINOR_VERSION) -#define TAG NAME "-" MAJOR MINOR -const char *_PySys_ImplCacheTag = TAG; -#undef NAME +#define _PY_IMPL_CACHE_TAG _PY_IMPL_NAME "-" MAJOR MINOR +#endif +const char *_PySys_ImplCacheTag = _PY_IMPL_CACHE_TAG; +#ifdef MAJOR #undef MAJOR +#endif +#ifdef MINOR #undef MINOR -#undef TAG +#endif static PyObject * make_impl_info(PyObject *version_info) @@ -3599,9 +3605,12 @@ make_impl_info(PyObject *version_info) if (res < 0) goto error; - value = PyUnicode_FromString(_PySys_ImplCacheTag); - if (value == NULL) + value = _PySys_ImplCacheTag + ? PyUnicode_FromString(_PySys_ImplCacheTag) + : Py_NewRef(Py_None); + if (value == NULL) { goto error; + } res = PyDict_SetItemString(impl_info, "cache_tag", value); Py_DECREF(value); if (res < 0) From 80ba4e10f5070e6d2e35618e08057be44f913965 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Feb 2026 05:04:52 +0200 Subject: [PATCH 050/498] Disable pip version check when upgrading certifi (#144632) --- Mac/BuildScript/resources/install_certificates.command | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mac/BuildScript/resources/install_certificates.command b/Mac/BuildScript/resources/install_certificates.command index 19b4adac07bb1d..700eb462b68c18 100755 --- a/Mac/BuildScript/resources/install_certificates.command +++ b/Mac/BuildScript/resources/install_certificates.command @@ -25,7 +25,8 @@ def main(): print(" -- pip install --upgrade certifi") subprocess.check_call([sys.executable, - "-E", "-s", "-m", "pip", "install", "--upgrade", "certifi"]) + "-E", "-s", "-m", "pip", "install", "--upgrade", "certifi", + "--disable-pip-version-check"]) import certifi From 2042e26f8d11805431b71e60e6e2b1d98457dbf9 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Tue, 10 Feb 2026 01:45:06 -0500 Subject: [PATCH 051/498] gh-124111: Update macOS installer to use Tcl/Tk 9.0.3 (#144646) --- Mac/BuildScript/build-installer.py | 6 +++--- .../macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 1852397ed6f391..5a542322b5b4a2 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -264,10 +264,10 @@ def library_recipes(): tk_patches = ['backport_gh71383_fix.patch', 'tk868_on_10_8_10_9.patch', 'backport_gh110950_fix.patch'] else: - tcl_tk_ver='9.0.2' - tcl_checksum='e074c6a8d9ba2cddf914ba97b6677a552d7a52a3ca102924389a05ccb249b520' + tcl_tk_ver='9.0.3' + tcl_checksum='2537ba0c86112c8c953f7c09d33f134dd45c0fb3a71f2d7f7691fd301d2c33a6' - tk_checksum='76fb852b2f167592fe8b41aa6549ce4e486dbf3b259a269646600e3894517c76' + tk_checksum='bf344efadb618babb7933f69275620f72454d1c8220130da93e3f7feb0efbf9b' tk_patches = [] diff --git a/Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst b/Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst new file mode 100644 index 00000000000000..1318b41478f81f --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst @@ -0,0 +1 @@ +Update macOS installer to use Tcl/Tk 9.0.3. From 704b915494521d6061c5377e90be6361ea2325b2 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Tue, 10 Feb 2026 01:45:55 -0500 Subject: [PATCH 052/498] gh-144551: Update macOS installer to use OpenSSL 3.5.5 (#144645) --- Mac/BuildScript/build-installer.py | 6 +++--- .../macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 5a542322b5b4a2..cd5f4c71b005ed 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 3.5.4", - url="https://github.com/openssl/openssl/releases/download/openssl-3.5.4/openssl-3.5.4.tar.gz", - checksum="967311f84955316969bdb1d8d4b983718ef42338639c621ec4c34fddef355e99", + name="OpenSSL 3.5.5", + url="https://github.com/openssl/openssl/releases/download/openssl-3.5.5/openssl-3.5.5.tar.gz", + checksum="b28c91532a8b65a1f983b4c28b7488174e4a01008e29ce8e69bd789f28bc2a89", buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst b/Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst new file mode 100644 index 00000000000000..4b979a405fd8fd --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst @@ -0,0 +1 @@ +Update macOS installer to use OpenSSL 3.5.5. From d2d245942eccf108ac3c97b82a7dda59a509372c Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Tue, 10 Feb 2026 19:29:55 +1100 Subject: [PATCH 053/498] gh-144648: Improve libproc usage in _remote_debugging (#144649) --- .../macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst | 1 + Modules/_remote_debugging/subprocess.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst diff --git a/Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst b/Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst new file mode 100644 index 00000000000000..5f8ba046f3571e --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst @@ -0,0 +1 @@ +Allowed _remote_debugging to build on more OS versions by using proc_listpids() rather than proc_listallpids(). diff --git a/Modules/_remote_debugging/subprocess.c b/Modules/_remote_debugging/subprocess.c index 2056217664a9ee..1b16dd8343f2a5 100644 --- a/Modules/_remote_debugging/subprocess.c +++ b/Modules/_remote_debugging/subprocess.c @@ -273,6 +273,7 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result) #if defined(__APPLE__) && TARGET_OS_OSX +#include #include static int @@ -283,7 +284,7 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result) pid_t *ppids = NULL; /* Get count of all PIDs */ - int n_pids = proc_listallpids(NULL, 0); + int n_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); if (n_pids <= 0) { PyErr_SetString(PyExc_OSError, "Failed to get process count"); goto done; @@ -298,7 +299,7 @@ get_child_pids_platform(pid_t target_pid, int recursive, pid_array_t *result) } /* Get actual PIDs */ - int actual = proc_listallpids(pid_list, buffer_size * sizeof(pid_t)); + int actual = proc_listpids(PROC_ALL_PIDS, 0, pid_list, buffer_size * sizeof(pid_t)); if (actual <= 0) { PyErr_SetString(PyExc_OSError, "Failed to list PIDs"); goto done; From 2c1ca6bb5be960529b2f2adac23a8aec46bc031c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Tue, 10 Feb 2026 10:04:50 +0000 Subject: [PATCH 054/498] gh-144563: Fix remote debugging with duplicate libpython mappings from ctypes (#144595) When _ctypes is imported, it may call dlopen on the libpython shared library, causing the dynamic linker to load a second mapping of the library into the process address space. The remote debugging code iterates memory regions from low addresses upward and returns the first mapping whose filename matches libpython. After _ctypes is imported, it finds the dlopen'd copy first, but that copy's PyRuntime section was never initialized, so reading debug offsets from it fails. Fix this by validating each candidate PyRuntime address before accepting it. The validation reads the first 8 bytes and checks for the "xdebugpy" cookie that is only present in an initialized PyRuntime. Uninitialized duplicate mappings will fail this check and be skipped, allowing the search to continue to the real, initialized PyRuntime. --- Lib/test/test_external_inspection.py | 38 ++++++++++++ ...-02-08-18-13-38.gh-issue-144563.hb3kpp.rst | 4 ++ Modules/_remote_debugging/asyncio.c | 12 ++-- Python/remote_debug.h | 59 +++++++++++++++---- 4 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst diff --git a/Lib/test/test_external_inspection.py b/Lib/test/test_external_inspection.py index fe1b5fbe00bbc4..890aa584cd192c 100644 --- a/Lib/test/test_external_inspection.py +++ b/Lib/test/test_external_inspection.py @@ -516,6 +516,44 @@ def foo(): finally: _cleanup_sockets(client_socket, server_socket) + @skip_if_not_supported + @unittest.skipIf( + sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED, + "Test only runs on Linux with process_vm_readv support", + ) + def test_self_trace_after_ctypes_import(self): + """Test that RemoteUnwinder works on the same process after _ctypes import. + + When _ctypes is imported, it may call dlopen on the libpython shared + library, creating a duplicate mapping in the process address space. + The remote debugging code must skip these uninitialized duplicate + mappings and find the real PyRuntime. See gh-144563. + """ + # Run the test in a subprocess to avoid side effects + script = textwrap.dedent("""\ + import os + import _remote_debugging + + # Should work before _ctypes import + unwinder = _remote_debugging.RemoteUnwinder(os.getpid()) + + import _ctypes + + # Should still work after _ctypes import (gh-144563) + unwinder = _remote_debugging.RemoteUnwinder(os.getpid()) + """) + + result = subprocess.run( + [sys.executable, "-c", script], + capture_output=True, + text=True, + timeout=SHORT_TIMEOUT, + ) + self.assertEqual( + result.returncode, 0, + f"stdout: {result.stdout}\nstderr: {result.stderr}" + ) + @skip_if_not_supported @unittest.skipIf( sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED, diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst new file mode 100644 index 00000000000000..023f9dce20124f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst @@ -0,0 +1,4 @@ +Fix interaction of the Tachyon profiler and :mod:`ctypes` and other modules +that load the Python shared library (if present) in an independent map as +this was causing the mechanism that loads the binary information to be +confused. Patch by Pablo Galindo diff --git a/Modules/_remote_debugging/asyncio.c b/Modules/_remote_debugging/asyncio.c index 3fcc939fd0e876..fc059659511fd8 100644 --- a/Modules/_remote_debugging/asyncio.c +++ b/Modules/_remote_debugging/asyncio.c @@ -18,7 +18,8 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle) #ifdef MS_WINDOWS // On Windows, search for asyncio debug in executable or DLL - address = search_windows_map_for_section(handle, "AsyncioD", L"_asyncio"); + address = search_windows_map_for_section(handle, "AsyncioD", L"_asyncio", + NULL); if (address == 0) { // Error out: 'python' substring covers both executable and DLL PyObject *exc = PyErr_GetRaisedException(); @@ -27,7 +28,8 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle) } #elif defined(__linux__) && HAVE_PROCESS_VM_READV // On Linux, search for asyncio debug in executable or DLL - address = search_linux_map_for_section(handle, "AsyncioDebug", "python"); + address = search_linux_map_for_section(handle, "AsyncioDebug", "python", + NULL); if (address == 0) { // Error out: 'python' substring covers both executable and DLL PyObject *exc = PyErr_GetRaisedException(); @@ -36,10 +38,12 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle) } #elif defined(__APPLE__) && TARGET_OS_OSX // On macOS, try libpython first, then fall back to python - address = search_map_for_section(handle, "AsyncioDebug", "libpython"); + address = search_map_for_section(handle, "AsyncioDebug", "libpython", + NULL); if (address == 0) { PyErr_Clear(); - address = search_map_for_section(handle, "AsyncioDebug", "python"); + address = search_map_for_section(handle, "AsyncioDebug", "python", + NULL); } if (address == 0) { // Error out: 'python' substring covers both executable and DLL diff --git a/Python/remote_debug.h b/Python/remote_debug.h index dba6da3bad4197..4ae1166e885485 100644 --- a/Python/remote_debug.h +++ b/Python/remote_debug.h @@ -150,6 +150,31 @@ typedef struct { Py_ssize_t page_size; } proc_handle_t; +// Forward declaration for use in validation function +static int +_Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address, size_t len, void* dst); + +// Optional callback to validate a candidate section address found during +// memory map searches. Returns 1 if the address is valid, 0 to skip it. +// This allows callers to filter out duplicate/stale mappings (e.g. from +// ctypes dlopen) whose sections were never initialized. +typedef int (*section_validator_t)(proc_handle_t *handle, uintptr_t address); + +// Validate that a candidate address starts with _Py_Debug_Cookie. +static int +_Py_RemoteDebug_ValidatePyRuntimeCookie(proc_handle_t *handle, uintptr_t address) +{ + if (address == 0) { + return 0; + } + char buf[sizeof(_Py_Debug_Cookie) - 1]; + if (_Py_RemoteDebug_ReadRemoteMemory(handle, address, sizeof(buf), buf) != 0) { + PyErr_Clear(); + return 0; + } + return memcmp(buf, _Py_Debug_Cookie, sizeof(buf)) == 0; +} + static void _Py_RemoteDebug_FreePageCache(proc_handle_t *handle) { @@ -509,7 +534,8 @@ pid_to_task(pid_t pid) } static uintptr_t -search_map_for_section(proc_handle_t *handle, const char* secname, const char* substr) { +search_map_for_section(proc_handle_t *handle, const char* secname, const char* substr, + section_validator_t validator) { mach_vm_address_t address = 0; mach_vm_size_t size = 0; mach_msg_type_number_t count = sizeof(vm_region_basic_info_data_64_t); @@ -561,7 +587,9 @@ search_map_for_section(proc_handle_t *handle, const char* secname, const char* s if (strncmp(filename, substr, strlen(substr)) == 0) { uintptr_t result = search_section_in_file( secname, map_filename, address, size, proc_ref); - if (result != 0) { + if (result != 0 + && (validator == NULL || validator(handle, result))) + { return result; } } @@ -678,7 +706,8 @@ search_elf_file_for_section( } static uintptr_t -search_linux_map_for_section(proc_handle_t *handle, const char* secname, const char* substr) +search_linux_map_for_section(proc_handle_t *handle, const char* secname, const char* substr, + section_validator_t validator) { char maps_file_path[64]; sprintf(maps_file_path, "/proc/%d/maps", handle->pid); @@ -753,9 +782,12 @@ search_linux_map_for_section(proc_handle_t *handle, const char* secname, const c if (strstr(filename, substr)) { retval = search_elf_file_for_section(handle, secname, start, path); - if (retval) { + if (retval + && (validator == NULL || validator(handle, retval))) + { break; } + retval = 0; } } @@ -859,7 +891,8 @@ static void* analyze_pe(const wchar_t* mod_path, BYTE* remote_base, const char* static uintptr_t -search_windows_map_for_section(proc_handle_t* handle, const char* secname, const wchar_t* substr) { +search_windows_map_for_section(proc_handle_t* handle, const char* secname, const wchar_t* substr, + section_validator_t validator) { HANDLE hProcSnap; do { hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, handle->pid); @@ -882,8 +915,11 @@ search_windows_map_for_section(proc_handle_t* handle, const char* secname, const for (BOOL hasModule = Module32FirstW(hProcSnap, &moduleEntry); hasModule; hasModule = Module32NextW(hProcSnap, &moduleEntry)) { // Look for either python executable or DLL if (wcsstr(moduleEntry.szModule, substr)) { - runtime_addr = analyze_pe(moduleEntry.szExePath, moduleEntry.modBaseAddr, secname); - if (runtime_addr != NULL) { + void *candidate = analyze_pe(moduleEntry.szExePath, moduleEntry.modBaseAddr, secname); + if (candidate != NULL + && (validator == NULL || validator(handle, (uintptr_t)candidate))) + { + runtime_addr = candidate; break; } } @@ -904,7 +940,8 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle) #ifdef MS_WINDOWS // On Windows, search for 'python' in executable or DLL - address = search_windows_map_for_section(handle, "PyRuntime", L"python"); + address = search_windows_map_for_section(handle, "PyRuntime", L"python", + _Py_RemoteDebug_ValidatePyRuntimeCookie); if (address == 0) { // Error out: 'python' substring covers both executable and DLL PyObject *exc = PyErr_GetRaisedException(); @@ -915,7 +952,8 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle) } #elif defined(__linux__) && HAVE_PROCESS_VM_READV // On Linux, search for 'python' in executable or DLL - address = search_linux_map_for_section(handle, "PyRuntime", "python"); + address = search_linux_map_for_section(handle, "PyRuntime", "python", + _Py_RemoteDebug_ValidatePyRuntimeCookie); if (address == 0) { // Error out: 'python' substring covers both executable and DLL PyObject *exc = PyErr_GetRaisedException(); @@ -929,7 +967,8 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle) const char* candidates[] = {"libpython", "python", "Python", NULL}; for (const char** candidate = candidates; *candidate; candidate++) { PyErr_Clear(); - address = search_map_for_section(handle, "PyRuntime", *candidate); + address = search_map_for_section(handle, "PyRuntime", *candidate, + _Py_RemoteDebug_ValidatePyRuntimeCookie); if (address != 0) { break; } From 9b8d59c136c8016f88844b716ddbd11bc7defb84 Mon Sep 17 00:00:00 2001 From: kovan Date: Tue, 10 Feb 2026 11:13:40 +0100 Subject: [PATCH 055/498] gh-72798: Add mapping example to str.translate documentation (#144454) Add an example showing how to use str.translate() with a dictionary mapping directly, demonstrating character replacement and deletion. Co-authored-by: Claude Opus 4.5 --- Doc/library/stdtypes.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index b8c079faa93d6d..ffb5a053a6dce8 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2870,6 +2870,14 @@ expression support in the :mod:`re` module). You can use :meth:`str.maketrans` to create a translation map from character-to-character mappings in different formats. + The following example uses a mapping to replace ``'a'`` with ``'X'``, + ``'b'`` with ``'Y'``, and delete ``'c'``: + + .. doctest:: + + >>> 'abc123'.translate({ord('a'): 'X', ord('b'): 'Y', ord('c'): None}) + 'XY123' + See also the :mod:`codecs` module for a more flexible approach to custom character mappings. From 73fa6be2fe6c4a17d91413e12ab6af8376767211 Mon Sep 17 00:00:00 2001 From: Alper Date: Tue, 10 Feb 2026 02:56:52 -0800 Subject: [PATCH 056/498] gh-144490: Fix mimalloc debug build for C++ (#144620) --- Include/internal/mimalloc/mimalloc/types.h | 4 ++-- Lib/test/test_cppext/extension.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Include/internal/mimalloc/mimalloc/types.h b/Include/internal/mimalloc/mimalloc/types.h index 19e93224174314..286e7bf668312d 100644 --- a/Include/internal/mimalloc/mimalloc/types.h +++ b/Include/internal/mimalloc/mimalloc/types.h @@ -608,8 +608,8 @@ struct mi_heap_s { #if (MI_DEBUG) // use our own assertion to print without memory allocation -mi_decl_noreturn mi_decl_cold mi_decl_throw -void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func); +mi_decl_noreturn mi_decl_cold +void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func) mi_decl_throw; #define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__)) #else #define mi_assert(x) diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index a8cd70aacbc805..b631ddad7201f0 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -15,10 +15,8 @@ #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API # include "internal/pycore_frame.h" - // mimalloc emits many compiler warnings when Python is built in debug - // mode (when MI_DEBUG is not zero). // mimalloc emits compiler warnings when Python is built on Windows. -# if !defined(Py_DEBUG) && !defined(MS_WINDOWS) +# if !defined(MS_WINDOWS) # include "internal/pycore_backoff.h" # include "internal/pycore_cell.h" # endif From b121dc434748772272514311fe315e009fdfe6e5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 10 Feb 2026 12:15:14 +0100 Subject: [PATCH 057/498] gh-144652: Support Windows exit status in support get_signal_name() (#144653) Format Windows exit status as hexadecimal. --- Lib/test/support/__init__.py | 4 ++++ Lib/test/test_support.py | 1 + 2 files changed, 5 insertions(+) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 66469d088f339c..307bac65ae50a8 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3116,6 +3116,10 @@ def get_signal_name(exitcode): except KeyError: pass + # Format Windows exit status as hexadecimal + if 0xC0000000 <= exitcode: + return f"0x{exitcode:X}" + return None class BrokenIter: diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index be7e307b4f1111..a3129dbcb0a54e 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -788,6 +788,7 @@ def test_get_signal_name(self): (128 + int(signal.SIGABRT), 'SIGABRT'), (3221225477, "STATUS_ACCESS_VIOLATION"), (0xC00000FD, "STATUS_STACK_OVERFLOW"), + (0xC0000906, "0xC0000906"), ): self.assertEqual(support.get_signal_name(exitcode), expected, exitcode) From ac8b5b6890006ee7254ea878866cb486ff835ecb Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Tue, 10 Feb 2026 05:08:33 -0800 Subject: [PATCH 058/498] gh-143650: Fix importlib race condition on import failure (GH-143651) Fix a race condition where a thread could receive a partially-initialized module when another thread's import fails. The race occurs when: 1. Thread 1 starts importing, adds module to sys.modules 2. Thread 2 sees the module in sys.modules via the fast path 3. Thread 1's import fails, removes module from sys.modules 4. Thread 2 returns a stale module reference not in sys.modules The fix adds verification after the "skip lock" optimization in both Python and C code paths to check if the module is still in sys.modules. If the module was removed (due to import failure), we retry the import so the caller receives the actual exception from the import failure rather than a stale module reference. Co-Authored-By: Claude Opus 4.5 --- Lib/importlib/_bootstrap.py | 8 +++ .../test_importlib/test_threaded_import.py | 65 +++++++++++++++++++ ...-01-10-10-58-36.gh-issue-143650.k8mR4x.rst | 2 + Python/import.c | 43 +++++++++++- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 07d938b18fe727..cfcebb7309803c 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -1280,6 +1280,14 @@ def _find_and_load(name, import_): # NOTE: because of this, initializing must be set *before* # putting the new module in sys.modules. _lock_unlock_module(name) + else: + # Verify the module is still in sys.modules. Another thread may have + # removed it (due to import failure) between our sys.modules.get() + # above and the _initializing check. If removed, we retry the import + # to preserve normal semantics: the caller gets the exception from + # the actual import failure rather than a synthetic error. + if sys.modules.get(name) is not module: + return _find_and_load(name, import_) if module is None: message = f'import of {name} halted; None in sys.modules' diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index f78dc399720c86..8b793ebf29bcae 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -259,6 +259,71 @@ def test_multiprocessing_pool_circular_import(self, size): 'partial', 'pool_in_threads.py') script_helper.assert_python_ok(fn) + def test_import_failure_race_condition(self): + # Regression test for race condition where a thread could receive + # a partially-initialized module when another thread's import fails. + # The race occurs when: + # 1. Thread 1 starts importing, adds module to sys.modules + # 2. Thread 2 sees the module in sys.modules + # 3. Thread 1's import fails, removes module from sys.modules + # 4. Thread 2 should NOT return the stale module reference + os.mkdir(TESTFN) + self.addCleanup(shutil.rmtree, TESTFN) + sys.path.insert(0, TESTFN) + self.addCleanup(sys.path.remove, TESTFN) + + # Create a module that partially initializes then fails + modname = 'failing_import_module' + with open(os.path.join(TESTFN, modname + '.py'), 'w') as f: + f.write(''' +import time +PARTIAL_ATTR = 'initialized' +time.sleep(0.05) # Widen race window +raise RuntimeError("Intentional import failure") +''') + self.addCleanup(forget, modname) + importlib.invalidate_caches() + + errors = [] + results = [] + + def do_import(delay=0): + time.sleep(delay) + try: + mod = __import__(modname) + # If we got a module, verify it's in sys.modules + if modname not in sys.modules: + errors.append( + f"Got module {mod!r} but {modname!r} not in sys.modules" + ) + elif sys.modules[modname] is not mod: + errors.append( + f"Got different module than sys.modules[{modname!r}]" + ) + else: + results.append(('success', mod)) + except RuntimeError: + results.append(('RuntimeError',)) + except Exception as e: + errors.append(f"Unexpected exception: {e}") + + # Run multiple iterations to increase chance of hitting the race + for _ in range(10): + errors.clear() + results.clear() + if modname in sys.modules: + del sys.modules[modname] + + t1 = threading.Thread(target=do_import, args=(0,)) + t2 = threading.Thread(target=do_import, args=(0.01,)) + t1.start() + t2.start() + t1.join() + t2.join() + + # Neither thread should have errors about stale modules + self.assertEqual(errors, [], f"Race condition detected: {errors}") + def setUpModule(): thread_info = threading_helper.threading_setup() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst new file mode 100644 index 00000000000000..7bee70a828acfe --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst @@ -0,0 +1,2 @@ +Fix race condition in :mod:`importlib` where a thread could receive a stale +module reference when another thread's import fails. diff --git a/Python/import.c b/Python/import.c index e7f803d84f1367..c9e892c96b0339 100644 --- a/Python/import.c +++ b/Python/import.c @@ -297,12 +297,32 @@ PyImport_GetModule(PyObject *name) mod = import_get_module(tstate, name); if (mod != NULL && mod != Py_None) { if (import_ensure_initialized(tstate->interp, mod, name) < 0) { + goto error; + } + /* Verify the module is still in sys.modules. Another thread may have + removed it (due to import failure) between our import_get_module() + call and the _initializing check in import_ensure_initialized(). */ + PyObject *mod_check = import_get_module(tstate, name); + if (mod_check != mod) { + Py_XDECREF(mod_check); + if (_PyErr_Occurred(tstate)) { + goto error; + } + /* The module was removed or replaced. Return NULL to report + "not found" rather than trying to keep up with racing + modifications to sys.modules; returning the new value would + require looping to redo the ensure_initialized check. */ Py_DECREF(mod); - remove_importlib_frames(tstate); return NULL; } + Py_DECREF(mod_check); } return mod; + +error: + Py_DECREF(mod); + remove_importlib_frames(tstate); + return NULL; } /* Get the module object corresponding to a module name. @@ -3897,6 +3917,27 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) { goto error; } + /* Verify the module is still in sys.modules. Another thread may have + removed it (due to import failure) between our import_get_module() + call and the _initializing check in import_ensure_initialized(). + If removed, we retry the import to preserve normal semantics: the + caller gets the exception from the actual import failure rather + than a synthetic error. */ + PyObject *mod_check = import_get_module(tstate, abs_name); + if (mod_check != mod) { + Py_XDECREF(mod_check); + if (_PyErr_Occurred(tstate)) { + goto error; + } + Py_DECREF(mod); + mod = import_find_and_load(tstate, abs_name); + if (mod == NULL) { + goto error; + } + } + else { + Py_DECREF(mod_check); + } } else { Py_XDECREF(mod); From 40a82abe9335e78e34ca564243499490e50b8888 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Tue, 10 Feb 2026 15:10:01 +0200 Subject: [PATCH 059/498] Clarify the docs for `args` in asyncio callbacks (#143873) Co-authored-by: Kumar Aditya --- Doc/library/asyncio-eventloop.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 72f484fd1cbe77..bdb24b3a58c267 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -297,8 +297,9 @@ clocks to track time. are called is undefined. The optional positional *args* will be passed to the callback when - it is called. If you want the callback to be called with keyword - arguments use :func:`functools.partial`. + it is called. Use :func:`functools.partial` + :ref:`to pass keyword arguments ` to + *callback*. An optional keyword-only *context* argument allows specifying a custom :class:`contextvars.Context` for the *callback* to run in. @@ -1034,8 +1035,8 @@ Watching file descriptors .. method:: loop.add_writer(fd, callback, *args) Start monitoring the *fd* file descriptor for write availability and - invoke *callback* with the specified arguments once *fd* is available for - writing. + invoke *callback* with the specified arguments *args* once *fd* is + available for writing. Any preexisting callback registered for *fd* is cancelled and replaced by *callback*. @@ -1308,7 +1309,8 @@ Unix signals .. method:: loop.add_signal_handler(signum, callback, *args) - Set *callback* as the handler for the *signum* signal. + Set *callback* as the handler for the *signum* signal, + passing *args* as positional arguments. The callback will be invoked by *loop*, along with other queued callbacks and runnable coroutines of that event loop. Unlike signal handlers @@ -1343,7 +1345,8 @@ Executing code in thread or process pools .. awaitablemethod:: loop.run_in_executor(executor, func, *args) - Arrange for *func* to be called in the specified executor. + Arrange for *func* to be called in the specified executor + passing *args* as positional arguments. The *executor* argument should be an :class:`concurrent.futures.Executor` instance. The default executor is used if *executor* is ``None``. From 6c8ca1c3783097b5db0fc40a7b625e2f7cc1fc5b Mon Sep 17 00:00:00 2001 From: Sacul <183588943+Sacul0457@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:33:32 +0800 Subject: [PATCH 060/498] gh-134584: Optimize `_BINARY_OP_SUBSCR_LIST_SLICE` (GH-144659) --- Include/internal/pycore_opcode_metadata.h | 4 +- Include/internal/pycore_uop_ids.h | 2 +- Include/internal/pycore_uop_metadata.h | 8 ++-- Lib/test/test_capi/test_opt.py | 17 +++++++++ ...-02-10-12-08-58.gh-issue-134584.P9LDy5.rst | 1 + Modules/_testinternalcapi/test_cases.c.h | 38 +++++++++++-------- Python/bytecodes.c | 12 ++++-- Python/executor_cases.c.h | 26 +++++-------- Python/generated_cases.c.h | 38 +++++++++++-------- Python/optimizer_bytecodes.c | 6 +++ Python/optimizer_cases.c.h | 16 ++++++-- 11 files changed, 108 insertions(+), 60 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 98d9c2b51a7834..4c1e7aebd0d291 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1103,7 +1103,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [BINARY_OP_SUBSCR_DICT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [BINARY_OP_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, - [BINARY_OP_SUBSCR_LIST_SLICE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_SUBSCR_LIST_SLICE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, [BINARY_OP_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_SUBSCR_USTR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, @@ -1356,7 +1356,7 @@ _PyOpcode_macro_expansion[256] = { [BINARY_OP_SUBSCR_DICT] = { .nuops = 4, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_GETITEM] = { .nuops = 5, .uops = { { _RECORD_NOS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, - [BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 3, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 } } }, + [BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 5, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_STR_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_COMPACT_ASCII, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_TUPLE_INT] = { .nuops = 6, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_TUPLE, OPARG_SIMPLE, 0 }, { _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_TUPLE_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_USTR_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_USTR_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index f9313621756b45..94b05b736ed277 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -414,7 +414,7 @@ extern "C" { #define _BINARY_OP_SUBSCR_INIT_CALL_r21 611 #define _BINARY_OP_SUBSCR_INIT_CALL_r31 612 #define _BINARY_OP_SUBSCR_LIST_INT_r23 613 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 614 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 614 #define _BINARY_OP_SUBSCR_STR_INT_r23 615 #define _BINARY_OP_SUBSCR_TUPLE_INT_r03 616 #define _BINARY_OP_SUBSCR_TUPLE_INT_r13 617 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 0835ee5c9499d1..5a47eae7a9abb1 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -119,7 +119,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_BINARY_OP_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, - [_BINARY_OP_SUBSCR_LIST_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_BINARY_OP_SUBSCR_LIST_SLICE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_BINARY_OP_SUBSCR_STR_INT] = HAS_DEOPT_FLAG, [_BINARY_OP_SUBSCR_USTR_INT] = HAS_DEOPT_FLAG, [_GUARD_NOS_TUPLE] = HAS_EXIT_FLAG, @@ -1159,7 +1159,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { .entries = { { -1, -1, -1 }, { -1, -1, -1 }, - { 1, 2, _BINARY_OP_SUBSCR_LIST_SLICE_r21 }, + { 3, 2, _BINARY_OP_SUBSCR_LIST_SLICE_r23 }, { -1, -1, -1 }, }, }, @@ -3702,7 +3702,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_BINARY_SLICE_r31] = _BINARY_SLICE, [_STORE_SLICE_r30] = _STORE_SLICE, [_BINARY_OP_SUBSCR_LIST_INT_r23] = _BINARY_OP_SUBSCR_LIST_INT, - [_BINARY_OP_SUBSCR_LIST_SLICE_r21] = _BINARY_OP_SUBSCR_LIST_SLICE, + [_BINARY_OP_SUBSCR_LIST_SLICE_r23] = _BINARY_OP_SUBSCR_LIST_SLICE, [_BINARY_OP_SUBSCR_STR_INT_r23] = _BINARY_OP_SUBSCR_STR_INT, [_BINARY_OP_SUBSCR_USTR_INT_r23] = _BINARY_OP_SUBSCR_USTR_INT, [_GUARD_NOS_TUPLE_r02] = _GUARD_NOS_TUPLE, @@ -4297,7 +4297,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_BINARY_OP_SUBSCR_LIST_INT] = "_BINARY_OP_SUBSCR_LIST_INT", [_BINARY_OP_SUBSCR_LIST_INT_r23] = "_BINARY_OP_SUBSCR_LIST_INT_r23", [_BINARY_OP_SUBSCR_LIST_SLICE] = "_BINARY_OP_SUBSCR_LIST_SLICE", - [_BINARY_OP_SUBSCR_LIST_SLICE_r21] = "_BINARY_OP_SUBSCR_LIST_SLICE_r21", + [_BINARY_OP_SUBSCR_LIST_SLICE_r23] = "_BINARY_OP_SUBSCR_LIST_SLICE_r23", [_BINARY_OP_SUBSCR_STR_INT] = "_BINARY_OP_SUBSCR_STR_INT", [_BINARY_OP_SUBSCR_STR_INT_r23] = "_BINARY_OP_SUBSCR_STR_INT_r23", [_BINARY_OP_SUBSCR_TUPLE_INT] = "_BINARY_OP_SUBSCR_TUPLE_INT", diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 765cb69dc04df1..2cad53d9c0728b 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3660,6 +3660,23 @@ def testfunc(n): self.assertLessEqual(count_ops(ex, "_POP_TOP_INT"), 1) self.assertIn("_POP_TOP_NOP", uops) + def test_binary_subscr_list_slice(self): + def testfunc(n): + x = 0 + for _ in range(n): + l = [1, 2, 3] + x += l[0:1][0] + return x + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + uops = get_opnames(ex) + + self.assertIn("_BINARY_OP_SUBSCR_LIST_SLICE", uops) + self.assertNotIn("_GUARD_TOS_LIST", uops) + self.assertEqual(count_ops(ex, "_POP_TOP"), 3) + self.assertEqual(count_ops(ex, "_POP_TOP_NOP"), 4) + def test_is_op(self): def test_is_false(n): a = object() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst new file mode 100644 index 00000000000000..fab50180bb6219 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst @@ -0,0 +1 @@ +Optimize and eliminate ref-counting in ``_BINARY_OP_SUBSCR_LIST_SLICE`` diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index dda3bc53dc5e0d..35b1bc4e17c5d5 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -892,6 +892,9 @@ _PyStackRef list_st; _PyStackRef sub_st; _PyStackRef res; + _PyStackRef ls; + _PyStackRef ss; + _PyStackRef value; // _GUARD_TOS_SLICE { tos = stack_pointer[-1]; @@ -925,26 +928,31 @@ PyObject *res_o = _PyList_SliceSubscript(list, sub); stack_pointer = _PyFrame_GetStackPointer(frame); STAT_INC(BINARY_OP, hit); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = sub_st; - sub_st = PyStackRef_NULL; - stack_pointer[-1] = sub_st; - PyStackRef_CLOSE(tmp); - tmp = list_st; - list_st = PyStackRef_NULL; - stack_pointer[-2] = list_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (res_o == NULL) { JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); + ls = list_st; + ss = sub_st; + } + // _POP_TOP + { + value = ss; + stack_pointer[-2] = res; + stack_pointer[-1] = ls; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _POP_TOP + { + value = ls; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer[0] = res; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); DISPATCH(); } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index bd22599aef725d..e1884ac38c016d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -938,9 +938,9 @@ dummy_func( } macro(BINARY_OP_SUBSCR_LIST_SLICE) = - _GUARD_TOS_SLICE + _GUARD_NOS_LIST + unused/5 + _BINARY_OP_SUBSCR_LIST_SLICE; + _GUARD_TOS_SLICE + _GUARD_NOS_LIST + unused/5 + _BINARY_OP_SUBSCR_LIST_SLICE + POP_TOP + POP_TOP; - op(_BINARY_OP_SUBSCR_LIST_SLICE, (list_st, sub_st -- res)) { + op(_BINARY_OP_SUBSCR_LIST_SLICE, (list_st, sub_st -- res, ls, ss)) { PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); @@ -949,9 +949,13 @@ dummy_func( PyObject *res_o = _PyList_SliceSubscript(list, sub); STAT_INC(BINARY_OP, hit); - DECREF_INPUTS(); - ERROR_IF(res_o == NULL); + if (res_o == NULL) { + ERROR_NO_POP(); + } res = PyStackRef_FromPyObjectSteal(res_o); + ls = list_st; + ss = sub_st; + INPUTS_DEAD(); } macro(BINARY_OP_SUBSCR_STR_INT) = diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index f8de66cbce3a9f..f976e150451d49 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5368,12 +5368,14 @@ break; } - case _BINARY_OP_SUBSCR_LIST_SLICE_r21: { + case _BINARY_OP_SUBSCR_LIST_SLICE_r23: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef sub_st; _PyStackRef list_st; _PyStackRef res; + _PyStackRef ls; + _PyStackRef ss; _PyStackRef _stack_item_0 = _tos_cache0; _PyStackRef _stack_item_1 = _tos_cache1; sub_st = _stack_item_1; @@ -5390,27 +5392,19 @@ PyObject *res_o = _PyList_SliceSubscript(list, sub); stack_pointer = _PyFrame_GetStackPointer(frame); STAT_INC(BINARY_OP, hit); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = sub_st; - sub_st = PyStackRef_NULL; - stack_pointer[-1] = sub_st; - PyStackRef_CLOSE(tmp); - tmp = list_st; - list_st = PyStackRef_NULL; - stack_pointer[-2] = list_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (res_o == NULL) { SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } res = PyStackRef_FromPyObjectSteal(res_o); + ls = list_st; + ss = sub_st; + _tos_cache2 = ss; + _tos_cache1 = ls; _tos_cache0 = res; - _tos_cache1 = PyStackRef_ZERO_BITS; - _tos_cache2 = PyStackRef_ZERO_BITS; - SET_CURRENT_CACHED_VALUES(1); + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 4cc9d9e03a545d..202bf5edcf09df 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -892,6 +892,9 @@ _PyStackRef list_st; _PyStackRef sub_st; _PyStackRef res; + _PyStackRef ls; + _PyStackRef ss; + _PyStackRef value; // _GUARD_TOS_SLICE { tos = stack_pointer[-1]; @@ -925,26 +928,31 @@ PyObject *res_o = _PyList_SliceSubscript(list, sub); stack_pointer = _PyFrame_GetStackPointer(frame); STAT_INC(BINARY_OP, hit); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = sub_st; - sub_st = PyStackRef_NULL; - stack_pointer[-1] = sub_st; - PyStackRef_CLOSE(tmp); - tmp = list_st; - list_st = PyStackRef_NULL; - stack_pointer[-2] = list_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (res_o == NULL) { JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); + ls = list_st; + ss = sub_st; + } + // _POP_TOP + { + value = ss; + stack_pointer[-2] = res; + stack_pointer[-1] = ls; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _POP_TOP + { + value = ls; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer[0] = res; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); DISPATCH(); } diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index e82770742a356c..7c928e6502a412 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -422,6 +422,12 @@ dummy_func(void) { ss = sub_st; } + op(_BINARY_OP_SUBSCR_LIST_SLICE, (list_st, sub_st -- res, ls, ss)) { + res = sym_new_type(ctx, &PyList_Type); + ls = list_st; + ss = sub_st; + } + op(_TO_BOOL, (value -- res)) { int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false); if (!already_bool) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index cc1d28f49442b4..24ae511ebcde31 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -957,11 +957,21 @@ } case _BINARY_OP_SUBSCR_LIST_SLICE: { + JitOptRef sub_st; + JitOptRef list_st; JitOptRef res; - res = sym_new_not_null(ctx); - CHECK_STACK_BOUNDS(-1); + JitOptRef ls; + JitOptRef ss; + sub_st = stack_pointer[-1]; + list_st = stack_pointer[-2]; + res = sym_new_type(ctx, &PyList_Type); + ls = list_st; + ss = sub_st; + CHECK_STACK_BOUNDS(1); stack_pointer[-2] = res; - stack_pointer += -1; + stack_pointer[-1] = ls; + stack_pointer[0] = ss; + stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); break; } From cc81707e406c49c63afc18048e1a221d796ce638 Mon Sep 17 00:00:00 2001 From: Nybblista <170842536+nybblista@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:38:24 +0300 Subject: [PATCH 061/498] gh-144629: Add test for the PyFunction_GetAnnotations() function (#144630) --- Lib/test/test_capi/test_function.py | 19 ++++++++++++++++++- Modules/_testcapi/function.c | 8 ++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_function.py b/Lib/test/test_capi/test_function.py index 9dca377e28ba42..c1a278e5d4da91 100644 --- a/Lib/test/test_capi/test_function.py +++ b/Lib/test/test_capi/test_function.py @@ -307,10 +307,27 @@ def function_without_closure(): ... _testcapi.function_get_closure(function_without_closure), (1, 2)) self.assertEqual(function_without_closure.__closure__, (1, 2)) + def test_function_get_annotations(self): + # Test PyFunction_GetAnnotations() + def normal(): + pass + + def annofn(arg: int) -> str: + return f'arg = {arg}' + + annotations = _testcapi.function_get_annotations(normal) + self.assertIsNone(annotations) + + annotations = _testcapi.function_get_annotations(annofn) + self.assertIsInstance(annotations, dict) + self.assertEqual(annotations, annofn.__annotations__) + + with self.assertRaises(SystemError): + _testcapi.function_get_annotations(None) + # TODO: test PyFunction_New() # TODO: test PyFunction_NewWithQualName() # TODO: test PyFunction_SetVectorcall() - # TODO: test PyFunction_GetAnnotations() # TODO: test PyFunction_SetAnnotations() # TODO: test PyClassMethod_New() # TODO: test PyStaticMethod_New() diff --git a/Modules/_testcapi/function.c b/Modules/_testcapi/function.c index ec1ba508df2ce9..40767adbd3f14a 100644 --- a/Modules/_testcapi/function.c +++ b/Modules/_testcapi/function.c @@ -123,6 +123,13 @@ function_set_closure(PyObject *self, PyObject *args) } +static PyObject * +function_get_annotations(PyObject *self, PyObject *func) +{ + return Py_XNewRef(PyFunction_GetAnnotations(func)); +} + + static PyMethodDef test_methods[] = { {"function_get_code", function_get_code, METH_O, NULL}, {"function_get_globals", function_get_globals, METH_O, NULL}, @@ -133,6 +140,7 @@ static PyMethodDef test_methods[] = { {"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL}, {"function_get_closure", function_get_closure, METH_O, NULL}, {"function_set_closure", function_set_closure, METH_VARARGS, NULL}, + {"function_get_annotations", function_get_annotations, METH_O, NULL}, {NULL}, }; From 3dadc22a2796af7718f1aec02e30f100ac6553bd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 10 Feb 2026 15:47:12 +0100 Subject: [PATCH 062/498] gh-141563: Add missing cast to _PyDateTime_IMPORT() (#144667) Fix compilation on C++. Add test on PyDateTime_IMPORT in test_cext and test_cppext. --- Include/datetime.h | 2 +- Lib/test/test_cext/extension.c | 20 ++++++++++++++++++++ Lib/test/test_cppext/extension.cpp | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Include/datetime.h b/Include/datetime.h index ed7e55009d2208..66e6c6e3ac3575 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -198,7 +198,7 @@ static PyDateTime_CAPI *PyDateTimeAPI = NULL; static inline PyDateTime_CAPI * _PyDateTime_IMPORT(void) { - PyDateTime_CAPI *val = _Py_atomic_load_ptr(&PyDateTimeAPI); + PyDateTime_CAPI *val = (PyDateTime_CAPI *)_Py_atomic_load_ptr(&PyDateTimeAPI); if (val == NULL) { PyDateTime_CAPI *capi = (PyDateTime_CAPI *)PyCapsule_Import( PyDateTime_CAPSULE_NAME, 0); diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c index 0f668c1da32d6e..20c2b6e89d8e17 100644 --- a/Lib/test/test_cext/extension.c +++ b/Lib/test/test_cext/extension.c @@ -11,6 +11,7 @@ #endif #include "Python.h" +#include "datetime.h" #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API. @@ -50,8 +51,21 @@ _testcext_add(PyObject *Py_UNUSED(module), PyObject *args) } +static PyObject * +test_datetime(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +{ + PyDateTime_IMPORT; + if (PyErr_Occurred()) { + return NULL; + } + + Py_RETURN_NONE; +} + + static PyMethodDef _testcext_methods[] = { {"add", _testcext_add, METH_VARARGS, _testcext_add_doc}, + {"test_datetime", test_datetime, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} // sentinel }; @@ -65,12 +79,18 @@ _testcext_exec( #endif ) { + PyObject *result; + #ifdef __STDC_VERSION__ if (PyModule_AddIntMacro(module, __STDC_VERSION__) < 0) { return -1; } #endif + result = PyObject_CallMethod(module, "test_datetime", ""); + if (!result) return -1; + Py_DECREF(result); + // test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR() Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int)); assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0); diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index b631ddad7201f0..51271250366429 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -11,6 +11,7 @@ #endif #include "Python.h" +#include "datetime.h" #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API @@ -228,11 +229,23 @@ test_virtual_object(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) Py_RETURN_NONE; } +static PyObject * +test_datetime(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +{ + PyDateTime_IMPORT; + if (PyErr_Occurred()) { + return NULL; + } + + Py_RETURN_NONE; +} + static PyMethodDef _testcppext_methods[] = { {"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc}, {"test_api_casts", test_api_casts, METH_NOARGS, _Py_NULL}, {"test_unicode", test_unicode, METH_NOARGS, _Py_NULL}, {"test_virtual_object", test_virtual_object, METH_NOARGS, _Py_NULL}, + {"test_datetime", test_datetime, METH_NOARGS, _Py_NULL}, // Note: _testcppext_exec currently runs all test functions directly. // When adding a new one, add a call there. @@ -261,6 +274,10 @@ _testcppext_exec(PyObject *module) if (!result) return -1; Py_DECREF(result); + result = PyObject_CallMethod(module, "test_datetime", ""); + if (!result) return -1; + Py_DECREF(result); + // test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR() Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int)); assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0); From 23d45f0c24ab4ed6fa9bf21ddced78650aa7ae30 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 10 Feb 2026 16:45:24 +0100 Subject: [PATCH 063/498] gh-141563: Don't test datetime.h with the limited C API (#144673) Fix test_cext and test_cppext. --- Lib/test/test_cext/extension.c | 3 +++ Lib/test/test_cppext/extension.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c index 20c2b6e89d8e17..28531b47383b85 100644 --- a/Lib/test/test_cext/extension.c +++ b/Lib/test/test_cext/extension.c @@ -54,10 +54,13 @@ _testcext_add(PyObject *Py_UNUSED(module), PyObject *args) static PyObject * test_datetime(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) { + // datetime.h is excluded from the limited C API +#ifndef Py_LIMITED_API PyDateTime_IMPORT; if (PyErr_Occurred()) { return NULL; } +#endif Py_RETURN_NONE; } diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index 51271250366429..7d360f88fdd1f1 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -232,10 +232,13 @@ test_virtual_object(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) static PyObject * test_datetime(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) { + // datetime.h is excluded from the limited C API +#ifndef Py_LIMITED_API PyDateTime_IMPORT; if (PyErr_Occurred()) { return NULL; } +#endif Py_RETURN_NONE; } From b4a620d2d74ce6aef9c9a404353c701ca8d45028 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:49:20 +0200 Subject: [PATCH 064/498] gh-133879: Copyedit "What's new in Python 3.15" (#144661) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/profiling.rst | 14 +++--- Doc/whatsnew/3.15.rst | 89 ++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/Doc/library/profiling.rst b/Doc/library/profiling.rst index 0df9a5120a5df0..9b58cae28ab781 100644 --- a/Doc/library/profiling.rst +++ b/Doc/library/profiling.rst @@ -63,7 +63,7 @@ Choosing a profiler For most performance analysis, use the statistical profiler (:mod:`profiling.sampling`). It has minimal overhead, works for both development -and production, and provides rich visualization options including flamegraphs, +and production, and provides rich visualization options including flame graphs, heatmaps, GIL analysis, and more. Use the deterministic profiler (:mod:`profiling.tracing`) when you need **exact @@ -81,7 +81,7 @@ The following table summarizes the key differences: +--------------------+------------------------------+------------------------------+ | **Accuracy** | Statistical estimate | Exact call counts | +--------------------+------------------------------+------------------------------+ -| **Output formats** | pstats, flamegraph, heatmap, | pstats | +| **Output formats** | pstats, flame graph, heatmap,| pstats | | | gecko, collapsed | | +--------------------+------------------------------+------------------------------+ | **Profiling modes**| Wall-clock, CPU, GIL | Wall-clock | @@ -103,7 +103,7 @@ performance analysis tasks. Use it the same way you would use One of the main strengths of the sampling profiler is its variety of output formats. Beyond traditional pstats tables, it can generate interactive -flamegraphs that visualize call hierarchies, line-level source heatmaps that +flame graphs that visualize call hierarchies, line-level source heatmaps that show exactly where time is spent in your code, and Firefox Profiler output for timeline-based analysis. @@ -157,7 +157,7 @@ command:: python -m profiling.sampling run -m mypackage.module This runs the script under the profiler and prints a summary of where time was -spent. For an interactive flamegraph:: +spent. For an interactive flame graph:: python -m profiling.sampling run --flamegraph script.py @@ -197,7 +197,7 @@ Understanding profile output Both profilers collect function-level statistics, though they present them in different formats. The sampling profiler offers multiple visualizations -(flamegraphs, heatmaps, Firefox Profiler, pstats tables), while the +(flame graphs, heatmaps, Firefox Profiler, pstats tables), while the deterministic profiler produces pstats-compatible output. Regardless of format, the underlying concepts are the same. @@ -226,7 +226,7 @@ Key profiling concepts: **Caller/Callee relationships** Which functions called a given function (callers) and which functions it - called (callees). Flamegraphs visualize this as nested rectangles; pstats + called (callees). Flame graphs visualize this as nested rectangles; pstats can display it via the :meth:`~pstats.Stats.print_callers` and :meth:`~pstats.Stats.print_callees` methods. @@ -248,7 +248,7 @@ continue to work without modification in all future Python versions. .. seealso:: :mod:`profiling.sampling` - Statistical sampling profiler with flamegraphs, heatmaps, and GIL analysis. + Statistical sampling profiler with flame graphs, heatmaps, and GIL analysis. Recommended for most users. :mod:`profiling.tracing` diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 68fa10b0c08d17..7ab549475152a9 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -68,7 +68,7 @@ Summary -- Release highlights * :pep:`799`: :ref:`A dedicated profiling package for organizing Python profiling tools ` * :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler - profiling tools ` + ` * :pep:`798`: :ref:`Unpacking in Comprehensions ` * :pep:`686`: :ref:`Python now uses UTF-8 as the default encoding @@ -161,13 +161,13 @@ Key features include: timing with direct and cumulative samples. Best for detailed analysis and integration with existing Python profiling tools. * ``--collapsed``: Generates collapsed stack traces (one line per stack). This format is - specifically designed for creating flamegraphs with external tools like Brendan Gregg's + specifically designed for creating flame graphs with external tools like Brendan Gregg's FlameGraph scripts or speedscope. - * ``--flamegraph``: Generates a self-contained interactive HTML flamegraph using D3.js. - Opens directly in your browser for immediate visual analysis. Flamegraphs show the call + * ``--flamegraph``: Generates a self-contained interactive HTML flame graph using D3.js. + Opens directly in your browser for immediate visual analysis. Flame graphs show the call hierarchy where width represents time spent, making it easy to spot bottlenecks at a glance. - * ``--gecko``: Generates Gecko Profiler format compatible with Firefox Profiler - (https://profiler.firefox.com). Upload the output to Firefox Profiler for advanced + * ``--gecko``: Generates Gecko Profiler format compatible with `Firefox Profiler + `__. Upload the output to Firefox Profiler for advanced timeline-based analysis with features like stack charts, markers, and network activity. * ``--heatmap``: Generates an interactive HTML heatmap visualization with line-level sample counts. Creates a directory with per-file heatmaps showing exactly where time is spent @@ -189,6 +189,7 @@ available output formats, profiling modes, and configuration options. (Contributed by Pablo Galindo and László Kiss Kollár in :gh:`135953` and :gh:`138122`.) + .. _whatsnew315-unpacking-in-comprehensions: :pep:`798`: Unpacking in Comprehensions @@ -229,6 +230,7 @@ agen() for x in a)``. (Contributed by Adam Hartz in :gh:`143055`.) + .. _whatsnew315-improved-error-messages: Improved error messages @@ -447,6 +449,7 @@ Other language changes making it a :term:`generic type`. (Contributed by James Hilton-Balfe in :gh:`128335`.) + New modules =========== @@ -476,6 +479,7 @@ argparse inline code when color output is enabled. (Contributed by Savannah Ostrowski in :gh:`142390`.) + base64 ------ @@ -488,6 +492,7 @@ base64 * Added the *ignorechars* parameter in :func:`~base64.b64decode`. (Contributed by Serhiy Storchaka in :gh:`144001`.) + binascii -------- @@ -526,6 +531,7 @@ collections between :class:`~collections.Counter` objects. (Contributed by Raymond Hettinger in :gh:`138682`.) + collections.abc --------------- @@ -581,7 +587,6 @@ dbm (Contributed by Andrea Oliveri in :gh:`134004`.) - difflib ------- @@ -667,8 +672,10 @@ math mimetypes --------- -* Add ``application/dicom`` MIME type for ``.dcm`` extension. (Contributed by Benedikt Johannes in :gh:`144217`.) -* Add ``application/node`` MIME type for ``.cjs`` extension. (Contributed by John Franey in :gh:`140937`.) +* Add ``application/dicom`` MIME type for ``.dcm`` extension. + (Contributed by Benedikt Johannes in :gh:`144217`.) +* Add ``application/node`` MIME type for ``.cjs`` extension. + (Contributed by John Franey in :gh:`140937`.) * Add ``application/toml``. (Contributed by Gil Forcada in :gh:`139959`.) * Add ``image/jxl``. (Contributed by Foolbar in :gh:`144213`.) * Rename ``application/x-texinfo`` to ``application/texinfo``. @@ -748,16 +755,16 @@ sqlite3 * The :ref:`command-line interface ` has several new features: - * SQL keyword completion on . - (Contributed by Long Tan in :gh:`133393`.) + * SQL keyword completion on . + (Contributed by Long Tan in :gh:`133393`.) - * Prompts, error messages, and help text are now colored. - This is enabled by default, see :ref:`using-on-controlling-color` for - details. - (Contributed by Stan Ulbrych and Łukasz Langa in :gh:`133461`.) + * Prompts, error messages, and help text are now colored. + This is enabled by default, see :ref:`using-on-controlling-color` for + details. + (Contributed by Stan Ulbrych and Łukasz Langa in :gh:`133461`.) - * Table, index, trigger, view, column, function, and schema completion on . - (Contributed by Long Tan in :gh:`136101`.) + * Table, index, trigger, view, column, function, and schema completion on . + (Contributed by Long Tan in :gh:`136101`.) ssl @@ -769,21 +776,21 @@ ssl * Added new methods for managing groups used for SSL key agreement - * :meth:`ssl.SSLContext.set_groups` sets the groups allowed for doing - key agreement, extending the previous - :meth:`ssl.SSLContext.set_ecdh_curve` method. - This new API provides the ability to list multiple groups and - supports fixed-field and post-quantum groups in addition to ECDH - curves. This method can also be used to control what key shares - are sent in the TLS handshake. - * :meth:`ssl.SSLSocket.group` returns the group selected for doing key - agreement on the current connection after the TLS handshake completes. - This call requires OpenSSL 3.2 or later. - * :meth:`ssl.SSLContext.get_groups` returns a list of all available key - agreement groups compatible with the minimum and maximum TLS versions - currently set in the context. This call requires OpenSSL 3.5 or later. - - (Contributed by Ron Frederick in :gh:`136306`.) + * :meth:`ssl.SSLContext.set_groups` sets the groups allowed for doing + key agreement, extending the previous + :meth:`ssl.SSLContext.set_ecdh_curve` method. + This new API provides the ability to list multiple groups and + supports fixed-field and post-quantum groups in addition to ECDH + curves. This method can also be used to control what key shares + are sent in the TLS handshake. + * :meth:`ssl.SSLSocket.group` returns the group selected for doing key + agreement on the current connection after the TLS handshake completes. + This call requires OpenSSL 3.2 or later. + * :meth:`ssl.SSLContext.get_groups` returns a list of all available key + agreement groups compatible with the minimum and maximum TLS versions + currently set in the context. This call requires OpenSSL 3.5 or later. + + (Contributed by Ron Frederick in :gh:`136306`.) * Added a new method :meth:`ssl.SSLContext.set_ciphersuites` for setting TLS 1.3 ciphers. For TLS 1.2 or earlier, :meth:`ssl.SSLContext.set_ciphers` should @@ -807,7 +814,8 @@ ssl selected for the server to complete the TLS handshake on the current connection. This call requires OpenSSL 3.5 or later. - (Contributed by Ron Frederick in :gh:`138252`.) + (Contributed by Ron Frederick in :gh:`138252`.) + subprocess ---------- @@ -824,6 +832,7 @@ subprocess traditional busy loop (non-blocking call and short sleeps). (Contributed by Giampaolo Rodola in :gh:`83069`). + symtable -------- @@ -879,18 +888,18 @@ tkinter arguments: *nolinestop* which allows the search to continue across line boundaries; and *strictlimits* which restricts the search to within the specified range. - (Contributed by Rihaan Meher in :gh:`130848`) + (Contributed by Rihaan Meher in :gh:`130848`.) * A new method :meth:`!tkinter.Text.search_all` has been introduced. This method allows for searching for all matches of a pattern using Tcl's ``-all`` and ``-overlap`` options. - (Contributed by Rihaan Meher in :gh:`130848`) + (Contributed by Rihaan Meher in :gh:`130848`.) * Added new methods :meth:`!pack_content`, :meth:`!place_content` and :meth:`!grid_content` which use Tk commands with new names (introduced in Tk 8.6) instead of :meth:`!*_slaves` methods which use Tk commands with outdated names. - (Contributed by Serhiy Storchaka in :gh:`143754`) + (Contributed by Serhiy Storchaka in :gh:`143754`.) .. _whatsnew315-tomllib-1-1-0: @@ -1060,6 +1069,7 @@ Optimizations (Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`. Special thanks to the MSVC team including Hulon Jenkins.) + base64 & binascii ----------------- @@ -1072,6 +1082,7 @@ base64 & binascii two orders of magnitude less memory. (Contributed by James Seo and Serhiy Storchaka in :gh:`101178`.) + csv --- @@ -1202,7 +1213,7 @@ importlib.resources * Removed deprecated ``package`` parameter from :func:`importlib.resources.files` function. - (Contributed by Semyon Moroz in :gh:`138044`) + (Contributed by Semyon Moroz in :gh:`138044`.) pathlib @@ -1453,7 +1464,7 @@ Changed C APIs * If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` or :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` flag is set then :c:macro:`Py_TPFLAGS_HAVE_GC` must be set too. - (Contributed by Sergey Miryanov in :gh:`134786`) + (Contributed by Sergey Miryanov in :gh:`134786`.) Porting to Python 3.15 @@ -1610,7 +1621,7 @@ Build changes :manpage:`PR_SET_VMA_ANON_NAME ` (Linux 5.17 or newer). Annotations are visible in ``/proc//maps`` if the kernel supports the feature and :option:`-X dev <-X>` is passed to the Python or Python is built in :ref:`debug mode `. - (Contributed by Donghee Na in :gh:`141770`) + (Contributed by Donghee Na in :gh:`141770`.) Porting to Python 3.15 From eb6d0e0b2b9f1cc36fb2b7e396bf3100214b3e09 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 10 Feb 2026 18:27:44 +0100 Subject: [PATCH 065/498] gh-141563: Fix test_cext on Windows (#144677) The 'module' argument is now always needed to call the test_datetime method. --- Lib/test/test_cext/extension.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c index 28531b47383b85..a2f6151d8b36ed 100644 --- a/Lib/test/test_cext/extension.c +++ b/Lib/test/test_cext/extension.c @@ -74,13 +74,7 @@ static PyMethodDef _testcext_methods[] = { static int -_testcext_exec( -#ifdef __STDC_VERSION__ - PyObject *module -#else - PyObject *Py_UNUSED(module) -#endif - ) +_testcext_exec(PyObject *module) { PyObject *result; From b67a64d7e277b6ab7b4d77e12f35c58b64f55e65 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 10 Feb 2026 20:31:12 +0100 Subject: [PATCH 066/498] gh-141563: Fix test_cppext on macOS (#144685) Don't test internal header files including mimalloc on macOS since mimalloc emits compiler warnings: In file included from extension.cpp:21: In file included from Include/internal/pycore_backoff.h:15: In file included from Include/internal/pycore_interp_structs.h:15: In file included from Include/internal/pycore_tstate.h:14: In file included from Include/internal/pycore_mimalloc.h:43: Include/internal/mimalloc/mimalloc.h:464:85: error: defaulted function definitions are a C++11 extension [-Werror,-Wc++11-extensions] mi_stl_allocator() mi_attr_noexcept = default; ^ Include/internal/mimalloc/mimalloc.h:465:85: error: defaulted function definitions are a C++11 extension [-Werror,-Wc++11-extensions] mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default; Log also CXX and CXXFLAGS env vars in test_cppext. Log also CPPFLAGS in test_cext. --- Lib/test/test_cext/setup.py | 2 +- Lib/test/test_cppext/extension.cpp | 5 +++-- Lib/test/test_cppext/setup.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_cext/setup.py b/Lib/test/test_cext/setup.py index 67dfddec751791..db43f6fb17a132 100644 --- a/Lib/test/test_cext/setup.py +++ b/Lib/test/test_cext/setup.py @@ -118,7 +118,7 @@ def main(): print(f"Add PCbuild directory: {pcbuild}") # Display information to help debugging - for env_name in ('CC', 'CFLAGS'): + for env_name in ('CC', 'CFLAGS', 'CPPFLAGS'): if env_name in os.environ: print(f"{env_name} env var: {os.environ[env_name]!r}") else: diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index 7d360f88fdd1f1..06ef997d57af46 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -16,8 +16,9 @@ #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API # include "internal/pycore_frame.h" - // mimalloc emits compiler warnings when Python is built on Windows. -# if !defined(MS_WINDOWS) + // mimalloc emits compiler warnings when Python is built on Windows + // and macOS. +# if !defined(MS_WINDOWS) && !defined(__APPLE__) # include "internal/pycore_backoff.h" # include "internal/pycore_cell.h" # endif diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py index 98442b106b6113..a3eec1c67e1556 100644 --- a/Lib/test/test_cppext/setup.py +++ b/Lib/test/test_cppext/setup.py @@ -101,7 +101,7 @@ def main(): print(f"Add PCbuild directory: {pcbuild}") # Display information to help debugging - for env_name in ('CC', 'CFLAGS', 'CPPFLAGS'): + for env_name in ('CC', 'CXX', 'CFLAGS', 'CPPFLAGS', 'CXXFLAGS'): if env_name in os.environ: print(f"{env_name} env var: {os.environ[env_name]!r}") else: From 87c9789b9a067caf84a0e70093c798525732f8a1 Mon Sep 17 00:00:00 2001 From: Dov Murik Date: Tue, 10 Feb 2026 16:55:40 -0500 Subject: [PATCH 067/498] docs: profiling.sampling: Fix sampling-rate default value description typo (#144686) --- Doc/library/profiling.sampling.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/profiling.sampling.rst b/Doc/library/profiling.sampling.rst index ac1098698c8cbb..87e431969393b6 100644 --- a/Doc/library/profiling.sampling.rst +++ b/Doc/library/profiling.sampling.rst @@ -354,7 +354,7 @@ Together, these determine how many samples will be collected during a profiling session. The :option:`--sampling-rate` option (:option:`-r`) sets how frequently samples -are collected. The default is 1 kHz (10,000 samples per second):: +are collected. The default is 1 kHz (1,000 samples per second):: python -m profiling.sampling run -r 20khz script.py From d18dbd5e1ce6ca43b559450bab312ded1117d746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Kiss=20Koll=C3=A1r?= Date: Tue, 10 Feb 2026 23:09:07 +0000 Subject: [PATCH 068/498] gh-138122: Add sampling profiler visualisation to docs (#142772) Co-authored-by: Pablo Galindo Salgado --- .../profiling-sampling-visualization.css | 570 ++++++++ .../profiling-sampling-visualization.js | 1163 +++++++++++++++++ Doc/conf.py | 1 + .../profiling-sampling-visualization.html | 1 + Doc/library/profiling.sampling.rst | 17 + Doc/tools/extensions/profiling_trace.py | 166 +++ 6 files changed, 1918 insertions(+) create mode 100644 Doc/_static/profiling-sampling-visualization.css create mode 100644 Doc/_static/profiling-sampling-visualization.js create mode 100644 Doc/library/profiling-sampling-visualization.html create mode 100644 Doc/tools/extensions/profiling_trace.py diff --git a/Doc/_static/profiling-sampling-visualization.css b/Doc/_static/profiling-sampling-visualization.css new file mode 100644 index 00000000000000..6bfbec3b8a6044 --- /dev/null +++ b/Doc/_static/profiling-sampling-visualization.css @@ -0,0 +1,570 @@ +/** + * Sampling Profiler Visualization - Scoped CSS + */ + +.sampling-profiler-viz { + /* Match docs background colors */ + --bg-page: #ffffff; + --bg-panel: #ffffff; + --bg-subtle: #f8f8f8; + --bg-code: #f8f8f8; + + /* Match docs border style */ + --border-color: #e1e4e8; + --border-accent: #3776ab; + + /* Match docs text colors */ + --text-primary: #0d0d0d; + --text-secondary: #505050; + --text-muted: #6e6e6e; + --text-code: #333333; + + /* Accent colors */ + --color-python-blue: #306998; + --color-green: #388e3c; + --color-orange: #e65100; + --color-purple: #7b1fa2; + --color-red: #c62828; + --color-teal: #00897b; + --color-yellow: #d4a910; + --color-highlight: #fff9e6; + + --radius-lg: 8px; + --radius-md: 6px; + --radius-sm: 4px; + + /* Lighter shadows to match docs style */ + --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.08); + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04); + + --container-height: 520px; + --code-panel-width: 320px; + + /* Reset for isolation */ + font-family: var(--font-ui); + line-height: 1.5; + font-weight: 400; + color: var(--text-primary); + background-color: var(--bg-page); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* Layout */ + position: relative; + width: 100%; + max-width: 920px; + height: var(--container-height); + display: grid; + grid-template-columns: var(--code-panel-width) 1fr; + margin: 24px auto; + border-radius: var(--radius-lg); + overflow: hidden; + box-shadow: var(--shadow-card); + border: 1px solid var(--border-color); + background: var(--bg-panel); + /* Prevent any DOM changes inside from affecting page scroll */ + contain: strict; +} + +.sampling-profiler-viz * { + box-sizing: border-box; +} + +/* Code Panel - Left Column */ +.sampling-profiler-viz #code-panel { + background: var(--bg-panel); + border-right: 1px solid var(--border-color); + overflow-y: auto; + font-family: var(--font-mono); + font-size: 12px; + line-height: 1.6; + display: flex; + flex-direction: column; +} + +.sampling-profiler-viz #code-panel .code-panel-title { + padding: 12px 16px; + font-size: 10px; + font-weight: 600; + color: var(--text-muted); + border-bottom: 1px solid var(--border-color); + background: var(--bg-code); + text-transform: uppercase; + letter-spacing: 1px; + flex-shrink: 0; +} + +.sampling-profiler-viz #code-panel .code-container { + margin: 0; + padding: 12px 0; + overflow-x: auto; + flex: 1; +} + +.sampling-profiler-viz #code-panel .line { + display: flex; + padding: 1px 0; + min-height: 20px; + transition: background-color 0.1s ease; +} + +.sampling-profiler-viz #code-panel .line-number { + color: var(--text-muted); + min-width: 40px; + text-align: right; + padding-right: 12px; + padding-left: 12px; + user-select: none; + flex-shrink: 0; + font-size: 11px; +} + +.sampling-profiler-viz #code-panel .line-content { + flex: 1; + color: var(--text-code); + padding-right: 12px; + white-space: pre; +} + +.sampling-profiler-viz #code-panel .line.highlighted { + background: var(--color-highlight); + border-left: 3px solid var(--color-yellow); +} + +.sampling-profiler-viz #code-panel .line.highlighted .line-number { + color: var(--color-yellow); + padding-left: 9px; +} + +.sampling-profiler-viz #code-panel .line.highlighted .line-content { + font-weight: 600; +} + +/* Python Syntax Highlighting */ +.sampling-profiler-viz #code-panel .keyword { + color: var(--color-red); + font-weight: 600; +} + +.sampling-profiler-viz #code-panel .function { + color: var(--color-purple); + font-weight: 600; +} + +.sampling-profiler-viz #code-panel .number { + color: var(--color-python-blue); +} + +.sampling-profiler-viz #code-panel .string { + color: #032f62; +} + +.sampling-profiler-viz #code-panel .comment { + color: #6a737d; + font-style: italic; +} + +.sampling-profiler-viz #code-panel .builtin { + color: var(--color-python-blue); +} + +/* Visualization Column - Right Side */ +.sampling-profiler-viz .viz-column { + display: flex; + flex-direction: column; + background: var(--bg-subtle); + overflow: hidden; +} + +/* Stack Section */ +.sampling-profiler-viz .stack-section { + padding: 12px 16px; + flex: 1; + min-height: 150px; + overflow-y: auto; +} + +.sampling-profiler-viz .stack-section-title { + font-size: 10px; + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 1px; + margin-bottom: 10px; +} + +.sampling-profiler-viz .stack-visualization { + display: flex; + flex-direction: column; + gap: 4px; + min-height: 80px; +} + +/* Stack Frames - Vertical Layout */ +.sampling-profiler-viz .stack-frame { + position: relative; + width: 100%; + height: 32px; + cursor: pointer; + contain: layout style paint; + opacity: 0; + transform: translateY(-10px); +} + +.sampling-profiler-viz .stack-frame.visible { + opacity: 1; + transform: translateY(0); + transition: + opacity 0.3s ease, + transform 0.3s ease; +} + +.sampling-profiler-viz .stack-frame-bg { + position: absolute; + inset: 0; + border-radius: var(--radius-sm); + transition: opacity 0.15s; +} + +.sampling-profiler-viz .stack-frame-text { + position: absolute; + left: 10px; + top: 50%; + transform: translateY(-50%); + font: 500 11px var(--font-mono); + color: white; + pointer-events: none; +} + +.sampling-profiler-viz .stack-frame-flash { + position: absolute; + inset: 0; + background: white; + border-radius: var(--radius-sm); + opacity: 0; + pointer-events: none; +} + +.sampling-profiler-viz .stack-frame:hover .stack-frame-bg { + opacity: 0.85; +} + +/* Flying frames */ +.sampling-profiler-viz .stack-frame.flying { + pointer-events: none; + z-index: 1000; + position: fixed; + top: 0; + left: 0; + width: auto; + height: 32px; + opacity: 1; +} + +/* Flying stack clone */ +.stack-visualization.flying-clone { + transform-origin: center center; + will-change: transform, opacity; +} + +/* Sampling Panel */ +.sampling-profiler-viz .sampling-panel { + margin: 0 16px 12px 16px; + background: var(--bg-panel); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + box-shadow: var(--shadow-sm); + overflow: hidden; + display: flex; + flex-direction: column; + flex: 0 0 auto; + height: 200px; + /* Lock font size to prevent Sphinx responsive scaling */ + font-size: 12px; +} + +.sampling-profiler-viz .sampling-header { + padding: 8px 10px; + border-bottom: 1px solid var(--border-color); + flex-shrink: 0; +} + +.sampling-profiler-viz .sampling-title { + font: 600 10px var(--font-mono); + color: var(--text-primary); + margin: 0 0 3px 0; +} + +.sampling-profiler-viz .sampling-stats { + font: 400 9px var(--font-mono); + color: var(--text-secondary); + display: flex; + gap: 12px; +} + +.sampling-profiler-viz .sampling-stats .missed { + color: var(--color-red); +} + +.sampling-profiler-viz .sampling-bars { + flex: 1; + padding: 10px 12px; + overflow-y: auto; +} + +.sampling-profiler-viz .sampling-bar-row { + display: flex; + align-items: center; + height: 22px; + gap: 8px; +} + +.sampling-profiler-viz .bar-label { + font: 500 8px var(--font-mono); + color: var(--text-primary); + flex-shrink: 0; + width: 60px; + overflow: hidden; + text-overflow: ellipsis; +} + +.sampling-profiler-viz .bar-container { + flex: 1; + height: 12px; + background: var(--border-color); + border-radius: 3px; + position: relative; + overflow: hidden; +} + +.sampling-profiler-viz .bar-fill { + height: 100%; + border-radius: 3px; + transition: width 0.2s ease; + min-width: 2px; +} + +.sampling-profiler-viz .bar-percent { + font: 500 8px var(--font-mono); + color: var(--text-secondary); + width: 36px; + text-align: right; + flex-shrink: 0; +} + +/* Impact effect circle */ +.impact-circle { + position: fixed; + width: 30px; + height: 30px; + border-radius: 50%; + background: var(--color-teal); + transform: translate(-50%, -50%); + pointer-events: none; + z-index: 2000; +} + +/* Control Panel - Integrated */ +.sampling-profiler-viz #control-panel { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 16px; + background: var(--bg-panel); + border-top: 1px solid var(--border-color); + flex-shrink: 0; + flex-wrap: wrap; +} + +.sampling-profiler-viz .control-group { + display: flex; + gap: 6px; + align-items: center; +} + +.sampling-profiler-viz .control-group label { + font-size: 10px; + color: var(--text-muted); + font-weight: 500; + white-space: nowrap; +} + +.sampling-profiler-viz .control-btn { + background: var(--bg-panel); + color: var(--text-primary); + border: 1px solid var(--border-color); + padding: 6px 10px; + border-radius: var(--radius-sm); + cursor: pointer; + transition: all 0.15s ease; + font-family: var(--font-mono); + font-size: 11px; + font-weight: 500; + display: flex; + align-items: center; + gap: 4px; +} + +.sampling-profiler-viz .control-btn:hover { + background: var(--bg-subtle); + border-color: var(--text-muted); +} + +.sampling-profiler-viz .control-btn:active { + transform: scale(0.98); +} + +.sampling-profiler-viz .control-btn.active { + background: var(--color-python-blue); + color: white; + border-color: var(--color-python-blue); +} + +.sampling-profiler-viz .control-btn.active:hover { + background: #2f6493; +} + +/* Timeline Scrubber */ +.sampling-profiler-viz .timeline-scrubber { + flex: 1; + display: flex; + align-items: center; + gap: 8px; + min-width: 160px; +} + +.sampling-profiler-viz #timeline-scrubber { + flex: 1; + height: 5px; + border-radius: 3px; + background: var(--border-color); + outline: none; + appearance: none; + -webkit-appearance: none; + cursor: pointer; + min-width: 60px; +} + +.sampling-profiler-viz #timeline-scrubber::-webkit-slider-thumb { + -webkit-appearance: none; + width: 14px; + height: 14px; + border-radius: 50%; + background: var(--color-python-blue); + cursor: pointer; + transition: transform 0.15s; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); +} + +.sampling-profiler-viz #timeline-scrubber::-webkit-slider-thumb:hover { + transform: scale(1.15); +} + +.sampling-profiler-viz #timeline-scrubber::-moz-range-thumb { + width: 14px; + height: 14px; + border-radius: 50%; + background: var(--color-python-blue); + cursor: pointer; + border: none; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); +} + +.sampling-profiler-viz #time-display { + font: 500 10px var(--font-mono); + color: var(--text-secondary); + min-width: 90px; + text-align: right; + font-variant-numeric: tabular-nums; +} + +/* Sample Interval Slider */ +.sampling-profiler-viz #sample-interval { + width: 80px; + height: 4px; + border-radius: 2px; + background: var(--border-color); + outline: none; + appearance: none; + -webkit-appearance: none; + cursor: pointer; + flex-shrink: 0; +} + +.sampling-profiler-viz #sample-interval::-webkit-slider-thumb { + -webkit-appearance: none; + width: 12px; + height: 12px; + border-radius: 50%; + background: var(--color-teal); + cursor: pointer; + transition: transform 0.15s; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +} + +.sampling-profiler-viz #sample-interval::-webkit-slider-thumb:hover { + transform: scale(1.15); +} + +.sampling-profiler-viz #sample-interval::-moz-range-thumb { + width: 12px; + height: 12px; + border-radius: 50%; + background: var(--color-teal); + cursor: pointer; + border: none; +} + +.sampling-profiler-viz #interval-display { + font: 500 9px var(--font-mono); + color: var(--text-secondary); + min-width: 40px; + font-variant-numeric: tabular-nums; +} + +/* Flash overlay */ +.sampling-profiler-viz .flash-overlay { + position: absolute; + inset: 0; + background: white; + pointer-events: none; + opacity: 0; +} + +/* Performance optimizations */ +.sampling-profiler-viz .stack-frame, +.sampling-profiler-viz .flying-frame, +.sampling-profiler-viz .sampling-bar-row { + will-change: transform, opacity; + contain: layout style paint; +} + +/* Reduced motion support */ +@media (prefers-reduced-motion: reduce) { + .sampling-profiler-viz .stack-frame, + .sampling-profiler-viz .flying-frame, + .sampling-profiler-viz .sampling-bar-row, + .impact-circle { + animation-duration: 0.01ms !important; + transition-duration: 0.01ms !important; + } +} + +/* Responsive adjustments for narrower viewports */ +@media (max-width: 800px) { + .sampling-profiler-viz { + grid-template-columns: 280px 1fr; + --container-height: 550px; + } + + .sampling-profiler-viz #code-panel { + font-size: 11px; + } + + .sampling-profiler-viz .control-btn { + padding: 5px 8px; + font-size: 10px; + } +} diff --git a/Doc/_static/profiling-sampling-visualization.js b/Doc/_static/profiling-sampling-visualization.js new file mode 100644 index 00000000000000..3729be6795c1c8 --- /dev/null +++ b/Doc/_static/profiling-sampling-visualization.js @@ -0,0 +1,1163 @@ +/** + * Sampling Profiler Visualization + */ +(function () { + "use strict"; + + // ============================================================================ + // Configuration + // ============================================================================ + + const TIMINGS = { + sampleIntervalMin: 100, + sampleIntervalMax: 500, + sampleIntervalDefault: 200, + sampleToFlame: 600, + defaultSpeed: 0.05, + }; + + const LAYOUT = { frameSpacing: 6 }; + + // Function name to color mapping + const FUNCTION_COLORS = { + main: "#306998", + fibonacci: "#D4A910", + add: "#E65100", + multiply: "#7B1FA2", + calculate: "#D4A910", + }; + const DEFAULT_FUNCTION_COLOR = "#306998"; + + // Easing functions - cubic-bezier approximations + const EASING_MAP = { + linear: "linear", + easeOutQuad: "cubic-bezier(0.25, 0.46, 0.45, 0.94)", + easeOutCubic: "cubic-bezier(0.215, 0.61, 0.355, 1)", + }; + + function getFunctionColor(funcName) { + return FUNCTION_COLORS[funcName] || DEFAULT_FUNCTION_COLOR; + } + + // ============================================================================ + // Animation Manager + // ============================================================================ + + class AnimationManager { + constructor() { + this.activeAnimations = new Set(); + } + + to(element, props, duration, easing = "easeOutQuad", onComplete = null) { + this.killAnimationsOf(element); + + const cssEasing = EASING_MAP[easing] || EASING_MAP.easeOutQuad; + + const transformProps = {}; + const otherProps = {}; + + for (const [key, value] of Object.entries(props)) { + if (key === "position") { + if (typeof value.x === "number") transformProps.x = value.x; + if (typeof value.y === "number") transformProps.y = value.y; + } else if (key === "x" || key === "y") { + transformProps[key] = value; + } else if (key === "scale") { + transformProps.scale = value; + } else if (key === "alpha" || key === "opacity") { + otherProps.opacity = value; + } else { + otherProps[key] = value; + } + } + + const computedStyle = getComputedStyle(element); + const matrix = new DOMMatrix(computedStyle.transform); + const currentScale = Math.sqrt( + matrix.m11 * matrix.m11 + matrix.m21 * matrix.m21, + ); + + transformProps.x ??= matrix.m41; + transformProps.y ??= matrix.m42; + transformProps.scale ??= currentScale; + + const initialTransform = this._buildTransformString( + matrix.m41, + matrix.m42, + currentScale, + ); + + const finalTransform = this._buildTransformString( + transformProps.x, + transformProps.y, + transformProps.scale, + ); + + const initialKeyframe = { transform: initialTransform }; + const finalKeyframe = { transform: finalTransform }; + + for (const [key, value] of Object.entries(otherProps)) { + const currentVal = + key === "opacity" + ? element.style.opacity || computedStyle.opacity + : element.style[key]; + initialKeyframe[key] = currentVal; + finalKeyframe[key] = value; + } + + const animation = element.animate([initialKeyframe, finalKeyframe], { + duration, + easing: cssEasing, + fill: "forwards", + }); + + this.activeAnimations.add(animation); + animation.onfinish = () => { + this.activeAnimations.delete(animation); + element.style.transform = finalTransform; + for (const [key, value] of Object.entries(finalKeyframe)) { + if (key !== "transform") { + element.style[key] = typeof value === "number" ? `${value}` : value; + } + } + if (onComplete) onComplete(); + }; + + return animation; + } + + killAnimationsOf(element) { + element.getAnimations().forEach((animation) => animation.cancel()); + this.activeAnimations.forEach((animation) => { + if (animation.effect && animation.effect.target === element) { + animation.cancel(); + this.activeAnimations.delete(animation); + } + }); + } + + _buildTransformString(x, y, scale = 1) { + return `translate(${x}px, ${y}px) scale(${scale})`; + } + } + + const anim = new AnimationManager(); + + // ============================================================================ + // Execution Trace Model + // ============================================================================ + + class ExecutionEvent { + constructor( + type, + functionName, + lineno, + timestamp, + args = null, + value = null, + ) { + this.type = type; + this.functionName = functionName; + this.lineno = lineno; + this.timestamp = timestamp; + this.args = args; + this.value = value; + } + } + + class ExecutionTrace { + constructor(source, events) { + this.source = source; + this.events = events.map( + (e) => + new ExecutionEvent(e.type, e.func, e.line, e.ts, e.args, e.value), + ); + this.duration = events.length > 0 ? events[events.length - 1].ts : 0; + } + + getEventsUntil(timestamp) { + return this.events.filter((e) => e.timestamp <= timestamp); + } + + getStackAt(timestamp) { + const stack = []; + const events = this.getEventsUntil(timestamp); + + for (const event of events) { + if (event.type === "call") { + stack.push({ + func: event.functionName, + line: event.lineno, + args: event.args, + }); + } else if (event.type === "return") { + stack.pop(); + } else if (event.type === "line") { + if (stack.length > 0) { + stack[stack.length - 1].line = event.lineno; + } + } + } + return stack; + } + + getNextEvent(timestamp) { + return this.events.find((e) => e.timestamp > timestamp); + } + + getSourceLines() { + return this.source.split("\n"); + } + } + + // ============================================================================ + // Demo Data + // ============================================================================ + + // This placeholder is replaced by the profiling_trace Sphinx extension + // during the documentation build with dynamically generated trace data. + const DEMO_SIMPLE = /* PROFILING_TRACE_DATA */ null; + + // ============================================================================ + // Code Panel Component + // ============================================================================ + + class CodePanel { + constructor(source) { + this.source = source; + this.currentLine = null; + + this.element = document.createElement("div"); + this.element.id = "code-panel"; + + const title = document.createElement("div"); + title.className = "code-panel-title"; + title.textContent = "source code"; + this.element.appendChild(title); + + this.codeContainer = document.createElement("pre"); + this.codeContainer.className = "code-container"; + this.element.appendChild(this.codeContainer); + + this._renderSource(); + } + + updateSource(source) { + this.source = source; + this.codeContainer.innerHTML = ""; + this._renderSource(); + this.currentLine = null; + } + + _renderSource() { + const lines = this.source.split("\n"); + + lines.forEach((line, index) => { + const lineNumber = index + 1; + const lineDiv = document.createElement("div"); + lineDiv.className = "line"; + lineDiv.dataset.line = lineNumber; + + const lineNumSpan = document.createElement("span"); + lineNumSpan.className = "line-number"; + lineNumSpan.textContent = lineNumber; + lineDiv.appendChild(lineNumSpan); + + const codeSpan = document.createElement("span"); + codeSpan.className = "line-content"; + codeSpan.innerHTML = this._highlightSyntax(line); + lineDiv.appendChild(codeSpan); + + this.codeContainer.appendChild(lineDiv); + }); + } + + _highlightSyntax(line) { + return line + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/(f?"[^"]*"|f?'[^']*')/g, '$1') + .replace(/(#.*$)/g, '$1') + .replace( + /\b(def|if|elif|else|return|for|in|range|print|__name__|__main__)\b/g, + '$1', + ) + .replace( + /def<\/span>\s+(\w+)/g, + 'def $1', + ) + .replace(/\b(\d+)\b/g, '$1'); + } + + highlightLine(lineNumber) { + if (this.currentLine === lineNumber) return; + + if (this.currentLine !== null) { + const prevLine = this.codeContainer.querySelector( + `[data-line="${this.currentLine}"]`, + ); + if (prevLine) prevLine.classList.remove("highlighted"); + } + + if (lineNumber === null || lineNumber === undefined) { + this.currentLine = null; + return; + } + + this.currentLine = lineNumber; + const newLine = this.codeContainer.querySelector( + `[data-line="${lineNumber}"]`, + ); + if (newLine) { + newLine.classList.add("highlighted"); + } + } + + reset() { + this.highlightLine(null); + this.codeContainer.scrollTop = 0; + } + + destroy() { + this.element.remove(); + } + } + + // ============================================================================ + // Stack Frame Component + // ============================================================================ + + class DOMStackFrame { + constructor(functionName, lineno, args = null) { + this.functionName = functionName; + this.lineno = lineno; + this.args = args; + this.isActive = false; + this.color = getFunctionColor(functionName); + + this.element = document.createElement("div"); + this.element.className = "stack-frame"; + this.element.dataset.function = functionName; + + this.bgElement = document.createElement("div"); + this.bgElement.className = "stack-frame-bg"; + this.bgElement.style.backgroundColor = this.color; + this.element.appendChild(this.bgElement); + + this.textElement = document.createElement("span"); + this.textElement.className = "stack-frame-text"; + this.textElement.textContent = functionName; + this.element.appendChild(this.textElement); + + this.flashElement = document.createElement("div"); + this.flashElement.className = "stack-frame-flash"; + this.element.appendChild(this.flashElement); + + this.element.addEventListener("pointerover", this._onHover.bind(this)); + this.element.addEventListener("pointerout", this._onHoverOut.bind(this)); + } + + destroy() { + this.element.parentNode?.removeChild(this.element); + } + + updateLine(lineno) { + this.lineno = lineno; + this.textElement.textContent = this.functionName; + } + + setActive(isActive) { + if (this.isActive === isActive) return; + this.isActive = isActive; + this.bgElement.style.opacity = isActive ? "1.0" : "0.9"; + } + + _onHover() { + this.bgElement.style.opacity = "0.8"; + } + + _onHoverOut() { + this.bgElement.style.opacity = this.isActive ? "1.0" : "0.9"; + } + + flash(duration = 150) { + this.flashElement.animate([{ opacity: 1 }, { opacity: 0 }], { + duration, + easing: "ease-out", + }); + } + + getPosition() { + const rect = this.element.getBoundingClientRect(); + return { x: rect.left, y: rect.top }; + } + } + + // ============================================================================ + // Stack Visualization Component + // ============================================================================ + + class DOMStackVisualization { + constructor() { + this.frames = []; + this.frameSpacing = LAYOUT.frameSpacing; + + this.element = document.createElement("div"); + this.element.className = "stack-visualization"; + } + + processEvent(event) { + if (event.type === "call") { + this.pushFrame(event.functionName, event.lineno, event.args); + } else if (event.type === "return") { + this.popFrame(); + } else if (event.type === "line") { + this.updateTopFrameLine(event.lineno); + } + } + + updateTopFrameLine(lineno) { + if (this.frames.length > 0) { + this.frames[this.frames.length - 1].updateLine(lineno); + } + } + + pushFrame(functionName, lineno, args = null) { + if (this.frames.length > 0) { + this.frames[this.frames.length - 1].setActive(false); + } + + const frame = new DOMStackFrame(functionName, lineno, args); + frame.setActive(true); + this.element.appendChild(frame.element); + this.frames.push(frame); + + requestAnimationFrame(() => { + frame.element.classList.add("visible"); + }); + } + + popFrame() { + if (this.frames.length === 0) return; + + const frame = this.frames.pop(); + frame.element.classList.remove("visible"); + setTimeout(() => frame.destroy(), 300); + + if (this.frames.length > 0) { + this.frames[this.frames.length - 1].setActive(true); + } + } + + clear() { + this.frames.forEach((frame) => frame.destroy()); + this.frames = []; + this.element.innerHTML = ""; + } + + flashAll() { + this.frames.forEach((frame) => frame.flash()); + } + + createStackClone(container) { + const clone = this.element.cloneNode(false); + clone.className = "stack-visualization flying-clone"; + + const elementRect = this.element.getBoundingClientRect(); + const containerRect = container.getBoundingClientRect(); + + // Position relative to container since contain: strict makes position:fixed relative to container + clone.style.position = "absolute"; + clone.style.left = elementRect.left - containerRect.left + "px"; + clone.style.top = elementRect.top - containerRect.top + "px"; + clone.style.width = elementRect.width + "px"; + clone.style.pointerEvents = "none"; + clone.style.zIndex = "1000"; + + this.frames.forEach((frame) => { + const frameClone = frame.element.cloneNode(true); + frameClone.classList.add("visible"); + frameClone.style.opacity = "1"; + frameClone.style.transform = "translateY(0)"; + frameClone.style.transition = "none"; + clone.appendChild(frameClone); + }); + + container.appendChild(clone); + return clone; + } + + updateToMatch(targetStack) { + while (this.frames.length > targetStack.length) { + this.popFrame(); + } + + targetStack.forEach(({ func, line, args }, index) => { + if (index < this.frames.length) { + const frame = this.frames[index]; + if (frame.functionName !== func) { + frame.updateLine(line); + } + frame.setActive(index === targetStack.length - 1); + } else { + this.pushFrame(func, line, args); + } + }); + + if (this.frames.length > 0) { + this.frames[this.frames.length - 1].setActive(true); + } + } + } + + // ============================================================================ + // Sampling Panel Component + // ============================================================================ + + class DOMSamplingPanel { + constructor() { + this.samples = []; + this.functionCounts = {}; + this.totalSamples = 0; + this.sampleInterval = TIMINGS.sampleIntervalDefault; + this.groundTruthFunctions = new Set(); + this.bars = {}; + + this.element = document.createElement("div"); + this.element.className = "sampling-panel"; + + const header = document.createElement("div"); + header.className = "sampling-header"; + + const title = document.createElement("h3"); + title.className = "sampling-title"; + title.textContent = "Sampling Profiler"; + header.appendChild(title); + + const stats = document.createElement("div"); + stats.className = "sampling-stats"; + + this.sampleCountEl = document.createElement("span"); + this.sampleCountEl.textContent = "Samples: 0"; + stats.appendChild(this.sampleCountEl); + + this.intervalEl = document.createElement("span"); + this.intervalEl.textContent = `Interval: ${this.sampleInterval}ms`; + stats.appendChild(this.intervalEl); + + this.missedFunctionsEl = document.createElement("span"); + this.missedFunctionsEl.className = "missed"; + stats.appendChild(this.missedFunctionsEl); + + header.appendChild(stats); + this.element.appendChild(header); + + this.barsContainer = document.createElement("div"); + this.barsContainer.className = "sampling-bars"; + this.element.appendChild(this.barsContainer); + } + + setSampleInterval(interval) { + this.sampleInterval = interval; + this.intervalEl.textContent = `Interval: ${interval}ms`; + } + + setGroundTruth(allFunctions) { + this.groundTruthFunctions = new Set(allFunctions); + this._updateMissedCount(); + } + + addSample(stack) { + this.totalSamples++; + this.sampleCountEl.textContent = `Samples: ${this.totalSamples}`; + + stack.forEach((frame) => { + const funcName = frame.func; + this.functionCounts[funcName] = + (this.functionCounts[funcName] || 0) + 1; + }); + + this._updateBars(); + this._updateMissedCount(); + } + + reset() { + this.samples = []; + this.functionCounts = {}; + this.totalSamples = 0; + this.sampleCountEl.textContent = "Samples: 0"; + this.missedFunctionsEl.textContent = ""; + this.barsContainer.innerHTML = ""; + this.bars = {}; + } + + _updateMissedCount() { + if (this.groundTruthFunctions.size === 0) return; + + const capturedFunctions = new Set(Object.keys(this.functionCounts)); + const notYetSeen = [...this.groundTruthFunctions].filter( + (f) => !capturedFunctions.has(f), + ); + + if (notYetSeen.length > 0) { + this.missedFunctionsEl.textContent = `Not yet seen: ${notYetSeen.length}`; + this.missedFunctionsEl.classList.add("missed"); + this.missedFunctionsEl.style.color = ""; + } else if (this.totalSamples > 0) { + this.missedFunctionsEl.textContent = "All captured!"; + this.missedFunctionsEl.classList.remove("missed"); + this.missedFunctionsEl.style.color = "var(--color-green)"; + } else { + this.missedFunctionsEl.textContent = ""; + } + } + + _updateBars() { + const sorted = Object.entries(this.functionCounts).sort( + (a, b) => b[1] - a[1], + ); + + sorted.forEach(([funcName, count], index) => { + const percentage = + this.totalSamples > 0 ? count / this.totalSamples : 0; + + if (!this.bars[funcName]) { + const row = this._createBarRow(funcName); + this.barsContainer.appendChild(row); + this.bars[funcName] = row; + } + + const row = this.bars[funcName]; + const barFill = row.querySelector(".bar-fill"); + barFill.style.width = `${percentage * 100}%`; + + const percentEl = row.querySelector(".bar-percent"); + percentEl.textContent = `${(percentage * 100).toFixed(0)}%`; + + const currentIndex = Array.from(this.barsContainer.children).indexOf( + row, + ); + if (currentIndex !== index) { + this.barsContainer.insertBefore( + row, + this.barsContainer.children[index], + ); + } + }); + } + + _createBarRow(funcName) { + const row = document.createElement("div"); + row.className = "sampling-bar-row"; + row.dataset.function = funcName; + + const label = document.createElement("span"); + label.className = "bar-label"; + label.textContent = funcName; + row.appendChild(label); + + const barContainer = document.createElement("div"); + barContainer.className = "bar-container"; + + const barFill = document.createElement("div"); + barFill.className = "bar-fill"; + barFill.style.backgroundColor = getFunctionColor(funcName); + barContainer.appendChild(barFill); + + row.appendChild(barContainer); + + const percent = document.createElement("span"); + percent.className = "bar-percent"; + percent.textContent = "0%"; + row.appendChild(percent); + + return row; + } + + getTargetPosition() { + const rect = this.barsContainer.getBoundingClientRect(); + return { x: rect.left + rect.width / 2, y: rect.top + 50 }; + } + + showImpactEffect(position) { + const impact = document.createElement("div"); + impact.className = "impact-circle"; + impact.style.position = "fixed"; + impact.style.left = `${position.x}px`; + impact.style.top = `${position.y}px`; + + // Append to barsContainer parent to avoid triggering scroll + this.element.appendChild(impact); + + impact.animate( + [ + { transform: "translate(-50%, -50%) scale(1)", opacity: 0.6 }, + { transform: "translate(-50%, -50%) scale(4)", opacity: 0 }, + ], + { + duration: 300, + easing: "ease-out", + }, + ).onfinish = () => impact.remove(); + } + } + + // ============================================================================ + // Control Panel Component + // ============================================================================ + + class ControlPanel { + constructor( + container, + onPlay, + onPause, + onReset, + onSpeedChange, + onSeek, + onStep, + onSampleIntervalChange = null, + ) { + this.container = container; + this.onPlay = onPlay; + this.onPause = onPause; + this.onReset = onReset; + this.onSpeedChange = onSpeedChange; + this.onSeek = onSeek; + this.onStep = onStep; + this.onSampleIntervalChange = onSampleIntervalChange; + + this.isPlaying = false; + this.speed = TIMINGS.defaultSpeed; + + this._createControls(); + } + + _createControls() { + const panel = document.createElement("div"); + panel.id = "control-panel"; + + const sampleIntervalHtml = this.onSampleIntervalChange + ? ` +

+ + + ${TIMINGS.sampleIntervalDefault}ms +
+ ` + : ""; + + panel.innerHTML = ` +
+ + + +
+ + ${sampleIntervalHtml} + +
+ + 0ms +
+ `; + + this.container.appendChild(panel); + + this.playPauseBtn = panel.querySelector("#play-pause-btn"); + this.resetBtn = panel.querySelector("#reset-btn"); + this.stepBtn = panel.querySelector("#step-btn"); + this.scrubber = panel.querySelector("#timeline-scrubber"); + this.timeDisplay = panel.querySelector("#time-display"); + + this.playPauseBtn.addEventListener("click", () => + this._togglePlayPause(), + ); + this.resetBtn.addEventListener("click", () => this._handleReset()); + this.stepBtn.addEventListener("click", () => this._handleStep()); + this.scrubber.addEventListener("input", (e) => this._handleSeek(e)); + + if (this.onSampleIntervalChange) { + this.sampleIntervalSlider = panel.querySelector("#sample-interval"); + this.intervalDisplay = panel.querySelector("#interval-display"); + this.sampleIntervalSlider.addEventListener("input", (e) => + this._handleSampleIntervalChange(e), + ); + } + } + + _handleSampleIntervalChange(e) { + const interval = parseInt(e.target.value); + this.intervalDisplay.textContent = `${interval}ms`; + this.onSampleIntervalChange(interval); + } + + _togglePlayPause() { + this.isPlaying = !this.isPlaying; + + if (this.isPlaying) { + this.playPauseBtn.textContent = "⏸ Pause"; + this.playPauseBtn.classList.add("active"); + this.onPlay(); + } else { + this.playPauseBtn.textContent = "▶ Play"; + this.playPauseBtn.classList.remove("active"); + this.onPause(); + } + } + + _handleReset() { + this.isPlaying = false; + this.playPauseBtn.textContent = "▶ Play"; + this.playPauseBtn.classList.remove("active"); + this.scrubber.value = 0; + this.timeDisplay.textContent = "0ms"; + this.onReset(); + } + + _handleStep() { + if (this.onStep) this.onStep(); + } + + _handleSeek(e) { + const percentage = parseFloat(e.target.value); + this.onSeek(percentage / 100); + } + + updateTimeDisplay(currentTime, totalTime) { + this.timeDisplay.textContent = `${Math.floor(currentTime)}ms / ${Math.floor(totalTime)}ms`; + const percentage = (currentTime / totalTime) * 100; + this.scrubber.value = percentage; + } + + setDuration(duration) { + this.duration = duration; + } + + pause() { + if (this.isPlaying) this._togglePlayPause(); + } + + destroy() { + const panel = this.container.querySelector("#control-panel"); + if (panel) panel.remove(); + } + } + + // ============================================================================ + // Visual Effects Manager + // ============================================================================ + + class VisualEffectsManager { + constructor(container) { + this.container = container; + this.flyingAnimationInProgress = false; + + this.flashOverlay = document.createElement("div"); + this.flashOverlay.className = "flash-overlay"; + this.container.appendChild(this.flashOverlay); + } + + triggerSamplingEffect(stackViz, samplingPanel, currentTime, trace) { + if (this.flyingAnimationInProgress) return; + + const stack = trace.getStackAt(currentTime); + + if (stack.length === 0) { + samplingPanel.addSample(stack); + return; + } + + this.flyingAnimationInProgress = true; + stackViz.flashAll(); + + const clone = stackViz.createStackClone(this.container); + const targetPosition = samplingPanel.getTargetPosition(); + + this._animateFlash(); + this._animateFlyingStack(clone, targetPosition, () => { + samplingPanel.showImpactEffect(targetPosition); + clone.remove(); + + const currentStack = trace.getStackAt(currentTime); + samplingPanel.addSample(currentStack); + this.flyingAnimationInProgress = false; + }); + } + + _animateFlash() { + anim.to(this.flashOverlay, { opacity: 0.1 }, 0).onfinish = () => { + anim.to(this.flashOverlay, { opacity: 0 }, 150, "easeOutQuad"); + }; + } + + _animateFlyingStack(clone, targetPosition, onComplete) { + const containerRect = this.container.getBoundingClientRect(); + const cloneRect = clone.getBoundingClientRect(); + + // Convert viewport coordinates to container-relative + const startX = cloneRect.left - containerRect.left + cloneRect.width / 2; + const startY = cloneRect.top - containerRect.top + cloneRect.height / 2; + const targetX = targetPosition.x - containerRect.left; + const targetY = targetPosition.y - containerRect.top; + + const deltaX = targetX - startX; + const deltaY = targetY - startY; + + anim.to( + clone, + { + x: deltaX, + y: deltaY, + scale: 0.3, + opacity: 0.6, + }, + TIMINGS.sampleToFlame, + "easeOutCubic", + onComplete, + ); + } + } + + // ============================================================================ + // Main Visualization Class + // ============================================================================ + + class SamplingVisualization { + constructor(container) { + this.container = container; + + this.trace = new ExecutionTrace(DEMO_SIMPLE.source, DEMO_SIMPLE.trace); + + this.currentTime = 0; + this.isPlaying = false; + this.playbackSpeed = TIMINGS.defaultSpeed; + this.eventIndex = 0; + + this.sampleInterval = TIMINGS.sampleIntervalDefault; + this.lastSampleTime = 0; + + this._createLayout(); + + this.effectsManager = new VisualEffectsManager(this.vizColumn); + + this.lastTime = performance.now(); + this._animate(); + } + + _createLayout() { + this.codePanel = new CodePanel(this.trace.source); + this.container.appendChild(this.codePanel.element); + + this.vizColumn = document.createElement("div"); + this.vizColumn.className = "viz-column"; + this.container.appendChild(this.vizColumn); + + const stackSection = document.createElement("div"); + stackSection.className = "stack-section"; + + const stackTitle = document.createElement("div"); + stackTitle.className = "stack-section-title"; + stackTitle.textContent = "Call Stack"; + stackSection.appendChild(stackTitle); + + this.stackViz = new DOMStackVisualization(); + stackSection.appendChild(this.stackViz.element); + this.vizColumn.appendChild(stackSection); + + this.samplingPanel = new DOMSamplingPanel(); + this.samplingPanel.setGroundTruth(this._getGroundTruthFunctions()); + this.vizColumn.appendChild(this.samplingPanel.element); + + this.controls = new ControlPanel( + this.vizColumn, + () => this.play(), + () => this.pause(), + () => this.reset(), + (speed) => this.setSpeed(speed), + (progress) => this.seek(progress), + () => this.step(), + (interval) => this.setSampleInterval(interval), + ); + this.controls.setDuration(this.trace.duration); + } + + _getGroundTruthFunctions() { + const functions = new Set(); + this.trace.events.forEach((event) => { + if (event.type === "call") { + functions.add(event.functionName); + } + }); + return [...functions]; + } + + play() { + this.isPlaying = true; + } + + pause() { + this.isPlaying = false; + } + + reset() { + this.currentTime = 0; + this.eventIndex = 0; + this.isPlaying = false; + this.lastSampleTime = 0; + this.stackViz.clear(); + this.codePanel.reset(); + this.samplingPanel.reset(); + this.controls.updateTimeDisplay(0, this.trace.duration); + } + + setSpeed(speed) { + this.playbackSpeed = speed; + } + + setSampleInterval(interval) { + this.sampleInterval = interval; + this.samplingPanel.setSampleInterval(interval); + } + + seek(progress) { + this.currentTime = progress * this.trace.duration; + this.eventIndex = 0; + this.lastSampleTime = 0; + this._rebuildState(); + } + + step() { + this.pause(); + + const nextEvent = this.trace.getNextEvent(this.currentTime); + + if (nextEvent) { + // Calculate delta to reach next event + epsilon + const targetTime = nextEvent.timestamp + 0.1; + const delta = targetTime - this.currentTime; + if (delta > 0) { + this._advanceTime(delta); + } + } + } + + _animate(currentTime = performance.now()) { + const deltaTime = currentTime - this.lastTime; + this.lastTime = currentTime; + + this.update(deltaTime); + requestAnimationFrame((t) => this._animate(t)); + } + + update(deltaTime) { + if (!this.isPlaying) { + this.controls.updateTimeDisplay(this.currentTime, this.trace.duration); + return; + } + + const virtualDelta = deltaTime * this.playbackSpeed; + this._advanceTime(virtualDelta); + } + + _advanceTime(virtualDelta) { + this.currentTime += virtualDelta; + + if (this.currentTime >= this.trace.duration) { + this.currentTime = this.trace.duration; + this.isPlaying = false; + this.controls.pause(); + } + + while (this.eventIndex < this.trace.events.length) { + const event = this.trace.events[this.eventIndex]; + + if (event.timestamp > this.currentTime) break; + + this._processEvent(event); + this.eventIndex++; + } + + this.controls.updateTimeDisplay(this.currentTime, this.trace.duration); + + if (this.currentTime - this.lastSampleTime >= this.sampleInterval) { + this._takeSample(); + this.lastSampleTime = this.currentTime; + } + } + + _processEvent(event) { + this.stackViz.processEvent(event); + + if (event.type === "call") { + this.codePanel.highlightLine(event.lineno); + } else if (event.type === "return") { + const currentStack = this.trace.getStackAt(this.currentTime); + if (currentStack.length > 0) { + this.codePanel.highlightLine( + currentStack[currentStack.length - 1].line, + ); + } else { + this.codePanel.highlightLine(null); + } + } else if (event.type === "line") { + this.codePanel.highlightLine(event.lineno); + } + } + + _takeSample() { + this.effectsManager.triggerSamplingEffect( + this.stackViz, + this.samplingPanel, + this.currentTime, + this.trace, + ); + } + + _rebuildState() { + this.stackViz.clear(); + this.codePanel.reset(); + this.samplingPanel.reset(); + + for (let t = 0; t < this.currentTime; t += this.sampleInterval) { + const stack = this.trace.getStackAt(t); + this.samplingPanel.addSample(stack); + this.lastSampleTime = t; + } + + const stack = this.trace.getStackAt(this.currentTime); + this.stackViz.updateToMatch(stack); + + if (stack.length > 0) { + this.codePanel.highlightLine(stack[stack.length - 1].line); + } + + this.eventIndex = this.trace.getEventsUntil(this.currentTime).length; + } + } + + // ============================================================================ + // Initialize + // ============================================================================ + + function init() { + // If trace data hasn't been injected yet (local dev), don't initialize + if (!DEMO_SIMPLE) return; + + const appContainer = document.getElementById("sampling-profiler-viz"); + if (appContainer) { + new SamplingVisualization(appContainer); + } + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } +})(); diff --git a/Doc/conf.py b/Doc/conf.py index f6efc5ff22a5e1..859c1d26ed9f22 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -33,6 +33,7 @@ 'issue_role', 'lexers', 'misc_news', + 'profiling_trace', 'pydoc_topics', 'pyspecific', 'sphinx.ext.coverage', diff --git a/Doc/library/profiling-sampling-visualization.html b/Doc/library/profiling-sampling-visualization.html new file mode 100644 index 00000000000000..0cbd0f2374deaa --- /dev/null +++ b/Doc/library/profiling-sampling-visualization.html @@ -0,0 +1 @@ +
diff --git a/Doc/library/profiling.sampling.rst b/Doc/library/profiling.sampling.rst index 87e431969393b6..6c37a8d34cbd42 100644 --- a/Doc/library/profiling.sampling.rst +++ b/Doc/library/profiling.sampling.rst @@ -44,6 +44,23 @@ of samples over a profiling session, Tachyon constructs an accurate statistical estimate of where time is spent. The more samples collected, the more precise this estimate becomes. +.. only:: html + + The following interactive visualization demonstrates how sampling profiling + works. Press **Play** to watch a Python program execute, and observe how the + profiler periodically captures snapshots of the call stack. Adjust the + **sample interval** to see how sampling frequency affects the results. + + .. raw:: html + :file: profiling-sampling-visualization.html + +.. only:: not html + + .. note:: + + An interactive visualization of sampling profiling is available in the + HTML version of this documentation. + How time is estimated --------------------- diff --git a/Doc/tools/extensions/profiling_trace.py b/Doc/tools/extensions/profiling_trace.py new file mode 100644 index 00000000000000..7185ef351ddc7f --- /dev/null +++ b/Doc/tools/extensions/profiling_trace.py @@ -0,0 +1,166 @@ +""" +Sphinx extension to generate profiler trace data during docs build. + +This extension executes a demo Python program with sys.settrace() to capture +the execution trace and injects it into the profiling visualization JS file. +""" + +import json +import re +import sys +from io import StringIO +from pathlib import Path + +from sphinx.errors import ExtensionError + +DEMO_SOURCE = """\ +def add(a, b): + return a + b + +def multiply(x, y): + result = 0 + for i in range(y): + result = add(result, x) + return result + +def calculate(a, b): + sum_val = add(a, b) + product = multiply(a, b) + return sum_val + product + +def main(): + result = calculate(3, 4) + print(f"Result: {result}") + +main() +""" + +PLACEHOLDER = "/* PROFILING_TRACE_DATA */null" + + +def generate_trace(source: str) -> list[dict]: + """ + Execute the source code with tracing enabled and capture execution events. + """ + trace_events = [] + timestamp = [0] + timestamp_step = 50 + tracing_active = [False] + pending_line = [None] + + def tracer(frame, event, arg): + if frame.f_code.co_filename != '': + return tracer + + func_name = frame.f_code.co_name + lineno = frame.f_lineno + + if event == 'line' and not tracing_active[0]: + pending_line[0] = {'type': 'line', 'line': lineno} + return tracer + + # Start tracing only once main() is called + if event == 'call' and func_name == 'main': + tracing_active[0] = True + # Emit the buffered line event (the main() call line) at ts=0 + if pending_line[0]: + pending_line[0]['ts'] = 0 + trace_events.append(pending_line[0]) + pending_line[0] = None + timestamp[0] = timestamp_step + + # Skip events until we've entered main() + if not tracing_active[0]: + return tracer + + if event == 'call': + trace_events.append({ + 'type': 'call', + 'func': func_name, + 'line': lineno, + 'ts': timestamp[0], + }) + elif event == 'line': + trace_events.append({ + 'type': 'line', + 'line': lineno, + 'ts': timestamp[0], + }) + elif event == 'return': + try: + value = arg if arg is None else repr(arg) + except Exception: + value = '' + trace_events.append({ + 'type': 'return', + 'func': func_name, + 'ts': timestamp[0], + 'value': value, + }) + + if func_name == 'main': + tracing_active[0] = False + + timestamp[0] += timestamp_step + return tracer + + # Suppress print output during tracing + old_stdout = sys.stdout + sys.stdout = StringIO() + + old_trace = sys.gettrace() + sys.settrace(tracer) + try: + code = compile(source, '', 'exec') + exec(code, {'__name__': '__main__'}) + finally: + sys.settrace(old_trace) + sys.stdout = old_stdout + + return trace_events + + +def inject_trace(app, exception): + if exception: + return + + js_path = ( + Path(app.outdir) / '_static' / 'profiling-sampling-visualization.js' + ) + + if not js_path.exists(): + return + + trace = generate_trace(DEMO_SOURCE) + + demo_data = {'source': DEMO_SOURCE.rstrip(), 'trace': trace, 'samples': []} + + demo_json = json.dumps(demo_data, indent=2) + content = js_path.read_text(encoding='utf-8') + + pattern = r"(const DEMO_SIMPLE\s*=\s*/\* PROFILING_TRACE_DATA \*/)[^;]+;" + + if re.search(pattern, content): + content = re.sub( + pattern, lambda m: f"{m.group(1)} {demo_json};", content + ) + js_path.write_text(content, encoding='utf-8') + print( + f"profiling_trace: Injected {len(trace)} trace events into {js_path.name}" + ) + else: + raise ExtensionError( + f"profiling_trace: Placeholder pattern not found in {js_path.name}" + ) + + +def setup(app): + app.connect('build-finished', inject_trace) + app.add_js_file('profiling-sampling-visualization.js') + app.add_css_file('profiling-sampling-visualization.css') + + return { + 'version': '1.0', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } From d5f96c86653de4dc8c5074ab0bf3027d0a3c1878 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Wed, 11 Feb 2026 15:27:16 +1100 Subject: [PATCH 069/498] gh-140421: Disable perf trampoline on older macOS (#144647) Trampoline requires clock_gettime() which was added in macOS 10.12. --- .../Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst | 1 + configure | 8 +++++++- configure.ac | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst diff --git a/Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst b/Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst new file mode 100644 index 00000000000000..cab48f105cc58b --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst @@ -0,0 +1 @@ +Disable the perf trampoline on older macOS versions where it cannot be built. diff --git a/configure b/configure index cd8983683333cd..73a758384553b2 100755 --- a/configure +++ b/configure @@ -13873,7 +13873,13 @@ case $PLATFORM_TRIPLET in #( aarch64-linux-gnu) : perf_trampoline=yes ;; #( darwin) : - perf_trampoline=yes ;; #( + case $MACOSX_DEPLOYMENT_TARGET in #( + 10.[0-9]|10.1[0-1]) : + perf_trampoline=no ;; #( + *) : + perf_trampoline=yes + ;; +esac ;; #( *) : perf_trampoline=no ;; diff --git a/configure.ac b/configure.ac index e9b45d459fee2a..2ba63b2a8a05e0 100644 --- a/configure.ac +++ b/configure.ac @@ -3717,7 +3717,10 @@ AC_MSG_CHECKING([perf trampoline]) AS_CASE([$PLATFORM_TRIPLET], [x86_64-linux-gnu], [perf_trampoline=yes], [aarch64-linux-gnu], [perf_trampoline=yes], - [darwin], [perf_trampoline=yes], + [darwin], [AS_CASE([$MACOSX_DEPLOYMENT_TARGET], + [[10.[0-9]|10.1[0-1]]], [perf_trampoline=no], + [perf_trampoline=yes] + )], [perf_trampoline=no] ) AC_MSG_RESULT([$perf_trampoline]) From 936d60dbe1679f05d7ceb0a6d1f65bc741390ac6 Mon Sep 17 00:00:00 2001 From: Adorilson Bezerra Date: Wed, 11 Feb 2026 08:41:37 +0000 Subject: [PATCH 070/498] gh-106318: Improve str.rstrip() method doc (#143893) Co-authored-by: Victor Stinner Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/stdtypes.rst | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index ffb5a053a6dce8..c8dc834fe84446 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2630,14 +2630,17 @@ expression support in the :mod:`re` module). Return a copy of the string with trailing characters removed. The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* - argument is not a suffix; rather, all combinations of its values are stripped:: + argument is not a suffix; rather, all combinations of its values are stripped. + For example: + + .. doctest:: >>> ' spacious '.rstrip() ' spacious' >>> 'mississippi'.rstrip('ipz') 'mississ' - See :meth:`str.removesuffix` for a method that will remove a single suffix + See :meth:`removesuffix` for a method that will remove a single suffix string rather than all of a set of characters. For example:: >>> 'Monty Python'.rstrip(' Python') @@ -2645,6 +2648,9 @@ expression support in the :mod:`re` module). >>> 'Monty Python'.removesuffix(' Python') 'Monty' + See also :meth:`strip`. + + .. method:: str.split(sep=None, maxsplit=-1) Return a list of the words in the string, using *sep* as the delimiter @@ -2795,7 +2801,11 @@ expression support in the :mod:`re` module). The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* argument is not a prefix or suffix; rather, all combinations of its - values are stripped:: + values are stripped. + + For example: + + .. doctest:: >>> ' spacious '.strip() 'spacious' @@ -2806,12 +2816,17 @@ expression support in the :mod:`re` module). from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in *chars*. A similar action takes place on the trailing end. - For example:: + + For example: + + .. doctest:: >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' >>> comment_string.strip('.#! ') 'Section 3.2.1 Issue #32' + See also :meth:`rstrip`. + .. method:: str.swapcase() From 15b216f30d0445469ec31bc7509fcc55a216ef7c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:22:36 +0200 Subject: [PATCH 071/498] Python 3.15.0a6 --- Doc/library/base64.rst | 6 +- Doc/library/binascii.rst | 14 +- Doc/library/contextlib.rst | 8 +- Doc/library/inspect.rst | 2 +- Doc/library/multiprocessing.rst | 2 +- Doc/library/os.path.rst | 2 +- Doc/library/symtable.rst | 4 +- Doc/library/tomllib.rst | 2 +- Doc/library/urllib.parse.rst | 8 +- Doc/reference/expressions.rst | 4 +- Doc/using/cmdline.rst | 2 +- Include/patchlevel.h | 4 +- Lib/pydoc_data/module_docs.py | 10 +- Lib/pydoc_data/topics.py | 584 ++++++--- Misc/NEWS.d/3.15.0a6.rst | 1101 +++++++++++++++++ ...-01-15-03-36-16.gh-issue-143842.EZLutl.rst | 2 - ...-01-16-14-27-53.gh-issue-143941.TiaE-3.rst | 3 - ...-01-17-15-31-19.gh-issue-143960.Zi0EqR.rst | 1 - ...-01-27-23-39-26.gh-issue-144278.tejFwL.rst | 5 - ...-01-28-19-04-12.gh-issue-144309.3sMFOh.rst | 1 - ...-02-10-06-31-29.gh-issue-140421.vxosUx.rst | 1 - ...-12-16-18-39-30.gh-issue-141070.4EKDZ1.rst | 1 - ...-01-16-15-04-26.gh-issue-143869.vf94km.rst | 5 - ...-02-10-05-42-26.gh-issue-115231.6T7dzi.rst | 2 - ...-10-16-22-36-05.gh-issue-140232.u3srgv.rst | 1 - ...-10-24-17-30-51.gh-issue-140557.X2GETk.rst | 2 - ...-11-29-10-06-06.gh-issue-142037.OpIGzK.rst | 7 - ...-12-21-18-12-30.gh-issue-143055.PzwccL.rst | 1 - ...-12-24-13-19-16.gh-issue-132657._P4DDb.rst | 6 - ...-12-29-19-31-46.gh-issue-143192.JxGAyl.rst | 1 - ...-01-08-14-55-31.gh-issue-143569.-Ltu3c.rst | 3 - ...-01-10-10-58-36.gh-issue-143650.k8mR4x.rst | 2 - ...-01-11-20-11-36.gh-issue-143670.klnGoD.rst | 1 - ...-01-13-22-26-49.gh-issue-141805.QzIKPS.rst | 3 - ...-01-16-23-19-38.gh-issue-143939.w9TWch.rst | 3 - ...-01-19-01-26-12.gh-issue-144005.Z3O33m.rst | 1 - ...-01-19-01-56-44.gh-issue-144007.1xjdBf.rst | 1 - ...-01-19-02-33-45.gh-issue-144012.wVEEWs.rst | 1 - ...-01-21-02-30-06.gh-issue-144068.9TTu7v.rst | 1 - ...-01-22-16-20-16.gh-issue-144157.dxyp7k.rst | 2 - ...-01-22-17-04-30.gh-issue-143962.dQR1a9.rst | 3 - ...-01-23-20-20-42.gh-issue-144194.IbXfxd.rst | 1 - ...-01-27-17-49-43.gh-issue-120321.Vo7c9T.rst | 2 - ...-01-29-01-42-14.gh-issue-144319._7EtdB.rst | 1 - ...-01-29-02-18-08.gh-issue-144307.CLbm_o.rst | 1 - ...-01-29-16-57-11.gh-issue-139103.icXIEQ.rst | 2 - ...-01-30-10-38-07.gh-issue-140550.Us9vPD.rst | 2 - ...-01-30-15-54-50.gh-issue-144280.kgiP5R.rst | 1 - ...-02-02-17-07-34.gh-issue-141563.GheXjr.rst | 1 - ...-02-02-17-50-14.gh-issue-120321.Xfr7tL.rst | 5 - ...-02-03-17-08-13.gh-issue-144446.db5619.rst | 2 - ...-02-04-11-19-45.gh-issue-144330.kOowSb.rst | 2 - ...-02-04-12-19-48.gh-issue-131798.My5jLy.rst | 1 - ...-02-05-13-30-00.gh-issue-144513.IjSTd7.rst | 2 - ...-02-06-17-59-47.gh-issue-144549.5BhPlY.rst | 1 - ...-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst | 2 - ...-02-08-18-13-38.gh-issue-144563.hb3kpp.rst | 4 - ...-02-10-12-08-58.gh-issue-134584.P9LDy5.rst | 1 - ...-01-13-01-21-20.gh-issue-143774.rqGwX1.rst | 1 - ...0-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst | 1 - ...4-11-27-13-11-16.gh-issue-67041.ym2WKK.rst | 6 - ...-10-27-00-13-04.gh-issue-140715.WkozE0.rst | 1 - ...-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst | 5 - ...-11-22-20-30-00.gh-issue-141860.frksvr.rst | 5 - ...-12-08-18-40-17.gh-issue-142438.tH-Y16.rst | 2 - ...-12-15-02-02-45.gh-issue-142555.EC9QN_.rst | 3 - ...-12-19-11-30-31.gh-issue-142966.PzGiv2.rst | 1 - ...-12-28-15-55-53.gh-issue-101178.26jYPs.rst | 2 - ...-01-05-05-31-05.gh-issue-143423.X7YdnR.rst | 1 - ...-01-07-11-57-59.gh-issue-140557.3P6-nW.rst | 2 - ...-01-07-19-01-59.gh-issue-142434.SHRS5p.rst | 3 - ...-01-09-12-37-19.gh-issue-143602.V8vQpj.rst | 2 - ...-01-11-14-14-19.gh-issue-143689.fzHJ2W.rst | 1 - ...-01-13-10-38-43.gh-issue-143543.DeQRCO.rst | 2 - ...-01-13-15-56-03.gh-issue-132604.lvjNTr.rst | 4 - ...-01-13-16-19-50.gh-issue-143756.LQOra1.rst | 1 - ...-01-14-20-35-40.gh-issue-143754.m2NQXA.rst | 3 - ...-01-15-16-04-39.gh-issue-143874.1qQgvo.rst | 1 - ...-01-16-06-22-10.gh-issue-143831.VLBTLp.rst | 3 - ...-01-16-10-53-17.gh-issue-143897.hWJBHN.rst | 3 - ...-01-16-14-02-39.gh-issue-143904.rErHHA.rst | 2 - ...-01-17-07-48-27.gh-issue-143952.lqJ55y.rst | 2 - ...-01-18-14-35-37.gh-issue-143999.MneN4O.rst | 1 - ...-01-19-00-57-40.gh-issue-144023.29XUcp.rst | 2 - ...-01-19-10-26-59.gh-issue-144001.dGj8Nk.rst | 2 - ...-01-19-12-48-59.gh-issue-144030.7OK_gB.rst | 3 - ...6-01-19-16-45-16.gh-issue-83069.0TaeH9.rst | 7 - ...-01-20-16-35-55.gh-issue-144050.0kKFbF.rst | 2 - ...-01-20-20-54-46.gh-issue-143658.v8i1jE.rst | 4 - ...-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst | 3 - ...-01-22-10-18-17.gh-issue-144128.akwY06.rst | 2 - ...-01-23-06-43-21.gh-issue-144169.LFy9yi.rst | 2 - ...-01-24-13-49-05.gh-issue-143594.nilGlg.rst | 1 - ...-01-24-23-11-17.gh-issue-144212.IXqVL8.rst | 1 - ...-01-25-03-23-20.gh-issue-144217.E1wVXH.rst | 1 - ...-01-26-12-30-57.gh-issue-142956.X9CS8J.rst | 1 - ...-01-27-00-03-41.gh-issue-132888.yhTfUN.rst | 2 - ...-01-27-09-58-52.gh-issue-144249.mCIy95.rst | 2 - ...-01-27-10-02-04.gh-issue-144264.Wmzbol.rst | 3 - ...-01-27-14-23-10.gh-issue-144206.l0un4U.rst | 2 - ...-01-30-13-23-06.gh-issue-140824.J1OCrC.rst | 2 - ...-01-31-17-15-49.gh-issue-144363.X9f0sU.rst | 1 - ...-02-01-15-25-00.gh-issue-144380.U7py_s.rst | 1 - ...6-02-02-12-09-38.gh-issue-74453.19h4Z5.rst | 8 - ...-02-03-08-50-58.gh-issue-123471.yF1Gym.rst | 1 - ...-02-03-14-16-49.gh-issue-144386.9Wa59r.rst | 4 - ...-02-05-17-15-31.gh-issue-144493.XuxwVu.rst | 1 - ...-02-06-23-58-54.gh-issue-144538.5_OvGv.rst | 1 - ...-01-16-11-07-36.gh-issue-143916.dpWeOD.rst | 2 - ...-01-16-11-13-15.gh-issue-143919.kchwZV.rst | 1 - ...-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 - ...-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 - ...-01-16-11-51-19.gh-issue-143925.mrtcHW.rst | 1 - ...-01-16-14-40-31.gh-issue-143935.U2YtKl.rst | 6 - ...-01-21-12-34-05.gh-issue-144125.TAz5uo.rst | 4 - ...6-01-08-16-56-59.gh-issue-65784.aKNo1U.rst | 3 - ...-02-03-07-57-24.gh-issue-144415.U3L15r.rst | 3 - ...6-01-05-21-36-58.gh-issue-80620.p1bD58.rst | 1 - ...-02-09-22-43-47.gh-issue-144551.VOfgfD.rst | 1 - ...-02-09-23-01-49.gh-issue-124111.WmQG7S.rst | 1 - ...-02-10-08-00-17.gh-issue-144648.KEuUXp.rst | 1 - README.rst | 2 +- 122 files changed, 1543 insertions(+), 446 deletions(-) create mode 100644 Misc/NEWS.d/3.15.0a6.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-01-15-03-36-16.gh-issue-143842.EZLutl.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-01-16-14-27-53.gh-issue-143941.TiaE-3.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-01-17-15-31-19.gh-issue-143960.Zi0EqR.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-01-28-19-04-12.gh-issue-144309.3sMFOh.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst delete mode 100644 Misc/NEWS.d/next/C_API/2025-12-16-18-39-30.gh-issue-141070.4EKDZ1.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-01-16-15-04-26.gh-issue-143869.vf94km.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-22-36-05.gh-issue-140232.u3srgv.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-24-17-30-51.gh-issue-140557.X2GETk.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-10-06-06.gh-issue-142037.OpIGzK.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-21-18-12-30.gh-issue-143055.PzwccL.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-24-13-19-16.gh-issue-132657._P4DDb.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-29-19-31-46.gh-issue-143192.JxGAyl.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-14-55-31.gh-issue-143569.-Ltu3c.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-13-22-26-49.gh-issue-141805.QzIKPS.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-16-23-19-38.gh-issue-143939.w9TWch.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-26-12.gh-issue-144005.Z3O33m.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-56-44.gh-issue-144007.1xjdBf.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-02-33-45.gh-issue-144012.wVEEWs.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-16-20-16.gh-issue-144157.dxyp7k.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-17-04-30.gh-issue-143962.dQR1a9.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-23-20-20-42.gh-issue-144194.IbXfxd.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-27-17-49-43.gh-issue-120321.Vo7c9T.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-01-42-14.gh-issue-144319._7EtdB.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-02-18-08.gh-issue-144307.CLbm_o.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-15-54-50.gh-issue-144280.kgiP5R.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-50-14.gh-issue-120321.Xfr7tL.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2026-01-13-01-21-20.gh-issue-143774.rqGwX1.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-11-27-13-11-16.gh-issue-67041.ym2WKK.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-11-22-20-30-00.gh-issue-141860.frksvr.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-08-18-40-17.gh-issue-142438.tH-Y16.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-15-02-02-45.gh-issue-142555.EC9QN_.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-19-11-30-31.gh-issue-142966.PzGiv2.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-05-05-31-05.gh-issue-143423.X7YdnR.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-07-11-57-59.gh-issue-140557.3P6-nW.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-11-14-14-19.gh-issue-143689.fzHJ2W.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-13-16-19-50.gh-issue-143756.LQOra1.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-15-16-04-39.gh-issue-143874.1qQgvo.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-16-06-22-10.gh-issue-143831.VLBTLp.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-16-10-53-17.gh-issue-143897.hWJBHN.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-16-14-02-39.gh-issue-143904.rErHHA.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-17-07-48-27.gh-issue-143952.lqJ55y.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-18-14-35-37.gh-issue-143999.MneN4O.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-19-00-57-40.gh-issue-144023.29XUcp.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-19-10-26-59.gh-issue-144001.dGj8Nk.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-19-12-48-59.gh-issue-144030.7OK_gB.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-19-16-45-16.gh-issue-83069.0TaeH9.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-24-23-11-17.gh-issue-144212.IXqVL8.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-25-03-23-20.gh-issue-144217.E1wVXH.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-26-12-30-57.gh-issue-142956.X9CS8J.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-27-00-03-41.gh-issue-132888.yhTfUN.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-27-09-58-52.gh-issue-144249.mCIy95.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-27-10-02-04.gh-issue-144264.Wmzbol.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-01-15-25-00.gh-issue-144380.U7py_s.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-03-08-50-58.gh-issue-123471.yF1Gym.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-03-14-16-49.gh-issue-144386.9Wa59r.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst delete mode 100644 Misc/NEWS.d/next/Tests/2026-01-08-16-56-59.gh-issue-65784.aKNo1U.rst delete mode 100644 Misc/NEWS.d/next/Tests/2026-02-03-07-57-24.gh-issue-144415.U3L15r.rst delete mode 100644 Misc/NEWS.d/next/Windows/2026-01-05-21-36-58.gh-issue-80620.p1bD58.rst delete mode 100644 Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst delete mode 100644 Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst delete mode 100644 Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 975c488813722e..771628677c3d98 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -105,10 +105,10 @@ POST request. For more information about the strict base64 check, see :func:`binascii.a2b_base64` - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *ignorechars* parameter. - .. deprecated:: next + .. deprecated:: 3.15 Accepting the ``+`` and ``/`` characters with an alternative alphabet is now deprecated. @@ -142,7 +142,7 @@ POST request. ``/`` in the standard Base64 alphabet, and return the decoded :class:`bytes`. - .. deprecated:: next + .. deprecated:: 3.15 Accepting the ``+`` and ``/`` characters is now deprecated. diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 39320da93a8ad7..8a241e51ebfee6 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -75,7 +75,7 @@ The :mod:`!binascii` module defines the following functions: .. versionchanged:: 3.11 Added the *strict_mode* parameter. - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *ignorechars* parameter. @@ -122,7 +122,7 @@ The :mod:`!binascii` module defines the following functions: Invalid Ascii85 data will raise :exc:`binascii.Error`. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: b2a_ascii85(data, /, *, foldspaces=False, wrapcol=0, pad=False, adobe=False) @@ -145,7 +145,7 @@ The :mod:`!binascii` module defines the following functions: *adobe* controls whether the encoded byte sequence is framed with ``<~`` and ``~>``, which is used by the Adobe implementation. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: a2b_base85(string, /) @@ -160,7 +160,7 @@ The :mod:`!binascii` module defines the following functions: Invalid Base85 data will raise :exc:`binascii.Error`. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: b2a_base85(data, /, *, pad=False) @@ -171,7 +171,7 @@ The :mod:`!binascii` module defines the following functions: If *pad* is true, the input is padded with ``b'\0'`` so its length is a multiple of 4 bytes before encoding. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: a2b_z85(string, /) @@ -188,7 +188,7 @@ The :mod:`!binascii` module defines the following functions: Invalid Z85 data will raise :exc:`binascii.Error`. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: b2a_z85(data, /, *, pad=False) @@ -201,7 +201,7 @@ The :mod:`!binascii` module defines the following functions: See `Z85 specification `_ for more information. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: a2b_qp(data, header=False) diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 564c11d0596c44..eec9ed1ba2581e 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -564,7 +564,7 @@ Functions and classes provided: Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm* is not a context manager. - .. versionchanged:: next + .. versionchanged:: 3.15 Added support for arbitrary descriptors :meth:`!__enter__` and :meth:`!__exit__`. @@ -586,7 +586,7 @@ Functions and classes provided: The passed in object is returned from the function, allowing this method to be used as a function decorator. - .. versionchanged:: next + .. versionchanged:: 3.15 Added support for arbitrary descriptors :meth:`!__exit__`. .. method:: callback(callback, /, *args, **kwds) @@ -646,7 +646,7 @@ Functions and classes provided: Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm* is not an asynchronous context manager. - .. versionchanged:: next + .. versionchanged:: 3.15 Added support for arbitrary descriptors :meth:`!__aenter__` and :meth:`!__aexit__`. .. method:: push_async_exit(exit) @@ -654,7 +654,7 @@ Functions and classes provided: Similar to :meth:`ExitStack.push` but expects either an asynchronous context manager or a coroutine function. - .. versionchanged:: next + .. versionchanged:: 3.15 Added support for arbitrary descriptors :meth:`!__aexit__`. .. method:: push_async_callback(callback, /, *args, **kwds) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 57353bfb9717d1..1455d907de8888 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -360,7 +360,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes): Add ``f_generator`` attribute to frames. -.. versionchanged:: next +.. versionchanged:: 3.15 Add ``gi_state`` attribute to generators, ``cr_state`` attribute to coroutines, and ``ag_state`` attribute to async generators. diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index d3baf2d760f615..e313a15bbd7949 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1257,7 +1257,7 @@ Miscellaneous .. versionadded:: 3.4 - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *on_error* parameter. .. function:: set_start_method(method, force=False) diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 70ff6256821d7d..808187061733be 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -120,7 +120,7 @@ the :mod:`glob` module.) .. versionchanged:: 3.6 Accepts a :term:`path-like object`. - .. deprecated:: next + .. deprecated:: 3.15 Deprecated in favor of :func:`os.path.commonpath` for path prefixes. The :func:`os.path.commonprefix` function is being deprecated due to having a misleading name and module. The function is not safe to use for diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 63549f440a5f13..264857f7b76aad 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -184,7 +184,7 @@ Examining Symbol Tables Return a tuple containing names of :term:`cell variables ` in this table. - .. versionadded:: next + .. versionadded:: 3.15 .. class:: Class @@ -301,7 +301,7 @@ Examining Symbol Tables Return ``True`` if the symbol is referenced but not assigned in a nested block. - .. versionadded:: next + .. versionadded:: 3.15 .. method:: is_free_class() diff --git a/Doc/library/tomllib.rst b/Doc/library/tomllib.rst index d3767798055da4..dc6e0cc178bf66 100644 --- a/Doc/library/tomllib.rst +++ b/Doc/library/tomllib.rst @@ -18,7 +18,7 @@ support writing TOML. .. versionadded:: 3.11 The module was added with support for TOML 1.0.0. -.. versionchanged:: next +.. versionchanged:: 3.15 Added TOML 1.1.0 support. See the :ref:`What's New ` for details. diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 0fd307068effa5..ef48addaba03e9 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -217,7 +217,7 @@ or on combining URL components into a URL string. .. versionchanged:: 3.12 Leading WHATWG C0 control and space characters are stripped from the URL. - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *missing_as_none* parameter. .. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser @@ -333,7 +333,7 @@ or on combining URL components into a URL string. By default, *keep_empty* is true if *parts* is the result of the :func:`urlsplit` call with ``missing_as_none=True``. - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *keep_empty* parameter. @@ -371,7 +371,7 @@ or on combining URL components into a URL string. By default, *keep_empty* is true if *parts* is the result of the :func:`urlparse` call with ``missing_as_none=True``. - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *keep_empty* parameter. @@ -444,7 +444,7 @@ or on combining URL components into a URL string. .. versionchanged:: 3.2 Result is a structured object rather than a simple 2-tuple. - .. versionchanged:: next + .. versionchanged:: 3.15 Added the *missing_as_none* parameter. .. function:: unwrap(url) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 281d032b2a0f16..54384a8cf3fb90 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -323,7 +323,7 @@ See also :pep:`530`. asynchronous functions. Outer comprehensions implicitly become asynchronous. -.. versionchanged:: next +.. versionchanged:: 3.15 Unpacking with the ``*`` operator is now allowed in the expression. @@ -455,7 +455,7 @@ prevails. the key. Starting with 3.8, the key is evaluated before the value, as proposed by :pep:`572`. -.. versionchanged:: next +.. versionchanged:: 3.15 Unpacking with the ``**`` operator is now allowed in dictionary comprehensions. .. _genexpr: diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index c97058119ae838..515424424c1773 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -1105,7 +1105,7 @@ conflict. and kill the process. Only enable this in environments where the huge-page pool is properly sized and fork-safety is not a concern. - .. versionadded:: next + .. versionadded:: 3.15 .. envvar:: PYTHONLEGACYWINDOWSFSENCODING diff --git a/Include/patchlevel.h b/Include/patchlevel.h index ea42c123116959..117b041cdc11ee 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -24,10 +24,10 @@ #define PY_MINOR_VERSION 15 #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.15.0a5+" +#define PY_VERSION "3.15.0a6" /*--end constants--*/ diff --git a/Lib/pydoc_data/module_docs.py b/Lib/pydoc_data/module_docs.py index f6d84a60b43a12..76a2c18bdb2f0e 100644 --- a/Lib/pydoc_data/module_docs.py +++ b/Lib/pydoc_data/module_docs.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Sun Oct 12 12:02:22 2025 +# Autogenerated by Sphinx on Wed Feb 11 14:22:57 2026 # as part of the release process. module_docs = { @@ -23,7 +23,6 @@ 'bisect': 'bisect#module-bisect', 'builtins': 'builtins#module-builtins', 'bz2': 'bz2#module-bz2', - 'cProfile': 'profile#module-cProfile', 'calendar': 'calendar#module-calendar', 'cgi': 'cgi#module-cgi', 'cgitb': 'cgitb#module-cgitb', @@ -149,6 +148,7 @@ 'mailcap': 'mailcap#module-mailcap', 'marshal': 'marshal#module-marshal', 'math': 'math#module-math', + 'math.integer': 'math.integer#module-math.integer', 'mimetypes': 'mimetypes#module-mimetypes', 'mmap': 'mmap#module-mmap', 'modulefinder': 'modulefinder#module-modulefinder', @@ -183,8 +183,10 @@ 'posix': 'posix#module-posix', 'pprint': 'pprint#module-pprint', 'profile': 'profile#module-profile', - 'profiling.sampling': 'profile#module-profiling.sampling', - 'pstats': 'profile#module-pstats', + 'profiling': 'profiling#module-profiling', + 'profiling.sampling': 'profiling.sampling#module-profiling.sampling', + 'profiling.tracing': 'profiling.tracing#module-profiling.tracing', + 'pstats': 'pstats#module-pstats', 'pty': 'pty#module-pty', 'pwd': 'pwd#module-pwd', 'py_compile': 'py_compile#module-py_compile', diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index e2d3a5184d87d5..32cf9a995bae3d 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Wed Jan 14 16:41:25 2026 +# Autogenerated by Sphinx on Wed Feb 11 14:22:57 2026 # as part of the release process. topics = { @@ -46,11 +46,10 @@ | "[" [target_list] "]" | attributeref | subscription - | slicing | "*" target -(See section Primaries for the syntax definitions for *attributeref*, -*subscription*, and *slicing*.) +(See section Primaries for the syntax definitions for *attributeref* +and *subscription*.) An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter @@ -59,12 +58,11 @@ Assignment is defined recursively depending on the form of the target (list). When a target is part of a mutable object (an attribute -reference, subscription or slicing), the mutable object must -ultimately perform the assignment and decide about its validity, and -may raise an exception if the assignment is unacceptable. The rules -observed by various types and the exceptions raised are given with the -definition of the object types (see section The standard type -hierarchy). +reference or subscription), the mutable object must ultimately perform +the assignment and decide about its validity, and may raise an +exception if the assignment is unacceptable. The rules observed by +various types and the exceptions raised are given with the definition +of the object types (see section The standard type hierarchy). Assignment of an object to a target list, optionally enclosed in parentheses or square brackets, is recursively defined as follows. @@ -130,9 +128,13 @@ class Cls: attributes, such as properties created with "property()". * If the target is a subscription: The primary expression in the - reference is evaluated. It should yield either a mutable sequence - object (such as a list) or a mapping object (such as a dictionary). - Next, the subscript expression is evaluated. + reference is evaluated. Next, the subscript expression is evaluated. + Then, the primary’s "__setitem__()" method is called with two + arguments: the subscript and the assigned object. + + Typically, "__setitem__()" is defined on mutable sequence objects + (such as lists) and mapping objects (such as dictionaries), and + behaves as follows. If the primary is a mutable sequence object (such as a list), the subscript must yield an integer. If it is negative, the sequence’s @@ -149,27 +151,17 @@ class Cls: existing key/value pair with the same key value, or insert a new key/value pair (if no key with the same value existed). - For user-defined objects, the "__setitem__()" method is called with - appropriate arguments. - -* If the target is a slicing: The primary expression in the reference - is evaluated. It should yield a mutable sequence object (such as a - list). The assigned object should be a sequence object of the same - type. Next, the lower and upper bound expressions are evaluated, - insofar they are present; defaults are zero and the sequence’s - length. The bounds should evaluate to integers. If either bound is - negative, the sequence’s length is added to it. The resulting - bounds are clipped to lie between zero and the sequence’s length, - inclusive. Finally, the sequence object is asked to replace the - slice with the items of the assigned sequence. The length of the - slice may be different from the length of the assigned sequence, - thus changing the length of the target sequence, if the target - sequence allows it. - -**CPython implementation detail:** In the current implementation, the -syntax for targets is taken to be the same as for expressions, and -invalid syntax is rejected during the code generation phase, causing -less detailed error messages. + If the target is a slicing: The primary expression should evaluate + to a mutable sequence object (such as a list). The assigned object + should be *iterable*. The slicing’s lower and upper bounds should be + integers; if they are "None" (or not present), the defaults are zero + and the sequence’s length. If either bound is negative, the + sequence’s length is added to it. The resulting bounds are clipped + to lie between zero and the sequence’s length, inclusive. Finally, + the sequence object is asked to replace the slice with the items of + the assigned sequence. The length of the slice may be different + from the length of the assigned sequence, thus changing the length + of the target sequence, if the target sequence allows it. Although the definition of assignment implies that overlaps between the left-hand side and the right-hand side are ‘simultaneous’ (for @@ -196,7 +188,7 @@ class Cls: binary operation and an assignment statement: augmented_assignment_stmt: augtarget augop (expression_list | yield_expression) - augtarget: identifier | attributeref | subscription | slicing + augtarget: identifier | attributeref | subscription augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" | ">>=" | "<<=" | "&=" | "^=" | "|=" @@ -921,7 +913,7 @@ class to a new value, *value*. binary operation and an assignment statement: augmented_assignment_stmt: augtarget augop (expression_list | yield_expression) - augtarget: identifier | attributeref | subscription | slicing + augtarget: identifier | attributeref | subscription augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" | ">>=" | "<<=" | "&=" | "^=" | "|=" @@ -4914,8 +4906,8 @@ def inner(x): statement in the same code block. Trying to delete an unbound name raises a "NameError" exception. -Deletion of attribute references, subscriptions and slicings is passed -to the primary object involved; deletion of a slicing is in general +Deletion of attribute references and subscriptions is passed to the +primary object involved; deletion of a slicing is in general equivalent to assignment of an empty slice of the right type (but even this is determined by the sliced object). @@ -4931,8 +4923,8 @@ def inner(x): dict_display: "{" [dict_item_list | dict_comprehension] "}" dict_item_list: dict_item ("," dict_item)* [","] + dict_comprehension: dict_item comp_for dict_item: expression ":" expression | "**" or_expr - dict_comprehension: expression ":" expression comp_for A dictionary display yields a new dictionary object. @@ -4951,11 +4943,22 @@ def inner(x): Added in version 3.5: Unpacking into dictionary displays, originally proposed by **PEP 448**. -A dict comprehension, in contrast to list and set comprehensions, -needs two expressions separated with a colon followed by the usual -“for” and “if” clauses. When the comprehension is run, the resulting -key and value elements are inserted in the new dictionary in the order -they are produced. +A dict comprehension may take one of two forms: + +* The first form uses two expressions separated with a colon followed + by the usual “for” and “if” clauses. When the comprehension is run, + the resulting key and value elements are inserted in the new + dictionary in the order they are produced. + +* The second form uses a single expression prefixed by the "**" + dictionary unpacking operator followed by the usual “for” and “if” + clauses. When the comprehension is evaluated, the expression is + evaluated and then unpacked, inserting zero or more key/value pairs + into the new dictionary. + +Both forms of dictionary comprehension retain the property that if the +same key is specified multiple times, the associated value in the +resulting dictionary will be the last one specified. Restrictions on the types of the key values are listed earlier in section The standard type hierarchy. (To summarize, the key type @@ -4967,6 +4970,9 @@ def inner(x): the evaluation order of key and value was not well-defined. In CPython, the value was evaluated before the key. Starting with 3.8, the key is evaluated before the value, as proposed by **PEP 572**. + +Changed in version 3.15.0a5 (unreleased): Unpacking with the "**" +operator is now allowed in dictionary comprehensions. ''', 'dynamic-features': r'''Interaction with dynamic features ********************************* @@ -6843,7 +6849,9 @@ def whats_on_the_telly(penguin=None): The *public names* defined by a module are determined by checking the module’s namespace for a variable named "__all__"; if defined, it must be a sequence of strings which are names defined or imported by that -module. The names given in "__all__" are all considered public and +module. Names containing non-ASCII characters must be in the +normalization form NFKC; see Non-ASCII characters in names for +details. The names given in "__all__" are all considered public and are required to exist. If "__all__" is not defined, the set of public names includes all names found in the module’s namespace which do not begin with an underscore character ("'_'"). "__all__" should contain @@ -7849,8 +7857,8 @@ class that has an "__rsub__()" method, "type(y).__rsub__(y, x)" is | value...}", "{expressions...}" | list display, dictionary display, set | | | display | +-------------------------------------------------+---------------------------------------+ -| "x[index]", "x[index:index]", | Subscription, slicing, call, | -| "x(arguments...)", "x.attribute" | attribute reference | +| "x[index]", "x[index:index]" "x(arguments...)", | Subscription (including slicing), | +| "x.attribute" | call, attribute reference | +-------------------------------------------------+---------------------------------------+ | "await x" | Await expression | +-------------------------------------------------+---------------------------------------+ @@ -8187,22 +8195,32 @@ class C: pass # a class with no methods (yet) and so forth. Missing slice items are always filled in with "None". -object.__getitem__(self, key) +object.__getitem__(self, subscript) + + Called to implement *subscription*, that is, "self[subscript]". See + Subscriptions and slicings for details on the syntax. - Called to implement evaluation of "self[key]". For *sequence* - types, the accepted keys should be integers. Optionally, they may - support "slice" objects as well. Negative index support is also - optional. If *key* is of an inappropriate type, "TypeError" may be - raised; if *key* is a value outside the set of indexes for the - sequence (after any special interpretation of negative values), - "IndexError" should be raised. For *mapping* types, if *key* is - missing (not in the container), "KeyError" should be raised. + There are two types of built-in objects that support subscription + via "__getitem__()": + + * **sequences**, where *subscript* (also called *index*) should be + an integer or a "slice" object. See the sequence documentation + for the expected behavior, including handling "slice" objects and + negative indices. + + * **mappings**, where *subscript* is also called the *key*. See + mapping documentation for the expected behavior. + + If *subscript* is of an inappropriate type, "__getitem__()" should + raise "TypeError". If *subscript* has an inappropriate value, + "__getitem__()" should raise an "LookupError" or one of its + subclasses ("IndexError" for sequences; "KeyError" for mappings). Note: - "for" loops expect that an "IndexError" will be raised for - illegal indexes to allow proper detection of the end of the - sequence. + The sequence iteration protocol (used, for example, in "for" + loops), expects that an "IndexError" will be raised for illegal + indexes to allow proper detection of the end of a sequence. Note: @@ -8292,37 +8310,40 @@ class C: pass # a class with no methods (yet) 'slicings': r'''Slicings ******** -A slicing selects a range of items in a sequence object (e.g., a -string, tuple or list). Slicings may be used as expressions or as -targets in assignment or "del" statements. The syntax for a slicing: - - slicing: primary "[" slice_list "]" - slice_list: slice_item ("," slice_item)* [","] - slice_item: expression | proper_slice - proper_slice: [lower_bound] ":" [upper_bound] [ ":" [stride] ] - lower_bound: expression - upper_bound: expression - stride: expression - -There is ambiguity in the formal syntax here: anything that looks like -an expression list also looks like a slice list, so any subscription -can be interpreted as a slicing. Rather than further complicating the -syntax, this is disambiguated by defining that in this case the -interpretation as a subscription takes priority over the -interpretation as a slicing (this is the case if the slice list -contains no proper slice). - -The semantics for a slicing are as follows. The primary is indexed -(using the same "__getitem__()" method as normal subscription) with a -key that is constructed from the slice list, as follows. If the slice -list contains at least one comma, the key is a tuple containing the -conversion of the slice items; otherwise, the conversion of the lone -slice item is the key. The conversion of a slice item that is an -expression is that expression. The conversion of a proper slice is a -slice object (see section The standard type hierarchy) whose "start", -"stop" and "step" attributes are the values of the expressions given -as lower bound, upper bound and stride, respectively, substituting -"None" for missing expressions. +A more advanced form of subscription, *slicing*, is commonly used to +extract a portion of a sequence. In this form, the subscript is a +*slice*: up to three expressions separated by colons. Any of the +expressions may be omitted, but a slice must contain at least one +colon: + + >>> number_names = ['zero', 'one', 'two', 'three', 'four', 'five'] + >>> number_names[1:3] + ['one', 'two'] + >>> number_names[1:] + ['one', 'two', 'three', 'four', 'five'] + >>> number_names[:3] + ['zero', 'one', 'two'] + >>> number_names[:] + ['zero', 'one', 'two', 'three', 'four', 'five'] + >>> number_names[::2] + ['zero', 'two', 'four'] + >>> number_names[:-3] + ['zero', 'one', 'two'] + >>> del number_names[4:] + >>> number_names + ['zero', 'one', 'two', 'three'] + +When a slice is evaluated, the interpreter constructs a "slice" object +whose "start", "stop" and "step" attributes, respectively, are the +results of the expressions between the colons. Any missing expression +evaluates to "None". This "slice" object is then passed to the +"__getitem__()" or "__class_getitem__()" *special method*, as above. + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[2:3] + subscripted with: slice(2, 3, None) + >>> demo[::'spam'] + subscripted with: slice(None, None, 'spam') ''', 'specialattrs': r'''Special Attributes ****************** @@ -9557,22 +9578,32 @@ class of a class is known as that class’s *metaclass*, and most and so forth. Missing slice items are always filled in with "None". -object.__getitem__(self, key) +object.__getitem__(self, subscript) + + Called to implement *subscription*, that is, "self[subscript]". See + Subscriptions and slicings for details on the syntax. + + There are two types of built-in objects that support subscription + via "__getitem__()": - Called to implement evaluation of "self[key]". For *sequence* - types, the accepted keys should be integers. Optionally, they may - support "slice" objects as well. Negative index support is also - optional. If *key* is of an inappropriate type, "TypeError" may be - raised; if *key* is a value outside the set of indexes for the - sequence (after any special interpretation of negative values), - "IndexError" should be raised. For *mapping* types, if *key* is - missing (not in the container), "KeyError" should be raised. + * **sequences**, where *subscript* (also called *index*) should be + an integer or a "slice" object. See the sequence documentation + for the expected behavior, including handling "slice" objects and + negative indices. + + * **mappings**, where *subscript* is also called the *key*. See + mapping documentation for the expected behavior. + + If *subscript* is of an inappropriate type, "__getitem__()" should + raise "TypeError". If *subscript* has an inappropriate value, + "__getitem__()" should raise an "LookupError" or one of its + subclasses ("IndexError" for sequences; "KeyError" for mappings). Note: - "for" loops expect that an "IndexError" will be raised for - illegal indexes to allow proper detection of the end of the - sequence. + The sequence iteration protocol (used, for example, in "for" + loops), expects that an "IndexError" will be raised for illegal + indexes to allow proper detection of the end of a sequence. Note: @@ -10262,6 +10293,8 @@ class is used in a class pattern with positional arguments, each Like "find()", but raise "ValueError" when the substring is not found. For example: + >>> 'spam, spam, spam'.index('spam') + 0 >>> 'spam, spam, spam'.index('eggs') Traceback (most recent call last): File "", line 1, in @@ -10277,6 +10310,18 @@ class is used in a class pattern with positional arguments, each there is at least one character, "False" otherwise. A character "c" is alphanumeric if one of the following returns "True": "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()". + For example: + + .. doctest:: + + >>> 'abc123'.isalnum() + True + >>> 'abc123!@#'.isalnum() + False + >>> ''.isalnum() + False + >>> ' '.isalnum() + False str.isalpha() @@ -10538,6 +10583,17 @@ class is used in a class pattern with positional arguments, each found, return a 3-tuple containing the string itself, followed by two empty strings. + For example: + + >>> 'Monty Python'.partition(' ') + ('Monty', ' ', 'Python') + >>> "Monty Python's Flying Circus".partition(' ') + ('Monty', ' ', "Python's Flying Circus") + >>> 'Monty Python'.partition('-') + ('Monty Python', '', '') + + See also "rpartition()". + str.removeprefix(prefix, /) If the string starts with the *prefix* string, return @@ -10600,7 +10656,18 @@ class is used in a class pattern with positional arguments, each str.rindex(sub[, start[, end]]) Like "rfind()" but raises "ValueError" when the substring *sub* is - not found. + not found. For example: + + >>> 'spam, spam, spam'.rindex('spam') + 12 + >>> 'spam, spam, spam'.rindex('eggs') + Traceback (most recent call last): + File "", line 1, in + 'spam, spam, spam'.rindex('eggs') + ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^ + ValueError: substring not found + + See also "index()" and "find()". str.rjust(width, fillchar=' ', /) @@ -10617,6 +10684,17 @@ class is used in a class pattern with positional arguments, each found, return a 3-tuple containing two empty strings, followed by the string itself. + For example: + + >>> 'Monty Python'.rpartition(' ') + ('Monty', ' ', 'Python') + >>> "Monty Python's Flying Circus".rpartition(' ') + ("Monty Python's Flying", ' ', 'Circus') + >>> 'Monty Python'.rpartition('-') + ('', '', 'Monty Python') + + See also "partition()". + str.rsplit(sep=None, maxsplit=-1) Return a list of the words in the string, using *sep* as the @@ -10632,21 +10710,23 @@ class is used in a class pattern with positional arguments, each *chars* argument is a string specifying the set of characters to be removed. If omitted or "None", the *chars* argument defaults to removing whitespace. The *chars* argument is not a suffix; rather, - all combinations of its values are stripped: + all combinations of its values are stripped. For example: >>> ' spacious '.rstrip() ' spacious' >>> 'mississippi'.rstrip('ipz') 'mississ' - See "str.removesuffix()" for a method that will remove a single - suffix string rather than all of a set of characters. For example: + See "removesuffix()" for a method that will remove a single suffix + string rather than all of a set of characters. For example: >>> 'Monty Python'.rstrip(' Python') 'M' >>> 'Monty Python'.removesuffix(' Python') 'Monty' + See also "strip()". + str.split(sep=None, maxsplit=-1) Return a list of the words in the string, using *sep* as the @@ -10771,6 +10851,17 @@ class is used in a class pattern with positional arguments, each With optional *start*, test string beginning at that position. With optional *end*, stop comparing string at that position. + For example: + + >>> 'Python'.startswith('Py') + True + >>> 'a tuple of prefixes'.startswith(('at', 'a')) + True + >>> 'Python is amazing'.startswith('is', 7) + True + + See also "endswith()" and "removeprefix()". + str.strip(chars=None, /) Return a copy of the string with the leading and trailing @@ -10778,7 +10869,9 @@ class is used in a class pattern with positional arguments, each set of characters to be removed. If omitted or "None", the *chars* argument defaults to removing whitespace. The *chars* argument is not a prefix or suffix; rather, all combinations of its values are - stripped: + stripped. + + For example: >>> ' spacious '.strip() 'spacious' @@ -10789,12 +10882,16 @@ class is used in a class pattern with positional arguments, each stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in *chars*. A similar action takes place on the - trailing end. For example: + trailing end. + + For example: >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' >>> comment_string.strip('.#! ') 'Section 3.2.1 Issue #32' + See also "rstrip()". + str.swapcase() Return a copy of the string with uppercase characters converted to @@ -10851,6 +10948,12 @@ class is used in a class pattern with positional arguments, each You can use "str.maketrans()" to create a translation map from character-to-character mappings in different formats. + The following example uses a mapping to replace "'a'" with "'X'", + "'b'" with "'Y'", and delete "'c'": + + >>> 'abc123'.translate({ord('a'): 'X', ord('b'): 'Y', ord('c'): None}) + 'XY123' + See also the "codecs" module for a more flexible approach to custom character mappings. @@ -11445,62 +11548,168 @@ class is used in a class pattern with positional arguments, each ''', - 'subscriptions': r'''Subscriptions -************* + 'subscriptions': r'''Subscriptions and slicings +************************** + +The *subscription* syntax is usually used for selecting an element +from a container – for example, to get a value from a "dict": + + >>> digits_by_name = {'one': 1, 'two': 2} + >>> digits_by_name['two'] # Subscripting a dictionary using the key 'two' + 2 + +In the subscription syntax, the object being subscribed – a primary – +is followed by a *subscript* in square brackets. In the simplest case, +the subscript is a single expression. -The subscription of an instance of a container class will generally -select an element from the container. The subscription of a *generic -class* will generally return a GenericAlias object. +Depending on the type of the object being subscribed, the subscript is +sometimes called a *key* (for mappings), *index* (for sequences), or +*type argument* (for *generic types*). Syntactically, these are all +equivalent: - subscription: primary "[" flexible_expression_list "]" + >>> colors = ['red', 'blue', 'green', 'black'] + >>> colors[3] # Subscripting a list using the index 3 + 'black' -When an object is subscripted, the interpreter will evaluate the -primary and the expression list. + >>> list[str] # Parameterizing the list type using the type argument str + list[str] -The primary must evaluate to an object that supports subscription. An -object may support subscription through defining one or both of -"__getitem__()" and "__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 +At runtime, the interpreter will evaluate the primary and the +subscript, and call the primary’s "__getitem__()" or +"__class_getitem__()" *special method* with the subscript as argument. +For more details on which of these methods is called, see __class_getitem__ versus __getitem__. -If the expression list contains at least one comma, or if any of the -expressions are starred, the expression list will evaluate to a -"tuple" containing the items of the expression list. Otherwise, the -expression list will evaluate to the value of the list’s sole member. - -Changed in version 3.11: Expressions in an expression list may be -starred. See **PEP 646**. - -For built-in objects, there are two types of objects that support -subscription via "__getitem__()": - -1. Mappings. 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. An example of a builtin mapping class is - the "dict" class. - -2. Sequences. If the primary is a *sequence*, the expression list must - evaluate to an "int" or a "slice" (as discussed in the following - section). Examples of builtin sequence classes include the "str", - "list" and "tuple" classes. - -The formal syntax makes no special provision for negative indices in -*sequences*. However, built-in sequences all provide a "__getitem__()" -method that interprets negative indices by adding the length of the -sequence 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 occurs in the object’s -"__getitem__()" method, subclasses overriding this method will need to -explicitly add that support. - -A "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. +To show how subscription works, we can define a custom object that +implements "__getitem__()" and prints out the value of the subscript: + + >>> class SubscriptionDemo: + ... def __getitem__(self, key): + ... print(f'subscripted with: {key!r}') + ... + >>> demo = SubscriptionDemo() + >>> demo[1] + subscripted with: 1 + >>> demo['a' * 3] + subscripted with: 'aaa' + +See "__getitem__()" documentation for how built-in types handle +subscription. + +Subscriptions may also be used as targets in assignment or deletion +statements. In these cases, the interpreter will call the subscripted +object’s "__setitem__()" or "__delitem__()" *special method*, +respectively, instead of "__getitem__()". + + >>> colors = ['red', 'blue', 'green', 'black'] + >>> colors[3] = 'white' # Setting item at index + >>> colors + ['red', 'blue', 'green', 'white'] + >>> del colors[3] # Deleting item at index 3 + >>> colors + ['red', 'blue', 'green'] + +All advanced forms of *subscript* documented in the following sections +are also usable for assignment and deletion. + + +Slicings +======== + +A more advanced form of subscription, *slicing*, is commonly used to +extract a portion of a sequence. In this form, the subscript is a +*slice*: up to three expressions separated by colons. Any of the +expressions may be omitted, but a slice must contain at least one +colon: + + >>> number_names = ['zero', 'one', 'two', 'three', 'four', 'five'] + >>> number_names[1:3] + ['one', 'two'] + >>> number_names[1:] + ['one', 'two', 'three', 'four', 'five'] + >>> number_names[:3] + ['zero', 'one', 'two'] + >>> number_names[:] + ['zero', 'one', 'two', 'three', 'four', 'five'] + >>> number_names[::2] + ['zero', 'two', 'four'] + >>> number_names[:-3] + ['zero', 'one', 'two'] + >>> del number_names[4:] + >>> number_names + ['zero', 'one', 'two', 'three'] + +When a slice is evaluated, the interpreter constructs a "slice" object +whose "start", "stop" and "step" attributes, respectively, are the +results of the expressions between the colons. Any missing expression +evaluates to "None". This "slice" object is then passed to the +"__getitem__()" or "__class_getitem__()" *special method*, as above. + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[2:3] + subscripted with: slice(2, 3, None) + >>> demo[::'spam'] + subscripted with: slice(None, None, 'spam') + + +Comma-separated subscripts +========================== + +The subscript can also be given as two or more comma-separated +expressions or slices: + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[1, 2, 3] + subscripted with: (1, 2, 3) + >>> demo[1:2, 3] + subscripted with: (slice(1, 2, None), 3) + +This form is commonly used with numerical libraries for slicing multi- +dimensional data. In this case, the interpreter constructs a "tuple" +of the results of the expressions or slices, and passes this tuple to +the "__getitem__()" or "__class_getitem__()" *special method*, as +above. + +The subscript may also be given as a single expression or slice +followed by a comma, to specify a one-element tuple: + + >>> demo['spam',] + subscripted with: ('spam',) + + +“Starred” subscriptions +======================= + +Added in version 3.11: Expressions in *tuple_slices* may be starred. +See **PEP 646**. + +The subscript can also contain a starred expression. In this case, the +interpreter unpacks the result into a tuple, and passes this tuple to +"__getitem__()" or "__class_getitem__()": + + # continuing with the SubscriptionDemo instance defined above: + >>> demo[*range(10)] + subscripted with: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) + +Starred expressions may be combined with comma-separated expressions +and slices: + + >>> demo['a', 'b', *range(3), 'c'] + subscripted with: ('a', 'b', 0, 1, 2, 'c') + + +Formal subscription grammar +=========================== + + subscription: primary '[' subscript ']' + subscript: single_subscript | tuple_subscript + single_subscript: proper_slice | assignment_expression + proper_slice: [expression] ":" [expression] [ ":" [expression] ] + tuple_subscript: ','.(single_subscript | starred_expression)+ [','] + +Recall that the "|" operator denotes ordered choice. Specifically, in +"subscript", if both alternatives would match, the first +("single_subscript") has priority. ''', 'truth': r'''Truth Value Testing ******************* @@ -11906,10 +12115,19 @@ def foo(): "a[-2]" equals "a[n-2]", the second to last item of sequence a with length "n". -Sequences also support slicing: "a[i:j]" selects all items with index -*k* such that *i* "<=" *k* "<" *j*. When used as an expression, a -slice is a sequence of the same type. The comment above about negative -indexes also applies to negative slice positions. +The resulting value must be a nonnegative integer less than the number +of items in the sequence. If it is not, an "IndexError" is raised. + +Sequences also support slicing: "a[start:stop]" selects all items with +index *k* such that *start* "<=" *k* "<" *stop*. When used as an +expression, a slice is a sequence of the same type. The comment above +about negative subscripts also applies to negative slice positions. +Note that no error is raised if a slice position is less than zero or +larger than the length of the sequence. + +If *start* is missing or "None", slicing behaves as if *start* was +zero. If *stop* is missing or "None", slicing behaves as if *stop* was +equal to the length of the sequence. Some sequences also support “extended slicing” with a third “step” parameter: "a[i:j:k]" selects all items of *a* with index *x* where "x @@ -11930,27 +12148,33 @@ def foo(): The following types are immutable sequences: Strings - A string is a sequence of values that represent Unicode code - points. All the code points in the range "U+0000 - U+10FFFF" can be - represented in a string. Python doesn’t have a char type; instead, - every code point in the string is represented as a string object - with length "1". The built-in function "ord()" converts a code - point from its string form to an integer in the range "0 - 10FFFF"; - "chr()" converts an integer in the range "0 - 10FFFF" to the - corresponding length "1" string object. "str.encode()" can be used - to convert a "str" to "bytes" using the given text encoding, and + A string ("str") is a sequence of values that represent + *characters*, or more formally, *Unicode code points*. All the code + points in the range "0" to "0x10FFFF" can be represented in a + string. + + Python doesn’t have a dedicated *character* type. Instead, every + code point in the string is represented as a string object with + length "1". + + The built-in function "ord()" converts a code point from its string + form to an integer in the range "0" to "0x10FFFF"; "chr()" converts + an integer in the range "0" to "0x10FFFF" to the corresponding + length "1" string object. "str.encode()" can be used to convert a + "str" to "bytes" using the given text encoding, and "bytes.decode()" can be used to achieve the opposite. Tuples - The items of a tuple are arbitrary Python objects. Tuples of two or - more items are formed by comma-separated lists of expressions. A - tuple of one item (a ‘singleton’) can be formed by affixing a comma - to an expression (an expression by itself does not create a tuple, - since parentheses must be usable for grouping of expressions). An - empty tuple can be formed by an empty pair of parentheses. + The items of a "tuple" are arbitrary Python objects. Tuples of two + or more items are formed by comma-separated lists of expressions. + A tuple of one item (a ‘singleton’) can be formed by affixing a + comma to an expression (an expression by itself does not create a + tuple, since parentheses must be usable for grouping of + expressions). An empty tuple can be formed by an empty pair of + parentheses. Bytes - A bytes object is an immutable array. The items are 8-bit bytes, + A "bytes" object is an immutable array. The items are 8-bit bytes, represented by integers in the range 0 <= x < 256. Bytes literals (like "b'abc'") and the built-in "bytes()" constructor can be used to create bytes objects. Also, bytes objects can be decoded to @@ -12079,6 +12303,10 @@ def foo(): +----------------------------------------------------+----------------------------------------------------+ | Attribute | Meaning | |====================================================|====================================================| +| function.__builtins__ | A reference to the "dictionary" that holds the | +| | function’s builtins namespace. Added in version | +| | 3.10. | ++----------------------------------------------------+----------------------------------------------------+ | function.__globals__ | A reference to the "dictionary" that holds the | | | function’s global variables – the global namespace | | | of the module in which the function was defined. | diff --git a/Misc/NEWS.d/3.15.0a6.rst b/Misc/NEWS.d/3.15.0a6.rst new file mode 100644 index 00000000000000..c3e20e0f662fb2 --- /dev/null +++ b/Misc/NEWS.d/3.15.0a6.rst @@ -0,0 +1,1101 @@ +.. date: 2026-02-10-08-00-17 +.. gh-issue: 144648 +.. nonce: KEuUXp +.. release date: 2026-02-11 +.. section: macOS + +Allowed _remote_debugging to build on more OS versions by using +proc_listpids() rather than proc_listallpids(). + +.. + +.. date: 2026-02-09-23-01-49 +.. gh-issue: 124111 +.. nonce: WmQG7S +.. section: macOS + +Update macOS installer to use Tcl/Tk 9.0.3. + +.. + +.. date: 2026-02-09-22-43-47 +.. gh-issue: 144551 +.. nonce: VOfgfD +.. section: macOS + +Update macOS installer to use OpenSSL 3.5.5. + +.. + +.. date: 2026-01-05-21-36-58 +.. gh-issue: 80620 +.. nonce: p1bD58 +.. section: Windows + +Support negative timestamps in :func:`time.gmtime`, :func:`time.localtime`, +and various :mod:`datetime` functions. + +.. + +.. date: 2026-02-03-07-57-24 +.. gh-issue: 144415 +.. nonce: U3L15r +.. section: Tests + +The Android testbed now distinguishes between stdout/stderr messages which +were triggered by a newline, and those triggered by a manual call to +``flush``. This fixes logging of progress indicators and similar content. + +.. + +.. date: 2026-01-08-16-56-59 +.. gh-issue: 65784 +.. nonce: aKNo1U +.. section: Tests + +Add support for parametrized resource ``wantobjects`` in regrtests, which +allows to run Tkinter tests with the specified value of +:data:`!tkinter.wantobjects`, for example ``-u wantobjects=0``. + +.. + +.. date: 2026-01-21-12-34-05 +.. gh-issue: 144125 +.. nonce: TAz5uo +.. section: Security + +:mod:`~email.generator.BytesGenerator` will now refuse to serialize (write) +headers that are unsafely folded or delimited; see +:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas +Bloemsaat and Petr Viktorin in :gh:`121650`). + +.. + +.. date: 2026-01-16-14-40-31 +.. gh-issue: 143935 +.. nonce: U2YtKl +.. section: Security + +Fixed a bug in the folding of comments when flattening an email message +using a modern email policy. Comments consisting of a very long sequence of +non-foldable characters could trigger a forced line wrap that omitted the +required leading space on the continuation line, causing the remainder of +the comment to be interpreted as a new header field. This enabled header +injection with carefully crafted inputs. + +.. + +.. date: 2026-01-16-11-51-19 +.. gh-issue: 143925 +.. nonce: mrtcHW +.. section: Security + +Reject control characters in ``data:`` URL media types. + +.. + +.. date: 2026-01-16-11-43-47 +.. gh-issue: 143923 +.. nonce: DuytMe +.. section: Security + +Reject control characters in POP3 commands. + +.. + +.. date: 2026-01-16-11-41-06 +.. gh-issue: 143921 +.. nonce: AeCOor +.. section: Security + +Reject control characters in IMAP commands. + +.. + +.. date: 2026-01-16-11-13-15 +.. gh-issue: 143919 +.. nonce: kchwZV +.. section: Security + +Reject control characters in :class:`http.cookies.Morsel` fields and values. + +.. + +.. date: 2026-01-16-11-07-36 +.. gh-issue: 143916 +.. nonce: dpWeOD +.. section: Security + +Reject C0 control characters within wsgiref.headers.Headers fields, values, +and parameters. + +.. + +.. date: 2026-02-06-23-58-54 +.. gh-issue: 144538 +.. nonce: 5_OvGv +.. section: Library + +Bump the version of pip bundled in ensurepip to version 26.0.1 + +.. + +.. date: 2026-02-05-17-15-31 +.. gh-issue: 144493 +.. nonce: XuxwVu +.. section: Library + +Improve an exception error message in ``_overlapped.BindLocal()`` that is +raised when :meth:`asyncio.loop.sock_connect` is called on a +:class:`asyncio.ProactorEventLoop` with a socket that has an invalid address +family. + +.. + +.. date: 2026-02-03-14-16-49 +.. gh-issue: 144386 +.. nonce: 9Wa59r +.. section: Library + +Add support for arbitrary descriptors :meth:`!__enter__`, :meth:`!__exit__`, +:meth:`!__aenter__`, and :meth:`!__aexit__` in :class:`contextlib.ExitStack` +and :class:`contextlib.AsyncExitStack`, for consistency with the +:keyword:`with` and :keyword:`async with` statements. + +.. + +.. date: 2026-02-03-08-50-58 +.. gh-issue: 123471 +.. nonce: yF1Gym +.. section: Library + +Make concurrent iteration over +:class:`itertools.combinations_with_replacement` and +:class:`itertools.permutations` safe under free-threading. + +.. + +.. date: 2026-02-02-12-09-38 +.. gh-issue: 74453 +.. nonce: 19h4Z5 +.. section: Library + +Deprecate :func:`os.path.commonprefix` in favor of +:func:`os.path.commonpath` for path segment prefixes. + +The :func:`os.path.commonprefix` function is being deprecated due to having +a misleading name and module. The function is not safe to use for path +prefixes despite being included in a module about path manipulation, meaning +it is easy to accidentally introduce path traversal vulnerabilities into +Python programs by using this function. + +.. + +.. date: 2026-02-01-15-25-00 +.. gh-issue: 144380 +.. nonce: U7py_s +.. section: Library + +Improve performance of :class:`io.BufferedReader` line iteration by ~49%. + +.. + +.. date: 2026-01-31-17-15-49 +.. gh-issue: 144363 +.. nonce: X9f0sU +.. section: Library + +Update bundled `libexpat `_ to 2.7.4 + +.. + +.. date: 2026-01-30-13-23-06 +.. gh-issue: 140824 +.. nonce: J1OCrC +.. section: Library + +When :mod:`faulthandler` dumps the list of third-party extension modules, +ignore sub-modules of stdlib packages. Patch by Victor Stinner. + +.. + +.. date: 2026-01-27-14-23-10 +.. gh-issue: 144206 +.. nonce: l0un4U +.. section: Library + +Improve error messages for buffer overflow in :func:`fcntl.fcntl` and +:func:`fcntl.ioctl`. + +.. + +.. date: 2026-01-27-10-02-04 +.. gh-issue: 144264 +.. nonce: Wmzbol +.. section: Library + +Speed up Base64 decoding of data containing ignored characters (both in +non-strict mode and with an explicit *ignorechars* argument). It is now up +to 2 times faster for multiline Base64 data. + +.. + +.. date: 2026-01-27-09-58-52 +.. gh-issue: 144249 +.. nonce: mCIy95 +.. section: Library + +Add filename context to :exc:`OSError` exceptions raised by +:func:`ssl.SSLContext.load_cert_chain`, allowing users to have more context. + +.. + +.. date: 2026-01-27-00-03-41 +.. gh-issue: 132888 +.. nonce: yhTfUN +.. section: Library + +Fix incorrect use of :func:`ctypes.GetLastError` and add missing error +checks for Windows API calls in :mod:`!_pyrepl.windows_console`. + +.. + +.. date: 2026-01-26-12-30-57 +.. gh-issue: 142956 +.. nonce: X9CS8J +.. section: Library + +Updated :mod:`tomllib` to parse TOML 1.1.0. + +.. + +.. date: 2026-01-25-03-23-20 +.. gh-issue: 144217 +.. nonce: E1wVXH +.. section: Library + +:mod:`mimetypes`: Add support for DICOM files (for medical imaging) with the +official MIME type ``application/dicom``. Patch by Benedikt Johannes. + +.. + +.. date: 2026-01-24-23-11-17 +.. gh-issue: 144212 +.. nonce: IXqVL8 +.. section: Library + +Mime type ``image/jxl`` is now supported by :mod:`mimetypes`. + +.. + +.. date: 2026-01-24-13-49-05 +.. gh-issue: 143594 +.. nonce: nilGlg +.. section: Library + +Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` +methods. + +.. + +.. date: 2026-01-23-06-43-21 +.. gh-issue: 144169 +.. nonce: LFy9yi +.. section: Library + +Fix three crashes when non-string keyword arguments are supplied to objects +in the :mod:`ast` module. + +.. + +.. date: 2026-01-22-10-18-17 +.. gh-issue: 144128 +.. nonce: akwY06 +.. section: Library + +Fix a crash in :meth:`array.array.fromlist` when an element's +:meth:`~object.__index__` method mutates the input list during conversion. + +.. + +.. date: 2026-01-21-19-39-07 +.. gh-issue: 144100 +.. nonce: hLMZ8Y +.. section: Library + +Fixed a crash in ctypes when using a deprecated ``POINTER(str)`` type in +``argtypes``. Instead of aborting, ctypes now raises a proper Python +exception when the pointer target type is unresolved. + +.. + +.. date: 2026-01-20-20-54-46 +.. gh-issue: 143658 +.. nonce: v8i1jE +.. section: Library + +:mod:`importlib.metadata`: Use :meth:`str.lower` and :meth:`str.replace` to +further improve performance of +:meth:`!importlib.metadata.Prepared.normalize`. Patch by Hugo van Kemenade +and Henry Schreiner. + +.. + +.. date: 2026-01-20-16-35-55 +.. gh-issue: 144050 +.. nonce: 0kKFbF +.. section: Library + +Fix :func:`stat.filemode` in the pure-Python implementation to avoid +misclassifying invalid mode values as block devices. + +.. + +.. date: 2026-01-19-16-45-16 +.. gh-issue: 83069 +.. nonce: 0TaeH9 +.. section: Library + +:meth:`subprocess.Popen.wait`: when ``timeout`` is not ``None``, an +efficient event-driven mechanism now waits for process termination, if +available. Linux >= 5.3 uses :func:`os.pidfd_open` + :func:`select.poll`. +macOS and other BSD variants use :func:`select.kqueue` + ``KQ_FILTER_PROC`` ++ ``KQ_NOTE_EXIT``. Windows keeps using ``WaitForSingleObject`` (unchanged). +If none of these mechanisms are available, the function falls back to the +traditional busy loop (non-blocking call and short sleeps). Patch by +Giampaolo Rodola. + +.. + +.. date: 2026-01-19-12-48-59 +.. gh-issue: 144030 +.. nonce: 7OK_gB +.. section: Library + +The Python implementation of :func:`functools.lru_cache` differed from the +default C implementation in that it did not check that its argument is +callable. This discrepancy is now fixed and both raise a :exc:`TypeError`. + +.. + +.. date: 2026-01-19-10-26-59 +.. gh-issue: 144001 +.. nonce: dGj8Nk +.. section: Library + +Added the *ignorechars* parameter in :func:`binascii.a2b_base64` and +:func:`base64.b64decode`. + +.. + +.. date: 2026-01-19-00-57-40 +.. gh-issue: 144023 +.. nonce: 29XUcp +.. section: Library + +Fixed validation of file descriptor 0 in posix functions when used with +follow_symlinks parameter. + +.. + +.. date: 2026-01-18-14-35-37 +.. gh-issue: 143999 +.. nonce: MneN4O +.. section: Library + +Fix an issue where :func:`inspect.getgeneratorstate` and +:func:`inspect.getcoroutinestate` could fail for generators wrapped by +:func:`types.coroutine` in the suspended state. + +.. + +.. date: 2026-01-17-07-48-27 +.. gh-issue: 143952 +.. nonce: lqJ55y +.. section: Library + +Fixed :mod:`asyncio` debugging tools to work with new remote debugging API. +Patch by Bartosz Sławecki. + +.. + +.. date: 2026-01-16-14-02-39 +.. gh-issue: 143904 +.. nonce: rErHHA +.. section: Library + +:func:`struct.pack_into` now raises OverflowError instead of IndexError for +too large *offset* argument. + +.. + +.. date: 2026-01-16-10-53-17 +.. gh-issue: 143897 +.. nonce: hWJBHN +.. section: Library + +Remove the :meth:`!isxidstart` and :meth:`!isxidcontinue` methods of +:data:`unicodedata.ucd_3_2_0`. They are now only exposed as +:func:`unicodedata.isxidstart` and :func:`unicodedata.isxidcontinue`. + +.. + +.. date: 2026-01-16-06-22-10 +.. gh-issue: 143831 +.. nonce: VLBTLp +.. section: Library + +:class:`annotationlib.ForwardRef` objects are now hashable when created from +annotation scopes with closures. Previously, hashing such objects would +throw an exception. Patch by Bartosz Sławecki. + +.. + +.. date: 2026-01-15-16-04-39 +.. gh-issue: 143874 +.. nonce: 1qQgvo +.. section: Library + +Fixed a bug in :mod:`pdb` where expression results were not sent back to +remote client. + +.. + +.. date: 2026-01-14-20-35-40 +.. gh-issue: 143754 +.. nonce: m2NQXA +.. section: Library + +Add new :mod:`tkinter` widget methods :meth:`!pack_content`, +:meth:`!place_content` and :meth:`!grid_content` which are alternative +spelling of old :meth:`!*_slaves` methods. + +.. + +.. date: 2026-01-13-16-19-50 +.. gh-issue: 143756 +.. nonce: LQOra1 +.. section: Library + +Fix potential thread safety issues in :mod:`ssl` module. + +.. + +.. date: 2026-01-13-15-56-03 +.. gh-issue: 132604 +.. nonce: lvjNTr +.. section: Library + +Previously, :class:`~typing.Protocol` classes that were not decorated with +:deco:`~typing.runtime_checkable`, but that inherited from another +``Protocol`` class that did have this decorator, could be used in +:func:`isinstance` and :func:`issubclass` checks. This behavior is now +deprecated and such checks will throw a :exc:`TypeError` in Python 3.20. +Patch by Bartosz Sławecki. + +.. + +.. date: 2026-01-13-10-38-43 +.. gh-issue: 143543 +.. nonce: DeQRCO +.. section: Library + +Fix a crash in itertools.groupby that could occur when a user-defined +:meth:`~object.__eq__` method re-enters the iterator during key comparison. + +.. + +.. date: 2026-01-11-14-14-19 +.. gh-issue: 143689 +.. nonce: fzHJ2W +.. section: Library + +Fix :meth:`io.BufferedReader.read1` state cleanup on buffer allocation +failure. + +.. + +.. date: 2026-01-09-12-37-19 +.. gh-issue: 143602 +.. nonce: V8vQpj +.. section: Library + +Fix a inconsistency issue in :meth:`~io.RawIOBase.write` that leads to +unexpected buffer overwrite by deduplicating the buffer exports. + +.. + +.. date: 2026-01-07-19-01-59 +.. gh-issue: 142434 +.. nonce: SHRS5p +.. section: Library + +Use ``ppoll()`` if available in :func:`select.poll` to have a timeout +resolution of 1 nanosecond, instead of a resolution of 1 ms. Patch by Victor +Stinner. + +.. + +.. date: 2026-01-07-11-57-59 +.. gh-issue: 140557 +.. nonce: 3P6-nW +.. section: Library + +:class:`array.array` buffers now have the same alignment when empty as when +allocated. Unaligned buffers can still be created by slicing. + +.. + +.. date: 2026-01-05-05-31-05 +.. gh-issue: 143423 +.. nonce: X7YdnR +.. section: Library + +Fix free-threaded build detection in the sampling profiler when +Py_GIL_DISABLED is set to 0. + +.. + +.. date: 2025-12-28-15-55-53 +.. gh-issue: 101178 +.. nonce: 26jYPs +.. section: Library + +Add Ascii85, Base85, and Z85 support to :mod:`binascii` and improve the +performance of the base-85 converters in :mod:`base64`. + +.. + +.. date: 2025-12-19-11-30-31 +.. gh-issue: 142966 +.. nonce: PzGiv2 +.. section: Library + +Fix :func:`!ctypes.POINTER.set_type` not updating the format string to match +the type. + +.. + +.. date: 2025-12-15-02-02-45 +.. gh-issue: 142555 +.. nonce: EC9QN_ +.. section: Library + +:mod:`array`: fix a crash in ``a[i] = v`` when converting *i* to an index +via :meth:`i.__index__ ` or :meth:`i.__float__ +` mutates the array. + +.. + +.. date: 2025-12-08-18-40-17 +.. gh-issue: 142438 +.. nonce: tH-Y16 +.. section: Library + +Fix _decimal builds configured with EXTRA_FUNCTIONALITY by correcting the +Context.apply wrapper to pass the right argument. + +.. + +.. date: 2025-11-22-20-30-00 +.. gh-issue: 141860 +.. nonce: frksvr +.. section: Library + +Add an ``on_error`` keyword-only parameter to +:func:`multiprocessing.set_forkserver_preload` to control how import +failures during module preloading are handled. Accepts ``'ignore'`` +(default, silent), ``'warn'`` (emit :exc:`ImportWarning`), or ``'fail'`` +(raise exception). Contributed by Nick Neumann and Gregory P. Smith. + +.. + +.. date: 2025-11-06-12-03-29 +.. gh-issue: 125346 +.. nonce: 7Gfpgw +.. section: Library + +Accepting ``+`` and ``/`` characters with an alternative alphabet in +:func:`base64.b64decode` and :func:`base64.urlsafe_b64decode` is now +deprecated. In future Python versions they will be errors in the strict mode +and discarded in the non-strict mode. + +.. + +.. date: 2025-10-27-00-13-04 +.. gh-issue: 140715 +.. nonce: WkozE0 +.. section: Library + +Add ``'%F'`` support to :meth:`~datetime.datetime.strptime`. + +.. + +.. date: 2024-11-27-13-11-16 +.. gh-issue: 67041 +.. nonce: ym2WKK +.. section: Library + +Add the *missing_as_none* parameter to :func:`~urllib.parse.urlparse`, +:func:`~urllib.parse.urlsplit` and :func:`~urllib.parse.urldefrag` +functions. Add the *keep_empty* parameter to +:func:`~urllib.parse.urlunparse` and :func:`~urllib.parse.urlunsplit` +functions. This allows to distinguish between empty and not defined URI +components and preserve empty components. + +.. + +.. date: 2020-07-14-23-54-18 +.. gh-issue: 77188 +.. nonce: TyI3_Q +.. section: Library + +The :mod:`pickle` module now properly handles name-mangled private methods. + +.. + +.. date: 2026-01-13-01-21-20 +.. gh-issue: 143774 +.. nonce: rqGwX1 +.. section: IDLE + +Better explain the operation of Format / Format Paragraph. + +.. + +.. date: 2026-02-10-12-08-58 +.. gh-issue: 134584 +.. nonce: P9LDy5 +.. section: Core and Builtins + +Optimize and eliminate ref-counting in ``_BINARY_OP_SUBSCR_LIST_SLICE`` + +.. + +.. date: 2026-02-08-18-13-38 +.. gh-issue: 144563 +.. nonce: hb3kpp +.. section: Core and Builtins + +Fix interaction of the Tachyon profiler and :mod:`ctypes` and other modules +that load the Python shared library (if present) in an independent map as +this was causing the mechanism that loads the binary information to be +confused. Patch by Pablo Galindo + +.. + +.. date: 2026-02-08-12-47-27 +.. gh-issue: 144601 +.. nonce: E4Yi9J +.. section: Core and Builtins + +Fix crash when importing a module whose ``PyInit`` function raises an +exception from a subinterpreter. + +.. + +.. date: 2026-02-06-17-59-47 +.. gh-issue: 144549 +.. nonce: 5BhPlY +.. section: Core and Builtins + +Fix building the tail calling interpreter on Visual Studio 2026 with +free-threading. + +.. + +.. date: 2026-02-05-13-30-00 +.. gh-issue: 144513 +.. nonce: IjSTd7 +.. section: Core and Builtins + +Fix potential deadlock when using critical sections during stop-the-world +pauses in the free-threaded build. + +.. + +.. date: 2026-02-04-12-19-48 +.. gh-issue: 131798 +.. nonce: My5jLy +.. section: Core and Builtins + +Optimise ``_GUARD_TOS_SLICE`` in the JIT. + +.. + +.. date: 2026-02-04-11-19-45 +.. gh-issue: 144330 +.. nonce: kOowSb +.. section: Core and Builtins + +Move ``classmethod`` and ``staticmethod`` initialization from ``__init__()`` +to ``__new__()``. Patch by Victor Stinner. + +.. + +.. date: 2026-02-03-17-08-13 +.. gh-issue: 144446 +.. nonce: db5619 +.. section: Core and Builtins + +Fix data races in the free-threaded build when reading frame object +attributes while another thread is executing the frame. + +.. + +.. date: 2026-02-02-17-50-14 +.. gh-issue: 120321 +.. nonce: Xfr7tL +.. section: Core and Builtins + +Add ``gi_state``, ``cr_state``, and ``ag_state`` attributes to generators, +coroutines, and async generators that return the current state as a string +(e.g., ``GEN_RUNNING``). The :mod:`inspect` module functions +:func:`~inspect.getgeneratorstate`, :func:`~inspect.getcoroutinestate`, and +:func:`~inspect.getasyncgenstate` now return these attributes directly. + +.. + +.. date: 2026-02-02-17-07-34 +.. gh-issue: 141563 +.. nonce: GheXjr +.. section: Core and Builtins + +Fix thread safety of :c:macro:`! PyDateTime_IMPORT`. + +.. + +.. date: 2026-01-30-15-54-50 +.. gh-issue: 144280 +.. nonce: kgiP5R +.. section: Core and Builtins + +Fix a bug in JIT where the predicate symbol had no truthiness + +.. + +.. date: 2026-01-30-10-38-07 +.. gh-issue: 140550 +.. nonce: Us9vPD +.. section: Core and Builtins + +In :c:member:`PyModuleDef.m_slots`, allow slots that repeat information +present in :c:type:`PyModuleDef`. + +.. + +.. date: 2026-01-29-16-57-11 +.. gh-issue: 139103 +.. nonce: icXIEQ +.. section: Core and Builtins + +Improve scaling of :func:`~collections.namedtuple` instantiation in the +free-threaded build. + +.. + +.. date: 2026-01-29-02-18-08 +.. gh-issue: 144307 +.. nonce: CLbm_o +.. section: Core and Builtins + +Prevent a reference leak in module teardown at interpreter finalization. + +.. + +.. date: 2026-01-29-01-42-14 +.. gh-issue: 144319 +.. nonce: _7EtdB +.. section: Core and Builtins + +Add huge pages support for the pymalloc allocator. Patch by Pablo Galindo + +.. + +.. date: 2026-01-27-17-49-43 +.. gh-issue: 120321 +.. nonce: Vo7c9T +.. section: Core and Builtins + +Made ``gi_yieldfrom`` thread-safe in the free-threading build by using a +lightweight lock on the frame state. + +.. + +.. date: 2026-01-23-20-20-42 +.. gh-issue: 144194 +.. nonce: IbXfxd +.. section: Core and Builtins + +Fix error handling in perf jitdump initialization on memory allocation +failure. + +.. + +.. date: 2026-01-22-17-04-30 +.. gh-issue: 143962 +.. nonce: dQR1a9 +.. section: Core and Builtins + +Name suggestion for not normalized name suggests now the normalized name or +the closest name to the normalized name. If the suggested name is not ASCII, +include also its ASCII representation. + +.. + +.. date: 2026-01-22-16-20-16 +.. gh-issue: 144157 +.. nonce: dxyp7k +.. section: Core and Builtins + +:meth:`bytes.translate` now allows the compiler to unroll its loop more +usefully for a 2x speedup in the common no-deletions specified case. + +.. + +.. date: 2026-01-21-02-30-06 +.. gh-issue: 144068 +.. nonce: 9TTu7v +.. section: Core and Builtins + +Fix JIT tracer memory leak, ensure the JIT tracer state is freed when daemon +threads are cleaned up during interpreter shutdown. + +.. + +.. date: 2026-01-19-02-33-45 +.. gh-issue: 144012 +.. nonce: wVEEWs +.. section: Core and Builtins + +Check if the result is ``NULL`` in ``BINARY_OP_EXTENT`` opcode. + +.. + +.. date: 2026-01-19-01-56-44 +.. gh-issue: 144007 +.. nonce: 1xjdBf +.. section: Core and Builtins + +Eliminate redundant refcounting in the JIT for ``BINARY_OP``. + +.. + +.. date: 2026-01-19-01-26-12 +.. gh-issue: 144005 +.. nonce: Z3O33m +.. section: Core and Builtins + +Eliminate redundant refcounting from ``BINARY_OP_EXTEND``. + +.. + +.. date: 2026-01-16-23-19-38 +.. gh-issue: 143939 +.. nonce: w9TWch +.. section: Core and Builtins + +Fix erroneous "cannot reuse already awaited coroutine" error that could +occur when a generator was run during the process of clearing a coroutine's +frame. + +.. + +.. date: 2026-01-13-22-26-49 +.. gh-issue: 141805 +.. nonce: QzIKPS +.. section: Core and Builtins + +Fix crash in :class:`set` when objects with the same hash are concurrently +added to the set after removing an element with the same hash while the set +still contains elements with the same hash. + +.. + +.. date: 2026-01-11-20-11-36 +.. gh-issue: 143670 +.. nonce: klnGoD +.. section: Core and Builtins + +Fixes a crash in ``ga_repr_items_list`` function. + +.. + +.. date: 2026-01-10-10-58-36 +.. gh-issue: 143650 +.. nonce: k8mR4x +.. section: Core and Builtins + +Fix race condition in :mod:`importlib` where a thread could receive a stale +module reference when another thread's import fails. + +.. + +.. date: 2026-01-08-14-55-31 +.. gh-issue: 143569 +.. nonce: -Ltu3c +.. section: Core and Builtins + +Generator expressions in 3.15 now conform to the documented behavior when +the iterable does not support iteration. This matches the behavior in 3.14 +and earlier + +.. + +.. date: 2025-12-29-19-31-46 +.. gh-issue: 143192 +.. nonce: JxGAyl +.. section: Core and Builtins + +Improve performance of bitwise operations on multi-digit ints. + +.. + +.. date: 2025-12-24-13-19-16 +.. gh-issue: 132657 +.. nonce: _P4DDb +.. section: Core and Builtins + +If we are specializing to ``LOAD_GLOBAL_MODULE`` or ``LOAD_ATTR_MODULE``, +try to enable deferred reference counting for the value, if the object is +owned by a different thread. This applies to the free-threaded build only +and should improve scaling of multi-threaded programs. Note that when +deferred reference counting is enabled, the object will be deallocated by +the GC, rather than by :c:func:`Py_DECREF`. + +.. + +.. date: 2025-12-21-18-12-30 +.. gh-issue: 143055 +.. nonce: PzwccL +.. section: Core and Builtins + +Implement :pep:`798` (Unpacking in Comprehensions). Patch by Adam Hartz. + +.. + +.. date: 2025-11-29-10-06-06 +.. gh-issue: 142037 +.. nonce: OpIGzK +.. section: Core and Builtins + +Improve error messages for printf-style formatting. For errors in the format +string, always include the position of the start of the format unit. For +errors related to the formatted arguments, always include the number or the +name of the argument. Raise more specific errors and include more +information (type and number of arguments, most probable causes of error). + +.. + +.. date: 2025-10-24-17-30-51 +.. gh-issue: 140557 +.. nonce: X2GETk +.. section: Core and Builtins + +:class:`bytearray` buffers now have the same alignment when empty as when +allocated. Unaligned buffers can still be created by slicing. + +.. + +.. date: 2025-10-16-22-36-05 +.. gh-issue: 140232 +.. nonce: u3srgv +.. section: Core and Builtins + +Frozenset objects with immutable elements are no longer tracked by the +garbage collector. + +.. + +.. date: 2024-02-10-05-42-26 +.. gh-issue: 115231 +.. nonce: 6T7dzi +.. section: Core and Builtins + +Setup ``__module__`` attribute for built-in static methods. Patch by Sergey +B Kirpichev. + +.. + +.. date: 2026-01-16-15-04-26 +.. gh-issue: 143869 +.. nonce: vf94km +.. section: C API + +Added :c:func:`PyLong_GetNativeLayout`, :c:struct:`PyLongLayout`, +:c:struct:`PyLongExport`, :c:func:`PyLong_Export`, +:c:func:`PyLong_FreeExport`, :c:struct:`PyLongWriter`, +:c:func:`PyLongWriter_Create`, :c:func:`PyLongWriter_Finish` and +:c:func:`PyLongWriter_Discard` to the limited API. + +.. + +.. date: 2025-12-16-18-39-30 +.. gh-issue: 141070 +.. nonce: 4EKDZ1 +.. section: C API + +Renamed :c:func:`!PyUnstable_Object_Dump` to :c:func:`PyObject_Dump`. + +.. + +.. date: 2026-02-10-06-31-29 +.. gh-issue: 140421 +.. nonce: vxosUx +.. section: Build + +Disable the perf trampoline on older macOS versions where it cannot be +built. + +.. + +.. date: 2026-01-28-19-04-12 +.. gh-issue: 144309 +.. nonce: 3sMFOh +.. section: Build + +Build Python with POSIX 2024, instead of POSIX 2008. Patch by Victor +Stinner. + +.. + +.. date: 2026-01-27-23-39-26 +.. gh-issue: 144278 +.. nonce: tejFwL +.. section: Build + +Enables defining the ``_PY_IMPL_NAME`` and ``_PY_IMPL_CACHE_TAG`` +preprocessor definitions to override :data:`sys.implementation` at build +time. Definitions need to include quotes when setting to a string literal. +Setting the cache tag to ``NULL`` has the effect of completely disabling +automatic creation and use of ``.pyc`` files. + +.. + +.. date: 2026-01-17-15-31-19 +.. gh-issue: 143960 +.. nonce: Zi0EqR +.. section: Build + +Add support for OpenSSL 3.6, drop EOL 3.2. Patch by Hugo van Kemenade. + +.. + +.. date: 2026-01-16-14-27-53 +.. gh-issue: 143941 +.. nonce: TiaE-3 +.. section: Build + +Move WASI-related files to :file:`Platforms/WASI`. Along the way, leave a +deprecated :file:`Tools/wasm/wasi/__main__.py` behind for +backwards-compatibility. + +.. + +.. date: 2026-01-15-03-36-16 +.. gh-issue: 143842 +.. nonce: EZLutl +.. section: Build + +Prevent static builds from clashing with curses by making the optimizer +COLORS table static. diff --git a/Misc/NEWS.d/next/Build/2026-01-15-03-36-16.gh-issue-143842.EZLutl.rst b/Misc/NEWS.d/next/Build/2026-01-15-03-36-16.gh-issue-143842.EZLutl.rst deleted file mode 100644 index 4d5b1146463568..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-01-15-03-36-16.gh-issue-143842.EZLutl.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent static builds from clashing with curses by making the optimizer -COLORS table static. diff --git a/Misc/NEWS.d/next/Build/2026-01-16-14-27-53.gh-issue-143941.TiaE-3.rst b/Misc/NEWS.d/next/Build/2026-01-16-14-27-53.gh-issue-143941.TiaE-3.rst deleted file mode 100644 index 68839364a0ddee..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-01-16-14-27-53.gh-issue-143941.TiaE-3.rst +++ /dev/null @@ -1,3 +0,0 @@ -Move WASI-related files to :file:`Platforms/WASI`. Along the way, leave a -deprecated :file:`Tools/wasm/wasi/__main__.py` behind for -backwards-compatibility. diff --git a/Misc/NEWS.d/next/Build/2026-01-17-15-31-19.gh-issue-143960.Zi0EqR.rst b/Misc/NEWS.d/next/Build/2026-01-17-15-31-19.gh-issue-143960.Zi0EqR.rst deleted file mode 100644 index 2b8e01f937db76..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-01-17-15-31-19.gh-issue-143960.Zi0EqR.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for OpenSSL 3.6, drop EOL 3.2. Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst b/Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst deleted file mode 100644 index 49dbdd621851f6..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-01-27-23-39-26.gh-issue-144278.tejFwL.rst +++ /dev/null @@ -1,5 +0,0 @@ -Enables defining the ``_PY_IMPL_NAME`` and ``_PY_IMPL_CACHE_TAG`` preprocessor -definitions to override :data:`sys.implementation` at build time. Definitions -need to include quotes when setting to a string literal. Setting the cache tag -to ``NULL`` has the effect of completely disabling automatic creation and use of -``.pyc`` files. diff --git a/Misc/NEWS.d/next/Build/2026-01-28-19-04-12.gh-issue-144309.3sMFOh.rst b/Misc/NEWS.d/next/Build/2026-01-28-19-04-12.gh-issue-144309.3sMFOh.rst deleted file mode 100644 index c64ef494d27380..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-01-28-19-04-12.gh-issue-144309.3sMFOh.rst +++ /dev/null @@ -1 +0,0 @@ -Build Python with POSIX 2024, instead of POSIX 2008. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst b/Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst deleted file mode 100644 index cab48f105cc58b..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-02-10-06-31-29.gh-issue-140421.vxosUx.rst +++ /dev/null @@ -1 +0,0 @@ -Disable the perf trampoline on older macOS versions where it cannot be built. diff --git a/Misc/NEWS.d/next/C_API/2025-12-16-18-39-30.gh-issue-141070.4EKDZ1.rst b/Misc/NEWS.d/next/C_API/2025-12-16-18-39-30.gh-issue-141070.4EKDZ1.rst deleted file mode 100644 index 09ccd125995e03..00000000000000 --- a/Misc/NEWS.d/next/C_API/2025-12-16-18-39-30.gh-issue-141070.4EKDZ1.rst +++ /dev/null @@ -1 +0,0 @@ -Renamed :c:func:`!PyUnstable_Object_Dump` to :c:func:`PyObject_Dump`. diff --git a/Misc/NEWS.d/next/C_API/2026-01-16-15-04-26.gh-issue-143869.vf94km.rst b/Misc/NEWS.d/next/C_API/2026-01-16-15-04-26.gh-issue-143869.vf94km.rst deleted file mode 100644 index 60b0c1ec13062b..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-01-16-15-04-26.gh-issue-143869.vf94km.rst +++ /dev/null @@ -1,5 +0,0 @@ -Added :c:func:`PyLong_GetNativeLayout`, :c:struct:`PyLongLayout`, -:c:struct:`PyLongExport`, :c:func:`PyLong_Export`, -:c:func:`PyLong_FreeExport`, :c:struct:`PyLongWriter`, -:c:func:`PyLongWriter_Create`, :c:func:`PyLongWriter_Finish` and -:c:func:`PyLongWriter_Discard` to the limited API. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst deleted file mode 100644 index 0e41bc963bebec..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Setup ``__module__`` attribute for built-in static methods. Patch by Sergey -B Kirpichev. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-22-36-05.gh-issue-140232.u3srgv.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-22-36-05.gh-issue-140232.u3srgv.rst deleted file mode 100644 index e40daacbc45b7b..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-16-22-36-05.gh-issue-140232.u3srgv.rst +++ /dev/null @@ -1 +0,0 @@ -Frozenset objects with immutable elements are no longer tracked by the garbage collector. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-24-17-30-51.gh-issue-140557.X2GETk.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-24-17-30-51.gh-issue-140557.X2GETk.rst deleted file mode 100644 index d584279a0901b0..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-24-17-30-51.gh-issue-140557.X2GETk.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`bytearray` buffers now have the same alignment -when empty as when allocated. Unaligned buffers can still be created by slicing. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-10-06-06.gh-issue-142037.OpIGzK.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-10-06-06.gh-issue-142037.OpIGzK.rst deleted file mode 100644 index 6a59be7726f254..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-10-06-06.gh-issue-142037.OpIGzK.rst +++ /dev/null @@ -1,7 +0,0 @@ -Improve error messages for printf-style formatting. -For errors in the format string, always include the position of the -start of the format unit. -For errors related to the formatted arguments, always include the number -or the name of the argument. -Raise more specific errors and include more information (type and number -of arguments, most probable causes of error). diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-21-18-12-30.gh-issue-143055.PzwccL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-21-18-12-30.gh-issue-143055.PzwccL.rst deleted file mode 100644 index d3ed40668f6539..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-21-18-12-30.gh-issue-143055.PzwccL.rst +++ /dev/null @@ -1 +0,0 @@ -Implement :pep:`798` (Unpacking in Comprehensions). Patch by Adam Hartz. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-24-13-19-16.gh-issue-132657._P4DDb.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-24-13-19-16.gh-issue-132657._P4DDb.rst deleted file mode 100644 index bbc9611b748fde..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-24-13-19-16.gh-issue-132657._P4DDb.rst +++ /dev/null @@ -1,6 +0,0 @@ -If we are specializing to ``LOAD_GLOBAL_MODULE`` or ``LOAD_ATTR_MODULE``, try -to enable deferred reference counting for the value, if the object is owned by -a different thread. This applies to the free-threaded build only and should -improve scaling of multi-threaded programs. Note that when deferred reference -counting is enabled, the object will be deallocated by the GC, rather than by -:c:func:`Py_DECREF`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-29-19-31-46.gh-issue-143192.JxGAyl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-29-19-31-46.gh-issue-143192.JxGAyl.rst deleted file mode 100644 index 3a99b3d9e6a1c2..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-29-19-31-46.gh-issue-143192.JxGAyl.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of bitwise operations on multi-digit ints. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-14-55-31.gh-issue-143569.-Ltu3c.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-14-55-31.gh-issue-143569.-Ltu3c.rst deleted file mode 100644 index c625c3b9a84d20..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-08-14-55-31.gh-issue-143569.-Ltu3c.rst +++ /dev/null @@ -1,3 +0,0 @@ -Generator expressions in 3.15 now conform to the documented behavior when -the iterable does not support iteration. This matches the behavior in 3.14 -and earlier diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst deleted file mode 100644 index 7bee70a828acfe..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-10-58-36.gh-issue-143650.k8mR4x.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix race condition in :mod:`importlib` where a thread could receive a stale -module reference when another thread's import fails. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst deleted file mode 100644 index 4ce0e71a47e145..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-11-20-11-36.gh-issue-143670.klnGoD.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes a crash in ``ga_repr_items_list`` function. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-13-22-26-49.gh-issue-141805.QzIKPS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-13-22-26-49.gh-issue-141805.QzIKPS.rst deleted file mode 100644 index 8878d872c5b3a7..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-13-22-26-49.gh-issue-141805.QzIKPS.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix crash in :class:`set` when objects with the same hash are concurrently -added to the set after removing an element with the same hash while the set -still contains elements with the same hash. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-16-23-19-38.gh-issue-143939.w9TWch.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-16-23-19-38.gh-issue-143939.w9TWch.rst deleted file mode 100644 index 47423663e07864..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-16-23-19-38.gh-issue-143939.w9TWch.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix erroneous "cannot reuse already awaited coroutine" error that could -occur when a generator was run during the process of clearing a coroutine's -frame. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-26-12.gh-issue-144005.Z3O33m.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-26-12.gh-issue-144005.Z3O33m.rst deleted file mode 100644 index b3582197f45dda..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-26-12.gh-issue-144005.Z3O33m.rst +++ /dev/null @@ -1 +0,0 @@ -Eliminate redundant refcounting from ``BINARY_OP_EXTEND``. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-56-44.gh-issue-144007.1xjdBf.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-56-44.gh-issue-144007.1xjdBf.rst deleted file mode 100644 index 26db86fae6bf25..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-01-56-44.gh-issue-144007.1xjdBf.rst +++ /dev/null @@ -1 +0,0 @@ -Eliminate redundant refcounting in the JIT for ``BINARY_OP``. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-02-33-45.gh-issue-144012.wVEEWs.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-02-33-45.gh-issue-144012.wVEEWs.rst deleted file mode 100644 index 716a6e149cf885..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-19-02-33-45.gh-issue-144012.wVEEWs.rst +++ /dev/null @@ -1 +0,0 @@ -Check if the result is ``NULL`` in ``BINARY_OP_EXTENT`` opcode. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst deleted file mode 100644 index b3e5db64a368b3..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst +++ /dev/null @@ -1 +0,0 @@ -Fix JIT tracer memory leak, ensure the JIT tracer state is freed when daemon threads are cleaned up during interpreter shutdown. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-16-20-16.gh-issue-144157.dxyp7k.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-16-20-16.gh-issue-144157.dxyp7k.rst deleted file mode 100644 index ff62d739d7804c..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-16-20-16.gh-issue-144157.dxyp7k.rst +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`bytes.translate` now allows the compiler to unroll its loop more -usefully for a 2x speedup in the common no-deletions specified case. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-17-04-30.gh-issue-143962.dQR1a9.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-17-04-30.gh-issue-143962.dQR1a9.rst deleted file mode 100644 index 71c2476c02b89d..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-22-17-04-30.gh-issue-143962.dQR1a9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Name suggestion for not normalized name suggests now the normalized name or -the closest name to the normalized name. If the suggested name is not ASCII, -include also its ASCII representation. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-23-20-20-42.gh-issue-144194.IbXfxd.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-23-20-20-42.gh-issue-144194.IbXfxd.rst deleted file mode 100644 index 1f33284439c041..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-23-20-20-42.gh-issue-144194.IbXfxd.rst +++ /dev/null @@ -1 +0,0 @@ -Fix error handling in perf jitdump initialization on memory allocation failure. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-27-17-49-43.gh-issue-120321.Vo7c9T.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-27-17-49-43.gh-issue-120321.Vo7c9T.rst deleted file mode 100644 index 052ed07c123bcf..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-27-17-49-43.gh-issue-120321.Vo7c9T.rst +++ /dev/null @@ -1,2 +0,0 @@ -Made ``gi_yieldfrom`` thread-safe in the free-threading build -by using a lightweight lock on the frame state. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-01-42-14.gh-issue-144319._7EtdB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-01-42-14.gh-issue-144319._7EtdB.rst deleted file mode 100644 index 805ba6067edd87..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-01-42-14.gh-issue-144319._7EtdB.rst +++ /dev/null @@ -1 +0,0 @@ -Add huge pages support for the pymalloc allocator. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-02-18-08.gh-issue-144307.CLbm_o.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-02-18-08.gh-issue-144307.CLbm_o.rst deleted file mode 100644 index d6928e643dccd3..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-02-18-08.gh-issue-144307.CLbm_o.rst +++ /dev/null @@ -1 +0,0 @@ -Prevent a reference leak in module teardown at interpreter finalization. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst deleted file mode 100644 index de3391dfcea708..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-29-16-57-11.gh-issue-139103.icXIEQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve scaling of :func:`~collections.namedtuple` instantiation in the -free-threaded build. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst deleted file mode 100644 index 7815176ec85d2d..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-10-38-07.gh-issue-140550.Us9vPD.rst +++ /dev/null @@ -1,2 +0,0 @@ -In :c:member:`PyModuleDef.m_slots`, allow slots that repeat information -present in :c:type:`PyModuleDef`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-15-54-50.gh-issue-144280.kgiP5R.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-15-54-50.gh-issue-144280.kgiP5R.rst deleted file mode 100644 index d6a4203189063a..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-30-15-54-50.gh-issue-144280.kgiP5R.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug in JIT where the predicate symbol had no truthiness diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst deleted file mode 100644 index 4059525f090c50..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-07-34.gh-issue-141563.GheXjr.rst +++ /dev/null @@ -1 +0,0 @@ -Fix thread safety of :c:macro:`! PyDateTime_IMPORT`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-50-14.gh-issue-120321.Xfr7tL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-50-14.gh-issue-120321.Xfr7tL.rst deleted file mode 100644 index 3e868c837839e2..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-02-17-50-14.gh-issue-120321.Xfr7tL.rst +++ /dev/null @@ -1,5 +0,0 @@ -Add ``gi_state``, ``cr_state``, and ``ag_state`` attributes to generators, -coroutines, and async generators that return the current state as a string -(e.g., ``GEN_RUNNING``). The :mod:`inspect` module functions -:func:`~inspect.getgeneratorstate`, :func:`~inspect.getcoroutinestate`, and -:func:`~inspect.getasyncgenstate` now return these attributes directly. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst deleted file mode 100644 index 71cf49366287ae..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-03-17-08-13.gh-issue-144446.db5619.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix data races in the free-threaded build when reading frame object attributes -while another thread is executing the frame. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst deleted file mode 100644 index b3c61e162f4ffb..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-11-19-45.gh-issue-144330.kOowSb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Move ``classmethod`` and ``staticmethod`` initialization from ``__init__()`` -to ``__new__()``. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst deleted file mode 100644 index 849889f81fc323..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-04-12-19-48.gh-issue-131798.My5jLy.rst +++ /dev/null @@ -1 +0,0 @@ -Optimise ``_GUARD_TOS_SLICE`` in the JIT. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst deleted file mode 100644 index f97160172735e1..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-05-13-30-00.gh-issue-144513.IjSTd7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix potential deadlock when using critical sections during stop-the-world -pauses in the free-threaded build. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst deleted file mode 100644 index 9679e2cf6af426..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-17-59-47.gh-issue-144549.5BhPlY.rst +++ /dev/null @@ -1 +0,0 @@ -Fix building the tail calling interpreter on Visual Studio 2026 with free-threading. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst deleted file mode 100644 index 1c7772e2f3ca26..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-12-47-27.gh-issue-144601.E4Yi9J.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash when importing a module whose ``PyInit`` function raises an -exception from a subinterpreter. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst deleted file mode 100644 index 023f9dce20124f..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-18-13-38.gh-issue-144563.hb3kpp.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix interaction of the Tachyon profiler and :mod:`ctypes` and other modules -that load the Python shared library (if present) in an independent map as -this was causing the mechanism that loads the binary information to be -confused. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst deleted file mode 100644 index fab50180bb6219..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-12-08-58.gh-issue-134584.P9LDy5.rst +++ /dev/null @@ -1 +0,0 @@ -Optimize and eliminate ref-counting in ``_BINARY_OP_SUBSCR_LIST_SLICE`` diff --git a/Misc/NEWS.d/next/IDLE/2026-01-13-01-21-20.gh-issue-143774.rqGwX1.rst b/Misc/NEWS.d/next/IDLE/2026-01-13-01-21-20.gh-issue-143774.rqGwX1.rst deleted file mode 100644 index dd15d1672b1b54..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2026-01-13-01-21-20.gh-issue-143774.rqGwX1.rst +++ /dev/null @@ -1 +0,0 @@ -Better explain the operation of Format / Format Paragraph. diff --git a/Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst b/Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst deleted file mode 100644 index 3e956409d52a58..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-07-14-23-54-18.gh-issue-77188.TyI3_Q.rst +++ /dev/null @@ -1 +0,0 @@ -The :mod:`pickle` module now properly handles name-mangled private methods. diff --git a/Misc/NEWS.d/next/Library/2024-11-27-13-11-16.gh-issue-67041.ym2WKK.rst b/Misc/NEWS.d/next/Library/2024-11-27-13-11-16.gh-issue-67041.ym2WKK.rst deleted file mode 100644 index 9ad1e28eac17c7..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-11-27-13-11-16.gh-issue-67041.ym2WKK.rst +++ /dev/null @@ -1,6 +0,0 @@ -Add the *missing_as_none* parameter to :func:`~urllib.parse.urlparse`, -:func:`~urllib.parse.urlsplit` and :func:`~urllib.parse.urldefrag` -functions. Add the *keep_empty* parameter to -:func:`~urllib.parse.urlunparse` and :func:`~urllib.parse.urlunsplit` -functions. This allows to distinguish between empty and not defined URI -components and preserve empty components. diff --git a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst b/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst deleted file mode 100644 index c2bb69b894c1dd..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-10-27-00-13-04.gh-issue-140715.WkozE0.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``'%F'`` support to :meth:`~datetime.datetime.strptime`. diff --git a/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst b/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst deleted file mode 100644 index 187a6ebbe79b26..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst +++ /dev/null @@ -1,5 +0,0 @@ -Accepting ``+`` and ``/`` characters with an alternative alphabet in -:func:`base64.b64decode` and :func:`base64.urlsafe_b64decode` is now -deprecated. -In future Python versions they will be errors in the strict mode and -discarded in the non-strict mode. diff --git a/Misc/NEWS.d/next/Library/2025-11-22-20-30-00.gh-issue-141860.frksvr.rst b/Misc/NEWS.d/next/Library/2025-11-22-20-30-00.gh-issue-141860.frksvr.rst deleted file mode 100644 index b1efd9c014f1f4..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-11-22-20-30-00.gh-issue-141860.frksvr.rst +++ /dev/null @@ -1,5 +0,0 @@ -Add an ``on_error`` keyword-only parameter to -:func:`multiprocessing.set_forkserver_preload` to control how import failures -during module preloading are handled. Accepts ``'ignore'`` (default, silent), -``'warn'`` (emit :exc:`ImportWarning`), or ``'fail'`` (raise exception). -Contributed by Nick Neumann and Gregory P. Smith. diff --git a/Misc/NEWS.d/next/Library/2025-12-08-18-40-17.gh-issue-142438.tH-Y16.rst b/Misc/NEWS.d/next/Library/2025-12-08-18-40-17.gh-issue-142438.tH-Y16.rst deleted file mode 100644 index 5c1db433e1b14b..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-08-18-40-17.gh-issue-142438.tH-Y16.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix _decimal builds configured with EXTRA_FUNCTIONALITY by correcting the -Context.apply wrapper to pass the right argument. diff --git a/Misc/NEWS.d/next/Library/2025-12-15-02-02-45.gh-issue-142555.EC9QN_.rst b/Misc/NEWS.d/next/Library/2025-12-15-02-02-45.gh-issue-142555.EC9QN_.rst deleted file mode 100644 index 72cc7c634b5750..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-15-02-02-45.gh-issue-142555.EC9QN_.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`array`: fix a crash in ``a[i] = v`` when converting *i* to -an index via :meth:`i.__index__ ` or :meth:`i.__float__ -` mutates the array. diff --git a/Misc/NEWS.d/next/Library/2025-12-19-11-30-31.gh-issue-142966.PzGiv2.rst b/Misc/NEWS.d/next/Library/2025-12-19-11-30-31.gh-issue-142966.PzGiv2.rst deleted file mode 100644 index 92ea407c6b456e..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-19-11-30-31.gh-issue-142966.PzGiv2.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :func:`!ctypes.POINTER.set_type` not updating the format string to match the type. diff --git a/Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst b/Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst deleted file mode 100644 index 1859538896932d..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-28-15-55-53.gh-issue-101178.26jYPs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add Ascii85, Base85, and Z85 support to :mod:`binascii` and improve the -performance of the base-85 converters in :mod:`base64`. diff --git a/Misc/NEWS.d/next/Library/2026-01-05-05-31-05.gh-issue-143423.X7YdnR.rst b/Misc/NEWS.d/next/Library/2026-01-05-05-31-05.gh-issue-143423.X7YdnR.rst deleted file mode 100644 index d9276dfd400a5d..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-05-05-31-05.gh-issue-143423.X7YdnR.rst +++ /dev/null @@ -1 +0,0 @@ -Fix free-threaded build detection in the sampling profiler when Py_GIL_DISABLED is set to 0. diff --git a/Misc/NEWS.d/next/Library/2026-01-07-11-57-59.gh-issue-140557.3P6-nW.rst b/Misc/NEWS.d/next/Library/2026-01-07-11-57-59.gh-issue-140557.3P6-nW.rst deleted file mode 100644 index 997ad592bbaafd..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-07-11-57-59.gh-issue-140557.3P6-nW.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`array.array` buffers now have the same alignment when empty as when -allocated. Unaligned buffers can still be created by slicing. diff --git a/Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst b/Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst deleted file mode 100644 index cb6990a463bdd9..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-07-19-01-59.gh-issue-142434.SHRS5p.rst +++ /dev/null @@ -1,3 +0,0 @@ -Use ``ppoll()`` if available in :func:`select.poll` to have a timeout -resolution of 1 nanosecond, instead of a resolution of 1 ms. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst b/Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst deleted file mode 100644 index 0eaec9029221ba..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-09-12-37-19.gh-issue-143602.V8vQpj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a inconsistency issue in :meth:`~io.RawIOBase.write` that leads to -unexpected buffer overwrite by deduplicating the buffer exports. diff --git a/Misc/NEWS.d/next/Library/2026-01-11-14-14-19.gh-issue-143689.fzHJ2W.rst b/Misc/NEWS.d/next/Library/2026-01-11-14-14-19.gh-issue-143689.fzHJ2W.rst deleted file mode 100644 index a423b1b70ad077..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-11-14-14-19.gh-issue-143689.fzHJ2W.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :meth:`io.BufferedReader.read1` state cleanup on buffer allocation failure. diff --git a/Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst b/Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst deleted file mode 100644 index 14622a395ec22e..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-13-10-38-43.gh-issue-143543.DeQRCO.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in itertools.groupby that could occur when a user-defined -:meth:`~object.__eq__` method re-enters the iterator during key comparison. diff --git a/Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst b/Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst deleted file mode 100644 index 92c4dbb536cdf6..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-13-15-56-03.gh-issue-132604.lvjNTr.rst +++ /dev/null @@ -1,4 +0,0 @@ -Previously, :class:`~typing.Protocol` classes that were not decorated with :deco:`~typing.runtime_checkable`, -but that inherited from another ``Protocol`` class that did have this decorator, could be used in :func:`isinstance` -and :func:`issubclass` checks. This behavior is now deprecated and such checks will throw a :exc:`TypeError` -in Python 3.20. Patch by Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Library/2026-01-13-16-19-50.gh-issue-143756.LQOra1.rst b/Misc/NEWS.d/next/Library/2026-01-13-16-19-50.gh-issue-143756.LQOra1.rst deleted file mode 100644 index fc7eefff8619ae..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-13-16-19-50.gh-issue-143756.LQOra1.rst +++ /dev/null @@ -1 +0,0 @@ -Fix potential thread safety issues in :mod:`ssl` module. diff --git a/Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst b/Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst deleted file mode 100644 index edfdd109400d08..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-14-20-35-40.gh-issue-143754.m2NQXA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add new :mod:`tkinter` widget methods :meth:`!pack_content`, -:meth:`!place_content` and :meth:`!grid_content` which are alternative -spelling of old :meth:`!*_slaves` methods. diff --git a/Misc/NEWS.d/next/Library/2026-01-15-16-04-39.gh-issue-143874.1qQgvo.rst b/Misc/NEWS.d/next/Library/2026-01-15-16-04-39.gh-issue-143874.1qQgvo.rst deleted file mode 100644 index a11cf715b04a8d..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-15-16-04-39.gh-issue-143874.1qQgvo.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a bug in :mod:`pdb` where expression results were not sent back to remote client. diff --git a/Misc/NEWS.d/next/Library/2026-01-16-06-22-10.gh-issue-143831.VLBTLp.rst b/Misc/NEWS.d/next/Library/2026-01-16-06-22-10.gh-issue-143831.VLBTLp.rst deleted file mode 100644 index 620adea1b6d782..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-16-06-22-10.gh-issue-143831.VLBTLp.rst +++ /dev/null @@ -1,3 +0,0 @@ -:class:`annotationlib.ForwardRef` objects are now hashable when created from -annotation scopes with closures. Previously, hashing such objects would -throw an exception. Patch by Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Library/2026-01-16-10-53-17.gh-issue-143897.hWJBHN.rst b/Misc/NEWS.d/next/Library/2026-01-16-10-53-17.gh-issue-143897.hWJBHN.rst deleted file mode 100644 index d53eac0bd356ea..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-16-10-53-17.gh-issue-143897.hWJBHN.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the :meth:`!isxidstart` and :meth:`!isxidcontinue` methods of -:data:`unicodedata.ucd_3_2_0`. They are now only exposed as -:func:`unicodedata.isxidstart` and :func:`unicodedata.isxidcontinue`. diff --git a/Misc/NEWS.d/next/Library/2026-01-16-14-02-39.gh-issue-143904.rErHHA.rst b/Misc/NEWS.d/next/Library/2026-01-16-14-02-39.gh-issue-143904.rErHHA.rst deleted file mode 100644 index f856a4be9fc9fe..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-16-14-02-39.gh-issue-143904.rErHHA.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`struct.pack_into` now raises OverflowError instead of IndexError for -too large *offset* argument. diff --git a/Misc/NEWS.d/next/Library/2026-01-17-07-48-27.gh-issue-143952.lqJ55y.rst b/Misc/NEWS.d/next/Library/2026-01-17-07-48-27.gh-issue-143952.lqJ55y.rst deleted file mode 100644 index 1a99d315710459..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-17-07-48-27.gh-issue-143952.lqJ55y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed :mod:`asyncio` debugging tools to work with new remote debugging API. -Patch by Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Library/2026-01-18-14-35-37.gh-issue-143999.MneN4O.rst b/Misc/NEWS.d/next/Library/2026-01-18-14-35-37.gh-issue-143999.MneN4O.rst deleted file mode 100644 index dc87411aacc821..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-18-14-35-37.gh-issue-143999.MneN4O.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an issue where :func:`inspect.getgeneratorstate` and :func:`inspect.getcoroutinestate` could fail for generators wrapped by :func:`types.coroutine` in the suspended state. diff --git a/Misc/NEWS.d/next/Library/2026-01-19-00-57-40.gh-issue-144023.29XUcp.rst b/Misc/NEWS.d/next/Library/2026-01-19-00-57-40.gh-issue-144023.29XUcp.rst deleted file mode 100644 index 0d06506e1ec106..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-19-00-57-40.gh-issue-144023.29XUcp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed validation of file descriptor 0 in posix functions when used with -follow_symlinks parameter. diff --git a/Misc/NEWS.d/next/Library/2026-01-19-10-26-59.gh-issue-144001.dGj8Nk.rst b/Misc/NEWS.d/next/Library/2026-01-19-10-26-59.gh-issue-144001.dGj8Nk.rst deleted file mode 100644 index 02d453f4d2ceee..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-19-10-26-59.gh-issue-144001.dGj8Nk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added the *ignorechars* parameter in :func:`binascii.a2b_base64` and -:func:`base64.b64decode`. diff --git a/Misc/NEWS.d/next/Library/2026-01-19-12-48-59.gh-issue-144030.7OK_gB.rst b/Misc/NEWS.d/next/Library/2026-01-19-12-48-59.gh-issue-144030.7OK_gB.rst deleted file mode 100644 index ef3c02925405b8..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-19-12-48-59.gh-issue-144030.7OK_gB.rst +++ /dev/null @@ -1,3 +0,0 @@ -The Python implementation of :func:`functools.lru_cache` differed from the -default C implementation in that it did not check that its argument is -callable. This discrepancy is now fixed and both raise a :exc:`TypeError`. diff --git a/Misc/NEWS.d/next/Library/2026-01-19-16-45-16.gh-issue-83069.0TaeH9.rst b/Misc/NEWS.d/next/Library/2026-01-19-16-45-16.gh-issue-83069.0TaeH9.rst deleted file mode 100644 index d0d4f2bd53100f..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-19-16-45-16.gh-issue-83069.0TaeH9.rst +++ /dev/null @@ -1,7 +0,0 @@ -:meth:`subprocess.Popen.wait`: when ``timeout`` is not ``None``, an efficient -event-driven mechanism now waits for process termination, if available. Linux ->= 5.3 uses :func:`os.pidfd_open` + :func:`select.poll`. macOS and other BSD -variants use :func:`select.kqueue` + ``KQ_FILTER_PROC`` + ``KQ_NOTE_EXIT``. -Windows keeps using ``WaitForSingleObject`` (unchanged). If none of these -mechanisms are available, the function falls back to the traditional busy loop -(non-blocking call and short sleeps). Patch by Giampaolo Rodola. diff --git a/Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst b/Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst deleted file mode 100644 index dfc062d023c8f1..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-20-16-35-55.gh-issue-144050.0kKFbF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`stat.filemode` in the pure-Python implementation to avoid misclassifying -invalid mode values as block devices. diff --git a/Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst b/Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst deleted file mode 100644 index 8935b4c655023a..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-20-20-54-46.gh-issue-143658.v8i1jE.rst +++ /dev/null @@ -1,4 +0,0 @@ -:mod:`importlib.metadata`: Use :meth:`str.lower` and :meth:`str.replace` to -further improve performance of -:meth:`!importlib.metadata.Prepared.normalize`. Patch by Hugo van Kemenade -and Henry Schreiner. diff --git a/Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst b/Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst deleted file mode 100644 index 7093b753141fb8..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-21-19-39-07.gh-issue-144100.hLMZ8Y.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a crash in ctypes when using a deprecated ``POINTER(str)`` type in -``argtypes``. Instead of aborting, ctypes now raises a proper Python -exception when the pointer target type is unresolved. diff --git a/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst b/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst deleted file mode 100644 index 4010695aec980d..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in :meth:`array.array.fromlist` when an element's :meth:`~object.__index__` method mutates -the input list during conversion. diff --git a/Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst b/Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst deleted file mode 100644 index e2ef3d7c051d14..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-23-06-43-21.gh-issue-144169.LFy9yi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix three crashes when non-string keyword arguments are supplied to objects -in the :mod:`ast` module. diff --git a/Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst b/Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst deleted file mode 100644 index e0c2c287f57271..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-24-13-49-05.gh-issue-143594.nilGlg.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods. diff --git a/Misc/NEWS.d/next/Library/2026-01-24-23-11-17.gh-issue-144212.IXqVL8.rst b/Misc/NEWS.d/next/Library/2026-01-24-23-11-17.gh-issue-144212.IXqVL8.rst deleted file mode 100644 index be77fb345adae3..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-24-23-11-17.gh-issue-144212.IXqVL8.rst +++ /dev/null @@ -1 +0,0 @@ -Mime type ``image/jxl`` is now supported by :mod:`mimetypes`. diff --git a/Misc/NEWS.d/next/Library/2026-01-25-03-23-20.gh-issue-144217.E1wVXH.rst b/Misc/NEWS.d/next/Library/2026-01-25-03-23-20.gh-issue-144217.E1wVXH.rst deleted file mode 100644 index d85df59b3749f1..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-25-03-23-20.gh-issue-144217.E1wVXH.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`mimetypes`: Add support for DICOM files (for medical imaging) with the official MIME type ``application/dicom``. Patch by Benedikt Johannes. diff --git a/Misc/NEWS.d/next/Library/2026-01-26-12-30-57.gh-issue-142956.X9CS8J.rst b/Misc/NEWS.d/next/Library/2026-01-26-12-30-57.gh-issue-142956.X9CS8J.rst deleted file mode 100644 index 27f104fa0b62f9..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-26-12-30-57.gh-issue-142956.X9CS8J.rst +++ /dev/null @@ -1 +0,0 @@ -Updated :mod:`tomllib` to parse TOML 1.1.0. diff --git a/Misc/NEWS.d/next/Library/2026-01-27-00-03-41.gh-issue-132888.yhTfUN.rst b/Misc/NEWS.d/next/Library/2026-01-27-00-03-41.gh-issue-132888.yhTfUN.rst deleted file mode 100644 index 71b984c69c5c29..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-27-00-03-41.gh-issue-132888.yhTfUN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix incorrect use of :func:`ctypes.GetLastError` and add missing error -checks for Windows API calls in :mod:`!_pyrepl.windows_console`. diff --git a/Misc/NEWS.d/next/Library/2026-01-27-09-58-52.gh-issue-144249.mCIy95.rst b/Misc/NEWS.d/next/Library/2026-01-27-09-58-52.gh-issue-144249.mCIy95.rst deleted file mode 100644 index 52f27cec478259..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-27-09-58-52.gh-issue-144249.mCIy95.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add filename context to :exc:`OSError` exceptions raised by -:func:`ssl.SSLContext.load_cert_chain`, allowing users to have more context. diff --git a/Misc/NEWS.d/next/Library/2026-01-27-10-02-04.gh-issue-144264.Wmzbol.rst b/Misc/NEWS.d/next/Library/2026-01-27-10-02-04.gh-issue-144264.Wmzbol.rst deleted file mode 100644 index 11e3fdeb4355cf..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-27-10-02-04.gh-issue-144264.Wmzbol.rst +++ /dev/null @@ -1,3 +0,0 @@ -Speed up Base64 decoding of data containing ignored characters (both in -non-strict mode and with an explicit *ignorechars* argument). -It is now up to 2 times faster for multiline Base64 data. diff --git a/Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst b/Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst deleted file mode 100644 index 1e16d28a756296..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve error messages for buffer overflow in :func:`fcntl.fcntl` and -:func:`fcntl.ioctl`. diff --git a/Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst b/Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst deleted file mode 100644 index dd90b6a21d135d..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-30-13-23-06.gh-issue-140824.J1OCrC.rst +++ /dev/null @@ -1,2 +0,0 @@ -When :mod:`faulthandler` dumps the list of third-party extension modules, -ignore sub-modules of stdlib packages. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst b/Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst deleted file mode 100644 index c17cea6613d06b..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-31-17-15-49.gh-issue-144363.X9f0sU.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled `libexpat `_ to 2.7.4 diff --git a/Misc/NEWS.d/next/Library/2026-02-01-15-25-00.gh-issue-144380.U7py_s.rst b/Misc/NEWS.d/next/Library/2026-02-01-15-25-00.gh-issue-144380.U7py_s.rst deleted file mode 100644 index 4b5b1b3776d735..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-01-15-25-00.gh-issue-144380.U7py_s.rst +++ /dev/null @@ -1 +0,0 @@ -Improve performance of :class:`io.BufferedReader` line iteration by ~49%. diff --git a/Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst b/Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst deleted file mode 100644 index 8629c834e5b0cd..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-02-12-09-38.gh-issue-74453.19h4Z5.rst +++ /dev/null @@ -1,8 +0,0 @@ -Deprecate :func:`os.path.commonprefix` in favor of -:func:`os.path.commonpath` for path segment prefixes. - -The :func:`os.path.commonprefix` function is being deprecated due to -having a misleading name and module. The function is not safe to use for -path prefixes despite being included in a module about path manipulation, -meaning it is easy to accidentally introduce path traversal -vulnerabilities into Python programs by using this function. diff --git a/Misc/NEWS.d/next/Library/2026-02-03-08-50-58.gh-issue-123471.yF1Gym.rst b/Misc/NEWS.d/next/Library/2026-02-03-08-50-58.gh-issue-123471.yF1Gym.rst deleted file mode 100644 index 85e9a03426e1fc..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-03-08-50-58.gh-issue-123471.yF1Gym.rst +++ /dev/null @@ -1 +0,0 @@ -Make concurrent iteration over :class:`itertools.combinations_with_replacement` and :class:`itertools.permutations` safe under free-threading. diff --git a/Misc/NEWS.d/next/Library/2026-02-03-14-16-49.gh-issue-144386.9Wa59r.rst b/Misc/NEWS.d/next/Library/2026-02-03-14-16-49.gh-issue-144386.9Wa59r.rst deleted file mode 100644 index 6e60eeba208ffd..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-03-14-16-49.gh-issue-144386.9Wa59r.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add support for arbitrary descriptors :meth:`!__enter__`, :meth:`!__exit__`, -:meth:`!__aenter__`, and :meth:`!__aexit__` in :class:`contextlib.ExitStack` -and :class:`contextlib.AsyncExitStack`, for consistency with the -:keyword:`with` and :keyword:`async with` statements. diff --git a/Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst b/Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst deleted file mode 100644 index fe205b58013af0..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-05-17-15-31.gh-issue-144493.XuxwVu.rst +++ /dev/null @@ -1 +0,0 @@ -Improve an exception error message in ``_overlapped.BindLocal()`` that is raised when :meth:`asyncio.loop.sock_connect` is called on a :class:`asyncio.ProactorEventLoop` with a socket that has an invalid address family. diff --git a/Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst b/Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst deleted file mode 100644 index fbded72d92551b..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-06-23-58-54.gh-issue-144538.5_OvGv.rst +++ /dev/null @@ -1 +0,0 @@ -Bump the version of pip bundled in ensurepip to version 26.0.1 diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst deleted file mode 100644 index 44bd0b27059f94..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Reject C0 control characters within wsgiref.headers.Headers fields, values, -and parameters. diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst deleted file mode 100644 index 788c3e4ac2ebf7..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst +++ /dev/null @@ -1 +0,0 @@ -Reject control characters in :class:`http.cookies.Morsel` fields and values. diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst deleted file mode 100644 index 4e13fe92bc60fb..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +++ /dev/null @@ -1 +0,0 @@ -Reject control characters in IMAP commands. diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst deleted file mode 100644 index 3cde4df3e0069f..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst +++ /dev/null @@ -1 +0,0 @@ -Reject control characters in POP3 commands. diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst deleted file mode 100644 index 46109dfbef3ee7..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst +++ /dev/null @@ -1 +0,0 @@ -Reject control characters in ``data:`` URL media types. diff --git a/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst b/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst deleted file mode 100644 index c3d864936884ac..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst +++ /dev/null @@ -1,6 +0,0 @@ -Fixed a bug in the folding of comments when flattening an email message -using a modern email policy. Comments consisting of a very long sequence of -non-foldable characters could trigger a forced line wrap that omitted the -required leading space on the continuation line, causing the remainder of -the comment to be interpreted as a new header field. This enabled header -injection with carefully crafted inputs. diff --git a/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst b/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst deleted file mode 100644 index e6333e724972c5..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst +++ /dev/null @@ -1,4 +0,0 @@ -:mod:`~email.generator.BytesGenerator` will now refuse to serialize (write) headers -that are unsafely folded or delimited; see -:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas -Bloemsaat and Petr Viktorin in :gh:`121650`). diff --git a/Misc/NEWS.d/next/Tests/2026-01-08-16-56-59.gh-issue-65784.aKNo1U.rst b/Misc/NEWS.d/next/Tests/2026-01-08-16-56-59.gh-issue-65784.aKNo1U.rst deleted file mode 100644 index 7d1a153fc7a6ca..00000000000000 --- a/Misc/NEWS.d/next/Tests/2026-01-08-16-56-59.gh-issue-65784.aKNo1U.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add support for parametrized resource ``wantobjects`` in regrtests, -which allows to run Tkinter tests with the specified value of -:data:`!tkinter.wantobjects`, for example ``-u wantobjects=0``. diff --git a/Misc/NEWS.d/next/Tests/2026-02-03-07-57-24.gh-issue-144415.U3L15r.rst b/Misc/NEWS.d/next/Tests/2026-02-03-07-57-24.gh-issue-144415.U3L15r.rst deleted file mode 100644 index b3a8d46329679e..00000000000000 --- a/Misc/NEWS.d/next/Tests/2026-02-03-07-57-24.gh-issue-144415.U3L15r.rst +++ /dev/null @@ -1,3 +0,0 @@ -The Android testbed now distinguishes between stdout/stderr messages which -were triggered by a newline, and those triggered by a manual call to -``flush``. This fixes logging of progress indicators and similar content. diff --git a/Misc/NEWS.d/next/Windows/2026-01-05-21-36-58.gh-issue-80620.p1bD58.rst b/Misc/NEWS.d/next/Windows/2026-01-05-21-36-58.gh-issue-80620.p1bD58.rst deleted file mode 100644 index fb2f500bc45234..00000000000000 --- a/Misc/NEWS.d/next/Windows/2026-01-05-21-36-58.gh-issue-80620.p1bD58.rst +++ /dev/null @@ -1 +0,0 @@ -Support negative timestamps in :func:`time.gmtime`, :func:`time.localtime`, and various :mod:`datetime` functions. diff --git a/Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst b/Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst deleted file mode 100644 index 4b979a405fd8fd..00000000000000 --- a/Misc/NEWS.d/next/macOS/2026-02-09-22-43-47.gh-issue-144551.VOfgfD.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use OpenSSL 3.5.5. diff --git a/Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst b/Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst deleted file mode 100644 index 1318b41478f81f..00000000000000 --- a/Misc/NEWS.d/next/macOS/2026-02-09-23-01-49.gh-issue-124111.WmQG7S.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use Tcl/Tk 9.0.3. diff --git a/Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst b/Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst deleted file mode 100644 index 5f8ba046f3571e..00000000000000 --- a/Misc/NEWS.d/next/macOS/2026-02-10-08-00-17.gh-issue-144648.KEuUXp.rst +++ /dev/null @@ -1 +0,0 @@ -Allowed _remote_debugging to build on more OS versions by using proc_listpids() rather than proc_listallpids(). diff --git a/README.rst b/README.rst index c507bf3b16ea4a..68e114e66abe43 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.15.0 alpha 5 +This is Python version 3.15.0 alpha 6 ===================================== .. image:: https://github.com/python/cpython/actions/workflows/build.yml/badge.svg?branch=main&event=push From 17ab556e39e9b40c7d4308664de42f0564048044 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Wed, 11 Feb 2026 07:44:22 -0500 Subject: [PATCH 072/498] gh-144321: Fix named tuple bug when input is a non-sequence iterable (#144600) --- Lib/test/test_typing.py | 9 +++++++++ Lib/typing.py | 3 +-- .../2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 72ae7776ab9062..50938eadc8f9f3 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -8532,6 +8532,15 @@ class ThisWontWorkEither(NamedTuple): def name(self): return __class__.__name__ + def test_named_tuple_non_sequence_input(self): + field_names = ["x", "y"] + field_values = [int, int] + Point = NamedTuple("Point", zip(field_names, field_values)) + p = Point(1, 2) + self.assertEqual(p.x, 1) + self.assertEqual(p.y, 2) + self.assertEqual(repr(p),"Point(x=1, y=2)") + class TypedDictTests(BaseTestCase): def test_basics_functional_syntax(self): diff --git a/Lib/typing.py b/Lib/typing.py index 71a08a5f1df811..2dfa6d3b1499ca 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -3075,8 +3075,7 @@ class Employee(NamedTuple): """ types = {n: _type_check(t, f"field {n} annotation must be a type") for n, t in fields} - field_names = [n for n, _ in fields] - nt = _make_nmtuple(typename, field_names, _make_eager_annotate(types), module=_caller()) + nt = _make_nmtuple(typename, types, _make_eager_annotate(types), module=_caller()) nt.__orig_bases__ = (NamedTuple,) return nt diff --git a/Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst b/Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst new file mode 100644 index 00000000000000..45561898e2e1e9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst @@ -0,0 +1,3 @@ +The functional syntax for creating :class:`typing.NamedTuple` +classes now supports passing any :term:`iterable` of fields and types. +Previously, only sequences were supported. From 12dbae4c02dac197330d5bfa650b495e962aba6d Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Wed, 11 Feb 2026 13:55:36 +0100 Subject: [PATCH 073/498] gh-142518: Define lock-free and per-object lock (#144548) - Add definitions of lock-free and per-object lock to the glossary - Cross-reference these from list thread safety notes - Change admonition to rubric --- Doc/glossary.rst | 20 ++++++ Doc/library/stdtypes.rst | 149 ++++++++++++++++++++------------------- 2 files changed, 96 insertions(+), 73 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 24b95b88dfb651..1dccb77cc53228 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -951,6 +951,16 @@ Glossary to locks exist such as queues, producer/consumer patterns, and thread-local state. See also :term:`deadlock`, and :term:`reentrant`. + lock-free + An operation that does not acquire any :term:`lock` and uses atomic CPU + instructions to ensure correctness. Lock-free operations can execute + concurrently without blocking each other and cannot be blocked by + operations that hold locks. In :term:`free-threaded ` + Python, built-in types like :class:`dict` and :class:`list` provide + lock-free read operations, which means other threads may observe + intermediate states during multi-step modifications even when those + modifications hold the :term:`per-object lock`. + loader An object that loads a module. It must define the :meth:`!exec_module` and :meth:`!create_module` methods @@ -1217,6 +1227,16 @@ Glossary `, the :class:`inspect.Parameter` class, the :ref:`function` section, and :pep:`362`. + per-object lock + A :term:`lock` associated with an individual object instance rather than + a global lock shared across all objects. In :term:`free-threaded + ` Python, built-in types like :class:`dict` and + :class:`list` use per-object locks to allow concurrent operations on + different objects while serializing operations on the same object. + Operations that hold the per-object lock prevent other locking operations + on the same object from proceeding, but do not block :term:`lock-free` + operations. + path entry A single location on the :term:`import path` which the :term:`path based finder` consults to find modules for importing. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index c8dc834fe84446..3745f32d874bd4 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1441,108 +1441,111 @@ application). list appear empty for the duration, and raises :exc:`ValueError` if it can detect that the list has been mutated during a sort. -.. admonition:: Thread safety +.. _thread-safety-list: - Reading a single element from a :class:`list` is - :term:`atomic `: +.. rubric:: Thread safety for list objects - .. code-block:: - :class: green +Reading a single element from a :class:`list` is +:term:`atomic `: - lst[i] # list.__getitem__ +.. code-block:: + :class: green - The following methods traverse the list and use :term:`atomic ` - reads of each item to perform their function. That means that they may - return results affected by concurrent modifications: + lst[i] # list.__getitem__ - .. code-block:: - :class: maybe +The following methods traverse the list and use :term:`atomic ` +reads of each item to perform their function. That means that they may +return results affected by concurrent modifications: - item in lst - lst.index(item) - lst.count(item) +.. code-block:: + :class: maybe - All of the above methods/operations are also lock-free. They do not block - concurrent modifications. Other operations that hold a lock will not block - these from observing intermediate states. + item in lst + lst.index(item) + lst.count(item) - All other operations from here on block using the per-object lock. +All of the above operations avoid acquiring :term:`per-object locks +`. They do not block concurrent modifications. Other +operations that hold a lock will not block these from observing intermediate +states. - Writing a single item via ``lst[i] = x`` is safe to call from multiple - threads and will not corrupt the list. +All other operations from here on block using the :term:`per-object lock`. - The following operations return new objects and appear - :term:`atomic ` to other threads: +Writing a single item via ``lst[i] = x`` is safe to call from multiple +threads and will not corrupt the list. - .. code-block:: - :class: good +The following operations return new objects and appear +:term:`atomic ` to other threads: - lst1 + lst2 # concatenates two lists into a new list - x * lst # repeats lst x times into a new list - lst.copy() # returns a shallow copy of the list +.. code-block:: + :class: good - Methods that only operate on a single elements with no shifting required are - :term:`atomic `: + lst1 + lst2 # concatenates two lists into a new list + x * lst # repeats lst x times into a new list + lst.copy() # returns a shallow copy of the list - .. code-block:: - :class: good +The following methods that only operate on a single element with no shifting +required are :term:`atomic `: - lst.append(x) # append to the end of the list, no shifting required - lst.pop() # pop element from the end of the list, no shifting required +.. code-block:: + :class: good - The :meth:`~list.clear` method is also :term:`atomic `. - Other threads cannot observe elements being removed. + lst.append(x) # append to the end of the list, no shifting required + lst.pop() # pop element from the end of the list, no shifting required - The :meth:`~list.sort` method is not :term:`atomic `. - Other threads cannot observe intermediate states during sorting, but the - list appears empty for the duration of the sort. +The :meth:`~list.clear` method is also :term:`atomic `. +Other threads cannot observe elements being removed. - The following operations may allow lock-free operations to observe - intermediate states since they modify multiple elements in place: +The :meth:`~list.sort` method is not :term:`atomic `. +Other threads cannot observe intermediate states during sorting, but the +list appears empty for the duration of the sort. - .. code-block:: - :class: maybe +The following operations may allow :term:`lock-free` operations to observe +intermediate states since they modify multiple elements in place: - lst.insert(idx, item) # shifts elements - lst.pop(idx) # idx not at the end of the list, shifts elements - lst *= x # copies elements in place +.. code-block:: + :class: maybe - The :meth:`~list.remove` method may allow concurrent modifications since - element comparison may execute arbitrary Python code (via - :meth:`~object.__eq__`). + lst.insert(idx, item) # shifts elements + lst.pop(idx) # idx not at the end of the list, shifts elements + lst *= x # copies elements in place - :meth:`~list.extend` is safe to call from multiple threads. However, its - guarantees depend on the iterable passed to it. If it is a :class:`list`, a - :class:`tuple`, a :class:`set`, a :class:`frozenset`, a :class:`dict` or a - :ref:`dictionary view object ` (but not their subclasses), the - ``extend`` operation is safe from concurrent modifications to the iterable. - Otherwise, an iterator is created which can be concurrently modified by - another thread. The same applies to inplace concatenation of a list with - other iterables when using ``lst += iterable``. +The :meth:`~list.remove` method may allow concurrent modifications since +element comparison may execute arbitrary Python code (via +:meth:`~object.__eq__`). - Similarly, assigning to a list slice with ``lst[i:j] = iterable`` is safe - to call from multiple threads, but ``iterable`` is only locked when it is - also a :class:`list` (but not its subclasses). +:meth:`~list.extend` is safe to call from multiple threads. However, its +guarantees depend on the iterable passed to it. If it is a :class:`list`, a +:class:`tuple`, a :class:`set`, a :class:`frozenset`, a :class:`dict` or a +:ref:`dictionary view object ` (but not their subclasses), the +``extend`` operation is safe from concurrent modifications to the iterable. +Otherwise, an iterator is created which can be concurrently modified by +another thread. The same applies to inplace concatenation of a list with +other iterables when using ``lst += iterable``. - Operations that involve multiple accesses, as well as iteration, are never - atomic. For example: +Similarly, assigning to a list slice with ``lst[i:j] = iterable`` is safe +to call from multiple threads, but ``iterable`` is only locked when it is +also a :class:`list` (but not its subclasses). - .. code-block:: - :class: bad +Operations that involve multiple accesses, as well as iteration, are never +atomic. For example: - # NOT atomic: read-modify-write - lst[i] = lst[i] + 1 +.. code-block:: + :class: bad - # NOT atomic: check-then-act - if lst: - item = lst.pop() + # NOT atomic: read-modify-write + lst[i] = lst[i] + 1 - # NOT thread-safe: iteration while modifying - for item in lst: - process(item) # another thread may modify lst + # NOT atomic: check-then-act + if lst: + item = lst.pop() - Consider external synchronization when sharing :class:`list` instances - across threads. See :ref:`freethreading-python-howto` for more information. + # NOT thread-safe: iteration while modifying + for item in lst: + process(item) # another thread may modify lst + +Consider external synchronization when sharing :class:`list` instances +across threads. See :ref:`freethreading-python-howto` for more information. .. _typesseq-tuple: From 37430cac94125ec1a221a4a3825d584146608870 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 11 Feb 2026 07:56:36 -0500 Subject: [PATCH 074/498] Docs: remove links of modules to themselves (#144695) --- Doc/library/codecs.rst | 18 ++++----- Doc/library/curses.rst | 8 ++-- Doc/library/dbm.rst | 40 ++++++++++---------- Doc/library/dialog.rst | 18 ++++----- Doc/library/email.encoders.rst | 2 +- Doc/library/email.policy.rst | 2 +- Doc/library/importlib.rst | 14 +++---- Doc/library/json.rst | 2 +- Doc/library/multiprocessing.rst | 18 ++++----- Doc/library/pathlib.rst | 2 +- Doc/library/pdb.rst | 8 ++-- Doc/library/profile.rst | 22 +++++------ Doc/library/profiling.rst | 8 ++-- Doc/library/profiling.sampling.rst | 4 +- Doc/library/profiling.tracing.rst | 8 ++-- Doc/library/pstats.rst | 10 ++--- Doc/library/pyexpat.rst | 4 +- Doc/library/site.rst | 16 ++++---- Doc/library/test.rst | 60 +++++++++++++++--------------- Doc/library/turtle.rst | 18 ++++----- Doc/library/urllib.request.rst | 6 +-- Doc/library/weakref.rst | 10 ++--- Doc/library/wsgiref.rst | 34 ++++++++--------- Doc/library/xml.rst | 2 +- 24 files changed, 167 insertions(+), 167 deletions(-) diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 9f958ee98c6119..36f5e94b8477ec 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -1551,8 +1551,8 @@ mapping. It is not supported by :meth:`str.encode` (which only produces Restoration of the ``rot13`` alias. -:mod:`encodings` --- Encodings package --------------------------------------- +:mod:`!encodings` --- Encodings package +--------------------------------------- .. module:: encodings :synopsis: Encodings package @@ -1611,8 +1611,8 @@ This module implements the following exception: Raised when a codec is invalid or incompatible. -:mod:`encodings.idna` --- Internationalized Domain Names in Applications ------------------------------------------------------------------------- +:mod:`!encodings.idna` --- Internationalized Domain Names in Applications +------------------------------------------------------------------------- .. module:: encodings.idna :synopsis: Internationalized Domain Names implementation @@ -1654,7 +1654,7 @@ When receiving host names from the wire (such as in reverse name lookup), no automatic conversion to Unicode is performed: applications wishing to present such host names to the user should decode them to Unicode. -The module :mod:`encodings.idna` also implements the nameprep procedure, which +The module :mod:`!encodings.idna` also implements the nameprep procedure, which performs certain normalizations on host names, to achieve case-insensitivity of international domain names, and to unify similar characters. The nameprep functions can be used directly if desired. @@ -1677,8 +1677,8 @@ functions can be used directly if desired. Convert a label to Unicode, as specified in :rfc:`3490`. -:mod:`encodings.mbcs` --- Windows ANSI codepage ------------------------------------------------ +:mod:`!encodings.mbcs` --- Windows ANSI codepage +------------------------------------------------ .. module:: encodings.mbcs :synopsis: Windows ANSI codepage @@ -1695,8 +1695,8 @@ This module implements the ANSI codepage (CP_ACP). Support any error handler. -:mod:`encodings.utf_8_sig` --- UTF-8 codec with BOM signature -------------------------------------------------------------- +:mod:`!encodings.utf_8_sig` --- UTF-8 codec with BOM signature +-------------------------------------------------------------- .. module:: encodings.utf_8_sig :synopsis: UTF-8 codec with BOM signature diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 397584e70bf4ce..84efc6654e87c6 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -1824,8 +1824,8 @@ The following table lists the predefined colors: +-------------------------+----------------------------+ -:mod:`curses.textpad` --- Text input widget for curses programs -=============================================================== +:mod:`!curses.textpad` --- Text input widget for curses programs +================================================================ .. module:: curses.textpad :synopsis: Emacs-like input editing in a curses window. @@ -1833,13 +1833,13 @@ The following table lists the predefined colors: .. sectionauthor:: Eric Raymond -The :mod:`curses.textpad` module provides a :class:`Textbox` class that handles +The :mod:`!curses.textpad` module provides a :class:`Textbox` class that handles elementary text editing in a curses window, supporting a set of keybindings resembling those of Emacs (thus, also of Netscape Navigator, BBedit 6.x, FrameMaker, and many other programs). The module also provides a rectangle-drawing function useful for framing text boxes or for other purposes. -The module :mod:`curses.textpad` defines the following function: +The module :mod:`!curses.textpad` defines the following function: .. function:: rectangle(win, uly, ulx, lry, lrx) diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 64201af2d22a58..2481d77f5fbfba 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -157,8 +157,8 @@ then prints out the contents of the database:: The individual submodules are described in the following sections. -:mod:`dbm.sqlite3` --- SQLite backend for dbm ---------------------------------------------- +:mod:`!dbm.sqlite3` --- SQLite backend for dbm +---------------------------------------------- .. module:: dbm.sqlite3 :platform: All @@ -172,7 +172,7 @@ The individual submodules are described in the following sections. This module uses the standard library :mod:`sqlite3` module to provide an SQLite backend for the :mod:`!dbm` module. -The files created by :mod:`dbm.sqlite3` can thus be opened by :mod:`sqlite3`, +The files created by :mod:`!dbm.sqlite3` can thus be opened by :mod:`sqlite3`, or any other SQLite browser, including the SQLite CLI. .. include:: ../includes/wasm-notavail.rst @@ -220,8 +220,8 @@ or any other SQLite browser, including the SQLite CLI. .. versionadded:: 3.15 -:mod:`dbm.gnu` --- GNU database manager ---------------------------------------- +:mod:`!dbm.gnu` --- GNU database manager +---------------------------------------- .. module:: dbm.gnu :platform: Unix @@ -231,20 +231,20 @@ or any other SQLite browser, including the SQLite CLI. -------------- -The :mod:`dbm.gnu` module provides an interface to the :abbr:`GDBM (GNU dbm)` +The :mod:`!dbm.gnu` module provides an interface to the :abbr:`GDBM (GNU dbm)` library, similar to the :mod:`dbm.ndbm` module, but with additional functionality like crash tolerance. .. note:: - The file formats created by :mod:`dbm.gnu` and :mod:`dbm.ndbm` are incompatible + The file formats created by :mod:`!dbm.gnu` and :mod:`dbm.ndbm` are incompatible and can not be used interchangeably. .. include:: ../includes/wasm-mobile-notavail.rst .. exception:: error - Raised on :mod:`dbm.gnu`-specific errors, such as I/O errors. :exc:`KeyError` is + Raised on :mod:`!dbm.gnu`-specific errors, such as I/O errors. :exc:`KeyError` is raised for general mapping errors like specifying an incorrect key. @@ -343,8 +343,8 @@ functionality like crash tolerance. unwritten data to be written to the disk. -:mod:`dbm.ndbm` --- New Database Manager ----------------------------------------- +:mod:`!dbm.ndbm` --- New Database Manager +----------------------------------------- .. module:: dbm.ndbm :platform: Unix @@ -354,14 +354,14 @@ functionality like crash tolerance. -------------- -The :mod:`dbm.ndbm` module provides an interface to the +The :mod:`!dbm.ndbm` module provides an interface to the :abbr:`NDBM (New Database Manager)` library. This module can be used with the "classic" NDBM interface or the :abbr:`GDBM (GNU dbm)` compatibility interface. .. note:: - The file formats created by :mod:`dbm.gnu` and :mod:`dbm.ndbm` are incompatible + The file formats created by :mod:`dbm.gnu` and :mod:`!dbm.ndbm` are incompatible and can not be used interchangeably. .. warning:: @@ -375,7 +375,7 @@ This module can be used with the "classic" NDBM interface or the .. exception:: error - Raised on :mod:`dbm.ndbm`-specific errors, such as I/O errors. :exc:`KeyError` is raised + Raised on :mod:`!dbm.ndbm`-specific errors, such as I/O errors. :exc:`KeyError` is raised for general mapping errors like specifying an incorrect key. @@ -425,8 +425,8 @@ This module can be used with the "classic" NDBM interface or the Close the NDBM database. -:mod:`dbm.dumb` --- Portable DBM implementation ------------------------------------------------ +:mod:`!dbm.dumb` --- Portable DBM implementation +------------------------------------------------ .. module:: dbm.dumb :synopsis: Portable implementation of the simple DBM interface. @@ -437,14 +437,14 @@ This module can be used with the "classic" NDBM interface or the .. note:: - The :mod:`dbm.dumb` module is intended as a last resort fallback for the - :mod:`!dbm` module when a more robust module is not available. The :mod:`dbm.dumb` + The :mod:`!dbm.dumb` module is intended as a last resort fallback for the + :mod:`!dbm` module when a more robust module is not available. The :mod:`!dbm.dumb` module is not written for speed and is not nearly as heavily used as the other database modules. -------------- -The :mod:`dbm.dumb` module provides a persistent :class:`dict`-like +The :mod:`!dbm.dumb` module provides a persistent :class:`dict`-like interface which is written entirely in Python. Unlike other :mod:`!dbm` backends, such as :mod:`dbm.gnu`, no external library is required. @@ -453,7 +453,7 @@ The :mod:`!dbm.dumb` module defines the following: .. exception:: error - Raised on :mod:`dbm.dumb`-specific errors, such as I/O errors. :exc:`KeyError` is + Raised on :mod:`!dbm.dumb`-specific errors, such as I/O errors. :exc:`KeyError` is raised for general mapping errors like specifying an incorrect key. @@ -484,7 +484,7 @@ The :mod:`!dbm.dumb` module defines the following: Python's AST compiler. .. warning:: - :mod:`dbm.dumb` does not support concurrent read/write access. (Multiple + :mod:`!dbm.dumb` does not support concurrent read/write access. (Multiple simultaneous read accesses are safe.) When a program has the database open for writing, no other program should have it open for reading or writing. diff --git a/Doc/library/dialog.rst b/Doc/library/dialog.rst index e0693e8eb6ed22..6fee23e942183d 100644 --- a/Doc/library/dialog.rst +++ b/Doc/library/dialog.rst @@ -1,8 +1,8 @@ Tkinter Dialogs =============== -:mod:`tkinter.simpledialog` --- Standard Tkinter input dialogs -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:mod:`!tkinter.simpledialog` --- Standard Tkinter input dialogs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: tkinter.simpledialog :platform: Tk @@ -12,7 +12,7 @@ Tkinter Dialogs -------------- -The :mod:`tkinter.simpledialog` module contains convenience classes and +The :mod:`!tkinter.simpledialog` module contains convenience classes and functions for creating simple modal dialogs to get a value from the user. @@ -39,8 +39,8 @@ functions for creating simple modal dialogs to get a value from the user. -:mod:`tkinter.filedialog` --- File selection dialogs -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:mod:`!tkinter.filedialog` --- File selection dialogs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: tkinter.filedialog :platform: Tk @@ -50,7 +50,7 @@ functions for creating simple modal dialogs to get a value from the user. -------------- -The :mod:`tkinter.filedialog` module provides classes and factory functions for +The :mod:`!tkinter.filedialog` module provides classes and factory functions for creating file/directory selection windows. Native Load/Save Dialogs @@ -204,8 +204,8 @@ These do not emulate the native look-and-feel of the platform. directory. Confirmation is required if an already existing file is selected. -:mod:`tkinter.commondialog` --- Dialog window templates -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:mod:`!tkinter.commondialog` --- Dialog window templates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: tkinter.commondialog :platform: Tk @@ -215,7 +215,7 @@ These do not emulate the native look-and-feel of the platform. -------------- -The :mod:`tkinter.commondialog` module provides the :class:`Dialog` class that +The :mod:`!tkinter.commondialog` module provides the :class:`Dialog` class that is the base class for dialogs defined in other supporting modules. .. class:: Dialog(master=None, **options) diff --git a/Doc/library/email.encoders.rst b/Doc/library/email.encoders.rst index 9c8c8c9234ed7a..1a9a1cad3a619e 100644 --- a/Doc/library/email.encoders.rst +++ b/Doc/library/email.encoders.rst @@ -25,7 +25,7 @@ is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type message containing binary data. The :mod:`email` package provides some convenient encoders in its -:mod:`~email.encoders` module. These encoders are actually used by the +:mod:`!encoders` module. These encoders are actually used by the :class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` class constructors to provide default encodings. All encoder functions take exactly one argument, the message object to encode. They usually extract the diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index 1ff3e2c3f8df6b..fef064114ecf1b 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -602,7 +602,7 @@ The header objects and their attributes are described in This concrete :class:`Policy` is the backward compatibility policy. It replicates the behavior of the email package in Python 3.2. The - :mod:`~email.policy` module also defines an instance of this class, + :mod:`!policy` module also defines an instance of this class, :const:`compat32`, that is used as the default policy. Thus the default behavior of the email package is to maintain compatibility with Python 3.2. diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index b2151f4d760927..5f0858cb134ebf 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -215,8 +215,8 @@ Functions in unexpected behavior. It's recommended to use the :class:`threading.Lock` or other synchronization primitives for thread-safe module reloading. -:mod:`importlib.abc` -- Abstract base classes related to import ---------------------------------------------------------------- +:mod:`!importlib.abc` -- Abstract base classes related to import +---------------------------------------------------------------- .. module:: importlib.abc :synopsis: Abstract base classes related to import @@ -226,7 +226,7 @@ Functions -------------- -The :mod:`importlib.abc` module contains all of the core abstract base classes +The :mod:`!importlib.abc` module contains all of the core abstract base classes used by :keyword:`import`. Some subclasses of the core abstract base classes are also provided to help in implementing the core ABCs. @@ -596,8 +596,8 @@ ABC hierarchy:: itself does not end in ``__init__``. -:mod:`importlib.machinery` -- Importers and path hooks ------------------------------------------------------- +:mod:`!importlib.machinery` -- Importers and path hooks +------------------------------------------------------- .. module:: importlib.machinery :synopsis: Importers and path hooks @@ -1112,8 +1112,8 @@ find and load modules. Path to the ``.fwork`` file for the extension module. -:mod:`importlib.util` -- Utility code for importers ---------------------------------------------------- +:mod:`!importlib.util` -- Utility code for importers +---------------------------------------------------- .. module:: importlib.util :synopsis: Utility code for importers diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 50a41cc29da0f6..57aad5ba9d1793 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -748,7 +748,7 @@ Command-line interface -------------- The :mod:`!json` module can be invoked as a script via ``python -m json`` -to validate and pretty-print JSON objects. The :mod:`json.tool` submodule +to validate and pretty-print JSON objects. The :mod:`!json.tool` submodule implements this interface. If the optional ``infile`` and ``outfile`` arguments are not diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index d3baf2d760f615..854c9ed784c24a 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -279,7 +279,7 @@ processes: p.join() Queues are thread and process safe. - Any object put into a :mod:`~multiprocessing` queue will be serialized. + Any object put into a :mod:`!multiprocessing` queue will be serialized. **Pipes** @@ -1725,13 +1725,13 @@ inherited by child processes. attributes which allow one to use it to store and retrieve strings. -The :mod:`multiprocessing.sharedctypes` module -"""""""""""""""""""""""""""""""""""""""""""""" +The :mod:`!multiprocessing.sharedctypes` module +""""""""""""""""""""""""""""""""""""""""""""""" .. module:: multiprocessing.sharedctypes :synopsis: Allocate ctypes objects from shared memory. -The :mod:`multiprocessing.sharedctypes` module provides functions for allocating +The :mod:`!multiprocessing.sharedctypes` module provides functions for allocating :mod:`ctypes` objects from shared memory which can be inherited by child processes. @@ -2658,7 +2658,7 @@ Usually message passing between processes is done using queues or by using :class:`~Connection` objects returned by :func:`~multiprocessing.Pipe`. -However, the :mod:`multiprocessing.connection` module allows some extra +However, the :mod:`!multiprocessing.connection` module allows some extra flexibility. It basically gives a high level message oriented API for dealing with sockets or Windows named pipes. It also has support for *digest authentication* using the :mod:`hmac` module, and for polling @@ -2965,18 +2965,18 @@ Below is an example session with logging turned on:: For a full table of logging levels, see the :mod:`logging` module. -The :mod:`multiprocessing.dummy` module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The :mod:`!multiprocessing.dummy` module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: multiprocessing.dummy :synopsis: Dumb wrapper around threading. -:mod:`multiprocessing.dummy` replicates the API of :mod:`!multiprocessing` but is +:mod:`!multiprocessing.dummy` replicates the API of :mod:`!multiprocessing` but is no more than a wrapper around the :mod:`threading` module. .. currentmodule:: multiprocessing.pool -In particular, the ``Pool`` function provided by :mod:`multiprocessing.dummy` +In particular, the ``Pool`` function provided by :mod:`!multiprocessing.dummy` returns an instance of :class:`ThreadPool`, which is a subclass of :class:`Pool` that supports all the same method calls but uses a pool of worker threads rather than worker processes. diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 4814f5f86b2907..2b4aa1ee209997 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1946,7 +1946,7 @@ Protocols :synopsis: pathlib types for static type checking -The :mod:`pathlib.types` module provides types for static type checking. +The :mod:`!pathlib.types` module provides types for static type checking. .. versionadded:: 3.14 diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 8ab3e7ec9ef9d2..bfe017a5c8fe1c 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -1,7 +1,7 @@ .. _debugger: -:mod:`pdb` --- The Python Debugger -================================== +:mod:`!pdb` --- The Python Debugger +=================================== .. module:: pdb :synopsis: The Python debugger for interactive interpreters. @@ -12,7 +12,7 @@ -------------- -The module :mod:`pdb` defines an interactive source code debugger for Python +The module :mod:`!pdb` defines an interactive source code debugger for Python programs. It supports setting (conditional) breakpoints and single stepping at the source line level, inspection of stack frames, source code listing, and evaluation of arbitrary Python code in the context of any stack frame. It also @@ -82,7 +82,7 @@ Command-line interface .. program:: pdb -You can also invoke :mod:`pdb` from the command line to debug other scripts. For +You can also invoke :mod:`!pdb` from the command line to debug other scripts. For example:: python -m pdb [-c command] (-m module | -p pid | pyfile) [args ...] diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 218aa88bc49d47..f7e85d1598727f 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -14,10 +14,10 @@ .. deprecated-removed:: 3.15 3.17 -The :mod:`profile` module is deprecated and will be removed in Python 3.17. +The :mod:`!profile` module is deprecated and will be removed in Python 3.17. Use :mod:`profiling.tracing` instead. -The :mod:`profile` module provides a pure Python implementation of a +The :mod:`!profile` module provides a pure Python implementation of a deterministic profiler. While useful for understanding profiler internals or extending profiler behavior through subclassing, its pure Python implementation introduces significant overhead compared to the C-based :mod:`profiling.tracing` @@ -32,7 +32,7 @@ For most profiling tasks, use: Migration ========= -Migrating from :mod:`profile` to :mod:`profiling.tracing` is straightforward. +Migrating from :mod:`!profile` to :mod:`profiling.tracing` is straightforward. The APIs are compatible:: # Old (deprecated) @@ -57,7 +57,7 @@ a straightforward migration path. :mod:`!profile` and :mod:`!profiling.tracing` module reference ============================================================== -Both the :mod:`profile` and :mod:`profiling.tracing` modules provide the +Both the :mod:`!profile` and :mod:`profiling.tracing` modules provide the following functions: .. function:: run(command, filename=None, sort=-1) @@ -114,7 +114,7 @@ following functions: print(s.getvalue()) The :class:`Profile` class can also be used as a context manager (supported - only in :mod:`profiling.tracing`, not in the deprecated :mod:`profile` + only in :mod:`profiling.tracing`, not in the deprecated :mod:`!profile` module; see :ref:`typecontextmanager`):: import profiling.tracing @@ -178,18 +178,18 @@ printed. Differences from :mod:`!profiling.tracing` ========================================== -The :mod:`profile` module differs from :mod:`profiling.tracing` in several +The :mod:`!profile` module differs from :mod:`profiling.tracing` in several ways: **Higher overhead.** The pure Python implementation is significantly slower than the C implementation, making it unsuitable for profiling long-running programs or performance-sensitive code. -**Calibration support.** The :mod:`profile` module supports calibration to +**Calibration support.** The :mod:`!profile` module supports calibration to compensate for profiling overhead. This is not needed in :mod:`profiling.tracing` because the C implementation has negligible overhead. -**Custom timers.** Both modules support custom timers, but :mod:`profile` +**Custom timers.** Both modules support custom timers, but :mod:`!profile` accepts timer functions that return tuples (like :func:`os.times`), while :mod:`profiling.tracing` requires a function returning a single number. @@ -254,9 +254,9 @@ this error. The error that accumulates in this fashion is typically less than the accuracy of the clock (less than one clock tick), but it *can* accumulate and become very significant. -The problem is more important with the deprecated :mod:`profile` module than +The problem is more important with the deprecated :mod:`!profile` module than with the lower-overhead :mod:`profiling.tracing`. For this reason, -:mod:`profile` provides a means of calibrating itself for a given platform so +:mod:`!profile` provides a means of calibrating itself for a given platform so that this error can be probabilistically (on the average) removed. After the profiler is calibrated, it will be more accurate (in a least square sense), but it will sometimes produce negative numbers (when call counts are exceptionally @@ -271,7 +271,7 @@ calibration. Calibration =========== -The profiler of the :mod:`profile` module subtracts a constant from each event +The profiler of the :mod:`!profile` module subtracts a constant from each event handling time to compensate for the overhead of calling the time function, and socking away the results. By default, the constant is 0. The following procedure can be used to obtain a better constant for a given platform (see diff --git a/Doc/library/profiling.rst b/Doc/library/profiling.rst index 9b58cae28ab781..f4ac47826b28ef 100644 --- a/Doc/library/profiling.rst +++ b/Doc/library/profiling.rst @@ -2,9 +2,9 @@ .. _profiling-module: -*************************************** -:mod:`profiling` --- Python profilers -*************************************** +************************************** +:mod:`!profiling` --- Python profilers +************************************** .. module:: profiling :synopsis: Python profiling tools for performance analysis. @@ -31,7 +31,7 @@ performance bottlenecks and guide optimization efforts. Python provides two fundamentally different approaches to collecting this information: statistical sampling and deterministic tracing. -The :mod:`profiling` package organizes Python's built-in profiling tools under +The :mod:`!profiling` package organizes Python's built-in profiling tools under a single namespace. It contains two submodules, each implementing a different profiling methodology: diff --git a/Doc/library/profiling.sampling.rst b/Doc/library/profiling.sampling.rst index 6c37a8d34cbd42..078062c08c6020 100644 --- a/Doc/library/profiling.sampling.rst +++ b/Doc/library/profiling.sampling.rst @@ -3,7 +3,7 @@ .. _profiling-sampling: *************************************************** -:mod:`profiling.sampling` --- Statistical profiler +:mod:`!profiling.sampling` --- Statistical profiler *************************************************** .. module:: profiling.sampling @@ -22,7 +22,7 @@ :align: center :width: 300px -The :mod:`profiling.sampling` module, named **Tachyon**, provides statistical +The :mod:`!profiling.sampling` module, named **Tachyon**, provides statistical profiling of Python programs through periodic stack sampling. Tachyon can run scripts directly or attach to any running Python process without requiring code changes or restarts. Because sampling occurs externally to the target diff --git a/Doc/library/profiling.tracing.rst b/Doc/library/profiling.tracing.rst index 6e6ba9173a1d2f..d45423cf0d8a72 100644 --- a/Doc/library/profiling.tracing.rst +++ b/Doc/library/profiling.tracing.rst @@ -1,7 +1,7 @@ .. _profiling-tracing: **************************************************** -:mod:`profiling.tracing` --- Deterministic profiler +:mod:`!profiling.tracing` --- Deterministic profiler **************************************************** .. module:: profiling.tracing @@ -17,7 +17,7 @@ -------------- -The :mod:`profiling.tracing` module provides deterministic profiling of Python +The :mod:`!profiling.tracing` module provides deterministic profiling of Python programs. It monitors every function call, function return, and exception event, recording precise timing for each. This approach provides exact call counts and complete visibility into program execution, making it ideal for development and @@ -79,7 +79,7 @@ Command-line interface .. program:: profiling.tracing -The :mod:`profiling.tracing` module can be invoked as a script to profile +The :mod:`!profiling.tracing` module can be invoked as a script to profile another script or module: .. code-block:: shell-session @@ -311,7 +311,7 @@ this latency, which can make them appear slower than they actually are. This error is typically less than one clock tick per call but can become significant for functions called many times. -The :mod:`profiling.tracing` module (and its ``cProfile`` alias) is +The :mod:`!profiling.tracing` module (and its ``cProfile`` alias) is implemented as a C extension with low overhead, so these timing issues are less pronounced than with the deprecated pure Python :mod:`profile` module. diff --git a/Doc/library/pstats.rst b/Doc/library/pstats.rst index ce1cc5c9535ca6..585f17bdb99a70 100644 --- a/Doc/library/pstats.rst +++ b/Doc/library/pstats.rst @@ -1,8 +1,8 @@ .. _pstats-module: -******************************************** -:mod:`pstats` --- Statistics for profilers -******************************************** +******************************************* +:mod:`!pstats` --- Statistics for profilers +******************************************* .. module:: pstats :synopsis: Statistics object for analyzing profiler output. @@ -11,7 +11,7 @@ -------------- -The :mod:`pstats` module provides tools for reading, manipulating, and +The :mod:`!pstats` module provides tools for reading, manipulating, and displaying profiling statistics generated by Python's profilers. It reads output from both :mod:`profiling.tracing` (deterministic profiler) and :mod:`profiling.sampling` (statistical profiler). @@ -341,7 +341,7 @@ The :class:`!Stats` class Command-line interface ====================== -The :mod:`pstats` module can be invoked as a script to interactively browse +The :mod:`!pstats` module can be invoked as a script to interactively browse profile data:: python -m pstats profile_output.prof diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index 0910c2d50791e8..7a53b53a183641 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -759,7 +759,7 @@ values: the type, the quantifier, the name, and a tuple of children. Children are simply additional content model descriptions. The values of the first two fields are constants defined in the -:mod:`xml.parsers.expat.model` module. These constants can be collected in two +:mod:`!xml.parsers.expat.model` module. These constants can be collected in two groups: the model type group and the quantifier group. The constants in the model type group are: @@ -833,7 +833,7 @@ Expat error constants .. module:: xml.parsers.expat.errors -The following constants are provided in the :mod:`xml.parsers.expat.errors` +The following constants are provided in the :mod:`!xml.parsers.expat.errors` module. These constants are useful in interpreting some of the attributes of the :exc:`ExpatError` exception objects raised when an error has occurred. Since for backwards compatibility reasons, the constants' value is the error diff --git a/Doc/library/site.rst b/Doc/library/site.rst index 09a98b4e3b22af..70774020c00f50 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -130,28 +130,28 @@ directory precedes the :file:`foo` directory because :file:`bar.pth` comes alphabetically before :file:`foo.pth`; and :file:`spam` is omitted because it is not mentioned in either path configuration file. -:mod:`sitecustomize` --------------------- +:mod:`!sitecustomize` +--------------------- .. module:: sitecustomize After these path manipulations, an attempt is made to import a module named -:mod:`sitecustomize`, which can perform arbitrary site-specific customizations. +:mod:`!sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` or its subclass exception, and the exception's :attr:`~ImportError.name` attribute equals to ``'sitecustomize'``, it is silently ignored. If Python is started without output streams available, as with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), -attempted output from :mod:`sitecustomize` is ignored. Any other exception +attempted output from :mod:`!sitecustomize` is ignored. Any other exception causes a silent and perhaps mysterious failure of the process. -:mod:`usercustomize` --------------------- +:mod:`!usercustomize` +--------------------- .. module:: usercustomize -After this, an attempt is made to import a module named :mod:`usercustomize`, +After this, an attempt is made to import a module named :mod:`!usercustomize`, which can perform arbitrary user-specific customizations, if :data:`~site.ENABLE_USER_SITE` is true. This file is intended to be created in the user site-packages directory (see below), which is part of ``sys.path`` unless @@ -161,7 +161,7 @@ attribute equals to ``'usercustomize'``, it is silently ignored. Note that for some non-Unix systems, ``sys.prefix`` and ``sys.exec_prefix`` are empty, and the path manipulations are skipped; however the import of -:mod:`sitecustomize` and :mod:`usercustomize` is still attempted. +:mod:`sitecustomize` and :mod:`!usercustomize` is still attempted. .. currentmodule:: site diff --git a/Doc/library/test.rst b/Doc/library/test.rst index a179ea6df057f1..b5a3005f854410 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -164,7 +164,7 @@ Running tests using the command-line interface The :mod:`!test` package can be run as a script to drive Python's regression test suite, thanks to the :option:`-m` option: :program:`python -m test`. Under -the hood, it uses :mod:`test.regrtest`; the call :program:`python -m +the hood, it uses :mod:`!test.regrtest`; the call :program:`python -m test.regrtest` used in previous Python versions still works. Running the script by itself automatically starts running all regression tests in the :mod:`!test` package. It does this by finding all modules in the package whose @@ -197,19 +197,19 @@ regression tests. :ref:`controlled using environment variables `. -:mod:`test.support` --- Utilities for the Python test suite -=========================================================== +:mod:`!test.support` --- Utilities for the Python test suite +============================================================ .. module:: test.support :synopsis: Support for Python's regression test suite. -The :mod:`test.support` module provides support for Python's regression +The :mod:`!test.support` module provides support for Python's regression test suite. .. note:: - :mod:`test.support` is not a public module. It is documented here to help + :mod:`!test.support` is not a public module. It is documented here to help Python developers write tests. The API of this module is subject to change without backwards compatibility concerns between releases. @@ -230,7 +230,7 @@ This module defines the following exceptions: function. -The :mod:`test.support` module defines the following constants: +The :mod:`!test.support` module defines the following constants: .. data:: verbose @@ -363,7 +363,7 @@ The :mod:`test.support` module defines the following constants: .. data:: TEST_SUPPORT_DIR - Set to the top level directory that contains :mod:`test.support`. + Set to the top level directory that contains :mod:`!test.support`. .. data:: TEST_HOME_DIR @@ -438,7 +438,7 @@ The :mod:`test.support` module defines the following constants: Used to test mixed type comparison. -The :mod:`test.support` module defines the following functions: +The :mod:`!test.support` module defines the following functions: .. function:: busy_retry(timeout, err_msg=None, /, *, error=True) @@ -1043,7 +1043,7 @@ The :mod:`test.support` module defines the following functions: .. versionadded:: 3.11 -The :mod:`test.support` module defines the following classes: +The :mod:`!test.support` module defines the following classes: .. class:: SuppressCrashReport() @@ -1089,14 +1089,14 @@ The :mod:`test.support` module defines the following classes: Try to match a single stored value (*dv*) with a supplied value (*v*). -:mod:`test.support.socket_helper` --- Utilities for socket tests -================================================================ +:mod:`!test.support.socket_helper` --- Utilities for socket tests +================================================================= .. module:: test.support.socket_helper :synopsis: Support for socket tests. -The :mod:`test.support.socket_helper` module provides support for socket tests. +The :mod:`!test.support.socket_helper` module provides support for socket tests. .. versionadded:: 3.9 @@ -1167,14 +1167,14 @@ The :mod:`test.support.socket_helper` module provides support for socket tests. exceptions. -:mod:`test.support.script_helper` --- Utilities for the Python execution tests -============================================================================== +:mod:`!test.support.script_helper` --- Utilities for the Python execution tests +=============================================================================== .. module:: test.support.script_helper :synopsis: Support for Python's script execution tests. -The :mod:`test.support.script_helper` module provides support for Python's +The :mod:`!test.support.script_helper` module provides support for Python's script execution tests. .. function:: interpreter_requires_environment() @@ -1278,13 +1278,13 @@ script execution tests. path and the archive name for the zip file. -:mod:`test.support.bytecode_helper` --- Support tools for testing correct bytecode generation -============================================================================================= +:mod:`!test.support.bytecode_helper` --- Support tools for testing correct bytecode generation +============================================================================================== .. module:: test.support.bytecode_helper :synopsis: Support tools for testing correct bytecode generation. -The :mod:`test.support.bytecode_helper` module provides support for testing +The :mod:`!test.support.bytecode_helper` module provides support for testing and inspecting bytecode generation. .. versionadded:: 3.9 @@ -1310,13 +1310,13 @@ The module defines the following class: Throws :exc:`AssertionError` if *opname* is found. -:mod:`test.support.threading_helper` --- Utilities for threading tests -====================================================================== +:mod:`!test.support.threading_helper` --- Utilities for threading tests +======================================================================= .. module:: test.support.threading_helper :synopsis: Support for threading tests. -The :mod:`test.support.threading_helper` module provides support for threading tests. +The :mod:`!test.support.threading_helper` module provides support for threading tests. .. versionadded:: 3.10 @@ -1397,13 +1397,13 @@ The :mod:`test.support.threading_helper` module provides support for threading t finished. -:mod:`test.support.os_helper` --- Utilities for os tests -======================================================================== +:mod:`!test.support.os_helper` --- Utilities for os tests +========================================================= .. module:: test.support.os_helper :synopsis: Support for os tests. -The :mod:`test.support.os_helper` module provides support for os tests. +The :mod:`!test.support.os_helper` module provides support for os tests. .. versionadded:: 3.10 @@ -1592,13 +1592,13 @@ The :mod:`test.support.os_helper` module provides support for os tests. wrapped with a wait loop that checks for the existence of the file. -:mod:`test.support.import_helper` --- Utilities for import tests -================================================================ +:mod:`!test.support.import_helper` --- Utilities for import tests +================================================================= .. module:: test.support.import_helper :synopsis: Support for import tests. -The :mod:`test.support.import_helper` module provides support for import tests. +The :mod:`!test.support.import_helper` module provides support for import tests. .. versionadded:: 3.10 @@ -1706,13 +1706,13 @@ The :mod:`test.support.import_helper` module provides support for import tests. will be reverted at the end of the block. -:mod:`test.support.warnings_helper` --- Utilities for warnings tests -==================================================================== +:mod:`!test.support.warnings_helper` --- Utilities for warnings tests +===================================================================== .. module:: test.support.warnings_helper :synopsis: Support for warnings tests. -The :mod:`test.support.warnings_helper` module provides support for warnings tests. +The :mod:`!test.support.warnings_helper` module provides support for warnings tests. .. versionadded:: 3.10 diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 95a57c57e71d56..bfe93bc253d4fc 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -2248,7 +2248,7 @@ Settings and special methods Set turtle mode ("standard", "logo" or "world") and perform reset. If mode is not given, current mode is returned. - Mode "standard" is compatible with old :mod:`turtle`. Mode "logo" is + Mode "standard" is compatible with old :mod:`!turtle`. Mode "logo" is compatible with most Logo turtle graphics. Mode "world" uses user-defined "world coordinates". **Attention**: in this mode angles appear distorted if ``x/y`` unit-ratio doesn't equal 1. @@ -2689,7 +2689,7 @@ Screen and Turtle. Python script :file:`{filename}.py`. It is intended to serve as a template for translation of the docstrings into different languages. -If you (or your students) want to use :mod:`turtle` with online help in your +If you (or your students) want to use :mod:`!turtle` with online help in your native language, you have to translate the docstrings and save the resulting file as e.g. :file:`turtle_docstringdict_german.py`. @@ -2752,7 +2752,7 @@ Short explanation of selected entries: auto``. - If you set e.g. ``language = italian`` the docstringdict :file:`turtle_docstringdict_italian.py` will be loaded at import time (if - present on the import path, e.g. in the same directory as :mod:`turtle`). + present on the import path, e.g. in the same directory as :mod:`!turtle`). - The entries *exampleturtle* and *examplescreen* define the names of these objects as they occur in the docstrings. The transformation of method-docstrings to function-docstrings will delete these names from the @@ -2761,7 +2761,7 @@ Short explanation of selected entries: switch ("no subprocess"). This will prevent :func:`exitonclick` to enter the mainloop. -There can be a :file:`turtle.cfg` file in the directory where :mod:`turtle` is +There can be a :file:`turtle.cfg` file in the directory where :mod:`!turtle` is stored and an additional one in the current working directory. The latter will override the settings of the first one. @@ -2770,13 +2770,13 @@ study it as an example and see its effects when running the demos (preferably not from within the demo-viewer). -:mod:`turtledemo` --- Demo scripts -================================== +:mod:`!turtledemo` --- Demo scripts +=================================== .. module:: turtledemo :synopsis: A viewer for example turtle scripts -The :mod:`turtledemo` package includes a set of demo scripts. These +The :mod:`!turtledemo` package includes a set of demo scripts. These scripts can be run and viewed using the supplied demo viewer as follows:: python -m turtledemo @@ -2785,11 +2785,11 @@ Alternatively, you can run the demo scripts individually. For example, :: python -m turtledemo.bytedesign -The :mod:`turtledemo` package directory contains: +The :mod:`!turtledemo` package directory contains: - A demo viewer :file:`__main__.py` which can be used to view the sourcecode of the scripts and run them at the same time. -- Multiple scripts demonstrating different features of the :mod:`turtle` +- Multiple scripts demonstrating different features of the :mod:`!turtle` module. Examples can be accessed via the Examples menu. They can also be run standalone. - A :file:`turtle.cfg` file which serves as an example of how to write diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 83d2c8704e35d9..b857b2a235e1bd 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1539,13 +1539,13 @@ some point in the future. -:mod:`urllib.response` --- Response classes used by urllib -========================================================== +:mod:`!urllib.response` --- Response classes used by urllib +=========================================================== .. module:: urllib.response :synopsis: Response classes used by urllib. -The :mod:`urllib.response` module defines functions and classes which define a +The :mod:`!urllib.response` module defines functions and classes which define a minimal file-like interface, including ``read()`` and ``readline()``. Functions defined by this module are used internally by the :mod:`!urllib.request` module. The typical response object is a :class:`urllib.response.addinfourl` instance: diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 2a25ed045c68bd..6dc5f90686c778 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -1,7 +1,7 @@ .. _mod-weakref: -:mod:`weakref` --- Weak references -================================== +:mod:`!weakref` --- Weak references +=================================== .. module:: weakref :synopsis: Support for weak references and weak dictionaries. @@ -15,7 +15,7 @@ -------------- -The :mod:`weakref` module allows the Python programmer to create :dfn:`weak +The :mod:`!weakref` module allows the Python programmer to create :dfn:`weak references` to objects. .. When making changes to the examples in this file, be sure to update @@ -39,7 +39,7 @@ associate a name with each. If you used a Python dictionary to map names to images, or images to names, the image objects would remain alive just because they appeared as values or keys in the dictionaries. The :class:`WeakKeyDictionary` and :class:`WeakValueDictionary` classes supplied by -the :mod:`weakref` module are an alternative, using weak references to construct +the :mod:`!weakref` module are an alternative, using weak references to construct mappings that don't keep objects alive solely because they appear in the mapping objects. If, for example, an image object is a value in a :class:`WeakValueDictionary`, then when the last remaining references to that @@ -63,7 +63,7 @@ remains alive until the object is collected. Most programs should find that using one of these weak container types or :class:`finalize` is all they need -- it's not usually necessary to create your own weak references directly. The low-level machinery is -exposed by the :mod:`weakref` module for the benefit of advanced uses. +exposed by the :mod:`!weakref` module for the benefit of advanced uses. Not all objects can be weakly referenced. Objects which support weak references include class instances, functions written in Python (but not in C), instance methods, diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 8e9b9ada93842f..0ace7b72d32570 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -13,7 +13,7 @@ .. warning:: - :mod:`wsgiref` is a reference implementation and is not recommended for + :mod:`!wsgiref` is a reference implementation and is not recommended for production. The module only implements basic security checks. The Web Server Gateway Interface (WSGI) is a standard interface between web @@ -40,8 +40,8 @@ to tutorials and other resources. .. XXX If you're just trying to write a web application... -:mod:`wsgiref.util` -- WSGI environment utilities -------------------------------------------------- +:mod:`!wsgiref.util` -- WSGI environment utilities +-------------------------------------------------- .. module:: wsgiref.util :synopsis: WSGI environment utilities. @@ -149,7 +149,7 @@ in type annotations. httpd.serve_forever() -In addition to the environment functions above, the :mod:`wsgiref.util` module +In addition to the environment functions above, the :mod:`!wsgiref.util` module also provides these miscellaneous utilities: @@ -189,8 +189,8 @@ also provides these miscellaneous utilities: Support for :meth:`~object.__getitem__` method has been removed. -:mod:`wsgiref.headers` -- WSGI response header tools ----------------------------------------------------- +:mod:`!wsgiref.headers` -- WSGI response header tools +----------------------------------------------------- .. module:: wsgiref.headers :synopsis: WSGI response header tools. @@ -273,8 +273,8 @@ manipulation of WSGI response headers using a mapping-like interface. *headers* parameter is optional. -:mod:`wsgiref.simple_server` -- a simple WSGI HTTP server ---------------------------------------------------------- +:mod:`!wsgiref.simple_server` -- a simple WSGI HTTP server +---------------------------------------------------------- .. module:: wsgiref.simple_server :synopsis: A simple WSGI HTTP server. @@ -315,7 +315,7 @@ request. (E.g., using the :func:`shift_path_info` function from This function is a small but complete WSGI application that returns a text page containing the message "Hello world!" and a list of the key/value pairs provided in the *environ* parameter. It's useful for verifying that a WSGI server (such - as :mod:`wsgiref.simple_server`) is able to run a simple WSGI application + as :mod:`!wsgiref.simple_server`) is able to run a simple WSGI application correctly. The *start_response* callable should follow the :class:`.StartResponse` protocol. @@ -387,8 +387,8 @@ request. (E.g., using the :func:`shift_path_info` function from interface. -:mod:`wsgiref.validate` --- WSGI conformance checker ----------------------------------------------------- +:mod:`!wsgiref.validate` --- WSGI conformance checker +----------------------------------------------------- .. module:: wsgiref.validate :synopsis: WSGI conformance checker. @@ -396,7 +396,7 @@ request. (E.g., using the :func:`shift_path_info` function from When creating new WSGI application objects, frameworks, servers, or middleware, it can be useful to validate the new code's conformance using -:mod:`wsgiref.validate`. This module provides a function that creates WSGI +:mod:`!wsgiref.validate`. This module provides a function that creates WSGI application objects that validate communications between a WSGI server or gateway and a WSGI application object, to check both sides for protocol conformance. @@ -455,8 +455,8 @@ Paste" library. httpd.serve_forever() -:mod:`wsgiref.handlers` -- server/gateway base classes ------------------------------------------------------- +:mod:`!wsgiref.handlers` -- server/gateway base classes +------------------------------------------------------- .. module:: wsgiref.handlers :synopsis: WSGI server/gateway base classes. @@ -627,7 +627,7 @@ input, output, and error streams. The default environment variables to be included in every request's WSGI environment. By default, this is a copy of ``os.environ`` at the time that - :mod:`wsgiref.handlers` was imported, but subclasses can either create their own + :mod:`!wsgiref.handlers` was imported, but subclasses can either create their own at the class or instance level. Note that the dictionary should be considered read-only, since the default value is shared between multiple classes and instances. @@ -778,8 +778,8 @@ input, output, and error streams. .. versionadded:: 3.2 -:mod:`wsgiref.types` -- WSGI types for static type checking ------------------------------------------------------------ +:mod:`!wsgiref.types` -- WSGI types for static type checking +------------------------------------------------------------ .. module:: wsgiref.types :synopsis: WSGI types for static type checking diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index acd8d399fe32fc..81d47147f33816 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -20,7 +20,7 @@ Python's interfaces for processing XML are grouped in the ``xml`` package. If you need to parse untrusted or unauthenticated data, see :ref:`xml-security`. -It is important to note that modules in the :mod:`xml` package require that +It is important to note that modules in the :mod:`!xml` package require that there be at least one SAX-compliant XML parser available. The Expat parser is included with Python, so the :mod:`xml.parsers.expat` module will always be available. From 35dc547ab5a6bb9be9748002d42d0d9e86f9cced Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Wed, 11 Feb 2026 14:33:00 +0100 Subject: [PATCH 075/498] gh-142518: Document thread-safety guarantees of dict operations (#144184) * Address feedback; move thread safety section below see-also * Address feedback - don't mention equality comparison only * Change admonition to rubric; cross-reference glossary --------- Co-authored-by: Petr Viktorin --- Doc/library/stdtypes.rst | 140 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 3745f32d874bd4..0e5f5dc39e7277 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -5593,6 +5593,146 @@ can be used interchangeably to index the same dictionary entry. of a :class:`dict`. +.. _thread-safety-dict: + +.. rubric:: Thread safety for dict objects + +Creating a dictionary with the :class:`dict` constructor is atomic when the +argument to it is a :class:`dict` or a :class:`tuple`. When using the +:meth:`dict.fromkeys` method, dictionary creation is atomic when the +argument is a :class:`dict`, :class:`tuple`, :class:`set` or +:class:`frozenset`. + +The following operations and functions are :term:`lock-free` and +:term:`atomic `. + +.. code-block:: + :class: good + + d[key] # dict.__getitem__ + d.get(key) # dict.get + key in d # dict.__contains__ + len(d) # dict.__len__ + +All other operations from here on hold the :term:`per-object lock`. + +Writing or removing a single item is safe to call from multiple threads +and will not corrupt the dictionary: + +.. code-block:: + :class: good + + d[key] = value # write + del d[key] # delete + d.pop(key) # remove and return + d.popitem() # remove and return last item + d.setdefault(key, v) # insert if missing + +These operations may compare keys using :meth:`~object.__eq__`, which can +execute arbitrary Python code. During such comparisons, the dictionary may +be modified by another thread. For built-in types like :class:`str`, +:class:`int`, and :class:`float`, that implement :meth:`~object.__eq__` in C, +the underlying lock is not released during comparisons and this is not a +concern. + +The following operations return new objects and hold the :term:`per-object lock` +for the duration of the operation: + +.. code-block:: + :class: good + + d.copy() # returns a shallow copy of the dictionary + d | other # merges two dicts into a new dict + d.keys() # returns a new dict_keys view object + d.values() # returns a new dict_values view object + d.items() # returns a new dict_items view object + +The :meth:`~dict.clear` method holds the lock for its duration. Other +threads cannot observe elements being removed. + +The following operations lock both dictionaries. For :meth:`~dict.update` +and ``|=``, this applies only when the other operand is a :class:`dict` +that uses the standard dict iterator (but not subclasses that override +iteration). For equality comparison, this applies to :class:`dict` and +its subclasses: + +.. code-block:: + :class: good + + d.update(other_dict) # both locked when other_dict is a dict + d |= other_dict # both locked when other_dict is a dict + d == other_dict # both locked for dict and subclasses + +All comparison operations also compare values using :meth:`~object.__eq__`, +so for non-built-in types the lock may be released during comparison. + +:meth:`~dict.fromkeys` locks both the new dictionary and the iterable +when the iterable is exactly a :class:`dict`, :class:`set`, or +:class:`frozenset` (not subclasses): + +.. code-block:: + :class: good + + dict.fromkeys(a_dict) # locks both + dict.fromkeys(a_set) # locks both + dict.fromkeys(a_frozenset) # locks both + +When updating from a non-dict iterable, only the target dictionary is +locked. The iterable may be concurrently modified by another thread: + +.. code-block:: + :class: maybe + + d.update(iterable) # iterable is not a dict: only d locked + d |= iterable # iterable is not a dict: only d locked + dict.fromkeys(iterable) # iterable is not a dict/set/frozenset: only result locked + +Operations that involve multiple accesses, as well as iteration, are never +atomic: + +.. code-block:: + :class: bad + + # NOT atomic: read-modify-write + d[key] = d[key] + 1 + + # NOT atomic: check-then-act (TOCTOU) + if key in d: + del d[key] + + # NOT thread-safe: iteration while modifying + for key, value in d.items(): + process(key) # another thread may modify d + +To avoid time-of-check to time-of-use (TOCTOU) issues, use atomic +operations or handle exceptions: + +.. code-block:: + :class: good + + # Use pop() with default instead of check-then-delete + d.pop(key, None) + + # Or handle the exception + try: + del d[key] + except KeyError: + pass + +To safely iterate over a dictionary that may be modified by another +thread, iterate over a copy: + +.. code-block:: + :class: good + + # Make a copy to iterate safely + for key, value in d.copy().items(): + process(key) + +Consider external synchronization when sharing :class:`dict` instances +across threads. See :ref:`freethreading-python-howto` for more information. + + .. _dict-views: Dictionary view objects From 81484c5629f9d8b698a2be58f850a0e4efe48ed3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:12:31 +0200 Subject: [PATCH 076/498] gh-144639: Ruff: target Python 3.14 syntax in `Lib/test` (#144656) Co-authored-by: Alex Waygood Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Lib/test/.ruff.toml | 12 ++---------- Lib/test/support/import_helper.py | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml index a1b749798fa263..7b46139f786cf7 100644 --- a/Lib/test/.ruff.toml +++ b/Lib/test/.ruff.toml @@ -1,6 +1,7 @@ extend = "../../.ruff.toml" # Inherit the project-wide settings -target-version = "py312" +# Unlike Tools/, tests can use newer syntax than PYTHON_FOR_REGEN +target-version = "py314" extend-exclude = [ # Excluded (run with the other AC files in its own separate ruff job in pre-commit) @@ -15,15 +16,6 @@ extend-exclude = [ "test_grammar.py", ] -[per-file-target-version] -# Type parameter defaults -"test_type_params.py" = "py313" - -# Template string literals -"test_annotationlib.py" = "py314" -"test_string/test_templatelib.py" = "py314" -"test_tstring.py" = "py314" - [lint] select = [ "F401", # Unused import diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 093de6a82d8ca7..e8a58ed77061f5 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -71,7 +71,7 @@ def make_legacy_pyc(source, allow_compile=False): try: pyc_file = importlib.util.cache_from_source(source) shutil.move(pyc_file, legacy_pyc) - except (FileNotFoundError, NotImplementedError): + except FileNotFoundError, NotImplementedError: if not allow_compile: raise py_compile.compile(source, legacy_pyc, doraise=True) From 347d3594d3993282c3ae5a6872f36a71fbfbc734 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 11 Feb 2026 20:59:31 +0530 Subject: [PATCH 077/498] gh-143300: implement `PyUnstable_SetImmortal` for marking objects as immortal (#144543) --- Doc/c-api/object.rst | 17 ++++++++ Include/cpython/object.h | 2 + ...-02-11-13-30-11.gh-issue-143300.yjB63-.rst | 1 + Modules/_testcapi/object.c | 39 +++++++++++++++++++ Objects/object.c | 11 ++++++ 5 files changed, 70 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 992a4383f97241..f71bfebdb2a19a 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -801,3 +801,20 @@ Object Protocol cannot fail. .. versionadded:: 3.14 + +.. c:function:: int PyUnstable_SetImmortal(PyObject *op) + + Marks the object *op* :term:`immortal`. The argument should be uniquely referenced by + the calling thread. This is intended to be used for reducing reference counting contention + in the :term:`free-threaded build` for objects which are shared across threads. + + This is a one-way process: objects can only be made immortal; they cannot be + made mortal once again. Immortal objects do not participate in reference counting + and will never be garbage collected. If the object is GC-tracked, it is untracked. + + This function is intended to be used soon after *op* is created, by the code that + creates it, such as in the object's :c:member:`~PyTypeObject.tp_new` slot. + Returns 1 if the object was made immortal and returns 0 if it was not. + This function cannot fail. + + .. versionadded:: next diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 28c909531dba64..61cdb93d1d5354 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -493,3 +493,5 @@ PyAPI_FUNC(int) PyUnstable_TryIncRef(PyObject *); PyAPI_FUNC(void) PyUnstable_EnableTryIncRef(PyObject *); PyAPI_FUNC(int) PyUnstable_Object_IsUniquelyReferenced(PyObject *); + +PyAPI_FUNC(int) PyUnstable_SetImmortal(PyObject *op); diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst new file mode 100644 index 00000000000000..85c75a224e42fc --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst @@ -0,0 +1 @@ +Add :c:func:`PyUnstable_SetImmortal` C-API function to mark objects as :term:`immortal`. diff --git a/Modules/_testcapi/object.c b/Modules/_testcapi/object.c index 153b28e5fe2e95..9160005e00654f 100644 --- a/Modules/_testcapi/object.c +++ b/Modules/_testcapi/object.c @@ -201,6 +201,44 @@ test_py_try_inc_ref(PyObject *self, PyObject *unused) Py_RETURN_NONE; } +static PyObject * +test_py_set_immortal(PyObject *self, PyObject *unused) +{ + // the object is allocated on C stack as otherwise, + // it would trip the refleak checker when the object + // is made immortal and leak memory, for the same + // reason we cannot call PyObject_Init() on it. + PyObject object = {0}; +#ifdef Py_GIL_DISABLED + object.ob_tid = _Py_ThreadId(); + object.ob_gc_bits = 0; + object.ob_ref_local = 1; + object.ob_ref_shared = 0; +#else + object.ob_refcnt = 1; +#endif + object.ob_type = &PyBaseObject_Type; + + assert(!PyUnstable_IsImmortal(&object)); + int rc = PyUnstable_SetImmortal(&object); + assert(rc == 1); + assert(PyUnstable_IsImmortal(&object)); + Py_DECREF(&object); // should not dealloc + assert(PyUnstable_IsImmortal(&object)); + + // Check already immortal object + rc = PyUnstable_SetImmortal(&object); + assert(rc == 0); + + // Check unicode objects + PyObject *unicode = PyUnicode_FromString("test"); + assert(!PyUnstable_IsImmortal(unicode)); + rc = PyUnstable_SetImmortal(unicode); + assert(rc == 0); + assert(!PyUnstable_IsImmortal(unicode)); + Py_DECREF(unicode); + Py_RETURN_NONE; +} static PyObject * _test_incref(PyObject *ob) @@ -528,6 +566,7 @@ static PyMethodDef test_methods[] = { {"pyobject_is_unique_temporary", pyobject_is_unique_temporary, METH_O}, {"pyobject_is_unique_temporary_new_object", pyobject_is_unique_temporary_new_object, METH_NOARGS}, {"test_py_try_inc_ref", test_py_try_inc_ref, METH_NOARGS}, + {"test_py_set_immortal", test_py_set_immortal, METH_NOARGS}, {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, {"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS}, diff --git a/Objects/object.c b/Objects/object.c index a4f8ddf54b9484..1ddd949d28143e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2839,6 +2839,17 @@ PyUnstable_EnableTryIncRef(PyObject *op) #endif } +int +PyUnstable_SetImmortal(PyObject *op) +{ + assert(op != NULL); + if (!_PyObject_IsUniquelyReferenced(op) || PyUnicode_Check(op)) { + return 0; + } + _Py_SetImmortal(op); + return 1; +} + void _Py_ResurrectReference(PyObject *op) { From 7cfeb8c7569e89fe0a106efe0c2e1e85844211d3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 11 Feb 2026 17:33:36 +0200 Subject: [PATCH 078/498] Post 3.15.0a6 --- Include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 117b041cdc11ee..50d5ac4a73c1d8 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 6 /* Version as a string */ -#define PY_VERSION "3.15.0a6" +#define PY_VERSION "3.15.0a6+" /*--end constants--*/ From 3718f4be60ebb0725b35f597a9de3f7a93ba9f72 Mon Sep 17 00:00:00 2001 From: Ronald Eddy Jr Date: Wed, 11 Feb 2026 11:35:25 -0500 Subject: [PATCH 079/498] Fix typos and grammar errors across documentation (#144709) --- Doc/bugs.rst | 2 +- Doc/c-api/float.rst | 4 ++-- Doc/c-api/init.rst | 8 ++++---- Doc/c-api/init_config.rst | 6 +++--- Doc/c-api/intro.rst | 4 ++-- Doc/c-api/module.rst | 2 +- Doc/c-api/structures.rst | 2 +- Doc/c-api/veryhigh.rst | 2 +- Doc/deprecations/pending-removal-in-3.15.rst | 2 +- Doc/glossary.rst | 2 +- Doc/library/mailbox.rst | 10 +++++----- Doc/library/multiprocessing.rst | 4 ++-- Doc/library/os.rst | 10 +++++----- Doc/library/pickle.rst | 4 ++-- Doc/library/pyexpat.rst | 2 +- Doc/library/resource.rst | 4 ++-- Doc/library/secrets.rst | 2 +- Doc/library/select.rst | 10 +++++----- Doc/library/selectors.rst | 2 +- Doc/library/shelve.rst | 4 ++-- Doc/library/shlex.rst | 6 +++--- Doc/library/shutil.rst | 4 ++-- Doc/library/signal.rst | 6 +++--- Doc/library/site.rst | 6 +++--- Doc/library/socket.rst | 12 ++++++------ Doc/library/sqlite3.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/library/trace.rst | 2 +- Doc/library/tracemalloc.rst | 7 +++---- Doc/library/typing.rst | 2 +- Doc/library/xml.dom.minidom.rst | 2 +- Doc/library/xmlrpc.server.rst | 2 +- Doc/tutorial/classes.rst | 2 +- Doc/tutorial/controlflow.rst | 8 ++++---- Doc/tutorial/datastructures.rst | 2 +- Doc/tutorial/whatnow.rst | 2 +- 36 files changed, 76 insertions(+), 77 deletions(-) diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 0683eebbaf677b..254a22f2622bd8 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -9,7 +9,7 @@ stability. In order to maintain this reputation, the developers would like to know of any deficiencies you find in Python. It can be sometimes faster to fix bugs yourself and contribute patches to -Python as it streamlines the process and involves less people. Learn how to +Python as it streamlines the process and involves fewer people. Learn how to :ref:`contribute `. Documentation bugs diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index b0d440580b9886..dcd545478277a8 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -80,7 +80,7 @@ Floating-Point Objects .. c:macro:: Py_INFINITY - This macro expands a to constant expression of type :c:expr:`double`, that + This macro expands to a constant expression of type :c:expr:`double`, that represents the positive infinity. It is equivalent to the :c:macro:`!INFINITY` macro from the C11 standard @@ -92,7 +92,7 @@ Floating-Point Objects .. c:macro:: Py_NAN - This macro expands a to constant expression of type :c:expr:`double`, that + This macro expands to a constant expression of type :c:expr:`double`, that represents a quiet not-a-number (qNaN) value. On most platforms, this is equivalent to the :c:macro:`!NAN` macro from diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 7411644f9e110b..6786aa76563f52 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -424,7 +424,7 @@ Initializing and finalizing the interpreter Note that Python will do a best effort at freeing all memory allocated by the Python interpreter. Therefore, any C-Extension should make sure to correctly clean up all - of the preveiously allocated PyObjects before using them in subsequent calls to + of the previously allocated PyObjects before using them in subsequent calls to :c:func:`Py_Initialize`. Otherwise it could introduce vulnerabilities and incorrect behavior. @@ -1407,7 +1407,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. Get the current interpreter. - Issue a fatal error if there no :term:`attached thread state`. + Issue a fatal error if there is no :term:`attached thread state`. It cannot return NULL. .. versionadded:: 3.9 @@ -1979,7 +1979,7 @@ Python-level trace functions in previous versions. *what* when after any bytecode is processed after which the exception becomes set within the frame being executed. The effect of this is that as exception propagation causes the Python stack to unwind, the callback is called upon - return to each frame as the exception propagates. Only trace functions receives + return to each frame as the exception propagates. Only trace functions receive these events; they are not needed by the profiler. @@ -2119,7 +2119,7 @@ Reference tracing the tracer function is called. Return ``0`` on success. Set an exception and return ``-1`` on error. - Not that tracer functions **must not** create Python objects inside or + Note that tracer functions **must not** create Python objects inside or otherwise the call will be re-entrant. The tracer also **must not** clear any existing exception or set an exception. A :term:`thread state` will be active every time the tracer function is called. diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index c345029e4acd49..a143274bfe69e2 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -544,9 +544,9 @@ Configuration Options Visibility: -* Public: Can by get by :c:func:`PyConfig_Get` and set by +* Public: Can be retrieved by :c:func:`PyConfig_Get` and set by :c:func:`PyConfig_Set`. -* Read-only: Can by get by :c:func:`PyConfig_Get`, but cannot be set by +* Read-only: Can be retrieved by :c:func:`PyConfig_Get`, but cannot be set by :c:func:`PyConfig_Set`. @@ -1153,7 +1153,7 @@ PyConfig Most ``PyConfig`` methods :ref:`preinitialize Python ` if needed. In that case, the Python preinitialization configuration - (:c:type:`PyPreConfig`) in based on the :c:type:`PyConfig`. If configuration + (:c:type:`PyPreConfig`) is based on the :c:type:`PyConfig`. If configuration fields which are in common with :c:type:`PyPreConfig` are tuned, they must be set before calling a :c:type:`PyConfig` method: diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index e7ea5b9ba4016c..a5dfbe7f4e1305 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -220,7 +220,7 @@ Docstring macros General utility macros ---------------------- -The following macros common tasks not specific to Python. +The following macros are for common tasks not specific to Python. .. c:macro:: Py_UNUSED(arg) @@ -317,7 +317,7 @@ Assertion utilities In debug mode, and on unsupported compilers, the macro expands to a call to :c:func:`Py_FatalError`. - A use for ``Py_UNREACHABLE()`` is following a call a function that + A use for ``Py_UNREACHABLE()`` is following a call to a function that never returns but that is not declared ``_Noreturn``. If a code path is very unlikely code but can be reached under exceptional diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 5c8b0511492c1e..aa2145b5fe5d09 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -752,7 +752,7 @@ remove it. .. versionchanged:: 3.9 :c:member:`m_traverse`, :c:member:`m_clear` and :c:member:`m_free` - functions are longer called before the module state is allocated. + functions are no longer called before the module state is allocated. .. _moduledef-dynamic: diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 62f45def04f746..70c4de543b7d00 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -410,7 +410,7 @@ There are these calling conventions: These two constants are not used to indicate the calling convention but the -binding when use with methods of classes. These may not be used for functions +binding when used with methods of classes. These may not be used for functions defined for modules. At most one of these flags may be set for any given method. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 7eb9f0b54abd4e..6256bf7a1454a9 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -191,7 +191,7 @@ the same library that the Python runtime is using. objects *globals* and *locals* with the compiler flags specified by *flags*. *globals* must be a dictionary; *locals* can be any object that implements the mapping protocol. The parameter *start* specifies - the start symbol and must one of the :ref:`available start symbols `. + the start symbol and must be one of the :ref:`available start symbols `. Returns the result of executing the code as a Python object, or ``NULL`` if an exception was raised. diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index 00266b1725c8a1..e7f27f73664df3 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -54,7 +54,7 @@ Pending removal in Python 3.15 * :func:`~threading.RLock` will take no arguments in Python 3.15. Passing any arguments has been deprecated since Python 3.14, - as the Python version does not permit any arguments, + as the Python version does not permit any arguments, but the C version allows any number of positional or keyword arguments, ignoring every argument. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 1dccb77cc53228..6151143a97b420 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -1359,7 +1359,7 @@ Glossary 'email.mime.text' race condition - A condition of a program where the its behavior + A condition of a program where the behavior depends on the relative timing or ordering of events, particularly in multi-threaded programs. Race conditions can lead to :term:`non-deterministic` behavior and bugs that are difficult to diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index 62e289573c0c7e..ed135bf02cb968 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -1025,7 +1025,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. .. method:: remove_flag(flag) Unset the flag(s) specified by *flag* without changing other flags. To - remove more than one flag at a time, *flag* maybe a string of more than + remove more than one flag at a time, *flag* may be a string of more than one character. If "info" contains experimental information rather than flags, the current "info" is not modified. @@ -1190,7 +1190,7 @@ When a :class:`!MaildirMessage` instance is created based upon a .. method:: remove_flag(flag) Unset the flag(s) specified by *flag* without changing other flags. To - remove more than one flag at a time, *flag* maybe a string of more than + remove more than one flag at a time, *flag* may be a string of more than one character. When an :class:`!mboxMessage` instance is created based upon a @@ -1562,7 +1562,7 @@ When a :class:`!BabylMessage` instance is created based upon an .. method:: remove_flag(flag) Unset the flag(s) specified by *flag* without changing other flags. To - remove more than one flag at a time, *flag* maybe a string of more than + remove more than one flag at a time, *flag* may be a string of more than one character. When an :class:`!MMDFMessage` instance is created based upon a @@ -1641,7 +1641,7 @@ The following exception classes are defined in the :mod:`!mailbox` module: .. exception:: Error() - The based class for all other module-specific exceptions. + The base class for all other module-specific exceptions. .. exception:: NoSuchMailboxError() @@ -1661,7 +1661,7 @@ The following exception classes are defined in the :mod:`!mailbox` module: Raised when some mailbox-related condition beyond the control of the program causes it to be unable to proceed, such as when failing to acquire a lock that - another program already holds a lock, or when a uniquely generated file name + another program already holds, or when a uniquely generated file name already exists. diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index c25cba28761481..2b67d10d7bf1b7 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1222,7 +1222,7 @@ Miscellaneous Set the path of the Python interpreter to use when starting a child process. (By default :data:`sys.executable` is used). Embedders will probably need to - do some thing like :: + do something like :: set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe')) @@ -2473,7 +2473,7 @@ with the :class:`Pool` class. duration of the Pool's work queue. A frequent pattern found in other systems (such as Apache, mod_wsgi, etc) to free resources held by workers is to allow a worker within a pool to complete only a set - amount of work before being exiting, being cleaned up and a new + amount of work before exiting, being cleaned up and a new process spawned to replace the old one. The *maxtasksperchild* argument to the :class:`Pool` exposes this ability to the end user. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 13bbd9d61e947b..7418f3a8bacb0f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -111,7 +111,7 @@ Python UTF-8 Mode .. versionchanged:: 3.15 Python UTF-8 mode is now enabled by default (:pep:`686`). - It may be disabled with by setting :envvar:`PYTHONUTF8=0 ` as + It may be disabled by setting :envvar:`PYTHONUTF8=0 ` as an environment variable or by using the :option:`-X utf8=0 <-X>` command line option. The Python UTF-8 Mode ignores the :term:`locale encoding` and forces the usage @@ -254,7 +254,7 @@ process and user. .. warning:: This function is not thread-safe. Calling it while the environment is - being modified in an other thread is an undefined behavior. Reading from + being modified in another thread is an undefined behavior. Reading from :data:`os.environ` or :data:`os.environb`, or calling :func:`os.getenv` while reloading, may return an empty result. @@ -4371,7 +4371,7 @@ Naturally, they are all only available on Linux. except it includes any time that the system is suspended. The file descriptor's behaviour can be modified by specifying a *flags* value. - Any of the following variables may used, combined using bitwise OR + Any of the following variables may be used, combined using bitwise OR (the ``|`` operator): - :const:`TFD_NONBLOCK` @@ -4403,7 +4403,7 @@ Naturally, they are all only available on Linux. *fd* must be a valid timer file descriptor. The timer's behaviour can be modified by specifying a *flags* value. - Any of the following variables may used, combined using bitwise OR + Any of the following variables may be used, combined using bitwise OR (the ``|`` operator): - :const:`TFD_TIMER_ABSTIME` @@ -4472,7 +4472,7 @@ Naturally, they are all only available on Linux. Return a two-item tuple of floats (``next_expiration``, ``interval``). - ``next_expiration`` denotes the relative time until next the timer next fires, + ``next_expiration`` denotes the relative time until the timer next fires, regardless of if the :const:`TFD_TIMER_ABSTIME` flag is set. ``interval`` denotes the timer's interval. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index d3468cce39b6d2..02b79a9f3a7a47 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -519,7 +519,7 @@ The following types can be pickled: * classes accessible from the top level of a module; -* instances of such classes whose the result of calling :meth:`~object.__getstate__` +* instances of such classes for which the result of calling :meth:`~object.__getstate__` is picklable (see section :ref:`pickle-inst` for details). Attempts to pickle unpicklable objects will raise the :exc:`PicklingError` @@ -588,7 +588,7 @@ methods: .. method:: object.__getnewargs_ex__() - In protocols 2 and newer, classes that implements the + In protocols 2 and newer, classes that implement the :meth:`__getnewargs_ex__` method can dictate the values passed to the :meth:`__new__` method upon unpickling. The method must return a pair ``(args, kwargs)`` where *args* is a tuple of positional arguments diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index 7a53b53a183641..ff5265835da3f8 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -485,7 +485,7 @@ otherwise stated. ...``). The *doctypeName* is provided exactly as presented. The *systemId* and *publicId* parameters give the system and public identifiers if specified, or ``None`` if omitted. *has_internal_subset* will be true if the document - contains and internal document declaration subset. This requires Expat version + contains an internal document declaration subset. This requires Expat version 1.2 or newer. diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index c58dc4243ecb19..b176a28fdfe35b 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -356,9 +356,9 @@ These functions are used to retrieve resource usage information: print(getrusage(RUSAGE_SELF)) The fields of the return value each describe how a particular system resource - has been used, e.g. amount of time spent running is user mode or number of times + has been used, e.g. amount of time spent running in user mode or number of times the process was swapped out of main memory. Some values are dependent on the - clock tick internal, e.g. the amount of memory the process is using. + clock tick interval, e.g. the amount of memory the process is using. For backward compatibility, the return value is also accessible as a tuple of 16 elements. diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index 997d1f32cccd75..e266849918a80b 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -120,7 +120,7 @@ argument to the various ``token_*`` functions. That argument is taken as the number of bytes of randomness to use. Otherwise, if no argument is provided, or if the argument is ``None``, -the ``token_*`` functions uses :const:`DEFAULT_ENTROPY` instead. +the ``token_*`` functions use :const:`DEFAULT_ENTROPY` instead. .. data:: DEFAULT_ENTROPY diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 9effd9752c68a7..f6d8ce3c30ff1d 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -174,7 +174,7 @@ The module defines the following: The minimum number of bytes which can be written without blocking to a pipe when the pipe has been reported as ready for writing by :func:`~select.select`, :func:`!poll` or another interface in this module. This doesn't apply - to other kind of file-like objects such as sockets. + to other kinds of file-like objects such as sockets. This value is guaranteed by POSIX to be at least 512. @@ -226,7 +226,7 @@ object. implement :meth:`!fileno`, so they can also be used as the argument. *eventmask* is an optional bitmask describing the type of events you want to - check for. The constants are the same that with :c:func:`!poll` + check for. The constants are the same as with :c:func:`!poll` object. The default value is a combination of the constants :const:`POLLIN`, :const:`POLLPRI`, and :const:`POLLOUT`. @@ -241,7 +241,7 @@ object. .. method:: devpoll.modify(fd[, eventmask]) This method does an :meth:`unregister` followed by a - :meth:`register`. It is (a bit) more efficient that doing the same + :meth:`register`. It is (a bit) more efficient than doing the same explicitly. @@ -580,9 +580,9 @@ https://man.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 +---------------------------+---------------------------------------------+ | :const:`KQ_EV_DELETE` | Removes an event from the queue | +---------------------------+---------------------------------------------+ - | :const:`KQ_EV_ENABLE` | Permitscontrol() to returns the event | + | :const:`KQ_EV_ENABLE` | Permits control() to return the event | +---------------------------+---------------------------------------------+ - | :const:`KQ_EV_DISABLE` | Disablesevent | + | :const:`KQ_EV_DISABLE` | Disables event | +---------------------------+---------------------------------------------+ | :const:`KQ_EV_ONESHOT` | Removes event after first occurrence | +---------------------------+---------------------------------------------+ diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index ee556f1f3cecae..2d523a9d2ea440 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -54,7 +54,7 @@ Classes hierarchy:: In the following, *events* is a bitwise mask indicating which I/O events should -be waited for on a given file object. It can be a combination of the modules +be waited for on a given file object. It can be a combination of the module's constants below: +-----------------------+-----------------------------------------------+ diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index a8d22f3b8a033d..bd3d56f6af595a 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -51,7 +51,7 @@ lots of shared sub-objects. The keys are ordinary strings. :term:`bytes-like object`; the *protocol* value may be ignored by the serializer. - The *deserializer* argument must be callable which takes a serialized object + The *deserializer* argument must be a callable which takes a serialized object given as a :class:`bytes` object and returns the corresponding object. A :exc:`ShelveError` is raised if *serializer* is given but *deserializer* @@ -85,7 +85,7 @@ lots of shared sub-objects. The keys are ordinary strings. to load a shelf from an untrusted source. Like with pickle, loading a shelf can execute arbitrary code. -Shelf objects support most of methods and operations supported by dictionaries +Shelf objects support most of the methods and operations supported by dictionaries (except copying, constructors and operators ``|`` and ``|=``). This eases the transition from dictionary based scripts to those requiring persistent storage. diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index 00f4920a3268a8..0653bf2f4189c2 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -343,7 +343,7 @@ variables which either control lexical analysis or can be used for debugging: Parsing Rules ------------- -When operating in non-POSIX mode, :class:`~shlex.shlex` will try to obey to the +When operating in non-POSIX mode, :class:`~shlex.shlex` will try to obey the following rules. * Quote characters are not recognized within words (``Do"Not"Separate`` is @@ -366,7 +366,7 @@ following rules. * It's not possible to parse empty strings, even if quoted. -When operating in POSIX mode, :class:`~shlex.shlex` will try to obey to the +When operating in POSIX mode, :class:`~shlex.shlex` will try to obey the following parsing rules. * Quotes are stripped out, and do not separate words (``"Do"Not"Separate"`` is @@ -382,7 +382,7 @@ following parsing rules. * Enclosing characters in quotes which are part of :attr:`~shlex.escapedquotes` (e.g. ``'"'``) preserves the literal value of all characters within the quotes, with the exception of the characters - mentioned in :attr:`~shlex.escape`. The escape characters retain its + mentioned in :attr:`~shlex.escape`. The escape characters retain their special meaning only when followed by the quote in use, or the escape character itself. Otherwise the escape character will be considered a normal character. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 647e9bbd1d46a5..33f56121e84514 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -540,12 +540,12 @@ On Solaris :func:`os.sendfile` is used. On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB instead of 64 KiB) and a :func:`memoryview`-based variant of -:func:`shutil.copyfileobj` is used, which is still reads and writes in a loop. +:func:`shutil.copyfileobj` is used, which still reads and writes in a loop. :func:`shutil.copy2` uses the native ``CopyFile2`` call on Windows, which is the most efficient method, supports copy-on-write, and preserves metadata. If the fast-copy operation fails and no data was written in the destination -file then shutil will silently fallback on using less efficient +file then shutil will silently fall back to less efficient :func:`copyfileobj` function internally. .. versionchanged:: 3.8 diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 485eb6058c7e20..d85d7138911016 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -36,7 +36,7 @@ Execution of Python signal handlers A Python signal handler does not get executed inside the low-level (C) signal handler. Instead, the low-level signal handler sets a flag which tells the :term:`virtual machine` to execute the corresponding Python signal handler -at a later point(for example at the next :term:`bytecode` instruction). +at a later point (for example, at the next :term:`bytecode` instruction). This has consequences: * It makes little sense to catch synchronous errors like :const:`SIGFPE` or @@ -92,13 +92,13 @@ The signal module defines three enums: .. class:: Handlers - :class:`enum.IntEnum` collection the constants :const:`SIG_DFL` and :const:`SIG_IGN`. + :class:`enum.IntEnum` collection of the constants :const:`SIG_DFL` and :const:`SIG_IGN`. .. versionadded:: 3.5 .. class:: Sigmasks - :class:`enum.IntEnum` collection the constants :const:`SIG_BLOCK`, :const:`SIG_UNBLOCK` and :const:`SIG_SETMASK`. + :class:`enum.IntEnum` collection of the constants :const:`SIG_BLOCK`, :const:`SIG_UNBLOCK` and :const:`SIG_SETMASK`. .. availability:: Unix. diff --git a/Doc/library/site.rst b/Doc/library/site.rst index 70774020c00f50..4686c9fc92ced2 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -140,7 +140,7 @@ After these path manipulations, an attempt is made to import a module named It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` or its subclass exception, and the exception's :attr:`~ImportError.name` -attribute equals to ``'sitecustomize'``, +attribute equals ``'sitecustomize'``, it is silently ignored. If Python is started without output streams available, as with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), attempted output from :mod:`!sitecustomize` is ignored. Any other exception @@ -157,7 +157,7 @@ which can perform arbitrary user-specific customizations, if user site-packages directory (see below), which is part of ``sys.path`` unless disabled by :option:`-s`. If this import fails with an :exc:`ImportError` or its subclass exception, and the exception's :attr:`~ImportError.name` -attribute equals to ``'usercustomize'``, it is silently ignored. +attribute equals ``'usercustomize'``, it is silently ignored. Note that for some non-Unix systems, ``sys.prefix`` and ``sys.exec_prefix`` are empty, and the path manipulations are skipped; however the import of @@ -173,7 +173,7 @@ Readline configuration On systems that support :mod:`readline`, this module will also import and configure the :mod:`rlcompleter` module, if Python is started in :ref:`interactive mode ` and without the :option:`-S` option. -The default behavior is enable tab-completion and to use +The default behavior is to enable tab completion and to use :file:`~/.python_history` as the history save file. To disable it, delete (or override) the :data:`sys.__interactivehook__` attribute in your :mod:`sitecustomize` or :mod:`usercustomize` module or your diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index ac962f5beeb149..24ce0ee56d92a6 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -118,10 +118,10 @@ created. Socket addresses are represented as follows: ``'can0'``. The network interface name ``''`` can be used to receive packets from all network interfaces of this family. - - :const:`CAN_ISOTP` protocol require a tuple ``(interface, rx_addr, tx_addr)`` + - :const:`CAN_ISOTP` protocol requires a tuple ``(interface, rx_addr, tx_addr)`` where both additional parameters are unsigned long integer that represent a CAN identifier (standard or extended). - - :const:`CAN_J1939` protocol require a tuple ``(interface, name, pgn, addr)`` + - :const:`CAN_J1939` protocol requires a tuple ``(interface, name, pgn, addr)`` where additional parameters are 64-bit unsigned integer representing the ECU name, a 32-bit unsigned integer representing the Parameter Group Number (PGN), and an 8-bit integer representing the address. @@ -1037,7 +1037,7 @@ The :mod:`!socket` module also offers various network-related services: .. function:: close(fd) Close a socket file descriptor. This is like :func:`os.close`, but for - sockets. On some platforms (most noticeable Windows) :func:`os.close` + sockets. On some platforms (most notably Windows) :func:`os.close` does not work for socket file descriptors. .. versionadded:: 3.7 @@ -1602,7 +1602,7 @@ to sockets. address family --- see above.) If the connection is interrupted by a signal, the method waits until the - connection completes, or raise a :exc:`TimeoutError` on timeout, if the + connection completes, or raises a :exc:`TimeoutError` on timeout, if the signal handler doesn't raise an exception and the socket is blocking or has a timeout. For non-blocking sockets, the method raises an :exc:`InterruptedError` exception if the connection is interrupted by a @@ -2109,11 +2109,11 @@ to sockets. Set the value of the given socket option (see the Unix manual page :manpage:`setsockopt(2)`). The needed symbolic constants are defined in this module (:ref:`!SO_\* etc. `). The value can be an integer, - ``None`` or a :term:`bytes-like object` representing a buffer. In the later + ``None`` or a :term:`bytes-like object` representing a buffer. In the latter case it is up to the caller to ensure that the bytestring contains the proper bits (see the optional built-in module :mod:`struct` for a way to encode C structures as bytestrings). When *value* is set to ``None``, - *optlen* argument is required. It's equivalent to call :c:func:`setsockopt` C + *optlen* argument is required. It's equivalent to calling :c:func:`setsockopt` C function with ``optval=NULL`` and ``optlen=optlen``. .. versionchanged:: 3.5 diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3b1a9c2f6eefe9..02663e2054d5f1 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -291,7 +291,7 @@ Module functions Set it to any combination (using ``|``, bitwise or) of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to enable this. - Column names takes precedence over declared types if both flags are set. + Column names take precedence over declared types if both flags are set. By default (``0``), type detection is disabled. :param isolation_level: diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 5ddf88692ece35..76b205691bfeb4 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -560,7 +560,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only in the range 0--127, and produce undefined results otherwise. Some systems have a convention for assigning specific meanings to specific exit codes, but these are generally underdeveloped; Unix programs generally use 2 for command - line syntax errors and 1 for all other kind of errors. If another type of + line syntax errors and 1 for all other kinds of errors. If another type of object is passed, ``None`` is equivalent to passing zero, and any other object is printed to :data:`stderr` and results in an exit code of 1. In particular, ``sys.exit("some error message")`` is a quick way to exit a diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index e0ae55ecc45acc..57b8fa29eb3600 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -43,7 +43,7 @@ all Python modules imported during the execution into the current directory. Display the version of the module and exit. .. versionadded:: 3.8 - Added ``--module`` option that allows to run an executable module. + Added ``--module`` option that allows running an executable module. Main options ^^^^^^^^^^^^ diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index d11ad11bbb008b..0fa70389f1f577 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -589,7 +589,7 @@ Snapshot If *cumulative* is ``True``, cumulate size and count of memory blocks of all frames of the traceback of a trace, not only the most recent frame. - The cumulative mode can only be used with *key_type* equals to + The cumulative mode can only be used with *key_type* equal to ``'filename'`` and ``'lineno'``. The result is sorted from the biggest to the smallest by: @@ -720,11 +720,10 @@ Traceback When a snapshot is taken, tracebacks of traces are limited to :func:`get_traceback_limit` frames. See the :func:`take_snapshot` function. The original number of frames of the traceback is stored in the - :attr:`Traceback.total_nframe` attribute. That allows to know if a traceback + :attr:`Traceback.total_nframe` attribute. That allows one to know if a traceback has been truncated by the traceback limit. - The :attr:`Trace.traceback` attribute is an instance of :class:`Traceback` - instance. + The :attr:`Trace.traceback` attribute is a :class:`Traceback` instance. .. versionchanged:: 3.7 Frames are now sorted from the oldest to the most recent, instead of most recent to oldest. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 7b62b9208412e9..a0e396983885d2 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -813,7 +813,7 @@ For example, this conforms to :pep:`484`:: def __len__(self) -> int: ... def __iter__(self) -> Iterator[int]: ... -:pep:`544` allows to solve this problem by allowing users to write +:pep:`544` solves this problem by allowing users to write the above code without explicit base classes in the class definition, allowing ``Bucket`` to be implicitly considered a subtype of both ``Sized`` and ``Iterable[int]`` by static type checkers. This is known as diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index f68a78e47f6aa5..321d93079bc6fa 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -62,7 +62,7 @@ document. What the :func:`parse` and :func:`parseString` functions do is connect an XML parser with a "DOM builder" that can accept parse events from any SAX parser and -convert them into a DOM tree. The name of the functions are perhaps misleading, +convert them into a DOM tree. The names of the functions are perhaps misleading, but are easy to grasp when learning the interfaces. The parsing of the document will be completed before these functions return; it's simply that these functions do not provide a parser implementation themselves. diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 8da8208331b8c2..9f16c470567406 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -230,7 +230,7 @@ a server allowing dotted names and registering a multicall function. Enabling the *allow_dotted_names* option allows intruders to access your module's global variables and may allow intruders to execute arbitrary code on - your machine. Only use this example only within a secure, closed network. + your machine. Only use this example within a secure, closed network. :: diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 7ab0b427a6cb52..4f7da5253f78bc 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -420,7 +420,7 @@ of the class:: 'Buddy' As discussed in :ref:`tut-object`, shared data can have possibly surprising -effects with involving :term:`mutable` objects such as lists and dictionaries. +effects involving :term:`mutable` objects such as lists and dictionaries. For example, the *tricks* list in the following code should not be used as a class variable because just a single list would be shared by all *Dog* instances:: diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index f3e69756401b8b..bee6cc39fafcdb 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -155,8 +155,8 @@ that takes an iterable is :func:`sum`:: 6 Later we will see more functions that return iterables and take iterables as -arguments. In chapter :ref:`tut-structures`, we will discuss in more detail about -:func:`list`. +arguments. In chapter :ref:`tut-structures`, we will discuss :func:`list` in more +detail. .. _tut-break: @@ -441,7 +441,7 @@ Several other key features of this statement: ``False`` and ``None`` are compared by identity. - Patterns may use named constants. These must be dotted names - to prevent them from being interpreted as capture variable:: + to prevent them from being interpreted as capture variables:: from enum import Enum class Color(Enum): @@ -1107,7 +1107,7 @@ Intermezzo: Coding Style Now that you are about to write longer, more complex pieces of Python, it is a good time to talk about *coding style*. Most languages can be written (or more -concise, *formatted*) in different styles; some are more readable than others. +concisely, *formatted*) in different styles; some are more readable than others. Making it easy for others to read your code is always a good idea, and adopting a nice coding style helps tremendously for that. diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index ccad53a5b2d33b..fe62ee153fe034 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -337,7 +337,7 @@ Unpacking in Lists and List Comprehensions ------------------------------------------ The section on :ref:`tut-unpacking-arguments` describes the use of ``*`` to -"unpack" the elements of an iterable object, providing each one seperately as +"unpack" the elements of an iterable object, providing each one separately as an argument to a function. Unpacking can also be used in other contexts, for example, when creating lists. When specifying elements of a list, prefixing an expression by a ``*`` will unpack the result of that expression, adding each of diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 359cf80a7b2ecf..aae8f29b007762 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -68,6 +68,6 @@ already contain the solution for your problem. .. rubric:: Footnotes -.. [#] "Cheese Shop" is a Monty Python's sketch: a customer enters a cheese shop, +.. [#] "Cheese Shop" is a Monty Python sketch: a customer enters a cheese shop, but whatever cheese he asks for, the clerk says it's missing. From c6e418d1744aed95a6f25d22565204649dde29c7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 11 Feb 2026 18:38:23 +0100 Subject: [PATCH 080/498] gh-141563: Enable test_cppext internal C API tests on macOS (#144711) Build the C API in C++11 mode on macOS. --- Lib/test/test_cppext/__init__.py | 14 +++++++++++--- Lib/test/test_cppext/extension.cpp | 5 ++--- Lib/test/test_cppext/setup.py | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py index 9013503995bdce..1fd01702f64029 100644 --- a/Lib/test/test_cppext/__init__.py +++ b/Lib/test/test_cppext/__init__.py @@ -4,6 +4,7 @@ import shlex import shutil import subprocess +import sys import unittest from test import support @@ -27,9 +28,6 @@ class BaseTests: TEST_INTERNAL_C_API = False - def test_build(self): - self.check_build('_testcppext') - def check_build(self, extension_name, std=None, limited=False): venv_dir = 'env' with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: @@ -91,6 +89,9 @@ def run_cmd(operation, cmd): class TestPublicCAPI(BaseTests, unittest.TestCase): + def test_build(self): + self.check_build('_testcppext') + @support.requires_gil_enabled('incompatible with Free Threading') def test_build_limited_cpp03(self): self.check_build('_test_limited_cpp03ext', std='c++03', limited=True) @@ -119,6 +120,13 @@ def test_build_cpp14(self): class TestInteralCAPI(BaseTests, unittest.TestCase): TEST_INTERNAL_C_API = True + def test_build(self): + kwargs = {} + if sys.platform == 'darwin': + # Old Apple clang++ default C++ std is gnu++98 + kwargs['std'] = 'c++11' + self.check_build('_testcppext_internal', **kwargs) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index 06ef997d57af46..92c4645039a03b 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -16,9 +16,8 @@ #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API # include "internal/pycore_frame.h" - // mimalloc emits compiler warnings when Python is built on Windows - // and macOS. -# if !defined(MS_WINDOWS) && !defined(__APPLE__) + // mimalloc emits compiler warnings on Windows. +# if !defined(MS_WINDOWS) # include "internal/pycore_backoff.h" # include "internal/pycore_cell.h" # endif diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py index a3eec1c67e1556..2d9052a6b879da 100644 --- a/Lib/test/test_cppext/setup.py +++ b/Lib/test/test_cppext/setup.py @@ -59,7 +59,7 @@ def main(): else: cppflags.append(f'-std={std}') - if limited or (std != 'c++03'): + if limited or (std != 'c++03') and not internal: # See CPPFLAGS_PEDANTIC docstring cppflags.extend(CPPFLAGS_PEDANTIC) From 3e0322ff16f47caa3e273d453f007d3918b8ac80 Mon Sep 17 00:00:00 2001 From: William Meehan Date: Wed, 11 Feb 2026 15:58:24 -0500 Subject: [PATCH 081/498] gh-84424: Use numeric_changed for UCD.numeric (GH-19457) This was causing ucd_3_2_0.numeric() to pick up only decimal changes between Unicode 3.2.0 and the current version. --- Lib/test/test_unicodedata.py | 8 ++++++-- .../next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst | 1 + Modules/unicodedata.c | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index a46ca034f3bfc9..83b94f97c22c9d 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -182,10 +182,14 @@ def test_numeric(self): # New in 4.1.0 self.assertEqual(self.db.numeric('\U0001012A', None), None if self.old else 9000) + # Changed in 4.1.0 + self.assertEqual(self.db.numeric('\u5793', None), 1e20 if self.old else None) # New in 5.0.0 self.assertEqual(self.db.numeric('\u07c0', None), None if self.old else 0.0) # New in 5.1.0 self.assertEqual(self.db.numeric('\ua627', None), None if self.old else 7.0) + # Changed in 5.2.0 + self.assertEqual(self.db.numeric('\u09f6'), 3.0 if self.old else 3/16) # New in 6.0.0 self.assertEqual(self.db.numeric('\u0b72', None), None if self.old else 0.25) # New in 12.0.0 @@ -857,9 +861,9 @@ def graphemes(*args): class Unicode_3_2_0_FunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): db = unicodedata.ucd_3_2_0 old = True - expectedchecksum = ('f4526159891a4b766dd48045646547178737ba09' + expectedchecksum = ('4154d8d1232837e255edf3cdcbb5ab184d71f4a4' if quicktest else - 'f217b8688d7bdff31db4207e078a96702f091597') + '3aabaf66823b21b3d305dad804a62f6f6387c93e') class UnicodeMiscTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst b/Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst new file mode 100644 index 00000000000000..1f48525cdbecd0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst @@ -0,0 +1 @@ +Fix :meth:`!unicodedata.ucd_3_2_0.numeric` for non-decimal values. diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 586ce8d36dd46f..091e6bcb9f3f49 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -270,9 +270,9 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, have_old = 1; rc = -1.0; } - else if (old->decimal_changed != 0xFF) { + else if (old->numeric_changed != 0.0) { have_old = 1; - rc = old->decimal_changed; + rc = old->numeric_changed; } } From cac0c98450c27dbb6e185ab1c05e1d51d34135d9 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Thu, 12 Feb 2026 01:12:08 +0100 Subject: [PATCH 082/498] gh-144675: update to WASI SDK 30 (#144676) Signed-off-by: Roman Volosatovs Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- .github/workflows/reusable-wasi.yml | 2 +- .../next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst | 1 + Platforms/WASI/config.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst diff --git a/.github/workflows/reusable-wasi.yml b/.github/workflows/reusable-wasi.yml index 3c81f6ef82dc8c..68c5ef14cfe212 100644 --- a/.github/workflows/reusable-wasi.yml +++ b/.github/workflows/reusable-wasi.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 60 env: WASMTIME_VERSION: 38.0.3 - WASI_SDK_VERSION: 29 + WASI_SDK_VERSION: 30 WASI_SDK_PATH: /opt/wasi-sdk CROSS_BUILD_PYTHON: cross-build/build CROSS_BUILD_WASI: cross-build/wasm32-wasip1 diff --git a/Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst b/Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst new file mode 100644 index 00000000000000..1018ed95a2af77 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst @@ -0,0 +1 @@ +Update to WASI SDK 30. diff --git a/Platforms/WASI/config.toml b/Platforms/WASI/config.toml index 7ca2f76f56dc7a..2f7a87decd6212 100644 --- a/Platforms/WASI/config.toml +++ b/Platforms/WASI/config.toml @@ -2,5 +2,5 @@ # This allows for blanket copying of the WASI build code between supported # Python versions. [targets] -wasi-sdk = 29 +wasi-sdk = 30 host-triple = "wasm32-wasip1" From 46d5106cfa903329821c097c3bf309e3efcd718f Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 12 Feb 2026 00:15:33 +0000 Subject: [PATCH 083/498] gh-142349: Implement PEP 810 - Explicit lazy imports (#142351) Co-authored-by: T. Wouters Co-authored-by: Brittany Reynoso Co-authored-by: Dino Viehland --- Doc/c-api/exceptions.rst | 2 + Doc/c-api/import.rst | 52 + Doc/library/ast.rst | 9 +- Doc/library/exceptions.rst | 6 + Doc/library/sys.rst | 84 + Doc/library/types.rst | 12 + Doc/reference/lexical_analysis.rst | 4 + Doc/reference/simple_stmts.rst | 57 +- Doc/using/cmdline.rst | 19 + Doc/whatsnew/3.15.rst | 105 ++ Grammar/python.gram | 16 +- Include/cpython/initconfig.h | 1 + Include/import.h | 14 + Include/internal/pycore_ast.h | 11 +- Include/internal/pycore_ast_state.h | 1 + Include/internal/pycore_ceval.h | 14 +- Include/internal/pycore_compile.h | 1 + Include/internal/pycore_dict.h | 9 + .../pycore_global_objects_fini_generated.h | 2 + Include/internal/pycore_global_strings.h | 2 + Include/internal/pycore_import.h | 20 + Include/internal/pycore_interp_structs.h | 8 + Include/internal/pycore_lazyimportobject.h | 35 + Include/internal/pycore_magic_number.h | 5 +- Include/internal/pycore_moduleobject.h | 2 + .../internal/pycore_runtime_init_generated.h | 2 + Include/internal/pycore_symtable.h | 1 + .../internal/pycore_unicodeobject_generated.h | 8 + Include/pyerrors.h | 3 + Lib/_compat_pickle.py | 1 + Lib/_pyrepl/utils.py | 6 + Lib/dis.py | 11 +- Lib/idlelib/colorizer.py | 8 +- Lib/idlelib/idle_test/test_colorizer.py | 18 + Lib/importlib/_bootstrap.py | 6 + Lib/keyword.py | 1 + Lib/rlcompleter.py | 13 +- Lib/test/.ruff.toml | 3 + Lib/test/exception_hierarchy.txt | 1 + Lib/test/test_ast/data/ast_repr.txt | 12 +- Lib/test/test_ast/snippets.py | 18 +- Lib/test/test_ast/test_ast.py | 4 +- Lib/test/test_capi/test_config.py | 1 + Lib/test/test_dis.py | 2 +- Lib/test/test_embed.py | 1 + .../test_import/data/lazy_imports/basic2.py | 4 + .../lazy_imports/basic_compatibility_mode.py | 2 + .../basic_compatibility_mode_relative.py | 2 + .../basic_compatibility_mode_used.py | 3 + .../data/lazy_imports/basic_dir.py | 2 + .../data/lazy_imports/basic_from_unused.py | 1 + .../data/lazy_imports/basic_unused.py | 1 + .../data/lazy_imports/basic_used.py | 3 + .../data/lazy_imports/broken_attr_module.py | 3 + .../data/lazy_imports/broken_module.py | 2 + .../lazy_imports/compatibility_mode_func.py | 5 + .../compatibility_mode_try_except.py | 5 + .../data/lazy_imports/dunder_lazy_import.py | 1 + .../dunder_lazy_import_builtins.py | 14 + .../lazy_imports/dunder_lazy_import_used.py | 3 + .../data/lazy_imports/eager_import_func.py | 3 + .../data/lazy_imports/global_filter.py | 10 + .../data/lazy_imports/global_filter_from.py | 11 + .../lazy_imports/global_filter_from_true.py | 11 + .../data/lazy_imports/global_filter_true.py | 11 + .../data/lazy_imports/global_off.py | 5 + .../data/lazy_imports/global_on.py | 5 + .../data/lazy_imports/globals_access.py | 9 + .../data/lazy_imports/lazy_class_body.py | 3 + .../data/lazy_imports/lazy_compat_from.py | 6 + .../data/lazy_imports/lazy_future_import.py | 1 + .../data/lazy_imports/lazy_get_value.py | 7 + .../data/lazy_imports/lazy_import_func.py | 2 + .../data/lazy_imports/lazy_import_pkg.py | 2 + .../data/lazy_imports/lazy_try_except.py | 4 + .../data/lazy_imports/lazy_try_except_from.py | 4 + .../lazy_imports/lazy_try_except_from_star.py | 1 + .../data/lazy_imports/lazy_with.py | 3 + .../data/lazy_imports/lazy_with_from.py | 3 + .../data/lazy_imports/modules_dict.py | 5 + .../data/lazy_imports/modules_getattr.py | 5 + .../lazy_imports/modules_getattr_other.py | 5 + .../data/lazy_imports/multi_from_import.py | 5 + .../data/lazy_imports/pkg/__init__.py | 1 + .../test_import/data/lazy_imports/pkg/b.py | 2 + .../test_import/data/lazy_imports/pkg/bar.py | 2 + .../test_import/data/lazy_imports/pkg/c.py | 4 + .../data/lazy_imports/relative_lazy.py | 5 + .../data/lazy_imports/relative_lazy_from.py | 8 + .../data/lazy_imports/try_except_eager.py | 4 + .../lazy_imports/try_except_eager_from.py | 4 + Lib/test/test_import/test_lazy_imports.py | 1662 +++++++++++++++++ Lib/test/test_pyrepl/test_utils.py | 32 + Lib/test/test_syntax.py | 122 ++ Lib/test/test_sys.py | 3 +- Lib/test/test_traceback.py | 42 + Lib/test/test_types.py | 11 +- Lib/traceback.py | 26 + Lib/types.py | 3 + Makefile.pre.in | 4 + ...-12-06-15-46-32.gh-issue-142349.IdTuYL.rst | 1 + Modules/_testcapi/import.c | 67 +- Modules/_testinternalcapi/test_cases.c.h | 81 +- Modules/_typesmodule.c | 2 + Objects/dictobject.c | 12 +- Objects/exceptions.c | 8 +- Objects/lazyimportobject.c | 157 ++ Objects/moduleobject.c | 71 +- PCbuild/_freeze_module.vcxproj | 1 + PCbuild/_freeze_module.vcxproj.filters | 3 + PCbuild/pythoncore.vcxproj | 2 + PCbuild/pythoncore.vcxproj.filters | 6 + Parser/Python.asdl | 4 +- Parser/action_helpers.c | 15 +- Parser/parser.c | 118 +- Parser/pegen.h | 2 +- Programs/test_frozenmain.h | 2 +- Python/Python-ast.c | 113 +- Python/bltinmodule.c | 57 + Python/bytecodes.c | 64 +- Python/ceval.c | 208 ++- Python/ceval.h | 1 + Python/clinic/bltinmodule.c.h | 97 +- Python/clinic/import.c.h | 37 +- Python/clinic/sysmodule.c.h | 176 +- Python/codegen.c | 89 +- Python/compile.c | 20 + Python/executor_cases.c.h | 87 +- Python/generated_cases.c.h | 81 +- Python/import.c | 704 ++++++- Python/initconfig.c | 60 + Python/jit.c | 2 + Python/pylifecycle.c | 30 + Python/specialize.c | 15 +- Python/symtable.c | 68 + Python/sysmodule.c | 139 +- Tools/c-analyzer/cpython/globals-to-fix.tsv | 3 + Tools/jit/template.c | 2 + 138 files changed, 5126 insertions(+), 197 deletions(-) create mode 100644 Include/internal/pycore_lazyimportobject.h create mode 100644 Lib/test/test_import/data/lazy_imports/basic2.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_dir.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_from_unused.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_unused.py create mode 100644 Lib/test/test_import/data/lazy_imports/basic_used.py create mode 100644 Lib/test/test_import/data/lazy_imports/broken_attr_module.py create mode 100644 Lib/test/test_import/data/lazy_imports/broken_module.py create mode 100644 Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py create mode 100644 Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py create mode 100644 Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py create mode 100644 Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py create mode 100644 Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py create mode 100644 Lib/test/test_import/data/lazy_imports/eager_import_func.py create mode 100644 Lib/test/test_import/data/lazy_imports/global_filter.py create mode 100644 Lib/test/test_import/data/lazy_imports/global_filter_from.py create mode 100644 Lib/test/test_import/data/lazy_imports/global_filter_from_true.py create mode 100644 Lib/test/test_import/data/lazy_imports/global_filter_true.py create mode 100644 Lib/test/test_import/data/lazy_imports/global_off.py create mode 100644 Lib/test/test_import/data/lazy_imports/global_on.py create mode 100644 Lib/test/test_import/data/lazy_imports/globals_access.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_class_body.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_compat_from.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_future_import.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_get_value.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_import_func.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_try_except.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_try_except_from.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_try_except_from_star.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_with.py create mode 100644 Lib/test/test_import/data/lazy_imports/lazy_with_from.py create mode 100644 Lib/test/test_import/data/lazy_imports/modules_dict.py create mode 100644 Lib/test/test_import/data/lazy_imports/modules_getattr.py create mode 100644 Lib/test/test_import/data/lazy_imports/modules_getattr_other.py create mode 100644 Lib/test/test_import/data/lazy_imports/multi_from_import.py create mode 100644 Lib/test/test_import/data/lazy_imports/pkg/__init__.py create mode 100644 Lib/test/test_import/data/lazy_imports/pkg/b.py create mode 100644 Lib/test/test_import/data/lazy_imports/pkg/bar.py create mode 100644 Lib/test/test_import/data/lazy_imports/pkg/c.py create mode 100644 Lib/test/test_import/data/lazy_imports/relative_lazy.py create mode 100644 Lib/test/test_import/data/lazy_imports/relative_lazy_from.py create mode 100644 Lib/test/test_import/data/lazy_imports/try_except_eager.py create mode 100644 Lib/test/test_import/data/lazy_imports/try_except_eager_from.py create mode 100644 Lib/test/test_import/test_lazy_imports.py create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst create mode 100644 Objects/lazyimportobject.c diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 59af470f59ff34..a1cfb8872345cf 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -1119,6 +1119,8 @@ Exception types * :exc:`FloatingPointError` * * .. c:var:: PyObject *PyExc_GeneratorExit * :exc:`GeneratorExit` + * * .. c:var:: PyObject *PyExc_ImportCycleError + * :exc:`ImportCycleError` * * .. c:var:: PyObject *PyExc_ImportError * :exc:`ImportError` * * .. c:var:: PyObject *PyExc_IndentationError diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index a28c0713dd3b2f..04b5adb9a8f43d 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -346,6 +346,58 @@ Importing Modules .. versionadded:: 3.14 +.. c:function:: PyImport_LazyImportsMode PyImport_GetLazyImportsMode() + + Gets the current lazy imports mode. + + .. versionadded:: next + +.. c:function:: PyObject* PyImport_GetLazyImportsFilter() + + Return a :term:`strong reference` to the current lazy imports filter, + or ``NULL`` if none exists. This function always succeeds. + + .. versionadded:: next + +.. c:function:: int PyImport_SetLazyImportsMode(PyImport_LazyImportsMode mode) + + Similar to :c:func:`PyImport_ImportModuleAttr`, but names are UTF-8 encoded + strings instead of Python :class:`str` objects. + + This function always returns ``0``. + + .. versionadded:: next + +.. c:function:: int PyImport_SetLazyImportsFilter(PyObject *filter) + + Sets the current lazy imports filter. The *filter* should be a callable that + will receive ``(importing_module_name, imported_module_name, [fromlist])`` + when an import can potentially be lazy and that must return ``True`` if + the import should be lazy and ``False`` otherwise. + + Return ``0`` on success and ``-1`` with an exception set otherwise. + + .. versionadded:: next + +.. c:type:: PyImport_LazyImportsMode + + Enumeration of possible lazy import modes. + + .. c:enumerator:: PyImport_LAZY_NORMAL + + Respect the ``lazy`` keyword in source code. This is the default mode. + + .. c:enumerator:: PyImport_LAZY_ALL + + Make all imports lazy by default. + + .. c:enumerator:: PyImport_LAZY_NONE + + Disable lazy imports entirely. Even explicit ``lazy`` statements become + eager imports. + + .. versionadded:: next + .. c:function:: PyObject* PyImport_CreateModuleFromInitfunc(PyObject *spec, PyObject* (*initfunc)(void)) This function is a building block that enables embedders to implement diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index ee7ce15c48b589..8815187ea8c884 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1114,7 +1114,8 @@ Imports names=[ alias(name='x'), alias(name='y'), - alias(name='z')])]) + alias(name='z')], + is_lazy=0)]) .. class:: ImportFrom(module, names, level) @@ -1135,7 +1136,8 @@ Imports alias(name='x'), alias(name='y'), alias(name='z')], - level=0)]) + level=0, + is_lazy=0)]) .. class:: alias(name, asname) @@ -1153,7 +1155,8 @@ Imports names=[ alias(name='a', asname='b'), alias(name='c')], - level=2)]) + level=2, + is_lazy=0)]) Control flow ^^^^^^^^^^^^ diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index f3aca1ba49257b..33f37bdf1fc1cd 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -266,6 +266,12 @@ The following exceptions are the exceptions that are usually raised. .. versionadded:: 3.6 +.. exception:: ImportCycleError + + A subclass of :exc:`ImportError` which is raised when a lazy import fails + because it (directly or indirectly) tries to import itself. + + .. versionadded:: next .. exception:: IndexError diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 76b205691bfeb4..4c76feafc9b492 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -911,6 +911,35 @@ always available. Unless explicitly noted otherwise, all variables are read-only .. versionadded:: 3.11 + +.. function:: get_lazy_imports() + + Returns the current lazy imports mode as a string. + + * ``"normal"``: Only imports explicitly marked with the ``lazy`` keyword + are lazy + * ``"all"``: All top-level imports are potentially lazy + * ``"none"``: All lazy imports are suppressed (even explicitly marked + ones) + + See also :func:`set_lazy_imports` and :pep:`810`. + + .. versionadded:: next + + +.. function:: get_lazy_imports_filter() + + Returns the current lazy imports filter function, or ``None`` if no + filter is set. + + The filter function is called for every potentially lazy import to + determine whether it should actually be lazy. See + :func:`set_lazy_imports_filter` for details on the filter function + signature. + + .. versionadded:: next + + .. function:: getrefcount(object) Return the reference count of the *object*. The count returned is generally one @@ -1719,6 +1748,61 @@ always available. Unless explicitly noted otherwise, all variables are read-only .. versionadded:: 3.11 + +.. function:: set_lazy_imports(mode) + + Sets the global lazy imports mode. The *mode* parameter must be one of + the following strings: + + * ``"normal"``: Only imports explicitly marked with the ``lazy`` keyword + are lazy + * ``"all"``: All top-level imports become potentially lazy + * ``"none"``: All lazy imports are suppressed (even explicitly marked + ones) + + This function is intended for advanced users who need to control lazy + imports across their entire application. Library developers should + generally not use this function as it affects the runtime execution of + applications. + + In addition to the mode, lazy imports can be controlled via the filter + provided by :func:`set_lazy_imports_filter`. + + See also :func:`get_lazy_imports` and :pep:`810`. + + .. versionadded:: next + + +.. function:: set_lazy_imports_filter(filter) + + Sets the lazy imports filter callback. The *filter* parameter must be a + callable or ``None`` to clear the filter. + + The filter function is called for every potentially lazy import to + determine whether it should actually be lazy. It must have the following + signature:: + + def filter(importing_module: str, imported_module: str, + fromlist: tuple[str, ...] | None) -> bool + + Where: + + * *importing_module* is the name of the module doing the import + * *imported_module* is the name of the module being imported + * *fromlist* is the tuple of names being imported (for ``from ... import`` + statements), or ``None`` for regular imports + + The filter should return ``True`` to allow the import to be lazy, or + ``False`` to force an eager import. + + This is an advanced feature intended for specialized users who need + fine-grained control over lazy import behavior. + + See also :func:`get_lazy_imports_filter` and :pep:`810`. + + .. versionadded:: next + + .. function:: setprofile(profilefunc) .. index:: diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 40b5f3db13de5f..01f4df3c89091f 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -343,6 +343,18 @@ Standard names are defined for the following types: .. seealso:: :pep:`667` +.. data:: LazyImportType + + The type of lazy import proxy objects. These objects are created when a + module is lazily imported and serve as placeholders until the module is + actually accessed. This type can be used to detect lazy imports + programmatically. + + .. versionadded:: next + + .. seealso:: :pep:`810` + + .. data:: GetSetDescriptorType The type of objects defined in extension modules with ``PyGetSetDef``, such diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 046c759854c4df..5c931683db100a 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -457,6 +457,7 @@ Some names are only reserved under specific contexts. These are known as - ``match``, ``case``, and ``_``, when used in the :keyword:`match` statement. - ``type``, when used in the :keyword:`type` statement. +- ``lazy``, when used before an :keyword:`import` statement. These syntactically act as keywords in their specific contexts, but this distinction is done at the parser level, not when tokenizing. @@ -468,6 +469,9 @@ identifier names. .. versionchanged:: 3.12 ``type`` is now a soft keyword. +.. versionchanged:: next + ``lazy`` is now a soft keyword. + .. index:: single: _, identifiers single: __, identifiers diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 36b30c9b16b0db..9ada6f047843b4 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -743,14 +743,15 @@ The :keyword:`!import` statement pair: name; binding pair: keyword; from pair: keyword; as + pair: keyword; lazy pair: exception; ImportError single: , (comma); import statement .. productionlist:: python-grammar - import_stmt: "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])* - : | "from" `relative_module` "import" `identifier` ["as" `identifier`] + import_stmt: ["lazy"] "import" `module` ["as" `identifier`] ("," `module` ["as" `identifier`])* + : | ["lazy"] "from" `relative_module` "import" `identifier` ["as" `identifier`] : ("," `identifier` ["as" `identifier`])* - : | "from" `relative_module` "import" "(" `identifier` ["as" `identifier`] + : | ["lazy"] "from" `relative_module` "import" "(" `identifier` ["as" `identifier`] : ("," `identifier` ["as" `identifier`])* [","] ")" : | "from" `relative_module` "import" "*" module: (`identifier` ".")* `identifier` @@ -869,6 +870,56 @@ determine dynamically the modules to be loaded. .. _normalization form: https://www.unicode.org/reports/tr15/#Norm_Forms +.. _lazy-imports: +.. _lazy: + +Lazy imports +------------ + +.. index:: + pair: lazy; import + single: lazy import + +The :keyword:`lazy` keyword is a :ref:`soft keyword ` that +only has special meaning when it appears immediately before an +:keyword:`import` or :keyword:`from` statement. When an import statement is +preceded by the :keyword:`lazy` keyword, the import becomes *lazy*: the +module is not loaded immediately at the import statement. Instead, a lazy +proxy object is created and bound to the name. The actual module is loaded +on first use of that name. + +Lazy imports are only permitted at module scope. Using :keyword:`lazy` +inside a function, class body, or +:keyword:`try`/:keyword:`except`/:keyword:`finally` block raises a +:exc:`SyntaxError`. Star imports cannot be lazy (``lazy from module import +*`` is a syntax error), and :ref:`future statements ` cannot be +lazy. + +When using ``lazy from ... import``, each imported name is bound to a lazy +proxy object. The first access to any of these names triggers loading of the +entire module and resolves only that specific name to its actual value. +Other names remain as lazy proxies until they are accessed. + +Example:: + + lazy import json + import sys + + print('json' in sys.modules) # False - json module not yet loaded + + # First use triggers loading + result = json.dumps({"hello": "world"}) + + print('json' in sys.modules) # True - now loaded + +If an error occurs during module loading (such as :exc:`ImportError` or +:exc:`SyntaxError`), it is raised at the point where the lazy import is first +used, not at the import statement itself. + +See :pep:`810` for the full specification of lazy imports. + +.. versionadded:: next + .. _future: Future statements diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 515424424c1773..2e7ea7b4fc4cba 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -694,6 +694,14 @@ Miscellaneous options .. versionadded:: 3.14 + * :samp:`-X lazy_imports={all,none,normal}` controls lazy import behavior. + ``all`` makes all imports lazy by default, ``none`` disables lazy imports + entirely (even explicit ``lazy`` statements become eager), and ``normal`` + (the default) respects the ``lazy`` keyword in source code. + See also :envvar:`PYTHON_LAZY_IMPORTS`. + + .. versionadded:: next + It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -1360,6 +1368,17 @@ conflict. .. versionadded:: 3.14 +.. envvar:: PYTHON_LAZY_IMPORTS + + Controls lazy import behavior. Accepts three values: ``all`` makes all + imports lazy by default, ``none`` disables lazy imports entirely (even + explicit ``lazy`` statements become eager), and ``normal`` (the default) + respects the ``lazy`` keyword in source code. + + See also the :option:`-X lazy_imports <-X>` command-line option. + + .. versionadded:: next + Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 7ab549475152a9..0e440ccfd011f0 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -65,6 +65,8 @@ Summary -- Release highlights .. PEP-sized items next. +* :pep:`810`: :ref:`Explicit lazy imports for faster startup times + ` * :pep:`799`: :ref:`A dedicated profiling package for organizing Python profiling tools ` * :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler @@ -82,6 +84,102 @@ Summary -- Release highlights New features ============ +.. _whatsnew315-pep810: + +:pep:`810`: Explicit lazy imports +--------------------------------- + +Large Python applications often suffer from slow startup times. A +significant contributor to this problem is the import system: when a module +is imported, Python must locate the file, read it from disk, compile it to +bytecode, and execute all top-level code. For applications with deep +dependency trees, this process can take seconds, even when most of the +imported code is never actually used during a particular run. + +Developers have worked around this by moving imports inside functions, using +:mod:`importlib` to load modules on demand, or restructuring code to avoid +unnecessary dependencies. These approaches work but make code harder to read +and maintain, scatter import statements throughout the codebase, and require +discipline to apply consistently. + +Python now provides a cleaner solution through explicit :keyword:`lazy` +imports using the new ``lazy`` soft keyword. When you mark an import as +lazy, Python defers the actual module loading until the imported name is +first used. This gives you the organizational benefits of declaring all +imports at the top of the file while only paying the loading cost for +modules you actually use. + +The ``lazy`` keyword works with both ``import`` and ``from ... import`` +statements. When you write ``lazy import heavy_module``, Python does not +immediately load the module. Instead, it creates a lightweight proxy object. +The actual module loading happens transparently when you first access the +name: + +.. code-block:: python + + lazy import json + lazy from datetime import datetime + + print("Starting up...") # json and datetime not loaded yet + + data = json.loads('{"key": "value"}') # json gets loads here + now = datetime() # datetime loads here + +This mechanism is particularly useful for applications that import many +modules at the top level but may only use a subset of them in any given run. +The deferred loading reduces startup latency without requiring code +restructuring or conditional imports scattered throughout the codebase. + +In the case where loading a lazily imported module fails (for example, if +the module does not exist), Python raises the exception at the point of +first use rather than at import time. The associated traceback includes both +the location where the name was accessed and the original import statement, +making it straightforward to diagnose & debug the failure. + +For cases where you want to enable lazy loading globally without modifying +source code, Python provides the :option:`-X lazy_imports <-X>` command-line +option and the :envvar:`PYTHON_LAZY_IMPORTS` environment variable. Both +accept three values: ``all`` makes all imports lazy by default, ``none`` +disables lazy imports entirely (even explicit ``lazy`` statements become +eager), and ``normal`` (the default) respects the ``lazy`` keyword in source +code. The :func:`sys.set_lazy_imports` and :func:`sys.get_lazy_imports` +functions allow changing and querying this mode at runtime. + +For more selective control, :func:`sys.set_lazy_imports_filter` accepts a +callable that determines whether a specific module should be loaded lazily. +The filter receives three arguments: the importing module's name (or +``None``), the imported module's name, and the fromlist (or ``None`` for +regular imports). It should return ``True`` to allow the import to be lazy, +or ``False`` to force eager loading. This allows patterns like making only +your own application's modules lazy while keeping third-party dependencies +eager: + +.. code-block:: python + + import sys + + def myapp_filter(importing, imported, fromlist): + return imported.startswith("myapp.") + sys.set_lazy_imports_filter(myapp_filter) + sys.set_lazy_imports("all") + + import myapp.slow_module # lazy (matches filter) + import json # eager (does not match filter) + +The proxy type itself is available as :data:`types.LazyImportType` for code +that needs to detect lazy imports programmatically. + +There are some restrictions on where the ``lazy`` keyword can be used. Lazy +imports are only permitted at module scope; using ``lazy`` inside a +function, class body, or ``try``/``except``/``finally`` block raises a +:exc:`SyntaxError`. Neither star imports nor future imports can be lazy +(``lazy from module import *`` and ``lazy from __future__ import ...`` both +raise :exc:`SyntaxError`). + +.. seealso:: :pep:`810` for the full specification and rationale. + +(Contributed by Pablo Galindo Salgado and Dino Viehland in :gh:`142349`.) + .. _whatsnew315-profiling-package: :pep:`799`: A dedicated profiling package @@ -840,6 +938,13 @@ symtable (Contributed by Yashp002 in :gh:`143504`.) +symtable +-------- + +* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods. + (Contributed by Yashp002 in :gh:`143504`.) + + sys --- diff --git a/Grammar/python.gram b/Grammar/python.gram index 9698d6e20100c6..1212e8640a1a9c 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -121,9 +121,9 @@ simple_stmts[asdl_stmt_seq*]: simple_stmt[stmt_ty] (memo): | assignment | &"type" type_alias + | &('import' | 'from' | "lazy") import_stmt | e=star_expressions { _PyAST_Expr(e, EXTRA) } | &'return' return_stmt - | &('import' | 'from') import_stmt | &'raise' raise_stmt | &'pass' pass_stmt | &'del' del_stmt @@ -216,7 +216,7 @@ assert_stmt[stmt_ty]: | invalid_assert_stmt | 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) } -import_stmt[stmt_ty]: +import_stmt[stmt_ty](memo): | invalid_import | import_name | import_from @@ -224,13 +224,15 @@ import_stmt[stmt_ty]: # Import statements # ----------------- -import_name[stmt_ty]: 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) } +import_name[stmt_ty]: + | lazy="lazy"? 'import' a=dotted_as_names { _PyAST_Import(a, lazy ? 1 : 0, EXTRA) } + # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS import_from[stmt_ty]: - | 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets { - _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) } - | 'from' a=('.' | '...')+ 'import' b=import_from_targets { - _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) } + | lazy="lazy"? 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets { + _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), lazy, EXTRA) } + | lazy="lazy"? 'from' a=('.' | '...')+ 'import' b=import_from_targets { + _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), lazy ? 1 : 0, EXTRA) } import_from_targets[asdl_alias_seq*]: | '(' a=import_from_as_names [','] ')' { a } | import_from_as_names !',' diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 5606ebeb7c95e0..1ccc496c63ac78 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -191,6 +191,7 @@ typedef struct PyConfig { int enable_gil; int tlbc_enabled; #endif + int lazy_imports; /* --- Path configuration inputs ------------ */ int pathconfig_warnings; diff --git a/Include/import.h b/Include/import.h index d91ebe96ca868d..cc7ad71f2676a2 100644 --- a/Include/import.h +++ b/Include/import.h @@ -88,6 +88,20 @@ PyAPI_FUNC(int) PyImport_AppendInittab( PyObject* (*initfunc)(void) ); +typedef enum { + PyImport_LAZY_NORMAL, + PyImport_LAZY_ALL, + PyImport_LAZY_NONE, +} PyImport_LazyImportsMode; + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyImport_SetLazyImportsMode(PyImport_LazyImportsMode mode); +PyAPI_FUNC(int) PyImport_SetLazyImportsFilter(PyObject *filter); + +PyAPI_FUNC(PyImport_LazyImportsMode) PyImport_GetLazyImportsMode(void); +PyAPI_FUNC(PyObject *) PyImport_GetLazyImportsFilter(void); +#endif + #ifndef Py_LIMITED_API # define Py_CPYTHON_IMPORT_H # include "cpython/import.h" diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h index 60367202bab637..b47398669bbe51 100644 --- a/Include/internal/pycore_ast.h +++ b/Include/internal/pycore_ast.h @@ -329,12 +329,14 @@ struct _stmt { struct { asdl_alias_seq *names; + int is_lazy; } Import; struct { identifier module; asdl_alias_seq *names; int level; + int is_lazy; } ImportFrom; struct { @@ -764,11 +766,12 @@ stmt_ty _PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, end_col_offset, PyArena *arena); stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_Import(asdl_alias_seq * names, int is_lazy, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); stmt_ty _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); + int is_lazy, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int diff --git a/Include/internal/pycore_ast_state.h b/Include/internal/pycore_ast_state.h index d4ac419f51d6b2..1caf200ee34b2a 100644 --- a/Include/internal/pycore_ast_state.h +++ b/Include/internal/pycore_ast_state.h @@ -205,6 +205,7 @@ struct ast_state { PyObject *id; PyObject *ifs; PyObject *is_async; + PyObject *is_lazy; PyObject *items; PyObject *iter; PyObject *key; diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index e9f1f65e53cec1..1ee1f830827576 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -310,7 +310,19 @@ PyAPI_FUNC(void) _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, PyAPI_FUNC(void) _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg); PyAPI_FUNC(void) _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs); PyAPI_FUNC(PyObject *) _PyEval_ImportFrom(PyThreadState *, PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *, _PyInterpreterFrame *, PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) _PyEval_LazyImportName( + PyThreadState *tstate, PyObject *builtins, PyObject *globals, + PyObject *locals, PyObject *name, PyObject *fromlist, PyObject *level, + int lazy); +PyAPI_FUNC(PyObject *) _PyEval_LazyImportFrom( + PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *v, PyObject *name); +PyAPI_FUNC(PyObject *) _PyEval_ImportName( + PyThreadState *tstate, PyObject *builtins, PyObject *globals, + PyObject *locals, PyObject *name, PyObject *fromlist, PyObject *level); +PyObject * _PyEval_ImportNameWithImport( + PyThreadState *tstate, PyObject *import_func, PyObject *globals, + PyObject *locals, PyObject *name, PyObject *fromlist, PyObject *level); PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs); PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys); PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index 527141b54d0dca..911cc1f10f1513 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -131,6 +131,7 @@ int _PyCompile_PushFBlock(struct _PyCompiler *c, _Py_SourceLocation loc, void _PyCompile_PopFBlock(struct _PyCompiler *c, enum _PyCompile_FBlockType t, _PyJumpTargetLabel block_label); _PyCompile_FBlockInfo *_PyCompile_TopFBlock(struct _PyCompiler *c); +bool _PyCompile_InExceptionHandler(struct _PyCompiler *c); int _PyCompile_EnterScope(struct _PyCompiler *c, identifier name, int scope_type, void *key, int lineno, PyObject *private, diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 950547cb002f4c..379bf6a81784b0 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -36,6 +36,8 @@ extern int _PyDict_DelItem_KnownHash_LockHeld(PyObject *mp, PyObject *key, extern int _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); +extern void _PyDict_ClearKeysVersionLockHeld(PyObject *mp); + extern int _PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); @@ -264,6 +266,13 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { #define DICT_UNIQUE_ID_SHIFT (32) #define DICT_UNIQUE_ID_MAX ((UINT64_C(1) << (64 - DICT_UNIQUE_ID_SHIFT)) - 1) +/* The first three dict watcher IDs are reserved for CPython, + * so we don't need to check that they haven't been used */ +#define BUILTINS_WATCHER_ID 0 +#define GLOBALS_WATCHER_ID 1 +#define MODULE_WATCHER_ID 2 +#define FIRST_AVAILABLE_WATCHER 3 + PyAPI_FUNC(void) _PyDict_SendEvent(int watcher_bits, diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 09b8762ee2de35..64e3438f9157fe 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -1446,6 +1446,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iter__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__itruediv__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ixor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lazy_import__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lazy_modules__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__le__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__len__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__length_hint__)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 040f79afeebb11..78ed30dd7f62a2 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -169,6 +169,8 @@ struct _Py_global_strings { STRUCT_FOR_ID(__iter__) STRUCT_FOR_ID(__itruediv__) STRUCT_FOR_ID(__ixor__) + STRUCT_FOR_ID(__lazy_import__) + STRUCT_FOR_ID(__lazy_modules__) STRUCT_FOR_ID(__le__) STRUCT_FOR_ID(__len__) STRUCT_FOR_ID(__length_hint__) diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 4c8b8c0ed868d6..32ed3a62b2b4a7 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -32,6 +32,18 @@ extern int _PyImport_FixupBuiltin( PyObject *modules ); +extern PyObject * _PyImport_ResolveName( + PyThreadState *tstate, PyObject *name, PyObject *globals, int level); +extern PyObject * _PyImport_GetAbsName( + PyThreadState *tstate, PyObject *name, PyObject *globals, int level); +// Symbol is exported for the JIT on Windows builds. +PyAPI_FUNC(PyObject *) _PyImport_LoadLazyImportTstate( + PyThreadState *tstate, PyObject *lazy_import); +extern PyObject * _PyImport_LazyImportModuleLevelObject( + PyThreadState *tstate, PyObject *name, PyObject *builtins, + PyObject *globals, PyObject *locals, PyObject *fromlist, int level); + + #ifdef HAVE_DLOPEN # include // RTLD_NOW, RTLD_LAZY # if HAVE_DECL_RTLD_NOW @@ -69,11 +81,19 @@ extern void _PyImport_ClearModules(PyInterpreterState *interp); extern void _PyImport_ClearModulesByIndex(PyInterpreterState *interp); +extern PyObject * _PyImport_InitLazyModules( + PyInterpreterState *interp); +extern void _PyImport_ClearLazyModules(PyInterpreterState *interp); + extern int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp); extern int _PyImport_IsDefaultImportFunc( PyInterpreterState *interp, PyObject *func); +extern int _PyImport_IsDefaultLazyImportFunc( + PyInterpreterState *interp, + PyObject *func); + extern PyObject * _PyImport_GetImportlibLoader( PyInterpreterState *interp, const char *loader_name); diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 723657e4cef10d..3ebc8967c3dc7f 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -324,6 +324,14 @@ struct _import_state { int dlopenflags; #endif PyObject *import_func; + PyObject *lazy_import_func; + int lazy_imports_mode; + PyObject *lazy_imports_filter; + PyObject *lazy_importing_modules; + PyObject *lazy_modules; +#ifdef Py_GIL_DISABLED + PyMutex lazy_mutex; +#endif /* The global import lock. */ _PyRecursiveMutex lock; /* diagnostic info in PyImport_ImportModuleLevelObject() */ diff --git a/Include/internal/pycore_lazyimportobject.h b/Include/internal/pycore_lazyimportobject.h new file mode 100644 index 00000000000000..b81e4211b08ff3 --- /dev/null +++ b/Include/internal/pycore_lazyimportobject.h @@ -0,0 +1,35 @@ +// Lazy object interface. + +#ifndef Py_INTERNAL_LAZYIMPORTOBJECT_H +#define Py_INTERNAL_LAZYIMPORTOBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +PyAPI_DATA(PyTypeObject) PyLazyImport_Type; +#define PyLazyImport_CheckExact(op) Py_IS_TYPE((op), &PyLazyImport_Type) + +typedef struct { + PyObject_HEAD + PyObject *lz_builtins; + PyObject *lz_from; + PyObject *lz_attr; + // Frame information for the original import location. + PyCodeObject *lz_code; // Code object where the lazy import was created. + int lz_instr_offset; // Instruction offset where the lazy import was created. +} PyLazyImportObject; + + +PyAPI_FUNC(PyObject *) _PyLazyImport_GetName(PyObject *lazy_import); +PyAPI_FUNC(PyObject *) _PyLazyImport_New( + struct _PyInterpreterFrame *frame, PyObject *import_func, PyObject *from, PyObject *attr); + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_LAZYIMPORTOBJECT_H diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 919a2ec0d1aa9e..3fcf650426d36d 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -286,11 +286,12 @@ Known values: Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST) Python 3.15a1 3654 (Fix missing exception handlers in logical expression) Python 3.15a1 3655 (Fix miscompilation of some module-level annotations) - Python 3.15a2 3656 (Add TRACE_RECORD instruction, for platforms with switch based interpreter) + Python 3.15a1 3656 (Add TRACE_RECORD instruction, for platforms with switch based interpreter) Python 3.15a4 3657 (Add BINARY_OP_SUBSCR_USTR_INT) Python 3.15a4 3658 (Optimize bytecode for list/set called on genexp) Python 3.15a4 3659 (Add CALL_FUNCTION_EX specialization) Python 3.15a4 3660 (Change generator preamble code) + Python 3.15a4 3661 (Lazy imports IMPORT_NAME opcode changes) Python 3.16 will start with 3700 @@ -304,7 +305,7 @@ PC/launcher.c must also be updated. */ -#define PYC_MAGIC_NUMBER 3660 +#define PYC_MAGIC_NUMBER 3661 /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes (little-endian) and then appending b'\r\n'. */ #define PYC_MAGIC_NUMBER_TOKEN \ diff --git a/Include/internal/pycore_moduleobject.h b/Include/internal/pycore_moduleobject.h index 9a62daf6621ca2..7882ce03323561 100644 --- a/Include/internal/pycore_moduleobject.h +++ b/Include/internal/pycore_moduleobject.h @@ -19,6 +19,8 @@ extern int _PyModule_IsPossiblyShadowing(PyObject *); extern int _PyModule_IsExtension(PyObject *obj); +extern int _PyModule_InitModuleDictWatcher(PyInterpreterState *interp); + typedef int (*_Py_modexecfunc)(PyObject *); typedef struct { diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index f4ea7b7954bb84..d4b7b090f93f31 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -1444,6 +1444,8 @@ extern "C" { INIT_ID(__iter__), \ INIT_ID(__itruediv__), \ INIT_ID(__ixor__), \ + INIT_ID(__lazy_import__), \ + INIT_ID(__lazy_modules__), \ INIT_ID(__le__), \ INIT_ID(__len__), \ INIT_ID(__length_hint__), \ diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index c0164507ea033e..e1176c65c5ca9e 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -126,6 +126,7 @@ typedef struct _symtable_entry { unsigned ste_method : 1; /* true if block is a function block defined in class scope */ unsigned ste_has_conditional_annotations : 1; /* true if block has conditionally executed annotations */ unsigned ste_in_conditional_block : 1; /* set while we are inside a conditionally executed block */ + unsigned ste_in_try_block : 1; /* set while we are inside a try/except block */ unsigned ste_in_unevaluated_annotation : 1; /* set while we are processing an annotation that will not be evaluated */ int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */ _Py_SourceLocation ste_loc; /* source location of block */ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index f9677d01228dce..d843674f180902 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -456,6 +456,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(__lazy_import__); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(__lazy_modules__); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(__le__); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 5d0028c116e2d8..cfabbc5fe8d5da 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -91,6 +91,9 @@ PyAPI_DATA(PyObject *) PyExc_EOFError; PyAPI_DATA(PyObject *) PyExc_FloatingPointError; PyAPI_DATA(PyObject *) PyExc_OSError; PyAPI_DATA(PyObject *) PyExc_ImportError; +#if !defined(Py_LIMITED_API) +PyAPI_DATA(PyObject *) PyExc_ImportCycleError; +#endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError; #endif diff --git a/Lib/_compat_pickle.py b/Lib/_compat_pickle.py index a981326432429b..928db663b446ba 100644 --- a/Lib/_compat_pickle.py +++ b/Lib/_compat_pickle.py @@ -240,6 +240,7 @@ REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'OSError') PYTHON3_IMPORTERROR_EXCEPTIONS = ( + 'ImportCycleError', 'ModuleNotFoundError', ) diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py index 06cddef851bb40..25d7ac1bd0b14e 100644 --- a/Lib/_pyrepl/utils.py +++ b/Lib/_pyrepl/utils.py @@ -276,6 +276,12 @@ def is_soft_keyword_used(*tokens: TI | None) -> bool: TI(T.NAME, string=s) ): return not keyword.iskeyword(s) + case ( + None | TI(T.NEWLINE) | TI(T.INDENT) | TI(T.DEDENT) | TI(string=":" | ";"), + TI(string="lazy"), + TI(string="import") | TI(string="from") + ): + return True case _: return False diff --git a/Lib/dis.py b/Lib/dis.py index 8c257d118fb23b..58c7f6419032c6 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -35,6 +35,7 @@ FUNCTION_ATTR_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure', 'annotate') ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] +IMPORT_NAME = opmap['IMPORT_NAME'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] LOAD_SMALL_INT = opmap['LOAD_SMALL_INT'] BINARY_OP = opmap['BINARY_OP'] @@ -600,6 +601,12 @@ def get_argval_argrepr(self, op, arg, offset): argval, argrepr = _get_name_info(arg//4, get_name) if (arg & 1) and argrepr: argrepr = f"{argrepr} + NULL|self" + elif deop == IMPORT_NAME: + argval, argrepr = _get_name_info(arg//4, get_name) + if (arg & 1) and argrepr: + argrepr = f"{argrepr} + lazy" + elif (arg & 2) and argrepr: + argrepr = f"{argrepr} + eager" else: argval, argrepr = _get_name_info(arg, get_name) elif deop in hasjump or deop in hasexc: @@ -1012,7 +1019,9 @@ def _find_imports(co): (level_op[0] in hasconst or level_op[0] == LOAD_SMALL_INT)): level = _get_const_value(level_op[0], level_op[1], consts) fromlist = _get_const_value(from_op[0], from_op[1], consts) - yield (names[oparg], level, fromlist) + # IMPORT_NAME encodes lazy/eager flags in bits 0-1, + # name index in bits 2+. + yield (names[oparg >> 2], level, fromlist) def _find_store_names(co): """Find names of variables which are written in the code diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py index bffa2ddd3cd9cd..6db38de3aa6cb9 100644 --- a/Lib/idlelib/colorizer.py +++ b/Lib/idlelib/colorizer.py @@ -42,6 +42,11 @@ def make_pat(): ]) + r"))" ) + lazy_softkw = ( + r"^[ \t]*" + # at beginning of line + possible indentation + r"(?Plazy)" + + r"(?=[ \t]+(?:import|from)\b)" # followed by 'import' or 'from' + ) builtinlist = [str(name) for name in dir(builtins) if not name.startswith('_') and name not in keyword.kwlist] @@ -56,7 +61,7 @@ def make_pat(): prog = re.compile("|".join([ builtin, comment, string, kw, match_softkw, case_default, - case_softkw_and_pattern, + case_softkw_and_pattern, lazy_softkw, any("SYNC", [r"\n"]), ]), re.DOTALL | re.MULTILINE) @@ -70,6 +75,7 @@ def make_pat(): "CASE_SOFTKW": "KEYWORD", "CASE_DEFAULT_UNDERSCORE": "KEYWORD", "CASE_SOFTKW2": "KEYWORD", + "LAZY_SOFTKW": "KEYWORD", } diff --git a/Lib/idlelib/idle_test/test_colorizer.py b/Lib/idlelib/idle_test/test_colorizer.py index 40800df97b0bd3..fb6ee825086750 100644 --- a/Lib/idlelib/idle_test/test_colorizer.py +++ b/Lib/idlelib/idle_test/test_colorizer.py @@ -542,6 +542,24 @@ def test_case_soft_keyword(self): self._assert_highlighting('case _:', {'KEYWORD': [('1.0', '1.4'), ('1.5', '1.6')]}) + def test_lazy_soft_keyword(self): + # lazy followed by import + self._assert_highlighting('lazy import foo', + {'KEYWORD': [('1.0', '1.4'), + ('1.5', '1.11')]}) + self._assert_highlighting(' lazy import foo', + {'KEYWORD': [('1.4', '1.8'), + ('1.9', '1.15')]}) + + # lazy followed by from + self._assert_highlighting('lazy from foo import bar', + {'KEYWORD': [('1.0', '1.4'), ('1.5', '1.9'), + ('1.14', '1.20')]}) + + # lazy not followed by import/from (not highlighted) + self._assert_highlighting('lazy = 1', {}) + self._assert_highlighting('lazy foo', {}) + def test_long_multiline_string(self): source = textwrap.dedent('''\ """a diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index cfcebb7309803c..45beb51659f5b7 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -1256,6 +1256,12 @@ def _find_and_load_unlocked(name, import_): except AttributeError: msg = f"Cannot set an attribute on {parent!r} for child module {child!r}" _warnings.warn(msg, ImportWarning) + # Set attributes to lazy submodules on the module. + try: + _imp._set_lazy_attributes(module, name) + except Exception as e: + msg = f"Cannot set lazy attributes on {name!r}: {e!r}" + _warnings.warn(msg, ImportWarning) return module diff --git a/Lib/keyword.py b/Lib/keyword.py index e22c837835e740..98ffe2de28b1a1 100644 --- a/Lib/keyword.py +++ b/Lib/keyword.py @@ -56,6 +56,7 @@ softkwlist = [ '_', 'case', + 'lazy', 'match', 'type' ] diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py index 23eb0020f42e8a..e8cef29d00467f 100644 --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -36,6 +36,7 @@ import re import __main__ import warnings +import types __all__ = ["Completer"] @@ -188,7 +189,17 @@ def attr_matches(self, text): # property method, which is not desirable. matches.append(match) continue - if (value := getattr(thisobject, word, None)) is not None: + + if (isinstance(thisobject, types.ModuleType) + and + isinstance(thisobject.__dict__.get(word), + types.LazyImportType) + ): + value = thisobject.__dict__.get(word) + else: + value = getattr(thisobject, word, None) + + if value is not None: matches.append(self._callable_postfix(value, match)) else: matches.append(match) diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml index 7b46139f786cf7..b5be4c3afaf958 100644 --- a/Lib/test/.ruff.toml +++ b/Lib/test/.ruff.toml @@ -14,6 +14,9 @@ extend-exclude = [ # New grammar constructions may not yet be recognized by Ruff, # and tests re-use the same names as only the grammar is being checked. "test_grammar.py", + # Lazy import syntax (PEP 810) is not yet supported by Ruff + "test_import/data/lazy_imports/*.py", + "test_import/data/lazy_imports/**/*.py", ] [lint] diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt index f2649aa2d41fef..98a5e950602eaf 100644 --- a/Lib/test/exception_hierarchy.txt +++ b/Lib/test/exception_hierarchy.txt @@ -14,6 +14,7 @@ BaseException ├── EOFError ├── ExceptionGroup [BaseExceptionGroup] ├── ImportError + │ └── ImportCycleError │ └── ModuleNotFoundError ├── LookupError │ ├── IndexError diff --git a/Lib/test/test_ast/data/ast_repr.txt b/Lib/test/test_ast/data/ast_repr.txt index 1c1985519cd8b4..cc6accd766b78a 100644 --- a/Lib/test/test_ast/data/ast_repr.txt +++ b/Lib/test/test_ast/data/ast_repr.txt @@ -69,10 +69,14 @@ Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=Name(...), name='ex Module(body=[TryStar(body=[Pass()], handlers=[ExceptHandler(type=Name(...), name='exc', body=[Pass(...)])], orelse=[Pass()], finalbody=[Pass()])], type_ignores=[]) Module(body=[Assert(test=Name(id='v', ctx=Load(...)), msg=None)], type_ignores=[]) Module(body=[Assert(test=Name(id='v', ctx=Load(...)), msg=Constant(value='message', kind=None))], type_ignores=[]) -Module(body=[Import(names=[alias(name='sys', asname=None)])], type_ignores=[]) -Module(body=[Import(names=[alias(name='foo', asname='bar')])], type_ignores=[]) -Module(body=[ImportFrom(module='sys', names=[alias(name='x', asname='y')], level=0)], type_ignores=[]) -Module(body=[ImportFrom(module='sys', names=[alias(name='v', asname=None)], level=0)], type_ignores=[]) +Module(body=[Import(names=[alias(name='sys', asname=None)], is_lazy=0)], type_ignores=[]) +Module(body=[Import(names=[alias(name='foo', asname='bar')], is_lazy=0)], type_ignores=[]) +Module(body=[ImportFrom(module='sys', names=[alias(name='x', asname='y')], level=0, is_lazy=0)], type_ignores=[]) +Module(body=[ImportFrom(module='sys', names=[alias(name='v', asname=None)], level=0, is_lazy=0)], type_ignores=[]) +Module(body=[Import(names=[alias(name='sys', asname=None)], is_lazy=1)], type_ignores=[]) +Module(body=[Import(names=[alias(name='foo', asname='bar')], is_lazy=1)], type_ignores=[]) +Module(body=[ImportFrom(module='sys', names=[alias(name='x', asname='y')], level=0, is_lazy=1)], type_ignores=[]) +Module(body=[ImportFrom(module='sys', names=[alias(name='v', asname=None)], level=0, is_lazy=1)], type_ignores=[]) Module(body=[Global(names=['v'])], type_ignores=[]) Module(body=[Expr(value=Constant(value=1, kind=None))], type_ignores=[]) Module(body=[Pass()], type_ignores=[]) diff --git a/Lib/test/test_ast/snippets.py b/Lib/test/test_ast/snippets.py index b76f98901d2ad8..a565ed10f8b434 100644 --- a/Lib/test/test_ast/snippets.py +++ b/Lib/test/test_ast/snippets.py @@ -118,6 +118,12 @@ # ImportFrom "from sys import x as y", "from sys import v", + # Lazy Import + "lazy import sys", + "lazy import foo as bar", + # Lazy ImportFrom + "lazy from sys import x as y", + "lazy from sys import v", # Global "global v", # Expr @@ -460,10 +466,14 @@ def main(): ('Module', [('TryStar', (1, 0, 7, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 8, 3, 17), 'Exception', ('Load',)), 'exc', [('Pass', (4, 2, 4, 6))])], [('Pass', (5, 7, 5, 11))], [('Pass', (7, 2, 7, 6))])], []), ('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []), ('Module', [('Assert', (1, 0, 1, 19), ('Name', (1, 7, 1, 8), 'v', ('Load',)), ('Constant', (1, 10, 1, 19), 'message', None))], []), -('Module', [('Import', (1, 0, 1, 10), [('alias', (1, 7, 1, 10), 'sys', None)])], []), -('Module', [('Import', (1, 0, 1, 17), [('alias', (1, 7, 1, 17), 'foo', 'bar')])], []), -('Module', [('ImportFrom', (1, 0, 1, 22), 'sys', [('alias', (1, 16, 1, 22), 'x', 'y')], 0)], []), -('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', (1, 16, 1, 17), 'v', None)], 0)], []), +('Module', [('Import', (1, 0, 1, 10), [('alias', (1, 7, 1, 10), 'sys', None)], 0)], []), +('Module', [('Import', (1, 0, 1, 17), [('alias', (1, 7, 1, 17), 'foo', 'bar')], 0)], []), +('Module', [('ImportFrom', (1, 0, 1, 22), 'sys', [('alias', (1, 16, 1, 22), 'x', 'y')], 0, 0)], []), +('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', (1, 16, 1, 17), 'v', None)], 0, 0)], []), +('Module', [('Import', (1, 0, 1, 15), [('alias', (1, 12, 1, 15), 'sys', None)], 1)], []), +('Module', [('Import', (1, 0, 1, 22), [('alias', (1, 12, 1, 22), 'foo', 'bar')], 1)], []), +('Module', [('ImportFrom', (1, 0, 1, 27), 'sys', [('alias', (1, 21, 1, 27), 'x', 'y')], 0, 1)], []), +('Module', [('ImportFrom', (1, 0, 1, 22), 'sys', [('alias', (1, 21, 1, 22), 'v', None)], 0, 1)], []), ('Module', [('Global', (1, 0, 1, 8), ['v'])], []), ('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []), ('Module', [('Pass', (1, 0, 1, 4))], []), diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index c5f42cb7888c08..f29f98beb2d048 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -1701,8 +1701,8 @@ def check_text(code, empty, full, **kwargs): check_text( "import _ast as ast; from module import sub", - empty="Module(body=[Import(names=[alias(name='_ast', asname='ast')]), ImportFrom(module='module', names=[alias(name='sub')], level=0)])", - full="Module(body=[Import(names=[alias(name='_ast', asname='ast')]), ImportFrom(module='module', names=[alias(name='sub')], level=0)], type_ignores=[])", + empty="Module(body=[Import(names=[alias(name='_ast', asname='ast')], is_lazy=0), ImportFrom(module='module', names=[alias(name='sub')], level=0, is_lazy=0)])", + full="Module(body=[Import(names=[alias(name='_ast', asname='ast')], is_lazy=0), ImportFrom(module='module', names=[alias(name='sub')], level=0, is_lazy=0)], type_ignores=[])", ) def test_copy_location(self): diff --git a/Lib/test/test_capi/test_config.py b/Lib/test/test_capi/test_config.py index b04d0923926ded..f10ad50d3bea7e 100644 --- a/Lib/test/test_capi/test_config.py +++ b/Lib/test/test_capi/test_config.py @@ -62,6 +62,7 @@ def test_config_get(self): ("int_max_str_digits", int, None), ("interactive", bool, None), ("isolated", bool, None), + ("lazy_imports", int, None), ("malloc_stats", bool, None), ("pymalloc_hugepages", bool, None), ("module_search_paths", list[str], "path"), diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 8529afaa3f5370..cefd64ddfe8417 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -292,7 +292,7 @@ def wrap_func_w_kwargs(): 1 LOAD_SMALL_INT 0 LOAD_CONST 1 (('*',)) - IMPORT_NAME 0 (math) + IMPORT_NAME 2 (math + eager) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) POP_TOP LOAD_CONST 2 (None) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 29b1249b10dfc8..35246d7c484439 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -635,6 +635,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'tracemalloc': 0, 'perf_profiling': 0, 'import_time': 0, + 'lazy_imports': -1, 'thread_inherit_context': DEFAULT_THREAD_INHERIT_CONTEXT, 'context_aware_warnings': DEFAULT_CONTEXT_AWARE_WARNINGS, 'code_debug_ranges': True, diff --git a/Lib/test/test_import/data/lazy_imports/basic2.py b/Lib/test/test_import/data/lazy_imports/basic2.py new file mode 100644 index 00000000000000..f93ec89d5abfb6 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic2.py @@ -0,0 +1,4 @@ +def f(): + pass + +x = 42 diff --git a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py new file mode 100644 index 00000000000000..5076fa4894ebd6 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py @@ -0,0 +1,2 @@ +__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] +import test.test_import.data.lazy_imports.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py new file mode 100644 index 00000000000000..e37759348f3e91 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py @@ -0,0 +1,2 @@ +__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] +lazy from .basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py new file mode 100644 index 00000000000000..64f36645f68790 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py @@ -0,0 +1,3 @@ +__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] +import test.test_import.data.lazy_imports.basic2 +test.test_import.data.lazy_imports.basic2.f() diff --git a/Lib/test/test_import/data/lazy_imports/basic_dir.py b/Lib/test/test_import/data/lazy_imports/basic_dir.py new file mode 100644 index 00000000000000..ca9e29d3d9962e --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_dir.py @@ -0,0 +1,2 @@ +lazy import test.test_import.data.lazy_imports.basic2 +x = dir() diff --git a/Lib/test/test_import/data/lazy_imports/basic_from_unused.py b/Lib/test/test_import/data/lazy_imports/basic_from_unused.py new file mode 100644 index 00000000000000..686caa86a6caa7 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_from_unused.py @@ -0,0 +1 @@ +lazy from test.test_import.data.lazy_imports import basic2 diff --git a/Lib/test/test_import/data/lazy_imports/basic_unused.py b/Lib/test/test_import/data/lazy_imports/basic_unused.py new file mode 100644 index 00000000000000..bf8ae4613e4478 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_unused.py @@ -0,0 +1 @@ +lazy import test.test_import.data.lazy_imports.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/basic_used.py b/Lib/test/test_import/data/lazy_imports/basic_used.py new file mode 100644 index 00000000000000..84e354750f8ea2 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/basic_used.py @@ -0,0 +1,3 @@ +lazy import test.test_import.data.lazy_imports.basic2 as basic2 + +basic2.f() diff --git a/Lib/test/test_import/data/lazy_imports/broken_attr_module.py b/Lib/test/test_import/data/lazy_imports/broken_attr_module.py new file mode 100644 index 00000000000000..a60bca2bad02ee --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/broken_attr_module.py @@ -0,0 +1,3 @@ +# Module that exists but doesn't have expected attributes +x = 42 +# No 'nonexistent_attr' here diff --git a/Lib/test/test_import/data/lazy_imports/broken_module.py b/Lib/test/test_import/data/lazy_imports/broken_module.py new file mode 100644 index 00000000000000..b49d4a4a15f1d4 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/broken_module.py @@ -0,0 +1,2 @@ +# Module that raises an error during import +raise ValueError("This module always fails to import") diff --git a/Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py b/Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py new file mode 100644 index 00000000000000..307338a0886ac3 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py @@ -0,0 +1,5 @@ +__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] +def f(): + import test.test_import.data.lazy_imports.basic2 + +f() diff --git a/Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py b/Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py new file mode 100644 index 00000000000000..6d54e69a9a4268 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py @@ -0,0 +1,5 @@ +__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] +try: + import test.test_import.data.lazy_imports.basic2 +except: + pass diff --git a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py new file mode 100644 index 00000000000000..1a8a19c3c90814 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py @@ -0,0 +1 @@ +basic = __lazy_import__('test.test_import.data.lazy_imports.basic2') diff --git a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py new file mode 100644 index 00000000000000..f1fed0fc31768e --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py @@ -0,0 +1,14 @@ +import sys + +def myimport(*args): + return sys.modules[__name__] + + +new_globals = dict(globals()) +new_globals["__builtins__"] = { + "__import__": myimport, +} +basic2 = 42 +basic = __lazy_import__("test.test_import.data.lazy_imports.basic2", + globals=new_globals) +basic diff --git a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py new file mode 100644 index 00000000000000..2432ca17b16287 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py @@ -0,0 +1,3 @@ +basic = __lazy_import__('test.test_import.data.lazy_imports', + fromlist=("basic2", )) +basic diff --git a/Lib/test/test_import/data/lazy_imports/eager_import_func.py b/Lib/test/test_import/data/lazy_imports/eager_import_func.py new file mode 100644 index 00000000000000..89e643ac183e9b --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/eager_import_func.py @@ -0,0 +1,3 @@ +def f(): + import test.test_import.data.lazy_imports.basic2 as basic2 + return basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_filter.py b/Lib/test/test_import/data/lazy_imports/global_filter.py new file mode 100644 index 00000000000000..72cb5f2ef5a02b --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/global_filter.py @@ -0,0 +1,10 @@ +import sys + +def filter(module_name, imported_name, from_list): + assert module_name == __name__ + assert imported_name == "test.test_import.data.lazy_imports.basic2" + return False + +sys.set_lazy_imports_filter(filter) + +lazy import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_from.py b/Lib/test/test_import/data/lazy_imports/global_filter_from.py new file mode 100644 index 00000000000000..733839d9c1e935 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/global_filter_from.py @@ -0,0 +1,11 @@ +import importlib + +def filter(module_name, imported_name, from_list): + assert module_name == __name__ + assert imported_name == "test.test_import.data.lazy_imports.basic2" + assert from_list == ['f'] + return False + +importlib.set_lazy_imports(None, filter) + +lazy from import test.test_import.data.lazy_imports.basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py b/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py new file mode 100644 index 00000000000000..c019f1ae8117a4 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py @@ -0,0 +1,11 @@ +import importlib + +def filter(module_name, imported_name, from_list): + assert module_name == __name__ + assert imported_name == "test.test_import.data.lazy_imports.basic2" + assert from_list == ['f'] + return True + +importlib.set_lazy_imports(None, filter) + +lazy from import test.test_import.data.lazy_imports.basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_true.py b/Lib/test/test_import/data/lazy_imports/global_filter_true.py new file mode 100644 index 00000000000000..4881b30fb02409 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/global_filter_true.py @@ -0,0 +1,11 @@ +import sys + +def filter(module_name, imported_name, from_list): + assert module_name == __name__ + assert imported_name == "test.test_import.data.lazy_imports.basic2" + return True + +sys.set_lazy_imports("normal") +sys.set_lazy_imports_filter(filter) + +lazy import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_off.py b/Lib/test/test_import/data/lazy_imports/global_off.py new file mode 100644 index 00000000000000..4f202744a9ed42 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/global_off.py @@ -0,0 +1,5 @@ +import sys + +sys.set_lazy_imports("none") + +lazy import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_on.py b/Lib/test/test_import/data/lazy_imports/global_on.py new file mode 100644 index 00000000000000..3f8e1d2aa01380 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/global_on.py @@ -0,0 +1,5 @@ +import sys + +sys.set_lazy_imports("all") + +import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/globals_access.py b/Lib/test/test_import/data/lazy_imports/globals_access.py new file mode 100644 index 00000000000000..c12c6a029c2b81 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/globals_access.py @@ -0,0 +1,9 @@ +# Test that globals() returns lazy proxy objects without reifying +lazy import test.test_import.data.lazy_imports.basic2 as basic2 + +def get_from_globals(): + g = globals() + return g['basic2'] + +def get_direct(): + return basic2 diff --git a/Lib/test/test_import/data/lazy_imports/lazy_class_body.py b/Lib/test/test_import/data/lazy_imports/lazy_class_body.py new file mode 100644 index 00000000000000..e154b78f6cdc13 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_class_body.py @@ -0,0 +1,3 @@ +# SyntaxError: lazy import inside class body is not allowed +class Foo: + lazy import json diff --git a/Lib/test/test_import/data/lazy_imports/lazy_compat_from.py b/Lib/test/test_import/data/lazy_imports/lazy_compat_from.py new file mode 100644 index 00000000000000..f887f47b92c3f4 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_compat_from.py @@ -0,0 +1,6 @@ +# Test __lazy_modules__ with from imports +__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] +from test.test_import.data.lazy_imports.basic2 import x, f + +def get_x(): + return x diff --git a/Lib/test/test_import/data/lazy_imports/lazy_future_import.py b/Lib/test/test_import/data/lazy_imports/lazy_future_import.py new file mode 100644 index 00000000000000..8bd258b76b4cbd --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_future_import.py @@ -0,0 +1 @@ +lazy from __future__ import annotations diff --git a/Lib/test/test_import/data/lazy_imports/lazy_get_value.py b/Lib/test/test_import/data/lazy_imports/lazy_get_value.py new file mode 100644 index 00000000000000..0ff572fa1e398a --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_get_value.py @@ -0,0 +1,7 @@ +lazy import test.test_import.data.lazy_imports.basic2 as basic2 + +def f(): + x = globals() + return x['basic2'].resolve() + +f() diff --git a/Lib/test/test_import/data/lazy_imports/lazy_import_func.py b/Lib/test/test_import/data/lazy_imports/lazy_import_func.py new file mode 100644 index 00000000000000..af758b51127686 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_import_func.py @@ -0,0 +1,2 @@ +def f(): + lazy import foo diff --git a/Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py b/Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py new file mode 100644 index 00000000000000..79aa9a567398bb --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py @@ -0,0 +1,2 @@ +lazy import test.test_import.data.lazy_imports.pkg.bar +x = test.test_import.data.lazy_imports.pkg.bar.f diff --git a/Lib/test/test_import/data/lazy_imports/lazy_try_except.py b/Lib/test/test_import/data/lazy_imports/lazy_try_except.py new file mode 100644 index 00000000000000..e58d1f929cae18 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_try_except.py @@ -0,0 +1,4 @@ +try: + lazy import foo +except: + pass diff --git a/Lib/test/test_import/data/lazy_imports/lazy_try_except_from.py b/Lib/test/test_import/data/lazy_imports/lazy_try_except_from.py new file mode 100644 index 00000000000000..8c97553f486cef --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_try_except_from.py @@ -0,0 +1,4 @@ +try: + lazy from foo import bar +except: + pass diff --git a/Lib/test/test_import/data/lazy_imports/lazy_try_except_from_star.py b/Lib/test/test_import/data/lazy_imports/lazy_try_except_from_star.py new file mode 100644 index 00000000000000..b2370eaae771c1 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_try_except_from_star.py @@ -0,0 +1 @@ +lazy from foo import * diff --git a/Lib/test/test_import/data/lazy_imports/lazy_with.py b/Lib/test/test_import/data/lazy_imports/lazy_with.py new file mode 100644 index 00000000000000..b383879936a219 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_with.py @@ -0,0 +1,3 @@ +import contextlib +with contextlib.nullcontext(): + lazy import test.test_import.data.lazy_imports.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/lazy_with_from.py b/Lib/test/test_import/data/lazy_imports/lazy_with_from.py new file mode 100644 index 00000000000000..7936326a9e3d35 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/lazy_with_from.py @@ -0,0 +1,3 @@ +import contextlib +with contextlib.nullcontext(): + lazy import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/modules_dict.py b/Lib/test/test_import/data/lazy_imports/modules_dict.py new file mode 100644 index 00000000000000..327f866398c86d --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/modules_dict.py @@ -0,0 +1,5 @@ +lazy import test.test_import.data.lazy_imports.basic2 as basic2 + +import sys +mod = sys.modules[__name__] +x = mod.__dict__ diff --git a/Lib/test/test_import/data/lazy_imports/modules_getattr.py b/Lib/test/test_import/data/lazy_imports/modules_getattr.py new file mode 100644 index 00000000000000..ae1d4bb3f976ea --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/modules_getattr.py @@ -0,0 +1,5 @@ +lazy import test.test_import.data.lazy_imports.basic2 as basic2 + +import sys +mod = sys.modules[__name__] +x = mod.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/modules_getattr_other.py b/Lib/test/test_import/data/lazy_imports/modules_getattr_other.py new file mode 100644 index 00000000000000..e4d83e6336db72 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/modules_getattr_other.py @@ -0,0 +1,5 @@ +lazy import test.test_import.data.lazy_imports.basic2 as basic2 + +import sys +mod = sys.modules[__name__] +x = mod.__name__ diff --git a/Lib/test/test_import/data/lazy_imports/multi_from_import.py b/Lib/test/test_import/data/lazy_imports/multi_from_import.py new file mode 100644 index 00000000000000..96dc9757500549 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/multi_from_import.py @@ -0,0 +1,5 @@ +# Test that lazy from import with multiple names only reifies accessed names +lazy from test.test_import.data.lazy_imports.basic2 import f, x + +def get_globals(): + return globals() diff --git a/Lib/test/test_import/data/lazy_imports/pkg/__init__.py b/Lib/test/test_import/data/lazy_imports/pkg/__init__.py new file mode 100644 index 00000000000000..2d76abaa89f893 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/pkg/__init__.py @@ -0,0 +1 @@ +x = 42 diff --git a/Lib/test/test_import/data/lazy_imports/pkg/b.py b/Lib/test/test_import/data/lazy_imports/pkg/b.py new file mode 100644 index 00000000000000..a266b7c7c0d165 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/pkg/b.py @@ -0,0 +1,2 @@ +def foo(): + return 'foo' diff --git a/Lib/test/test_import/data/lazy_imports/pkg/bar.py b/Lib/test/test_import/data/lazy_imports/pkg/bar.py new file mode 100644 index 00000000000000..b8d8b60b886b88 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/pkg/bar.py @@ -0,0 +1,2 @@ +print("BAR_MODULE_LOADED") +def f(): pass diff --git a/Lib/test/test_import/data/lazy_imports/pkg/c.py b/Lib/test/test_import/data/lazy_imports/pkg/c.py new file mode 100644 index 00000000000000..0bb031198648ab --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/pkg/c.py @@ -0,0 +1,4 @@ +lazy from . import b, x + +def get_globals(): + return globals() diff --git a/Lib/test/test_import/data/lazy_imports/relative_lazy.py b/Lib/test/test_import/data/lazy_imports/relative_lazy.py new file mode 100644 index 00000000000000..6273d3883abf88 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/relative_lazy.py @@ -0,0 +1,5 @@ +# Test relative imports with lazy keyword +lazy from . import basic2 + +def get_basic2(): + return basic2 diff --git a/Lib/test/test_import/data/lazy_imports/relative_lazy_from.py b/Lib/test/test_import/data/lazy_imports/relative_lazy_from.py new file mode 100644 index 00000000000000..1bae2d6853dfcf --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/relative_lazy_from.py @@ -0,0 +1,8 @@ +# Test relative from imports with lazy keyword +lazy from .basic2 import x, f + +def get_x(): + return x + +def get_f(): + return f diff --git a/Lib/test/test_import/data/lazy_imports/try_except_eager.py b/Lib/test/test_import/data/lazy_imports/try_except_eager.py new file mode 100644 index 00000000000000..4cdaa9a9b48eae --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/try_except_eager.py @@ -0,0 +1,4 @@ +try: + import test.test_import.data.lazy_imports.basic2 +except: + pass diff --git a/Lib/test/test_import/data/lazy_imports/try_except_eager_from.py b/Lib/test/test_import/data/lazy_imports/try_except_eager_from.py new file mode 100644 index 00000000000000..6eadaaa71ca454 --- /dev/null +++ b/Lib/test/test_import/data/lazy_imports/try_except_eager_from.py @@ -0,0 +1,4 @@ +try: + from test.test_import.data.lazy_imports.basic2 import f +except: + pass diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py new file mode 100644 index 00000000000000..1193af9589034b --- /dev/null +++ b/Lib/test/test_import/test_lazy_imports.py @@ -0,0 +1,1662 @@ +"""Tests for PEP 810 lazy imports.""" + +import io +import dis +import subprocess +import sys +import textwrap +import threading +import types +import unittest + +try: + import _testcapi +except ImportError: + _testcapi = None + + +class LazyImportTests(unittest.TestCase): + """Tests for basic lazy import functionality.""" + + def tearDown(self): + """Clean up any test modules from sys.modules.""" + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + sys.lazy_modules.clear() + + def test_basic_unused(self): + """Lazy imported module should not be loaded if never accessed.""" + import test.test_import.data.lazy_imports.basic_unused + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules) + self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"}) + + def test_sys_lazy_modules(self): + try: + import test.test_import.data.lazy_imports.basic_from_unused + except ImportError as e: + self.fail('lazy import failed') + + self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules) + self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules) + self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"}) + test.test_import.data.lazy_imports.basic_from_unused.basic2 + self.assertNotIn("test.test_import.data", sys.lazy_modules) + + def test_basic_unused_use_externally(self): + """Lazy import should load module when accessed from outside.""" + from test.test_import.data.lazy_imports import basic_unused + + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + x = basic_unused.test.test_import.data.lazy_imports.basic2 + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_basic_from_unused_use_externally(self): + """Lazy 'from' import should load when accessed from outside.""" + from test.test_import.data.lazy_imports import basic_from_unused + + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + x = basic_from_unused.basic2 + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_basic_unused_dir(self): + """dir() on module should not trigger lazy import reification.""" + import test.test_import.data.lazy_imports.basic_unused + + x = dir(test.test_import.data.lazy_imports.basic_unused) + self.assertIn("test", x) + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_basic_dir(self): + """dir() at module scope should not trigger lazy import reification.""" + from test.test_import.data.lazy_imports import basic_dir + + self.assertIn("test", basic_dir.x) + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_basic_used(self): + """Lazy import should load when accessed within the module.""" + import test.test_import.data.lazy_imports.basic_used + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class GlobalLazyImportModeTests(unittest.TestCase): + """Tests for sys.set_lazy_imports() global mode control.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_global_off(self): + """Mode 'none' should disable lazy imports entirely.""" + import test.test_import.data.lazy_imports.global_off + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_global_on(self): + """Mode 'all' should make regular imports lazy.""" + import test.test_import.data.lazy_imports.global_on + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_global_filter(self): + """Filter returning False should prevent lazy loading.""" + import test.test_import.data.lazy_imports.global_filter + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_global_filter_true(self): + """Filter returning True should allow lazy loading.""" + import test.test_import.data.lazy_imports.global_filter_true + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_global_filter_from(self): + """Filter should work with 'from' imports.""" + import test.test_import.data.lazy_imports.global_filter + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_global_filter_from_true(self): + """Filter returning True should allow lazy 'from' imports.""" + import test.test_import.data.lazy_imports.global_filter_true + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class CompatibilityModeTests(unittest.TestCase): + """Tests for __lazy_modules__ compatibility mode.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_compatibility_mode(self): + """__lazy_modules__ should enable lazy imports for listed modules.""" + import test.test_import.data.lazy_imports.basic_compatibility_mode + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_compatibility_mode_used(self): + """Using a lazy import from __lazy_modules__ should load the module.""" + import test.test_import.data.lazy_imports.basic_compatibility_mode_used + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_compatibility_mode_func(self): + """Imports inside functions should be eager even in compatibility mode.""" + import test.test_import.data.lazy_imports.compatibility_mode_func + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_compatibility_mode_try_except(self): + """Imports in try/except should be eager even in compatibility mode.""" + import test.test_import.data.lazy_imports.compatibility_mode_try_except + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_compatibility_mode_relative(self): + """__lazy_modules__ should work with relative imports.""" + import test.test_import.data.lazy_imports.basic_compatibility_mode_relative + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class ModuleIntrospectionTests(unittest.TestCase): + """Tests for module dict and getattr behavior with lazy imports.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_modules_dict(self): + """Accessing module.__dict__ should not trigger reification.""" + import test.test_import.data.lazy_imports.modules_dict + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_modules_getattr(self): + """Module __getattr__ for lazy import name should trigger reification.""" + import test.test_import.data.lazy_imports.modules_getattr + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_modules_getattr_other(self): + """Module __getattr__ for other names should not trigger reification.""" + import test.test_import.data.lazy_imports.modules_getattr_other + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class LazyImportTypeTests(unittest.TestCase): + """Tests for the LazyImportType and its resolve() method.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_lazy_value_resolve(self): + """resolve() method should force the lazy import to load.""" + import test.test_import.data.lazy_imports.lazy_get_value + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_lazy_import_type_exposed(self): + """LazyImportType should be exposed in types module.""" + self.assertHasAttr(types, 'LazyImportType') + self.assertEqual(types.LazyImportType.__name__, 'lazy_import') + + def test_lazy_import_type_cant_construct(self): + """LazyImportType should not be directly constructible.""" + self.assertRaises(TypeError, types.LazyImportType, {}, "module") + + +class SyntaxRestrictionTests(unittest.TestCase): + """Tests for syntax restrictions on lazy imports.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_lazy_try_except(self): + """lazy import inside try/except should raise SyntaxError.""" + with self.assertRaises(SyntaxError): + import test.test_import.data.lazy_imports.lazy_try_except + + def test_lazy_try_except_from(self): + """lazy from import inside try/except should raise SyntaxError.""" + with self.assertRaises(SyntaxError): + import test.test_import.data.lazy_imports.lazy_try_except_from + + def test_lazy_try_except_from_star(self): + """lazy from import * should raise SyntaxError.""" + with self.assertRaises(SyntaxError): + import test.test_import.data.lazy_imports.lazy_try_except_from_star + + def test_lazy_future_import(self): + """lazy from __future__ import should raise SyntaxError.""" + with self.assertRaises(SyntaxError) as cm: + import test.test_import.data.lazy_imports.lazy_future_import + # Check we highlight 'lazy' (column offset 0, end offset 4) + self.assertEqual(cm.exception.offset, 1) + self.assertEqual(cm.exception.end_offset, 5) + + def test_lazy_import_func(self): + """lazy import inside function should raise SyntaxError.""" + with self.assertRaises(SyntaxError): + import test.test_import.data.lazy_imports.lazy_import_func + + def test_lazy_import_exec_in_function(self): + """lazy import via exec() inside a function should raise SyntaxError.""" + # exec() inside a function creates a non-module-level context + # where lazy imports are not allowed + def f(): + exec("lazy import json") + + with self.assertRaises(SyntaxError) as cm: + f() + self.assertIn("only allowed at module level", str(cm.exception)) + + def test_lazy_import_exec_at_module_level(self): + """lazy import via exec() at module level should work.""" + # exec() at module level (globals == locals) should allow lazy imports + code = textwrap.dedent(""" + import sys + exec("lazy import json") + # Should be lazy - not loaded yet + assert 'json' not in sys.modules + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class EagerImportInLazyModeTests(unittest.TestCase): + """Tests for imports that should remain eager even in lazy mode.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_try_except_eager(self): + """Imports in try/except should be eager even with mode='all'.""" + sys.set_lazy_imports("all") + import test.test_import.data.lazy_imports.try_except_eager + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_try_except_eager_from(self): + """From imports in try/except should be eager even with mode='all'.""" + sys.set_lazy_imports("all") + import test.test_import.data.lazy_imports.try_except_eager_from + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_eager_import_func(self): + """Imports inside functions should return modules, not proxies.""" + sys.set_lazy_imports("all") + import test.test_import.data.lazy_imports.eager_import_func + + f = test.test_import.data.lazy_imports.eager_import_func.f + self.assertEqual(type(f()), type(sys)) + + +class WithStatementTests(unittest.TestCase): + """Tests for lazy imports in with statement context.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_lazy_with(self): + """lazy import with 'with' statement should work.""" + import test.test_import.data.lazy_imports.lazy_with + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_lazy_with_from(self): + """lazy from import with 'with' statement should work.""" + import test.test_import.data.lazy_imports.lazy_with_from + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class PackageTests(unittest.TestCase): + """Tests for lazy imports with packages.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_lazy_import_pkg(self): + """lazy import of package submodule should load the package.""" + import test.test_import.data.lazy_imports.lazy_import_pkg + + self.assertIn("test.test_import.data.lazy_imports.pkg", sys.modules) + self.assertIn("test.test_import.data.lazy_imports.pkg.bar", sys.modules) + + def test_lazy_import_pkg_cross_import(self): + """Cross-imports within package should preserve lazy imports.""" + import test.test_import.data.lazy_imports.pkg.c + + self.assertIn("test.test_import.data.lazy_imports.pkg", sys.modules) + self.assertIn("test.test_import.data.lazy_imports.pkg.c", sys.modules) + self.assertNotIn("test.test_import.data.lazy_imports.pkg.b", sys.modules) + + g = test.test_import.data.lazy_imports.pkg.c.get_globals() + self.assertEqual(type(g["x"]), int) + self.assertEqual(type(g["b"]), types.LazyImportType) + + +class DunderLazyImportTests(unittest.TestCase): + """Tests for __lazy_import__ builtin function.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_dunder_lazy_import(self): + """__lazy_import__ should create lazy import proxy.""" + import test.test_import.data.lazy_imports.dunder_lazy_import + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_dunder_lazy_import_used(self): + """Using __lazy_import__ result should trigger module load.""" + import test.test_import.data.lazy_imports.dunder_lazy_import_used + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_dunder_lazy_import_builtins(self): + """__lazy_import__ should use module's __builtins__ for __import__.""" + from test.test_import.data.lazy_imports import dunder_lazy_import_builtins + + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertEqual(dunder_lazy_import_builtins.basic.basic2, 42) + + +class SysLazyImportsAPITests(unittest.TestCase): + """Tests for sys lazy imports API functions.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_set_lazy_imports_requires_string(self): + """set_lazy_imports should reject non-string arguments.""" + with self.assertRaises(TypeError): + sys.set_lazy_imports(True) + with self.assertRaises(TypeError): + sys.set_lazy_imports(None) + with self.assertRaises(TypeError): + sys.set_lazy_imports(1) + + def test_set_lazy_imports_rejects_invalid_mode(self): + """set_lazy_imports should reject invalid mode strings.""" + with self.assertRaises(ValueError): + sys.set_lazy_imports("invalid") + with self.assertRaises(ValueError): + sys.set_lazy_imports("on") + with self.assertRaises(ValueError): + sys.set_lazy_imports("off") + + def test_get_lazy_imports_returns_string(self): + """get_lazy_imports should return string modes.""" + sys.set_lazy_imports("normal") + self.assertEqual(sys.get_lazy_imports(), "normal") + + sys.set_lazy_imports("all") + self.assertEqual(sys.get_lazy_imports(), "all") + + sys.set_lazy_imports("none") + self.assertEqual(sys.get_lazy_imports(), "none") + + def test_get_lazy_imports_filter_default(self): + """get_lazy_imports_filter should return None by default.""" + sys.set_lazy_imports_filter(None) + self.assertIsNone(sys.get_lazy_imports_filter()) + + def test_set_and_get_lazy_imports_filter(self): + """set/get_lazy_imports_filter should round-trip filter function.""" + def my_filter(name): + return name.startswith("test.") + + sys.set_lazy_imports_filter(my_filter) + self.assertIs(sys.get_lazy_imports_filter(), my_filter) + + def test_lazy_modules_attribute_is_set(self): + """sys.lazy_modules should be a set per PEP 810.""" + self.assertIsInstance(sys.lazy_modules, dict) + + def test_lazy_modules_tracks_lazy_imports(self): + """sys.lazy_modules should track lazily imported module names.""" + code = textwrap.dedent(""" + import sys + initial_count = len(sys.lazy_modules) + import test.test_import.data.lazy_imports.basic_unused + assert "test.test_import.data.lazy_imports" in sys.lazy_modules + assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"} + assert len(sys.lazy_modules) > initial_count + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class ErrorHandlingTests(unittest.TestCase): + """Tests for error handling during lazy import reification. + + PEP 810: Errors during reification should show exception chaining with + both the lazy import definition location and the access location. + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_import_error_shows_chained_traceback(self): + """ImportError during reification should chain to show both definition and access.""" + # Errors at reification must show where the lazy import was defined + # AND where the access happened, per PEP 810 "Reification" section + code = textwrap.dedent(""" + import sys + lazy import test.test_import.data.lazy_imports.nonexistent_module + + try: + x = test.test_import.data.lazy_imports.nonexistent_module + except ImportError as e: + # Should have __cause__ showing the original error + # The exception chain shows both where import was defined and where access happened + assert e.__cause__ is not None, "Expected chained exception" + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_attribute_error_on_from_import_shows_chained_traceback(self): + """Accessing missing attribute from lazy from-import should chain errors.""" + # Tests 'lazy from module import nonexistent' behavior + code = textwrap.dedent(""" + import sys + lazy from test.test_import.data.lazy_imports.basic2 import nonexistent_name + + try: + x = nonexistent_name + except ImportError as e: + # PEP 810: Enhanced error reporting through exception chaining + assert e.__cause__ is not None, "Expected chained exception" + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_reification_retries_on_failure(self): + """Failed reification should allow retry on subsequent access. + + PEP 810: "If reification fails, the lazy object is not reified or replaced. + Subsequent uses of the lazy object will re-try the reification." + """ + code = textwrap.dedent(""" + import sys + import types + + lazy import test.test_import.data.lazy_imports.broken_module + + # First access - should fail + try: + x = test.test_import.data.lazy_imports.broken_module + except ValueError: + pass + + # The lazy object should still be a lazy proxy (not reified) + g = globals() + lazy_obj = g['test'] + # The root 'test' binding should still allow retry + # Second access - should also fail (retry the import) + try: + x = test.test_import.data.lazy_imports.broken_module + except ValueError: + print("OK - retry worked") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_error_during_module_execution_propagates(self): + """Errors in module code during reification should propagate correctly.""" + # Module that raises during import should propagate with chaining + code = textwrap.dedent(""" + import sys + lazy import test.test_import.data.lazy_imports.broken_module + + try: + _ = test.test_import.data.lazy_imports.broken_module + print("FAIL - should have raised") + except ValueError as e: + # The ValueError from the module should be the cause + if "always fails" in str(e) or (e.__cause__ and "always fails" in str(e.__cause__)): + print("OK") + else: + print(f"FAIL - wrong error: {e}") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class GlobalsAndDictTests(unittest.TestCase): + """Tests for globals() and __dict__ behavior with lazy imports. + + PEP 810: "Calling globals() or accessing a module's __dict__ does not trigger + reification – they return the module's dictionary, and accessing lazy objects + through that dictionary still returns lazy proxy objects." + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_globals_returns_lazy_proxy_when_accessed_from_function(self): + """globals() accessed from a function should return lazy proxy without reification. + + Note: At module level, accessing globals()['name'] triggers LOAD_NAME which + automatically resolves lazy imports. Inside a function, accessing globals()['name'] + uses BINARY_SUBSCR which returns the lazy proxy without resolution. + """ + code = textwrap.dedent(""" + import sys + import types + + lazy from test.test_import.data.lazy_imports.basic2 import x + + # Check that module is not yet loaded + assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + + def check_lazy(): + # Access through globals() from inside a function + g = globals() + lazy_obj = g['x'] + return type(lazy_obj) is types.LazyImportType + + # Inside function, should get lazy proxy + is_lazy = check_lazy() + assert is_lazy, "Expected LazyImportType from function scope" + + # Module should STILL not be loaded + assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_globals_dict_access_returns_lazy_proxy_inline(self): + """Accessing globals()['name'] inline should return lazy proxy. + + Note: Assigning g['name'] to a local variable at module level triggers + reification due to STORE_NAME bytecode. Inline access preserves laziness. + """ + code = textwrap.dedent(""" + import sys + import types + lazy import json + # Inline access without assignment to local variable preserves lazy proxy + assert type(globals()['json']) is types.LazyImportType + assert 'json' not in sys.modules + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_module_dict_returns_lazy_proxy_without_reifying(self): + """module.__dict__ access should not trigger reification.""" + import test.test_import.data.lazy_imports.globals_access + + # Module not loaded yet via direct dict access + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + # Access via get_from_globals should return lazy proxy + lazy_obj = test.test_import.data.lazy_imports.globals_access.get_from_globals() + self.assertEqual(type(lazy_obj), types.LazyImportType) + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_direct_access_triggers_reification(self): + """Direct name access (not through globals()) should trigger reification.""" + import test.test_import.data.lazy_imports.globals_access + + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + # Direct access should reify + result = test.test_import.data.lazy_imports.globals_access.get_direct() + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_resolve_method_forces_reification(self): + """Calling resolve() on lazy proxy should force reification. + + Note: Must access lazy proxy from within a function to avoid automatic + reification by LOAD_NAME at module level. + """ + code = textwrap.dedent(""" + import sys + import types + + lazy from test.test_import.data.lazy_imports.basic2 import x + + assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + + def test_resolve(): + g = globals() + lazy_obj = g['x'] + assert type(lazy_obj) is types.LazyImportType, f"Expected lazy proxy, got {type(lazy_obj)}" + + resolved = lazy_obj.resolve() + + # Now module should be loaded + assert 'test.test_import.data.lazy_imports.basic2' in sys.modules + assert resolved == 42 # x is 42 in basic2.py + return True + + assert test_resolve() + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_add_lazy_to_globals(self): + code = textwrap.dedent(""" + import sys + import types + + lazy from test.test_import.data.lazy_imports import basic2 + + assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + + class C: pass + sneaky = C() + sneaky.x = 1 + + def f(): + t = 0 + for _ in range(5): + t += sneaky.x + return t + + f() + globals()["sneaky"] = globals()["basic2"] + assert f() == 210 + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class MultipleNameFromImportTests(unittest.TestCase): + """Tests for lazy from ... import with multiple names. + + PEP 810: "When using lazy from ... import, each imported name is bound to a + lazy proxy object. The first access to any of these names triggers loading + of the entire module and reifies only that specific name to its actual value. + Other names remain as lazy proxies until they are accessed." + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_accessing_one_name_leaves_others_as_proxies(self): + """Accessing one name from multi-name import should leave others lazy.""" + code = textwrap.dedent(""" + import sys + import types + + lazy from test.test_import.data.lazy_imports.basic2 import f, x + + # Neither should be loaded yet + assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + + g = globals() + assert type(g['f']) is types.LazyImportType + assert type(g['x']) is types.LazyImportType + + # Access 'x' - this loads the module and reifies only 'x' + value = x + assert value == 42 + + # Module is now loaded + assert 'test.test_import.data.lazy_imports.basic2' in sys.modules + + # 'x' should be reified (int), 'f' should still be lazy proxy + assert type(g['x']) is int, f"Expected int, got {type(g['x'])}" + assert type(g['f']) is types.LazyImportType, f"Expected LazyImportType, got {type(g['f'])}" + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_all_names_reified_after_all_accessed(self): + """All names should be reified after each is accessed.""" + code = textwrap.dedent(""" + import sys + import types + + lazy from test.test_import.data.lazy_imports.basic2 import f, x + + g = globals() + + # Access both + _ = x + _ = f + + # Both should be reified now + assert type(g['x']) is int + assert callable(g['f']) + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class SysLazyModulesTrackingTests(unittest.TestCase): + """Tests for sys.lazy_modules tracking behavior. + + PEP 810: "When the module is reified, it's removed from sys.lazy_modules" + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_module_added_to_lazy_modules_on_lazy_import(self): + """Module should be added to sys.lazy_modules when lazily imported.""" + # PEP 810 states lazy_modules tracks modules that have been lazily imported + # Note: The current implementation keeps modules in lazy_modules even after + # reification (primarily for diagnostics and introspection) + code = textwrap.dedent(""" + import sys + + initial_count = len(sys.lazy_modules) + + lazy import test.test_import.data.lazy_imports.basic2 + + # Should be in lazy_modules after lazy import + assert "test.test_import.data.lazy_imports" in sys.lazy_modules + assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"} + assert len(sys.lazy_modules) > initial_count + + # Trigger reification + _ = test.test_import.data.lazy_imports.basic2.x + + # Module should still be tracked (for diagnostics per PEP 810) + assert "test.test_import.data.lazy_imports" not in sys.lazy_modules + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_lazy_modules_is_per_interpreter(self): + """Each interpreter should have independent sys.lazy_modules.""" + # Basic test that sys.lazy_modules exists and is a set + self.assertIsInstance(sys.lazy_modules, dict) + + +class CommandLineAndEnvVarTests(unittest.TestCase): + """Tests for command-line and environment variable control. + + PEP 810: The global lazy imports flag can be controlled through: + - The -X lazy_imports= command-line option + - The PYTHON_LAZY_IMPORTS= environment variable + """ + + def test_cli_lazy_imports_all_makes_regular_imports_lazy(self): + """-X lazy_imports=all should make all imports potentially lazy.""" + code = textwrap.dedent(""" + import sys + # In 'all' mode, regular imports become lazy + import json + # json should not be in sys.modules yet (lazy) + # Actually accessing it triggers reification + if 'json' not in sys.modules: + print("LAZY") + else: + print("EAGER") + """) + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=all", "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("LAZY", result.stdout) + + def test_cli_lazy_imports_none_forces_all_imports_eager(self): + """-X lazy_imports=none should force all imports to be eager.""" + code = textwrap.dedent(""" + import sys + # Even explicit lazy imports should be eager in 'none' mode + lazy import json + if 'json' in sys.modules: + print("EAGER") + else: + print("LAZY") + """) + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=none", "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("EAGER", result.stdout) + + def test_cli_lazy_imports_normal_respects_lazy_keyword_only(self): + """-X lazy_imports=normal should respect lazy keyword only.""" + # Note: Use test modules instead of stdlib modules to avoid + # modules already loaded by the interpreter startup + code = textwrap.dedent(""" + import sys + import test.test_import.data.lazy_imports.basic2 # Should be eager + lazy import test.test_import.data.lazy_imports.pkg.b # Should be lazy + + eager_loaded = 'test.test_import.data.lazy_imports.basic2' in sys.modules + lazy_loaded = 'test.test_import.data.lazy_imports.pkg.b' in sys.modules + + if eager_loaded and not lazy_loaded: + print("OK") + else: + print(f"FAIL: eager={eager_loaded}, lazy={lazy_loaded}") + """) + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=normal", "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_env_var_lazy_imports_all_enables_global_lazy(self): + """PYTHON_LAZY_IMPORTS=all should enable global lazy imports.""" + code = textwrap.dedent(""" + import sys + import json + if 'json' not in sys.modules: + print("LAZY") + else: + print("EAGER") + """) + import os + env = os.environ.copy() + env["PYTHON_LAZY_IMPORTS"] = "all" + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True, + env=env + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("LAZY", result.stdout) + + def test_env_var_lazy_imports_none_disables_all_lazy(self): + """PYTHON_LAZY_IMPORTS=none should disable all lazy imports.""" + code = textwrap.dedent(""" + import sys + lazy import json + if 'json' in sys.modules: + print("EAGER") + else: + print("LAZY") + """) + import os + env = os.environ.copy() + env["PYTHON_LAZY_IMPORTS"] = "none" + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True, + env=env + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("EAGER", result.stdout) + + def test_cli_overrides_env_var(self): + """Command-line option should take precedence over environment variable.""" + # PEP 810: -X lazy_imports takes precedence over PYTHON_LAZY_IMPORTS + code = textwrap.dedent(""" + import sys + lazy import json + if 'json' in sys.modules: + print("EAGER") + else: + print("LAZY") + """) + import os + env = os.environ.copy() + env["PYTHON_LAZY_IMPORTS"] = "all" # env says all + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=none", "-c", code], # CLI says none + capture_output=True, + text=True, + env=env + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + # CLI should win - imports should be eager + self.assertIn("EAGER", result.stdout) + + def test_sys_set_lazy_imports_overrides_cli(self): + """sys.set_lazy_imports() should take precedence over CLI option.""" + code = textwrap.dedent(""" + import sys + sys.set_lazy_imports("none") # Override CLI + lazy import json + if 'json' in sys.modules: + print("EAGER") + else: + print("LAZY") + """) + result = subprocess.run( + [sys.executable, "-X", "lazy_imports=all", "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("EAGER", result.stdout) + + +class FilterFunctionSignatureTests(unittest.TestCase): + """Tests for the filter function signature per PEP 810. + + PEP 810: func(importer: str, name: str, fromlist: tuple[str, ...] | None) -> bool + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_filter_receives_correct_arguments_for_import(self): + """Filter should receive (importer, name, fromlist=None) for 'import x'.""" + code = textwrap.dedent(""" + import sys + + received_args = [] + + def my_filter(importer, name, fromlist): + received_args.append((importer, name, fromlist)) + return True + + sys.set_lazy_imports_filter(my_filter) + + lazy import json + + assert len(received_args) == 1, f"Expected 1 call, got {len(received_args)}" + importer, name, fromlist = received_args[0] + assert name == "json", f"Expected name='json', got {name!r}" + assert fromlist is None, f"Expected fromlist=None, got {fromlist!r}" + assert isinstance(importer, str), f"Expected str importer, got {type(importer)}" + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_filter_receives_fromlist_for_from_import(self): + """Filter should receive fromlist tuple for 'from x import y, z'.""" + code = textwrap.dedent(""" + import sys + + received_args = [] + + def my_filter(importer, name, fromlist): + received_args.append((importer, name, fromlist)) + return True + + sys.set_lazy_imports_filter(my_filter) + + lazy from json import dumps, loads + + assert len(received_args) == 1, f"Expected 1 call, got {len(received_args)}" + importer, name, fromlist = received_args[0] + assert name == "json", f"Expected name='json', got {name!r}" + assert fromlist == ("dumps", "loads"), f"Expected ('dumps', 'loads'), got {fromlist!r}" + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_filter_returning_false_forces_eager_import(self): + """Filter returning False should make import eager.""" + code = textwrap.dedent(""" + import sys + + def deny_filter(importer, name, fromlist): + return False + + sys.set_lazy_imports_filter(deny_filter) + + lazy import json + + # Should be eager due to filter + if 'json' in sys.modules: + print("EAGER") + else: + print("LAZY") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stderr: {result.stderr}") + self.assertIn("EAGER", result.stdout) + + +class AdditionalSyntaxRestrictionTests(unittest.TestCase): + """Additional syntax restriction tests per PEP 810.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_lazy_import_inside_class_raises_syntax_error(self): + """lazy import inside class body should raise SyntaxError.""" + # PEP 810: "The soft keyword is only allowed at the global (module) level, + # not inside functions, class bodies, try blocks, or import *" + with self.assertRaises(SyntaxError): + import test.test_import.data.lazy_imports.lazy_class_body + + +class MixedLazyEagerImportTests(unittest.TestCase): + """Tests for mixing lazy and eager imports of the same module. + + PEP 810: "If module foo is imported both lazily and eagerly in the same + program, the eager import takes precedence and both bindings resolve to + the same module object." + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_eager_import_before_lazy_resolves_to_same_module(self): + """Eager import before lazy should make lazy resolve to same module.""" + code = textwrap.dedent(""" + import sys + import json # Eager import first + + lazy import json as lazy_json # Lazy import same module + + # lazy_json should resolve to the same object + assert json is lazy_json, "Lazy and eager imports should resolve to same module" + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_lazy_import_before_eager_resolves_to_same_module(self): + """Lazy import followed by eager should both point to same module.""" + code = textwrap.dedent(""" + import sys + + lazy import json as lazy_json + + # Lazy not loaded yet + assert 'json' not in sys.modules + + import json # Eager import triggers load + + # Both should be the same object + assert json is lazy_json + print("OK") + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class RelativeImportTests(unittest.TestCase): + """Tests for relative imports with lazy keyword.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_relative_lazy_import(self): + """lazy from . import submodule should work.""" + from test.test_import.data.lazy_imports import relative_lazy + + # basic2 should not be loaded yet + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + # Access triggers reification + result = relative_lazy.get_basic2() + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + def test_relative_lazy_from_import(self): + """lazy from .module import name should work.""" + from test.test_import.data.lazy_imports import relative_lazy_from + + # basic2 should not be loaded yet + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + # Access triggers reification + result = relative_lazy_from.get_x() + self.assertEqual(result, 42) + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class LazyModulesCompatibilityFromImportTests(unittest.TestCase): + """Tests for __lazy_modules__ with from imports. + + PEP 810: "When a module is made lazy this way, from-imports using that + module are also lazy" + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_lazy_modules_makes_from_imports_lazy(self): + """__lazy_modules__ should make from imports of listed modules lazy.""" + from test.test_import.data.lazy_imports import lazy_compat_from + + # basic2 should not be loaded yet because it's in __lazy_modules__ + self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + # Access triggers reification + result = lazy_compat_from.get_x() + self.assertEqual(result, 42) + self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + + +class ImportStateAtReificationTests(unittest.TestCase): + """Tests for import system state at reification time. + + PEP 810: "Reification still calls __import__ to resolve the import, which uses + the state of the import system (e.g. sys.path, sys.meta_path, sys.path_hooks + and __import__) at reification time, not the state when the lazy import + statement was evaluated." + """ + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_sys_path_at_reification_time_is_used(self): + """sys.path changes after lazy import should affect reification.""" + code = textwrap.dedent(""" + import sys + import tempfile + import os + + # Create a temporary module + with tempfile.TemporaryDirectory() as tmpdir: + mod_path = os.path.join(tmpdir, "dynamic_test_module.py") + with open(mod_path, "w") as f: + f.write("VALUE = 'from_temp_dir'\\n") + + # Lazy import before adding to path + lazy import dynamic_test_module + + # Module cannot be found yet + try: + _ = dynamic_test_module + print("FAIL - should not find module") + except ModuleNotFoundError: + pass + + # Now add temp dir to path + sys.path.insert(0, tmpdir) + + # Now reification should succeed using current sys.path + assert dynamic_test_module.VALUE == 'from_temp_dir' + print("OK") + + sys.path.remove(tmpdir) + """) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class ThreadSafetyTests(unittest.TestCase): + """Tests for thread-safety of lazy imports.""" + + def tearDown(self): + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.lazy_imports'): + del sys.modules[key] + + sys.set_lazy_imports_filter(None) + sys.set_lazy_imports("normal") + + def test_concurrent_lazy_import_reification(self): + """Multiple threads racing to reify the same lazy import should succeed.""" + from test.test_import.data.lazy_imports import basic_unused + + num_threads = 10 + results = [None] * num_threads + errors = [] + barrier = threading.Barrier(num_threads) + + def access_lazy_import(idx): + try: + barrier.wait() + module = basic_unused.test.test_import.data.lazy_imports.basic2 + results[idx] = module + except Exception as e: + errors.append((idx, e)) + + threads = [ + threading.Thread(target=access_lazy_import, args=(i,)) + for i in range(num_threads) + ] + + for t in threads: + t.start() + for t in threads: + t.join() + + self.assertEqual(errors, [], f"Errors occurred: {errors}") + self.assertTrue(all(r is not None for r in results)) + first_module = results[0] + for r in results[1:]: + self.assertIs(r, first_module) + + def test_concurrent_reification_multiple_modules(self): + """Multiple threads reifying different lazy imports concurrently.""" + code = textwrap.dedent(""" + import sys + import threading + + sys.set_lazy_imports("all") + + lazy import json + lazy import os + lazy import io + lazy import re + + num_threads = 8 + results = {} + errors = [] + barrier = threading.Barrier(num_threads) + + def access_modules(idx): + try: + barrier.wait() + mods = [json, os, io, re] + results[idx] = [type(m).__name__ for m in mods] + except Exception as e: + errors.append((idx, e)) + + threads = [ + threading.Thread(target=access_modules, args=(i,)) + for i in range(num_threads) + ] + + for t in threads: + t.start() + for t in threads: + t.join() + + assert not errors, f"Errors: {errors}" + for idx, mods in results.items(): + assert all(m == 'module' for m in mods), f"Thread {idx} got: {mods}" + + print("OK") + """) + + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_concurrent_lazy_modules_set_updates(self): + """Multiple threads creating lazy imports should safely update sys.lazy_modules.""" + code = textwrap.dedent(""" + import sys + import threading + + num_threads = 16 + iterations = 50 + errors = [] + barrier = threading.Barrier(num_threads) + + def create_lazy_imports(idx): + try: + barrier.wait() + for i in range(iterations): + exec(f"lazy import json as json_{idx}_{i}", globals()) + exec(f"lazy import os as os_{idx}_{i}", globals()) + except Exception as e: + errors.append((idx, e)) + + threads = [ + threading.Thread(target=create_lazy_imports, args=(i,)) + for i in range(num_threads) + ] + + for t in threads: + t.start() + for t in threads: + t.join() + + assert not errors, f"Errors: {errors}" + assert isinstance(sys.lazy_modules, dict), "sys.lazy_modules is not a dict" + print("OK") + """) + + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_concurrent_reification_same_module_high_contention(self): + """High contention: many threads reifying the exact same lazy import.""" + code = textwrap.dedent(""" + import sys + import threading + import types + + sys.set_lazy_imports("all") + + lazy import json + + num_threads = 20 + results = [None] * num_threads + errors = [] + barrier = threading.Barrier(num_threads) + + def access_json(idx): + try: + barrier.wait() + for _ in range(100): + _ = json.dumps + _ = json.loads + results[idx] = json + except Exception as e: + errors.append((idx, e)) + + threads = [ + threading.Thread(target=access_json, args=(i,)) + for i in range(num_threads) + ] + + for t in threads: + t.start() + for t in threads: + t.join() + + assert not errors, f"Errors: {errors}" + assert all(r is not None for r in results), "Some threads got None" + first = results[0] + assert all(r is first for r in results), "Inconsistent module objects" + assert not isinstance(first, types.LazyImportType), "Got lazy import instead of module" + print("OK") + """) + + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + def test_concurrent_reification_with_module_attribute_access(self): + """Threads racing to reify and immediately access module attributes.""" + code = textwrap.dedent(""" + import sys + import threading + + sys.set_lazy_imports("all") + + lazy import collections + lazy import functools + lazy import itertools + + num_threads = 12 + results = {} + errors = [] + barrier = threading.Barrier(num_threads) + + def stress_lazy_imports(idx): + try: + barrier.wait() + for _ in range(50): + _ = collections.OrderedDict + _ = functools.partial + _ = itertools.chain + _ = collections.defaultdict + _ = functools.lru_cache + _ = itertools.islice + results[idx] = ( + type(collections).__name__, + type(functools).__name__, + type(itertools).__name__, + ) + except Exception as e: + errors.append((idx, e)) + + threads = [ + threading.Thread(target=stress_lazy_imports, args=(i,)) + for i in range(num_threads) + ] + + for t in threads: + t.start() + for t in threads: + t.join() + + assert not errors, f"Errors: {errors}" + for idx, types_tuple in results.items(): + assert all(t == 'module' for t in types_tuple), f"Thread {idx}: {types_tuple}" + print("OK") + """) + + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + text=True + ) + self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") + self.assertIn("OK", result.stdout) + + +class LazyImportDisTests(unittest.TestCase): + def test_lazy_import_dis(self): + """dis should properly show lazy import""" + code = compile("lazy import foo", "exec", "exec") + f = io.StringIO() + dis.dis(code, file=f) + self.assertIn("foo + lazy", f.getvalue()) + + def test_normal_import_dis(self): + """non lazy imports should just show the name""" + code = compile("import foo", "exec", "exec") + f = io.StringIO() + dis.dis(code, file=f) + for line in f.getvalue().split('\n'): + if "IMPORT_NAME" in line: + self.assertIn("(foo)", line) + break + else: + self.assertFail("IMPORT_NAME not found") + + +@unittest.skipIf(_testcapi is None, 'need the _testcapi module') +class LazyCApiTests(unittest.TestCase): + def tearDown(self): + sys.set_lazy_imports("normal") + sys.set_lazy_imports_filter(None) + + def test_set_matches_sys(self): + self.assertEqual(_testcapi.PyImport_GetLazyImportsMode(), sys.get_lazy_imports()) + for mode in ("normal", "all", "none"): + _testcapi.PyImport_SetLazyImportsMode(mode) + self.assertEqual(_testcapi.PyImport_GetLazyImportsMode(), sys.get_lazy_imports()) + + def test_filter_matches_sys(self): + self.assertEqual(_testcapi.PyImport_GetLazyImportsFilter(), sys.get_lazy_imports_filter()) + + def filter(*args): + pass + + _testcapi.PyImport_SetLazyImportsFilter(filter) + self.assertEqual(_testcapi.PyImport_GetLazyImportsFilter(), sys.get_lazy_imports_filter()) + + def test_set_bad_filter(self): + self.assertRaises(ValueError, _testcapi.PyImport_SetLazyImportsFilter, 42) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_pyrepl/test_utils.py b/Lib/test/test_pyrepl/test_utils.py index 656a1e441e0e47..3c55b6bdaeee9e 100644 --- a/Lib/test/test_pyrepl/test_utils.py +++ b/Lib/test/test_pyrepl/test_utils.py @@ -89,10 +89,42 @@ def test_gen_colors_keyword_highlighting(self): ("obj.list", [(".", "op")]), ("obj.match", [(".", "op")]), ("b. \\\n format", [(".", "op")]), + ("lazy", []), + ("lazy()", [('(', 'op'), (')', 'op')]), # highlights ("set", [("set", "builtin")]), ("list", [("list", "builtin")]), (" \n dict", [("dict", "builtin")]), + ( + " lazy import", + [("lazy", "soft_keyword"), ("import", "keyword")], + ), + ( + "lazy from cool_people import pablo", + [ + ("lazy", "soft_keyword"), + ("from", "keyword"), + ("import", "keyword"), + ], + ), + ( + "if sad: lazy import happy", + [ + ("if", "keyword"), + (":", "op"), + ("lazy", "soft_keyword"), + ("import", "keyword"), + ], + ), + ( + "pass; lazy import z", + [ + ("pass", "keyword"), + (";", "op"), + ("lazy", "soft_keyword"), + ("import", "keyword"), + ], + ), ] for code, expected_highlights in cases: with self.subTest(code=code): diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 93f0b98de71d81..19427f2469ec43 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -3475,6 +3475,128 @@ def test_ifexp_body_stmt_else_stmt(self): ]: self._check_error(f"x = {lhs_stmt} if 1 else {rhs_stmt}", msg) + +class LazyImportRestrictionTestCase(SyntaxErrorTestCase): + """Test syntax restrictions for lazy imports.""" + + def test_lazy_import_in_try_block(self): + """Test that lazy imports are not allowed inside try blocks.""" + self._check_error("""\ +try: + lazy import os +except: + pass +""", "lazy import not allowed inside try/except blocks") + + self._check_error("""\ +try: + lazy from sys import path +except ImportError: + pass +""", "lazy from ... import not allowed inside try/except blocks") + + def test_lazy_import_in_trystar_block(self): + """Test that lazy imports are not allowed inside try* blocks.""" + self._check_error("""\ +try: + lazy import json +except* Exception: + pass +""", "lazy import not allowed inside try/except blocks") + + self._check_error("""\ +try: + lazy from collections import defaultdict +except* ImportError: + pass +""", "lazy from ... import not allowed inside try/except blocks") + + def test_lazy_import_in_except_block(self): + """Test that lazy imports are not allowed inside except blocks.""" + self._check_error("""\ +try: + sys.modules # trigger the except block +except* Exception: + lazy import sys +""", "lazy import not allowed inside try/except blocks") + + def test_lazy_import_in_function(self): + """Test that lazy imports are not allowed inside functions.""" + self._check_error("""\ +def func(): + lazy import math +""", "lazy import not allowed inside functions") + + self._check_error("""\ +def func(): + lazy from datetime import datetime +""", "lazy from ... import not allowed inside functions") + + def test_lazy_import_in_async_function(self): + """Test that lazy imports are not allowed inside async functions.""" + self._check_error("""\ +async def async_func(): + lazy import asyncio +""", "lazy import not allowed inside functions") + + self._check_error("""\ +async def async_func(): + lazy from json import loads +""", "lazy from ... import not allowed inside functions") + + def test_lazy_import_in_class(self): + """Test that lazy imports are not allowed inside classes.""" + self._check_error("""\ +class MyClass: + lazy import typing +""", "lazy import not allowed inside classes") + + self._check_error("""\ +class MyClass: + lazy from abc import ABC +""", "lazy from ... import not allowed inside classes") + + def test_lazy_import_star_forbidden(self): + """Test that 'lazy from ... import *' is forbidden everywhere.""" + # At module level should also be forbidden + self._check_error("lazy from os import *", + "lazy from ... import \\* is not allowed") + + # Inside function should give lazy function error first + self._check_error("""\ +def func(): + lazy from sys import * +""", "lazy from ... import not allowed inside functions") + + def test_lazy_import_nested_scopes(self): + """Test lazy imports in nested scopes.""" + self._check_error("""\ +class Outer: + def method(self): + lazy import sys +""", "lazy import not allowed inside functions") + + self._check_error("""\ +def outer(): + class Inner: + lazy import json +""", "lazy import not allowed inside classes") + + self._check_error("""\ +def outer(): + def inner(): + lazy from collections import deque +""", "lazy from ... import not allowed inside functions") + + def test_lazy_import_valid_cases(self): + """Test that lazy imports work at module level.""" + # These should compile without errors + compile("lazy import os", "", "exec") + compile("lazy from sys import path", "", "exec") + compile("lazy import json as j", "", "exec") + compile("lazy from datetime import datetime as dt", "", "exec") + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) return tests diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index b44e0c9779aa59..8974361c2537d2 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -865,7 +865,8 @@ def test_sys_flags(self): "dont_write_bytecode", "no_user_site", "no_site", "ignore_environment", "verbose", "bytes_warning", "quiet", "hash_randomization", "isolated", "dev_mode", "utf8_mode", - "warn_default_encoding", "safe_path", "int_max_str_digits") + "warn_default_encoding", "safe_path", "int_max_str_digits", + "lazy_imports") for attr in attrs: self.assertHasAttr(sys.flags, attr) attr_type = bool if attr in ("dev_mode", "safe_path") else int diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index a4a49fd44bb2e0..eaca62b12d3eb1 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -5319,5 +5319,47 @@ def expected(t, m, fn, l, f, E, e, z): ] self.assertEqual(actual, expected(**colors)) + +class TestLazyImportSuggestions(unittest.TestCase): + """Test that lazy imports are not reified when computing AttributeError suggestions.""" + + def test_attribute_error_does_not_reify_lazy_imports(self): + """Printing an AttributeError should not trigger lazy import reification.""" + # pkg.bar prints "BAR_MODULE_LOADED" when imported. + # If lazy import is reified during suggestion computation, we'll see it. + code = textwrap.dedent(""" + lazy import test.test_import.data.lazy_imports.pkg.bar + test.test_import.data.lazy_imports.pkg.nonexistent + """) + rc, stdout, stderr = assert_python_failure('-c', code) + self.assertNotIn(b"BAR_MODULE_LOADED", stdout) + + def test_traceback_formatting_does_not_reify_lazy_imports(self): + """Formatting a traceback should not trigger lazy import reification.""" + code = textwrap.dedent(""" + import traceback + lazy import test.test_import.data.lazy_imports.pkg.bar + try: + test.test_import.data.lazy_imports.pkg.nonexistent + except AttributeError: + traceback.format_exc() + print("OK") + """) + rc, stdout, stderr = assert_python_ok('-c', code) + self.assertIn(b"OK", stdout) + self.assertNotIn(b"BAR_MODULE_LOADED", stdout) + + def test_suggestion_still_works_for_non_lazy_attributes(self): + """Suggestions should still work for non-lazy module attributes.""" + code = textwrap.dedent(""" + lazy import test.test_import.data.lazy_imports.pkg.bar + # Typo for __name__ + test.test_import.data.lazy_imports.pkg.__nme__ + """) + rc, stdout, stderr = assert_python_failure('-c', code) + self.assertIn(b"__name__", stderr) + self.assertNotIn(b"BAR_MODULE_LOADED", stdout) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index b0d2348c0e1cba..39d57c5f5b61c9 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -41,7 +41,7 @@ def clear_typing_caches(): class TypesTests(unittest.TestCase): def test_names(self): - c_only_names = {'CapsuleType'} + c_only_names = {'CapsuleType', 'LazyImportType'} ignored = {'new_class', 'resolve_bases', 'prepare_class', 'get_original_bases', 'DynamicClassAttribute', 'coroutine'} @@ -55,10 +55,11 @@ def test_names(self): 'CoroutineType', 'EllipsisType', 'FrameType', 'FunctionType', 'FrameLocalsProxyType', 'GeneratorType', 'GenericAlias', 'GetSetDescriptorType', - 'LambdaType', 'MappingProxyType', 'MemberDescriptorType', - 'MethodDescriptorType', 'MethodType', 'MethodWrapperType', - 'ModuleType', 'NoneType', 'NotImplementedType', 'SimpleNamespace', - 'TracebackType', 'UnionType', 'WrapperDescriptorType', + 'LambdaType', 'LazyImportType', 'MappingProxyType', + 'MemberDescriptorType', 'MethodDescriptorType', 'MethodType', + 'MethodWrapperType', 'ModuleType', 'NoneType', + 'NotImplementedType', 'SimpleNamespace', 'TracebackType', + 'UnionType', 'WrapperDescriptorType', } self.assertEqual(all_names, set(c_types.__all__)) self.assertEqual(all_names - c_only_names, set(py_types.__all__)) diff --git a/Lib/traceback.py b/Lib/traceback.py index 97d83f3ddd3297..b121733c27fd8c 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -5,6 +5,7 @@ import linecache import sys import textwrap +import types import warnings import codeop import keyword @@ -1629,12 +1630,29 @@ def _substitution_cost(ch_a, ch_b): return _MOVE_COST +def _is_lazy_import(obj, attr_name): + """Check if attr_name in obj's __dict__ is a lazy import. + + Returns True if obj is a module and the attribute is a LazyImportType, + False otherwise. This avoids triggering module loading when computing + suggestions for AttributeError. + """ + if not isinstance(obj, types.ModuleType): + return False + obj_dict = getattr(obj, '__dict__', None) + if obj_dict is None: + return False + attr_value = obj_dict.get(attr_name) + return isinstance(attr_value, types.LazyImportType) + + def _check_for_nested_attribute(obj, wrong_name, attrs): """Check if any attribute of obj has the wrong_name as a nested attribute. Returns the first nested attribute suggestion found, or None. Limited to checking 20 attributes. Only considers non-descriptor attributes to avoid executing arbitrary code. + Skips lazy imports to avoid triggering module loading. """ # Check for nested attributes (only one level deep) attrs_to_check = [x for x in attrs if not x.startswith('_')][:20] # Limit number of attributes to check @@ -1645,6 +1663,10 @@ def _check_for_nested_attribute(obj, wrong_name, attrs): if attr_from_class is not None and hasattr(attr_from_class, '__get__'): continue # Skip descriptors to avoid executing arbitrary code + # Skip lazy imports to avoid triggering module loading + if _is_lazy_import(obj, attr_name): + continue + # Safe to get the attribute since it's not a descriptor attr_obj = getattr(obj, attr_name) @@ -1675,6 +1697,8 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): except TypeError: # Attributes are unsortable, e.g. int and str d = list(obj.__class__.__dict__.keys()) + list(obj.__dict__.keys()) d = sorted([x for x in d if isinstance(x, str)]) + # Filter out lazy imports to avoid triggering module loading + d = [x for x in d if not _is_lazy_import(obj, x)] hide_underscored = (wrong_name[:1] != '_') if hide_underscored and tb is not None: while tb.tb_next is not None: @@ -1694,6 +1718,8 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): except TypeError: # Attributes are unsortable, e.g. int and str d = list(mod.__dict__.keys()) d = sorted([x for x in d if isinstance(x, str)]) + # Filter out lazy imports to avoid triggering module loading + d = [x for x in d if not _is_lazy_import(mod, x)] if wrong_name[:1] != '_': d = [x for x in d if x[:1] != '_'] except Exception: diff --git a/Lib/types.py b/Lib/types.py index 99f23c3f44270f..b4f9a5c5140860 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -76,6 +76,9 @@ def _m(self): pass # CapsuleType cannot be accessed from pure Python, # so there is no fallback definition. + # LazyImportType in pure Python cannot be guaranteed + # without overriding the filter, so there is no fallback. + del sys, _f, _g, _C, _c, _ag, _cell_factory # Not for export diff --git a/Makefile.pre.in b/Makefile.pre.in index d27e3301666868..f4119abf324fca 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -539,6 +539,7 @@ OBJECT_OBJS= \ Objects/funcobject.o \ Objects/interpolationobject.o \ Objects/iterobject.o \ + Objects/lazyimportobject.o \ Objects/listobject.o \ Objects/longobject.o \ Objects/dictobject.o \ @@ -1372,6 +1373,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_interpolation.h \ $(srcdir)/Include/internal/pycore_intrinsics.h \ $(srcdir)/Include/internal/pycore_jit.h \ + $(srcdir)/Include/internal/pycore_lazyimportobject.h \ $(srcdir)/Include/internal/pycore_list.h \ $(srcdir)/Include/internal/pycore_llist.h \ $(srcdir)/Include/internal/pycore_lock.h \ @@ -2676,6 +2678,8 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_import/data/package3 \ test/test_import/data/package4 \ test/test_import/data/unwritable \ + test/test_import/data/lazy_imports \ + test/test_import/data/lazy_imports/pkg \ test/test_importlib \ test/test_importlib/builtin \ test/test_importlib/extension \ diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst new file mode 100644 index 00000000000000..73cc167fd04013 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst @@ -0,0 +1 @@ +Implement :pep:`810`. Patch by Pablo Galindo and Dino Viehland. diff --git a/Modules/_testcapi/import.c b/Modules/_testcapi/import.c index 27d37498f3cd83..ebb1032fdd1c32 100644 --- a/Modules/_testcapi/import.c +++ b/Modules/_testcapi/import.c @@ -30,9 +30,75 @@ pyimport_importmoduleattrstring(PyObject *self, PyObject *args) } +static PyObject * +pyimport_setlazyimportsmode(PyObject *self, PyObject *args) +{ + PyObject *mode; + if (!PyArg_ParseTuple(args, "U", &mode)) { + return NULL; + } + if (strcmp(PyUnicode_AsUTF8(mode), "normal") == 0) { + PyImport_SetLazyImportsMode(PyImport_LAZY_NORMAL); + } else if (strcmp(PyUnicode_AsUTF8(mode), "all") == 0) { + PyImport_SetLazyImportsMode(PyImport_LAZY_ALL); + } else if (strcmp(PyUnicode_AsUTF8(mode), "none") == 0) { + PyImport_SetLazyImportsMode(PyImport_LAZY_NONE); + } else { + PyErr_SetString(PyExc_ValueError, "invalid mode"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +pyimport_getlazyimportsmode(PyObject *self, PyObject *args) +{ + switch (PyImport_GetLazyImportsMode()) { + case PyImport_LAZY_NORMAL: + return PyUnicode_FromString("normal"); + case PyImport_LAZY_ALL: + return PyUnicode_FromString("all"); + case PyImport_LAZY_NONE: + return PyUnicode_FromString("none"); + default: + PyErr_SetString(PyExc_ValueError, "unknown mode"); + return NULL; + } +} + +static PyObject * +pyimport_setlazyimportsfilter(PyObject *self, PyObject *args) +{ + PyObject *filter; + if (!PyArg_ParseTuple(args, "O", &filter)) { + return NULL; + } + + if (PyImport_SetLazyImportsFilter(filter) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +pyimport_getlazyimportsfilter(PyObject *self, PyObject *args) +{ + PyObject *res = PyImport_GetLazyImportsFilter(); + if (res == NULL) { + Py_RETURN_NONE; + } + return res; +} + static PyMethodDef test_methods[] = { {"PyImport_ImportModuleAttr", pyimport_importmoduleattr, METH_VARARGS}, {"PyImport_ImportModuleAttrString", pyimport_importmoduleattrstring, METH_VARARGS}, + {"PyImport_SetLazyImportsMode", pyimport_setlazyimportsmode, METH_VARARGS}, + {"PyImport_GetLazyImportsMode", pyimport_getlazyimportsmode, METH_NOARGS}, + {"PyImport_SetLazyImportsFilter", pyimport_setlazyimportsfilter, METH_VARARGS}, + {"PyImport_GetLazyImportsFilter", pyimport_getlazyimportsfilter, METH_NOARGS}, {NULL}, }; @@ -41,4 +107,3 @@ _PyTestCapi_Init_Import(PyObject *m) { return PyModule_AddFunctions(m, test_methods); } - diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 35b1bc4e17c5d5..ddd8fcdc231bf1 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -6371,9 +6371,19 @@ _PyStackRef res; from = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyEval_ImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyObject *res_o; + if (PyLazyImport_CheckExact(PyStackRef_AsPyObjectBorrow(from))) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_LazyImportFrom( + tstate, frame, PyStackRef_AsPyObjectBorrow(from), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_ImportFrom( + tstate, PyStackRef_AsPyObjectBorrow(from), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + } if (res_o == NULL) { JUMP_TO_LABEL(error); } @@ -6397,11 +6407,26 @@ _PyStackRef res; fromlist = stack_pointer[-1]; level = stack_pointer[-2]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + PyObject *res_o; + if (!(oparg & 0x02)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_LazyImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level), + oparg & 0x01); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_ImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level)); + stack_pointer = _PyFrame_GetStackPointer(frame); + } _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyEval_ImportName(tstate, frame, name, - PyStackRef_AsPyObjectBorrow(fromlist), - PyStackRef_AsPyObjectBorrow(level)); _PyStackRef tmp = fromlist; fromlist = PyStackRef_NULL; stack_pointer[-1] = fromlist; @@ -9156,6 +9181,15 @@ } JUMP_TO_LABEL(error); } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (v_o == NULL) { + JUMP_TO_LABEL(error); + } + } } else { _PyFrame_SetStackPointer(frame, stack_pointer); @@ -9180,6 +9214,15 @@ JUMP_TO_LABEL(error); } } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (v_o == NULL) { + JUMP_TO_LABEL(error); + } + } } } v = PyStackRef_FromPyObjectSteal(v_o); @@ -9432,6 +9475,30 @@ if (v_o == NULL) { JUMP_TO_LABEL(error); } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (l_v == NULL) { + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(v_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + JUMP_TO_LABEL(error); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = PyDict_SetItem(GLOBALS(), name, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(v_o); + Py_DECREF(l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + JUMP_TO_LABEL(error); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + } v = PyStackRef_FromPyObjectSteal(v_o); stack_pointer[0] = v; stack_pointer += 1; diff --git a/Modules/_typesmodule.c b/Modules/_typesmodule.c index df6b4c93cb87a6..6c9e7a0a3ba053 100644 --- a/Modules/_typesmodule.c +++ b/Modules/_typesmodule.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_descrobject.h" // _PyMethodWrapper_Type +#include "pycore_lazyimportobject.h" // PyLazyImport_Type #include "pycore_namespace.h" // _PyNamespace_Type #include "pycore_object.h" // _PyNone_Type, _PyNotImplemented_Type #include "pycore_unionobject.h" // _PyUnion_Type @@ -35,6 +36,7 @@ _types_exec(PyObject *m) EXPORT_STATIC_TYPE("GetSetDescriptorType", PyGetSetDescr_Type); // LambdaType is the same as FunctionType EXPORT_STATIC_TYPE("LambdaType", PyFunction_Type); + EXPORT_STATIC_TYPE("LazyImportType", PyLazyImport_Type); EXPORT_STATIC_TYPE("MappingProxyType", PyDictProxy_Type); EXPORT_STATIC_TYPE("MemberDescriptorType", PyMemberDescr_Type); EXPORT_STATIC_TYPE("MethodDescriptorType", PyMethodDescr_Type); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index c1584be3f0ed4a..ae7bf61767dc3b 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4693,6 +4693,14 @@ _PyDict_SizeOf_LockHeld(PyDictObject *mp) return (Py_ssize_t)res; } +void +_PyDict_ClearKeysVersionLockHeld(PyObject *mp) +{ + ASSERT_DICT_LOCKED(mp); + + FT_ATOMIC_STORE_UINT32_RELAXED(((PyDictObject *)mp)->ma_keys->dk_version, 0); +} + Py_ssize_t _PyDict_SizeOf(PyDictObject *mp) { @@ -7655,8 +7663,8 @@ PyDict_AddWatcher(PyDict_WatchCallback callback) { PyInterpreterState *interp = _PyInterpreterState_GET(); - /* Start at 2, as 0 and 1 are reserved for CPython */ - for (int i = 2; i < DICT_MAX_WATCHERS; i++) { + /* Some watchers are reserved for CPython, start at the first available one */ + for (int i = FIRST_AVAILABLE_WATCHER; i < DICT_MAX_WATCHERS; i++) { if (!interp->dict_state.watchers[i]) { interp->dict_state.watchers[i] = callback; return i; diff --git a/Objects/exceptions.c b/Objects/exceptions.c index ca6f323ac11fbc..499fb2b34b34a8 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2014,6 +2014,12 @@ static PyTypeObject _PyExc_ImportError = { }; PyObject *PyExc_ImportError = (PyObject *)&_PyExc_ImportError; +/* + * ImportCycleError extends ImportError + */ + +MiddlingExtendsException(PyExc_ImportError, ImportCycleError, ImportError, + "Import produces a cycle."); /* * ModuleNotFoundError extends ImportError */ @@ -4454,6 +4460,7 @@ static struct static_exception static_exceptions[] = { {&_PyExc_IncompleteInputError, "_IncompleteInputError"}, // base: SyntaxError(Exception) ITEM(IndexError), // base: LookupError(Exception) ITEM(KeyError), // base: LookupError(Exception) + ITEM(ImportCycleError), // base: ImportError(Exception) ITEM(ModuleNotFoundError), // base: ImportError(Exception) ITEM(NotImplementedError), // base: RuntimeError(Exception) ITEM(PythonFinalizationError), // base: RuntimeError(Exception) @@ -4643,4 +4650,3 @@ _PyException_AddNote(PyObject *exc, PyObject *note) Py_XDECREF(r); return res; } - diff --git a/Objects/lazyimportobject.c b/Objects/lazyimportobject.c new file mode 100644 index 00000000000000..451f335e033f16 --- /dev/null +++ b/Objects/lazyimportobject.c @@ -0,0 +1,157 @@ +// Lazy object implementation. + +#include "Python.h" +#include "pycore_ceval.h" +#include "pycore_frame.h" +#include "pycore_import.h" +#include "pycore_interpframe.h" +#include "pycore_lazyimportobject.h" +#include "pycore_modsupport.h" + +#define PyLazyImportObject_CAST(op) ((PyLazyImportObject *)(op)) + +PyObject * +_PyLazyImport_New(_PyInterpreterFrame *frame, PyObject *builtins, PyObject *name, PyObject *fromlist) +{ + PyLazyImportObject *m; + if (!name || !PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, "expected str for name"); + return NULL; + } + if (fromlist == Py_None || fromlist == NULL) { + fromlist = NULL; + } + else if (!PyUnicode_Check(fromlist) && !PyTuple_Check(fromlist)) { + PyErr_SetString(PyExc_TypeError, + "lazy_import: fromlist must be None, a string, or a tuple"); + return NULL; + } + m = PyObject_GC_New(PyLazyImportObject, &PyLazyImport_Type); + if (m == NULL) { + return NULL; + } + m->lz_builtins = Py_XNewRef(builtins); + m->lz_from = Py_NewRef(name); + m->lz_attr = Py_XNewRef(fromlist); + + // Capture frame information for the original import location. + m->lz_code = NULL; + m->lz_instr_offset = -1; + + if (frame != NULL) { + PyCodeObject *code = _PyFrame_GetCode(frame); + if (code != NULL) { + m->lz_code = (PyCodeObject *)Py_NewRef(code); + // Calculate the instruction offset from the current frame. + m->lz_instr_offset = _PyInterpreterFrame_LASTI(frame); + } + } + + _PyObject_GC_TRACK(m); + return (PyObject *)m; +} + +static int +lazy_import_traverse(PyObject *op, visitproc visit, void *arg) +{ + PyLazyImportObject *m = PyLazyImportObject_CAST(op); + Py_VISIT(m->lz_builtins); + Py_VISIT(m->lz_from); + Py_VISIT(m->lz_attr); + Py_VISIT(m->lz_code); + return 0; +} + +static int +lazy_import_clear(PyObject *op) +{ + PyLazyImportObject *m = PyLazyImportObject_CAST(op); + Py_CLEAR(m->lz_builtins); + Py_CLEAR(m->lz_from); + Py_CLEAR(m->lz_attr); + Py_CLEAR(m->lz_code); + return 0; +} + +static void +lazy_import_dealloc(PyObject *op) +{ + _PyObject_GC_UNTRACK(op); + (void)lazy_import_clear(op); + Py_TYPE(op)->tp_free(op); +} + +static PyObject * +lazy_import_name(PyLazyImportObject *m) +{ + if (m->lz_attr != NULL) { + if (PyUnicode_Check(m->lz_attr)) { + return PyUnicode_FromFormat("%U.%U", m->lz_from, m->lz_attr); + } + else { + return PyUnicode_FromFormat("%U...", m->lz_from); + } + } + return Py_NewRef(m->lz_from); +} + +static PyObject * +lazy_import_repr(PyObject *op) +{ + PyLazyImportObject *m = PyLazyImportObject_CAST(op); + PyObject *name = lazy_import_name(m); + if (name == NULL) { + return NULL; + } + PyObject *res = PyUnicode_FromFormat("<%T '%U'>", op, name); + Py_DECREF(name); + return res; +} + +PyObject * +_PyLazyImport_GetName(PyObject *op) +{ + PyLazyImportObject *lazy_import = PyLazyImportObject_CAST(op); + assert(PyLazyImport_CheckExact(lazy_import)); + return lazy_import_name(lazy_import); +} + +static PyObject * +lazy_import_resolve(PyObject *self, PyObject *args) +{ + return _PyImport_LoadLazyImportTstate(PyThreadState_GET(), self); +} + +static PyMethodDef lazy_import_methods[] = { + { + "resolve", lazy_import_resolve, METH_NOARGS, + PyDoc_STR("resolves the lazy import and returns the actual object") + }, + {NULL, NULL} +}; + + +PyDoc_STRVAR(lazy_import_doc, +"lazy_import(builtins, name, fromlist=None, /)\n" +"--\n" +"\n" +"Represents a deferred import that will be resolved on first use.\n" +"\n" +"Instances of this object accessed from the global scope will be\n" +"automatically imported based upon their name and then replaced with\n" +"the imported value."); + +PyTypeObject PyLazyImport_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "lazy_import", + .tp_basicsize = sizeof(PyLazyImportObject), + .tp_dealloc = lazy_import_dealloc, + .tp_repr = lazy_import_repr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_doc = lazy_import_doc, + .tp_traverse = lazy_import_traverse, + .tp_clear = lazy_import_clear, + .tp_methods = lazy_import_methods, + .tp_alloc = PyType_GenericAlloc, + .tp_free = PyObject_GC_Del, +}; diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index b72700770281fb..e3868097c0ba9f 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -7,6 +7,7 @@ #include "pycore_fileutils.h" // _Py_wgetcwd #include "pycore_import.h" // _PyImport_GetNextModuleIndex() #include "pycore_interp.h" // PyInterpreterState.importlib +#include "pycore_lazyimportobject.h" // _PyLazyImportObject_Check() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyModule_CreateInitialized() #include "pycore_moduleobject.h" // _PyModule_GetDefOrNull() @@ -18,7 +19,6 @@ #include "osdefs.h" // MAXPATHLEN - #define _PyModule_CAST(op) \ (assert(PyModule_Check(op)), _Py_CAST(PyModuleObject*, (op))) @@ -195,11 +195,40 @@ new_module_notrack(PyTypeObject *mt) return m; } +/* Module dict watcher callback. + * When a module dictionary is modified, we need to clear the keys version + * to invalidate any cached lookups that depend on the dictionary structure. + */ +static int +module_dict_watcher(PyDict_WatchEvent event, PyObject *dict, + PyObject *key, PyObject *new_value) +{ + assert(PyDict_Check(dict)); + // Only if a new lazy object shows up do we need to clear the dictionary. If + // this is adding a new key then the version will be reset anyway. + if (event == PyDict_EVENT_MODIFIED && + new_value != NULL && + PyLazyImport_CheckExact(new_value)) { + _PyDict_ClearKeysVersionLockHeld(dict); + } + return 0; +} + +int +_PyModule_InitModuleDictWatcher(PyInterpreterState *interp) +{ + // This is a reserved watcher for CPython so there's no need to check for non-NULL. + assert(interp->dict_state.watchers[MODULE_WATCHER_ID] == NULL); + interp->dict_state.watchers[MODULE_WATCHER_ID] = &module_dict_watcher; + return 0; +} + static void track_module(PyModuleObject *m) { _PyDict_EnablePerThreadRefcounting(m->md_dict); _PyObject_SetDeferredRefcount((PyObject *)m); + PyDict_Watch(MODULE_WATCHER_ID, m->md_dict); PyObject_GC_Track(m); } @@ -1308,6 +1337,28 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress) PyObject *attr, *mod_name, *getattr; attr = _PyObject_GenericGetAttrWithDict((PyObject *)m, name, NULL, suppress); if (attr) { + if (PyLazyImport_CheckExact(attr)) { + PyObject *new_value = _PyImport_LoadLazyImportTstate( + PyThreadState_GET(), attr); + if (new_value == NULL) { + if (suppress && + PyErr_ExceptionMatches(PyExc_ImportCycleError)) { + // ImportCycleError is raised when a lazy object tries + // to import itself. In this case, the error should not + // propagate to the caller and instead treated as if the + // attribute doesn't exist. + PyErr_Clear(); + } + Py_DECREF(attr); + return NULL; + } + + if (PyDict_SetItem(m->md_dict, name, new_value) < 0) { + Py_CLEAR(new_value); + } + Py_DECREF(attr); + return new_value; + } return attr; } if (suppress == 1) { @@ -1506,7 +1557,12 @@ static PyObject * module_dir(PyObject *self, PyObject *args) { PyObject *result = NULL; - PyObject *dict = PyObject_GetAttr(self, &_Py_ID(__dict__)); + PyObject *dict; + if (PyModule_CheckExact(self)) { + dict = Py_NewRef(((PyModuleObject *)self)->md_dict); + } else { + dict = PyObject_GetAttr(self, &_Py_ID(__dict__)); + } if (dict != NULL) { if (PyDict_Check(dict)) { @@ -1534,7 +1590,7 @@ static PyMethodDef module_methods[] = { }; static PyObject * -module_get_dict(PyModuleObject *m) +module_load_dict(PyModuleObject *m) { PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__)); if (dict == NULL) { @@ -1553,7 +1609,7 @@ module_get_annotate(PyObject *self, void *Py_UNUSED(ignored)) { PyModuleObject *m = _PyModule_CAST(self); - PyObject *dict = module_get_dict(m); + PyObject *dict = module_load_dict(m); if (dict == NULL) { return NULL; } @@ -1578,7 +1634,7 @@ module_set_annotate(PyObject *self, PyObject *value, void *Py_UNUSED(ignored)) return -1; } - PyObject *dict = module_get_dict(m); + PyObject *dict = module_load_dict(m); if (dict == NULL) { return -1; } @@ -1608,7 +1664,7 @@ module_get_annotations(PyObject *self, void *Py_UNUSED(ignored)) { PyModuleObject *m = _PyModule_CAST(self); - PyObject *dict = module_get_dict(m); + PyObject *dict = module_load_dict(m); if (dict == NULL) { return NULL; } @@ -1680,7 +1736,7 @@ module_set_annotations(PyObject *self, PyObject *value, void *Py_UNUSED(ignored) { PyModuleObject *m = _PyModule_CAST(self); - PyObject *dict = module_get_dict(m); + PyObject *dict = module_load_dict(m); if (dict == NULL) { return -1; } @@ -1709,7 +1765,6 @@ module_set_annotations(PyObject *self, PyObject *value, void *Py_UNUSED(ignored) return ret; } - static PyGetSetDef module_getsets[] = { {"__annotations__", module_get_annotations, module_set_annotations}, {"__annotate__", module_get_annotate, module_set_annotate}, diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 605861ad3fd06c..cb806459596084 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -146,6 +146,7 @@ + diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index c67fe53363ee84..6dcf0e8712903a 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -265,6 +265,9 @@ Source Files + + Source Files + Source Files diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 5e7e739dc5f787..5e37dd33c849f2 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -273,6 +273,7 @@ + @@ -548,6 +549,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 247f4b5a784f9c..664788e69af19a 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -735,6 +735,9 @@ Include\internal + + Include\internal + Include\internal @@ -1250,6 +1253,9 @@ Objects + + Objects + Objects diff --git a/Parser/Python.asdl b/Parser/Python.asdl index dbe226f837243c..2f0b123858f8d1 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -45,8 +45,8 @@ module Python | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) | Assert(expr test, expr? msg) - | Import(alias* names) - | ImportFrom(identifier? module, alias* names, int? level) + | Import(alias* names, int? is_lazy) + | ImportFrom(identifier? module, alias* names, int? level, int? is_lazy) | Global(identifier* names) | Nonlocal(identifier* names) diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index 50856686335a14..1f5b6220ba1baa 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -1971,10 +1971,16 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings, } stmt_ty -_PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq * names, int level, - int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) { +_PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq * names, + int level, expr_ty lazy_token, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) { if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) { + if (lazy_token) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(lazy_token, + "lazy from __future__ import is not allowed"); + return NULL; + } for (Py_ssize_t i = 0; i < asdl_seq_LEN(names); i++) { alias_ty alias = asdl_seq_GET(names, i); if (PyUnicode_CompareWithASCIIString(alias->name, "barry_as_FLUFL") == 0) { @@ -1982,7 +1988,8 @@ _PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq * na } } } - return _PyAST_ImportFrom(module, names, level, lineno, col_offset, end_lineno, end_col_offset, arena); + return _PyAST_ImportFrom(module, names, level, lazy_token ? 1 : 0, lineno, + col_offset, end_lineno, end_col_offset, arena); } asdl_stmt_seq* diff --git a/Parser/parser.c b/Parser/parser.c index b9848a865b6875..37c19c4c9020c8 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -60,8 +60,8 @@ static KeywordToken *reserved_keywords[] = { {NULL, -1}, }, (KeywordToken[]) { - {"return", 522}, {"import", 647}, + {"return", 522}, {"assert", 638}, {"global", 530}, {"except", 690}, @@ -81,6 +81,7 @@ static KeywordToken *reserved_keywords[] = { static char *soft_keywords[] = { "_", "case", + "lazy", "match", "type", NULL, @@ -1565,9 +1566,9 @@ simple_stmts_rule(Parser *p) // simple_stmt: // | assignment // | &"type" type_alias +// | &('import' | 'from' | "lazy") import_stmt // | star_expressions // | &'return' return_stmt -// | &('import' | 'from') import_stmt // | &'raise' raise_stmt // | &'pass' pass_stmt // | &'del' del_stmt @@ -1642,6 +1643,27 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&\"type\" type_alias")); } + { // &('import' | 'from' | "lazy") import_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from' | \"lazy\") import_stmt")); + stmt_ty import_stmt_var; + if ( + _PyPegen_lookahead(1, _tmp_5_rule, p) + && + (import_stmt_var = import_stmt_rule(p)) // import_stmt + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('import' | 'from' | \"lazy\") import_stmt")); + _res = import_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('import' | 'from' | \"lazy\") import_stmt")); + } { // star_expressions if (p->error_indicator) { p->level--; @@ -1696,27 +1718,6 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&'return' return_stmt")); } - { // &('import' | 'from') import_stmt - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); - stmt_ty import_stmt_var; - if ( - _PyPegen_lookahead(1, _tmp_5_rule, p) - && - (import_stmt_var = import_stmt_rule(p)) // import_stmt - ) - { - D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); - _res = import_stmt_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&('import' | 'from') import_stmt")); - } { // &'raise' raise_stmt if (p->error_indicator) { p->level--; @@ -3511,6 +3512,10 @@ import_stmt_rule(Parser *p) return NULL; } stmt_ty _res = NULL; + if (_PyPegen_is_memoized(p, import_stmt_type, &_res)) { + p->level--; + return _res; + } int _mark = p->mark; if (p->call_invalid_rules) { // invalid_import if (p->error_indicator) { @@ -3571,11 +3576,12 @@ import_stmt_rule(Parser *p) } _res = NULL; done: + _PyPegen_insert_memo(p, _mark, import_stmt_type, _res); p->level--; return _res; } -// import_name: 'import' dotted_as_names +// import_name: "lazy"? 'import' dotted_as_names static stmt_ty import_name_rule(Parser *p) { @@ -3597,21 +3603,24 @@ import_name_rule(Parser *p) 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 - { // 'import' dotted_as_names + { // "lazy"? 'import' dotted_as_names if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); + D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"lazy\"? 'import' dotted_as_names")); Token * _keyword; asdl_alias_seq* a; + void *lazy; if ( + (lazy = _PyPegen_expect_soft_keyword(p, "lazy"), !p->error_indicator) // "lazy"? + && (_keyword = _PyPegen_expect_token(p, 647)) // token='import' && (a = dotted_as_names_rule(p)) // dotted_as_names ) { - D(fprintf(stderr, "%*c+ import_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); + D(fprintf(stderr, "%*c+ import_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"lazy\"? 'import' dotted_as_names")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -3621,7 +3630,7 @@ import_name_rule(Parser *p) 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_Import ( a , EXTRA ); + _res = _PyAST_Import ( a , lazy ? 1 : 0 , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -3631,7 +3640,7 @@ import_name_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s import_name[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import' dotted_as_names")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"lazy\"? 'import' dotted_as_names")); } _res = NULL; done: @@ -3640,8 +3649,8 @@ import_name_rule(Parser *p) } // import_from: -// | 'from' (('.' | '...'))* dotted_name 'import' import_from_targets -// | 'from' (('.' | '...'))+ 'import' import_from_targets +// | "lazy"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets +// | "lazy"? 'from' (('.' | '...'))+ 'import' import_from_targets static stmt_ty import_from_rule(Parser *p) { @@ -3663,18 +3672,21 @@ import_from_rule(Parser *p) 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 - { // 'from' (('.' | '...'))* dotted_name 'import' import_from_targets + { // "lazy"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); + D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"lazy\"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); Token * _keyword; Token * _keyword_1; asdl_seq * a; expr_ty b; asdl_alias_seq* c; + void *lazy; if ( + (lazy = _PyPegen_expect_soft_keyword(p, "lazy"), !p->error_indicator) // "lazy"? + && (_keyword = _PyPegen_expect_token(p, 646)) // token='from' && (a = _loop0_17_rule(p)) // (('.' | '...'))* @@ -3686,7 +3698,7 @@ import_from_rule(Parser *p) (c = import_from_targets_rule(p)) // import_from_targets ) { - D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); + D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"lazy\"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -3696,7 +3708,7 @@ import_from_rule(Parser *p) 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 = _PyPegen_checked_future_import ( p , b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , EXTRA ); + _res = _PyPegen_checked_future_import ( p , b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , lazy , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -3706,19 +3718,22 @@ import_from_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"lazy\"? 'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); } - { // 'from' (('.' | '...'))+ 'import' import_from_targets + { // "lazy"? 'from' (('.' | '...'))+ 'import' import_from_targets if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); + D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"lazy\"? 'from' (('.' | '...'))+ 'import' import_from_targets")); Token * _keyword; Token * _keyword_1; asdl_seq * a; asdl_alias_seq* b; + void *lazy; if ( + (lazy = _PyPegen_expect_soft_keyword(p, "lazy"), !p->error_indicator) // "lazy"? + && (_keyword = _PyPegen_expect_token(p, 646)) // token='from' && (a = _loop1_18_rule(p)) // (('.' | '...'))+ @@ -3728,7 +3743,7 @@ import_from_rule(Parser *p) (b = import_from_targets_rule(p)) // import_from_targets ) { - D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); + D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"lazy\"? 'from' (('.' | '...'))+ 'import' import_from_targets")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -3738,7 +3753,7 @@ import_from_rule(Parser *p) 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_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , EXTRA ); + _res = _PyAST_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , lazy ? 1 : 0 , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -3748,7 +3763,7 @@ import_from_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s import_from[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"lazy\"? 'from' (('.' | '...'))+ 'import' import_from_targets")); } _res = NULL; done: @@ -28556,7 +28571,7 @@ _gather_4_rule(Parser *p) return _res; } -// _tmp_5: 'import' | 'from' +// _tmp_5: 'import' | 'from' | "lazy" static void * _tmp_5_rule(Parser *p) { @@ -28607,6 +28622,25 @@ _tmp_5_rule(Parser *p) D(fprintf(stderr, "%*c%s _tmp_5[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from'")); } + { // "lazy" + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"lazy\"")); + expr_ty _keyword; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "lazy")) // soft_keyword='"lazy"' + ) + { + D(fprintf(stderr, "%*c+ _tmp_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"lazy\"")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_5[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"lazy\"")); + } _res = NULL; done: p->level--; diff --git a/Parser/pegen.h b/Parser/pegen.h index be5333eb2684ae..85c9ada765d9bd 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -367,7 +367,7 @@ void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension); void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions); stmt_ty _PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq *, - int , int, int , int , int , PyArena *); + int, expr_ty, int, int, int, int, PyArena *); asdl_stmt_seq* _PyPegen_register_stmts(Parser *p, asdl_stmt_seq* stmts); stmt_ty _PyPegen_register_stmt(Parser *p, stmt_ty s); diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index dbeedb7ffe0ce6..f808544045e153 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -2,7 +2,7 @@ unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0, 0,0,0,0,0,243,184,0,0,0,128,0,94,0,82,1, - 73,0,116,0,94,0,82,1,73,1,116,1,93,2,33,0, + 73,0,116,0,94,0,82,1,73,4,116,1,93,2,33,0, 82,2,52,1,0,0,0,0,0,0,31,0,93,2,33,0, 82,3,93,0,80,6,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,52,2,0,0,0,0,0,0, diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 577adb825b070d..5d319992dcda1e 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -222,6 +222,7 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->id); Py_CLEAR(state->ifs); Py_CLEAR(state->is_async); + Py_CLEAR(state->is_lazy); Py_CLEAR(state->items); Py_CLEAR(state->iter); Py_CLEAR(state->key); @@ -327,6 +328,7 @@ static int init_identifiers(struct ast_state *state) if ((state->id = PyUnicode_InternFromString("id")) == NULL) return -1; if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return -1; if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return -1; + if ((state->is_lazy = PyUnicode_InternFromString("is_lazy")) == NULL) return -1; if ((state->items = PyUnicode_InternFromString("items")) == NULL) return -1; if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return -1; if ((state->key = PyUnicode_InternFromString("key")) == NULL) return -1; @@ -527,11 +529,13 @@ static const char * const Assert_fields[]={ }; static const char * const Import_fields[]={ "names", + "is_lazy", }; static const char * const ImportFrom_fields[]={ "module", "names", "level", + "is_lazy", }; static const char * const Global_fields[]={ "names", @@ -2254,6 +2258,21 @@ add_ast_annotations(struct ast_state *state) return 0; } } + { + PyObject *type = (PyObject *)&PyLong_Type; + type = _Py_union_type_or(type, Py_None); + cond = type != NULL; + if (!cond) { + Py_DECREF(Import_annotations); + return 0; + } + cond = PyDict_SetItemString(Import_annotations, "is_lazy", type) == 0; + Py_DECREF(type); + if (!cond) { + Py_DECREF(Import_annotations); + return 0; + } + } cond = PyObject_SetAttrString(state->Import_type, "_field_types", Import_annotations) == 0; if (!cond) { @@ -2315,6 +2334,22 @@ add_ast_annotations(struct ast_state *state) return 0; } } + { + PyObject *type = (PyObject *)&PyLong_Type; + type = _Py_union_type_or(type, Py_None); + cond = type != NULL; + if (!cond) { + Py_DECREF(ImportFrom_annotations); + return 0; + } + cond = PyDict_SetItemString(ImportFrom_annotations, "is_lazy", type) == + 0; + Py_DECREF(type); + if (!cond) { + Py_DECREF(ImportFrom_annotations); + return 0; + } + } cond = PyObject_SetAttrString(state->ImportFrom_type, "_field_types", ImportFrom_annotations) == 0; if (!cond) { @@ -6223,8 +6258,8 @@ init_types(void *arg) " | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" " | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" " | Assert(expr test, expr? msg)\n" - " | Import(alias* names)\n" - " | ImportFrom(identifier? module, alias* names, int? level)\n" + " | Import(alias* names, int? is_lazy)\n" + " | ImportFrom(identifier? module, alias* names, int? level, int? is_lazy)\n" " | Global(identifier* names)\n" " | Nonlocal(identifier* names)\n" " | Expr(expr value)\n" @@ -6353,17 +6388,21 @@ init_types(void *arg) if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1) return -1; state->Import_type = make_type(state, "Import", state->stmt_type, - Import_fields, 1, - "Import(alias* names)"); + Import_fields, 2, + "Import(alias* names, int? is_lazy)"); if (!state->Import_type) return -1; + if (PyObject_SetAttr(state->Import_type, state->is_lazy, Py_None) == -1) + return -1; state->ImportFrom_type = make_type(state, "ImportFrom", state->stmt_type, - ImportFrom_fields, 3, - "ImportFrom(identifier? module, alias* names, int? level)"); + ImportFrom_fields, 4, + "ImportFrom(identifier? module, alias* names, int? level, int? is_lazy)"); if (!state->ImportFrom_type) return -1; if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1) return -1; if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1) return -1; + if (PyObject_SetAttr(state->ImportFrom_type, state->is_lazy, Py_None) == -1) + return -1; state->Global_type = make_type(state, "Global", state->stmt_type, Global_fields, 1, "Global(identifier* names)"); @@ -7605,8 +7644,8 @@ _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int } stmt_ty -_PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) +_PyAST_Import(asdl_alias_seq * names, int is_lazy, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); @@ -7614,6 +7653,7 @@ _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int return NULL; p->kind = Import_kind; p->v.Import.names = names; + p->v.Import.is_lazy = is_lazy; p->lineno = lineno; p->col_offset = col_offset; p->end_lineno = end_lineno; @@ -7623,8 +7663,8 @@ _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int stmt_ty _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) + is_lazy, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); @@ -7634,6 +7674,7 @@ _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int p->v.ImportFrom.module = module; p->v.ImportFrom.names = names; p->v.ImportFrom.level = level; + p->v.ImportFrom.is_lazy = is_lazy; p->lineno = lineno; p->col_offset = col_offset; p->end_lineno = end_lineno; @@ -9467,6 +9508,11 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_int(state, o->v.Import.is_lazy); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->is_lazy, value) == -1) + goto failed; + Py_DECREF(value); break; case ImportFrom_kind: tp = (PyTypeObject *)state->ImportFrom_type; @@ -9488,6 +9534,11 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->level, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_int(state, o->v.ImportFrom.is_lazy); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->is_lazy, value) == -1) + goto failed; + Py_DECREF(value); break; case Global_kind: tp = (PyTypeObject *)state->Global_type; @@ -13483,6 +13534,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } if (isinstance) { asdl_alias_seq* names; + int is_lazy; if (PyObject_GetOptionalAttr(obj, state->names, &tmp) < 0) { return -1; @@ -13522,7 +13574,24 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } Py_CLEAR(tmp); } - *out = _PyAST_Import(names, lineno, col_offset, end_lineno, + if (PyObject_GetOptionalAttr(obj, state->is_lazy, &tmp) < 0) { + return -1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + is_lazy = 0; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'Import' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &is_lazy, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_Import(names, is_lazy, lineno, col_offset, end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; @@ -13536,6 +13605,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* identifier module; asdl_alias_seq* names; int level; + int is_lazy; if (PyObject_GetOptionalAttr(obj, state->module, &tmp) < 0) { return -1; @@ -13609,8 +13679,25 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = _PyAST_ImportFrom(module, names, level, lineno, col_offset, - end_lineno, end_col_offset, arena); + if (PyObject_GetOptionalAttr(obj, state->is_lazy, &tmp) < 0) { + return -1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + is_lazy = 0; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &is_lazy, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_ImportFrom(module, names, level, is_lazy, lineno, + col_offset, end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index c2d780ac9b9270..9144793ae73ce1 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -9,6 +9,7 @@ #include "pycore_fileutils.h" // _PyFile_Flush #include "pycore_floatobject.h" // _PyFloat_ExactDealloc() #include "pycore_interp.h" // _PyInterpreterState_GetConfig() +#include "pycore_import.h" // _PyImport_LazyImportModuleLevelObject () #include "pycore_long.h" // _PyLong_CompactValue #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _Py_AddToAllObjects() @@ -287,6 +288,61 @@ builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals, } +/*[clinic input] +__lazy_import__ as builtin___lazy_import__ + + name: object + globals: object(c_default="NULL") = None + locals: object(c_default="NULL") = None + fromlist: object(c_default="NULL") = () + level: int = 0 + +Lazily imports a module. + +Returns either the module to be imported or a imp.lazy_module object which +indicates the module to be lazily imported. +[clinic start generated code]*/ + +static PyObject * +builtin___lazy_import___impl(PyObject *module, PyObject *name, + PyObject *globals, PyObject *locals, + PyObject *fromlist, int level) +/*[clinic end generated code: output=300f1771094b9e8c input=9394874f340b2948]*/ +{ + PyObject *builtins; + PyThreadState *tstate = PyThreadState_GET(); + if (globals == NULL) { + globals = PyEval_GetGlobals(); + } + if (locals == NULL) { + locals = globals; + } + + if (PyDict_GetItemRef(globals, &_Py_ID(__builtins__), &builtins) < 0) { + return NULL; + } + if (builtins == NULL) { + PyErr_SetString(PyExc_ValueError, + "unable to get builtins for lazy import"); + return NULL; + } + if (PyModule_Check(builtins)) { + PyObject *builtins_dict = Py_XNewRef(PyModule_GetDict(builtins)); + if (builtins_dict == NULL) { + Py_DECREF(builtins); + PyErr_SetString(PyExc_AttributeError, + "builtins module has no dict"); + return NULL; + } + Py_SETREF(builtins, builtins_dict); + } + + PyObject *res = _PyImport_LazyImportModuleLevelObject( + tstate, name, builtins, globals, locals, fromlist, level); + Py_DECREF(builtins); + return res; +} + /*[clinic input] abs as builtin_abs @@ -3362,6 +3418,7 @@ static PyMethodDef builtin_methods[] = { {"__build_class__", _PyCFunction_CAST(builtin___build_class__), METH_FASTCALL | METH_KEYWORDS, build_class_doc}, BUILTIN___IMPORT___METHODDEF + BUILTIN___LAZY_IMPORT___METHODDEF BUILTIN_ABS_METHODDEF BUILTIN_ALL_METHODDEF BUILTIN_ANY_METHODDEF diff --git a/Python/bytecodes.c b/Python/bytecodes.c index e1884ac38c016d..b461f9b5bea8a6 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -11,12 +11,15 @@ #include "pycore_audit.h" // _PySys_Audit() #include "pycore_backoff.h" #include "pycore_cell.h" // PyCell_GetRef() +#include "pycore_ceval.h" // _PyEval_LazyImportName(), _PyEval_LazyImportFrom() #include "pycore_code.h" #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_function.h" +#include "pycore_import.h" // _PyImport_LoadLazyImportTstate() #include "pycore_instruments.h" #include "pycore_interpolation.h" // _PyInterpolation_Build() #include "pycore_intrinsics.h" +#include "pycore_lazyimportobject.h" // PyLazyImport_CheckExact() #include "pycore_long.h" // _PyLong_ExactDealloc(), _PyLong_GetZero() #include "pycore_moduleobject.h" // PyModuleObject #include "pycore_object.h" // _PyObject_GC_TRACK() @@ -1795,6 +1798,12 @@ dummy_func( } ERROR_NO_POP(); } + + if (PyLazyImport_CheckExact(v_o)) { + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + Py_SETREF(v_o, l_v); + ERROR_IF(v_o == NULL); + } } else { /* Slow-path if globals or builtins is not a dict */ @@ -1812,6 +1821,11 @@ dummy_func( ERROR_IF(true); } } + if (PyLazyImport_CheckExact(v_o)) { + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + Py_SETREF(v_o, l_v); + ERROR_IF(v_o == NULL); + } } } v = PyStackRef_FromPyObjectSteal(v_o); @@ -1821,6 +1835,22 @@ dummy_func( PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *v_o = _PyEval_LoadName(tstate, frame, name); ERROR_IF(v_o == NULL); + if (PyLazyImport_CheckExact(v_o)) { + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + // cannot early-decref v_o as it may cause a side-effect on l_v + if (l_v == NULL) { + Py_DECREF(v_o); + ERROR_IF(true); + } + int err = PyDict_SetItem(GLOBALS(), name, l_v); + if (err < 0) { + Py_DECREF(v_o); + Py_DECREF(l_v); + ERROR_IF(true); + } + Py_SETREF(v_o, l_v); + } + v = PyStackRef_FromPyObjectSteal(v_o); } @@ -1846,6 +1876,7 @@ dummy_func( op(_LOAD_GLOBAL, ( -- res[1])) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); + ERROR_IF(PyStackRef_IsNull(*res)); } @@ -2962,11 +2993,23 @@ dummy_func( b = res ? PyStackRef_True : PyStackRef_False; } - inst(IMPORT_NAME, (level, fromlist -- res)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - PyObject *res_o = _PyEval_ImportName(tstate, frame, name, - PyStackRef_AsPyObjectBorrow(fromlist), - PyStackRef_AsPyObjectBorrow(level)); + inst(IMPORT_NAME, (level, fromlist -- res)) { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + PyObject *res_o; + if (!(oparg & 0x02)) { + res_o = _PyEval_LazyImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level), + oparg & 0x01); + + } + else { + res_o = _PyEval_ImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level)); + } DECREF_INPUTS(); ERROR_IF(res_o == NULL); res = PyStackRef_FromPyObjectSteal(res_o); @@ -2974,7 +3017,16 @@ dummy_func( inst(IMPORT_FROM, (from -- from, res)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - PyObject *res_o = _PyEval_ImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name); + PyObject *res_o; + if (PyLazyImport_CheckExact(PyStackRef_AsPyObjectBorrow(from))) { + res_o = _PyEval_LazyImportFrom( + tstate, frame, PyStackRef_AsPyObjectBorrow(from), name); + } + else { + res_o = _PyEval_ImportFrom( + tstate, PyStackRef_AsPyObjectBorrow(from), name); + } + ERROR_IF(res_o == NULL); res = PyStackRef_FromPyObjectSteal(res_o); } diff --git a/Python/ceval.c b/Python/ceval.c index 61644d35b5e473..758b142d7a720e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2916,11 +2916,13 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) } PyObject * -_PyEval_ImportName(PyThreadState *tstate, _PyInterpreterFrame *frame, - PyObject *name, PyObject *fromlist, PyObject *level) +_PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, + PyObject *globals, PyObject *locals, PyObject *name, + PyObject *fromlist, PyObject *level) { PyObject *import_func; - if (PyMapping_GetOptionalItem(frame->f_builtins, &_Py_ID(__import__), &import_func) < 0) { + if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__import__), + &import_func) < 0) { return NULL; } if (import_func == NULL) { @@ -2928,29 +2930,143 @@ _PyEval_ImportName(PyThreadState *tstate, _PyInterpreterFrame *frame, return NULL; } - PyObject *locals = frame->f_locals; + PyObject *res = _PyEval_ImportNameWithImport( + tstate, import_func, globals, locals, name, fromlist, level); + Py_DECREF(import_func); + return res; +} + +PyObject * +_PyEval_ImportNameWithImport(PyThreadState *tstate, PyObject *import_func, + PyObject *globals, PyObject *locals, + PyObject *name, PyObject *fromlist, PyObject *level) +{ if (locals == NULL) { locals = Py_None; } /* Fast path for not overloaded __import__. */ if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) { - Py_DECREF(import_func); int ilevel = PyLong_AsInt(level); if (ilevel == -1 && _PyErr_Occurred(tstate)) { return NULL; } return PyImport_ImportModuleLevelObject( name, - frame->f_globals, + globals, locals, fromlist, ilevel); } - PyObject* args[5] = {name, frame->f_globals, locals, fromlist, level}; + PyObject *args[5] = {name, globals, locals, fromlist, level}; PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL); - Py_DECREF(import_func); + return res; +} + +static int +check_lazy_import_compatibility(PyThreadState *tstate, PyObject *globals, + PyObject *name, PyObject *level) +{ + // Check if this module should be imported lazily due to + // the compatibility mode support via __lazy_modules__. + PyObject *lazy_modules = NULL; + PyObject *abs_name = NULL; + int res = -1; + + if (globals != NULL && + PyMapping_GetOptionalItem(globals, &_Py_ID(__lazy_modules__), + &lazy_modules) < 0) + { + return -1; + } + if (lazy_modules == NULL) { + assert(!PyErr_Occurred()); + return 0; + } + + int ilevel = PyLong_AsInt(level); + if (ilevel == -1 && _PyErr_Occurred(tstate)) { + goto error; + } + + abs_name = _PyImport_GetAbsName(tstate, name, globals, ilevel); + if (abs_name == NULL) { + goto error; + } + + res = PySequence_Contains(lazy_modules, abs_name); +error: + Py_XDECREF(abs_name); + Py_XDECREF(lazy_modules); + return res; +} + +PyObject * +_PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, + PyObject *globals, PyObject *locals, PyObject *name, + PyObject *fromlist, PyObject *level, int lazy) +{ + PyObject *res = NULL; + // Check if global policy overrides the local syntax + switch (PyImport_GetLazyImportsMode()) { + case PyImport_LAZY_NONE: + lazy = 0; + break; + case PyImport_LAZY_ALL: + lazy = 1; + break; + case PyImport_LAZY_NORMAL: + break; + } + + if (!lazy) { + // See if __lazy_modules__ forces this to be lazy. + lazy = check_lazy_import_compatibility(tstate, globals, name, level); + if (lazy < 0) { + return NULL; + } + } + + if (!lazy) { + // Not a lazy import or lazy imports are disabled, fallback to the + // regular import. + return _PyEval_ImportName(tstate, builtins, globals, locals, + name, fromlist, level); + } + + PyObject *lazy_import_func; + if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__lazy_import__), + &lazy_import_func) < 0) { + goto error; + } + if (lazy_import_func == NULL) { + assert(!PyErr_Occurred()); + _PyErr_SetString(tstate, PyExc_ImportError, + "__lazy_import__ not found"); + goto error; + } + + if (locals == NULL) { + locals = Py_None; + } + + if (_PyImport_IsDefaultLazyImportFunc(tstate->interp, lazy_import_func)) { + int ilevel = PyLong_AsInt(level); + if (ilevel == -1 && PyErr_Occurred()) { + goto error; + } + + res = _PyImport_LazyImportModuleLevelObject( + tstate, name, builtins, globals, locals, fromlist, ilevel + ); + goto error; + } + + PyObject *args[6] = {name, globals, locals, fromlist, level, builtins}; + res = PyObject_Vectorcall(lazy_import_func, args, 6, NULL); +error: + Py_XDECREF(lazy_import_func); return res; } @@ -3122,6 +3238,64 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name) return NULL; } +PyObject * +_PyEval_LazyImportFrom(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *v, PyObject *name) +{ + assert(PyLazyImport_CheckExact(v)); + assert(name); + assert(PyUnicode_Check(name)); + PyObject *ret; + PyLazyImportObject *d = (PyLazyImportObject *)v; + PyObject *mod = PyImport_GetModule(d->lz_from); + if (mod != NULL) { + // Check if the module already has the attribute, if so, resolve it + // eagerly. + if (PyModule_Check(mod)) { + PyObject *mod_dict = PyModule_GetDict(mod); + if (mod_dict != NULL) { + if (PyDict_GetItemRef(mod_dict, name, &ret) < 0) { + Py_DECREF(mod); + return NULL; + } + if (ret != NULL) { + Py_DECREF(mod); + return ret; + } + } + } + Py_DECREF(mod); + } + + if (d->lz_attr != NULL) { + if (PyUnicode_Check(d->lz_attr)) { + PyObject *from = PyUnicode_FromFormat( + "%U.%U", d->lz_from, d->lz_attr); + if (from == NULL) { + return NULL; + } + ret = _PyLazyImport_New(frame, d->lz_builtins, from, name); + Py_DECREF(from); + return ret; + } + } + else { + Py_ssize_t dot = PyUnicode_FindChar( + d->lz_from, '.', 0, PyUnicode_GET_LENGTH(d->lz_from), 1 + ); + if (dot >= 0) { + PyObject *from = PyUnicode_Substring(d->lz_from, 0, dot); + if (from == NULL) { + return NULL; + } + ret = _PyLazyImport_New(frame, d->lz_builtins, from, name); + Py_DECREF(from); + return ret; + } + } + ret = _PyLazyImport_New(frame, d->lz_builtins, d->lz_from, name); + return ret; +} + #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ "BaseException is not allowed" @@ -3410,6 +3584,24 @@ _PyEval_LoadGlobalStackRef(PyObject *globals, PyObject *builtins, PyObject *name } *writeto = PyStackRef_FromPyObjectSteal(res); } + + PyObject *res_o = PyStackRef_AsPyObjectBorrow(*writeto); + if (res_o != NULL && PyLazyImport_CheckExact(res_o)) { + PyObject *l_v = _PyImport_LoadLazyImportTstate(PyThreadState_GET(), res_o); + PyStackRef_CLOSE(writeto[0]); + if (l_v == NULL) { + assert(PyErr_Occurred()); + *writeto = PyStackRef_NULL; + return; + } + int err = PyDict_SetItem(globals, name, l_v); + if (err < 0) { + Py_DECREF(l_v); + *writeto = PyStackRef_NULL; + return; + } + *writeto = PyStackRef_FromPyObjectSteal(l_v); + } } PyObject * diff --git a/Python/ceval.h b/Python/ceval.h index b170643e236733..bb5f7ddb857246 100644 --- a/Python/ceval.h +++ b/Python/ceval.h @@ -20,6 +20,7 @@ #include "pycore_interpolation.h" // _PyInterpolation_Build() #include "pycore_intrinsics.h" #include "pycore_jit.h" +#include "pycore_lazyimportobject.h" #include "pycore_list.h" // _PyList_GetItemRef() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // PyModuleObject diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index f08e5847abe32a..c8c141f863d26a 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -113,6 +113,101 @@ builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py return return_value; } +PyDoc_STRVAR(builtin___lazy_import____doc__, +"__lazy_import__($module, /, name, globals=None, locals=None,\n" +" fromlist=(), level=0)\n" +"--\n" +"\n" +"Lazily imports a module.\n" +"\n" +"Returns either the module to be imported or a imp.lazy_module object which\n" +"indicates the module to be lazily imported."); + +#define BUILTIN___LAZY_IMPORT___METHODDEF \ + {"__lazy_import__", _PyCFunction_CAST(builtin___lazy_import__), METH_FASTCALL|METH_KEYWORDS, builtin___lazy_import____doc__}, + +static PyObject * +builtin___lazy_import___impl(PyObject *module, PyObject *name, + PyObject *globals, PyObject *locals, + PyObject *fromlist, int level); + +static PyObject * +builtin___lazy_import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(name), &_Py_ID(globals), &_Py_ID(locals), &_Py_ID(fromlist), &_Py_ID(level), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__lazy_import__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + 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, + /*minpos*/ 1, /*maxpos*/ 5, /*minkw*/ 0, /*varpos*/ 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___lazy_import___impl(module, name, globals, locals, fromlist, level); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_abs__doc__, "abs($module, number, /)\n" "--\n" @@ -1285,4 +1380,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=06500bcc9a341e68 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1c3327da8885bb8e input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 9bbb13f7566517..de62714ebddafa 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -622,6 +622,41 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb return return_value; } +PyDoc_STRVAR(_imp__set_lazy_attributes__doc__, +"_set_lazy_attributes($module, modobj, name, /)\n" +"--\n" +"\n" +"Sets attributes to lazy submodules on the module, as side effects."); + +#define _IMP__SET_LAZY_ATTRIBUTES_METHODDEF \ + {"_set_lazy_attributes", _PyCFunction_CAST(_imp__set_lazy_attributes), METH_FASTCALL, _imp__set_lazy_attributes__doc__}, + +static PyObject * +_imp__set_lazy_attributes_impl(PyObject *module, PyObject *modobj, + PyObject *name); + +static PyObject * +_imp__set_lazy_attributes(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *modobj; + PyObject *name; + + if (!_PyArg_CheckPositional("_set_lazy_attributes", nargs, 2, 2)) { + goto exit; + } + modobj = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("_set_lazy_attributes", "argument 2", "str", args[1]); + goto exit; + } + name = args[1]; + return_value = _imp__set_lazy_attributes_impl(module, modobj, name); + +exit: + return return_value; +} + #ifndef _IMP_CREATE_DYNAMIC_METHODDEF #define _IMP_CREATE_DYNAMIC_METHODDEF #endif /* !defined(_IMP_CREATE_DYNAMIC_METHODDEF) */ @@ -629,4 +664,4 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=24f597d6b0f3feed input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5fa42f580441b3fa input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 4c4a86de2f99bd..f8ae7f18acc809 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -1820,6 +1820,180 @@ sys__is_gil_enabled(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +PyDoc_STRVAR(sys_set_lazy_imports_filter__doc__, +"set_lazy_imports_filter($module, /, filter)\n" +"--\n" +"\n" +"Set the lazy imports filter callback.\n" +"\n" +"The filter is a callable which disables lazy imports when they\n" +"would otherwise be enabled. Returns True if the import is still enabled\n" +"or False to disable it. The callable is called with:\n" +"\n" +"(importing_module_name, imported_module_name, [fromlist])\n" +"\n" +"Pass None to clear the filter."); + +#define SYS_SET_LAZY_IMPORTS_FILTER_METHODDEF \ + {"set_lazy_imports_filter", _PyCFunction_CAST(sys_set_lazy_imports_filter), METH_FASTCALL|METH_KEYWORDS, sys_set_lazy_imports_filter__doc__}, + +static PyObject * +sys_set_lazy_imports_filter_impl(PyObject *module, PyObject *filter); + +static PyObject * +sys_set_lazy_imports_filter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(filter), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"filter", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_lazy_imports_filter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *filter; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + filter = args[0]; + return_value = sys_set_lazy_imports_filter_impl(module, filter); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_get_lazy_imports_filter__doc__, +"get_lazy_imports_filter($module, /)\n" +"--\n" +"\n" +"Get the current lazy imports filter callback.\n" +"\n" +"Returns the filter callable or None if no filter is set."); + +#define SYS_GET_LAZY_IMPORTS_FILTER_METHODDEF \ + {"get_lazy_imports_filter", (PyCFunction)sys_get_lazy_imports_filter, METH_NOARGS, sys_get_lazy_imports_filter__doc__}, + +static PyObject * +sys_get_lazy_imports_filter_impl(PyObject *module); + +static PyObject * +sys_get_lazy_imports_filter(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_get_lazy_imports_filter_impl(module); +} + +PyDoc_STRVAR(sys_set_lazy_imports__doc__, +"set_lazy_imports($module, /, mode)\n" +"--\n" +"\n" +"Sets the global lazy imports mode.\n" +"\n" +"The mode parameter must be one of the following strings:\n" +"- \"all\": All top-level imports become potentially lazy\n" +"- \"none\": All lazy imports are suppressed (even explicitly marked ones)\n" +"- \"normal\": Only explicitly marked imports (with \'lazy\' keyword) are lazy\n" +"\n" +"In addition to the mode, lazy imports can be controlled via the filter\n" +"provided to sys.set_lazy_imports_filter"); + +#define SYS_SET_LAZY_IMPORTS_METHODDEF \ + {"set_lazy_imports", _PyCFunction_CAST(sys_set_lazy_imports), METH_FASTCALL|METH_KEYWORDS, sys_set_lazy_imports__doc__}, + +static PyObject * +sys_set_lazy_imports_impl(PyObject *module, PyObject *mode); + +static PyObject * +sys_set_lazy_imports(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"mode", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_lazy_imports", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *mode; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + mode = args[0]; + return_value = sys_set_lazy_imports_impl(module, mode); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_get_lazy_imports__doc__, +"get_lazy_imports($module, /)\n" +"--\n" +"\n" +"Gets the global lazy imports mode.\n" +"\n" +"Returns \"all\" if all top level imports are potentially lazy.\n" +"Returns \"none\" if all explicitly marked lazy imports are suppressed.\n" +"Returns \"normal\" if only explicitly marked imports are lazy."); + +#define SYS_GET_LAZY_IMPORTS_METHODDEF \ + {"get_lazy_imports", (PyCFunction)sys_get_lazy_imports, METH_NOARGS, sys_get_lazy_imports__doc__}, + +static PyObject * +sys_get_lazy_imports_impl(PyObject *module); + +static PyObject * +sys_get_lazy_imports(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_get_lazy_imports_impl(module); +} + PyDoc_STRVAR(_jit_is_available__doc__, "is_available($module, /)\n" "--\n" @@ -1947,4 +2121,4 @@ _jit_is_active(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=5f7d84c5bf00d557 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=adbadb629b98eabf input=a9049054013a1b77]*/ diff --git a/Python/codegen.c b/Python/codegen.c index 5227312b4f75f8..32a03e7212eeab 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -357,8 +357,8 @@ codegen_addop_o(compiler *c, location loc, #define LOAD_ZERO_SUPER_METHOD -4 static int -codegen_addop_name(compiler *c, location loc, - int opcode, PyObject *dict, PyObject *o) +codegen_addop_name_custom(compiler *c, location loc, int opcode, + PyObject *dict, PyObject *o, int shift, int low) { PyObject *mangled = _PyCompile_MaybeMangle(c, o); if (!mangled) { @@ -369,40 +369,51 @@ codegen_addop_name(compiler *c, location loc, if (arg < 0) { return ERROR; } + ADDOP_I(c, loc, opcode, (arg << shift) | low); + return SUCCESS; +} + +static int +codegen_addop_name(compiler *c, location loc, + int opcode, PyObject *dict, PyObject *o) +{ + int shift = 0, low = 0; if (opcode == LOAD_ATTR) { - arg <<= 1; + shift = 1; } if (opcode == LOAD_METHOD) { opcode = LOAD_ATTR; - arg <<= 1; - arg |= 1; + shift = 1; + low = 1; } if (opcode == LOAD_SUPER_ATTR) { - arg <<= 2; - arg |= 2; + shift = 2; + low = 2; } if (opcode == LOAD_SUPER_METHOD) { opcode = LOAD_SUPER_ATTR; - arg <<= 2; - arg |= 3; + shift = 2; + low = 3; } if (opcode == LOAD_ZERO_SUPER_ATTR) { opcode = LOAD_SUPER_ATTR; - arg <<= 2; + shift = 2; } if (opcode == LOAD_ZERO_SUPER_METHOD) { opcode = LOAD_SUPER_ATTR; - arg <<= 2; - arg |= 1; + shift = 2; + low = 1; } - ADDOP_I(c, loc, opcode, arg); - return SUCCESS; + return codegen_addop_name_custom(c, loc, opcode, dict, o, shift, low); } #define ADDOP_NAME(C, LOC, OP, O, TYPE) \ RETURN_IF_ERROR(codegen_addop_name((C), (LOC), (OP), METADATA(C)->u_ ## TYPE, (O))) -static int +#define ADDOP_NAME_CUSTOM(C, LOC, OP, O, TYPE, SHIFT, LOW) \ + RETURN_IF_ERROR(codegen_addop_name_custom((C), (LOC), (OP), METADATA(C)->u_ ## TYPE, (O), SHIFT, LOW)) + + static int codegen_addop_j(instr_sequence *seq, location loc, int opcode, jump_target_label target) { @@ -2864,6 +2875,17 @@ codegen_import_as(compiler *c, location loc, return codegen_nameop(c, loc, asname, Store); } +static int +codegen_validate_lazy_import(compiler *c, location loc) +{ + if (_PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE) { + return _PyCompile_Error( + c, loc, "lazy imports only allowed in module scope"); + } + + return SUCCESS; +} + static int codegen_import(compiler *c, stmt_ty s) { @@ -2884,7 +2906,18 @@ codegen_import(compiler *c, stmt_ty s) ADDOP_LOAD_CONST(c, loc, zero); ADDOP_LOAD_CONST(c, loc, Py_None); - ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names); + if (s->v.Import.is_lazy) { + RETURN_IF_ERROR(codegen_validate_lazy_import(c, loc)); + ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 1); + } else { + if (_PyCompile_InExceptionHandler(c) || + _PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE) { + // force eager import in try/except block + ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 2); + } else { + ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 0); + } + } if (alias->asname) { r = codegen_import_as(c, loc, alias->name, alias->asname); @@ -2930,13 +2963,29 @@ codegen_from_import(compiler *c, stmt_ty s) ADDOP_LOAD_CONST_NEW(c, LOC(s), names); + identifier from = &_Py_STR(empty); if (s->v.ImportFrom.module) { - ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names); + from = s->v.ImportFrom.module; } - else { - _Py_DECLARE_STR(empty, ""); - ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names); + if (s->v.ImportFrom.is_lazy) { + alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, 0); + if (PyUnicode_READ_CHAR(alias->name, 0) == '*') { + return _PyCompile_Error(c, LOC(s), "cannot lazy import *"); + } + RETURN_IF_ERROR(codegen_validate_lazy_import(c, LOC(s))); + ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 1); + } else { + alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, 0); + if (_PyCompile_InExceptionHandler(c) || + _PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE || + PyUnicode_READ_CHAR(alias->name, 0) == '*') { + // forced non-lazy import due to try/except or import * + ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 2); + } else { + ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 0); + } } + for (Py_ssize_t i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); identifier store_name; diff --git a/Python/compile.c b/Python/compile.c index 1f154004969f31..96779a0a219a55 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -800,6 +800,26 @@ _PyCompile_TopFBlock(compiler *c) return &c->u->u_fblock[c->u->u_nfblocks - 1]; } +bool +_PyCompile_InExceptionHandler(compiler *c) +{ + for (Py_ssize_t i = 0; i < c->u->u_nfblocks; i++) { + fblockinfo *block = &c->u->u_fblock[i]; + switch (block->fb_type) { + case COMPILE_FBLOCK_TRY_EXCEPT: + case COMPILE_FBLOCK_FINALLY_TRY: + case COMPILE_FBLOCK_FINALLY_END: + case COMPILE_FBLOCK_EXCEPTION_HANDLER: + case COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER: + case COMPILE_FBLOCK_HANDLER_CLEANUP: + return true; + default: + break; + } + } + return false; +} + void _PyCompile_DeferredAnnotations(compiler *c, PyObject **deferred_annotations, diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index f976e150451d49..9dead4eecc7826 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -7447,6 +7447,32 @@ SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (l_v == NULL) { + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(v_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_ERROR(); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = PyDict_SetItem(GLOBALS(), name, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(v_o); + Py_DECREF(l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_ERROR(); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + } v = PyStackRef_FromPyObjectSteal(v_o); _tos_cache0 = v; _tos_cache1 = PyStackRef_ZERO_BITS; @@ -10523,15 +10549,34 @@ oparg = CURRENT_OPARG(); fromlist = _stack_item_1; level = _stack_item_0; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - stack_pointer[0] = level; - stack_pointer[1] = fromlist; - stack_pointer += 2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + PyObject *res_o; + if (!(oparg & 0x02)) { + stack_pointer[0] = level; + stack_pointer[1] = fromlist; + stack_pointer += 2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_LazyImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level), + oparg & 0x01); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + stack_pointer[0] = level; + stack_pointer[1] = fromlist; + stack_pointer += 2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_ImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level)); + stack_pointer = _PyFrame_GetStackPointer(frame); + } _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyEval_ImportName(tstate, frame, name, - PyStackRef_AsPyObjectBorrow(fromlist), - PyStackRef_AsPyObjectBorrow(level)); _PyStackRef tmp = fromlist; fromlist = PyStackRef_NULL; stack_pointer[-1] = fromlist; @@ -10565,13 +10610,27 @@ oparg = CURRENT_OPARG(); from = _stack_item_0; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - stack_pointer[0] = from; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyEval_ImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyObject *res_o; + if (PyLazyImport_CheckExact(PyStackRef_AsPyObjectBorrow(from))) { + stack_pointer[0] = from; + stack_pointer += 1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_LazyImportFrom( + tstate, frame, PyStackRef_AsPyObjectBorrow(from), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + stack_pointer[0] = from; + stack_pointer += 1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_ImportFrom( + tstate, PyStackRef_AsPyObjectBorrow(from), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + } if (res_o == NULL) { + stack_pointer[-1] = from; SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 202bf5edcf09df..37fa6d679190dd 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6371,9 +6371,19 @@ _PyStackRef res; from = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyEval_ImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyObject *res_o; + if (PyLazyImport_CheckExact(PyStackRef_AsPyObjectBorrow(from))) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_LazyImportFrom( + tstate, frame, PyStackRef_AsPyObjectBorrow(from), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_ImportFrom( + tstate, PyStackRef_AsPyObjectBorrow(from), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + } if (res_o == NULL) { JUMP_TO_LABEL(error); } @@ -6397,11 +6407,26 @@ _PyStackRef res; fromlist = stack_pointer[-1]; level = stack_pointer[-2]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + PyObject *res_o; + if (!(oparg & 0x02)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_LazyImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level), + oparg & 0x01); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyEval_ImportName(tstate, BUILTINS(), GLOBALS(), + LOCALS(), name, + PyStackRef_AsPyObjectBorrow(fromlist), + PyStackRef_AsPyObjectBorrow(level)); + stack_pointer = _PyFrame_GetStackPointer(frame); + } _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyEval_ImportName(tstate, frame, name, - PyStackRef_AsPyObjectBorrow(fromlist), - PyStackRef_AsPyObjectBorrow(level)); _PyStackRef tmp = fromlist; fromlist = PyStackRef_NULL; stack_pointer[-1] = fromlist; @@ -9154,6 +9179,15 @@ } JUMP_TO_LABEL(error); } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (v_o == NULL) { + JUMP_TO_LABEL(error); + } + } } else { _PyFrame_SetStackPointer(frame, stack_pointer); @@ -9178,6 +9212,15 @@ JUMP_TO_LABEL(error); } } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (v_o == NULL) { + JUMP_TO_LABEL(error); + } + } } } v = PyStackRef_FromPyObjectSteal(v_o); @@ -9430,6 +9473,30 @@ if (v_o == NULL) { JUMP_TO_LABEL(error); } + if (PyLazyImport_CheckExact(v_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (l_v == NULL) { + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(v_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + JUMP_TO_LABEL(error); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = PyDict_SetItem(GLOBALS(), name, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(v_o); + Py_DECREF(l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + JUMP_TO_LABEL(error); + } + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_SETREF(v_o, l_v); + stack_pointer = _PyFrame_GetStackPointer(frame); + } v = PyStackRef_FromPyObjectSteal(v_o); stack_pointer[0] = v; stack_pointer += 1; diff --git a/Python/import.c b/Python/import.c index c9e892c96b0339..c20c55727d2f94 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4,21 +4,28 @@ #include "pycore_audit.h" // _PySys_Audit() #include "pycore_ceval.h" #include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION() +#include "pycore_dict.h" // _PyDict_Contains_KnownHash() #include "pycore_hashtable.h" // _Py_hashtable_new_full() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // struct _import_runtime_state +#include "pycore_interpframe.h" +#include "pycore_lazyimportobject.h" +#include "pycore_long.h" // _PyLong_GetZero #include "pycore_magic_number.h" // PYC_MAGIC_NUMBER_TOKEN #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_namespace.h" // _PyNamespace_Type #include "pycore_object.h" // _Py_SetImmortal() +#include "pycore_pyatomic_ft_wrappers.h" #include "pycore_pyerrors.h" // _PyErr_SetString() #include "pycore_pyhash.h" // _Py_KeyedHash() #include "pycore_pylifecycle.h" #include "pycore_pymem.h" // _PyMem_DefaultRawFree() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_sysmodule.h" // _PySys_ClearAttrString() #include "pycore_time.h" // _PyTime_AsMicroseconds() +#include "pycore_traceback.h" #include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8NoNUL() #include "pycore_weakref.h" // _PyWeakref_GET_REF() @@ -85,6 +92,8 @@ static struct _inittab *inittab_copy = NULL; (interp)->imports.modules #define MODULES_BY_INDEX(interp) \ (interp)->imports.modules_by_index +#define LAZY_MODULES(interp) \ + (interp)->imports.lazy_modules #define IMPORTLIB(interp) \ (interp)->imports.importlib #define OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) \ @@ -98,12 +107,30 @@ static struct _inittab *inittab_copy = NULL; #define IMPORT_FUNC(interp) \ (interp)->imports.import_func +#define LAZY_IMPORT_FUNC(interp) \ + (interp)->imports.lazy_import_func + #define IMPORT_LOCK(interp) \ (interp)->imports.lock #define FIND_AND_LOAD(interp) \ (interp)->imports.find_and_load +#define LAZY_IMPORTS_MODE(interp) \ + (interp)->imports.lazy_imports_mode + +#define LAZY_IMPORTS_FILTER(interp) \ + (interp)->imports.lazy_imports_filter + +#ifdef Py_GIL_DISABLED +#define LAZY_IMPORTS_LOCK(interp) PyMutex_Lock(&(interp)->imports.lazy_mutex) +#define LAZY_IMPORTS_UNLOCK(interp) PyMutex_Unlock(&(interp)->imports.lazy_mutex) +#else +#define LAZY_IMPORTS_LOCK(interp) +#define LAZY_IMPORTS_UNLOCK(interp) +#endif + + #define _IMPORT_TIME_HEADER(interp) \ do { \ if (FIND_AND_LOAD((interp)).header) { \ @@ -241,6 +268,20 @@ import_get_module(PyThreadState *tstate, PyObject *name) return m; } +PyObject * +_PyImport_InitLazyModules(PyInterpreterState *interp) +{ + assert(LAZY_MODULES(interp) == NULL); + LAZY_MODULES(interp) = PyDict_New(); + return LAZY_MODULES(interp); +} + +void +_PyImport_ClearLazyModules(PyInterpreterState *interp) +{ + Py_CLEAR(LAZY_MODULES(interp)); +} + static int import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name) { @@ -2147,7 +2188,8 @@ import_run_extension(PyThreadState *tstate, PyModInitFunction p0, if (filename == NULL) { return NULL; } - } else { + } + else { filename = Py_NewRef(info->filename); } // XXX There's a refleak somewhere with the filename. @@ -3539,6 +3581,13 @@ _PyImport_InitDefaultImportFunc(PyInterpreterState *interp) return -1; } IMPORT_FUNC(interp) = import_func; + + // Get the __lazy_import__ function + if (PyDict_GetItemStringRef(interp->builtins, "__lazy_import__", + &import_func) <= 0) { + return -1; + } + LAZY_IMPORT_FUNC(interp) = import_func; return 0; } @@ -3548,6 +3597,11 @@ _PyImport_IsDefaultImportFunc(PyInterpreterState *interp, PyObject *func) return func == IMPORT_FUNC(interp); } +int +_PyImport_IsDefaultLazyImportFunc(PyInterpreterState *interp, PyObject *func) +{ + return func == LAZY_IMPORT_FUNC(interp); +} /* Import a module, either built-in, frozen, or external, and return its module object WITH INCREMENTED REFERENCE COUNT */ @@ -3811,6 +3865,234 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level return NULL; } +PyObject * +_PyImport_ResolveName(PyThreadState *tstate, PyObject *name, + PyObject *globals, int level) +{ + return resolve_name(tstate, name, globals, level); +} + +PyObject * +_PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import) +{ + PyObject *obj = NULL; + PyObject *fromlist = Py_None; + PyObject *import_func = NULL; + assert(lazy_import != NULL); + assert(PyLazyImport_CheckExact(lazy_import)); + + PyLazyImportObject *lz = (PyLazyImportObject *)lazy_import; + PyInterpreterState *interp = tstate->interp; + + // Acquire the global import lock to serialize reification + _PyImport_AcquireLock(interp); + + // Check if we are already importing this module, if so, then we want to + // return an error that indicates we've hit a cycle which will indicate + // the value isn't yet available. + PyObject *importing = interp->imports.lazy_importing_modules; + if (importing == NULL) { + importing = interp->imports.lazy_importing_modules = PySet_New(NULL); + if (importing == NULL) { + _PyImport_ReleaseLock(interp); + return NULL; + } + } + + assert(PyAnySet_CheckExact(importing)); + int is_loading = _PySet_Contains((PySetObject *)importing, lazy_import); + if (is_loading < 0) { + _PyImport_ReleaseLock(interp); + return NULL; + } + else if (is_loading == 1) { + PyObject *name = _PyLazyImport_GetName(lazy_import); + if (name == NULL) { + _PyImport_ReleaseLock(interp); + return NULL; + } + PyObject *errmsg = PyUnicode_FromFormat( + "cannot import name %R (most likely due to a circular import)", + name); + if (errmsg == NULL) { + Py_DECREF(name); + _PyImport_ReleaseLock(interp); + return NULL; + } + PyErr_SetImportErrorSubclass(PyExc_ImportCycleError, errmsg, + lz->lz_from, NULL); + Py_DECREF(errmsg); + Py_DECREF(name); + _PyImport_ReleaseLock(interp); + return NULL; + } + else if (PySet_Add(importing, lazy_import) < 0) { + _PyImport_ReleaseLock(interp); + goto error; + } + + Py_ssize_t dot = -1; + int full = 0; + if (lz->lz_attr != NULL) { + full = 1; + } + if (!full) { + dot = PyUnicode_FindChar(lz->lz_from, '.', 0, + PyUnicode_GET_LENGTH(lz->lz_from), 1); + } + if (dot < 0) { + full = 1; + } + + if (lz->lz_attr != NULL) { + if (PyUnicode_Check(lz->lz_attr)) { + fromlist = PyTuple_New(1); + if (fromlist == NULL) { + goto error; + } + Py_INCREF(lz->lz_attr); + PyTuple_SET_ITEM(fromlist, 0, lz->lz_attr); + } + else { + Py_INCREF(lz->lz_attr); + fromlist = lz->lz_attr; + } + } + + PyObject *globals = PyEval_GetGlobals(); + + if (PyMapping_GetOptionalItem(lz->lz_builtins, &_Py_ID(__import__), + &import_func) < 0) { + goto error; + } + if (import_func == NULL) { + PyErr_SetString(PyExc_ImportError, "__import__ not found"); + goto error; + } + if (full) { + obj = _PyEval_ImportNameWithImport( + tstate, import_func, globals, globals, + lz->lz_from, fromlist, _PyLong_GetZero() + ); + } + else { + PyObject *name = PyUnicode_Substring(lz->lz_from, 0, dot); + if (name == NULL) { + goto error; + } + obj = _PyEval_ImportNameWithImport( + tstate, import_func, globals, globals, + name, fromlist, _PyLong_GetZero() + ); + Py_DECREF(name); + } + if (obj == NULL) { + goto error; + } + + if (lz->lz_attr != NULL && PyUnicode_Check(lz->lz_attr)) { + PyObject *from = obj; + obj = _PyEval_ImportFrom(tstate, from, lz->lz_attr); + Py_DECREF(from); + if (obj == NULL) { + goto error; + } + } + + assert(!PyLazyImport_CheckExact(obj)); + + goto ok; + +error: + Py_CLEAR(obj); + + // If an error occurred and we have frame information, add it to the + // exception. + if (PyErr_Occurred() && lz->lz_code != NULL && lz->lz_instr_offset >= 0) { + // Get the current exception - this already has the full traceback + // from the access point. + PyObject *exc = _PyErr_GetRaisedException(tstate); + + // Get import name - this can fail and set an exception. + PyObject *import_name = _PyLazyImport_GetName(lazy_import); + if (!import_name) { + // Failed to get import name, just restore original exception. + _PyErr_SetRaisedException(tstate, exc); + goto ok; + } + + // Resolve line number from instruction offset on demand. + int lineno = PyCode_Addr2Line((PyCodeObject *)lz->lz_code, + lz->lz_instr_offset*2); + + // Get strings - these can return NULL on encoding errors. + const char *filename_str = PyUnicode_AsUTF8(lz->lz_code->co_filename); + if (!filename_str) { + // Unicode conversion failed - clear error and restore original + // exception. + PyErr_Clear(); + Py_DECREF(import_name); + _PyErr_SetRaisedException(tstate, exc); + goto ok; + } + + const char *funcname_str = PyUnicode_AsUTF8(lz->lz_code->co_name); + if (!funcname_str) { + // Unicode conversion failed - clear error and restore original + // exception. + PyErr_Clear(); + Py_DECREF(import_name); + _PyErr_SetRaisedException(tstate, exc); + goto ok; + } + + // Create a cause exception showing where the lazy import was declared. + PyObject *msg = PyUnicode_FromFormat( + "deferred import of '%U' raised an exception during resolution", + import_name + ); + Py_DECREF(import_name); // Done with import_name. + + if (!msg) { + // Failed to create message - restore original exception. + _PyErr_SetRaisedException(tstate, exc); + goto ok; + } + + PyObject *cause_exc = PyObject_CallOneArg(PyExc_ImportError, msg); + Py_DECREF(msg); // Done with msg. + + if (!cause_exc) { + // Failed to create exception - restore original. + _PyErr_SetRaisedException(tstate, exc); + goto ok; + } + + // Add traceback entry for the lazy import declaration. + _PyErr_SetRaisedException(tstate, cause_exc); + _PyTraceback_Add(funcname_str, filename_str, lineno); + PyObject *cause_with_tb = _PyErr_GetRaisedException(tstate); + + // Set the cause on the original exception. + PyException_SetCause(exc, cause_with_tb); // Steals ref to cause_with_tb. + + // Restore the original exception with its full traceback. + _PyErr_SetRaisedException(tstate, exc); + } + +ok: + if (PySet_Discard(importing, lazy_import) < 0) { + Py_CLEAR(obj); + } + + // Release the global import lock. + _PyImport_ReleaseLock(interp); + + Py_XDECREF(fromlist); + Py_XDECREF(import_func); + return obj; +} + static PyObject * import_find_and_load(PyThreadState *tstate, PyObject *abs_name) { @@ -3865,6 +4147,28 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) #undef accumulated } +static PyObject * +get_abs_name(PyThreadState *tstate, PyObject *name, PyObject *globals, + int level) +{ + if (level > 0) { + return resolve_name(tstate, name, globals, level); + } + if (PyUnicode_GET_LENGTH(name) == 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); + return NULL; + } + return Py_NewRef(name); +} + +PyObject * +_PyImport_GetAbsName(PyThreadState *tstate, PyObject *name, + PyObject *globals, int level) +{ + return get_abs_name(tstate, name, globals, level); +} + + PyObject * PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, PyObject *locals, PyObject *fromlist, @@ -3895,17 +4199,9 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, goto error; } - if (level > 0) { - abs_name = resolve_name(tstate, name, globals, level); - if (abs_name == NULL) - goto error; - } - else { /* level == 0 */ - if (PyUnicode_GET_LENGTH(name) == 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); - goto error; - } - abs_name = Py_NewRef(name); + abs_name = get_abs_name(tstate, name, globals, level); + if (abs_name == NULL) { + goto error; } mod = import_get_module(tstate, abs_name); @@ -4029,6 +4325,243 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, return final_mod; } +static PyObject * +get_mod_dict(PyObject *module) +{ + if (PyModule_Check(module)) { + return Py_NewRef(_PyModule_GetDict(module)); + } + + return PyObject_GetAttr(module, &_Py_ID(__dict__)); +} + +// ensure we have the set for the parent module name in sys.lazy_modules. +// Returns a new reference. +static PyObject * +ensure_lazy_submodules(PyDictObject *lazy_modules, PyObject *parent) +{ + PyObject *lazy_submodules; + Py_BEGIN_CRITICAL_SECTION(lazy_modules); + int err = _PyDict_GetItemRef_Unicode_LockHeld(lazy_modules, parent, + &lazy_submodules); + if (err == 0) { + // value isn't present + lazy_submodules = PySet_New(NULL); + if (lazy_submodules != NULL && + _PyDict_SetItem_LockHeld(lazy_modules, parent, + lazy_submodules) < 0) { + Py_CLEAR(lazy_submodules); + } + } + Py_END_CRITICAL_SECTION(); + return lazy_submodules; +} + +static int +register_lazy_on_parent(PyThreadState *tstate, PyObject *name, + PyObject *builtins) +{ + int ret = -1; + PyObject *parent = NULL; + PyObject *child = NULL; + PyObject *parent_module = NULL; + PyObject *parent_dict = NULL; + + PyInterpreterState *interp = tstate->interp; + PyObject *lazy_modules = LAZY_MODULES(interp); + assert(lazy_modules != NULL); + + Py_INCREF(name); + while (true) { + Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, + PyUnicode_GET_LENGTH(name), -1); + if (dot < 0) { + ret = 0; + goto done; + } + parent = PyUnicode_Substring(name, 0, dot); + // If `parent` is NULL then this has hit the end of the import, no + // more "parent.child" in the import name. The entire import will be + // resolved lazily. + if (parent == NULL) { + goto done; + } + Py_XDECREF(child); + child = PyUnicode_Substring(name, dot + 1, PyUnicode_GET_LENGTH(name)); + if (child == NULL) { + goto done; + } + + // Record the child as being lazily imported from the parent. + PyObject *lazy_submodules = ensure_lazy_submodules( + (PyDictObject *)lazy_modules, parent); + if (lazy_submodules == NULL) { + goto done; + } + + if (PySet_Add(lazy_submodules, child) < 0) { + Py_DECREF(lazy_submodules); + goto done; + } + Py_DECREF(lazy_submodules); + + // Add the lazy import for the child to the parent. + Py_XSETREF(parent_module, PyImport_GetModule(parent)); + if (parent_module != NULL) { + Py_XSETREF(parent_dict, get_mod_dict(parent_module)); + if (parent_dict == NULL) { + goto done; + } + if (PyDict_CheckExact(parent_dict)) { + int contains = PyDict_Contains(parent_dict, child); + if (contains < 0) { + goto done; + } + if (!contains) { + PyObject *lazy_module_attr = _PyLazyImport_New( + tstate->current_frame, builtins, parent, child + ); + if (lazy_module_attr == NULL) { + goto done; + } + if (PyDict_SetItem(parent_dict, child, + lazy_module_attr) < 0) { + Py_DECREF(lazy_module_attr); + goto done; + } + Py_DECREF(lazy_module_attr); + } + } + ret = 0; + goto done; + } + + Py_SETREF(name, parent); + parent = NULL; + } + +done: + Py_XDECREF(parent_dict); + Py_XDECREF(parent_module); + Py_XDECREF(child); + Py_XDECREF(parent); + Py_XDECREF(name); + return ret; +} + +static int +register_from_lazy_on_parent(PyThreadState *tstate, PyObject *abs_name, + PyObject *from, PyObject *builtins) +{ + PyObject *fromname = PyUnicode_FromFormat("%U.%U", abs_name, from); + if (fromname == NULL) { + return -1; + } + int res = register_lazy_on_parent(tstate, fromname, builtins); + Py_DECREF(fromname); + return res; +} + +PyObject * +_PyImport_LazyImportModuleLevelObject(PyThreadState *tstate, + PyObject *name, PyObject *builtins, + PyObject *globals, PyObject *locals, + PyObject *fromlist, int level) +{ + PyObject *abs_name = get_abs_name(tstate, name, globals, level); + if (abs_name == NULL) { + return NULL; + } + + PyInterpreterState *interp = tstate->interp; + _PyInterpreterFrame *frame = _PyEval_GetFrame(); + if (frame == NULL || frame->f_globals != frame->f_locals) { + Py_DECREF(abs_name); + PyErr_SetString(PyExc_SyntaxError, + "'lazy import' is only allowed at module level"); + return NULL; + } + + // Check if the filter disables the lazy import. + // We must hold a reference to the filter while calling it to prevent + // use-after-free if another thread replaces it via + // PyImport_SetLazyImportsFilter. + LAZY_IMPORTS_LOCK(interp); + PyObject *filter = Py_XNewRef(LAZY_IMPORTS_FILTER(interp)); + LAZY_IMPORTS_UNLOCK(interp); + + if (filter != NULL) { + PyObject *modname; + if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &modname) < 0) { + Py_DECREF(filter); + Py_DECREF(abs_name); + return NULL; + } + if (modname == NULL) { + assert(!PyErr_Occurred()); + modname = Py_NewRef(Py_None); + } + PyObject *args[] = {modname, name, fromlist}; + PyObject *res = PyObject_Vectorcall(filter, args, 3, NULL); + + Py_DECREF(modname); + Py_DECREF(filter); + + if (res == NULL) { + Py_DECREF(abs_name); + return NULL; + } + + int is_true = PyObject_IsTrue(res); + Py_DECREF(res); + + if (is_true < 0) { + Py_DECREF(abs_name); + return NULL; + } + if (!is_true) { + Py_DECREF(abs_name); + return PyImport_ImportModuleLevelObject( + name, globals, locals, fromlist, level + ); + } + } + + // here, 'filter' is either NULL or is equivalent to a borrowed reference + PyObject *res = _PyLazyImport_New(frame, builtins, abs_name, fromlist); + if (res == NULL) { + Py_DECREF(abs_name); + return NULL; + } + if (fromlist && PyUnicode_Check(fromlist)) { + if (register_from_lazy_on_parent(tstate, abs_name, fromlist, + builtins) < 0) { + goto error; + } + } + else if (fromlist && PyTuple_Check(fromlist) && + PyTuple_GET_SIZE(fromlist)) { + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(fromlist); i++) { + if (register_from_lazy_on_parent(tstate, abs_name, + PyTuple_GET_ITEM(fromlist, i), + builtins) < 0) + { + goto error; + } + } + } + else if (register_lazy_on_parent(tstate, abs_name, builtins) < 0) { + goto error; + } + + Py_DECREF(abs_name); + return res; +error: + Py_DECREF(abs_name); + Py_DECREF(res); + return NULL; +} + PyObject * PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) @@ -4235,6 +4768,10 @@ _PyImport_ClearCore(PyInterpreterState *interp) Py_CLEAR(MODULES_BY_INDEX(interp)); Py_CLEAR(IMPORTLIB(interp)); Py_CLEAR(IMPORT_FUNC(interp)); + Py_CLEAR(LAZY_IMPORT_FUNC(interp)); + Py_CLEAR(interp->imports.lazy_modules); + Py_CLEAR(interp->imports.lazy_importing_modules); + Py_CLEAR(interp->imports.lazy_imports_filter); } void @@ -4370,6 +4907,58 @@ PyImport_ImportModuleAttrString(const char *modname, const char *attrname) return result; } +int +PyImport_SetLazyImportsFilter(PyObject *filter) +{ + if (filter == Py_None) { + filter = NULL; + } + if (filter != NULL && !PyCallable_Check(filter)) { + PyErr_SetString(PyExc_ValueError, + "filter provided but is not callable"); + return -1; + } + + PyInterpreterState *interp = _PyInterpreterState_GET(); + // Exchange the filter w/ the lock held. We can't use Py_XSETREF + // because we need to release the lock before the decref. + LAZY_IMPORTS_LOCK(interp); + PyObject *old = LAZY_IMPORTS_FILTER(interp); + LAZY_IMPORTS_FILTER(interp) = Py_XNewRef(filter); + LAZY_IMPORTS_UNLOCK(interp); + Py_XDECREF(old); + return 0; +} + +/* Return a strong reference to the current lazy imports filter + * or NULL if none exists. This function always succeeds. + */ +PyObject * +PyImport_GetLazyImportsFilter(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + LAZY_IMPORTS_LOCK(interp); + PyObject *res = Py_XNewRef(LAZY_IMPORTS_FILTER(interp)); + LAZY_IMPORTS_UNLOCK(interp); + return res; +} + +int +PyImport_SetLazyImportsMode(PyImport_LazyImportsMode mode) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + FT_ATOMIC_STORE_INT_RELAXED(LAZY_IMPORTS_MODE(interp), mode); + return 0; +} + +/* Checks if lazy imports is globally enabled or disabled. Return 1 when + * globally forced on, 0 when globally forced off, or -1 when not set.*/ +PyImport_LazyImportsMode +PyImport_GetLazyImportsMode(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return FT_ATOMIC_LOAD_INT_RELAXED(LAZY_IMPORTS_MODE(interp)); +} /**************/ /* the module */ @@ -4969,6 +5558,96 @@ _imp_source_hash_impl(PyObject *module, long key, Py_buffer *source) return PyBytes_FromStringAndSize(hash.data, sizeof(hash.data)); } +static int +publish_lazy_imports_on_module(PyThreadState *tstate, + PyObject *lazy_submodules, + PyObject *name, + PyObject *module_dict) +{ + PyObject *builtins = _PyEval_GetBuiltins(tstate); + PyObject *attr_name; + Py_ssize_t pos = 0; + Py_hash_t hash; + + // Enumerate the set of lazy submodules which have been imported from the + // parent module. + while (_PySet_NextEntryRef(lazy_submodules, &pos, &attr_name, &hash)) { + if (_PyDict_Contains_KnownHash(module_dict, attr_name, hash)) { + Py_DECREF(attr_name); + continue; + } + // Create a new lazy module attr for the subpackage which was + // previously lazily imported. + PyObject *lazy_module_attr = _PyLazyImport_New(tstate->current_frame, builtins, + name, attr_name); + if (lazy_module_attr == NULL) { + Py_DECREF(attr_name); + return -1; + } + + // Publish on the module that was just imported. + if (PyDict_SetItem(module_dict, attr_name, + lazy_module_attr) < 0) { + Py_DECREF(lazy_module_attr); + Py_DECREF(attr_name); + return -1; + } + Py_DECREF(lazy_module_attr); + Py_DECREF(attr_name); + } + return 0; +} + +/*[clinic input] +_imp._set_lazy_attributes + modobj: object + name: unicode + / +Sets attributes to lazy submodules on the module, as side effects. +[clinic start generated code]*/ + +static PyObject * +_imp__set_lazy_attributes_impl(PyObject *module, PyObject *modobj, + PyObject *name) +/*[clinic end generated code: output=3369bb3242b1f043 input=38ea6f30956dd7d6]*/ +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *module_dict = NULL; + PyObject *ret = NULL; + PyObject *lazy_modules = LAZY_MODULES(tstate->interp); + assert(lazy_modules != NULL); + + PyObject *lazy_submodules; + if (PyDict_GetItemRef(lazy_modules, name, &lazy_submodules) < 0) { + return NULL; + } + else if (lazy_submodules == NULL) { + Py_RETURN_NONE; + } + + module_dict = get_mod_dict(modobj); + if (module_dict == NULL || !PyDict_CheckExact(module_dict)) { + goto done; + } + + assert(PyAnySet_CheckExact(lazy_submodules)); + Py_BEGIN_CRITICAL_SECTION(lazy_submodules); + publish_lazy_imports_on_module(tstate, lazy_submodules, name, module_dict); + Py_END_CRITICAL_SECTION(); + Py_DECREF(lazy_submodules); + + // once a module is imported it is removed from sys.lazy_modules + if (PyDict_DelItem(lazy_modules, name) < 0) { + goto error; + } + +done: + ret = Py_NewRef(Py_None); + +error: + Py_XDECREF(module_dict); + return ret; +} PyDoc_STRVAR(doc_imp, "(Extremely) low-level import machinery bits as used by importlib."); @@ -4993,6 +5672,7 @@ static PyMethodDef imp_methods[] = { _IMP_EXEC_BUILTIN_METHODDEF _IMP__FIX_CO_FILENAME_METHODDEF _IMP_SOURCE_HASH_METHODDEF + _IMP__SET_LAZY_ATTRIBUTES_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Python/initconfig.c b/Python/initconfig.c index 46fd8929041f45..5ffee9eaf9f550 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -111,6 +111,7 @@ static const PyConfigSpec PYCONFIG_SPEC[] = { SPEC(base_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("base_prefix")), SPEC(bytes_warning, UINT, PUBLIC, SYS_FLAG(9)), SPEC(cpu_count, INT, PUBLIC, NO_SYS), + SPEC(lazy_imports, INT, PUBLIC, NO_SYS), SPEC(exec_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("exec_prefix")), SPEC(executable, WSTR_OPT, PUBLIC, SYS_ATTR("executable")), SPEC(inspect, BOOL, PUBLIC, SYS_FLAG(1)), @@ -318,6 +319,8 @@ The following implementation-specific options are available:\n\ "\ -X importtime[=2]: show how long each import takes; use -X importtime=2 to\n\ log imports of already-loaded modules; also PYTHONPROFILEIMPORTTIME\n\ +-X lazy_imports=[all|none|normal]: control global lazy imports;\n\ + default is normal; also PYTHON_LAZY_IMPORTS\n\ -X int_max_str_digits=N: limit the size of int<->str conversions;\n\ 0 disables the limit; also PYTHONINTMAXSTRDIGITS\n\ -X no_debug_ranges: don't include extra location information in code objects;\n\ @@ -432,6 +435,7 @@ static const char usage_envvars[] = "PYTHON_PRESITE: import this module before site (-X presite)\n" #endif "PYTHONPROFILEIMPORTTIME: show how long each import takes (-X importtime)\n" +"PYTHON_LAZY_IMPORTS: control global lazy imports (-X lazy_imports)\n" "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files\n" " (-X pycache_prefix)\n" "PYTHONSAFEPATH : don't prepend a potentially unsafe path to sys.path.\n" @@ -941,6 +945,8 @@ config_check_consistency(const PyConfig *config) assert(config->int_max_str_digits >= 0); // cpu_count can be -1 if the user doesn't override it. assert(config->cpu_count != 0); + // lazy_imports can be -1 (default), 0 (off), or 1 (on). + assert(config->lazy_imports >= -1 && config->lazy_imports <= 1); // config->use_frozen_modules is initialized later // by _PyConfig_InitImportConfig(). assert(config->thread_inherit_context >= 0); @@ -1052,6 +1058,7 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->_is_python_build = 0; config->code_debug_ranges = 1; config->cpu_count = -1; + config->lazy_imports = -1; #ifdef Py_GIL_DISABLED config->thread_inherit_context = 1; config->context_aware_warnings = 1; @@ -2300,6 +2307,49 @@ config_init_import_time(PyConfig *config) return _PyStatus_OK(); } +static PyStatus +config_init_lazy_imports(PyConfig *config) +{ + int lazy_imports = -1; + + const char *env = config_get_env(config, "PYTHON_LAZY_IMPORTS"); + if (env) { + if (strcmp(env, "all") == 0) { + lazy_imports = 1; + } + else if (strcmp(env, "none") == 0) { + lazy_imports = 0; + } + else if (strcmp(env, "normal") == 0) { + lazy_imports = -1; + } + else { + return _PyStatus_ERR("PYTHON_LAZY_IMPORTS: invalid value; " + "expected 'all', 'none', or 'normal'"); + } + config->lazy_imports = lazy_imports; + } + + const wchar_t *x_value = config_get_xoption_value(config, L"lazy_imports"); + if (x_value) { + if (wcscmp(x_value, L"all") == 0) { + lazy_imports = 1; + } + else if (wcscmp(x_value, L"none") == 0) { + lazy_imports = 0; + } + else if (wcscmp(x_value, L"normal") == 0) { + lazy_imports = -1; + } + else { + return _PyStatus_ERR("-X lazy_imports: invalid value; " + "expected 'all', 'none', or 'normal'"); + } + config->lazy_imports = lazy_imports; + } + return _PyStatus_OK(); +} + static PyStatus config_read_complex_options(PyConfig *config) { @@ -2323,6 +2373,13 @@ config_read_complex_options(PyConfig *config) } } + if (config->lazy_imports < 0) { + status = config_init_lazy_imports(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->tracemalloc < 0) { status = config_init_tracemalloc(config); if (_PyStatus_EXCEPTION(status)) { @@ -2712,6 +2769,9 @@ config_read(PyConfig *config, int compute_path_config) if (config->tracemalloc < 0) { config->tracemalloc = 0; } + if (config->lazy_imports < 0) { + config->lazy_imports = -1; // Default is auto/unset + } if (config->perf_profiling < 0) { config->perf_profiling = 0; } diff --git a/Python/jit.c b/Python/jit.c index 7e47b70f1f48f6..0791d042710efb 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -11,9 +11,11 @@ #include "pycore_floatobject.h" #include "pycore_frame.h" #include "pycore_function.h" +#include "pycore_import.h" #include "pycore_interpframe.h" #include "pycore_interpolation.h" #include "pycore_intrinsics.h" +#include "pycore_lazyimportobject.h" #include "pycore_list.h" #include "pycore_long.h" #include "pycore_mmap.h" diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index bb51f8d191c1c3..7dfeb5b847b254 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -15,6 +15,7 @@ #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interpolation.h" // _PyInterpolation_InitTypes() #include "pycore_long.h" // _PyLong_InitTypes() +#include "pycore_moduleobject.h" // _PyModule_InitModuleDictWatcher() #include "pycore_object.h" // _PyDebug_PrintTotalRefs() #include "pycore_obmalloc.h" // _PyMem_init_obmalloc() #include "pycore_optimizer.h" // _Py_Executors_InvalidateAll @@ -632,6 +633,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime, _PyInterpreterState_SetWhence(interp, _PyInterpreterState_WHENCE_RUNTIME); interp->_ready = 1; + /* Initialize the module dict watcher early, before any modules are created */ + if (_PyModule_InitModuleDictWatcher(interp) != 0) { + return _PyStatus_ERR("failed to initialize module dict watcher"); + } + status = _PyConfig_Copy(&interp->config, src_config); if (_PyStatus_EXCEPTION(status)) { return status; @@ -1335,6 +1341,22 @@ init_interp_main(PyThreadState *tstate) } } + // Initialize lazy imports based on configuration. Do this after site + // module is imported to avoid circular imports during startup. + if (config->lazy_imports != -1) { + PyImport_LazyImportsMode lazy_mode; + if (config->lazy_imports == 1) { + lazy_mode = PyImport_LAZY_ALL; + } + else { + lazy_mode = PyImport_LAZY_NONE; + } + if (PyImport_SetLazyImportsMode(lazy_mode) < 0) { + return _PyStatus_ERR("failed to set lazy imports mode"); + } + } + // If config->lazy_imports == -1, use the default mode, no change needed. + if (is_main_interp) { #ifndef MS_WINDOWS emit_stderr_warning_for_legacy_locale(interp->runtime); @@ -1802,6 +1824,9 @@ finalize_modules(PyThreadState *tstate) // initialization API) _PyImport_ClearModulesByIndex(interp); + // Clear the dict of lazily loaded module nname to submodule names + _PyImport_ClearLazyModules(interp); + // Clear and delete the modules directory. Actual modules will // still be there only if imported during the execution of some // destructor. @@ -2449,6 +2474,11 @@ new_interpreter(PyThreadState **tstate_p, _PyInterpreterState_SetWhence(interp, whence); interp->_ready = 1; + /* Initialize the module dict watcher early, before any modules are created */ + if (_PyModule_InitModuleDictWatcher(interp) != 0) { + goto error; + } + /* From this point until the init_interp_create_gil() call, we must not do anything that requires that the GIL be held (or otherwise exist). That applies whether or not the new diff --git a/Python/specialize.c b/Python/specialize.c index 21e0eb802dd099..7c02e929d47d9e 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -8,6 +8,7 @@ #include "pycore_dict.h" // DICT_KEYS_UNICODE #include "pycore_function.h" // _PyFunction_GetVersionForCurrentState() #include "pycore_interpframe.h" // FRAME_SPECIALS_SIZE +#include "pycore_lazyimportobject.h" // PyLazyImport_CheckExact #include "pycore_list.h" // _PyListIterObject #include "pycore_long.h" // _PyLong_IsNonNegativeCompact() #include "pycore_moduleobject.h" @@ -129,6 +130,7 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters #define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD 22 #define SPEC_FAIL_ATTR_CLASS_METHOD_OBJ 23 #define SPEC_FAIL_ATTR_OBJECT_SLOT 24 +#define SPEC_FAIL_ATTR_MODULE_LAZY_VALUE 25 #define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26 #define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27 @@ -383,6 +385,10 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P } PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); + if (value != NULL && PyLazyImport_CheckExact(value)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); + return -1; + } assert(index != DKIX_ERROR); if (index != (uint16_t)index) { SPECIALIZATION_FAIL(LOAD_ATTR, @@ -1307,16 +1313,17 @@ specialize_load_global_lock_held( SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); goto fail; } -#ifdef Py_GIL_DISABLED PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue((PyDictObject *)globals, name, &value); -#else - Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name); -#endif if (index == DKIX_ERROR) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR); goto fail; } + if (value != NULL && PyLazyImport_CheckExact(value)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); + Py_DECREF(value); + goto fail; + } PyInterpreterState *interp = _PyInterpreterState_GET(); if (index != DKIX_EMPTY) { if (index != (uint16_t)index) { diff --git a/Python/symtable.c b/Python/symtable.c index 29ac8f6880c575..beb6df88d097e3 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -141,6 +141,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_needs_classdict = 0; ste->ste_has_conditional_annotations = 0; ste->ste_in_conditional_block = 0; + ste->ste_in_try_block = 0; ste->ste_in_unevaluated_annotation = 0; ste->ste_annotation_block = NULL; @@ -1747,6 +1748,13 @@ symtable_enter_type_param_block(struct symtable *st, identifier name, #define LEAVE_CONDITIONAL_BLOCK(ST) \ (ST)->st_cur->ste_in_conditional_block = in_conditional_block; +#define ENTER_TRY_BLOCK(ST) \ + int in_try_block = (ST)->st_cur->ste_in_try_block; \ + (ST)->st_cur->ste_in_try_block = 1; + +#define LEAVE_TRY_BLOCK(ST) \ + (ST)->st_cur->ste_in_try_block = in_try_block; + #define ENTER_RECURSIVE() \ if (Py_EnterRecursiveCall(" during compilation")) { \ return 0; \ @@ -1808,6 +1816,38 @@ check_import_from(struct symtable *st, stmt_ty s) return 1; } +static int +check_lazy_import_context(struct symtable *st, stmt_ty s, + const char* import_type) +{ + // Check if inside try/except block. + if (st->st_cur->ste_in_try_block) { + PyErr_Format(PyExc_SyntaxError, + "lazy %s not allowed inside try/except blocks", + import_type); + SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); + return 0; + } + + // Check if inside function scope. + if (st->st_cur->ste_type == FunctionBlock) { + PyErr_Format(PyExc_SyntaxError, + "lazy %s not allowed inside functions", import_type); + SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); + return 0; + } + + // Check if inside class scope. + if (st->st_cur->ste_type == ClassBlock) { + PyErr_Format(PyExc_SyntaxError, + "lazy %s not allowed inside classes", import_type); + SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); + return 0; + } + + return 1; +} + static bool allows_top_level_await(struct symtable *st) { @@ -2076,19 +2116,23 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case Try_kind: { ENTER_CONDITIONAL_BLOCK(st); + ENTER_TRY_BLOCK(st); VISIT_SEQ(st, stmt, s->v.Try.body); VISIT_SEQ(st, excepthandler, s->v.Try.handlers); VISIT_SEQ(st, stmt, s->v.Try.orelse); VISIT_SEQ(st, stmt, s->v.Try.finalbody); + LEAVE_TRY_BLOCK(st); LEAVE_CONDITIONAL_BLOCK(st); break; } case TryStar_kind: { ENTER_CONDITIONAL_BLOCK(st); + ENTER_TRY_BLOCK(st); VISIT_SEQ(st, stmt, s->v.TryStar.body); VISIT_SEQ(st, excepthandler, s->v.TryStar.handlers); VISIT_SEQ(st, stmt, s->v.TryStar.orelse); VISIT_SEQ(st, stmt, s->v.TryStar.finalbody); + LEAVE_TRY_BLOCK(st); LEAVE_CONDITIONAL_BLOCK(st); break; } @@ -2098,9 +2142,33 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT(st, expr, s->v.Assert.msg); break; case Import_kind: + if (s->v.Import.is_lazy) { + if (!check_lazy_import_context(st, s, "import")) { + return 0; + } + } VISIT_SEQ(st, alias, s->v.Import.names); break; case ImportFrom_kind: + if (s->v.ImportFrom.is_lazy) { + if (!check_lazy_import_context(st, s, "from ... import")) { + return 0; + } + + // Check for import * + for (Py_ssize_t i = 0; i < asdl_seq_LEN(s->v.ImportFrom.names); + i++) { + alias_ty alias = (alias_ty)asdl_seq_GET( + s->v.ImportFrom.names, i); + if (alias->name && + _PyUnicode_EqualToASCIIString(alias->name, "*")) { + PyErr_SetString(PyExc_SyntaxError, + "lazy from ... import * is not allowed"); + SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); + return 0; + } + } + } VISIT_SEQ(st, alias, s->v.ImportFrom.names); if (!check_import_from(st, s)) { return 0; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 61dbe5edb87186..28b2108940c853 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2785,6 +2785,128 @@ PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) { return 0; } +/*[clinic input] +sys.set_lazy_imports_filter + + filter: object + +Set the lazy imports filter callback. + +The filter is a callable which disables lazy imports when they +would otherwise be enabled. Returns True if the import is still enabled +or False to disable it. The callable is called with: + +(importing_module_name, imported_module_name, [fromlist]) + +Pass None to clear the filter. +[clinic start generated code]*/ + +static PyObject * +sys_set_lazy_imports_filter_impl(PyObject *module, PyObject *filter) +/*[clinic end generated code: output=10251d49469c278c input=2eb48786bdd4ee42]*/ +{ + if (PyImport_SetLazyImportsFilter(filter) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +/*[clinic input] +sys.get_lazy_imports_filter + +Get the current lazy imports filter callback. + +Returns the filter callable or None if no filter is set. +[clinic start generated code]*/ + +static PyObject * +sys_get_lazy_imports_filter_impl(PyObject *module) +/*[clinic end generated code: output=3bf73022892165af input=cf1e07cb8e203c94]*/ +{ + PyObject *filter = PyImport_GetLazyImportsFilter(); + if (filter == NULL) { + assert(!PyErr_Occurred()); + Py_RETURN_NONE; + } + return filter; +} + +/*[clinic input] +sys.set_lazy_imports + + mode: object + +Sets the global lazy imports mode. + +The mode parameter must be one of the following strings: +- "all": All top-level imports become potentially lazy +- "none": All lazy imports are suppressed (even explicitly marked ones) +- "normal": Only explicitly marked imports (with 'lazy' keyword) are lazy + +In addition to the mode, lazy imports can be controlled via the filter +provided to sys.set_lazy_imports_filter + +[clinic start generated code]*/ + +static PyObject * +sys_set_lazy_imports_impl(PyObject *module, PyObject *mode) +/*[clinic end generated code: output=1ff34ba6c4feaf73 input=f04e70d8bf9fe4f6]*/ +{ + PyImport_LazyImportsMode lazy_mode; + if (!PyUnicode_Check(mode)) { + PyErr_SetString(PyExc_TypeError, + "mode must be a string: 'normal', 'all', or 'none'"); + return NULL; + } + if (PyUnicode_CompareWithASCIIString(mode, "normal") == 0) { + lazy_mode = PyImport_LAZY_NORMAL; + } + else if (PyUnicode_CompareWithASCIIString(mode, "all") == 0) { + lazy_mode = PyImport_LAZY_ALL; + } + else if (PyUnicode_CompareWithASCIIString(mode, "none") == 0) { + lazy_mode = PyImport_LAZY_NONE; + } + else { + PyErr_SetString(PyExc_ValueError, + "mode must be 'normal', 'all', or 'none'"); + return NULL; + } + + if (PyImport_SetLazyImportsMode(lazy_mode)) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +sys.get_lazy_imports + +Gets the global lazy imports mode. + +Returns "all" if all top level imports are potentially lazy. +Returns "none" if all explicitly marked lazy imports are suppressed. +Returns "normal" if only explicitly marked imports are lazy. + +[clinic start generated code]*/ + +static PyObject * +sys_get_lazy_imports_impl(PyObject *module) +/*[clinic end generated code: output=4147dec48c51ae99 input=8cb574f1e4e3003c]*/ +{ + switch (PyImport_GetLazyImportsMode()) { + case PyImport_LAZY_NORMAL: + return PyUnicode_FromString("normal"); + case PyImport_LAZY_ALL: + return PyUnicode_FromString("all"); + case PyImport_LAZY_NONE: + return PyUnicode_FromString("none"); + default: + PyErr_SetString(PyExc_RuntimeError, "unknown lazy imports mode"); + return NULL; + } +} static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ @@ -2850,6 +2972,10 @@ static PyMethodDef sys_methods[] = { SYS_UNRAISABLEHOOK_METHODDEF SYS_GET_INT_MAX_STR_DIGITS_METHODDEF SYS_SET_INT_MAX_STR_DIGITS_METHODDEF + SYS_GET_LAZY_IMPORTS_METHODDEF + SYS_SET_LAZY_IMPORTS_METHODDEF + SYS_GET_LAZY_IMPORTS_FILTER_METHODDEF + SYS_SET_LAZY_IMPORTS_FILTER_METHODDEF SYS__BASEREPL_METHODDEF #ifdef Py_STATS SYS__STATS_ON_METHODDEF @@ -3374,6 +3500,7 @@ static PyStructSequence_Field flags_fields[] = { {"gil", "-X gil"}, {"thread_inherit_context", "-X thread_inherit_context"}, {"context_aware_warnings", "-X context_aware_warnings"}, + {"lazy_imports", "-X lazy_imports"}, {0} }; @@ -3383,7 +3510,7 @@ static PyStructSequence_Desc flags_desc = { "sys.flags", /* name */ flags__doc__, /* doc */ flags_fields, /* fields */ - 18 + 19 }; static void @@ -3476,6 +3603,7 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags) #endif SetFlag(config->thread_inherit_context); SetFlag(config->context_aware_warnings); + SetFlag(config->lazy_imports); #undef SetFlagObj #undef SetFlag return 0; @@ -4203,6 +4331,15 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) goto error; } + PyObject *lazy_modules = _PyImport_InitLazyModules(interp); // borrowed reference + if (lazy_modules == NULL) { + goto error; + } + + if (PyDict_SetItemString(sysdict, "lazy_modules", lazy_modules) < 0) { + goto error; + } + PyStatus status = _PySys_SetPreliminaryStderr(sysdict); if (_PyStatus_EXCEPTION(status)) { return status; diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 301784f773d31f..d645d2b6150d34 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -59,6 +59,7 @@ Objects/interpolationobject.c - _PyInterpolation_Type - Objects/iterobject.c - PyCallIter_Type - Objects/iterobject.c - PySeqIter_Type - Objects/iterobject.c - _PyAnextAwaitable_Type - +Objects/lazyimportobject.c - PyLazyImport_Type - Objects/listobject.c - PyListIter_Type - Objects/listobject.c - PyListRevIter_Type - Objects/listobject.c - PyList_Type - @@ -176,6 +177,7 @@ Objects/exceptions.c - _PyExc_StopIteration - Objects/exceptions.c - _PyExc_GeneratorExit - Objects/exceptions.c - _PyExc_SystemExit - Objects/exceptions.c - _PyExc_KeyboardInterrupt - +Objects/exceptions.c - _PyExc_ImportCycleError - Objects/exceptions.c - _PyExc_ImportError - Objects/exceptions.c - _PyExc_ModuleNotFoundError - Objects/exceptions.c - _PyExc_OSError - @@ -242,6 +244,7 @@ Objects/exceptions.c - PyExc_StopIteration - Objects/exceptions.c - PyExc_GeneratorExit - Objects/exceptions.c - PyExc_SystemExit - Objects/exceptions.c - PyExc_KeyboardInterrupt - +Objects/exceptions.c - PyExc_ImportCycleError - Objects/exceptions.c - PyExc_ImportError - Objects/exceptions.c - PyExc_ModuleNotFoundError - Objects/exceptions.c - PyExc_OSError - diff --git a/Tools/jit/template.c b/Tools/jit/template.c index 3537c74a820365..afdd9b77e7c7ff 100644 --- a/Tools/jit/template.c +++ b/Tools/jit/template.c @@ -12,9 +12,11 @@ #include "pycore_frame.h" #include "pycore_function.h" #include "pycore_genobject.h" +#include "pycore_import.h" #include "pycore_interpframe.h" #include "pycore_interpolation.h" #include "pycore_intrinsics.h" +#include "pycore_lazyimportobject.h" #include "pycore_jit.h" #include "pycore_list.h" #include "pycore_long.h" From f912c835b94d75ae4823153c160f0cc674a243bb Mon Sep 17 00:00:00 2001 From: Adorilson Bezerra Date: Thu, 12 Feb 2026 07:40:17 +0000 Subject: [PATCH 084/498] gh-106318: Fix incorrectly rendered code block in `str.isalnum()` docs (GH-144718) --- Doc/library/stdtypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 0e5f5dc39e7277..d4540e0b819871 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2183,7 +2183,7 @@ expression support in the :mod:`re` module). Return ``True`` if all characters in the string are alphanumeric and there is at least one character, ``False`` otherwise. A character ``c`` is alphanumeric if one of the following returns ``True``: ``c.isalpha()``, ``c.isdecimal()``, - ``c.isdigit()``, or ``c.isnumeric()``. For example:: + ``c.isdigit()``, or ``c.isnumeric()``. For example: .. doctest:: From 7854597d885482bda7b50067ad2031d0ff0782c7 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 12 Feb 2026 08:18:36 +0000 Subject: [PATCH 085/498] gh-142349: Fix build errors from PEP 810 (#144726) --- Include/import.h | 2 +- Lib/test/test_peg_generator/test_c_parser.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Include/import.h b/Include/import.h index cc7ad71f2676a2..6f1c13787b8569 100644 --- a/Include/import.h +++ b/Include/import.h @@ -91,7 +91,7 @@ PyAPI_FUNC(int) PyImport_AppendInittab( typedef enum { PyImport_LAZY_NORMAL, PyImport_LAZY_ALL, - PyImport_LAZY_NONE, + PyImport_LAZY_NONE } PyImport_LazyImportsMode; #ifndef Py_LIMITED_API diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index 395f15b9a62cdf..3500f229b1b386 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -356,9 +356,9 @@ def test_same_name_different_types(self) -> None: grammar_source = """ start[mod_ty]: a[asdl_stmt_seq*]=import_from+ NEWLINE ENDMARKER { _PyAST_Module(a, NULL, p->arena)} import_from[stmt_ty]: ( a='from' !'import' c=simple_name 'import' d=import_as_names_from { - _PyAST_ImportFrom(c->v.Name.id, d, 0, EXTRA) } + _PyAST_ImportFrom(c->v.Name.id, d, 0, 0, EXTRA) } | a='from' '.' 'import' c=import_as_names_from { - _PyAST_ImportFrom(NULL, c, 1, EXTRA) } + _PyAST_ImportFrom(NULL, c, 1, 0, EXTRA) } ) simple_name[expr_ty]: NAME import_as_names_from[asdl_alias_seq*]: a[asdl_alias_seq*]=','.import_as_name_from+ { a } From 51a408ed779ced7c7a769447c5f7e9881d2cbb4a Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 12 Feb 2026 08:55:26 +0000 Subject: [PATCH 086/498] Add missing step to `Modules/expat/refresh.sh` instructions (GH-144719) --- Modules/expat/refresh.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/expat/refresh.sh b/Modules/expat/refresh.sh index 550340467a15a7..0e0bc0652c5539 100755 --- a/Modules/expat/refresh.sh +++ b/Modules/expat/refresh.sh @@ -64,13 +64,16 @@ This may be due to source changes and will require updating this script" >&2 exit 1 fi -echo " +echo ' Updated! next steps: - Verify all is okay: git diff git status -- Regenerate the sbom file +- Update the sbom file: + Under the package "SPDXRef-PACKAGE-expat", update the "checksumValue", + "downloadLocation", "referenceLocator", and "versionInfo" fields. +- Regenerate the sbom file: make regen-sbom -- Update warning count in Tools/build/.warningignore_macos +- Update the warning count in Tools/build/.warningignore_macos: (use info from CI if not on a Mac) -" +' From 2e3e76e5cde34786780f5b3723f495fdbdf37c84 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 12 Feb 2026 10:35:42 +0000 Subject: [PATCH 087/498] gh-57095: Add note about input splitting in `datetime.*.strptime` (GH-131049) Co-authored-by: Petr Viktorin --- Doc/library/datetime.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 7c172471b195d6..d861139cec6db5 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2689,6 +2689,12 @@ For the :meth:`.datetime.strptime` and :meth:`.date.strptime` class methods, the default value is ``1900-01-01T00:00:00.000``: any components not specified in the format string will be pulled from the default value. +.. note:: + Format strings without separators can be ambiguous for parsing. For + example, with ``%Y%m%d``, the string ``2026111`` may be parsed either as + ``2026-11-01`` or as ``2026-01-11``. + Use separators to ensure the input is parsed as intended. + .. note:: When used to parse partial dates lacking a year, :meth:`.datetime.strptime` and :meth:`.date.strptime` will raise when encountering February 29 because From 072cd7c33627a90e9399d9d880d764407584b08e Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Thu, 12 Feb 2026 11:45:28 +0000 Subject: [PATCH 088/498] gh-142349: Fix refcount corruption in lazy import specialization (#144733) Remove spurious Py_DECREF on borrowed ref in LOAD_GLOBAL specialization _PyDict_LookupIndexAndValue() returns a borrowed reference via _Py_dict_lookup(), but specialize_load_global_lock_held() called Py_DECREF(value) on it when bailing out for lazy imports. Each time the adaptive counter fired while a lazy import was still in globals, this stole one reference from the dict's object. With 8+ threads racing through LOAD_GLOBAL during concurrent lazy import resolution, enough triggers accumulated to drive the refcount to zero while the dict and other threads still referenced the object, causing use-after-free. --- Python/specialize.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/specialize.c b/Python/specialize.c index 7c02e929d47d9e..5ba016f83ea077 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1321,7 +1321,6 @@ specialize_load_global_lock_held( } if (value != NULL && PyLazyImport_CheckExact(value)) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); - Py_DECREF(value); goto fail; } PyInterpreterState *interp = _PyInterpreterState_GET(); From b6b72e766338490305f756e25b0e4725e1b31cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Thu, 12 Feb 2026 15:12:49 +0100 Subject: [PATCH 089/498] gh-144285: Improve `AttributeError` attribute suggestions (#144299) --- Lib/idlelib/idle_test/test_run.py | 2 +- Lib/test/test_traceback.py | 58 ++++++++++--------- Lib/traceback.py | 23 +++++--- ...-02-07-16-31-42.gh-issue-144285.iyH9iL.rst | 3 + 4 files changed, 49 insertions(+), 37 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 83ecbffa2a197e..9a9d3b7b4e219c 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -44,7 +44,7 @@ def __eq__(self, other): "Or did you forget to import 'abc'?\n"), ('int.reel', AttributeError, "type object 'int' has no attribute 'reel'. " - "Did you mean: 'real'?\n"), + "Did you mean '.real' instead of '.reel'?\n"), ) @force_not_colorized diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index eaca62b12d3eb1..99ac7fd83d91cb 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4176,25 +4176,25 @@ class CaseChangeOverSubstitution: BLuch = None for cls, suggestion in [ - (Addition, "'bluchin'?"), - (Substitution, "'blech'?"), - (Elimination, "'blch'?"), - (Addition, "'bluchin'?"), - (SubstitutionOverElimination, "'blach'?"), - (SubstitutionOverAddition, "'blach'?"), - (EliminationOverAddition, "'bluc'?"), - (CaseChangeOverSubstitution, "'BLuch'?"), + (Addition, "'.bluchin'"), + (Substitution, "'.blech'"), + (Elimination, "'.blch'"), + (Addition, "'.bluchin'"), + (SubstitutionOverElimination, "'.blach'"), + (SubstitutionOverAddition, "'.blach'"), + (EliminationOverAddition, "'.bluc'"), + (CaseChangeOverSubstitution, "'.BLuch'"), ]: actual = self.get_suggestion(cls(), 'bluch') - self.assertIn(suggestion, actual) + self.assertIn('Did you mean ' + suggestion, actual) def test_suggestions_underscored(self): class A: bluch = None - self.assertIn("'bluch'", self.get_suggestion(A(), 'blach')) - self.assertIn("'bluch'", self.get_suggestion(A(), '_luch')) - self.assertIn("'bluch'", self.get_suggestion(A(), '_bluch')) + self.assertIn("'.bluch'", self.get_suggestion(A(), 'blach')) + self.assertIn("'.bluch'", self.get_suggestion(A(), '_luch')) + self.assertIn("'.bluch'", self.get_suggestion(A(), '_bluch')) attr_function = self.attr_function class B: @@ -4202,13 +4202,13 @@ class B: def method(self, name): attr_function(self, name) - self.assertIn("'_bluch'", self.get_suggestion(B(), '_blach')) - self.assertIn("'_bluch'", self.get_suggestion(B(), '_luch')) - self.assertNotIn("'_bluch'", self.get_suggestion(B(), 'bluch')) + self.assertIn("'._bluch'", self.get_suggestion(B(), '_blach')) + self.assertIn("'._bluch'", self.get_suggestion(B(), '_luch')) + self.assertNotIn("'._bluch'", self.get_suggestion(B(), 'bluch')) - self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, '_blach'))) - self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, '_luch'))) - self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, 'bluch'))) + self.assertIn("'._bluch'", self.get_suggestion(partial(B().method, '_blach'))) + self.assertIn("'._bluch'", self.get_suggestion(partial(B().method, '_luch'))) + self.assertIn("'._bluch'", self.get_suggestion(partial(B().method, 'bluch'))) def test_do_not_trigger_for_long_attributes(self): @@ -4256,7 +4256,7 @@ class A: fiⁿₐˡᵢᶻₐᵗᵢᵒₙ = None suggestion = self.get_suggestion(A(), 'fiⁿₐˡᵢᶻₐᵗᵢᵒₙ') - self.assertIn("'finalization'", suggestion) + self.assertIn("'.finalization'", suggestion) self.assertNotIn("analization", suggestion) class B: @@ -4264,8 +4264,10 @@ class B: attr_µ = None # attr_\xb5 suggestion = self.get_suggestion(B(), 'attr_\xb5') - self.assertIn("'attr_\u03bc'", suggestion) - self.assertIn(r"'attr_\u03bc'", suggestion) + self.assertIn( + "'.attr_\u03bc' ('attr_\\u03bc') " + "instead of '.attr_\xb5' ('attr_\\xb5')", + suggestion) self.assertNotIn("attr_a", suggestion) @@ -4371,11 +4373,11 @@ def __init__(self): # Should suggest 'inner.value' actual = self.get_suggestion(Outer(), 'value') - self.assertIn("Did you mean: 'inner.value'", actual) + self.assertIn("Did you mean '.inner.value' instead of '.value'", actual) # Should suggest 'inner.data' actual = self.get_suggestion(Outer(), 'data') - self.assertIn("Did you mean: 'inner.data'", actual) + self.assertIn("Did you mean '.inner.data' instead of '.data'", actual) def test_getattr_nested_prioritizes_direct_matches(self): # Test that direct attribute matches are prioritized over nested ones @@ -4390,7 +4392,7 @@ def __init__(self): # Should suggest 'fooo' (direct) not 'inner.foo' (nested) actual = self.get_suggestion(Outer(), 'foo') - self.assertIn("Did you mean: 'fooo'", actual) + self.assertIn("Did you mean '.fooo'", actual) self.assertNotIn("inner.foo", actual) def test_getattr_nested_with_property(self): @@ -4487,7 +4489,7 @@ def __init__(self): # Should suggest only the first match (alphabetically) actual = self.get_suggestion(Outer(), 'value') - self.assertIn("'a_inner.value'", actual) + self.assertIn("'.a_inner.value'", actual) # Verify it's a single suggestion, not multiple self.assertEqual(actual.count("Did you mean"), 1) @@ -4510,10 +4512,10 @@ def __init__(self): self.exploder = ExplodingProperty() # Accessing attributes will raise self.safe_inner = SafeInner() - # Should still suggest 'safe_inner.target' without crashing + # Should still suggest '.safe_inner.target' without crashing # even though accessing exploder.target would raise an exception actual = self.get_suggestion(Outer(), 'target') - self.assertIn("'safe_inner.target'", actual) + self.assertIn("'.safe_inner.target'", actual) def test_getattr_nested_handles_hasattr_exceptions(self): # Test that exceptions in hasattr don't crash the system @@ -4534,7 +4536,7 @@ def __init__(self): # Should still find 'normal.target' even though weird.target check fails actual = self.get_suggestion(Outer(), 'target') - self.assertIn("'normal.target'", actual) + self.assertIn("'.normal.target'", actual) def make_module(self, code): tmpdir = Path(tempfile.mkdtemp()) diff --git a/Lib/traceback.py b/Lib/traceback.py index b121733c27fd8c..42453b4867ce99 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1128,7 +1128,16 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, self._str += (". Site initialization is disabled, did you forget to " + "add the site-packages directory to sys.path " + "or to enable your virtual environment?") - elif exc_type and issubclass(exc_type, (NameError, AttributeError)) and \ + elif exc_type and issubclass(exc_type, AttributeError) and \ + getattr(exc_value, "name", None) is not None: + wrong_name = getattr(exc_value, "name", None) + suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) + if suggestion: + if suggestion.isascii(): + self._str += f". Did you mean '.{suggestion}' instead of '.{wrong_name}'?" + else: + self._str += f". Did you mean '.{suggestion}' ({suggestion!a}) instead of '.{wrong_name}' ({wrong_name!a})?" + elif exc_type and issubclass(exc_type, NameError) and \ getattr(exc_value, "name", None) is not None: wrong_name = getattr(exc_value, "name", None) suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) @@ -1137,13 +1146,11 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, self._str += f". Did you mean: '{suggestion}'?" else: self._str += f". Did you mean: '{suggestion}' ({suggestion!a})?" - if issubclass(exc_type, NameError): - wrong_name = getattr(exc_value, "name", None) - if wrong_name is not None and wrong_name in sys.stdlib_module_names: - if suggestion: - self._str += f" Or did you forget to import '{wrong_name}'?" - else: - self._str += f". Did you forget to import '{wrong_name}'?" + if wrong_name is not None and wrong_name in sys.stdlib_module_names: + if suggestion: + self._str += f" Or did you forget to import '{wrong_name}'?" + else: + self._str += f". Did you forget to import '{wrong_name}'?" if lookup_lines: self._load_lines() self.__suppress_context__ = \ diff --git a/Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst b/Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst new file mode 100644 index 00000000000000..e1119a85e9c1f3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst @@ -0,0 +1,3 @@ +Attribute suggestions in :exc:`AttributeError` tracebacks are now formatted differently +to make them easier to understand, for example: ``Did you mean '.datetime.now' instead of '.now'``. +Contributed by Bartosz Sławecki. From eb6ebdbc95aa8d62ac3169e72aac164a21c5679c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 16:19:50 +0100 Subject: [PATCH 090/498] gh-138744: Upgrade Windows to 2025 in GitHub Actions (#144682) Replace windows-2022 with windows-2025. --- .github/workflows/jit.yml | 4 ++-- .github/workflows/reusable-windows-msi.yml | 2 +- .github/workflows/reusable-windows.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/jit.yml b/.github/workflows/jit.yml index cd6e9875d282d2..5a564b63f9d120 100644 --- a/.github/workflows/jit.yml +++ b/.github/workflows/jit.yml @@ -74,10 +74,10 @@ jobs: include: - target: i686-pc-windows-msvc/msvc architecture: Win32 - runner: windows-2022 + runner: windows-2025 - target: x86_64-pc-windows-msvc/msvc architecture: x64 - runner: windows-2022 + runner: windows-2025 - target: aarch64-pc-windows-msvc/msvc architecture: ARM64 runner: windows-11-arm diff --git a/.github/workflows/reusable-windows-msi.yml b/.github/workflows/reusable-windows-msi.yml index c7611804369600..96fc338c47bf29 100644 --- a/.github/workflows/reusable-windows-msi.yml +++ b/.github/workflows/reusable-windows-msi.yml @@ -17,7 +17,7 @@ env: jobs: build: name: installer for ${{ inputs.arch }} - runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2022' }} + runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025' }} timeout-minutes: 60 env: ARCH: ${{ inputs.arch }} diff --git a/.github/workflows/reusable-windows.yml b/.github/workflows/reusable-windows.yml index 82ea819867ef6d..2f6caf2f0044d4 100644 --- a/.github/workflows/reusable-windows.yml +++ b/.github/workflows/reusable-windows.yml @@ -21,7 +21,7 @@ env: jobs: build: name: Build and test (${{ inputs.arch }}) - runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2022' }} + runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025' }} timeout-minutes: 60 env: ARCH: ${{ inputs.arch }} From 9e5e1f9988faee0a18969d4d7dda6a3e4eaf850b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 17:03:55 +0100 Subject: [PATCH 091/498] gh-121617: Include for Py_CLEAR() macro (#144666) Python.h now also includes in the limited C API version 3.11 and newer to fix the Py_CLEAR() macro which uses memcpy(). Add a Py_CLEAR() test in test_cext. Modify also _Py_TYPEOF to use C23 typeof() if available. --- Doc/c-api/intro.rst | 2 +- Include/Python.h | 4 ++-- Include/pyport.h | 7 +++++-- Lib/test/test_cext/extension.c | 6 +++++- .../C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst | 3 +++ 5 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index a5dfbe7f4e1305..c3a80234f86116 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -123,6 +123,7 @@ System includes * ```` * ```` * ```` + * ```` * ```` * ```` (if present) @@ -138,7 +139,6 @@ System includes * ```` * ```` * ```` - * ```` .. note:: diff --git a/Include/Python.h b/Include/Python.h index 78083bbf31db75..17cbc083241514 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -22,12 +22,13 @@ #include // INT_MAX #include // HUGE_VAL #include // va_list +#include // memcpy() #include // wchar_t #ifdef HAVE_SYS_TYPES_H # include // ssize_t #endif -// , , and headers are no longer used +// , and headers are no longer used // by Python, but kept for the backward compatibility of existing third party C // extensions. They are not included by limited C API version 3.11 and newer. // @@ -37,7 +38,6 @@ # include // errno # include // FILE* # include // getenv() -# include // memcpy() #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000 # include // tolower() diff --git a/Include/pyport.h b/Include/pyport.h index 61e2317976eed1..1e1702abd99a2c 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -567,8 +567,11 @@ extern "C" { // // Example: _Py_TYPEOF(x) x_copy = (x); // -// The macro is only defined if GCC or clang compiler is used. -#if defined(__GNUC__) || defined(__clang__) +// On C23, use typeof(). Otherwise, the macro is only defined +// if GCC or clang compiler is used. +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +# define _Py_TYPEOF(expr) typeof(expr) +#elif defined(__GNUC__) || defined(__clang__) # define _Py_TYPEOF(expr) __typeof__(expr) #endif diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c index a2f6151d8b36ed..a6b30fd627fe99 100644 --- a/Lib/test/test_cext/extension.c +++ b/Lib/test/test_cext/extension.c @@ -76,7 +76,7 @@ static PyMethodDef _testcext_methods[] = { static int _testcext_exec(PyObject *module) { - PyObject *result; + PyObject *result, *obj; #ifdef __STDC_VERSION__ if (PyModule_AddIntMacro(module, __STDC_VERSION__) < 0) { @@ -92,6 +92,10 @@ _testcext_exec(PyObject *module) Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int)); assert(Py_BUILD_ASSERT_EXPR(sizeof(int) == sizeof(unsigned int)) == 0); + // Test Py_CLEAR() + obj = NULL; + Py_CLEAR(obj); + return 0; } diff --git a/Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst b/Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst new file mode 100644 index 00000000000000..cf84f8b1b0d36b --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst @@ -0,0 +1,3 @@ +``Python.h`` now also includes ```` in the limited C API version 3.11 +and newer to fix the :c:macro:`Py_CLEAR` macro which uses ``memcpy()``. Patch +by Victor Stinner. From e66f4a5a9c7ce744030d6352bf5575639b1096cc Mon Sep 17 00:00:00 2001 From: James Date: Thu, 12 Feb 2026 11:50:40 -0500 Subject: [PATCH 092/498] gh-80667: Fix case-sensitivity of some Unicode literal escapes (GH-107281) Lookup for CJK ideograms and Hangul syllables is now case-insensitive, as is the case for other character names. --- Lib/test/test_ucn.py | 8 ++++++++ .../2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst | 2 ++ Modules/unicodedata.c | 15 ++++++++------- 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst diff --git a/Lib/test/test_ucn.py b/Lib/test/test_ucn.py index 0e2c25aaff2fe9..0c641a455c0747 100644 --- a/Lib/test/test_ucn.py +++ b/Lib/test/test_ucn.py @@ -88,6 +88,9 @@ def test_hangul_syllables(self): self.checkletter("HANGUL SYLLABLE HWEOK", "\ud6f8") self.checkletter("HANGUL SYLLABLE HIH", "\ud7a3") + self.checkletter("haNGul SYllABle WAe", '\uc65c') + self.checkletter("HAngUL syLLabLE waE", '\uc65c') + self.assertRaises(ValueError, unicodedata.name, "\ud7a4") def test_cjk_unified_ideographs(self): @@ -103,6 +106,11 @@ def test_cjk_unified_ideographs(self): self.checkletter("CJK UNIFIED IDEOGRAPH-2B81D", "\U0002B81D") self.checkletter("CJK UNIFIED IDEOGRAPH-3134A", "\U0003134A") + self.checkletter("cjK UniFIeD idEogRAph-3aBc", "\u3abc") + self.checkletter("CJk uNIfiEd IDeOGraPH-3AbC", "\u3abc") + self.checkletter("cjK UniFIeD idEogRAph-2aBcD", "\U0002abcd") + self.checkletter("CJk uNIfiEd IDeOGraPH-2AbCd", "\U0002abcd") + def test_bmp_characters(self): for code in range(0x10000): char = chr(code) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst b/Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst new file mode 100644 index 00000000000000..db87a5ed9c7fc2 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst @@ -0,0 +1,2 @@ +Literals using the ``\N{name}`` escape syntax can now construct CJK +ideographs and Hangul syllables using case-insensitive names. diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 091e6bcb9f3f49..44ffedec3840fe 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1405,7 +1405,7 @@ find_syllable(const char *str, int *len, int *pos, int count, int column) len1 = Py_SAFE_DOWNCAST(strlen(s), size_t, int); if (len1 <= *len) continue; - if (strncmp(str, s, len1) == 0) { + if (PyOS_strnicmp(str, s, len1) == 0) { *len = len1; *pos = i; } @@ -1437,7 +1437,7 @@ _getcode(const char* name, int namelen, Py_UCS4* code) * PUA */ /* Check for hangul syllables. */ - if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) { + if (PyOS_strnicmp(name, "HANGUL SYLLABLE ", 16) == 0) { int len, L = -1, V = -1, T = -1; const char *pos = name + 16; find_syllable(pos, &len, &L, LCount, 0); @@ -1455,7 +1455,7 @@ _getcode(const char* name, int namelen, Py_UCS4* code) } /* Check for unified ideographs. */ - if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) { + if (PyOS_strnicmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) { /* Four or five hexdigits must follow. */ unsigned int v; v = 0; @@ -1465,10 +1465,11 @@ _getcode(const char* name, int namelen, Py_UCS4* code) return 0; while (namelen--) { v *= 16; - if (*name >= '0' && *name <= '9') - v += *name - '0'; - else if (*name >= 'A' && *name <= 'F') - v += *name - 'A' + 10; + Py_UCS1 c = Py_TOUPPER(*name); + if (c >= '0' && c <= '9') + v += c - '0'; + else if (c >= 'A' && c <= 'F') + v += c - 'A' + 10; else return 0; name++; From b488f338cf058f46cbf0255023ca1c1669b0eb44 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Feb 2026 19:40:42 +0100 Subject: [PATCH 093/498] gh-135906: Test more internal headers in test_cext/test_cppext (#144751) --- Lib/test/test_cext/extension.c | 5 ++++- Lib/test/test_cppext/extension.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c index a6b30fd627fe99..7555b78f18c2e6 100644 --- a/Lib/test/test_cext/extension.c +++ b/Lib/test/test_cext/extension.c @@ -15,9 +15,11 @@ #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API. - // - Cython uses pycore_frame.h. + // - Cython uses pycore_critical_section.h, pycore_frame.h and + // pycore_template.h. // - greenlet uses pycore_frame.h, pycore_interpframe_structs.h and // pycore_interpframe.h. +# include "internal/pycore_critical_section.h" # include "internal/pycore_frame.h" # include "internal/pycore_gc.h" # include "internal/pycore_interp.h" @@ -25,6 +27,7 @@ # include "internal/pycore_interpframe_structs.h" # include "internal/pycore_object.h" # include "internal/pycore_pystate.h" +# include "internal/pycore_template.h" #endif #ifndef MODULE_NAME diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp index 92c4645039a03b..4db63df94f5233 100644 --- a/Lib/test/test_cppext/extension.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -15,11 +15,20 @@ #ifdef TEST_INTERNAL_C_API // gh-135906: Check for compiler warnings in the internal C API + // - Cython uses pycore_critical_section.h, pycore_frame.h and + // pycore_template.h. + // - greenlet uses pycore_frame.h, pycore_interpframe_structs.h and + // pycore_interpframe.h. # include "internal/pycore_frame.h" +# include "internal/pycore_interpframe_structs.h" +# include "internal/pycore_template.h" + // mimalloc emits compiler warnings on Windows. # if !defined(MS_WINDOWS) # include "internal/pycore_backoff.h" # include "internal/pycore_cell.h" +# include "internal/pycore_critical_section.h" +# include "internal/pycore_interpframe.h" # endif #endif From 66da7bf6fe7b81e3ecc9c0a25bd47d4616c8d1a6 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Thu, 12 Feb 2026 14:40:21 -0600 Subject: [PATCH 094/498] gh-143916: Allow HTAB in wsgiref header values Co-authored-by: Victor Stinner --- Lib/test/test_wsgiref.py | 20 +++++++++++++------- Lib/wsgiref/headers.py | 35 ++++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index d24aaab1327409..a7a5c5ba33d493 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -504,14 +504,20 @@ def testExtras(self): ) def testRaisesControlCharacters(self): - headers = Headers() for c0 in control_characters_c0(): - self.assertRaises(ValueError, headers.__setitem__, f"key{c0}", "val") - self.assertRaises(ValueError, headers.__setitem__, "key", f"val{c0}") - self.assertRaises(ValueError, headers.add_header, f"key{c0}", "val", param="param") - self.assertRaises(ValueError, headers.add_header, "key", f"val{c0}", param="param") - self.assertRaises(ValueError, headers.add_header, "key", "val", param=f"param{c0}") - + with self.subTest(c0): + headers = Headers() + self.assertRaises(ValueError, headers.__setitem__, f"key{c0}", "val") + self.assertRaises(ValueError, headers.add_header, f"key{c0}", "val", param="param") + # HTAB (\x09) is allowed in values, not names. + if c0 == "\t": + headers["key"] = f"val{c0}" + headers.add_header("key", f"val{c0}") + headers.setdefault(f"key", f"val{c0}") + else: + self.assertRaises(ValueError, headers.__setitem__, "key", f"val{c0}") + self.assertRaises(ValueError, headers.add_header, "key", f"val{c0}", param="param") + self.assertRaises(ValueError, headers.add_header, "key", "val", param=f"param{c0}") class ErrorHandler(BaseCGIHandler): """Simple handler subclass for testing BaseHandler""" diff --git a/Lib/wsgiref/headers.py b/Lib/wsgiref/headers.py index e180a623cb2c30..eb6ea6a412dcc9 100644 --- a/Lib/wsgiref/headers.py +++ b/Lib/wsgiref/headers.py @@ -9,7 +9,11 @@ # existence of which force quoting of the parameter value. import re tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') -_control_chars_re = re.compile(r'[\x00-\x1F\x7F]') +# Disallowed characters for headers and values. +# HTAB (\x09) is allowed in header values, but +# not in header names. (RFC 9110 Section 5.5) +_name_disallowed_re = re.compile(r'[\x00-\x1F\x7F]') +_value_disallowed_re = re.compile(r'[\x00-\x08\x0A-\x1F\x7F]') def _formatparam(param, value=None, quote=1): """Convenience function to format and return a key=value pair. @@ -36,13 +40,14 @@ def __init__(self, headers=None): self._headers = headers if __debug__: for k, v in headers: - self._convert_string_type(k) - self._convert_string_type(v) + self._convert_string_type(k, name=True) + self._convert_string_type(v, name=False) - def _convert_string_type(self, value): + def _convert_string_type(self, value, *, name): """Convert/check value type.""" if type(value) is str: - if _control_chars_re.search(value): + regex = (_name_disallowed_re if name else _value_disallowed_re) + if regex.search(value): raise ValueError("Control characters not allowed in headers") return value raise AssertionError("Header names/values must be" @@ -56,14 +61,14 @@ def __setitem__(self, name, val): """Set the value of a header.""" del self[name] self._headers.append( - (self._convert_string_type(name), self._convert_string_type(val))) + (self._convert_string_type(name, name=True), self._convert_string_type(val, name=False))) def __delitem__(self,name): """Delete all occurrences of a header, if present. Does *not* raise an exception if the header is missing. """ - name = self._convert_string_type(name.lower()) + name = self._convert_string_type(name.lower(), name=True) self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name] def __getitem__(self,name): @@ -90,13 +95,13 @@ def get_all(self, name): fields deleted and re-inserted are always appended to the header list. If no fields exist with the given name, returns an empty list. """ - name = self._convert_string_type(name.lower()) + name = self._convert_string_type(name.lower(), name=True) return [kv[1] for kv in self._headers if kv[0].lower()==name] def get(self,name,default=None): """Get the first header value for 'name', or return 'default'""" - name = self._convert_string_type(name.lower()) + name = self._convert_string_type(name.lower(), name=True) for k,v in self._headers: if k.lower()==name: return v @@ -151,8 +156,8 @@ def setdefault(self,name,value): and value 'value'.""" result = self.get(name) if result is None: - self._headers.append((self._convert_string_type(name), - self._convert_string_type(value))) + self._headers.append((self._convert_string_type(name, name=True), + self._convert_string_type(value, name=False))) return value else: return result @@ -175,13 +180,13 @@ def add_header(self, _name, _value, **_params): """ parts = [] if _value is not None: - _value = self._convert_string_type(_value) + _value = self._convert_string_type(_value, name=False) parts.append(_value) for k, v in _params.items(): - k = self._convert_string_type(k) + k = self._convert_string_type(k, name=True) if v is None: parts.append(k.replace('_', '-')) else: - v = self._convert_string_type(v) + v = self._convert_string_type(v, name=False) parts.append(_formatparam(k.replace('_', '-'), v)) - self._headers.append((self._convert_string_type(_name), "; ".join(parts))) + self._headers.append((self._convert_string_type(_name, name=True), "; ".join(parts))) From 945bf8ce1bf7ee3881752c2ecc129e35ab818477 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Fri, 13 Feb 2026 00:15:23 +0100 Subject: [PATCH 095/498] gh-144706: Warn against using synchronization primitives within signal handlers (GH-144736) --- Doc/library/signal.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index d85d7138911016..c3fe9943ba9d76 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -68,6 +68,11 @@ the synchronization primitives from the :mod:`threading` module instead. Besides, only the main thread of the main interpreter is allowed to set a new signal handler. +.. warning:: + + Synchronization primitives such as :class:`threading.Lock` should not be used + within signal handlers. Doing so can lead to unexpected deadlocks. + Module contents --------------- From 82b92e3cd180723a354cdeb0f0f1d593f1b5eb0d Mon Sep 17 00:00:00 2001 From: Priyanshu Singh Date: Fri, 13 Feb 2026 21:05:08 +0530 Subject: [PATCH 096/498] gh-143637: Fix re-entrant mutation of ancillary data in socket.sendmsg() (#143892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Victor Stinner Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_socket.py | 18 ++++++++++++++++++ ...6-01-17-08-44-25.gh-issue-143637.qyPqDo.rst | 1 + Modules/socketmodule.c | 13 ++++++++----- 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 934b7137096bc0..3806ad988db214 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2222,6 +2222,24 @@ def test_addressinfo_enum(self): source=_socket) enum._test_simple_enum(CheckedAddressInfo, socket.AddressInfo) + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"),"sendmsg not supported") + def test_sendmsg_reentrant_ancillary_mutation(self): + + class Mut: + def __index__(self): + seq.clear() + return 0 + + seq = [ + (socket.SOL_SOCKET, Mut(), b'x'), + (socket.SOL_SOCKET, 0, b'x'), + ] + + left, right = socket.socketpair() + self.addCleanup(left.close) + self.addCleanup(right.close) + self.assertRaises(OSError, left.sendmsg, [b'x'], seq) + @unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') class BasicCANTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst new file mode 100644 index 00000000000000..cbb21194d5b387 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst @@ -0,0 +1 @@ +Fixed a crash in socket.sendmsg() that could occur if ancillary data is mutated re-entrantly during argument parsing. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ee78ad01598262..d4df40c78e8a4f 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -4983,11 +4983,13 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, if (cmsg_arg == NULL) ncmsgs = 0; else { - if ((cmsg_fast = PySequence_Fast(cmsg_arg, - "sendmsg() argument 2 must be an " - "iterable")) == NULL) + cmsg_fast = PySequence_Tuple(cmsg_arg); + if (cmsg_fast == NULL) { + PyErr_SetString(PyExc_TypeError, + "sendmsg() argument 2 must be an iterable"); goto finally; - ncmsgs = PySequence_Fast_GET_SIZE(cmsg_fast); + } + ncmsgs = PyTuple_GET_SIZE(cmsg_fast); } #ifndef CMSG_SPACE @@ -5007,8 +5009,9 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, controllen = controllen_last = 0; while (ncmsgbufs < ncmsgs) { size_t bufsize, space; + PyObject *item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs), + if (!PyArg_Parse(item, "(iiy*):[sendmsg() ancillary data items]", &cmsgs[ncmsgbufs].level, &cmsgs[ncmsgbufs].type, From d625f7da33bf8eb57fb7e1a05deae3f68bf4d00f Mon Sep 17 00:00:00 2001 From: Colin McAllister Date: Fri, 13 Feb 2026 11:17:53 -0600 Subject: [PATCH 097/498] gh-144787: [tests] Allow TLS v1.2 to be minimum version (GH-144790) Allow TLS v1.2 to be minimum version Updates test_min_max_version to allow TLS v1.2 to be minimum version if TLS 1.0 and 1.1 are disabled in OpenSSL. --- Lib/test/test_ssl.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 6023c89bca03f9..7e9ba735b3ce66 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1156,7 +1156,12 @@ def test_min_max_version(self): ctx.maximum_version = ssl.TLSVersion.MINIMUM_SUPPORTED self.assertIn( ctx.maximum_version, - {ssl.TLSVersion.TLSv1, ssl.TLSVersion.TLSv1_1, ssl.TLSVersion.SSLv3} + { + ssl.TLSVersion.TLSv1, + ssl.TLSVersion.TLSv1_1, + ssl.TLSVersion.TLSv1_2, + ssl.TLSVersion.SSLv3, + } ) ctx.minimum_version = ssl.TLSVersion.MAXIMUM_SUPPORTED From 928602c0ac385eca81b90956ba8d36d04e7dd6de Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 13 Feb 2026 12:48:52 -0600 Subject: [PATCH 098/498] gh-144551: Update Windows builds to use OpenSSL 3.0.19 (GH-144793) --- .../2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst | 1 + Misc/externals.spdx.json | 8 ++++---- PCbuild/get_externals.bat | 4 ++-- PCbuild/python.props | 4 ++-- PCbuild/readme.txt | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst diff --git a/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst b/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst new file mode 100644 index 00000000000000..81ff2f4a18c1e7 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst @@ -0,0 +1 @@ +Updated bundled version of OpenSSL to 3.0.19. diff --git a/Misc/externals.spdx.json b/Misc/externals.spdx.json index dba01de8352d52..a4321a8b9d7c1c 100644 --- a/Misc/externals.spdx.json +++ b/Misc/externals.spdx.json @@ -70,21 +70,21 @@ "checksums": [ { "algorithm": "SHA256", - "checksumValue": "9b07560b6c1afa666bd78b8d3aa5c83fdda02149afdf048596d5b0e0dac1ee55" + "checksumValue": "c6ea8a5423f3966923060db2089f869017dfb10bcf2037394146e7a74caec0a8" } ], - "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.0.18.tar.gz", + "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.0.19.tar.gz", "externalRefs": [ { "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:a:openssl:openssl:3.0.18:*:*:*:*:*:*:*", + "referenceLocator": "cpe:2.3:a:openssl:openssl:3.0.19:*:*:*:*:*:*:*", "referenceType": "cpe23Type" } ], "licenseConcluded": "NOASSERTION", "name": "openssl", "primaryPackagePurpose": "SOURCE", - "versionInfo": "3.0.18" + "versionInfo": "3.0.19" }, { "SPDXID": "SPDXRef-PACKAGE-sqlite", diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 9d02e2121cc623..2aed6cfa72d5a2 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.4 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.18 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.19 set libraries=%libraries% mpdecimal-4.0.0 set libraries=%libraries% sqlite-3.50.4.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.15.0 @@ -79,7 +79,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.4 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.18 +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.19 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.15.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 if NOT "%IncludeLLVM%"=="false" set binaries=%binaries% llvm-21.1.4.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index 7840e2a1cfc8e2..dcefc28058609f 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -82,8 +82,8 @@ $(libffiDir)$(ArchName)\ $(libffiOutDir)include $(ExternalsDir)\mpdecimal-4.0.0\ - $(ExternalsDir)openssl-3.0.18\ - $(ExternalsDir)openssl-bin-3.0.18\$(ArchName)\ + $(ExternalsDir)openssl-3.0.19\ + $(ExternalsDir)openssl-bin-3.0.19\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.3.1\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index c5d38296070e02..dc7b6acb9c043a 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -218,7 +218,7 @@ _lzma https://tukaani.org/xz/ _ssl - Python wrapper for version 3.0.15 of the OpenSSL secure sockets + Python wrapper for version 3.0.19 of the OpenSSL secure sockets library, which is itself downloaded from our binaries repository at https://github.com/python/cpython-bin-deps and built by openssl.vcxproj. From b933ef92619db2a103a26c70e69b6d31978eb566 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 13 Feb 2026 13:06:07 -0600 Subject: [PATCH 099/498] gh-144551: Update CI to use latest OpenSSL versions (GH-144794) Also update _ssl_data_36.h to include an added symbol from 3.6.1. --- .github/workflows/build.yml | 2 +- Modules/_ssl_data_36.h | 9 +++++++-- Tools/ssl/multissltests.py | 10 +++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 046e678f8c1b4b..f9a6fb61272e44 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -261,7 +261,7 @@ jobs: # Keep 1.1.1w in our list despite it being upstream EOL and otherwise # unsupported as it most resembles other 1.1.1-work-a-like ssl APIs # supported by important vendors such as AWS-LC. - openssl_ver: [1.1.1w, 3.0.18, 3.3.5, 3.4.3, 3.5.4, 3.6.0] + openssl_ver: [1.1.1w, 3.0.19, 3.3.6, 3.4.4, 3.5.5, 3.6.1] # See Tools/ssl/make_ssl_data.py for notes on adding a new version env: OPENSSL_VER: ${{ matrix.openssl_ver }} diff --git a/Modules/_ssl_data_36.h b/Modules/_ssl_data_36.h index 02b8b66e80fce2..5a2e0d067e2dc7 100644 --- a/Modules/_ssl_data_36.h +++ b/Modules/_ssl_data_36.h @@ -1,6 +1,6 @@ /* File generated by Tools/ssl/make_ssl_data.py */ -/* Generated on 2026-01-17T13:03:49.335767+00:00 */ -/* Generated from Git commit openssl-3.6.0-0-g7b371d80d9 */ +/* Generated on 2026-02-13T18:19:19.227109+00:00 */ +/* Generated from Git commit openssl-3.6.1-0-gc9a9e5b10 */ /* generated from args.lib2errnum */ static struct py_ssl_library_code library_codes[] = { @@ -1668,6 +1668,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"CERTIFICATE_VERIFY_ERROR", 46, 100}, #endif + #ifdef CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA + {"CIPHER_AEAD_IN_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA}, + #else + {"CIPHER_AEAD_IN_ENVELOPED_DATA", 46, 200}, + #endif #ifdef CMS_R_CIPHER_AEAD_SET_TAG_ERROR {"CIPHER_AEAD_SET_TAG_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_AEAD_SET_TAG_ERROR}, #else diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 828fb8b44f9b08..a08e0518f457f5 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -49,11 +49,11 @@ ] OPENSSL_RECENT_VERSIONS = [ - "3.0.18", - "3.3.5", - "3.4.3", - "3.5.4", - "3.6.0", + "3.0.19", + "3.3.6", + "3.4.4", + "3.5.5", + "3.6.1", # See make_ssl_data.py for notes on adding a new version. ] From 629a363ddd2889f023d5925506e61f5b6647accd Mon Sep 17 00:00:00 2001 From: Rafael Weingartner-Ortner <38643099+RafaelWO@users.noreply.github.com> Date: Fri, 13 Feb 2026 20:51:56 +0100 Subject: [PATCH 100/498] gh-136672: Docs: Move parts of Enum HOWTO to API Docs (GH-139176) To avoid duplicate content in the Enum HOWTO and API documentation which is not automatically synced, the section about supported __dunder__ and _sunder names is moved from HOWTO to API docs. See also https://github.com/python/cpython/pull/136791 --- Doc/howto/enum.rst | 82 +++++++------------------------------------- Doc/library/enum.rst | 57 ++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 81 deletions(-) diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst index 7713aede6d564a..93850b57af2c65 100644 --- a/Doc/howto/enum.rst +++ b/Doc/howto/enum.rst @@ -965,75 +965,16 @@ want one of them to be the value:: Finer Points -^^^^^^^^^^^^ - -Supported ``__dunder__`` names -"""""""""""""""""""""""""""""" - -:attr:`~enum.EnumType.__members__` is a read-only ordered mapping of ``member_name``:``member`` -items. It is only available on the class. - -:meth:`~object.__new__`, if specified, must create and return the enum members; it is -also a very good idea to set the member's :attr:`~Enum._value_` appropriately. Once -all the members are created it is no longer used. - - -Supported ``_sunder_`` names -"""""""""""""""""""""""""""" +------------ -- :attr:`~Enum._name_` -- name of the member -- :attr:`~Enum._value_` -- value of the member; can be set in ``__new__`` -- :meth:`~Enum._missing_` -- a lookup function used when a value is not found; - may be overridden -- :attr:`~Enum._ignore_` -- a list of names, either as a :class:`list` or a - :class:`str`, that will not be transformed into members, and will be removed - from the final class -- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for - an enum member; may be overridden -- :meth:`~Enum._add_alias_` -- adds a new name as an alias to an existing - member. -- :meth:`~Enum._add_value_alias_` -- adds a new value as an alias to an - existing member. See `MultiValueEnum`_ for an example. +Supported ``__dunder__`` and ``_sunder_`` names +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - .. note:: - - For standard :class:`Enum` classes the next value chosen is the highest - value seen incremented by one. - - For :class:`Flag` classes the next value chosen will be the next highest - power-of-two. - - .. versionchanged:: 3.13 - Prior versions would use the last seen value instead of the highest value. - -.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_`` -.. versionadded:: 3.7 ``_ignore_`` -.. versionadded:: 3.13 ``_add_alias_``, ``_add_value_alias_`` - -To help keep Python 2 / Python 3 code in sync an :attr:`~Enum._order_` attribute can -be provided. It will be checked against the actual order of the enumeration -and raise an error if the two do not match:: - - >>> class Color(Enum): - ... _order_ = 'RED GREEN BLUE' - ... RED = 1 - ... BLUE = 3 - ... GREEN = 2 - ... - Traceback (most recent call last): - ... - TypeError: member order does not match _order_: - ['RED', 'BLUE', 'GREEN'] - ['RED', 'GREEN', 'BLUE'] - -.. note:: - - In Python 2 code the :attr:`~Enum._order_` attribute is necessary as definition - order is lost before it can be recorded. +The supported ``__dunder__`` and ``_sunder_`` names can be found in the :ref:`Enum API documentation `. _Private__names -""""""""""""""" +^^^^^^^^^^^^^^^ :ref:`Private names ` are not converted to enum members, but remain normal attributes. @@ -1042,7 +983,7 @@ but remain normal attributes. ``Enum`` member type -"""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^ Enum members are instances of their enum class, and are normally accessed as ``EnumClass.member``. In certain situations, such as writing custom enum @@ -1055,7 +996,7 @@ recommended. Creating members that are mixed with other data types -""""""""""""""""""""""""""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When subclassing other data types, such as :class:`int` or :class:`str`, with an :class:`Enum`, all values after the ``=`` are passed to that data type's @@ -1069,7 +1010,7 @@ constructor. For example:: Boolean value of ``Enum`` classes and members -""""""""""""""""""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Enum classes that are mixed with non-:class:`Enum` types (such as :class:`int`, :class:`str`, etc.) are evaluated according to the mixed-in @@ -1084,7 +1025,7 @@ Plain :class:`Enum` classes always evaluate as :data:`True`. ``Enum`` classes with methods -""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you give your enum subclass extra methods, like the `Planet`_ class below, those methods will show up in a :func:`dir` of the member, @@ -1097,7 +1038,7 @@ but not of the class:: Combining members of ``Flag`` -""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Iterating over a combination of :class:`Flag` members will only return the members that are comprised of a single bit:: @@ -1117,7 +1058,7 @@ are comprised of a single bit:: ``Flag`` and ``IntFlag`` minutia -"""""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Using the following snippet for our examples:: @@ -1478,6 +1419,7 @@ alias:: behaviors as well as disallowing aliases. If the only desired change is disallowing aliases, the :func:`unique` decorator can be used instead. +.. _multi-value-enum: MultiValueEnum ^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index ec7cbfb52b6e99..de56048f56a243 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -307,6 +307,28 @@ Data Types No longer used, kept for backward compatibility. (class attribute, removed during class creation). + The :attr:`~Enum._order_` attribute can be provided to help keep Python 2 / Python 3 code in sync. + It will be checked against the actual order of the enumeration and raise an error if the two do not match:: + + >>> class Color(Enum): + ... _order_ = 'RED GREEN BLUE' + ... RED = 1 + ... BLUE = 3 + ... GREEN = 2 + ... + Traceback (most recent call last): + ... + TypeError: member order does not match _order_: + ['RED', 'BLUE', 'GREEN'] + ['RED', 'GREEN', 'BLUE'] + + .. note:: + + In Python 2 code the :attr:`~Enum._order_` attribute is necessary as definition + order is lost before it can be recorded. + + .. versionadded:: 3.6 + .. attribute:: Enum._ignore_ ``_ignore_`` is only used during creation and is removed from the @@ -316,6 +338,8 @@ Data Types names will also be removed from the completed enumeration. See :ref:`TimePeriod ` for an example. + .. versionadded:: 3.7 + .. method:: Enum.__dir__(self) Returns ``['__class__', '__doc__', '__module__', 'name', 'value']`` and @@ -346,7 +370,16 @@ Data Types :last_values: A list of the previous values. A *staticmethod* that is used to determine the next value returned by - :class:`auto`:: + :class:`auto`. + + .. note:: + For standard :class:`Enum` classes the next value chosen is the highest + value seen incremented by one. + + For :class:`Flag` classes the next value chosen will be the next highest + power-of-two. + + This method may be overridden, e.g.:: >>> from enum import auto, Enum >>> class PowersOfThree(Enum): @@ -359,6 +392,10 @@ Data Types >>> PowersOfThree.SECOND.value 9 + .. versionadded:: 3.6 + .. versionchanged:: 3.13 + Prior versions would use the last seen value instead of the highest value. + .. method:: Enum.__init__(self, *args, **kwds) By default, does nothing. If multiple values are given in the member @@ -397,6 +434,8 @@ Data Types >>> Build('deBUG') + .. versionadded:: 3.6 + .. method:: Enum.__new__(cls, *args, **kwds) By default, doesn't exist. If specified, either in the enum class @@ -490,7 +529,8 @@ Data Types >>> Color(42) - Raises a :exc:`ValueError` if the value is already linked with a different member. + | Raises a :exc:`ValueError` if the value is already linked with a different member. + | See :ref:`multi-value-enum` for an example. .. versionadded:: 3.13 @@ -889,6 +929,8 @@ Data Types --------------- +.. _enum-dunder-sunder: + Supported ``__dunder__`` names """""""""""""""""""""""""""""" @@ -896,7 +938,7 @@ Supported ``__dunder__`` names items. It is only available on the class. :meth:`~Enum.__new__`, if specified, must create and return the enum members; -it is also a very good idea to set the member's :attr:`!_value_` appropriately. +it is also a very good idea to set the member's :attr:`~Enum._value_` appropriately. Once all the members are created it is no longer used. @@ -912,17 +954,10 @@ Supported ``_sunder_`` names from the final class - :attr:`~Enum._order_` -- no longer used, kept for backward compatibility (class attribute, removed during class creation) + - :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for an enum member; may be overridden - .. note:: - - For standard :class:`Enum` classes the next value chosen is the highest - value seen incremented by one. - - For :class:`Flag` classes the next value chosen will be the next highest - power-of-two. - - :meth:`~Enum._add_alias_` -- adds a new name as an alias to an existing member. - :meth:`~Enum._add_value_alias_` -- adds a new value as an alias to an From 543f56fe8d264315f2413414638216fac01f3ade Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 13 Feb 2026 15:43:05 -0600 Subject: [PATCH 101/498] gh-144551: Update Windows builds to use OpenSSL 3.5.5 (GH-144796) --- .../2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst | 2 +- Misc/externals.spdx.json | 8 ++++---- PCbuild/get_externals.bat | 4 ++-- PCbuild/python.props | 4 ++-- PCbuild/readme.txt | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst b/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst index 81ff2f4a18c1e7..810985a352baeb 100644 --- a/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst +++ b/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst @@ -1 +1 @@ -Updated bundled version of OpenSSL to 3.0.19. +Updated bundled version of OpenSSL to 3.5.5. diff --git a/Misc/externals.spdx.json b/Misc/externals.spdx.json index a4321a8b9d7c1c..c96367f57fb3f2 100644 --- a/Misc/externals.spdx.json +++ b/Misc/externals.spdx.json @@ -70,21 +70,21 @@ "checksums": [ { "algorithm": "SHA256", - "checksumValue": "c6ea8a5423f3966923060db2089f869017dfb10bcf2037394146e7a74caec0a8" + "checksumValue": "619b30acf7d9b13c9d0ba90d17349e8b524c380cd23d39334b143f74dc4e5ec9" } ], - "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.0.19.tar.gz", + "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.5.5.tar.gz", "externalRefs": [ { "referenceCategory": "SECURITY", - "referenceLocator": "cpe:2.3:a:openssl:openssl:3.0.19:*:*:*:*:*:*:*", + "referenceLocator": "cpe:2.3:a:openssl:openssl:3.5.5:*:*:*:*:*:*:*", "referenceType": "cpe23Type" } ], "licenseConcluded": "NOASSERTION", "name": "openssl", "primaryPackagePurpose": "SOURCE", - "versionInfo": "3.0.19" + "versionInfo": "3.5.5" }, { "SPDXID": "SPDXRef-PACKAGE-sqlite", diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 2aed6cfa72d5a2..f80a025fb3bc78 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.4 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.19 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.5.5 set libraries=%libraries% mpdecimal-4.0.0 set libraries=%libraries% sqlite-3.50.4.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.15.0 @@ -79,7 +79,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.4 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.19 +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.5.5 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.15.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 if NOT "%IncludeLLVM%"=="false" set binaries=%binaries% llvm-21.1.4.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index dcefc28058609f..82e6365bb397a5 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -82,8 +82,8 @@ $(libffiDir)$(ArchName)\ $(libffiOutDir)include $(ExternalsDir)\mpdecimal-4.0.0\ - $(ExternalsDir)openssl-3.0.19\ - $(ExternalsDir)openssl-bin-3.0.19\$(ArchName)\ + $(ExternalsDir)openssl-3.5.5\ + $(ExternalsDir)openssl-bin-3.5.5\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.3.1\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index dc7b6acb9c043a..b98a956034c537 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -218,7 +218,7 @@ _lzma https://tukaani.org/xz/ _ssl - Python wrapper for version 3.0.19 of the OpenSSL secure sockets + Python wrapper for version 3.5 of the OpenSSL secure sockets library, which is itself downloaded from our binaries repository at https://github.com/python/cpython-bin-deps and built by openssl.vcxproj. From 7359bb8dacc055bdcbb61f8fa4e375b25eedffd9 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 13 Feb 2026 16:50:15 -0600 Subject: [PATCH 102/498] gh-144551: Update OpenSSL version references in Mac/BuildScript/ (GH-144810) --- Mac/BuildScript/README.rst | 2 +- Mac/BuildScript/resources/ReadMe.rtf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mac/BuildScript/README.rst b/Mac/BuildScript/README.rst index e44e74f3a49234..54341a81c26743 100644 --- a/Mac/BuildScript/README.rst +++ b/Mac/BuildScript/README.rst @@ -73,7 +73,7 @@ download them. - builds the following third-party libraries - * OpenSSL 3.0.x + * OpenSSL 3.5.x * Tcl/Tk 8.6.x * NCurses * SQLite diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index ee5ba4707dfea4..d81bcd5c745baa 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -19,7 +19,7 @@ \f1\b \cf0 \ul \ulc0 Certificate verification and OpenSSL\ \f0\b0 \ulnone \ -This package includes its own private copy of OpenSSL 3.0. The trust certificates in system and user keychains managed by the +This package includes its own private copy of OpenSSL 3.5. The trust certificates in system and user keychains managed by the \f2\i Keychain Access \f0\i0 application and the \f2\i security From fdbc135f9cf57599cca8aeeed947d0b736fdb197 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 13 Feb 2026 17:02:11 -0600 Subject: [PATCH 103/498] gh-144551: Update various CI jobs to OpenSSL 3.5 (GH-144808) Also includes a fix to the address sanitizer build to build the `_ssl` module against the expected OpenSSL build. --- .github/workflows/build.yml | 6 +++--- .github/workflows/reusable-macos.yml | 4 ++-- .github/workflows/reusable-ubuntu.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9a6fb61272e44..f302cb049326b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -428,7 +428,7 @@ jobs: needs: build-context if: needs.build-context.outputs.run-ubuntu == 'true' env: - OPENSSL_VER: 3.0.18 + OPENSSL_VER: 3.5.5 PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout@v6 @@ -539,7 +539,7 @@ jobs: matrix: os: [ubuntu-24.04] env: - OPENSSL_VER: 3.0.18 + OPENSSL_VER: 3.5.5 PYTHONSTRICTEXTENSIONBUILD: 1 ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 steps: @@ -574,7 +574,7 @@ jobs: run: | echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Configure CPython - run: ./configure --config-cache --with-address-sanitizer --without-pymalloc + run: ./configure --config-cache --with-address-sanitizer --without-pymalloc --with-openssl="$OPENSSL_DIR" - name: Build CPython run: make -j4 - name: Display build info diff --git a/.github/workflows/reusable-macos.yml b/.github/workflows/reusable-macos.yml index 7eef66bd9d9324..6afbf6595d93e3 100644 --- a/.github/workflows/reusable-macos.yml +++ b/.github/workflows/reusable-macos.yml @@ -35,7 +35,7 @@ jobs: run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV" - name: Install Homebrew dependencies run: | - brew install pkg-config openssl@3.0 xz gdbm tcl-tk@9 make + brew install pkg-config openssl@3.5 xz gdbm tcl-tk@9 make # Because alternate versions are not symlinked into place by default: brew link --overwrite tcl-tk@9 - name: Configure CPython @@ -50,7 +50,7 @@ jobs: --enable-safety \ ${{ inputs.free-threading && '--disable-gil' || '' }} \ --prefix=/opt/python-dev \ - --with-openssl="$(brew --prefix openssl@3.0)" + --with-openssl="$(brew --prefix openssl@3.5)" - name: Build CPython if : ${{ inputs.free-threading || inputs.os != 'macos-15-intel' }} run: gmake -j8 diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml index ad725e92f2b20f..03f41069b8430d 100644 --- a/.github/workflows/reusable-ubuntu.yml +++ b/.github/workflows/reusable-ubuntu.yml @@ -27,7 +27,7 @@ jobs: runs-on: ${{ inputs.os }} timeout-minutes: 60 env: - OPENSSL_VER: 3.0.18 + OPENSSL_VER: 3.5.5 PYTHONSTRICTEXTENSIONBUILD: 1 TERM: linux steps: From 75d4839fa9069241ca9c3ee45ad8369ef9777500 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 14 Feb 2026 06:06:15 +0100 Subject: [PATCH 104/498] gh-138912: Improve MATCH_CLASS opcode performance (GH-138915) Only check for duplicates if there is at least one positional pattern. With a test case for duplicate keyword attributes. --- Lib/test/test_syntax.py | 6 ++ ...-09-15-13-28-48.gh-issue-138912.61EYbn.rst | 1 + Python/ceval.c | 67 ++++++++++--------- 3 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 19427f2469ec43..e48749626fccad 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2345,6 +2345,12 @@ Traceback (most recent call last): SyntaxError: positional patterns follow keyword patterns + >>> match ...: + ... case Foo(y=1, x=2, y=3): + ... ... + Traceback (most recent call last): + SyntaxError: attribute name repeated in class pattern: y + >>> match ...: ... case C(a=b, c, d=e, f, g=h, i, j=k, ...): ... ... diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst new file mode 100644 index 00000000000000..f5d312a289fe21 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst @@ -0,0 +1 @@ +Improve :opcode:`MATCH_CLASS` performance by up to 52% in certain cases. Patch by Marc Mueller. diff --git a/Python/ceval.c b/Python/ceval.c index 758b142d7a720e..ab2eef560370f5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -509,15 +509,18 @@ match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type, PyObject *name, PyObject *seen) { assert(PyUnicode_CheckExact(name)); - assert(PySet_CheckExact(seen)); - if (PySet_Contains(seen, name) || PySet_Add(seen, name)) { - if (!_PyErr_Occurred(tstate)) { - // Seen it before! - _PyErr_Format(tstate, PyExc_TypeError, - "%s() got multiple sub-patterns for attribute %R", - ((PyTypeObject*)type)->tp_name, name); + // Only check for duplicates if seen is not NULL. + if (seen != NULL) { + assert(PySet_CheckExact(seen)); + if (PySet_Contains(seen, name) || PySet_Add(seen, name)) { + if (!_PyErr_Occurred(tstate)) { + // Seen it before! + _PyErr_Format(tstate, PyExc_TypeError, + "%s() got multiple sub-patterns for attribute %R", + ((PyTypeObject*)type)->tp_name, name); + } + return NULL; } - return NULL; } PyObject *attr; (void)PyObject_GetOptionalAttr(subject, name, &attr); @@ -540,14 +543,26 @@ _PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, if (PyObject_IsInstance(subject, type) <= 0) { return NULL; } + // Short circuit if there aren't any arguments: + Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwargs); + Py_ssize_t nattrs = nargs + nkwargs; + if (!nattrs) { + return PyTuple_New(0); + } // So far so good: - PyObject *seen = PySet_New(NULL); - if (seen == NULL) { - return NULL; + PyObject *seen = NULL; + // Only check for duplicates if there is at least one positional attribute + // and two or more attributes in total. Duplicate keyword attributes are + // detected during the compile stage and raise a SyntaxError. + if (nargs > 0 && nattrs > 1) { + seen = PySet_New(NULL); + if (seen == NULL) { + return NULL; + } } - PyObject *attrs = PyList_New(0); + PyObject *attrs = PyTuple_New(nattrs); if (attrs == NULL) { - Py_DECREF(seen); + Py_XDECREF(seen); return NULL; } // NOTE: From this point on, goto fail on failure: @@ -588,9 +603,8 @@ _PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, } if (match_self) { // Easy. Copy the subject itself, and move on to kwargs. - if (PyList_Append(attrs, subject) < 0) { - goto fail; - } + assert(PyTuple_GET_ITEM(attrs, 0) == NULL); + PyTuple_SET_ITEM(attrs, 0, Py_NewRef(subject)); } else { for (Py_ssize_t i = 0; i < nargs; i++) { @@ -606,36 +620,29 @@ _PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, if (attr == NULL) { goto fail; } - if (PyList_Append(attrs, attr) < 0) { - Py_DECREF(attr); - goto fail; - } - Py_DECREF(attr); + assert(PyTuple_GET_ITEM(attrs, i) == NULL); + PyTuple_SET_ITEM(attrs, i, attr); } } Py_CLEAR(match_args); } // Finally, the keyword subpatterns: - for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwargs); i++) { + for (Py_ssize_t i = 0; i < nkwargs; i++) { PyObject *name = PyTuple_GET_ITEM(kwargs, i); PyObject *attr = match_class_attr(tstate, subject, type, name, seen); if (attr == NULL) { goto fail; } - if (PyList_Append(attrs, attr) < 0) { - Py_DECREF(attr); - goto fail; - } - Py_DECREF(attr); + assert(PyTuple_GET_ITEM(attrs, nargs + i) == NULL); + PyTuple_SET_ITEM(attrs, nargs + i, attr); } - Py_SETREF(attrs, PyList_AsTuple(attrs)); - Py_DECREF(seen); + Py_XDECREF(seen); return attrs; fail: // We really don't care whether an error was raised or not... that's our // caller's problem. All we know is that the match failed. Py_XDECREF(match_args); - Py_DECREF(seen); + Py_XDECREF(seen); Py_DECREF(attrs); return NULL; } From 5922149a5033ec1151320864e605adf88f53f280 Mon Sep 17 00:00:00 2001 From: Yilei Date: Sat, 14 Feb 2026 03:41:28 -0800 Subject: [PATCH 105/498] gh-144766: Fix a crash in fork child process when perf support is enabled. (#144795) --- Lib/test/test_perf_profiler.py | 41 +++++++++++++++++++ ...-02-13-18-30-59.gh-issue-144766.JGu3x3.rst | 1 + Python/perf_trampoline.c | 6 +++ 3 files changed, 48 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py index 66348619073909..597e6599352049 100644 --- a/Lib/test/test_perf_profiler.py +++ b/Lib/test/test_perf_profiler.py @@ -170,6 +170,47 @@ def baz(): self.assertNotIn(f"py::bar:{script}", child_perf_file_contents) self.assertNotIn(f"py::baz:{script}", child_perf_file_contents) + @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT instrumented binaries") + def test_trampoline_works_after_fork_with_many_code_objects(self): + code = """if 1: + import gc, os, sys, signal + + # Create many code objects so trampoline_refcount > 1 + for i in range(50): + exec(compile(f"def _dummy_{i}(): pass", f"", "exec")) + + pid = os.fork() + if pid == 0: + # Child: create and destroy new code objects, + # then collect garbage. If the old code watcher + # survived the fork, the double-decrement of + # trampoline_refcount will cause a SIGSEGV. + for i in range(50): + exec(compile(f"def _child_{i}(): pass", f"", "exec")) + gc.collect() + os._exit(0) + else: + _, status = os.waitpid(pid, 0) + if os.WIFSIGNALED(status): + print(f"FAIL: child killed by signal {os.WTERMSIG(status)}", file=sys.stderr) + sys.exit(1) + sys.exit(os.WEXITSTATUS(status)) + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + env = {**os.environ, "PYTHON_JIT": "0"} + with subprocess.Popen( + [sys.executable, "-Xperf", script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + env=env, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(process.returncode, 0, stderr) + self.assertEqual(stderr, "") + @unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT instrumented binaries") def test_sys_api(self): for define_eval_hook in (False, True): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst new file mode 100644 index 00000000000000..d9613c95af1915 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst @@ -0,0 +1 @@ +Fix a crash in fork child process when perf support is enabled. diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c index c0dc1f7a49bdca..0d835f3b7f56a9 100644 --- a/Python/perf_trampoline.c +++ b/Python/perf_trampoline.c @@ -618,6 +618,12 @@ _PyPerfTrampoline_AfterFork_Child(void) int was_active = _PyIsPerfTrampolineActive(); _PyPerfTrampoline_Fini(); if (was_active) { + // After fork, Fini may leave the old code watcher registered + // if trampolined code objects from the parent still exist + // (trampoline_refcount > 0). Clear it unconditionally before + // Init registers a new one, to prevent two watchers sharing + // the same globals and double-decrementing trampoline_refcount. + perf_trampoline_reset_state(); _PyPerfTrampoline_Init(1); } } From 14cbd0e6afa98355bdc6749b8230fed4c9b21bd6 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:09:01 +0100 Subject: [PATCH 106/498] remove unused _PyFunction_LookupByVersion (GH-144814) --- Include/internal/pycore_function.h | 1 - Objects/funcobject.c | 26 -------------------------- Python/optimizer.c | 1 - 3 files changed, 28 deletions(-) diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h index 522e03c6696993..9c2121f59a4a0c 100644 --- a/Include/internal/pycore_function.h +++ b/Include/internal/pycore_function.h @@ -30,7 +30,6 @@ _PyFunction_IsVersionValid(uint32_t version) extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); PyAPI_FUNC(void) _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version); void _PyFunction_ClearCodeByVersion(uint32_t version); -PyFunctionObject *_PyFunction_LookupByVersion(uint32_t version, PyObject **p_code); extern PyObject *_Py_set_function_type_params( PyThreadState* unused, PyObject *func, PyObject *type_params); diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 8f4ff4e42392c2..ee0c46a95b9708 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -373,32 +373,6 @@ _PyFunction_ClearCodeByVersion(uint32_t version) #endif } -PyFunctionObject * -_PyFunction_LookupByVersion(uint32_t version, PyObject **p_code) -{ -#ifdef Py_GIL_DISABLED - return NULL; -#else - PyInterpreterState *interp = _PyInterpreterState_GET(); - struct _func_version_cache_item *slot = get_cache_item(interp, version); - if (slot->code) { - assert(PyCode_Check(slot->code)); - PyCodeObject *code = (PyCodeObject *)slot->code; - if (code->co_version == version) { - *p_code = slot->code; - } - } - else { - *p_code = NULL; - } - if (slot->func && slot->func->func_version == version) { - assert(slot->func->func_code == slot->code); - return slot->func; - } - return NULL; -#endif -} - uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) { diff --git a/Python/optimizer.c b/Python/optimizer.c index bf5d8a28264635..12ef7c3fc0adf5 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -8,7 +8,6 @@ #include "pycore_bitutils.h" // _Py_popcount32() #include "pycore_ceval.h" // _Py_set_eval_breaker_bit #include "pycore_code.h" // _Py_GetBaseCodeUnit -#include "pycore_function.h" // _PyFunction_LookupByVersion() #include "pycore_interpframe.h" #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_opcode_metadata.h" // _PyOpcode_OpName[] From caac966b0051578b60b4b07fe341174f25d9f8b1 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:39:10 +0100 Subject: [PATCH 107/498] fix warnings in jit builds (GH-144817) --- Python/jit.c | 2 +- Python/optimizer.c | 5 +++-- Python/optimizer_analysis.c | 8 ++++---- Python/optimizer_bytecodes.c | 13 ++++++++----- Python/optimizer_cases.c.h | 11 +++++++---- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Python/jit.c b/Python/jit.c index 0791d042710efb..3e0a0aa8bfcc81 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -164,7 +164,7 @@ mark_executable(unsigned char *memory, size_t size) jit_error("unable to flush instruction cache"); return -1; } - int old; + DWORD old; int failed = !VirtualProtect(memory, size, PAGE_EXECUTE_READ, &old); #else __builtin___clear_cache((char *)memory, (char *)memory + size); diff --git a/Python/optimizer.c b/Python/optimizer.c index 12ef7c3fc0adf5..466729b158d345 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1044,7 +1044,7 @@ _PyJit_TryInitializeTracing( tracer->initial_state.func = (PyFunctionObject *)Py_NewRef(func); tracer->initial_state.executor = (_PyExecutorObject *)Py_XNewRef(current_executor); tracer->initial_state.exit = exit; - tracer->initial_state.stack_depth = stack_pointer - _PyFrame_Stackbase(frame); + tracer->initial_state.stack_depth = (int)(stack_pointer - _PyFrame_Stackbase(frame)); tracer->initial_state.chain_depth = chain_depth; tracer->prev_state.dependencies_still_valid = true; tracer->prev_state.instr_code = (PyCodeObject *)Py_NewRef(_PyFrame_GetCode(frame)); @@ -1486,7 +1486,7 @@ stack_allocate(_PyUOpInstruction *buffer, _PyUOpInstruction *output, int length) write++; depth = _PyUop_Caching[uop].entries[depth].output; } - return write - output; + return (int)(write - output); } static int @@ -2130,6 +2130,7 @@ executor_to_gv(_PyExecutorObject *executor, FILE *out) assert(inst->format == UOP_FORMAT_JUMP); _PyUOpInstruction const *exit_inst = &executor->trace[inst->jump_target]; uint16_t base_exit_opcode = _PyUop_Uncached[exit_inst->opcode]; + (void)base_exit_opcode; assert(base_exit_opcode == _EXIT_TRACE || base_exit_opcode == _DYNAMIC_EXIT); exit = (_PyExitData *)exit_inst->operand0; } diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 7bd6970e5fd2dc..c6a513ad220b63 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -398,7 +398,7 @@ get_test_bit_for_bools(void) { uintptr_t true_bits = (uintptr_t)&_Py_TrueStruct; #endif for (int i = 4; i < 8; i++) { - if ((true_bits ^ false_bits) & (1 << i)) { + if ((true_bits ^ false_bits) & (uintptr_t)(1 << i)) { return i; } } @@ -412,8 +412,8 @@ test_bit_set_in_true(int bit) { #else uintptr_t true_bits = (uintptr_t)&_Py_TrueStruct; #endif - assert((true_bits ^ ((uintptr_t)&_Py_FalseStruct)) & (1 << bit)); - return true_bits & (1 << bit); + assert((true_bits ^ ((uintptr_t)&_Py_FalseStruct)) & (uintptr_t)(1 << bit)); + return true_bits & (uintptr_t)(1 << bit); } #ifdef Py_DEBUG @@ -504,7 +504,7 @@ optimize_uops( stack_pointer = ctx->frame->stack_pointer; } - DUMP_UOP(ctx, "abs", this_instr - trace, this_instr, stack_pointer); + DUMP_UOP(ctx, "abs", (int)(this_instr - trace), this_instr, stack_pointer); _PyUOpInstruction *out_ptr = ctx->out_buffer.next; diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 7c928e6502a412..2b35628ad99999 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -109,11 +109,13 @@ dummy_func(void) { } op(_STORE_ATTR_INSTANCE_VALUE, (offset/1, value, owner -- o)) { + (void)offset; (void)value; o = owner; } op(_STORE_ATTR_WITH_HINT, (hint/1, value, owner -- o)) { + (void)hint; (void)value; o = owner; } @@ -320,7 +322,8 @@ dummy_func(void) { r = right; } - op(_BINARY_OP_EXTEND, (left, right -- res, l, r)) { + op(_BINARY_OP_EXTEND, (descr/4, left, right -- res, l, r)) { + (void)descr; res = sym_new_not_null(ctx); l = left; r = right; @@ -386,7 +389,7 @@ dummy_func(void) { assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); assert(index >= 0); - int tuple_length = sym_tuple_length(tuple_st); + Py_ssize_t tuple_length = sym_tuple_length(tuple_st); if (tuple_length != -1 && index < tuple_length) { ADD_OP(_NOP, 0, 0); } @@ -951,7 +954,7 @@ dummy_func(void) { ctx->done = true; break; } - int returning_stacklevel = this_instr->operand1; + int returning_stacklevel = (int)this_instr->operand1; if (ctx->curr_frame_depth >= 2) { PyCodeObject *expected_code = ctx->frames[ctx->curr_frame_depth - 2].code; if (expected_code == returning_code) { @@ -979,7 +982,7 @@ dummy_func(void) { break; } _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = this_instr->operand1; + int returning_stacklevel = (int)this_instr->operand1; if (frame_pop(ctx, returning_code, returning_stacklevel)) { break; } @@ -1001,7 +1004,7 @@ dummy_func(void) { break; } _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = this_instr->operand1; + int returning_stacklevel = (int)this_instr->operand1; if (frame_pop(ctx, returning_code, returning_stacklevel)) { break; } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 24ae511ebcde31..7faa699a058249 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -896,6 +896,7 @@ right = stack_pointer[-1]; left = stack_pointer[-2]; PyObject *descr = (PyObject *)this_instr->operand0; + (void)descr; res = sym_new_not_null(ctx); l = left; r = right; @@ -1046,7 +1047,7 @@ assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); assert(index >= 0); - int tuple_length = sym_tuple_length(tuple_st); + Py_ssize_t tuple_length = sym_tuple_length(tuple_st); if (tuple_length != -1 && index < tuple_length) { ADD_OP(_NOP, 0, 0); } @@ -1271,7 +1272,7 @@ ctx->done = true; break; } - int returning_stacklevel = this_instr->operand1; + int returning_stacklevel = (int)this_instr->operand1; if (ctx->curr_frame_depth >= 2) { PyCodeObject *expected_code = ctx->frames[ctx->curr_frame_depth - 2].code; if (expected_code == returning_code) { @@ -1351,7 +1352,7 @@ break; } _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = this_instr->operand1; + int returning_stacklevel = (int)this_instr->operand1; if (frame_pop(ctx, returning_code, returning_stacklevel)) { break; } @@ -2033,6 +2034,7 @@ owner = stack_pointer[-1]; value = stack_pointer[-2]; uint16_t offset = (uint16_t)this_instr->operand0; + (void)offset; (void)value; o = owner; CHECK_STACK_BOUNDS(-1); @@ -2049,6 +2051,7 @@ owner = stack_pointer[-1]; value = stack_pointer[-2]; uint16_t hint = (uint16_t)this_instr->operand0; + (void)hint; (void)value; o = owner; CHECK_STACK_BOUNDS(-1); @@ -3595,7 +3598,7 @@ break; } _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = this_instr->operand1; + int returning_stacklevel = (int)this_instr->operand1; if (frame_pop(ctx, returning_code, returning_stacklevel)) { break; } From 645f5c4a737b3eab29d0b7bcd4ec5f8bd36f332d Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Sat, 14 Feb 2026 20:20:33 +0100 Subject: [PATCH 108/498] gh-144822: remove redundant decref in `codegen.c` (#144823) --- Python/codegen.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/codegen.c b/Python/codegen.c index 32a03e7212eeab..42fccb07d31dba 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -1422,7 +1422,6 @@ codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1); _PyCompile_ExitScope(c); if (co == NULL) { - Py_XDECREF(co); return ERROR; } int ret = codegen_make_closure(c, LOC(s), co, funcflags); From e6110efd03259acd1895cff63fbfa115ac5f16dc Mon Sep 17 00:00:00 2001 From: Ramin Farajpour Cami Date: Sun, 15 Feb 2026 18:09:57 +0330 Subject: [PATCH 109/498] gh-144759: Fix undefined behavior from NULL pointer arithmetic in lexer (#144788) Guard against NULL pointer arithmetic in `_PyLexer_remember_fstring_buffers` and `_PyLexer_restore_fstring_buffers`. When `start` or `multi_line_start` are NULL (uninitialized in tok_mode_stack[0]), performing `NULL - tok->buf` is undefined behavior. Add explicit NULL checks to store -1 as sentinel and restore NULL accordingly. Add test_lexer_buffer_realloc_with_null_start to test_repl.py that exercises the code path where the lexer buffer is reallocated while tok_mode_stack[0] has NULL start/multi_line_start pointers. This triggers _PyLexer_remember_fstring_buffers and verifies the NULL checks prevent undefined behavior. --- Lib/test/test_repl.py | 16 ++++++++++++++++ ...026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst | 4 ++++ Parser/lexer/buffer.c | 8 ++++---- 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 6cdb1ca65c6aed..40965835bcec00 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -143,6 +143,22 @@ def test_multiline_string_parsing(self): output = kill_python(p) self.assertEqual(p.returncode, 0) + @cpython_only + def test_lexer_buffer_realloc_with_null_start(self): + # gh-144759: NULL pointer arithmetic in the lexer when start and + # multi_line_start are NULL (uninitialized in tok_mode_stack[0]) + # and the lexer buffer is reallocated while parsing long input. + long_value = "a" * 2000 + user_input = dedent(f"""\ + x = f'{{{long_value!r}}}' + print(x) + """) + p = spawn_repl() + p.stdin.write(user_input) + output = kill_python(p) + self.assertEqual(p.returncode, 0) + self.assertIn(long_value, output) + def test_close_stdin(self): user_input = dedent(''' import os diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst new file mode 100644 index 00000000000000..46786d0672b0a8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst @@ -0,0 +1,4 @@ +Fix undefined behavior in the lexer when ``start`` and ``multi_line_start`` +pointers are ``NULL`` in ``_PyLexer_remember_fstring_buffers()`` and +``_PyLexer_restore_fstring_buffers()``. The ``NULL`` pointer arithmetic +(``NULL - valid_pointer``) is now guarded with explicit ``NULL`` checks. diff --git a/Parser/lexer/buffer.c b/Parser/lexer/buffer.c index 63aa1ea2ad4f60..e122fd0d9878ea 100644 --- a/Parser/lexer/buffer.c +++ b/Parser/lexer/buffer.c @@ -13,8 +13,8 @@ _PyLexer_remember_fstring_buffers(struct tok_state *tok) for (index = tok->tok_mode_stack_index; index >= 0; --index) { mode = &(tok->tok_mode_stack[index]); - mode->start_offset = mode->start - tok->buf; - mode->multi_line_start_offset = mode->multi_line_start - tok->buf; + mode->start_offset = mode->start == NULL ? -1 : mode->start - tok->buf; + mode->multi_line_start_offset = mode->multi_line_start == NULL ? -1 : mode->multi_line_start - tok->buf; } } @@ -27,8 +27,8 @@ _PyLexer_restore_fstring_buffers(struct tok_state *tok) for (index = tok->tok_mode_stack_index; index >= 0; --index) { mode = &(tok->tok_mode_stack[index]); - mode->start = tok->buf + mode->start_offset; - mode->multi_line_start = tok->buf + mode->multi_line_start_offset; + mode->start = mode->start_offset < 0 ? NULL : tok->buf + mode->start_offset; + mode->multi_line_start = mode->multi_line_start_offset < 0 ? NULL : tok->buf + mode->multi_line_start_offset; } } From 50c479e613beccf38b6ac2e5fe4e03dab8bbcb28 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Sun, 15 Feb 2026 20:21:54 +0530 Subject: [PATCH 110/498] add whatsnew entry for `PyUnstable_SetImmortal` and `PyDatetime_IMPORT` (#144830) --- Doc/c-api/datetime.rst | 9 +++++++++ Doc/whatsnew/3.15.rst | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index 127d7c9c91a3d5..d7b4e116c49e35 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -30,6 +30,10 @@ macros. This is not compatible with subinterpreters. + .. versionchanged:: 3.15 + + This macro is now thread safe. + .. c:type:: PyDateTime_CAPI Structure containing the fields for the datetime C API. @@ -44,6 +48,11 @@ macros. This variable is only available once :c:macro:`PyDateTime_IMPORT` succeeds. + .. versionchanged:: 3.15 + + This variable should not be accessed directly as direct access is not thread-safe. + Use :c:func:`PyDateTime_IMPORT` instead. + .. c:type:: PyDateTime_Date This subtype of :c:type:`PyObject` represents a Python date object. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 0e440ccfd011f0..cd80947924684d 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1563,6 +1563,8 @@ New features thread state. (Contributed by Victor Stinner in :gh:`139653`.) +* Add :c:func:`PyUnstable_SetImmortal` C-API function to mark objects as :term:`immortal`. + (Contributed by Kumar Aditya in :gh:`143300`.) Changed C APIs -------------- @@ -1571,6 +1573,9 @@ Changed C APIs flag is set then :c:macro:`Py_TPFLAGS_HAVE_GC` must be set too. (Contributed by Sergey Miryanov in :gh:`134786`.) +* :c:macro:`PyDateTime_IMPORT` is now thread safe. Code that directly checks ``PyDateTimeAPI`` + for ``NULL`` should be updated to call :c:macro:`PyDateTime_IMPORT` instead. + (Contributed by Kumar Aditya in :gh:`141563`.) Porting to Python 3.15 ---------------------- From 5a6615ff9281b4f5204d18159e19cd6e92b0fb9a Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sun, 15 Feb 2026 16:07:03 +0000 Subject: [PATCH 111/498] gh-142349: Add CODEOWNERS for lazy imports (#144840) --- .github/CODEOWNERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6b6074be0a5728..a12fae18d51c21 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -292,6 +292,12 @@ Python/jit.c @brandtbucher @savannahostrowski @diegorusso Tools/jit/ @brandtbucher @savannahostrowski @diegorusso InternalDocs/jit.md @brandtbucher @savannahostrowski @diegorusso @AA-Turner +# Lazy imports (PEP 810) +Objects/lazyimportobject.c @twouters @DinoV @pablogsal +Include/internal/pycore_lazyimportobject.h @twouters @DinoV @pablogsal +Lib/test/test_import/test_lazy_imports.py @twouters @DinoV @pablogsal +Lib/test/test_import/data/lazy_imports/ @twouters @DinoV @pablogsal + # Micro-op / μop / Tier 2 Optimiser Python/optimizer.c @markshannon @Fidget-Spinner Python/optimizer_analysis.c @markshannon @tomasr8 @Fidget-Spinner @savannahostrowski From 23c488d6197191d355be6733699a295c20806932 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sun, 15 Feb 2026 16:11:16 +0000 Subject: [PATCH 112/498] Format CODEOWNERS file (#144842) --- .github/CODEOWNERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a12fae18d51c21..32b883213685b2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -293,10 +293,10 @@ Tools/jit/ @brandtbucher @savannahostrowski @diegorusso InternalDocs/jit.md @brandtbucher @savannahostrowski @diegorusso @AA-Turner # Lazy imports (PEP 810) -Objects/lazyimportobject.c @twouters @DinoV @pablogsal -Include/internal/pycore_lazyimportobject.h @twouters @DinoV @pablogsal -Lib/test/test_import/test_lazy_imports.py @twouters @DinoV @pablogsal -Lib/test/test_import/data/lazy_imports/ @twouters @DinoV @pablogsal +Objects/lazyimportobject.c @twouters @DinoV @pablogsal +Include/internal/pycore_lazyimportobject.h @twouters @DinoV @pablogsal +Lib/test/test_import/test_lazy_imports.py @twouters @DinoV @pablogsal +Lib/test/test_import/data/lazy_imports/ @twouters @DinoV @pablogsal # Micro-op / μop / Tier 2 Optimiser Python/optimizer.c @markshannon @Fidget-Spinner From 5fe139cc39fb8110b3d6cbed6224d7c8f5d91987 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sun, 15 Feb 2026 18:36:47 +0000 Subject: [PATCH 113/498] gh-144727: Add test for circular lazy import crash (#144727) (#144838) Add a regression test ensuring that circular lazy imports raise a proper error (ImportCycleError) instead of crashing with a segfault. The crash was fixed in gh-144733 but no test was added at the time. --- Lib/test/test_import/test_lazy_imports.py | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py index 1193af9589034b..a4c9c14ae2b5f8 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_import/test_lazy_imports.py @@ -8,6 +8,8 @@ import threading import types import unittest +import tempfile +import os try: import _testcapi @@ -598,6 +600,39 @@ def test_error_during_module_execution_propagates(self): self.assertEqual(result.returncode, 0, f"stdout: {result.stdout}, stderr: {result.stderr}") self.assertIn("OK", result.stdout) + def test_circular_lazy_import_does_not_crash_for_gh_144727(self): + with tempfile.TemporaryDirectory() as tmpdir: + a_path = os.path.join(tmpdir, "a.py") + b_path = os.path.join(tmpdir, "b.py") + + with open(a_path, "w") as f: + f.write(textwrap.dedent("""\ + lazy import b + + def something(): + b.hello() + + something() + """)) + + with open(b_path, "w") as f: + f.write(textwrap.dedent("""\ + lazy import a + + def hello(): + print(a) + """)) + + result = subprocess.run( + [sys.executable, a_path], + capture_output=True, + text=True, + cwd=tmpdir, + ) + # Should get a proper Python error, not a crash + self.assertEqual(result.returncode, 1) + self.assertIn("Error", result.stderr) + class GlobalsAndDictTests(unittest.TestCase): """Tests for globals() and __dict__ behavior with lazy imports. From 300de1e98ac236bc887b49c0fbd7398266237b36 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Sun, 15 Feb 2026 17:43:39 -0800 Subject: [PATCH 114/498] gh-86519: Add prefixmatch APIs to the re module (GH-31137) Adds `prefixmatch` APIs to the re module as an alternate name for our long existing `match` APIs to help alleviate a common Python confusion for those coming from other languages regular expression libraries. These alleviate common confusion around what "match" means as Python is different than other popular languages regex libraries in our use of the term as an API name. The original `match` names are **NOT being deprecated**. Source tooling like linters, IDEs, and LLMs could suggest using `prefixmatch` instead of match to improve code health and reduce cognitive burden of understanding the intent of code when configured for a modern minimum Python version. See the documentation changes for a better description. Discussions took place in the PR, in the issue, and finally at https://discuss.python.org/t/add-re-prefixmatch-deprecate-re-match/105927 Co-Authored-By: Claude Opus 4.5 Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 --- Doc/library/re.rst | 193 +++++++++++------- Doc/whatsnew/3.15.rst | 15 +- Lib/re/__init__.py | 38 ++-- Lib/test/test_inspect/test_inspect.py | 5 +- Lib/test/test_re.py | 22 +- .../2022-02-05-00-15-03.bpo-42353.0ebVGG.rst | 10 + Modules/_sre/clinic/sre.c.h | 38 ++-- Modules/_sre/sre.c | 53 ++++- 8 files changed, 251 insertions(+), 123 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 734301317283fb..df99acf354bf1b 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -837,7 +837,7 @@ Flags value:: def myfunc(text, flag=re.NOFLAG): - return re.match(text, flag) + return re.search(text, flag) .. versionadded:: 3.11 @@ -893,8 +893,8 @@ Functions Compile a regular expression pattern into a :ref:`regular expression object `, which can be used for matching using its - :func:`~Pattern.match`, :func:`~Pattern.search` and other methods, described - below. + :func:`~Pattern.prefixmatch`, + :func:`~Pattern.search`, and other methods, described below. The expression's behaviour can be modified by specifying a *flags* value. Values can be any of the `flags`_ variables, combined using bitwise OR @@ -903,11 +903,11 @@ Functions The sequence :: prog = re.compile(pattern) - result = prog.match(string) + result = prog.search(string) is equivalent to :: - result = re.match(pattern, string) + result = re.search(pattern, string) but using :func:`re.compile` and saving the resulting regular expression object for reuse is more efficient when the expression will be used several @@ -933,6 +933,7 @@ Functions (the ``|`` operator). +.. function:: prefixmatch(pattern, string, flags=0) .. function:: match(pattern, string, flags=0) If zero or more characters at the beginning of *string* match the regular @@ -940,8 +941,10 @@ Functions ``None`` if the string does not match the pattern; note that this is different from a zero-length match. - Note that even in :const:`MULTILINE` mode, :func:`re.match` will only match - at the beginning of the string and not at the beginning of each line. + .. note:: + + Even in :const:`MULTILINE` mode, this will only match at the + beginning of the string and not at the beginning of each line. If you want to locate a match anywhere in *string*, use :func:`search` instead (see also :ref:`search-vs-match`). @@ -950,6 +953,18 @@ Functions Values can be any of the `flags`_ variables, combined using bitwise OR (the ``|`` operator). + This function now has two names and has long been known as + :func:`~re.match`. Use that name when you need to retain compatibility with + older Python versions. + + .. versionchanged:: next + The alternate :func:`~re.prefixmatch` name of this API was added as a + more explicitly descriptive name than :func:`~re.match`. Use it to better + express intent. The norm in other languages and regular expression + implementations is to use the term *match* to refer to the behavior of + what Python has always called :func:`~re.search`. + See :ref:`prefixmatch-vs-match`. + .. function:: fullmatch(pattern, string, flags=0) @@ -1271,6 +1286,7 @@ Regular Expression Objects >>> pattern.search("dog", 1) # No match; search doesn't include the "d" +.. method:: Pattern.prefixmatch(string[, pos[, endpos]]) .. method:: Pattern.match(string[, pos[, endpos]]) If zero or more characters at the *beginning* of *string* match this regular @@ -1278,17 +1294,32 @@ Regular Expression Objects string does not match the pattern; note that this is different from a zero-length match. + Note that even in :const:`MULTILINE` mode, this will only match at the + beginning of the string and not at the beginning of each line. + The optional *pos* and *endpos* parameters have the same meaning as for the :meth:`~Pattern.search` method. :: >>> pattern = re.compile("o") - >>> pattern.match("dog") # No match as "o" is not at the start of "dog". - >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". + >>> pattern.prefixmatch("dog") # No match as "o" is not at the start of "dog". + >>> pattern.prefixmatch("dog", 1) # Match as "o" is the 2nd character of "dog". If you want to locate a match anywhere in *string*, use :meth:`~Pattern.search` instead (see also :ref:`search-vs-match`). + This method now has two names and has long been known as + :meth:`~Pattern.match`. Use that name when you need to retain compatibility + with older Python versions. + + .. versionchanged:: next + The alternate :meth:`~Pattern.prefixmatch` name of this API was added as + a more explicitly descriptive name than :meth:`~Pattern.match`. Use it to + better express intent. The norm in other languages and regular expression + implementations is to use the term *match* to refer to the behavior of + what Python has always called :meth:`~Pattern.search`. + See :ref:`prefixmatch-vs-match`. + .. method:: Pattern.fullmatch(string[, pos[, endpos]]) @@ -1376,8 +1407,7 @@ Since :meth:`~Pattern.match` and :meth:`~Pattern.search` return ``None`` when there is no match, you can test whether there was a match with a simple ``if`` statement:: - match = re.search(pattern, string) - if match: + if match := re.search(pattern, string): process(match) .. class:: Match @@ -1415,15 +1445,15 @@ when there is no match, you can test whether there was a match with a simple If a group is contained in a part of the pattern that matched multiple times, the last match is returned. :: - >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") + >>> m = re.search(r"\A(\w+) (\w+)", "Norwegian Blue, pining for the fjords") >>> m.group(0) # The entire match - 'Isaac Newton' + 'Norwegian Blue' >>> m.group(1) # The first parenthesized subgroup. - 'Isaac' + 'Norwegian' >>> m.group(2) # The second parenthesized subgroup. - 'Newton' + 'Blue' >>> m.group(1, 2) # Multiple arguments give us a tuple. - ('Isaac', 'Newton') + ('Norwegian', 'Blue') If the regular expression uses the ``(?P...)`` syntax, the *groupN* arguments may also be strings identifying groups by their group name. If a @@ -1432,23 +1462,23 @@ when there is no match, you can test whether there was a match with a simple A moderately complicated example:: - >>> m = re.match(r"(?P\w+) (?P\w+)", "Malcolm Reynolds") - >>> m.group('first_name') - 'Malcolm' - >>> m.group('last_name') - 'Reynolds' + >>> m = re.search(r"(?P\w+) (?P\w+)", "killer rabbit") + >>> m.group('adjective') + 'killer' + >>> m.group('animal') + 'rabbit' Named groups can also be referred to by their index:: >>> m.group(1) - 'Malcolm' + 'killer' >>> m.group(2) - 'Reynolds' + 'rabbit' If a group matches multiple times, only the last match is accessible:: - >>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times. - >>> m.group(1) # Returns only the last match. + >>> m = re.search(r"(..)+", "a1b2c3") # Matches 3 times. + >>> m.group(1) # Returns only the last match. 'c3' @@ -1457,21 +1487,21 @@ when there is no match, you can test whether there was a match with a simple This is identical to ``m.group(g)``. This allows easier access to an individual group from a match:: - >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") + >>> m = re.search(r"(\w+) (\w+)", "Norwegian Blue, pining for the fjords") >>> m[0] # The entire match - 'Isaac Newton' + 'Norwegian Blue' >>> m[1] # The first parenthesized subgroup. - 'Isaac' + 'Norwegian' >>> m[2] # The second parenthesized subgroup. - 'Newton' + 'Blue' Named groups are supported as well:: - >>> m = re.match(r"(?P\w+) (?P\w+)", "Isaac Newton") - >>> m['first_name'] - 'Isaac' - >>> m['last_name'] - 'Newton' + >>> m = re.search(r"(?P\w+) (?P\w+)", "killer rabbit") + >>> m['adjective'] + 'killer' + >>> m['animal'] + 'rabbit' .. versionadded:: 3.6 @@ -1484,7 +1514,7 @@ when there is no match, you can test whether there was a match with a simple For example:: - >>> m = re.match(r"(\d+)\.(\d+)", "24.1632") + >>> m = re.search(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632') @@ -1492,7 +1522,7 @@ when there is no match, you can test whether there was a match with a simple might participate in the match. These groups will default to ``None`` unless the *default* argument is given:: - >>> m = re.match(r"(\d+)\.?(\d+)?", "24") + >>> m = re.search(r"(\d+)\.?(\d+)?", "24") >>> m.groups() # Second group defaults to None. ('24', None) >>> m.groups('0') # Now, the second group defaults to '0'. @@ -1505,9 +1535,9 @@ when there is no match, you can test whether there was a match with a simple the subgroup name. The *default* argument is used for groups that did not participate in the match; it defaults to ``None``. For example:: - >>> m = re.match(r"(?P\w+) (?P\w+)", "Malcolm Reynolds") + >>> m = re.search(r"(?P\w+) (?P\w+)", "killer rabbit") >>> m.groupdict() - {'first_name': 'Malcolm', 'last_name': 'Reynolds'} + {'adjective': 'killer', 'animal': 'rabbit'} .. method:: Match.start([group]) @@ -1610,42 +1640,41 @@ representing the card with that value. To see if a given string is a valid hand, one could do the following:: - >>> valid = re.compile(r"^[a2-9tjqk]{5}$") - >>> displaymatch(valid.match("akt5q")) # Valid. + >>> valid_hand_re = re.compile(r"^[a2-9tjqk]{5}$") + >>> displaymatch(valid_hand_re.search("akt5q")) # Valid. "" - >>> displaymatch(valid.match("akt5e")) # Invalid. - >>> displaymatch(valid.match("akt")) # Invalid. - >>> displaymatch(valid.match("727ak")) # Valid. + >>> displaymatch(valid_hand_re.search("akt5e")) # Invalid. + >>> displaymatch(valid_hand_re.search("akt")) # Invalid. + >>> displaymatch(valid_hand_re.search("727ak")) # Valid. "" That last hand, ``"727ak"``, contained a pair, or two of the same valued cards. To match this with a regular expression, one could use backreferences as such:: - >>> pair = re.compile(r".*(.).*\1") - >>> displaymatch(pair.match("717ak")) # Pair of 7s. + >>> pair_re = re.compile(r".*(.).*\1") + >>> displaymatch(pair_re.prefixmatch("717ak")) # Pair of 7s. "" - >>> displaymatch(pair.match("718ak")) # No pairs. - >>> displaymatch(pair.match("354aa")) # Pair of aces. + >>> displaymatch(pair_re.prefixmatch("718ak")) # No pairs. + >>> displaymatch(pair_re.prefixmatch("354aa")) # Pair of aces. "" To find out what card the pair consists of, one could use the :meth:`~Match.group` method of the match object in the following manner:: - >>> pair = re.compile(r".*(.).*\1") - >>> pair.match("717ak").group(1) + >>> pair_re = re.compile(r".*(.).*\1") + >>> pair_re.prefixmatch("717ak").group(1) '7' - # Error because re.match() returns None, which doesn't have a group() method: - >>> pair.match("718ak").group(1) + # Error because prefixmatch() returns None, which doesn't have a group() method: + >>> pair_re.prefixmatch("718ak").group(1) Traceback (most recent call last): File "", line 1, in - re.match(r".*(.).*\1", "718ak").group(1) + pair_re.prefixmatch("718ak").group(1) AttributeError: 'NoneType' object has no attribute 'group' - >>> pair.match("354aa").group(1) + >>> pair_re.prefixmatch("354aa").group(1) 'a' - Simulating scanf() ^^^^^^^^^^^^^^^^^^ @@ -1694,23 +1723,22 @@ The equivalent regular expression would be :: .. _search-vs-match: -search() vs. match() -^^^^^^^^^^^^^^^^^^^^ +search() vs. prefixmatch() +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. sectionauthor:: Fred L. Drake, Jr. Python offers different primitive operations based on regular expressions: -+ :func:`re.match` checks for a match only at the beginning of the string ++ :func:`re.prefixmatch` checks for a match only at the beginning of the string + :func:`re.search` checks for a match anywhere in the string (this is what Perl does by default) + :func:`re.fullmatch` checks for entire string to be a match - For example:: - >>> re.match("c", "abcdef") # No match - >>> re.search("c", "abcdef") # Match + >>> re.prefixmatch("c", "abcdef") # No match + >>> re.search("c", "abcdef") # Match >>> re.fullmatch("p.*n", "python") # Match @@ -1719,19 +1747,46 @@ For example:: Regular expressions beginning with ``'^'`` can be used with :func:`search` to restrict the match at the beginning of the string:: - >>> re.match("c", "abcdef") # No match - >>> re.search("^c", "abcdef") # No match - >>> re.search("^a", "abcdef") # Match + >>> re.prefixmatch("c", "abcdef") # No match + >>> re.search("^c", "abcdef") # No match + >>> re.search("^a", "abcdef") # Match -Note however that in :const:`MULTILINE` mode :func:`match` only matches at the +Note however that in :const:`MULTILINE` mode :func:`prefixmatch` only matches at the beginning of the string, whereas using :func:`search` with a regular expression beginning with ``'^'`` will match at the beginning of each line. :: - >>> re.match("X", "A\nB\nX", re.MULTILINE) # No match + >>> re.prefixmatch("X", "A\nB\nX", re.MULTILINE) # No match >>> re.search("^X", "A\nB\nX", re.MULTILINE) # Match +.. _prefixmatch-vs-match: + +prefixmatch() vs. match() +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Why is the :func:`~re.match` function and method discouraged in +favor of the longer :func:`~re.prefixmatch` spelling? + +Many other languages have gained regex support libraries since regular +expressions were added to Python. However in the most popular of those, they +use the term *match* in their APIs to mean the unanchored behavior provided in +Python by :func:`~re.search`. Thus use of the plain term *match* can be +unclear to those used to other languages when reading or writing code and +not familiar with the Python API's divergence from what otherwise become the +industry norm. + +Quoting from the Zen Of Python (``python3 -m this``): *"Explicit is better than +implicit"*. Anyone reading the name :func:`~re.prefixmatch` is likely to +understand the intended semantics. When reading :func:`~re.match` there remains +a seed of doubt about the intended behavior to anyone not already familiar with +this old Python gotcha. + +We **do not** plan to deprecate and remove the older *match* name, +as it has been used in code for over 30 years. +Code supporting older versions of Python should continue to use *match*. + +.. versionadded:: next Making a Phonebook ^^^^^^^^^^^^^^^^^^ @@ -1851,9 +1906,9 @@ every backslash (``'\'``) in a regular expression would have to be prefixed with another one to escape it. For example, the two following lines of code are functionally identical:: - >>> re.match(r"\W(.)\1\W", " ff ") + >>> re.search(r"\W(.)\1\W", " ff ") - >>> re.match("\\W(.)\\1\\W", " ff ") + >>> re.search("\\W(.)\\1\\W", " ff ") When one wants to match a literal backslash, it must be escaped in the regular @@ -1861,9 +1916,9 @@ expression. With raw string notation, this means ``r"\\"``. Without raw string notation, one must use ``"\\\\"``, making the following lines of code functionally identical:: - >>> re.match(r"\\", r"\\") + >>> re.search(r"\\", r"\\") - >>> re.match("\\\\", r"\\") + >>> re.search("\\\\", r"\\") diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index cd80947924684d..5dca1545b144ef 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -824,6 +824,19 @@ pickle (Contributed by Zackery Spytz and Serhiy Storchaka in :gh:`77188`.) +re +-- + +* :func:`re.prefixmatch` and a corresponding :meth:`~re.Pattern.prefixmatch` + have been added as alternate more explicit names for the existing + :func:`re.match` and :meth:`~re.Pattern.match` APIs. These are intended + to be used to alleviate confusion around what *match* means by following the + Zen of Python's *"Explicit is better than implicit"* mantra. Most other + language regular expression libraries use an API named *match* to mean what + Python has always called *search*. + (Contributed by Gregory P. Smith in :gh:`86519`.) + + resource -------- @@ -1285,7 +1298,7 @@ Diego Russo in :gh:`140683` and :gh:`142305`.) Removed -======= +======== ctypes ------ diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index ecec16e9005f3b..e6d29fd7a403b6 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -85,17 +85,18 @@ \\ Matches a literal backslash. This module exports the following functions: - match Match a regular expression pattern to the beginning of a string. - fullmatch Match a regular expression pattern to all of a string. - search Search a string for the presence of a pattern. - sub Substitute occurrences of a pattern found in a string. - subn Same as sub, but also return the number of substitutions made. - split Split a string by the occurrences of a pattern. - findall Find all occurrences of a pattern in a string. - finditer Return an iterator yielding a Match object for each match. - compile Compile a pattern into a Pattern object. - purge Clear the regular expression cache. - escape Backslash all non-alphanumerics in a string. + prefixmatch Match a regular expression pattern to the beginning of a str. + match The original name of prefixmatch prior to 3.15. + fullmatch Match a regular expression pattern to all of a string. + search Search a string for the presence of a pattern. + sub Substitute occurrences of a pattern found in a string. + subn Same as sub, but also return the number of substitutions made. + split Split a string by the occurrences of a pattern. + findall Find all occurrences of a pattern in a string. + finditer Return an iterator yielding a Match object for each match. + compile Compile a pattern into a Pattern object. + purge Clear the regular expression cache. + escape Backslash all non-alphanumerics in a string. Each function other than purge and escape can take an optional 'flags' argument consisting of one or more of the following module constants, joined by "|". @@ -130,7 +131,7 @@ # public symbols __all__ = [ - "match", "fullmatch", "search", "sub", "subn", "split", + "prefixmatch", "match", "fullmatch", "search", "sub", "subn", "split", "findall", "finditer", "compile", "purge", "escape", "error", "Pattern", "Match", "A", "I", "L", "M", "S", "X", "U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", @@ -159,10 +160,13 @@ class RegexFlag: # -------------------------------------------------------------------- # public interface -def match(pattern, string, flags=0): +def prefixmatch(pattern, string, flags=0): """Try to apply the pattern at the start of the string, returning a Match object, or None if no match was found.""" - return _compile(pattern, flags).match(string) + return _compile(pattern, flags).prefixmatch(string) + +# Our original name which was less explicitly clear about the behavior for prefixmatch. +match = prefixmatch def fullmatch(pattern, string, flags=0): """Try to apply the pattern to all of the string, returning @@ -311,7 +315,7 @@ def escape(pattern): return pattern.translate(_special_chars_map).encode('latin1') Pattern = type(_compiler.compile('', 0)) -Match = type(_compiler.compile('', 0).match('')) +Match = type(_compiler.compile('', 0).prefixmatch('')) # -------------------------------------------------------------------- # internals @@ -410,10 +414,10 @@ def __init__(self, lexicon, flags=0): def scan(self, string): result = [] append = result.append - match = self.scanner.scanner(string).match + _match = self.scanner.scanner(string).prefixmatch i = 0 while True: - m = match() + m = _match() if not m: break j = m.end() diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index e4a3a7d9add2c2..32bb47de04b113 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -6277,7 +6277,10 @@ def test_pwd_module_has_signatures(self): def test_re_module_has_signatures(self): import re - methods_no_signature = {'Match': {'group'}} + methods_no_signature = { + 'Match': {'group'}, + 'Pattern': {'match'}, # It is now an alias for prefixmatch + } self._test_module_has_signatures(re, methods_no_signature=methods_no_signature, good_exceptions={'error', 'PatternError'}) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 9f6f04bf6b8347..5e19307b815a1b 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -90,10 +90,13 @@ def test_search_star_plus(self): self.assertEqual(re.search('x+', 'axx').span(), (1, 3)) self.assertIsNone(re.search('x', 'aaa')) self.assertEqual(re.match('a*', 'xxx').span(0), (0, 0)) + self.assertEqual(re.prefixmatch('a*', 'xxx').span(0), (0, 0)) self.assertEqual(re.match('a*', 'xxx').span(), (0, 0)) self.assertEqual(re.match('x*', 'xxxa').span(0), (0, 3)) + self.assertEqual(re.prefixmatch('x*', 'xxxa').span(0), (0, 3)) self.assertEqual(re.match('x*', 'xxxa').span(), (0, 3)) self.assertIsNone(re.match('a+', 'xxx')) + self.assertIsNone(re.prefixmatch('a+', 'xxx')) def test_branching(self): """Test Branching @@ -180,6 +183,7 @@ def test_bug_449000(self): def test_bug_1661(self): # Verify that flags do not get silently ignored with compiled patterns pattern = re.compile('.') + self.assertRaises(ValueError, re.prefixmatch, pattern, 'A', re.I) self.assertRaises(ValueError, re.match, pattern, 'A', re.I) self.assertRaises(ValueError, re.search, pattern, 'A', re.I) self.assertRaises(ValueError, re.findall, pattern, 'A', re.I) @@ -517,6 +521,8 @@ def test_re_match(self): self.assertEqual(re.match(b'(a)', string).group(0), b'a') self.assertEqual(re.match(b'(a)', string).group(1), b'a') self.assertEqual(re.match(b'(a)', string).group(1, 1), (b'a', b'a')) + self.assertEqual(re.prefixmatch(b'(a)', string).group(1, 1), + (b'a', b'a')) for a in ("\xe0", "\u0430", "\U0001d49c"): self.assertEqual(re.match(a, a).groups(), ()) self.assertEqual(re.match('(%s)' % a, a).groups(), (a,)) @@ -558,10 +564,8 @@ def __index__(self): self.assertEqual(m.group(2, 1), ('b', 'a')) self.assertEqual(m.group(Index(2), Index(1)), ('b', 'a')) - def test_match_getitem(self): - pat = re.compile('(?:(?Pa)|(?Pb))(?Pc)?') - - m = pat.match('a') + def do_test_match_getitem(self, match_fn): + m = match_fn('a') self.assertEqual(m['a1'], 'a') self.assertEqual(m['b2'], None) self.assertEqual(m['c3'], None) @@ -585,7 +589,7 @@ def test_match_getitem(self): with self.assertRaisesRegex(IndexError, 'no such group'): 'a1={a2}'.format_map(m) - m = pat.match('ac') + m = match_fn('ac') self.assertEqual(m['a1'], 'a') self.assertEqual(m['b2'], None) self.assertEqual(m['c3'], 'c') @@ -602,6 +606,14 @@ def test_match_getitem(self): # No len(). self.assertRaises(TypeError, len, m) + def test_match_getitem(self): + pat = re.compile('(?:(?Pa)|(?Pb))(?Pc)?') + self.do_test_match_getitem(pat.match) + + def test_prefixmatch_getitem(self): + pat = re.compile('(?:(?Pa)|(?Pb))(?Pc)?') + self.do_test_match_getitem(pat.prefixmatch) + def test_re_fullmatch(self): # Issue 16203: Proposal: add re.fullmatch() method. self.assertEqual(re.fullmatch(r"a", "a").span(), (0, 1)) diff --git a/Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst b/Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst new file mode 100644 index 00000000000000..a3e0a3e14af1fa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst @@ -0,0 +1,10 @@ +The :mod:`re` module gains a new :func:`re.prefixmatch` function as an +explicit spelling of what has to date always been known as :func:`re.match`. +:class:`re.Pattern` similary gains a :meth:`re.Pattern.prefixmatch` method. + +Why? Explicit is better than implicit. Other widely used languages all use +the term "match" to mean what Python uses the term "search" for. The +unadorened "match" name in Python has been a frequent case of confusion and +coding bugs due to the inconsistency with the rest if the software industry. + +We do not plan to deprecate and remove the older ``match`` name. diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index d2f25a71495cda..b49bf4e058b69b 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -164,22 +164,22 @@ _sre_unicode_tolower(PyObject *module, PyObject *arg) return return_value; } -PyDoc_STRVAR(_sre_SRE_Pattern_match__doc__, -"match($self, /, string, pos=0, endpos=sys.maxsize)\n" +PyDoc_STRVAR(_sre_SRE_Pattern_prefixmatch__doc__, +"prefixmatch($self, /, string, pos=0, endpos=sys.maxsize)\n" "--\n" "\n" "Matches zero or more characters at the beginning of the string."); -#define _SRE_SRE_PATTERN_MATCH_METHODDEF \ - {"match", _PyCFunction_CAST(_sre_SRE_Pattern_match), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, +#define _SRE_SRE_PATTERN_PREFIXMATCH_METHODDEF \ + {"prefixmatch", _PyCFunction_CAST(_sre_SRE_Pattern_prefixmatch), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_prefixmatch__doc__}, static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, - PyObject *string, Py_ssize_t pos, - Py_ssize_t endpos); +_sre_SRE_Pattern_prefixmatch_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos); static PyObject * -_sre_SRE_Pattern_match(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Pattern_prefixmatch(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -205,7 +205,7 @@ _sre_SRE_Pattern_match(PyObject *self, PyTypeObject *cls, PyObject *const *args, static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "match", + .fname = "prefixmatch", .kwtuple = KWTUPLE, }; #undef KWTUPLE @@ -254,7 +254,7 @@ _sre_SRE_Pattern_match(PyObject *self, PyTypeObject *cls, PyObject *const *args, endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_match_impl((PatternObject *)self, cls, string, pos, endpos); + return_value = _sre_SRE_Pattern_prefixmatch_impl((PatternObject *)self, cls, string, pos, endpos); exit: return return_value; @@ -1523,25 +1523,25 @@ _sre_SRE_Match___deepcopy__(PyObject *self, PyObject *memo) return return_value; } -PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__, -"match($self, /)\n" +PyDoc_STRVAR(_sre_SRE_Scanner_prefixmatch__doc__, +"prefixmatch($self, /)\n" "--\n" "\n"); -#define _SRE_SRE_SCANNER_MATCH_METHODDEF \ - {"match", _PyCFunction_CAST(_sre_SRE_Scanner_match), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_match__doc__}, +#define _SRE_SRE_SCANNER_PREFIXMATCH_METHODDEF \ + {"prefixmatch", _PyCFunction_CAST(_sre_SRE_Scanner_prefixmatch), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_prefixmatch__doc__}, static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); +_sre_SRE_Scanner_prefixmatch_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * -_sre_SRE_Scanner_match(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sre_SRE_Scanner_prefixmatch(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { - PyErr_SetString(PyExc_TypeError, "match() takes no arguments"); + PyErr_SetString(PyExc_TypeError, "prefixmatch() takes no arguments"); return NULL; } - return _sre_SRE_Scanner_match_impl((ScannerObject *)self, cls); + return _sre_SRE_Scanner_prefixmatch_impl((ScannerObject *)self, cls); } PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, @@ -1568,4 +1568,4 @@ _sre_SRE_Scanner_search(PyObject *self, PyTypeObject *cls, PyObject *const *args #ifndef _SRE_SRE_PATTERN__FAIL_AFTER_METHODDEF #define _SRE_SRE_PATTERN__FAIL_AFTER_METHODDEF #endif /* !defined(_SRE_SRE_PATTERN__FAIL_AFTER_METHODDEF) */ -/*[clinic end generated code: output=bbf42e1de3bdd3ae input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0c867efb64e020aa input=a9049054013a1b77]*/ diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 59ff9078e6cff4..d6cdd861fd85a2 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -766,7 +766,7 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern) } /*[clinic input] -_sre.SRE_Pattern.match +_sre.SRE_Pattern.prefixmatch cls: defining_class / @@ -778,10 +778,10 @@ Matches zero or more characters at the beginning of the string. [clinic start generated code]*/ static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, - PyObject *string, Py_ssize_t pos, - Py_ssize_t endpos) -/*[clinic end generated code: output=ec6208ea58a0cca0 input=4bdb9c3e564d13ac]*/ +_sre_SRE_Pattern_prefixmatch_impl(PatternObject *self, PyTypeObject *cls, + PyObject *string, Py_ssize_t pos, + Py_ssize_t endpos) +/*[clinic end generated code: output=a0e079fb4f875240 input=e2a7e68ea47d048c]*/ { _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE state; @@ -809,6 +809,7 @@ _sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, return match; } + /*[clinic input] _sre.SRE_Pattern.fullmatch @@ -2671,7 +2672,7 @@ _sre_SRE_Match___deepcopy___impl(MatchObject *self, PyObject *memo) } PyDoc_STRVAR(match_doc, -"The result of re.match() and re.search().\n\ +"The result of re.search(), re.prefixmatch(), and re.fullmatch().\n\ Match objects always have a boolean value of True."); PyDoc_STRVAR(match_group_doc, @@ -2863,7 +2864,7 @@ scanner_end(ScannerObject* self) } /*[clinic input] -_sre.SRE_Scanner.match +_sre.SRE_Scanner.prefixmatch cls: defining_class / @@ -2871,8 +2872,8 @@ _sre.SRE_Scanner.match [clinic start generated code]*/ static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=6e22c149dc0f0325 input=b5146e1f30278cb7]*/ +_sre_SRE_Scanner_prefixmatch_impl(ScannerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=02b3b9d2954a2157 input=3049b20466c56a8e]*/ { _sremodulestate *module_state = get_sre_module_state_by_class(cls); SRE_STATE* state = &self->state; @@ -3170,7 +3171,12 @@ pattern_richcompare(PyObject *lefto, PyObject *righto, int op) #include "clinic/sre.c.h" static PyMethodDef pattern_methods[] = { - _SRE_SRE_PATTERN_MATCH_METHODDEF + _SRE_SRE_PATTERN_PREFIXMATCH_METHODDEF + /* "match" reuses the prefixmatch Clinic-generated parser and impl + * to avoid duplicating the argument parsing boilerplate code. */ + {"match", _PyCFunction_CAST(_sre_SRE_Pattern_prefixmatch), + METH_METHOD|METH_FASTCALL|METH_KEYWORDS, + _sre_SRE_Pattern_prefixmatch__doc__}, _SRE_SRE_PATTERN_FULLMATCH_METHODDEF _SRE_SRE_PATTERN_SEARCH_METHODDEF _SRE_SRE_PATTERN_SUB_METHODDEF @@ -3297,7 +3303,12 @@ static PyType_Spec match_spec = { }; static PyMethodDef scanner_methods[] = { - _SRE_SRE_SCANNER_MATCH_METHODDEF + _SRE_SRE_SCANNER_PREFIXMATCH_METHODDEF + /* "match" reuses the prefixmatch Clinic-generated parser and impl + * to avoid duplicating the argument parsing boilerplate code. */ + {"match", _PyCFunction_CAST(_sre_SRE_Scanner_prefixmatch), + METH_METHOD|METH_FASTCALL|METH_KEYWORDS, + _sre_SRE_Scanner_prefixmatch__doc__}, _SRE_SRE_SCANNER_SEARCH_METHODDEF {NULL, NULL} }; @@ -3401,11 +3412,31 @@ do { \ } \ } while (0) + +#ifdef Py_DEBUG +static void +_assert_match_aliases_prefixmatch(PyMethodDef *methods) +{ + PyMethodDef *prefixmatch_md = &methods[0]; + PyMethodDef *match_md = &methods[1]; + assert(strcmp(prefixmatch_md->ml_name, "prefixmatch") == 0); + assert(strcmp(match_md->ml_name, "match") == 0); + assert(match_md->ml_meth == prefixmatch_md->ml_meth); + assert(match_md->ml_flags == prefixmatch_md->ml_flags); + assert(match_md->ml_doc == prefixmatch_md->ml_doc); +} +#endif + static int sre_exec(PyObject *m) { _sremodulestate *state; +#ifdef Py_DEBUG + _assert_match_aliases_prefixmatch(pattern_methods); + _assert_match_aliases_prefixmatch(scanner_methods); +#endif + /* Create heap types */ state = get_sre_module_state(m); CREATE_TYPE(m, state->Pattern_Type, &pattern_spec); From c91638ca0671b8038831f963ed44e66cdda006a2 Mon Sep 17 00:00:00 2001 From: Ramin Farajpour Cami Date: Mon, 16 Feb 2026 06:13:07 +0330 Subject: [PATCH 115/498] gh-144833: Fix use-after-free in SSL module when SSL_new() fails (GH-144843) In newPySSLSocket(), when SSL_new() returns NULL, Py_DECREF(self) was called before _setSSLError(get_state_ctx(self), ...), causing a use-after-free. Additionally, get_state_ctx() was called with self (PySSLSocket*) instead of sslctx (PySSLContext*), which is a type confusion bug. Fix by calling _setSSLError() before Py_DECREF() and using sslctx instead of self for get_state_ctx(). --- .../Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst | 3 +++ Modules/_ssl.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst b/Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst new file mode 100644 index 00000000000000..6d5b18f59ee7ea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst @@ -0,0 +1,3 @@ +Fixed a use-after-free in :mod:`ssl` when ``SSL_new()`` returns NULL in +``newPySSLSocket()``. The error was reported via a dangling pointer after the +object had already been freed. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 66d699b4339ce3..b0c0d8deeecd23 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -917,8 +917,8 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->ssl = SSL_new(ctx); PySSL_END_ALLOW_THREADS(sslctx) if (self->ssl == NULL) { + _setSSLError(get_state_ctx(sslctx), NULL, 0, __FILE__, __LINE__); Py_DECREF(self); - _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } From 87c7f193b8ea7be36f3ba5a66b5c223efde4c674 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 15 Feb 2026 23:02:07 -0600 Subject: [PATCH 116/498] gh-144551: Update Android builds to use OpenSSL 3.0.19 (GH-144864) --- Android/android.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Android/android.py b/Android/android.py index 629696be3db300..0a894a958a0165 100755 --- a/Android/android.py +++ b/Android/android.py @@ -208,7 +208,7 @@ def make_build_python(context): def unpack_deps(host, prefix_dir): os.chdir(prefix_dir) deps_url = "https://github.com/beeware/cpython-android-source-deps/releases/download" - for name_ver in ["bzip2-1.0.8-3", "libffi-3.4.4-3", "openssl-3.0.18-0", + for name_ver in ["bzip2-1.0.8-3", "libffi-3.4.4-3", "openssl-3.0.19-1", "sqlite-3.50.4-0", "xz-5.4.6-1", "zstd-1.5.7-1"]: filename = f"{name_ver}-{host}.tar.gz" download(f"{deps_url}/{name_ver}/{filename}") From ebe02e4f393bc0bd2263c43da313b28012f82af9 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 15 Feb 2026 23:02:23 -0600 Subject: [PATCH 117/498] gh-144551: Update iOS builds to use OpenSSL 3.0.19 (GH-144865) --- Apple/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apple/__main__.py b/Apple/__main__.py index 256966e76c2c97..253bdfaab5520c 100644 --- a/Apple/__main__.py +++ b/Apple/__main__.py @@ -316,7 +316,7 @@ def unpack_deps( for name_ver in [ "BZip2-1.0.8-2", "libFFI-3.4.7-2", - "OpenSSL-3.0.18-1", + "OpenSSL-3.0.19-1", "XZ-5.6.4-2", "mpdecimal-4.0.0-2", "zstd-1.5.7-1", From 8b7b5a994602824a5e41cf2516691212fcdfa25e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 16 Feb 2026 13:31:18 +0200 Subject: [PATCH 118/498] gh-80667: Fix Tangut ideographs names in unicodedata (GH-144789) Co-authored-by: Pierre Le Marre --- Lib/test/test_ucn.py | 24 ++++ Lib/test/test_unicodedata.py | 107 +++++++++++++++++- ...3-02-05-20-02-30.gh-issue-80667.7LmzeA.rst | 1 + Modules/unicodedata.c | 105 ++++++++++------- Modules/unicodename_db.h | 28 +++++ Tools/unicode/makeunicodedata.py | 53 +++++---- 6 files changed, 254 insertions(+), 64 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst diff --git a/Lib/test/test_ucn.py b/Lib/test/test_ucn.py index 0c641a455c0747..5f4f1b8e52ccef 100644 --- a/Lib/test/test_ucn.py +++ b/Lib/test/test_ucn.py @@ -111,6 +111,30 @@ def test_cjk_unified_ideographs(self): self.checkletter("cjK UniFIeD idEogRAph-2aBcD", "\U0002abcd") self.checkletter("CJk uNIfiEd IDeOGraPH-2AbCd", "\U0002abcd") + def test_tangut_ideographs(self): + self.checkletter("TANGUT IDEOGRAPH-17000", "\U00017000") + self.checkletter("TANGUT IDEOGRAPH-187FF", "\U000187ff") + self.checkletter("TANGUT IDEOGRAPH-18D00", "\U00018D00") + self.checkletter("TANGUT IDEOGRAPH-18D1E", "\U00018d1e") + self.checkletter("tangut ideograph-18d1e", "\U00018d1e") + + def test_egyptian_hieroglyphs(self): + self.checkletter("EGYPTIAN HIEROGLYPH-13460", "\U00013460") + self.checkletter("EGYPTIAN HIEROGLYPH-143FA", "\U000143fa") + self.checkletter("egyptian hieroglyph-143fa", "\U000143fa") + + def test_khitan_small_script_characters(self): + self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18B00", "\U00018b00") + self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18CD5", "\U00018cd5") + self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18CFF", "\U00018cff") + self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18CFF", "\U00018cff") + self.checkletter("khitan small script character-18cff", "\U00018cff") + + def test_nushu_characters(self): + self.checkletter("NUSHU CHARACTER-1B170", "\U0001b170") + self.checkletter("NUSHU CHARACTER-1B2FB", "\U0001b2fb") + self.checkletter("nushu character-1b2fb", "\U0001b2fb") + def test_bmp_characters(self): for code in range(0x10000): char = chr(code) diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 83b94f97c22c9d..d100dae1110b7f 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -128,6 +128,60 @@ def test_function_checksum(self): result = h.hexdigest() self.assertEqual(result, self.expectedchecksum) + def test_name(self): + name = self.db.name + self.assertRaises(ValueError, name, '\0') + self.assertRaises(ValueError, name, '\n') + self.assertRaises(ValueError, name, '\x1F') + self.assertRaises(ValueError, name, '\x7F') + self.assertRaises(ValueError, name, '\x9F') + self.assertRaises(ValueError, name, '\uFFFE') + self.assertRaises(ValueError, name, '\uFFFF') + self.assertRaises(ValueError, name, '\U0010FFFF') + self.assertEqual(name('\U0010FFFF', 42), 42) + + self.assertEqual(name(' '), 'SPACE') + self.assertEqual(name('1'), 'DIGIT ONE') + self.assertEqual(name('A'), 'LATIN CAPITAL LETTER A') + self.assertEqual(name('\xA0'), 'NO-BREAK SPACE') + self.assertEqual(name('\u0221', None), None if self.old else + 'LATIN SMALL LETTER D WITH CURL') + self.assertEqual(name('\u3400'), 'CJK UNIFIED IDEOGRAPH-3400') + self.assertEqual(name('\u9FA5'), 'CJK UNIFIED IDEOGRAPH-9FA5') + self.assertEqual(name('\uAC00'), 'HANGUL SYLLABLE GA') + self.assertEqual(name('\uD7A3'), 'HANGUL SYLLABLE HIH') + self.assertEqual(name('\uF900'), 'CJK COMPATIBILITY IDEOGRAPH-F900') + self.assertEqual(name('\uFA6A'), 'CJK COMPATIBILITY IDEOGRAPH-FA6A') + self.assertEqual(name('\uFBF9'), + 'ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ' + 'ABOVE WITH ALEF MAKSURA ISOLATED FORM') + self.assertEqual(name('\U00013460', None), None if self.old else + 'EGYPTIAN HIEROGLYPH-13460') + self.assertEqual(name('\U000143FA', None), None if self.old else + 'EGYPTIAN HIEROGLYPH-143FA') + self.assertEqual(name('\U00017000', None), None if self.old else + 'TANGUT IDEOGRAPH-17000') + self.assertEqual(name('\U00018B00', None), None if self.old else + 'KHITAN SMALL SCRIPT CHARACTER-18B00') + self.assertEqual(name('\U00018CD5', None), None if self.old else + 'KHITAN SMALL SCRIPT CHARACTER-18CD5') + self.assertEqual(name('\U00018CFF', None), None if self.old else + 'KHITAN SMALL SCRIPT CHARACTER-18CFF') + self.assertEqual(name('\U00018D1E', None), None if self.old else + 'TANGUT IDEOGRAPH-18D1E') + self.assertEqual(name('\U0001B170', None), None if self.old else + 'NUSHU CHARACTER-1B170') + self.assertEqual(name('\U0001B2FB', None), None if self.old else + 'NUSHU CHARACTER-1B2FB') + self.assertEqual(name('\U0001FBA8', None), None if self.old else + 'BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO ' + 'MIDDLE LEFT AND MIDDLE RIGHT TO LOWER CENTRE') + self.assertEqual(name('\U0002A6D6'), 'CJK UNIFIED IDEOGRAPH-2A6D6') + self.assertEqual(name('\U0002FA1D'), 'CJK COMPATIBILITY IDEOGRAPH-2FA1D') + self.assertEqual(name('\U00033479', None), None if self.old else + 'CJK UNIFIED IDEOGRAPH-33479') + + @requires_resource('cpu') def test_name_inverse_lookup(self): for char in iterallchars(): looked_name = self.db.name(char, None) @@ -151,6 +205,17 @@ def test_lookup_nonexistant(self): "HANDBUG", "MODIFIER LETTER CYRILLIC SMALL QUESTION MARK", "???", + "CJK UNIFIED IDEOGRAPH-03400", + "CJK UNIFIED IDEOGRAPH-020000", + "CJK UNIFIED IDEOGRAPH-33FF", + "CJK UNIFIED IDEOGRAPH-F900", + "CJK UNIFIED IDEOGRAPH-13460", + "CJK UNIFIED IDEOGRAPH-17000", + "CJK UNIFIED IDEOGRAPH-18B00", + "CJK UNIFIED IDEOGRAPH-1B170", + "CJK COMPATIBILITY IDEOGRAPH-3400", + "TANGUT IDEOGRAPH-3400", + "HANGUL SYLLABLE AC00", ]: self.assertRaises(KeyError, self.db.lookup, nonexistent) @@ -613,7 +678,47 @@ class UnicodeFunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): # (e.g. 'make distclean && make') to get the correct checksum. expectedchecksum = ('83cc43a2fbb779185832b4c049217d80b05bf349' if quicktest else - '65670ae03a324c5f9e826a4de3e25bae4d73c9b7') + '180bdc91143d8aa2eb9dd6726e66d37606205942') + + @requires_resource('network') + def test_all_names(self): + TESTDATAFILE = "DerivedName.txt" + testdata = download_test_data_file(TESTDATAFILE) + + with testdata: + self.run_name_tests(testdata) + + def run_name_tests(self, testdata): + names_ref = {} + + def parse_cp(s): + return int(s, 16) + + # Parse data + for line in testdata: + line = line.strip() + if not line or line.startswith("#"): + continue + raw_cp, name = line.split("; ") + # Check for a range + if ".." in raw_cp: + cp1, cp2 = map(parse_cp, raw_cp.split("..")) + # remove ‘*’ at the end + assert name[-1] == '*', (raw_cp, name) + name = name[:-1] + for cp in range(cp1, cp2 + 1): + names_ref[cp] = f"{name}{cp:04X}" + elif name[-1] == '*': + cp = parse_cp(raw_cp) + name = name[:-1] + names_ref[cp] = f"{name}{cp:04X}" + else: + assert '*' not in name, (raw_cp, name) + cp = parse_cp(raw_cp) + names_ref[cp] = name + + for cp in range(0, sys.maxunicode + 1): + self.assertEqual(self.db.name(chr(cp), None), names_ref.get(cp)) def test_isxidstart(self): self.assertTrue(self.db.isxidstart('S')) diff --git a/Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst b/Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst new file mode 100644 index 00000000000000..f82f1eeb0589c6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst @@ -0,0 +1 @@ +Add support for Tangut Ideographs names in :mod:`unicodedata`. diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 44ffedec3840fe..1ed9760874b2a6 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1052,22 +1052,18 @@ static const char * const hangul_syllables[][3] = { { 0, 0, "H" } }; -/* These ranges need to match makeunicodedata.py:cjk_ranges. */ static int -is_unified_ideograph(Py_UCS4 code) -{ - return - (0x3400 <= code && code <= 0x4DBF) || /* CJK Ideograph Extension A */ - (0x4E00 <= code && code <= 0x9FFF) || /* CJK Ideograph */ - (0x20000 <= code && code <= 0x2A6DF) || /* CJK Ideograph Extension B */ - (0x2A700 <= code && code <= 0x2B73F) || /* CJK Ideograph Extension C */ - (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ - (0x2B820 <= code && code <= 0x2CEAD) || /* CJK Ideograph Extension E */ - (0x2CEB0 <= code && code <= 0x2EBE0) || /* CJK Ideograph Extension F */ - (0x2EBF0 <= code && code <= 0x2EE5D) || /* CJK Ideograph Extension I */ - (0x30000 <= code && code <= 0x3134A) || /* CJK Ideograph Extension G */ - (0x31350 <= code && code <= 0x323AF) || /* CJK Ideograph Extension H */ - (0x323B0 <= code && code <= 0x33479); /* CJK Ideograph Extension J */ +find_prefix_id(Py_UCS4 code) +{ + for (int i = 0; i < (int)Py_ARRAY_LENGTH(derived_name_ranges); i++) { + if (code < derived_name_ranges[i].first) { + return -1; + } + if (code <= derived_name_ranges[i].last) { + return derived_name_ranges[i].prefixid; + } + } + return -1; } /* macros used to determine if the given code point is in the PUA range that @@ -1345,7 +1341,9 @@ _getucname(PyObject *self, } } - if (SBase <= code && code < SBase+SCount) { + int prefixid = find_prefix_id(code); + if (prefixid == 0) { + assert(SBase <= code && code < SBase+SCount); /* Hangul syllable. */ int SIndex = code - SBase; int L = SIndex / NCount; @@ -1367,11 +1365,11 @@ _getucname(PyObject *self, return 1; } - if (is_unified_ideograph(code)) { - if (buflen < 28) - /* Worst case: CJK UNIFIED IDEOGRAPH-20000 */ + if (prefixid > 0) { + const char *prefix = derived_name_prefixes[prefixid]; + if (snprintf(buffer, buflen, "%s%04X", prefix, code) >= buflen) { return 0; - sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code); + } return 1; } @@ -1428,6 +1426,35 @@ _check_alias_and_seq(Py_UCS4* code, int with_named_seq) return 1; } +static Py_UCS4 +parse_hex_code(const char *name, int namelen) +{ + if (namelen < 4 || namelen > 6) { + return (Py_UCS4)-1; + } + if (*name == '0') { + return (Py_UCS4)-1; + } + int v = 0; + while (namelen--) { + v *= 16; + Py_UCS1 c = Py_TOUPPER(*name); + if (c >= '0' && c <= '9') { + v += c - '0'; + } + else if (c >= 'A' && c <= 'F') { + v += c - 'A' + 10; + } + else { + return (Py_UCS4)-1; + } + name++; + } + if (v > 0x10ffff) { + return (Py_UCS4)-1; + } + return v; +} static int _getcode(const char* name, int namelen, Py_UCS4* code) @@ -1436,8 +1463,19 @@ _getcode(const char* name, int namelen, Py_UCS4* code) * Named aliases are not resolved, they are returned as a code point in the * PUA */ - /* Check for hangul syllables. */ - if (PyOS_strnicmp(name, "HANGUL SYLLABLE ", 16) == 0) { + int i = 0; + size_t prefixlen; + for (; i < (int)Py_ARRAY_LENGTH(derived_name_prefixes); i++) { + const char *prefix = derived_name_prefixes[i]; + prefixlen = strlen(derived_name_prefixes[i]); + if (PyOS_strnicmp(name, prefix, prefixlen) == 0) { + break; + } + } + + if (i == 0) { + /* Hangul syllables. */ + assert(PyOS_strnicmp(name, "HANGUL SYLLABLE ", 16) == 0); int len, L = -1, V = -1, T = -1; const char *pos = name + 16; find_syllable(pos, &len, &L, LCount, 0); @@ -1454,28 +1492,11 @@ _getcode(const char* name, int namelen, Py_UCS4* code) return 0; } - /* Check for unified ideographs. */ - if (PyOS_strnicmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) { - /* Four or five hexdigits must follow. */ - unsigned int v; - v = 0; - name += 22; - namelen -= 22; - if (namelen != 4 && namelen != 5) + if (i < (int)Py_ARRAY_LENGTH(derived_name_prefixes)) { + Py_UCS4 v = parse_hex_code(name + prefixlen, namelen - prefixlen); + if (find_prefix_id(v) != i) { return 0; - while (namelen--) { - v *= 16; - Py_UCS1 c = Py_TOUPPER(*name); - if (c >= '0' && c <= '9') - v += c - '0'; - else if (c >= 'A' && c <= 'F') - v += c - 'A' + 10; - else - return 0; - name++; } - if (!is_unified_ideograph(v)) - return 0; *code = v; return 1; } diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index d67e968e7a01ae..d9d062a2345974 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -19684,3 +19684,31 @@ static const named_sequence named_sequences[] = { {2, {0x02E5, 0x02E9}}, {2, {0x02E9, 0x02E5}}, }; + +typedef struct { + Py_UCS4 first; + Py_UCS4 last; + int prefixid; +} derived_name_range; + +static const derived_name_range derived_name_ranges[] = { + {0x3400, 0x4DBF, 1}, + {0x4E00, 0x9FFF, 1}, + {0xAC00, 0xD7A3, 0}, + {0x17000, 0x187FF, 2}, + {0x18D00, 0x18D1E, 2}, + {0x20000, 0x2A6DF, 1}, + {0x2A700, 0x2B73F, 1}, + {0x2B740, 0x2B81D, 1}, + {0x2B820, 0x2CEAD, 1}, + {0x2CEB0, 0x2EBE0, 1}, + {0x2EBF0, 0x2EE5D, 1}, + {0x30000, 0x3134A, 1}, + {0x31350, 0x323AF, 1}, + {0x323B0, 0x33479, 1}, +}; +static const char * const derived_name_prefixes[] = { + "HANGUL SYLLABLE ", + "CJK UNIFIED IDEOGRAPH-", + "TANGUT IDEOGRAPH-", +}; diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index f5fa30a3622a3a..432dc3a68bf5ed 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -109,19 +109,13 @@ CASED_MASK = 0x2000 EXTENDED_CASE_MASK = 0x4000 -# these ranges need to match unicodedata.c:is_unified_ideograph -cjk_ranges = [ - ('3400', '4DBF'), # CJK Ideograph Extension A CJK - ('4E00', '9FFF'), # CJK Ideograph - ('20000', '2A6DF'), # CJK Ideograph Extension B - ('2A700', '2B73F'), # CJK Ideograph Extension C - ('2B740', '2B81D'), # CJK Ideograph Extension D - ('2B820', '2CEAD'), # CJK Ideograph Extension E - ('2CEB0', '2EBE0'), # CJK Ideograph Extension F - ('2EBF0', '2EE5D'), # CJK Ideograph Extension I - ('30000', '3134A'), # CJK Ideograph Extension G - ('31350', '323AF'), # CJK Ideograph Extension H - ('323B0', '33479'), # CJK Ideograph Extension J +# Maps the range names in UnicodeData.txt to prefixes for +# derived names specified by rule NR2. +# Hangul should always be at index 0, since it uses special format. +derived_name_range_names = [ + ("Hangul Syllable", "HANGUL SYLLABLE "), + ("CJK Ideograph", "CJK UNIFIED IDEOGRAPH-"), + ("Tangut Ideograph", "TANGUT IDEOGRAPH-"), ] @@ -135,7 +129,7 @@ def maketables(trace=0): for version in old_versions: print("--- Reading", UNICODE_DATA % ("-"+version), "...") - old_unicode = UnicodeData(version, cjk_check=False) + old_unicode = UnicodeData(version, ideograph_check=False) print(len(list(filter(None, old_unicode.table))), "characters") merge_old_version(version, unicode, old_unicode) @@ -731,6 +725,23 @@ def makeunicodename(unicode, trace): fprint(' {%d, {%s}},' % (len(sequence), seq_str)) fprint('};') + fprint(dedent(""" + typedef struct { + Py_UCS4 first; + Py_UCS4 last; + int prefixid; + } derived_name_range; + """)) + + fprint('static const derived_name_range derived_name_ranges[] = {') + for name_range in unicode.derived_name_ranges: + fprint(' {0x%s, 0x%s, %d},' % name_range) + fprint('};') + + fprint('static const char * const derived_name_prefixes[] = {') + for _, prefix in derived_name_range_names: + fprint(' "%s",' % prefix) + fprint('};') def merge_old_version(version, new, old): # Changes to exclusion file not implemented yet @@ -946,14 +957,14 @@ def from_row(row: List[str]) -> UcdRecord: class UnicodeData: # table: List[Optional[UcdRecord]] # index is codepoint; None means unassigned - def __init__(self, version, cjk_check=True): + def __init__(self, version, ideograph_check=True): self.changed = [] table = [None] * 0x110000 for s in UcdFile(UNICODE_DATA, version): char = int(s[0], 16) table[char] = from_row(s) - cjk_ranges_found = [] + self.derived_name_ranges = [] # expand first-last ranges field = None @@ -967,15 +978,15 @@ def __init__(self, version, cjk_check=True): s.name = "" field = dataclasses.astuple(s)[:15] elif s.name[-5:] == "Last>": - if s.name.startswith(" Date: Mon, 16 Feb 2026 14:14:26 +0100 Subject: [PATCH 119/498] bpo-32234: Allow mailbox instances as context managers (GH-4770) Co-authored-by: Petr Viktorin Co-authored-by: R. David Murray --- Doc/library/mailbox.rst | 8 ++++++++ Lib/mailbox.py | 7 +++++++ Lib/test/test_mailbox.py | 15 +++++++++++++++ .../2017-12-15-09-32-57.bpo-32234.XaOkhR.rst | 2 ++ 4 files changed, 32 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index ed135bf02cb968..3b0c17c838c879 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -78,6 +78,14 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. message. Failing to lock the mailbox runs the risk of losing messages or corrupting the entire mailbox. + The :class:`!Mailbox` class supports the :keyword:`with` statement. When used + as a context manager, :class:`!Mailbox` calls :meth:`lock` when the context is entered, + returns the mailbox object as the context object, and at context end calls :meth:`close`, + thereby releasing the lock. + + .. versionchanged:: next + Support for the :keyword:`with` statement was added. + :class:`!Mailbox` instances have the following methods: diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 65923e9c5de324..99426220154360 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -39,6 +39,13 @@ def __init__(self, path, factory=None, create=True): self._path = os.path.abspath(os.path.expanduser(path)) self._factory = factory + def __enter__(self): + self.lock() + return self + + def __exit__(self, type, value, traceback): + self.close() + def add(self, message): """Add message and return assigned key.""" raise NotImplementedError('Method must be implemented by subclass') diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 288b2c4496faa1..7421076ddd4c3a 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -542,6 +542,11 @@ def _test_flush_or_close(self, method, should_call_close): self.assertIn(self._box.get_string(key), contents) oldbox.close() + def test_use_context_manager(self): + # Mailboxes are usable as a context manager + with self._box as box: + self.assertIs(self._box, box) + def test_dump_message(self): # Write message representations to disk for input in (email.message_from_string(_sample_message), @@ -1122,6 +1127,16 @@ def test_ownership_after_flush(self): self.assertEqual(st.st_gid, other_gid) self.assertEqual(st.st_mode, mode) + def test_context_manager_locks_and_closes(self): + # Context manager locks/unlocks and closes. + # (This test uses an implementation detail to get the state.) + self.assertFalse(self._box._locked) + with self._box as context_object: + self.assertIs(self._box, context_object) + self.assertTrue(self._box._locked) + self.assertFalse(self._box._file.closed) + self.assertFalse(self._box._locked) + self.assertTrue(self._box._file.closed) class _TestMboxMMDF(_TestSingleFile): diff --git a/Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst b/Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst new file mode 100644 index 00000000000000..b22289835620df --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst @@ -0,0 +1,2 @@ +:class:`mailbox.Mailbox` instances can now be used as a context manager. +The Mailbox is locked on context entry and unlocked and closed at context exit. From 1797508ead02935ca7da859221247f4a7168cebd Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Mon, 16 Feb 2026 21:48:08 +0000 Subject: [PATCH 120/498] gh-144878: Gate PEP 810 builtins in xpickle compat tests (#144889) --- Lib/test/pickletester.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 7b1b117d6d3e32..5f627f047ea319 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -3202,6 +3202,7 @@ def test_builtin_exceptions(self): 'ExceptionGroup': (3, 11), '_IncompleteInputError': (3, 13), 'PythonFinalizationError': (3, 13), + 'ImportCycleError': (3, 15), } for t in builtins.__dict__.values(): if isinstance(t, type) and issubclass(t, BaseException): @@ -3228,6 +3229,7 @@ def test_builtin_functions(self): 'breakpoint': (3, 7), 'aiter': (3, 10), 'anext': (3, 10), + '__lazy_import__': (3, 15), } for t in builtins.__dict__.values(): if isinstance(t, types.BuiltinFunctionType): From 185a6e942af3e44b3bdb2bdcf2d55c0a6208f89b Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Mon, 16 Feb 2026 15:20:37 -0700 Subject: [PATCH 121/498] gh-140715: Add `%D` format code support to `strptime()` (GH-144819) * %D support for strptime, including test and Doc update * additional %D test * change documentation example date for %D so it is more legible to non-US readers * change testing date for %D so it is more legible to non-US readers * mv News blurb to Library, consistent with previous %F change * change invalid format code from %D to C-standard unused %! * Fix erroneous and misleading example Doc to %y from %Y, use correct C99+ definition for C99 %D; update additional tests --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Doc/library/datetime.rst | 6 +++--- Lib/_strptime.py | 1 + Lib/test/datetimetester.py | 7 +++++++ Lib/test/test_strptime.py | 9 ++++++++- Lib/test/test_time.py | 4 ++-- .../2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst | 1 + 6 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index d861139cec6db5..39a7a1530a95cc 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2534,8 +2534,8 @@ requires, and these work on all supported platforms. | ``%d`` | Day of the month as a | 01, 02, ..., 31 | \(9) | | | zero-padded decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/10/2025 | \(9), | -| | | | \(0) | +| ``%D`` | Equivalent to ``%m/%d/%y``. | 11/28/25 | \(9) | +| | | | | +-----------+--------------------------------+------------------------+-------+ | ``%e`` | The day of the month as a | ␣1, ␣2, ..., 31 | | | | space-padded decimal number. | | | @@ -2676,7 +2676,7 @@ differences between platforms in handling of unsupported format specifiers. ``%:z`` was added for :meth:`~.datetime.strftime`. .. versionadded:: 3.15 - ``%:z`` and ``%F`` were added for :meth:`~.datetime.strptime`. + ``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`. Technical Detail ^^^^^^^^^^^^^^^^ diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 8b62ea734b7d11..fe34808d88769a 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -418,6 +418,7 @@ def __init__(self, locale_time=None): mapping['W'] = mapping['U'].replace('U', 'W') base.__init__(mapping) + base.__setitem__('D', self.pattern('%m/%d/%y')) base.__setitem__('F', self.pattern('%Y-%m-%d')) base.__setitem__('T', self.pattern('%H:%M:%S')) base.__setitem__('R', self.pattern('%H:%M')) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 3784909ee77839..97eec618932aa5 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2200,6 +2200,13 @@ def test_strptime_F_format(self): self.theclass.strptime(test_date, "%Y-%m-%d") ) + def test_strptime_D_format(self): + test_date = "11/28/25" + self.assertEqual( + self.theclass.strptime(test_date, "%D"), + self.theclass.strptime(test_date, "%m/%d/%y") + ) + ############################################################################# # datetime tests diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 0784ea6a4cf5d4..fd8525feb88d53 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -286,7 +286,7 @@ def test_ValueError(self): def test_strptime_exception_context(self): # check that this doesn't chain exceptions needlessly (see #17572) with self.assertRaises(ValueError) as e: - _strptime._strptime_time('', '%D') + _strptime._strptime_time('', '%!') self.assertTrue(e.exception.__suppress_context__) # additional check for stray % branch with self.assertRaises(ValueError) as e: @@ -663,6 +663,13 @@ def test_strptime_T_format(self): time.strptime(test_time, "%H:%M:%S") ) + def test_strptime_D_format(self): + test_date = "11/28/25" + self.assertEqual( + time.strptime(test_date, "%D"), + time.strptime(test_date, "%m/%d/%y") + ) + class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index da0cf494bfa8ad..da5fd16b8b6291 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -358,7 +358,7 @@ def test_strptime(self): # Should be able to go round-trip from strftime to strptime without # raising an exception. tt = time.gmtime(self.t) - for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'F', 'H', 'I', + for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'D', 'F', 'H', 'I', 'j', 'm', 'M', 'p', 'S', 'T', 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): format = '%' + directive @@ -379,7 +379,7 @@ def test_strptime_bytes(self): def test_strptime_exception_context(self): # check that this doesn't chain exceptions needlessly (see #17572) with self.assertRaises(ValueError) as e: - time.strptime('', '%D') + time.strptime('', '%!') self.assertTrue(e.exception.__suppress_context__) # additional check for stray % branch with self.assertRaises(ValueError) as e: diff --git a/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst b/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst new file mode 100644 index 00000000000000..f7782f2fa4f23b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst @@ -0,0 +1 @@ +Add ``'%D'`` support to :meth:`~datetime.datetime.strptime`. From 18c04f2e2a7e47329e9eefc5f269afe2d68729b0 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Mon, 16 Feb 2026 22:57:49 +0000 Subject: [PATCH 122/498] gh-142349: Fix ast.unparse for lazy import statements (#144893) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unparser was not handling the `is_lazy` attribute on Import and ImportFrom AST nodes, causing lazy imports to be unparsed as regular imports. This broke the round-trip (parse → unparse → reparse) for any file containing `lazy import` statements. --- Lib/_ast_unparse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/_ast_unparse.py b/Lib/_ast_unparse.py index 1c8741b5a55483..0c3b1d3a9108a3 100644 --- a/Lib/_ast_unparse.py +++ b/Lib/_ast_unparse.py @@ -239,11 +239,11 @@ def visit_NamedExpr(self, node): self.traverse(node.value) def visit_Import(self, node): - self.fill("import ") + self.fill("lazy import " if node.is_lazy else "import ") self.interleave(lambda: self.write(", "), self.traverse, node.names) def visit_ImportFrom(self, node): - self.fill("from ") + self.fill("lazy from " if node.is_lazy else "from ") self.write("." * (node.level or 0)) if node.module: self.write(node.module) From 2f7634c0291c92cf1e040fc81c4210f0883e6036 Mon Sep 17 00:00:00 2001 From: Mauricio Villegas <5780272+mauvilsa@users.noreply.github.com> Date: Tue, 17 Feb 2026 03:28:21 +0100 Subject: [PATCH 123/498] gh-144782: Make sure that ArgumentParser instances are pickleable (#144783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartosz Sławecki Co-authored-by: AN Long Co-authored-by: Savannah Ostrowski --- Lib/argparse.py | 10 +++++---- Lib/test/test_argparse.py | 21 +++++++++++++++++++ ...-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 0494b545f2f1d3..296a210ad832da 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -148,6 +148,10 @@ def _copy_items(items): return copy.copy(items) +def _identity(value): + return value + + # =============== # Formatting Help # =============== @@ -199,7 +203,7 @@ def _set_color(self, color, *, file=None): self._decolor = decolor else: self._theme = get_theme(force_no_color=True).argparse - self._decolor = lambda text: text + self._decolor = _identity # =============================== # Section and indentation methods @@ -1981,9 +1985,7 @@ def __init__(self, self._subparsers = None # register types - def identity(string): - return string - self.register('type', None, identity) + self.register('type', None, _identity) # add help argument if necessary # (using explicit default to override global argument_default) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 78f02f70b9f0fc..4526efe4b80ef4 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -80,6 +80,27 @@ def test_skip_invalid_stdout(self): self.assertRegex(mocked_stderr.getvalue(), r'usage:') +class TestArgumentParserPickleable(unittest.TestCase): + + @force_not_colorized + def test_pickle_roundtrip(self): + import pickle + parser = argparse.ArgumentParser(exit_on_error=False) + parser.add_argument('--foo', type=int, default=42) + parser.add_argument('bar', nargs='?', default='baz') + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + # Try to pickle and unpickle the parser + parser2 = pickle.loads(pickle.dumps(parser, protocol=proto)) + # Check that the round-tripped parser still works + ns = parser2.parse_args(['--foo', '123', 'quux']) + self.assertEqual(ns.foo, 123) + self.assertEqual(ns.bar, 'quux') + ns2 = parser2.parse_args([]) + self.assertEqual(ns2.foo, 42) + self.assertEqual(ns2.bar, 'baz') + + class TestCase(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst b/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst new file mode 100644 index 00000000000000..871005fd7d986c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst @@ -0,0 +1 @@ +Fix :class:`argparse.ArgumentParser` to be :mod:`pickleable `. From 63531a3867cf4f8b5a7088fb7667d33534c43ff7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Feb 2026 10:49:30 +0100 Subject: [PATCH 124/498] gh-143637: Fix test_socket.test_sendmsg_reentrant_ancillary_mutation() on Solaris (#144890) Use socket.SCM_RIGHTS operation. --- Lib/test/test_socket.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 3806ad988db214..9ad5b29ea58ecb 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2228,11 +2228,11 @@ def test_sendmsg_reentrant_ancillary_mutation(self): class Mut: def __index__(self): seq.clear() - return 0 + return socket.SCM_RIGHTS seq = [ - (socket.SOL_SOCKET, Mut(), b'x'), - (socket.SOL_SOCKET, 0, b'x'), + (socket.SOL_SOCKET, Mut(), b'xxxx'), + (socket.SOL_SOCKET, socket.SCM_RIGHTS, b'xxxx'), ] left, right = socket.socketpair() From 696cdfc0a25aa4f1ba200464bd710ff54a261a78 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Feb 2026 10:54:41 +0100 Subject: [PATCH 125/498] gh-141510, PEP 814: Add built-in frozendict type (#144757) Add TYPE_FROZENDICT to the marshal module. Add C API functions: * PyAnyDict_Check() * PyAnyDict_CheckExact() * PyFrozenDict_Check() * PyFrozenDict_CheckExact() * PyFrozenDict_New() Add PyFrozenDict_Type C type. Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Adam Johnson Co-authored-by: Benedikt Johannes --- Doc/c-api/dict.rst | 57 +++- Doc/library/stdtypes.rst | 52 ++- Doc/whatsnew/3.15.rst | 27 ++ Include/cpython/dictobject.h | 15 +- Include/internal/pycore_dict.h | 9 + Include/internal/pycore_typeobject.h | 1 + Lib/_collections_abc.py | 1 + Lib/test/mapping_tests.py | 131 ++++---- Lib/test/test_dict.py | 52 +++ Lib/test/test_doctest/test_doctest.py | 2 +- Lib/test/test_inspect/test_inspect.py | 3 +- ...-02-12-19-03-31.gh-issue-141510.U_1tjz.rst | 9 + ...-02-12-19-01-13.gh-issue-141510.KlKjZg.rst | 1 + Objects/dictobject.c | 316 +++++++++++++++--- Objects/object.c | 5 +- Python/bltinmodule.c | 1 + Python/marshal.c | 22 +- Tools/c-analyzer/cpython/ignored.tsv | 1 + 18 files changed, 579 insertions(+), 126 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 9c4428ced41b5a..736f282e7bd47a 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -2,7 +2,7 @@ .. _dictobjects: -Dictionary Objects +Dictionary objects ------------------ .. index:: pair: object; dictionary @@ -444,7 +444,7 @@ Dictionary Objects .. versionadded:: 3.12 -Dictionary View Objects +Dictionary view objects ^^^^^^^^^^^^^^^^^^^^^^^ .. c:function:: int PyDictViewSet_Check(PyObject *op) @@ -490,7 +490,58 @@ Dictionary View Objects always succeeds. -Ordered Dictionaries +Frozen dictionary objects +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: next + + +.. c:var:: PyTypeObject PyFrozenDict_Type + + This instance of :c:type:`PyTypeObject` represents the Python frozen + dictionary type. + This is the same object as :class:`frozendict` in the Python layer. + + +.. c:function:: int PyAnyDict_Check(PyObject *p) + + Return true if *p* is a :class:`dict` object, a :class:`frozendict` object, + or an instance of a subtype of the :class:`!dict` or :class:`!frozendict` + type. + This function always succeeds. + + +.. c:function:: int PyAnyDict_CheckExact(PyObject *p) + + Return true if *p* is a :class:`dict` object or a :class:`frozendict` object, + but not an instance of a subtype of the :class:`!dict` or + :class:`!frozendict` type. + This function always succeeds. + + +.. c:function:: int PyFrozenDict_Check(PyObject *p) + + Return true if *p* is a :class:`frozendict` object or an instance of a + subtype of the :class:`!frozendict` type. + This function always succeeds. + + +.. c:function:: int PyFrozenDict_CheckExact(PyObject *p) + + Return true if *p* is a :class:`frozendict` object, but not an instance of a + subtype of the :class:`!frozendict` type. + This function always succeeds. + + +.. c:function:: PyObject* PyFrozenDict_New(PyObject *iterable) + + Return a new :class:`frozendict` from an iterable, or ``NULL`` on failure + with an exception set. + + Create an empty dictionary if *iterable* is ``NULL``. + + +Ordered dictionaries ^^^^^^^^^^^^^^^^^^^^ Python's C API provides interface for :class:`collections.OrderedDict` from C. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index d4540e0b819871..6f798f02e17899 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -5305,8 +5305,8 @@ frozenset, a temporary one is created from *elem*. .. _typesmapping: -Mapping Types --- :class:`dict` -=============================== +Mapping types --- :class:`!dict`, :class:`!frozendict` +====================================================== .. index:: pair: object; mapping @@ -5317,8 +5317,9 @@ Mapping Types --- :class:`dict` pair: built-in function; len A :term:`mapping` object maps :term:`hashable` values to arbitrary objects. -Mappings are mutable objects. There is currently only one standard mapping -type, the :dfn:`dictionary`. (For other containers see the built-in +There are currently two standard mapping types, the :dfn:`dictionary` and +:class:`frozendict`. +(For other containers see the built-in :class:`list`, :class:`set`, and :class:`tuple` classes, and the :mod:`collections` module.) @@ -5588,10 +5589,9 @@ can be used interchangeably to index the same dictionary entry. Dictionaries are now reversible. -.. seealso:: - :class:`types.MappingProxyType` can be used to create a read-only view - of a :class:`dict`. - + .. seealso:: + :class:`types.MappingProxyType` can be used to create a read-only view + of a :class:`dict`. .. _thread-safety-dict: @@ -5839,6 +5839,41 @@ An example of dictionary view usage:: 500 +Frozen dictionaries +------------------- + +.. class:: frozendict(**kwargs) + frozendict(mapping, /, **kwargs) + frozendict(iterable, /, **kwargs) + + Return a new frozen dictionary initialized from an optional positional + argument and a possibly empty set of keyword arguments. + + A :class:`!frozendict` has a similar API to the :class:`dict` API, with the + following differences: + + * :class:`!dict` has more methods than :class:`!frozendict`: + + * :meth:`!__delitem__` + * :meth:`!__setitem__` + * :meth:`~dict.clear` + * :meth:`~dict.pop` + * :meth:`~dict.popitem` + * :meth:`~dict.setdefault` + * :meth:`~dict.update` + + * A :class:`!frozendict` can be hashed with ``hash(frozendict)`` if all keys and + values can be hashed. + + * ``frozendict |= other`` does not modify the :class:`!frozendict` in-place but + creates a new frozen dictionary. + + :class:`!frozendict` is not a :class:`!dict` subclass but inherits directly + from ``object``. + + .. versionadded:: next + + .. _typecontextmanager: Context Manager Types @@ -6062,6 +6097,7 @@ list is non-exhaustive. * :class:`list` * :class:`dict` * :class:`set` +* :class:`frozendict` * :class:`frozenset` * :class:`type` * :class:`asyncio.Future` diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 5dca1545b144ef..e5714765208ff6 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -67,6 +67,8 @@ Summary -- Release highlights * :pep:`810`: :ref:`Explicit lazy imports for faster startup times ` +* :pep:`814`: :ref:`Add frozendict built-in type + ` * :pep:`799`: :ref:`A dedicated profiling package for organizing Python profiling tools ` * :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler @@ -180,6 +182,21 @@ raise :exc:`SyntaxError`). (Contributed by Pablo Galindo Salgado and Dino Viehland in :gh:`142349`.) + +.. _whatsnew315-frozendict: + +:pep:`814`: Add frozendict built-in type +---------------------------------------- + +A new public immutable type :class:`frozendict` is added to the :mod:`builtins` +module. It is not a ``dict`` subclass but inherits directly from ``object``. + +A ``frozendict`` can be hashed with ``hash(frozendict)`` if all keys and values +can be hashed. + +.. seealso:: :pep:`814` for the full specification and rationale. + + .. _whatsnew315-profiling-package: :pep:`799`: A dedicated profiling package @@ -1525,6 +1542,16 @@ C API changes New features ------------ +* Add the following functions for the new :class:`frozendict` type: + + * :c:func:`PyAnyDict_Check` + * :c:func:`PyAnyDict_CheckExact` + * :c:func:`PyFrozenDict_Check` + * :c:func:`PyFrozenDict_CheckExact` + * :c:func:`PyFrozenDict_New` + + (Contributed by Victor Stinner in :gh:`141510`.) + * Add :c:func:`PySys_GetAttr`, :c:func:`PySys_GetAttrString`, :c:func:`PySys_GetOptionalAttr`, and :c:func:`PySys_GetOptionalAttrString` functions as replacements for :c:func:`PySys_GetObject`. diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index 5f2f7b6d4f56bd..5e7811416aba63 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -32,6 +32,16 @@ typedef struct { PyDictValues *ma_values; } PyDictObject; +// frozendict +PyAPI_DATA(PyTypeObject) PyFrozenDict_Type; +#define PyFrozenDict_Check(op) PyObject_TypeCheck((op), &PyFrozenDict_Type) +#define PyFrozenDict_CheckExact(op) Py_IS_TYPE((op), &PyFrozenDict_Type) + +#define PyAnyDict_CheckExact(ob) \ + (PyDict_CheckExact(ob) || PyFrozenDict_CheckExact(ob)) +#define PyAnyDict_Check(ob) \ + (PyDict_Check(ob) || PyFrozenDict_Check(ob)) + PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, Py_hash_t hash); // PyDict_GetItemStringRef() can be used instead @@ -42,7 +52,7 @@ PyAPI_FUNC(PyObject *) PyDict_SetDefault( /* Get the number of items of a dictionary. */ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { PyDictObject *mp; - assert(PyDict_Check(op)); + assert(PyAnyDict_Check(op)); mp = _Py_CAST(PyDictObject*, op); #ifdef Py_GIL_DISABLED return _Py_atomic_load_ssize_relaxed(&mp->ma_used); @@ -93,3 +103,6 @@ PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id); // Mark given dictionary as "watched" (callback will be called if it is modified) PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict); PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict); + +// Create a frozendict. Create an empty dictionary if iterable is NULL. +PyAPI_FUNC(PyObject*) PyFrozenDict_New(PyObject *iterable); diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 379bf6a81784b0..59e88be6aeec12 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -408,6 +408,15 @@ _Py_DECREF_BUILTINS(PyObject *op) } #endif +/* frozendict */ +typedef struct { + PyDictObject ob_base; + Py_hash_t ma_hash; +} PyFrozenDictObject; + +#define _PyFrozenDictObject_CAST(op) \ + (assert(PyFrozenDict_Check(op)), _Py_CAST(PyFrozenDictObject*, (op))) + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index dfd355d5012066..8af317d54c0bda 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -26,6 +26,7 @@ extern "C" { #define _Py_TYPE_VERSION_BYTEARRAY 9 #define _Py_TYPE_VERSION_BYTES 10 #define _Py_TYPE_VERSION_COMPLEX 11 +#define _Py_TYPE_VERSION_FROZENDICT 12 #define _Py_TYPE_VERSION_NEXT 16 diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index 60b471317ce97c..23cc6d8faae2da 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -823,6 +823,7 @@ def __eq__(self, other): __reversed__ = None +Mapping.register(frozendict) Mapping.register(mappingproxy) Mapping.register(framelocalsproxy) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 20306e1526d7b8..9624072e69adfc 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -4,7 +4,7 @@ from test import support -class BasicTestMappingProtocol(unittest.TestCase): +class BasicTestImmutableMappingProtocol(unittest.TestCase): # This base class can be used to check that an object conforms to the # mapping protocol @@ -20,12 +20,9 @@ def _empty_mapping(self): """Return an empty mapping object""" return self.type2test() def _full_mapping(self, data): - """Return a mapping object with the value contained in data + """Return a mapping object with the values contained in data dictionary""" - x = self._empty_mapping() - for key, value in data.items(): - x[key] = value - return x + return self.type2test(data) def __init__(self, *args, **kw): unittest.TestCase.__init__(self, *args, **kw) @@ -88,6 +85,72 @@ def check_iterandlist(iter, lst, ref): self.assertEqual(d.get(knownkey, knownvalue), knownvalue) self.assertNotIn(knownkey, d) + def test_constructor(self): + self.assertEqual(self._empty_mapping(), self._empty_mapping()) + + def test_bool(self): + self.assertTrue(not self._empty_mapping()) + self.assertTrue(self.reference) + self.assertFalse(bool(self._empty_mapping())) + self.assertTrue(bool(self.reference)) + + def test_keys(self): + d = self._empty_mapping() + self.assertEqual(list(d.keys()), []) + d = self.reference + self.assertIn(list(self.inmapping.keys())[0], d.keys()) + self.assertNotIn(list(self.other.keys())[0], d.keys()) + self.assertRaises(TypeError, d.keys, None) + + def test_values(self): + d = self._empty_mapping() + self.assertEqual(list(d.values()), []) + + self.assertRaises(TypeError, d.values, None) + + def test_items(self): + d = self._empty_mapping() + self.assertEqual(list(d.items()), []) + + self.assertRaises(TypeError, d.items, None) + + def test_len(self): + d = self._empty_mapping() + self.assertEqual(len(d), 0) + + def test_getitem(self): + d = self.reference + self.assertEqual(d[list(self.inmapping.keys())[0]], + list(self.inmapping.values())[0]) + + self.assertRaises(TypeError, d.__getitem__) + + # no test_fromkeys or test_copy as both os.environ and selves don't support it + + def test_get(self): + d = self._empty_mapping() + self.assertIsNone(d.get(list(self.other.keys())[0])) + self.assertEqual(d.get(list(self.other.keys())[0], 3), 3) + d = self.reference + self.assertIsNone(d.get(list(self.other.keys())[0])) + self.assertEqual(d.get(list(self.other.keys())[0], 3), 3) + self.assertEqual(d.get(list(self.inmapping.keys())[0]), + list(self.inmapping.values())[0]) + self.assertEqual(d.get(list(self.inmapping.keys())[0], 3), + list(self.inmapping.values())[0]) + self.assertRaises(TypeError, d.get) + self.assertRaises(TypeError, d.get, None, None, None) + + +class BasicTestMappingProtocol(BasicTestImmutableMappingProtocol): + def _full_mapping(self, data): + """Return a mapping object with the values contained in data + dictionary""" + x = self._empty_mapping() + for key, value in data.items(): + x[key] = value + return x + def test_write(self): # Test for write operations on mapping p = self._empty_mapping() @@ -130,46 +193,6 @@ def test_write(self): p=self._empty_mapping() self.assertRaises(KeyError, p.popitem) - def test_constructor(self): - self.assertEqual(self._empty_mapping(), self._empty_mapping()) - - def test_bool(self): - self.assertTrue(not self._empty_mapping()) - self.assertTrue(self.reference) - self.assertTrue(bool(self._empty_mapping()) is False) - self.assertTrue(bool(self.reference) is True) - - def test_keys(self): - d = self._empty_mapping() - self.assertEqual(list(d.keys()), []) - d = self.reference - self.assertIn(list(self.inmapping.keys())[0], d.keys()) - self.assertNotIn(list(self.other.keys())[0], d.keys()) - self.assertRaises(TypeError, d.keys, None) - - def test_values(self): - d = self._empty_mapping() - self.assertEqual(list(d.values()), []) - - self.assertRaises(TypeError, d.values, None) - - def test_items(self): - d = self._empty_mapping() - self.assertEqual(list(d.items()), []) - - self.assertRaises(TypeError, d.items, None) - - def test_len(self): - d = self._empty_mapping() - self.assertEqual(len(d), 0) - - def test_getitem(self): - d = self.reference - self.assertEqual(d[list(self.inmapping.keys())[0]], - list(self.inmapping.values())[0]) - - self.assertRaises(TypeError, d.__getitem__) - def test_update(self): # mapping argument d = self._empty_mapping() @@ -265,22 +288,6 @@ def __next__(self): self.assertRaises(ValueError, d.update, [(1, 2, 3)]) - # no test_fromkeys or test_copy as both os.environ and selves don't support it - - def test_get(self): - d = self._empty_mapping() - self.assertTrue(d.get(list(self.other.keys())[0]) is None) - self.assertEqual(d.get(list(self.other.keys())[0], 3), 3) - d = self.reference - self.assertTrue(d.get(list(self.other.keys())[0]) is None) - self.assertEqual(d.get(list(self.other.keys())[0], 3), 3) - self.assertEqual(d.get(list(self.inmapping.keys())[0]), - list(self.inmapping.values())[0]) - self.assertEqual(d.get(list(self.inmapping.keys())[0], 3), - list(self.inmapping.values())[0]) - self.assertRaises(TypeError, d.get) - self.assertRaises(TypeError, d.get, None, None, None) - def test_setdefault(self): d = self._empty_mapping() self.assertRaises(TypeError, d.setdefault) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 6583c0f2aefb2b..1db3559a012fd3 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1723,6 +1723,58 @@ class Dict(dict): class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): type2test = Dict +class FrozenDictMappingTests(mapping_tests.BasicTestImmutableMappingProtocol): + type2test = frozendict + + +class FrozenDict(frozendict): + pass + + +class FrozenDictTests(unittest.TestCase): + def test_copy(self): + d = frozendict(x=1, y=2) + d2 = d.copy() + self.assertIs(d2, d) + + d = FrozenDict(x=1, y=2) + d2 = d.copy() + self.assertIsNot(d2, d) + self.assertEqual(d2, frozendict(x=1, y=2)) + self.assertEqual(type(d2), frozendict) + + def test_merge(self): + # test "a | b" operator + self.assertEqual(frozendict(x=1) | frozendict(y=2), + frozendict({'x': 1, 'y': 2})) + self.assertEqual(frozendict(x=1) | dict(y=2), + frozendict({'x': 1, 'y': 2})) + self.assertEqual(frozendict(x=1, y=2) | frozendict(y=5), + frozendict({'x': 1, 'y': 5})) + fd = frozendict(x=1, y=2) + self.assertIs(fd | frozendict(), fd) + self.assertIs(fd | {}, fd) + self.assertIs(frozendict() | fd, fd) + + def test_update(self): + # test "a |= b" operator + d = frozendict(x=1) + copy = d + self.assertIs(copy, d) + d |= frozendict(y=2) + self.assertIsNot(copy, d) + self.assertEqual(d, frozendict({'x': 1, 'y': 2})) + self.assertEqual(copy, frozendict({'x': 1})) + + def test_repr(self): + d = frozendict(x=1, y=2) + self.assertEqual(repr(d), "frozendict({'x': 1, 'y': 2})") + + class MyFrozenDict(frozendict): + pass + d = MyFrozenDict(x=1, y=2) + self.assertEqual(repr(d), "MyFrozenDict({'x': 1, 'y': 2})") + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_doctest/test_doctest.py b/Lib/test/test_doctest/test_doctest.py index 241d09db1fa70e..b125693ab0891c 100644 --- a/Lib/test/test_doctest/test_doctest.py +++ b/Lib/test/test_doctest/test_doctest.py @@ -742,7 +742,7 @@ def non_Python_modules(): r""" >>> import builtins >>> tests = doctest.DocTestFinder().find(builtins) - >>> 750 < len(tests) < 800 # approximate number of objects with docstrings + >>> 750 < len(tests) < 850 # approximate number of objects with docstrings True >>> real_tests = [t for t in tests if len(t.examples) > 0] >>> len(real_tests) # objects that actually have doctests diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 32bb47de04b113..00cc5aab32c273 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -6127,7 +6127,8 @@ def _test_builtin_methods_have_signatures(self, cls, no_signature, unsupported_s self.assertRaises(ValueError, inspect.signature, getattr(cls, name)) def test_builtins_have_signatures(self): - no_signature = {'type', 'super', 'bytearray', 'bytes', 'dict', 'int', 'str'} + no_signature = {'type', 'super', 'bytearray', 'bytes', + 'dict', 'frozendict', 'int', 'str'} # These need PEP 457 groups needs_groups = {"range", "slice", "dir", "getattr", "next", "iter", "vars"} diff --git a/Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst b/Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst new file mode 100644 index 00000000000000..57a25fe045f04c --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst @@ -0,0 +1,9 @@ +Add the following functions for the new :class:`frozendict` type: + +* :c:func:`PyAnyDict_Check` +* :c:func:`PyAnyDict_CheckExact` +* :c:func:`PyFrozenDict_Check` +* :c:func:`PyFrozenDict_CheckExact` +* :c:func:`PyFrozenDict_New` + +Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst new file mode 100644 index 00000000000000..4596e273fc6118 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst @@ -0,0 +1 @@ +Add built-in :class:`frozendict` type. Patch by Victor Stinner. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index ae7bf61767dc3b..46b0148cf59ab5 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -135,6 +135,10 @@ As a consequence of this, split keys have a maximum size of 16. #include "stringlib/eq.h" // unicode_eq() #include +// Forward declarations +static PyObject* frozendict_new(PyTypeObject *type, PyObject *args, + PyObject *kwds); + /*[clinic input] class dict "PyDictObject *" "&PyDict_Type" @@ -278,6 +282,11 @@ load_keys_nentries(PyDictObject *mp) #endif +#define _PyAnyDict_CAST(op) \ + (assert(PyAnyDict_Check(op)), _Py_CAST(PyDictObject*, op)) + +#define GET_USED(ep) FT_ATOMIC_LOAD_SSIZE_RELAXED((ep)->ma_used) + #define STORE_KEY(ep, key) FT_ATOMIC_STORE_PTR_RELEASE((ep)->me_key, key) #define STORE_VALUE(ep, value) FT_ATOMIC_STORE_PTR_RELEASE((ep)->me_value, value) #define STORE_SPLIT_VALUE(mp, idx, value) FT_ATOMIC_STORE_PTR_RELEASE(mp->ma_values->values[idx], value) @@ -654,7 +663,7 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) assert(op != NULL); - CHECK(PyDict_Check(op)); + CHECK(PyAnyDict_Check(op)); PyDictObject *mp = (PyDictObject *)op; PyDictKeysObject *keys = mp->ma_keys; @@ -909,7 +918,7 @@ new_dict_with_shared_keys(PyDictKeysObject *keys) static PyDictKeysObject * clone_combined_dict_keys(PyDictObject *orig) { - assert(PyDict_Check(orig)); + assert(PyAnyDict_Check(orig)); assert(Py_TYPE(orig)->tp_iter == dict_iter); assert(orig->ma_values == NULL); assert(orig->ma_keys != Py_EMPTY_KEYS); @@ -2293,7 +2302,7 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, static PyObject * dict_getitem(PyObject *op, PyObject *key, const char *warnmsg) { - if (!PyDict_Check(op)) { + if (!PyAnyDict_Check(op)) { return NULL; } PyDictObject *mp = (PyDictObject *)op; @@ -2392,7 +2401,7 @@ _PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) PyDictObject *mp = (PyDictObject *)op; PyObject *value; - if (!PyDict_Check(op)) { + if (!PyAnyDict_Check(op)) { PyErr_BadInternalCall(); return NULL; } @@ -2463,7 +2472,7 @@ _PyDict_GetItemRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, Py int PyDict_GetItemRef(PyObject *op, PyObject *key, PyObject **result) { - if (!PyDict_Check(op)) { + if (!PyAnyDict_Check(op)) { PyErr_BadInternalCall(); *result = NULL; return -1; @@ -2519,7 +2528,7 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) PyDictObject*mp = (PyDictObject *)op; PyObject *value; - if (!PyDict_Check(op)) { + if (!PyAnyDict_Check(op)) { PyErr_BadInternalCall(); return NULL; } @@ -2668,7 +2677,7 @@ setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) assert(key); assert(value); - assert(PyDict_Check(mp)); + assert(PyAnyDict_Check(mp)); Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { dict_unhashable_type(key); @@ -2713,6 +2722,16 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) Py_NewRef(key), Py_NewRef(value)); } +static int +_PyAnyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) +{ + assert(PyAnyDict_Check(op)); + assert(key); + assert(value); + return _PyDict_SetItem_Take2((PyDictObject *)op, + Py_NewRef(key), Py_NewRef(value)); +} + static int setitem_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) { @@ -2996,7 +3015,7 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject *key, *value; Py_hash_t hash; - if (!PyDict_Check(op)) + if (!PyAnyDict_Check(op)) return 0; mp = (PyDictObject *)op; @@ -3265,8 +3284,8 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) return NULL; - if (PyDict_CheckExact(d)) { - if (PyDict_CheckExact(iterable)) { + if (PyAnyDict_CheckExact(d)) { + if (PyAnyDict_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; Py_BEGIN_CRITICAL_SECTION2(d, iterable); @@ -3290,7 +3309,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) return NULL; } - if (PyDict_CheckExact(d)) { + if (PyAnyDict_CheckExact(d)) { Py_BEGIN_CRITICAL_SECTION(d); while ((key = PyIter_Next(it)) != NULL) { status = setitem_lock_held((PyDictObject *)d, key, value); @@ -3460,7 +3479,7 @@ dict_repr(PyObject *self) static Py_ssize_t dict_length(PyObject *self) { - return FT_ATOMIC_LOAD_SSIZE_RELAXED(((PyDictObject *)self)->ma_used); + return GET_USED(_PyAnyDict_CAST(self)); } static PyObject * @@ -3480,7 +3499,7 @@ dict_subscript(PyObject *self, PyObject *key) if (ix == DKIX_ERROR) return NULL; if (ix == DKIX_EMPTY || value == NULL) { - if (!PyDict_CheckExact(mp)) { + if (!PyAnyDict_CheckExact(mp)) { /* Look up __missing__ method if we're a subclass. */ PyObject *missing, *res; missing = _PyObject_LookupSpecial( @@ -3519,7 +3538,7 @@ keys_lock_held(PyObject *dict) { ASSERT_DICT_LOCKED(dict); - if (dict == NULL || !PyDict_Check(dict)) { + if (dict == NULL || !PyAnyDict_Check(dict)) { PyErr_BadInternalCall(); return NULL; } @@ -3568,7 +3587,7 @@ values_lock_held(PyObject *dict) { ASSERT_DICT_LOCKED(dict); - if (dict == NULL || !PyDict_Check(dict)) { + if (dict == NULL || !PyAnyDict_Check(dict)) { PyErr_BadInternalCall(); return NULL; } @@ -3616,7 +3635,7 @@ items_lock_held(PyObject *dict) { ASSERT_DICT_LOCKED(dict); - if (dict == NULL || !PyDict_Check(dict)) { + if (dict == NULL || !PyAnyDict_Check(dict)) { PyErr_BadInternalCall(); return NULL; } @@ -3696,7 +3715,7 @@ dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value) static int dict_update_arg(PyObject *self, PyObject *arg) { - if (PyDict_CheckExact(arg)) { + if (PyAnyDict_CheckExact(arg)) { return PyDict_Merge(self, arg, 1); } int has_keys = PyObject_HasAttrWithError(arg, &_Py_ID(keys)); @@ -3762,7 +3781,7 @@ merge_from_seq2_lock_held(PyObject *d, PyObject *seq2, int override) PyObject *fast; /* item as a 2-tuple or 2-list */ assert(d != NULL); - assert(PyDict_Check(d)); + assert(PyAnyDict_Check(d)); assert(seq2 != NULL); it = PyObject_GetIter(seq2); @@ -3958,13 +3977,13 @@ dict_merge(PyObject *a, PyObject *b, int override) * things quite efficiently. For the latter, we only require that * PyMapping_Keys() and PyObject_GetItem() be supported. */ - if (a == NULL || !PyDict_Check(a) || b == NULL) { + if (a == NULL || !PyAnyDict_Check(a) || b == NULL) { PyErr_BadInternalCall(); return -1; } mp = (PyDictObject*)a; int res = 0; - if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == dict_iter)) { + if (PyAnyDict_Check(b) && (Py_TYPE(b)->tp_iter == dict_iter)) { other = (PyDictObject*)b; int res; Py_BEGIN_CRITICAL_SECTION2(a, b); @@ -4075,6 +4094,9 @@ static PyObject * dict_copy_impl(PyDictObject *self) /*[clinic end generated code: output=ffb782cf970a5c39 input=73935f042b639de4]*/ { + if (PyFrozenDict_CheckExact(self)) { + return Py_NewRef(self); + } return PyDict_Copy((PyObject *)self); } @@ -4104,13 +4126,19 @@ copy_lock_held(PyObject *o) { PyObject *copy; PyDictObject *mp; + int frozendict = PyFrozenDict_Check(o); ASSERT_DICT_LOCKED(o); mp = (PyDictObject *)o; if (mp->ma_used == 0) { /* The dict is empty; just return a new dict. */ - return PyDict_New(); + if (frozendict) { + return PyFrozenDict_New(NULL); + } + else { + return PyDict_New(); + } } if (_PyDict_HasSplitTable(mp)) { @@ -4119,7 +4147,13 @@ copy_lock_held(PyObject *o) if (newvalues == NULL) { return PyErr_NoMemory(); } - split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); + if (frozendict) { + split_copy = (PyDictObject *)PyObject_GC_New(PyFrozenDictObject, + &PyFrozenDict_Type); + } + else { + split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); + } if (split_copy == NULL) { free_values(newvalues, false); return NULL; @@ -4132,13 +4166,18 @@ copy_lock_held(PyObject *o) split_copy->ma_used = mp->ma_used; split_copy->_ma_watcher_tag = 0; dictkeys_incref(mp->ma_keys); + if (frozendict) { + PyFrozenDictObject *frozen = (PyFrozenDictObject *)split_copy; + frozen->ma_hash = -1; + } _PyObject_GC_TRACK(split_copy); return (PyObject *)split_copy; } if (Py_TYPE(mp)->tp_iter == dict_iter && mp->ma_values == NULL && - (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3)) + (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3) && + !frozendict) { /* Use fast-copy if: @@ -4170,7 +4209,12 @@ copy_lock_held(PyObject *o) return (PyObject *)new; } - copy = PyDict_New(); + if (frozendict) { + copy = PyFrozenDict_New(NULL); + } + else { + copy = PyDict_New(); + } if (copy == NULL) return NULL; if (dict_merge(copy, o, 1) == 0) @@ -4182,7 +4226,7 @@ copy_lock_held(PyObject *o) PyObject * PyDict_Copy(PyObject *o) { - if (o == NULL || !PyDict_Check(o)) { + if (o == NULL || !PyAnyDict_Check(o)) { PyErr_BadInternalCall(); return NULL; } @@ -4199,11 +4243,11 @@ PyDict_Copy(PyObject *o) Py_ssize_t PyDict_Size(PyObject *mp) { - if (mp == NULL || !PyDict_Check(mp)) { + if (mp == NULL || !PyAnyDict_Check(mp)) { PyErr_BadInternalCall(); return -1; } - return FT_ATOMIC_LOAD_SSIZE_RELAXED(((PyDictObject *)mp)->ma_used); + return GET_USED((PyDictObject *)mp); } /* Return 1 if dicts equal, 0 if not, -1 if error. @@ -4289,7 +4333,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) int cmp; PyObject *res; - if (!PyDict_Check(v) || !PyDict_Check(w)) { + if (!PyAnyDict_Check(v) || !PyAnyDict_Check(w)) { res = Py_NotImplemented; } else if (op == Py_EQ || op == Py_NE) { @@ -4739,7 +4783,7 @@ dict___sizeof___impl(PyDictObject *self) static PyObject * dict_or(PyObject *self, PyObject *other) { - if (!PyDict_Check(self) || !PyDict_Check(other)) { + if (!PyAnyDict_Check(self) || !PyAnyDict_Check(other)) { Py_RETURN_NOTIMPLEMENTED; } PyObject *new = PyDict_Copy(self); @@ -4753,6 +4797,29 @@ dict_or(PyObject *self, PyObject *other) return new; } +static PyObject * +frozendict_or(PyObject *self, PyObject *other) +{ + if (PyFrozenDict_CheckExact(self)) { + // frozendict() | frozendict(...) => frozendict(...) + if (GET_USED((PyDictObject *)self) == 0 + && PyFrozenDict_CheckExact(other)) + { + return Py_NewRef(other); + } + + // frozendict(...) | frozendict() => frozendict(...) + if (PyAnyDict_CheckExact(other) + && GET_USED((PyDictObject *)other) == 0) + { + return Py_NewRef(self); + } + } + + return dict_or(self, other); +} + + static PyObject * dict_ior(PyObject *self, PyObject *other) { @@ -4905,7 +4972,15 @@ dict_vectorcall(PyObject *type, PyObject * const*args, return NULL; } - PyObject *self = dict_new(_PyType_CAST(type), NULL, NULL); + PyObject *self; + if (Py_Is((PyTypeObject*)type, &PyFrozenDict_Type) + || PyType_IsSubtype((PyTypeObject*)type, &PyFrozenDict_Type)) + { + self = frozendict_new(_PyType_CAST(type), NULL, NULL); + } + else { + self = dict_new(_PyType_CAST(type), NULL, NULL); + } if (self == NULL) { return NULL; } @@ -4918,7 +4993,8 @@ dict_vectorcall(PyObject *type, PyObject * const*args, } if (kwnames != NULL) { for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) { - if (PyDict_SetItem(self, PyTuple_GET_ITEM(kwnames, i), args[i]) < 0) { + PyObject *key = PyTuple_GET_ITEM(kwnames, i); // borrowed + if (_PyAnyDict_SetItem(self, key, args[i]) < 0) { Py_DECREF(self); return NULL; } @@ -4991,6 +5067,7 @@ PyTypeObject PyDict_Type = { .tp_version_tag = _Py_TYPE_VERSION_DICT, }; + /* For backward compatibility with old dictionary interface */ PyObject * @@ -5073,7 +5150,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype) return NULL; } di->di_dict = (PyDictObject*)Py_NewRef(dict); - used = FT_ATOMIC_LOAD_SSIZE_RELAXED(dict->ma_used); + used = GET_USED(dict); di->di_used = used; di->len = used; if (itertype == &PyDictRevIterKey_Type || @@ -5129,7 +5206,7 @@ dictiter_len(PyObject *self, PyObject *Py_UNUSED(ignored)) { dictiterobject *di = (dictiterobject *)self; Py_ssize_t len = 0; - if (di->di_dict != NULL && di->di_used == FT_ATOMIC_LOAD_SSIZE_RELAXED(di->di_dict->ma_used)) + if (di->di_dict != NULL && di->di_used == GET_USED(di->di_dict)) len = FT_ATOMIC_LOAD_SSIZE_RELAXED(di->len); return PyLong_FromSize_t(len); } @@ -5166,7 +5243,7 @@ dictiter_iternextkey_lock_held(PyDictObject *d, PyObject *self) Py_ssize_t i; PyDictKeysObject *k; - assert (PyDict_Check(d)); + assert (PyAnyDict_Check(d)); ASSERT_DICT_LOCKED(d); if (di->di_used != d->ma_used) { @@ -5290,7 +5367,7 @@ dictiter_iternextvalue_lock_held(PyDictObject *d, PyObject *self) PyObject *value; Py_ssize_t i; - assert (PyDict_Check(d)); + assert (PyAnyDict_Check(d)); ASSERT_DICT_LOCKED(d); if (di->di_used != d->ma_used) { @@ -5412,7 +5489,7 @@ dictiter_iternextitem_lock_held(PyDictObject *d, PyObject *self, PyObject *key, *value; Py_ssize_t i; - assert (PyDict_Check(d)); + assert (PyAnyDict_Check(d)); ASSERT_DICT_LOCKED(d); if (di->di_used != d->ma_used) { @@ -5518,7 +5595,7 @@ dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self, Py_ssize_t i; PyDictKeysObject *k; - assert (PyDict_Check(d)); + assert (PyAnyDict_Check(d)); if (di->di_used != _Py_atomic_load_ssize_relaxed(&d->ma_used)) { PyErr_SetString(PyExc_RuntimeError, @@ -5712,7 +5789,7 @@ dictreviter_iter_lock_held(PyDictObject *d, PyObject *self) { dictiterobject *di = (dictiterobject *)self; - assert (PyDict_Check(d)); + assert (PyAnyDict_Check(d)); ASSERT_DICT_LOCKED(d); if (di->di_used != d->ma_used) { @@ -5842,7 +5919,7 @@ static PyObject * dict___reversed___impl(PyDictObject *self) /*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/ { - assert (PyDict_Check(self)); + assert (PyAnyDict_Check(self)); return dictiter_new(self, &PyDictRevIterKey_Type); } @@ -5915,7 +5992,7 @@ dictview_len(PyObject *self) _PyDictViewObject *dv = (_PyDictViewObject *)self; Py_ssize_t len = 0; if (dv->dv_dict != NULL) - len = FT_ATOMIC_LOAD_SSIZE_RELAXED(dv->dv_dict->ma_used); + len = GET_USED(dv->dv_dict); return len; } @@ -5927,7 +6004,7 @@ _PyDictView_New(PyObject *dict, PyTypeObject *type) PyErr_BadInternalCall(); return NULL; } - if (!PyDict_Check(dict)) { + if (!PyAnyDict_Check(dict)) { /* XXX Get rid of this restriction later */ PyErr_Format(PyExc_TypeError, "%s() requires a dict argument, not '%s'", @@ -6117,7 +6194,7 @@ dictviews_to_set(PyObject *self) if (PyDictKeys_Check(self)) { // PySet_New() has fast path for the dict object. PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict; - if (PyDict_CheckExact(dict)) { + if (PyAnyDict_CheckExact(dict)) { left = dict; } } @@ -6847,6 +6924,11 @@ _PyObject_MaterializeManagedDict(PyObject *obj) int _PyDict_SetItem_LockHeld(PyDictObject *dict, PyObject *name, PyObject *value) { + if (!PyDict_Check(dict)) { + PyErr_BadInternalCall(); + return -1; + } + if (value == NULL) { Py_hash_t hash = _PyObject_HashFast(name); if (hash == -1) { @@ -7169,7 +7251,7 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) if (dict == NULL) { return 1; } - return FT_ATOMIC_LOAD_SSIZE_RELAXED(((PyDictObject *)dict)->ma_used) == 0; + return GET_USED((PyDictObject *)dict) == 0; } int @@ -7631,7 +7713,7 @@ validate_watcher_id(PyInterpreterState *interp, int watcher_id) int PyDict_Watch(int watcher_id, PyObject* dict) { - if (!PyDict_Check(dict)) { + if (!PyAnyDict_Check(dict)) { PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); return -1; } @@ -7646,7 +7728,7 @@ PyDict_Watch(int watcher_id, PyObject* dict) int PyDict_Unwatch(int watcher_id, PyObject* dict) { - if (!PyDict_Check(dict)) { + if (!PyAnyDict_Check(dict)) { PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); return -1; } @@ -7743,3 +7825,147 @@ _PyObject_InlineValuesConsistencyCheck(PyObject *obj) return 0; } #endif + +// --- frozendict implementation --------------------------------------------- + +static PyNumberMethods frozendict_as_number = { + .nb_or = frozendict_or, +}; + +static PyMappingMethods frozendict_as_mapping = { + .mp_length = dict_length, + .mp_subscript = dict_subscript, +}; + +static PyMethodDef frozendict_methods[] = { + DICT___CONTAINS___METHODDEF + {"__getitem__", dict_subscript, METH_O | METH_COEXIST, getitem__doc__}, + DICT___SIZEOF___METHODDEF + DICT_GET_METHODDEF + DICT_KEYS_METHODDEF + DICT_ITEMS_METHODDEF + DICT_VALUES_METHODDEF + DICT_FROMKEYS_METHODDEF + DICT_COPY_METHODDEF + DICT___REVERSED___METHODDEF + {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, + {NULL, NULL} /* sentinel */ +}; + + +static PyObject * +frozendict_repr(PyObject *self) +{ + PyObject *repr = dict_repr(self); + if (repr == NULL) { + return NULL; + } + assert(PyUnicode_Check(repr)); + + PyObject *res = PyUnicode_FromFormat("%s(%U)", + Py_TYPE(self)->tp_name, + repr); + Py_DECREF(repr); + return res; +} + +static Py_hash_t +frozendict_hash(PyObject *op) +{ + PyFrozenDictObject *self = _PyFrozenDictObject_CAST(op); + Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ma_hash); + if (hash != -1) { + return hash; + } + + PyObject *items = _PyDictView_New(op, &PyDictItems_Type); + if (items == NULL) { + return -1; + } + PyObject *frozenset = PyFrozenSet_New(items); + Py_DECREF(items); + if (frozenset == NULL) { + return -1; + } + + hash = PyObject_Hash(frozenset); + Py_DECREF(frozenset); + if (hash == -1) { + return -1; + } + + FT_ATOMIC_STORE_SSIZE_RELAXED(self->ma_hash, hash); + return hash; +} + + +static PyObject * +frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *d = dict_new(type, args, kwds); + if (d == NULL) { + return NULL; + } + PyFrozenDictObject *self = _PyFrozenDictObject_CAST(d); + self->ma_hash = -1; + + if (args != NULL) { + if (dict_update_common(d, args, kwds, "frozendict") < 0) { + Py_DECREF(d); + return NULL; + } + } + else { + assert(kwds == NULL); + } + + return d; +} + + +PyObject* +PyFrozenDict_New(PyObject *iterable) +{ + if (iterable != NULL) { + PyObject *args = PyTuple_Pack(1, iterable); + if (args == NULL) { + return NULL; + } + PyObject *frozendict = frozendict_new(&PyFrozenDict_Type, args, NULL); + Py_DECREF(args); + return frozendict; + } + else { + PyObject *args = Py_GetConstantBorrowed(Py_CONSTANT_EMPTY_TUPLE); + return frozendict_new(&PyFrozenDict_Type, args, NULL); + } +} + + +PyTypeObject PyFrozenDict_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "frozendict", + .tp_basicsize = sizeof(PyFrozenDictObject), + .tp_dealloc = dict_dealloc, + .tp_repr = frozendict_repr, + .tp_as_number = &frozendict_as_number, + .tp_as_sequence = &dict_as_sequence, + .tp_as_mapping = &frozendict_as_mapping, + .tp_hash = frozendict_hash, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE + | _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_MAPPING, + .tp_doc = dictionary_doc, + .tp_traverse = dict_traverse, + .tp_clear = dict_tp_clear, + .tp_richcompare = dict_richcompare, + .tp_iter = dict_iter, + .tp_methods = frozendict_methods, + .tp_init = dict_init, + .tp_alloc = _PyType_AllocNoTrack, + .tp_new = frozendict_new, + .tp_free = PyObject_GC_Del, + .tp_vectorcall = dict_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_FROZENDICT, +}; diff --git a/Objects/object.c b/Objects/object.c index 1ddd949d28143e..ab73d2eb1c9c1f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -58,7 +58,7 @@ _PyObject_CheckConsistency(PyObject *op, int check_content) if (PyUnicode_Check(op)) { _PyUnicode_CheckConsistency(op, check_content); } - else if (PyDict_Check(op)) { + else if (PyAnyDict_Check(op)) { _PyDict_CheckConsistency(op, check_content); } return 1; @@ -2532,8 +2532,9 @@ static PyTypeObject* static_types[] = { &PyEnum_Type, &PyFilter_Type, &PyFloat_Type, - &PyFrame_Type, &PyFrameLocalsProxy_Type, + &PyFrame_Type, + &PyFrozenDict_Type, &PyFrozenSet_Type, &PyFunction_Type, &PyGen_Type, diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9144793ae73ce1..493a6e0413d8eb 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -3536,6 +3536,7 @@ _PyBuiltin_Init(PyInterpreterState *interp) SETBUILTIN("enumerate", &PyEnum_Type); SETBUILTIN("filter", &PyFilter_Type); SETBUILTIN("float", &PyFloat_Type); + SETBUILTIN("frozendict", &PyFrozenDict_Type); SETBUILTIN("frozenset", &PyFrozenSet_Type); SETBUILTIN("property", &PyProperty_Type); SETBUILTIN("int", &PyLong_Type); diff --git a/Python/marshal.c b/Python/marshal.c index 190fcdc89afaa8..a71909f103ebfc 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -67,6 +67,7 @@ module marshal #define TYPE_TUPLE '(' // See also TYPE_SMALL_TUPLE. #define TYPE_LIST '[' #define TYPE_DICT '{' +#define TYPE_FROZENDICT '}' #define TYPE_CODE 'c' #define TYPE_UNICODE 'u' #define TYPE_UNKNOWN '?' @@ -575,10 +576,15 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(PyList_GET_ITEM(v, i), p); } } - else if (PyDict_CheckExact(v)) { + else if (PyAnyDict_CheckExact(v)) { Py_ssize_t pos; PyObject *key, *value; - W_TYPE(TYPE_DICT, p); + if (PyFrozenDict_CheckExact(v)) { + W_TYPE(TYPE_FROZENDICT, p); + } + else { + W_TYPE(TYPE_DICT, p); + } /* This one is NULL object terminated! */ pos = 0; while (PyDict_Next(v, &pos, &key, &value)) { @@ -1420,6 +1426,7 @@ r_object(RFILE *p) break; case TYPE_DICT: + case TYPE_FROZENDICT: v = PyDict_New(); R_REF(v); if (v == NULL) @@ -1443,7 +1450,16 @@ r_object(RFILE *p) Py_DECREF(val); } if (PyErr_Occurred()) { - Py_SETREF(v, NULL); + Py_CLEAR(v); + } + if (type == TYPE_FROZENDICT && v != NULL) { + PyObject *frozendict = PyFrozenDict_New(v); + if (frozendict != NULL) { + Py_SETREF(v, frozendict); + } + else { + Py_CLEAR(v); + } } retval = v; break; diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 91bbf94990ecc1..cbec0bf262f0e0 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -769,6 +769,7 @@ Modules/clinic/md5module.c.h _md5_md5 _keywords - Modules/clinic/grpmodule.c.h grp_getgrgid _keywords - Modules/clinic/grpmodule.c.h grp_getgrnam _keywords - Objects/object.c - constants static PyObject*[] +Objects/dictobject.c - PyFrozenDict_Type - ## False positives From 6ef2578f209f230f26c41683bd8eab6ee05e013c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 17 Feb 2026 12:49:31 +0200 Subject: [PATCH 126/498] Enable CPU tests on default ARM build (#144743) --- .github/workflows/build.yml | 7 +++++++ .github/workflows/reusable-ubuntu.yml | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f302cb049326b0..d777f35ac208fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -242,11 +242,18 @@ jobs: # BOLT currently crashes during instrumentation on aarch64 - os: ubuntu-24.04-arm bolt: true + include: + # Enable CPU-intensive tests on ARM (default build only) + - os: ubuntu-24.04-arm + bolt: false + free-threading: false + test-opts: '-u cpu' uses: ./.github/workflows/reusable-ubuntu.yml with: bolt-optimizations: ${{ matrix.bolt }} free-threading: ${{ matrix.free-threading }} os: ${{ matrix.os }} + test-opts: ${{ matrix.test-opts || '' }} build-ubuntu-ssltests-openssl: name: 'Ubuntu SSL tests with OpenSSL' diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml index 03f41069b8430d..4bb4f535acb360 100644 --- a/.github/workflows/reusable-ubuntu.yml +++ b/.github/workflows/reusable-ubuntu.yml @@ -17,6 +17,11 @@ on: description: OS to run the job required: true type: string + test-opts: + description: Extra options to pass to the test runner via TESTOPTS + required: false + type: string + default: '' env: FORCE_COLOR: 1 @@ -111,4 +116,6 @@ jobs: run: sudo mount "$CPYTHON_RO_SRCDIR" -oremount,rw - name: Tests working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: xvfb-run make ci + run: xvfb-run make ci EXTRATESTOPTS="${TEST_OPTS}" + env: + TEST_OPTS: ${{ inputs.test-opts }} From fc05e5e3d7bcd59a64eabb8b94ee7af4d0bcc4d5 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Tue, 17 Feb 2026 22:39:56 +0900 Subject: [PATCH 127/498] gh-141510: Update mp_length of frozendict to use non atomic operation (gh-144913) --- Objects/dictobject.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 46b0148cf59ab5..510a0fab468cc6 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3482,6 +3482,12 @@ dict_length(PyObject *self) return GET_USED(_PyAnyDict_CAST(self)); } +static Py_ssize_t +frozendict_length(PyObject *self) +{ + return _PyAnyDict_CAST(self)->ma_used; +} + static PyObject * dict_subscript(PyObject *self, PyObject *key) { @@ -7833,7 +7839,7 @@ static PyNumberMethods frozendict_as_number = { }; static PyMappingMethods frozendict_as_mapping = { - .mp_length = dict_length, + .mp_length = frozendict_length, .mp_subscript = dict_subscript, }; From 1bd8cf9ed26977ac8c5cf3ec0eccdb6e7a3798e4 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Tue, 17 Feb 2026 23:52:50 +0900 Subject: [PATCH 128/498] gh-141510: Remove unncessary lock holding for frozendict repr (gh-144920) --- Objects/dictobject.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 510a0fab468cc6..62abb793d002e0 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3381,19 +3381,18 @@ dict_dealloc(PyObject *self) static PyObject * -dict_repr_lock_held(PyObject *self) +anydict_repr_impl(PyObject *self) { PyDictObject *mp = (PyDictObject *)self; PyObject *key = NULL, *value = NULL; - ASSERT_DICT_LOCKED(mp); - int res = Py_ReprEnter((PyObject *)mp); + int res = Py_ReprEnter(self); if (res != 0) { return (res > 0 ? PyUnicode_FromString("{...}") : NULL); } if (mp->ma_used == 0) { - Py_ReprLeave((PyObject *)mp); + Py_ReprLeave(self); return PyUnicode_FromString("{}"); } @@ -3412,7 +3411,7 @@ dict_repr_lock_held(PyObject *self) Note that repr may mutate the dict. */ Py_ssize_t i = 0; int first = 1; - while (_PyDict_Next((PyObject *)mp, &i, &key, &value, NULL)) { + while (_PyDict_Next(self, &i, &key, &value, NULL)) { // Prevent repr from deleting key or value during key format. Py_INCREF(key); Py_INCREF(value); @@ -3454,18 +3453,25 @@ dict_repr_lock_held(PyObject *self) goto error; } - Py_ReprLeave((PyObject *)mp); + Py_ReprLeave(self); return PyUnicodeWriter_Finish(writer); error: - Py_ReprLeave((PyObject *)mp); + Py_ReprLeave(self); PyUnicodeWriter_Discard(writer); Py_XDECREF(key); Py_XDECREF(value); return NULL; } +static PyObject * +dict_repr_lock_held(PyObject *self) +{ + ASSERT_DICT_LOCKED((PyDictObject *)self); + return anydict_repr_impl(self); +} + static PyObject * dict_repr(PyObject *self) { @@ -7862,7 +7868,7 @@ static PyMethodDef frozendict_methods[] = { static PyObject * frozendict_repr(PyObject *self) { - PyObject *repr = dict_repr(self); + PyObject *repr = anydict_repr_impl(self); if (repr == NULL) { return NULL; } From 6577d870b0cb82baf540f4bcf49c01d68204e468 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 17 Feb 2026 09:12:25 -0700 Subject: [PATCH 129/498] gh-144438: Fix false sharing between QSBR and tlbc_index (gh-144554) Align the QSBR thread state array to a 64-byte cache line boundary and add padding at the end of _PyThreadStateImpl. Depending on heap layout, the QSBR array could end up sharing a cache line with a thread's tlbc_index, causing QSBR quiescent state updates to contend with reads of tlbc_index in RESUME_CHECK. This is sensitive to earlier allocations during interpreter init and can appear or disappear with seemingly unrelated changes. Either change alone is sufficient to fix the specific issue, but both are worthwhile to avoid similar problems in the future. --- Include/internal/pycore_qsbr.h | 3 ++- Include/internal/pycore_tstate.h | 6 ++++++ ...2-06-21-45-52.gh-issue-144438.GI_uB1LR.rst | 2 ++ Python/qsbr.c | 20 +++++++++++++------ 4 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst diff --git a/Include/internal/pycore_qsbr.h b/Include/internal/pycore_qsbr.h index 1f9b3fcf777493..eeca6fc472be37 100644 --- a/Include/internal/pycore_qsbr.h +++ b/Include/internal/pycore_qsbr.h @@ -83,8 +83,9 @@ struct _qsbr_shared { // Minimum observed read sequence of all QSBR thread states uint64_t rd_seq; - // Array of QSBR thread states. + // Array of QSBR thread states (aligned to 64 bytes). struct _qsbr_pad *array; + void *array_raw; // raw allocation pointer (for free) Py_ssize_t size; // Freelist of unused _qsbr_thread_states (protected by mutex) diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h index 64b90710b8e664..eb2b0c84acdc7c 100644 --- a/Include/internal/pycore_tstate.h +++ b/Include/internal/pycore_tstate.h @@ -102,6 +102,12 @@ typedef struct _PyThreadStateImpl { #if _Py_TIER2 struct _PyJitTracerState *jit_tracer_state; #endif + +#ifdef Py_GIL_DISABLED + // gh-144438: Add padding to ensure that the fields above don't share a + // cache line with other allocations. + char __padding[64]; +#endif } _PyThreadStateImpl; #ifdef __cplusplus diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst new file mode 100644 index 00000000000000..3e33e461ae8b5a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst @@ -0,0 +1,2 @@ +Align the QSBR thread state array to a 64-byte cache line boundary to +avoid false sharing in the :term:`free-threaded build`. diff --git a/Python/qsbr.c b/Python/qsbr.c index 6bf5b75f346690..e9d935bfb40d84 100644 --- a/Python/qsbr.c +++ b/Python/qsbr.c @@ -85,22 +85,29 @@ grow_thread_array(struct _qsbr_shared *shared) new_size = MIN_ARRAY_SIZE; } - struct _qsbr_pad *array = PyMem_RawCalloc(new_size, sizeof(*array)); - if (array == NULL) { + // Overallocate by 63 bytes so we can align to a 64-byte boundary. + // This avoids potential false sharing between the first entry and other + // allocations. + size_t alignment = 64; + size_t alloc_size = (size_t)new_size * sizeof(struct _qsbr_pad) + alignment - 1; + void *raw = PyMem_RawCalloc(1, alloc_size); + if (raw == NULL) { return -1; } + struct _qsbr_pad *array = _Py_ALIGN_UP(raw, alignment); - struct _qsbr_pad *old = shared->array; - if (old != NULL) { + void *old_raw = shared->array_raw; + if (shared->array != NULL) { memcpy(array, shared->array, shared->size * sizeof(*array)); } shared->array = array; + shared->array_raw = raw; shared->size = new_size; shared->freelist = NULL; initialize_new_array(shared); - PyMem_RawFree(old); + PyMem_RawFree(old_raw); return 0; } @@ -257,8 +264,9 @@ void _Py_qsbr_fini(PyInterpreterState *interp) { struct _qsbr_shared *shared = &interp->qsbr; - PyMem_RawFree(shared->array); + PyMem_RawFree(shared->array_raw); shared->array = NULL; + shared->array_raw = NULL; shared->size = 0; shared->freelist = NULL; } From 8e211b1ca93401d46009b556d648d12c679a132b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Feb 2026 18:39:33 +0100 Subject: [PATCH 130/498] gh-141510: Optimize hash(frozendict) (#144919) hash(frozendict) no longer creates a temporary items view and a temporary frozenset object. Copy frozenset_hash() code to frozendict_hash(). --- Lib/test/test_dict.py | 9 +++++++ Objects/dictobject.c | 56 ++++++++++++++++++++++++++++++------------- Objects/setobject.c | 5 +++- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 1db3559a012fd3..2a106a8a4e8739 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1775,6 +1775,15 @@ class MyFrozenDict(frozendict): d = MyFrozenDict(x=1, y=2) self.assertEqual(repr(d), "MyFrozenDict({'x': 1, 'y': 2})") + def test_hash(self): + # hash() doesn't rely on the items order + self.assertEqual(hash(frozendict(x=1, y=2)), + hash(frozendict(y=2, x=1))) + + fd = frozendict(x=[1], y=[2]) + with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"): + hash(fd) + if __name__ == "__main__": unittest.main() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 62abb793d002e0..f7a359e4a1a40d 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -7881,33 +7881,55 @@ frozendict_repr(PyObject *self) return res; } +static Py_uhash_t +_shuffle_bits(Py_uhash_t h) +{ + return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL; +} + +// Code copied from frozenset_hash() static Py_hash_t frozendict_hash(PyObject *op) { PyFrozenDictObject *self = _PyFrozenDictObject_CAST(op); - Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ma_hash); - if (hash != -1) { - return hash; + Py_hash_t shash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ma_hash); + if (shash != -1) { + return shash; } - PyObject *items = _PyDictView_New(op, &PyDictItems_Type); - if (items == NULL) { - return -1; - } - PyObject *frozenset = PyFrozenSet_New(items); - Py_DECREF(items); - if (frozenset == NULL) { - return -1; + PyDictObject *mp = _PyAnyDict_CAST(op); + Py_uhash_t hash = 0; + + PyObject *key, *value; // borrowed refs + Py_ssize_t pos = 0; + while (PyDict_Next(op, &pos, &key, &value)) { + Py_hash_t key_hash = PyObject_Hash(key); + if (key_hash == -1) { + return -1; + } + hash ^= _shuffle_bits(key_hash); + + Py_hash_t value_hash = PyObject_Hash(value); + if (value_hash == -1) { + return -1; + } + hash ^= _shuffle_bits(value_hash); } - hash = PyObject_Hash(frozenset); - Py_DECREF(frozenset); - if (hash == -1) { - return -1; + /* Factor in the number of active entries */ + hash ^= ((Py_uhash_t)mp->ma_used + 1) * 1927868237UL; + + /* Disperse patterns arising in nested frozendicts */ + hash ^= (hash >> 11) ^ (hash >> 25); + hash = hash * 69069U + 907133923UL; + + /* -1 is reserved as an error code */ + if (hash == (Py_uhash_t)-1) { + hash = 590923713UL; } - FT_ATOMIC_STORE_SSIZE_RELAXED(self->ma_hash, hash); - return hash; + FT_ATOMIC_STORE_SSIZE_RELAXED(self->ma_hash, (Py_hash_t)hash); + return (Py_hash_t)hash; } diff --git a/Objects/setobject.c b/Objects/setobject.c index 5d4d1812282eed..f8713bf3d1a432 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -964,7 +964,10 @@ _shuffle_bits(Py_uhash_t h) This hash algorithm can be used on either a frozenset or a set. When it is used on a set, it computes the hash value of the equivalent - frozenset without creating a new frozenset object. */ + frozenset without creating a new frozenset object. + + If you update this code, update also frozendict_hash() which copied this + code. */ static Py_hash_t frozenset_hash_impl(PyObject *self) From d1505b543a26d3288725ca83e4a70dfa378eb866 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Feb 2026 19:04:17 +0100 Subject: [PATCH 131/498] gh-141510: Change repr(frozendict) for empty dict (#144921) repr(frozendict()) returns "frozendict()" instead of "frozendict({})". --- Lib/test/test_dict.py | 3 +++ Objects/dictobject.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 2a106a8a4e8739..21f8bb11071c90 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1767,6 +1767,9 @@ def test_update(self): self.assertEqual(copy, frozendict({'x': 1})) def test_repr(self): + d = frozendict() + self.assertEqual(repr(d), "frozendict()") + d = frozendict(x=1, y=2) self.assertEqual(repr(d), "frozendict({'x': 1, 'y': 2})") diff --git a/Objects/dictobject.c b/Objects/dictobject.c index f7a359e4a1a40d..7db2e547b54dba 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -7868,6 +7868,11 @@ static PyMethodDef frozendict_methods[] = { static PyObject * frozendict_repr(PyObject *self) { + PyDictObject *mp = _PyAnyDict_CAST(self); + if (mp->ma_used == 0) { + return PyUnicode_FromFormat("%s()", Py_TYPE(self)->tp_name); + } + PyObject *repr = anydict_repr_impl(self); if (repr == NULL) { return NULL; From fa73fd473f00dd231f59e44798a3d00a46322658 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 17 Feb 2026 20:26:29 +0000 Subject: [PATCH 132/498] gh-141510: Update `test_xpickle` for `frozendict` (#144927) --- Lib/test/pickletester.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 5f627f047ea319..c4460c2e44d578 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -3167,6 +3167,7 @@ def test_builtin_types(self): 'bytes': (3, 0), 'BuiltinImporter': (3, 3), 'str': (3, 4), # not interoperable with Python < 3.4 + 'frozendict': (3, 15), } for t in builtins.__dict__.values(): if isinstance(t, type) and not issubclass(t, BaseException): From d1b541b047e15bb6bddea50a64d71ddb01935e33 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Wed, 18 Feb 2026 06:46:20 +0900 Subject: [PATCH 133/498] gh-141510: Optimize {frozen}dict.fromkeys for frozendict (gh-144915) --- ...-02-17-22-27-11.gh-issue-141510.-4yYsf.rst | 2 + Objects/dictobject.c | 63 ++++++++++++++++--- 2 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst new file mode 100644 index 00000000000000..b031fb3c75dea7 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst @@ -0,0 +1,2 @@ +Optimize :meth:`!frozendict.fromkeys` to avoid unnecessary thread-safety operations +in frozendict cases. Patch by Donghee Na. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 7db2e547b54dba..0959e2c78a3289 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2671,10 +2671,8 @@ _PyDict_LoadBuiltinsFromGlobals(PyObject *globals) /* Consumes references to key and value */ static int -setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) +anydict_setitem_take2(PyDictObject *mp, PyObject *key, PyObject *value) { - ASSERT_DICT_LOCKED(mp); - assert(key); assert(value); assert(PyAnyDict_Check(mp)); @@ -2693,6 +2691,14 @@ setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) return insertdict(mp, key, hash, value); } +/* Consumes references to key and value */ +static int +setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) +{ + ASSERT_DICT_LOCKED(mp); + return anydict_setitem_take2(mp, key, value); +} + int _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) { @@ -3284,8 +3290,8 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) return NULL; - if (PyAnyDict_CheckExact(d)) { - if (PyAnyDict_CheckExact(iterable)) { + if (PyDict_CheckExact(d)) { + if (PyDict_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; Py_BEGIN_CRITICAL_SECTION2(d, iterable); @@ -3293,6 +3299,14 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) Py_END_CRITICAL_SECTION2(); return d; } + else if (PyFrozenDict_CheckExact(iterable)) { + PyDictObject *mp = (PyDictObject *)d; + + Py_BEGIN_CRITICAL_SECTION(d); + d = (PyObject *)dict_dict_fromkeys(mp, iterable, value); + Py_END_CRITICAL_SECTION(); + return d; + } else if (PyAnySet_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; @@ -3302,6 +3316,29 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) return d; } } + else if (PyFrozenDict_CheckExact(d)) { + if (PyDict_CheckExact(iterable)) { + PyDictObject *mp = (PyDictObject *)d; + + Py_BEGIN_CRITICAL_SECTION(iterable); + d = (PyObject *)dict_dict_fromkeys(mp, iterable, value); + Py_END_CRITICAL_SECTION(); + return d; + } + else if (PyFrozenDict_CheckExact(iterable)) { + PyDictObject *mp = (PyDictObject *)d; + d = (PyObject *)dict_dict_fromkeys(mp, iterable, value); + return d; + } + else if (PyAnySet_CheckExact(iterable)) { + PyDictObject *mp = (PyDictObject *)d; + + Py_BEGIN_CRITICAL_SECTION(iterable); + d = (PyObject *)dict_set_fromkeys(mp, iterable, value); + Py_END_CRITICAL_SECTION(); + return d; + } + } it = PyObject_GetIter(iterable); if (it == NULL){ @@ -3309,7 +3346,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) return NULL; } - if (PyAnyDict_CheckExact(d)) { + if (PyDict_CheckExact(d)) { Py_BEGIN_CRITICAL_SECTION(d); while ((key = PyIter_Next(it)) != NULL) { status = setitem_lock_held((PyDictObject *)d, key, value); @@ -3321,7 +3358,19 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) } dict_iter_exit:; Py_END_CRITICAL_SECTION(); - } else { + } + else if (PyFrozenDict_CheckExact(d)) { + while ((key = PyIter_Next(it)) != NULL) { + // anydict_setitem_take2 consumes a reference to key + status = anydict_setitem_take2((PyDictObject *)d, + key, Py_NewRef(value)); + if (status < 0) { + assert(PyErr_Occurred()); + goto Fail; + } + } + } + else { while ((key = PyIter_Next(it)) != NULL) { status = PyObject_SetItem(d, key, value); Py_DECREF(key); From e779777c66595acc599162fc3c852f3cda3f5c45 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Feb 2026 23:03:22 +0100 Subject: [PATCH 134/498] gh-141510: Mention frozendict in dict documentation (#144934) test_genericalias now tests also frozendict. --- Doc/library/stdtypes.rst | 4 ++-- Lib/pydoc_data/topics.py | 8 ++++---- Lib/test/test_genericalias.py | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 6f798f02e17899..a8f693f4879025 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -5590,8 +5590,8 @@ can be used interchangeably to index the same dictionary entry. .. seealso:: - :class:`types.MappingProxyType` can be used to create a read-only view - of a :class:`dict`. + :class:`frozendict` and :class:`types.MappingProxyType` can be used to + create a read-only view of a :class:`dict`. .. _thread-safety-dict: diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 32cf9a995bae3d..dc09c5fd47affe 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -3676,8 +3676,8 @@ def f() -> annotation: ... * a class that inherits from any of the above - The standard library classes "dict" and "types.MappingProxyType" - are mappings. + The standard library classes "dict", "frozendict" + and "types.MappingProxyType" are mappings. [4] A string literal appearing as the first statement in the function body is transformed into the function’s "__doc__" attribute and @@ -13620,8 +13620,8 @@ class dict(iterable, /, **kwargs) See also: - "types.MappingProxyType" can be used to create a read-only view of a - "dict". + "frozendict" and "types.MappingProxyType" can be used to create a read-only + view of a "dict". Dictionary view objects diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 2b9cee6433b5b8..a5969b7a47d948 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -101,7 +101,8 @@ class BaseTest(unittest.TestCase): """Test basics.""" - generic_types = [type, tuple, list, dict, set, frozenset, enumerate, memoryview, + generic_types = [type, tuple, list, dict, frozendict, + set, frozenset, enumerate, memoryview, slice, defaultdict, deque, SequenceMatcher, From 836f2c97f99925e84ec20d3c6da335a841f63b62 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 18 Feb 2026 09:46:27 +0530 Subject: [PATCH 135/498] gh-144914: use `mimalloc` for raw allocations on free-threading (#144916) --- Doc/whatsnew/3.15.rst | 5 +++ Include/internal/pycore_pymem_init.h | 6 ++++ ...-02-17-18-27-28.gh-issue-144914.DcXO4m.rst | 1 + Objects/obmalloc.c | 35 ++++++++++++++++--- 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index e5714765208ff6..62ce7121424651 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1204,6 +1204,11 @@ Optimizations (Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`. Special thanks to the MSVC team including Hulon Jenkins.) +* ``mimalloc`` is now used as the default allocator for + for raw memory allocations such as via :c:func:`PyMem_RawMalloc` + for better performance on :term:`free-threaded builds `. + (Contributed by Kumar Aditya in :gh:`144914`.) + base64 & binascii ----------------- diff --git a/Include/internal/pycore_pymem_init.h b/Include/internal/pycore_pymem_init.h index c593edc86d9952..2a0e0817dcc7f8 100644 --- a/Include/internal/pycore_pymem_init.h +++ b/Include/internal/pycore_pymem_init.h @@ -30,6 +30,12 @@ extern void* _PyMem_MiCalloc(void *, size_t, size_t); extern void _PyMem_MiFree(void *, void *); extern void* _PyMem_MiRealloc(void *, void *, size_t); # define PYMEM_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree} +extern void* _PyMem_MiRawMalloc(void *, size_t); +extern void* _PyMem_MiRawCalloc(void *, size_t, size_t); +extern void _PyMem_MiRawFree(void *, void *); +extern void* _PyMem_MiRawRealloc(void *, void *, size_t); +# undef PYRAW_ALLOC +# define PYRAW_ALLOC {NULL, _PyMem_MiRawMalloc, _PyMem_MiRawCalloc, _PyMem_MiRawRealloc, _PyMem_MiRawFree} #elif defined(WITH_PYMALLOC) extern void* _PyObject_Malloc(void *, size_t); extern void* _PyObject_Calloc(void *, size_t, size_t); diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst new file mode 100644 index 00000000000000..f13b8541a0ebe2 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst @@ -0,0 +1 @@ +Use ``mimalloc`` for raw memory allocations such as via :c:func:`PyMem_RawMalloc` for better performance on :term:`free-threaded builds `. Patch by Kumar Aditya. diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index ce2e39790bd76c..b59ebdfbda3897 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -358,6 +358,29 @@ _PyObject_MiFree(void *ctx, void *ptr) mi_free(ptr); } +void * +_PyMem_MiRawMalloc(void *ctx, size_t size) +{ + return mi_malloc(size); +} + +void * +_PyMem_MiRawCalloc(void *ctx, size_t nelem, size_t elsize) +{ + return mi_calloc(nelem, elsize); +} + +void * +_PyMem_MiRawRealloc(void *ctx, void *ptr, size_t size) +{ + return mi_realloc(ptr, size); +} + +void +_PyMem_MiRawFree(void *ctx, void *ptr) +{ + mi_free(ptr); +} #endif // WITH_MIMALLOC @@ -365,7 +388,8 @@ _PyObject_MiFree(void *ctx, void *ptr) #ifdef WITH_MIMALLOC -# define MIMALLOC_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree} +# define MIMALLOC_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree} +# define MIMALLOC_RAWALLOC {NULL, _PyMem_MiRawMalloc, _PyMem_MiRawCalloc, _PyMem_MiRawRealloc, _PyMem_MiRawFree} # define MIMALLOC_OBJALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree} #endif @@ -383,7 +407,7 @@ void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); #if defined(Py_GIL_DISABLED) // Py_GIL_DISABLED requires using mimalloc for "mem" and "obj" domains. -# define PYRAW_ALLOC MALLOC_ALLOC +# define PYRAW_ALLOC MIMALLOC_RAWALLOC # define PYMEM_ALLOC MIMALLOC_ALLOC # define PYOBJ_ALLOC MIMALLOC_OBJALLOC #elif defined(WITH_PYMALLOC) @@ -758,7 +782,7 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator) case PYMEM_ALLOCATOR_MIMALLOC: case PYMEM_ALLOCATOR_MIMALLOC_DEBUG: { - PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; + PyMemAllocatorEx malloc_alloc = MIMALLOC_RAWALLOC; set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc); PyMemAllocatorEx pymalloc = MIMALLOC_ALLOC; @@ -828,6 +852,7 @@ get_current_allocator_name_unlocked(void) #ifdef WITH_MIMALLOC PyMemAllocatorEx mimalloc = MIMALLOC_ALLOC; PyMemAllocatorEx mimalloc_obj = MIMALLOC_OBJALLOC; + PyMemAllocatorEx mimalloc_raw = MIMALLOC_RAWALLOC; #endif if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) && @@ -845,7 +870,7 @@ get_current_allocator_name_unlocked(void) } #endif #ifdef WITH_MIMALLOC - if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) && + if (pymemallocator_eq(&_PyMem_Raw, &mimalloc_raw) && pymemallocator_eq(&_PyMem, &mimalloc) && pymemallocator_eq(&_PyObject, &mimalloc_obj)) { @@ -877,7 +902,7 @@ get_current_allocator_name_unlocked(void) } #endif #ifdef WITH_MIMALLOC - if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) && + if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &mimalloc_raw) && pymemallocator_eq(&_PyMem_Debug.mem.alloc, &mimalloc) && pymemallocator_eq(&_PyMem_Debug.obj.alloc, &mimalloc_obj)) { From 783e3fd4364faa1530c7eecae2bad7338a828905 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 18 Feb 2026 07:51:45 +0000 Subject: [PATCH 136/498] Move CODEOWNERS rule from devguide (GH-144924) --- .github/CODEOWNERS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 32b883213685b2..b53c3cc1f465ff 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -473,8 +473,9 @@ Lib/test/test_functools.py @rhettinger Modules/_functoolsmodule.c @rhettinger # Garbage collector -Modules/gcmodule.c @pablogsal -Doc/library/gc.rst @pablogsal +Modules/gcmodule.c @pablogsal +Doc/library/gc.rst @pablogsal +InternalDocs/garbage_collector.md @pablogsal # Gettext Doc/library/gettext.rst @tomasr8 From 6f7e3d44082351b4ee77a2ba186a6388c2950eb1 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 18 Feb 2026 07:52:04 +0000 Subject: [PATCH 137/498] Docs: Remove unnecessary entry from `nitpick_ignore` (GH-144933) --- Doc/conf.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Doc/conf.py b/Doc/conf.py index 859c1d26ed9f22..d7effe2572ec44 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -227,10 +227,6 @@ # Temporary undocumented names. # In future this list must be empty. nitpick_ignore += [ - # Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot - # be resolved, as the method is currently undocumented. For context, see - # https://github.com/python/cpython/pull/103289. - ('py:meth', '_SubParsersAction.add_parser'), # Attributes/methods/etc. that definitely should be documented better, # but are deferred for now: ('py:attr', '__wrapped__'), From 7a7521bcfad4a8346d460476de2e3fa11e412477 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 18 Feb 2026 04:58:30 -0500 Subject: [PATCH 138/498] Docs: an "improve this page" feature (#144939) * Docs: a start on an 'improve this page' feature * pr feedback: simplify the link, and don't scare people with the cla * pr feedback answered - use the actual page URL - tighten the wording * fix the improve link on the improve page * news item * Update Doc/improve-page.rst Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> * fix whitespace * A nojs version of the page * comments to help people keep the two pages in sync * protect against XSS * use template for issues from the nojs page * use the template from the JS page as well * give the docs issue template a fillable description field * ugh, getting sloppy * remove more sloppiness --------- Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/documentation.yml | 3 +- Doc/improve-page-nojs.rst | 29 +++++++++ Doc/improve-page.rst | 65 +++++++++++++++++++ Doc/tools/templates/customsourcelink.html | 17 ++++- ...-08-02-18-59-01.gh-issue-136246.RIK7nE.rst | 3 + 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 Doc/improve-page-nojs.rst create mode 100644 Doc/improve-page.rst create mode 100644 Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml index 944e590452c7cf..d720cf9c4de91e 100644 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -8,8 +8,9 @@ body: > [!NOTE] > Trivial changes (for example typos) don’t require an issue before opening a PR. - type: textarea + id: description attributes: label: "Documentation" - description: "A clear and concise description of the issue." + description: "A clear and concise description of the issue. Include a link to the page." validations: required: true diff --git a/Doc/improve-page-nojs.rst b/Doc/improve-page-nojs.rst new file mode 100644 index 00000000000000..91b3a88b95d38b --- /dev/null +++ b/Doc/improve-page-nojs.rst @@ -0,0 +1,29 @@ +:orphan: + +**************************** +Improve a documentation page +**************************** + +.. This is the no-javascript version of this page. The one most people + will see (with JavaScript enabled) is improve-page.rst. If you edit + this page, please also edit that one, and vice versa. + +.. only:: html and not epub + +We are always interested to hear ideas about improvements to the documentation. + +.. only:: translation + + If the bug or suggested improvement concerns the translation of this + documentation, open an issue or edit the page in + `translation's repository `_ instead. + +You have a few ways to ask questions or suggest changes: + +- You can start a discussion about the page on the Python discussion forum. + This link will start a topic in the Documentation category: + `New Documentation topic `_. + +- You can open an issue on the Python GitHub issue tracker. This link will + create a new issue with the "docs" label: + `New docs issue `_. diff --git a/Doc/improve-page.rst b/Doc/improve-page.rst new file mode 100644 index 00000000000000..dc89fcb22fbb59 --- /dev/null +++ b/Doc/improve-page.rst @@ -0,0 +1,65 @@ +:orphan: + +**************************** +Improve a documentation page +**************************** + +.. This is the JavaScript-enabled version of this page. Another version + (for those with JavaScript disabled) is improve-page-nojs.rst. If you + edit this page, please also edit that one, and vice versa. + +.. only:: html and not epub + + .. raw:: html + + + +We are always interested to hear ideas about improvements to the documentation. + +You were reading "PAGETITLE" at ``_. The source for that page is on +`GitHub `_. + +.. only:: translation + + If the bug or suggested improvement concerns the translation of this + documentation, open an issue or edit the page in + `translation's repository `_ instead. + +You have a few ways to ask questions or suggest changes: + +- You can start a discussion about the page on the Python discussion forum. + This link will start a pre-populated topic: + `Question about page "PAGETITLE" `_. + +- You can open an issue on the Python GitHub issue tracker. This link will + create a new pre-populated issue: + `Docs: problem with page "PAGETITLE" `_. + +- You can `edit the page on GitHub `_ + to open a pull request and begin the contribution process. diff --git a/Doc/tools/templates/customsourcelink.html b/Doc/tools/templates/customsourcelink.html index 0d83ac9f78adb9..8feeed2fee3650 100644 --- a/Doc/tools/templates/customsourcelink.html +++ b/Doc/tools/templates/customsourcelink.html @@ -1,10 +1,25 @@ {%- if show_source and has_source and sourcename %} + + + + - - -

{{ _('This page') }}

  • {% trans %}Report a bug{% endtrans %}
  • +
  • {% trans %}Improve this page{% endtrans %}
  • - {{ _('Show source') }}
  • diff --git a/Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst b/Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst new file mode 100644 index 00000000000000..5f83785df13209 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst @@ -0,0 +1,3 @@ +A new "Improve this page" link is available in the left-hand sidebar of the +docs, offering links to create GitHub issues, discussion forum posts, or +pull requests. From e49bfca87cc188c271946491edc33831a901c7f1 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:54:07 +0000 Subject: [PATCH 139/498] gh-142224: unicodedata: support bidi classes for unassigned code points (GH-144815) --- Lib/test/test_unicodedata.py | 21 +- ...3-00-00-00.gh-issue-142224.BidiMissing.rst | 2 + Modules/unicodedata_db.h | 4360 +++++++++-------- Tools/unicode/makeunicodedata.py | 70 +- 4 files changed, 2319 insertions(+), 2134 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index d100dae1110b7f..1d03e7d9fec717 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -319,7 +319,7 @@ def test_category(self): self.assertRaises(TypeError, self.db.category, 'xx') def test_bidirectional(self): - self.assertEqual(self.db.bidirectional('\uFFFE'), '') + self.assertEqual(self.db.bidirectional('\uFFFE'), 'BN') self.assertEqual(self.db.bidirectional(' '), 'WS') self.assertEqual(self.db.bidirectional('A'), 'L') self.assertEqual(self.db.bidirectional('\U00020000'), 'L') @@ -347,6 +347,17 @@ def test_bidirectional(self): self.assertRaises(TypeError, self.db.bidirectional) self.assertRaises(TypeError, self.db.bidirectional, 'xx') + def test_bidirectional_unassigned(self): + if self.old: + return + self.assertEqual(self.db.bidirectional('\u0378'), 'L') + self.assertEqual(self.db.bidirectional('\u077F'), 'AL') + self.assertEqual(self.db.bidirectional('\u20CF'), 'ET') + self.assertEqual(self.db.bidirectional('\u0590'), 'R') + self.assertEqual(self.db.bidirectional('\uFFFF'), 'BN') + self.assertEqual(self.db.bidirectional('\U0001FFFE'), 'BN') + self.assertEqual(self.db.bidirectional('\U00010D01'), 'AL') + def test_decomposition(self): self.assertEqual(self.db.decomposition('\uFFFE'),'') self.assertEqual(self.db.decomposition('\u00bc'), ' 0031 2044 0034') @@ -676,9 +687,9 @@ class UnicodeFunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): # Update this if the database changes. Make sure to do a full rebuild # (e.g. 'make distclean && make') to get the correct checksum. - expectedchecksum = ('83cc43a2fbb779185832b4c049217d80b05bf349' + expectedchecksum = ('668dbbea1136e69d4f00677a5988b23bc78aefc6' if quicktest else - '180bdc91143d8aa2eb9dd6726e66d37606205942') + 'b869af769bd8fe352c04622ab90533dc54df5cf3') @requires_resource('network') def test_all_names(self): @@ -966,9 +977,9 @@ def graphemes(*args): class Unicode_3_2_0_FunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): db = unicodedata.ucd_3_2_0 old = True - expectedchecksum = ('4154d8d1232837e255edf3cdcbb5ab184d71f4a4' + expectedchecksum = ('2164a66700e03cba9c9f5ed9e9a8d594d2da136a' if quicktest else - '3aabaf66823b21b3d305dad804a62f6f6387c93e') + 'a8276cec9b6991779c5bdaa46c1ae7cc50bc2403') class UnicodeMiscTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst b/Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst new file mode 100644 index 00000000000000..29fa908d739fc3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst @@ -0,0 +1,2 @@ +:func:`unicodedata.bidirectional` now return the correct default bidi class +for unassigned code points. diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index a0b65628035984..3cc5776a1f240d 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -80,6 +80,7 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {4, 233, 14, 0, 4, 0, 5, 3, 0}, {4, 234, 14, 0, 4, 0, 5, 3, 0}, {18, 0, 19, 0, 0, 170, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0}, {26, 0, 19, 0, 0, 170, 0, 0, 0}, {29, 0, 19, 0, 0, 138, 0, 0, 0}, {1, 0, 1, 0, 0, 138, 0, 0, 0}, @@ -92,6 +93,7 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {21, 0, 19, 0, 0, 0, 0, 0, 0}, {30, 0, 19, 0, 0, 0, 0, 0, 0}, {28, 0, 11, 0, 0, 0, 0, 0, 0}, + {0, 0, 4, 0, 0, 0, 0, 0, 0}, {4, 220, 14, 0, 0, 0, 5, 3, 0}, {4, 222, 14, 0, 0, 0, 5, 3, 0}, {4, 228, 14, 0, 0, 0, 5, 3, 0}, @@ -140,6 +142,7 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {19, 0, 5, 0, 0, 136, 0, 0, 0}, {7, 0, 9, 0, 0, 0, 0, 0, 0}, {30, 0, 5, 0, 0, 0, 0, 0, 0}, + {0, 0, 5, 0, 0, 0, 0, 0, 0}, {14, 0, 5, 0, 0, 0, 1, 0, 0}, {4, 36, 14, 0, 0, 0, 5, 3, 0}, {4, 0, 14, 0, 0, 0, 5, 3, 0}, @@ -236,7 +239,7 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {26, 0, 19, 0, 0, 136, 0, 0, 1}, {20, 0, 19, 0, 0, 0, 0, 0, 0}, {27, 0, 13, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 4, 0, 0}, + {0, 0, 15, 0, 0, 0, 4, 0, 0}, {14, 0, 20, 0, 0, 0, 4, 0, 0}, {14, 0, 21, 0, 0, 0, 4, 0, 0}, {14, 0, 22, 0, 0, 0, 4, 0, 0}, @@ -249,6 +252,7 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {18, 0, 1, 0, 4, 136, 0, 0, 0}, {28, 0, 11, 0, 0, 136, 0, 0, 0}, {28, 0, 11, 0, 1, 0, 0, 0, 0}, + {0, 0, 11, 0, 0, 0, 0, 0, 0}, {30, 0, 19, 0, 0, 136, 0, 0, 0}, {30, 0, 19, 0, 4, 136, 0, 0, 0}, {30, 0, 19, 0, 4, 136, 0, 0, 1}, @@ -317,11 +321,12 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {15, 0, 1, 0, 0, 0, 0, 0, 0}, {16, 0, 1, 0, 4, 0, 0, 0, 0}, {19, 0, 1, 0, 2, 170, 0, 0, 0}, - {0, 0, 0, 0, 2, 0, 0, 0, 0}, + {0, 0, 1, 0, 2, 0, 0, 0, 0}, {19, 0, 4, 0, 0, 170, 0, 0, 0}, {4, 26, 14, 0, 0, 0, 5, 3, 0}, {19, 0, 4, 0, 0, 136, 0, 0, 0}, {23, 0, 19, 0, 0, 0, 0, 0, 0}, + {0, 0, 15, 0, 0, 0, 0, 0, 0}, {28, 0, 5, 0, 0, 136, 0, 0, 0}, {26, 0, 19, 0, 2, 136, 0, 0, 0}, {22, 0, 19, 0, 2, 136, 0, 0, 0}, @@ -386,7 +391,7 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {5, 216, 1, 0, 0, 0, 5, 3, 0}, {5, 226, 1, 0, 0, 0, 5, 3, 0}, {9, 0, 1, 0, 2, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 1}, + {0, 0, 1, 0, 0, 0, 0, 0, 1}, {30, 0, 1, 0, 4, 0, 0, 0, 0}, {30, 0, 1, 0, 4, 0, 0, 0, 1}, {30, 0, 1, 0, 2, 0, 0, 0, 1}, @@ -880,11 +885,11 @@ static const unsigned short index1[] = { 222, 222, 222, 224, 225, 226, 78, 227, 228, 229, 230, 231, 232, 143, 233, 234, 235, 236, 237, 238, 239, 240, 78, 78, 78, 78, 241, 242, 143, 143, 143, 143, 143, 143, 143, 143, 243, 143, 244, 245, 246, 143, 143, 247, - 143, 143, 143, 248, 143, 249, 143, 250, 143, 251, 252, 253, 254, 143, - 143, 143, 143, 143, 255, 256, 257, 143, 258, 259, 143, 143, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 222, 274, - 275, 276, 277, 278, 279, 280, 222, 281, 265, 265, 265, 265, 265, 265, - 265, 282, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 143, 143, 143, 248, 143, 249, 143, 250, 143, 251, 252, 253, 254, 255, + 255, 255, 255, 255, 256, 257, 258, 255, 259, 260, 255, 255, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 222, 275, + 276, 277, 278, 279, 280, 281, 222, 282, 266, 266, 266, 266, 266, 266, + 266, 283, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, @@ -907,57 +912,57 @@ static const unsigned short index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 283, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 284, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 284, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 285, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 285, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 286, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 286, 101, 101, - 101, 101, 287, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 127, 127, 127, 127, 289, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 290, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 287, 101, 101, + 101, 101, 288, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 127, 127, 127, 127, 290, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 291, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 291, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 292, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 292, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 290, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 101, 101, 293, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 291, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -993,6 +998,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1029,6 +1035,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1064,6 +1071,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1100,6 +1108,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1136,6 +1145,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1171,6 +1181,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1207,6 +1218,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1242,6 +1254,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1278,6 +1291,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1313,6 +1327,10 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 294, + 295, 296, 297, 298, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1323,9 +1341,6 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 293, 294, 295, 296, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, - 294, 294, 294, 294, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, @@ -1349,17 +1364,7 @@ static const unsigned short index1[] = { 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 126, 126, 126, 126, 126, 126, + 143, 143, 143, 143, 143, 143, 143, 294, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, @@ -1396,7 +1401,7 @@ static const unsigned short index1[] = { 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 297, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 299, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, @@ -1432,7 +1437,7 @@ static const unsigned short index1[] = { 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 297, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 299, }; static const unsigned short index2[] = { @@ -1484,260 +1489,269 @@ static const unsigned short index2[] = { 62, 62, 71, 71, 61, 71, 71, 72, 62, 64, 64, 64, 62, 62, 62, 64, 64, 73, 62, 62, 62, 64, 64, 64, 64, 62, 63, 64, 64, 62, 74, 75, 75, 74, 75, 75, 74, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 46, 49, 46, 49, - 76, 56, 46, 49, 0, 0, 53, 49, 49, 49, 77, 46, 0, 0, 0, 0, 60, 78, 40, 77, - 40, 40, 40, 0, 40, 0, 40, 40, 45, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 0, 41, 41, 41, 41, 41, 41, 41, 40, 40, 45, - 45, 45, 45, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 49, 43, 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 46, 37, - 37, 51, 79, 79, 37, 37, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 37, 37, 37, 49, 51, - 37, 80, 46, 49, 51, 46, 49, 49, 46, 46, 46, 40, 81, 46, 40, 46, 46, 46, - 40, 46, 46, 46, 46, 40, 40, 40, 46, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 81, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, + 76, 56, 46, 49, 77, 77, 53, 49, 49, 49, 78, 46, 77, 77, 77, 77, 60, 79, + 40, 78, 40, 40, 40, 77, 40, 77, 40, 40, 45, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 77, 41, 41, 41, 41, 41, 41, 41, + 40, 40, 45, 45, 45, 45, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 49, 43, 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, + 45, 46, 37, 37, 51, 80, 80, 37, 37, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 37, 37, + 37, 49, 51, 37, 81, 46, 49, 51, 46, 49, 49, 46, 46, 46, 40, 82, 46, 40, + 46, 46, 46, 40, 46, 46, 46, 46, 40, 40, 40, 46, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 82, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 45, 44, 49, 45, 49, 49, 49, 45, 49, 49, 49, 49, 45, 45, 45, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 40, 45, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 82, 83, 83, - 83, 83, 83, 84, 84, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 40, 45, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, - 46, 49, 49, 40, 45, 40, 45, 46, 49, 40, 45, 46, 49, 40, 45, 40, 45, 40, - 45, 46, 49, 40, 45, 40, 45, 40, 45, 46, 49, 40, 45, 40, 45, 40, 45, 40, - 45, 40, 45, 40, 45, 46, 49, 40, 45, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 0, 46, 46, 46, 46, 46, 46, 46, 46, + 43, 43, 43, 43, 45, 44, 49, 45, 49, 49, 49, 45, 49, 49, 49, 49, 45, 45, + 45, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 40, 45, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 83, 84, 84, 84, 84, 84, 85, 85, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 40, 45, 46, 49, 46, 49, 46, 49, 46, + 49, 46, 49, 46, 49, 49, 40, 45, 40, 45, 46, 49, 40, 45, 46, 49, 40, 45, + 40, 45, 40, 45, 46, 49, 40, 45, 40, 45, 40, 45, 46, 49, 40, 45, 40, 45, + 40, 45, 40, 45, 40, 45, 40, 45, 46, 49, 40, 45, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 77, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 55, 85, 85, 85, 85, - 85, 85, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 77, 77, 55, + 86, 86, 86, 86, 86, 86, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 37, 49, 85, 86, 0, 0, 87, 87, 88, 0, 89, 83, 83, 83, - 83, 89, 83, 83, 83, 90, 89, 83, 83, 83, 83, 83, 83, 89, 89, 89, 89, 89, - 89, 83, 83, 89, 83, 83, 90, 91, 83, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 101, 102, 103, 104, 105, 106, 107, 108, 109, 107, 83, 89, 107, 100, - 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 0, 0, 0, 0, 110, 110, 110, 110, 107, 107, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 80, 80, 112, 113, 113, - 114, 115, 116, 87, 87, 83, 83, 83, 83, 83, 83, 83, 83, 117, 118, 119, - 116, 120, 116, 116, 116, 121, 121, 122, 122, 122, 122, 122, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 123, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 124, 125, 126, 117, 118, 119, 127, 128, - 129, 129, 130, 89, 83, 83, 83, 83, 83, 89, 83, 83, 89, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 113, 132, 132, 116, 121, 121, 133, - 121, 121, 121, 121, 134, 134, 134, 134, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 121, 122, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 122, 116, 121, 83, 83, 83, 83, 83, 83, 83, 111, 87, 83, 83, 83, 83, 89, - 83, 123, 123, 83, 83, 87, 89, 83, 83, 89, 121, 121, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 121, 121, 121, 136, 136, 121, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 0, 137, 121, - 138, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 83, 89, 83, 83, 89, 83, 83, 89, 89, 89, 83, 89, 89, 83, - 89, 83, 83, 83, 89, 83, 89, 83, 89, 83, 89, 83, 83, 0, 0, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 121, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 83, 83, 83, 83, 83, 83, 83, 89, - 83, 141, 141, 87, 142, 142, 142, 141, 0, 0, 89, 143, 143, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 83, 83, 83, 83, 141, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 141, 83, 83, 83, 141, 83, 83, 83, 83, 83, 0, 0, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 89, 89, 89, 0, 0, 107, 0, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 0, 0, 0, 0, 0, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 144, 121, 121, 121, - 121, 121, 121, 121, 111, 111, 0, 0, 0, 0, 0, 83, 83, 89, 89, 89, 83, 83, - 83, 83, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 123, 83, 83, 83, 83, 83, 89, 89, 89, 89, 89, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 111, 89, 83, 83, 89, 83, 83, 89, 83, 83, 83, - 89, 89, 89, 124, 125, 126, 83, 83, 83, 89, 83, 83, 89, 89, 83, 83, 83, - 83, 83, 139, 139, 139, 145, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 147, 146, 146, 146, - 146, 146, 146, 146, 147, 146, 146, 147, 146, 146, 146, 146, 146, 139, - 145, 148, 50, 145, 145, 145, 139, 139, 139, 139, 139, 139, 139, 139, 145, - 145, 145, 145, 149, 145, 145, 50, 83, 89, 83, 83, 139, 139, 139, 150, - 150, 150, 150, 150, 150, 150, 150, 50, 50, 139, 139, 85, 85, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 85, 55, 50, 50, 50, 50, 50, 50, - 146, 146, 146, 146, 146, 146, 146, 146, 50, 139, 145, 145, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 0, 146, 146, 146, 146, 146, 146, 146, 0, 146, 0, 0, 0, 146, 146, - 146, 146, 0, 0, 152, 50, 153, 145, 145, 139, 139, 139, 139, 0, 0, 145, - 145, 0, 0, 154, 154, 149, 50, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, - 150, 150, 0, 150, 50, 50, 139, 139, 0, 0, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 146, 146, 88, 88, 155, 155, 155, 155, 155, 155, 82, - 88, 50, 85, 83, 0, 0, 139, 139, 145, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 156, 0, 50, 156, 0, 50, 50, 0, 0, 152, 0, 145, 145, 145, 139, 139, 0, 0, - 0, 0, 139, 139, 0, 0, 139, 139, 157, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, - 156, 156, 156, 50, 0, 156, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 139, 139, 50, 50, 50, 139, 85, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 139, 139, 145, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 0, 50, 50, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 146, 146, 146, 146, 146, - 146, 146, 0, 146, 146, 0, 146, 146, 146, 146, 146, 0, 0, 152, 50, 145, - 145, 145, 139, 139, 139, 139, 139, 0, 139, 139, 145, 0, 145, 145, 149, 0, - 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 139, 139, 0, - 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 85, 88, 0, 0, 0, 0, - 0, 0, 0, 146, 139, 139, 139, 139, 139, 139, 0, 139, 145, 145, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 0, 146, 146, 146, 146, 146, 146, 146, 0, 146, 146, 0, 146, 146, - 146, 146, 146, 0, 0, 152, 50, 153, 139, 145, 139, 139, 139, 139, 0, 0, - 145, 154, 0, 0, 154, 154, 149, 0, 0, 0, 0, 0, 0, 0, 139, 158, 153, 0, 0, - 0, 0, 150, 150, 0, 146, 50, 50, 139, 139, 0, 0, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 82, 146, 155, 155, 155, 155, 155, 155, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 139, 50, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, - 50, 0, 50, 50, 159, 50, 0, 0, 0, 50, 50, 0, 50, 0, 50, 50, 0, 0, 0, 50, - 50, 0, 0, 0, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 153, 145, 139, 145, 145, 0, 0, 0, 145, 145, 145, 0, - 154, 154, 154, 157, 0, 0, 50, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 155, 155, 155, 87, 87, 87, 87, 87, 87, 88, 87, 0, 0, 0, 0, 0, 139, 145, - 145, 145, 139, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, - 50, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 0, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 152, 50, 139, 139, 139, - 145, 145, 145, 145, 0, 139, 139, 160, 0, 139, 139, 139, 149, 0, 0, 0, 0, - 0, 0, 0, 161, 162, 0, 146, 146, 146, 0, 50, 50, 0, 0, 50, 50, 139, 139, - 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, - 0, 85, 163, 163, 163, 163, 163, 163, 163, 82, 50, 139, 145, 145, 85, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 152, 50, - 145, 164, 165, 145, 153, 145, 145, 0, 164, 165, 165, 0, 165, 165, 139, - 157, 0, 0, 0, 0, 0, 0, 0, 153, 153, 0, 0, 0, 0, 0, 50, 50, 50, 0, 50, 50, - 139, 139, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 50, - 50, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 139, 145, 145, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 157, 157, 50, 153, 145, 145, 139, 139, - 139, 139, 0, 145, 145, 145, 0, 154, 154, 154, 149, 166, 82, 0, 0, 0, 0, - 50, 50, 50, 153, 155, 155, 155, 155, 155, 155, 155, 50, 50, 50, 139, 139, - 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 82, 50, 50, 50, 50, 50, 50, 0, 139, 145, - 145, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 167, 0, 0, 0, - 0, 153, 145, 145, 139, 139, 139, 0, 139, 0, 145, 145, 154, 145, 154, 154, - 154, 153, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 0, 0, 145, 145, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 139, 50, 168, 139, 139, 139, 139, - 169, 169, 157, 0, 0, 0, 0, 88, 50, 50, 50, 50, 50, 50, 55, 139, 170, 170, - 170, 170, 139, 139, 139, 85, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 50, - 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 139, 50, 168, 139, 139, 139, 139, 171, 171, 157, 139, - 139, 50, 0, 0, 50, 50, 50, 50, 50, 0, 55, 0, 172, 172, 172, 172, 139, - 139, 139, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 173, - 173, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 82, 82, 82, 85, 85, 85, 85, 85, - 85, 85, 85, 174, 85, 85, 85, 85, 85, 85, 82, 85, 82, 82, 82, 89, 89, 82, - 82, 82, 82, 82, 82, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 82, 89, 82, 89, 82, - 175, 176, 177, 176, 177, 145, 145, 50, 50, 50, 156, 50, 50, 50, 50, 0, - 50, 50, 50, 50, 156, 50, 50, 50, 50, 156, 50, 50, 50, 50, 156, 50, 50, - 50, 50, 156, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 156, 50, 50, - 50, 0, 0, 0, 0, 178, 179, 180, 181, 180, 180, 182, 180, 182, 179, 179, - 179, 179, 139, 145, 179, 180, 83, 83, 157, 85, 83, 83, 50, 50, 50, 50, - 50, 139, 139, 139, 139, 139, 139, 180, 139, 139, 139, 139, 0, 139, 139, - 139, 139, 180, 139, 139, 139, 139, 180, 139, 139, 139, 139, 180, 139, - 139, 139, 139, 180, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 180, 139, 139, 139, 0, 82, 82, 82, 82, 82, 82, 82, 82, 89, 82, - 82, 82, 82, 82, 82, 0, 82, 82, 85, 85, 85, 85, 85, 82, 82, 82, 82, 85, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 147, 146, 146, 146, 146, 183, 183, 139, 158, 139, - 139, 145, 139, 139, 139, 139, 139, 152, 183, 149, 157, 145, 145, 139, - 139, 146, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 85, 85, 85, - 85, 85, 85, 146, 146, 146, 146, 146, 146, 145, 145, 139, 139, 146, 146, - 146, 146, 139, 139, 139, 146, 183, 183, 183, 146, 146, 183, 183, 183, - 183, 183, 183, 183, 146, 146, 146, 139, 139, 139, 139, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 139, 183, 145, 139, - 139, 183, 183, 183, 183, 183, 183, 89, 146, 183, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 183, 183, 183, 139, 82, 82, 46, 46, 46, 46, 46, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 37, 49, 86, 87, 77, 77, 88, 88, 89, + 90, 91, 84, 84, 84, 84, 91, 84, 84, 84, 92, 91, 84, 84, 84, 84, 84, 84, + 91, 91, 91, 91, 91, 91, 84, 84, 91, 84, 84, 92, 93, 84, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 109, 84, 91, 109, 102, 90, 90, 90, 90, 90, 90, 90, 90, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, 90, 90, 112, + 112, 112, 112, 109, 109, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 113, + 113, 113, 113, 113, 113, 81, 81, 114, 115, 115, 116, 117, 118, 88, 88, + 84, 84, 84, 84, 84, 84, 84, 84, 119, 120, 121, 118, 122, 118, 118, 118, + 123, 123, 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 125, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 126, 127, 128, 119, 120, 121, 129, 130, 131, 131, 132, 91, 84, 84, + 84, 84, 84, 91, 84, 84, 91, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 115, 134, 134, 118, 123, 123, 135, 123, 123, 123, 123, 136, 136, + 136, 136, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 124, 123, 124, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 124, 118, 123, 84, 84, 84, 84, + 84, 84, 84, 113, 88, 84, 84, 84, 84, 91, 84, 125, 125, 84, 84, 88, 91, + 84, 84, 91, 123, 123, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 123, 123, 123, 138, 138, 123, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 139, 140, 123, 141, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 84, 91, 84, + 84, 91, 84, 84, 91, 91, 91, 84, 91, 91, 84, 91, 84, 84, 84, 91, 84, 91, + 84, 91, 84, 91, 84, 84, 139, 139, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 123, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 84, 84, 84, 84, 84, 84, + 84, 91, 84, 144, 144, 88, 145, 145, 145, 144, 90, 90, 91, 146, 146, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 84, 84, 84, 84, 144, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 144, 84, 84, 84, 144, 84, 84, 84, 84, 84, 90, 90, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 90, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 91, 91, 91, + 90, 90, 109, 90, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 139, 139, 139, 139, 139, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 147, 123, 123, 123, 123, 123, 123, 123, 113, 113, 139, 139, 139, + 139, 139, 84, 84, 91, 91, 91, 84, 84, 84, 84, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 125, 84, 84, 84, 84, 84, 91, 91, + 91, 91, 91, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 113, + 91, 84, 84, 91, 84, 84, 91, 84, 84, 84, 91, 91, 91, 126, 127, 128, 84, + 84, 84, 91, 84, 84, 91, 91, 84, 84, 84, 84, 84, 142, 142, 142, 148, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 150, 149, 149, 149, 149, 149, 149, 149, 150, 149, + 149, 150, 149, 149, 149, 149, 149, 142, 148, 151, 50, 148, 148, 148, 142, + 142, 142, 142, 142, 142, 142, 142, 148, 148, 148, 148, 152, 148, 148, 50, + 84, 91, 84, 84, 142, 142, 142, 153, 153, 153, 153, 153, 153, 153, 153, + 50, 50, 142, 142, 86, 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 86, 55, 50, 50, 50, 50, 50, 50, 149, 149, 149, 149, 149, 149, 149, + 149, 50, 142, 148, 148, 77, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 50, + 50, 77, 77, 50, 50, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 77, 149, 149, 149, 149, + 149, 149, 149, 77, 149, 77, 77, 77, 149, 149, 149, 149, 77, 77, 155, 50, + 156, 148, 148, 142, 142, 142, 142, 77, 77, 148, 148, 77, 77, 157, 157, + 152, 50, 77, 77, 77, 77, 77, 77, 77, 77, 156, 77, 77, 77, 77, 153, 153, + 77, 153, 50, 50, 142, 142, 77, 77, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 149, 149, 89, 89, 158, 158, 158, 158, 158, 158, 83, 89, + 50, 86, 84, 77, 77, 142, 142, 148, 77, 50, 50, 50, 50, 50, 50, 77, 77, + 77, 77, 50, 50, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, + 77, 50, 159, 77, 50, 159, 77, 50, 50, 77, 77, 155, 77, 148, 148, 148, + 142, 142, 77, 77, 77, 77, 142, 142, 77, 77, 142, 142, 160, 77, 77, 77, + 142, 77, 77, 77, 77, 77, 77, 77, 159, 159, 159, 50, 77, 159, 77, 77, 77, + 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 142, + 142, 50, 50, 50, 142, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 142, + 142, 148, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 77, 50, + 50, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 77, 149, 149, 149, 149, 149, 149, 149, 77, + 149, 149, 77, 149, 149, 149, 149, 149, 77, 77, 155, 50, 148, 148, 148, + 142, 142, 142, 142, 142, 77, 142, 142, 148, 77, 148, 148, 152, 77, 77, + 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, + 142, 142, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 86, + 89, 77, 77, 77, 77, 77, 77, 77, 149, 142, 142, 142, 142, 142, 142, 77, + 142, 148, 148, 77, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 50, 50, 77, + 77, 50, 50, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 77, 149, 149, 149, 149, 149, 149, + 149, 77, 149, 149, 77, 149, 149, 149, 149, 149, 77, 77, 155, 50, 156, + 142, 148, 142, 142, 142, 142, 77, 77, 148, 157, 77, 77, 157, 157, 152, + 77, 77, 77, 77, 77, 77, 77, 142, 161, 156, 77, 77, 77, 77, 153, 153, 77, + 149, 50, 50, 142, 142, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 83, 149, 158, 158, 158, 158, 158, 158, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 142, 50, 77, 50, 50, 50, 50, 50, 50, 77, 77, 77, 50, 50, + 50, 77, 50, 50, 162, 50, 77, 77, 77, 50, 50, 77, 50, 77, 50, 50, 77, 77, + 77, 50, 50, 77, 77, 77, 50, 50, 50, 77, 77, 77, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 156, 148, 142, 148, 148, 77, 77, + 77, 148, 148, 148, 77, 157, 157, 157, 160, 77, 77, 50, 77, 77, 77, 77, + 77, 77, 156, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 158, 158, 158, 88, 88, 88, + 88, 88, 88, 89, 88, 77, 77, 77, 77, 77, 142, 148, 148, 148, 142, 50, 50, + 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 77, 50, 50, 50, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 77, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 77, 77, 155, 50, 142, 142, 142, 148, 148, 148, + 148, 77, 142, 142, 163, 77, 142, 142, 142, 152, 77, 77, 77, 77, 77, 77, + 77, 164, 165, 77, 149, 149, 149, 77, 50, 50, 77, 77, 50, 50, 142, 142, + 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, + 77, 77, 77, 86, 166, 166, 166, 166, 166, 166, 166, 83, 50, 142, 148, 148, + 86, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 77, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, + 77, 77, 155, 50, 148, 167, 168, 148, 156, 148, 148, 77, 167, 168, 168, + 77, 168, 168, 142, 160, 77, 77, 77, 77, 77, 77, 77, 156, 156, 77, 77, 77, + 77, 77, 50, 50, 50, 77, 50, 50, 142, 142, 77, 77, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 77, 50, 50, 148, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 142, 142, 148, 148, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 50, 50, 50, 77, 50, 50, 50, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 160, 160, 50, 156, 148, 148, 142, 142, 142, 142, 77, + 148, 148, 148, 77, 157, 157, 157, 152, 169, 83, 77, 77, 77, 77, 50, 50, + 50, 156, 158, 158, 158, 158, 158, 158, 158, 50, 50, 50, 142, 142, 77, 77, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 83, 50, 50, 50, 50, 50, 50, 77, 142, 148, 148, + 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 50, 77, 77, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 170, 77, + 77, 77, 77, 156, 148, 148, 142, 142, 142, 77, 142, 77, 148, 148, 157, + 148, 157, 157, 157, 156, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 77, 77, 148, 148, 86, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 142, 50, 171, 142, 142, 142, 142, 172, 172, 160, 77, 77, 77, 77, 89, 50, + 50, 50, 50, 50, 50, 55, 142, 173, 173, 173, 173, 142, 142, 142, 86, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 86, 86, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 77, 50, + 77, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 77, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 142, 50, 171, 142, 142, 142, 142, 174, + 174, 160, 142, 142, 50, 77, 77, 50, 50, 50, 50, 50, 77, 55, 77, 175, 175, + 175, 175, 142, 142, 142, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 77, 77, 176, 176, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 83, 83, 83, 86, 86, 86, 86, 86, 86, 86, 86, 177, 86, + 86, 86, 86, 86, 86, 83, 86, 83, 83, 83, 91, 91, 83, 83, 83, 83, 83, 83, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 83, 91, 83, 91, 83, 178, 179, 180, 179, + 180, 148, 148, 50, 50, 50, 159, 50, 50, 50, 50, 77, 50, 50, 50, 50, 159, + 50, 50, 50, 50, 159, 50, 50, 50, 50, 159, 50, 50, 50, 50, 159, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 159, 50, 50, 50, 77, 77, 77, 77, + 181, 182, 183, 184, 183, 183, 185, 183, 185, 182, 182, 182, 182, 142, + 148, 182, 183, 84, 84, 160, 86, 84, 84, 50, 50, 50, 50, 50, 142, 142, + 142, 142, 142, 142, 183, 142, 142, 142, 142, 77, 142, 142, 142, 142, 183, + 142, 142, 142, 142, 183, 142, 142, 142, 142, 183, 142, 142, 142, 142, + 183, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 183, + 142, 142, 142, 77, 83, 83, 83, 83, 83, 83, 83, 83, 91, 83, 83, 83, 83, + 83, 83, 77, 83, 83, 86, 86, 86, 86, 86, 83, 83, 83, 83, 86, 86, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 150, 149, 149, 149, 149, + 186, 186, 142, 161, 142, 142, 148, 142, 142, 142, 142, 142, 155, 186, + 152, 160, 148, 148, 142, 142, 149, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 86, 86, 86, 86, 86, 86, 149, 149, 149, 149, 149, 149, 148, + 148, 142, 142, 149, 149, 149, 149, 142, 142, 142, 149, 186, 186, 186, + 149, 149, 186, 186, 186, 186, 186, 186, 186, 149, 149, 149, 142, 142, + 142, 142, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 142, 186, 148, 142, 142, 186, 186, 186, 186, 186, 186, 91, 149, 186, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 186, 186, 186, 142, 83, + 83, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, - 0, 0, 0, 46, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 46, 46, 46, 77, 46, 77, 77, 77, 77, 77, 46, 77, 77, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 85, 53, 49, 49, 49, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 185, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 187, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 86, 53, 49, 49, 49, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 188, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 188, 188, 188, 188, 188, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 77, + 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 77, 50, 50, 50, 50, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 77, 50, 50, 50, 50, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 77, 77, 50, 50, 50, + 50, 50, 50, 50, 77, 50, 77, 50, 50, 50, 50, 77, 77, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, + 50, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 0, 83, 83, 83, 85, 85, 85, 85, 85, 85, 85, 85, 85, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 0, 0, 0, - 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, + 84, 84, 84, 86, 86, 86, 86, 86, 86, 86, 86, 86, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 77, 77, 77, 77, 77, 77, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 49, - 49, 49, 49, 49, 49, 0, 0, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 77, 77, 49, 49, + 49, 49, 49, 49, 77, 77, 87, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1757,119 +1771,122 @@ static const unsigned short index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 82, 85, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 189, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 83, 86, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 192, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 176, 177, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 179, 180, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 85, 85, 85, 190, 190, 190, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 139, 139, 157, 191, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 139, 139, 191, 85, 85, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 139, 139, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 139, 139, 145, 139, 139, 139, 139, 139, 139, 139, 145, 145, 145, 145, - 145, 145, 145, 145, 139, 145, 145, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 149, 139, 85, 85, 85, 55, 85, 85, 85, 88, 50, 83, 0, 0, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 163, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 0, 0, 0, 0, 0, 0, 142, 142, 142, - 142, 142, 142, 86, 142, 142, 142, 142, 139, 139, 139, 192, 139, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, 86, 86, 193, 193, 193, + 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 142, 142, + 160, 194, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 142, 142, 194, 86, 86, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 142, 142, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 77, 50, 50, 50, 77, 142, 142, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 142, 142, 148, 142, + 142, 142, 142, 142, 142, 142, 148, 148, 148, 148, 148, 148, 148, 148, + 142, 148, 148, 142, 142, 142, 142, 142, 142, 142, 142, 142, 152, 142, 86, + 86, 86, 55, 86, 86, 86, 89, 50, 84, 77, 77, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 77, 77, 77, 77, 77, 77, 145, 145, 145, 145, 145, 145, + 87, 145, 145, 145, 145, 142, 142, 142, 195, 142, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 139, 139, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, + 50, 50, 50, 50, 50, 142, 142, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 91, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 93, 50, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 142, 142, + 142, 148, 148, 148, 148, 142, 142, 148, 148, 148, 77, 77, 77, 77, 148, + 148, 142, 148, 148, 148, 148, 148, 148, 92, 84, 91, 77, 77, 77, 77, 88, + 77, 77, 77, 145, 145, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 139, 139, 139, 145, 145, - 145, 145, 139, 139, 145, 145, 145, 0, 0, 0, 0, 145, 145, 139, 145, 145, - 145, 145, 145, 145, 90, 83, 89, 0, 0, 0, 0, 87, 0, 0, 0, 142, 142, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 50, 50, 50, 50, + 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, + 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 158, 77, 77, + 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 155, 0, 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 83, 89, 145, 145, 139, 0, 0, 85, 85, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 145, 139, 145, 139, - 139, 139, 139, 139, 139, 139, 0, 149, 183, 139, 183, 183, 139, 139, 139, - 139, 139, 139, 139, 139, 145, 145, 145, 145, 145, 145, 139, 139, 83, 83, - 83, 83, 83, 83, 83, 83, 0, 0, 89, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 55, 85, 85, 85, 85, - 85, 85, 0, 0, 83, 83, 83, 83, 83, 89, 89, 89, 89, 89, 89, 83, 83, 89, 84, - 89, 89, 83, 83, 89, 89, 83, 83, 83, 83, 83, 89, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 89, 0, 0, 83, 83, 83, 83, - 83, 83, 89, 83, 83, 83, 83, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 139, 139, 139, 139, 145, 50, 159, 50, 159, 50, 159, - 146, 147, 50, 159, 50, 50, 50, 159, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 152, 153, - 139, 139, 139, 139, 139, 165, 139, 165, 145, 145, 154, 154, 139, 165, - 194, 146, 146, 146, 146, 146, 146, 146, 146, 0, 85, 85, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 85, 85, 85, 85, 85, 85, 85, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 83, 89, 83, 83, 83, 83, 83, 83, 83, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 85, 85, 85, 139, 139, 145, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 145, - 139, 139, 139, 139, 145, 145, 139, 139, 191, 149, 139, 139, 146, 146, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 50, 146, 146, 146, 50, + 50, 50, 50, 50, 84, 91, 148, 148, 142, 77, 77, 86, 86, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 148, 142, 148, 142, 142, 142, + 142, 142, 142, 142, 77, 152, 186, 142, 186, 186, 142, 142, 142, 142, 142, + 142, 142, 142, 148, 148, 148, 148, 148, 148, 142, 142, 84, 84, 84, 84, + 84, 84, 84, 84, 77, 77, 91, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 77, 77, 77, 77, 77, 77, 86, 86, 86, 86, 86, 86, 86, 55, 86, 86, 86, + 86, 86, 86, 77, 77, 84, 84, 84, 84, 84, 91, 91, 91, 91, 91, 91, 84, 84, + 91, 85, 91, 91, 84, 84, 91, 91, 84, 84, 84, 84, 84, 91, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 91, 77, 77, 84, + 84, 84, 84, 84, 84, 91, 84, 84, 84, 84, 196, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 142, 142, 142, 142, + 148, 50, 162, 50, 162, 50, 162, 149, 150, 50, 162, 50, 50, 50, 162, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 155, 156, 142, 142, 142, 142, 142, 168, 142, 168, + 148, 148, 157, 157, 142, 168, 197, 149, 149, 149, 149, 149, 149, 149, + 149, 77, 86, 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 86, + 86, 86, 86, 86, 86, 86, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 91, + 84, 84, 84, 84, 84, 84, 84, 83, 83, 83, 83, 83, 83, 83, 83, 83, 86, 86, + 86, 142, 142, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 148, 142, 142, 142, 142, 148, 148, 142, 142, + 194, 152, 142, 142, 149, 149, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 50, 149, 149, 149, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 155, 148, 142, 142, 148, 148, + 148, 142, 148, 142, 142, 142, 194, 194, 77, 77, 77, 77, 77, 77, 77, 77, + 86, 86, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 152, 145, 139, 139, 145, 145, 145, 139, 145, 139, 139, 139, - 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 148, 148, 148, 148, 148, 148, 148, 148, 142, 142, 142, + 142, 142, 142, 142, 142, 148, 148, 142, 155, 77, 77, 77, 86, 86, 86, 86, + 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 50, 50, + 50, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, 145, 145, 145, - 145, 145, 145, 139, 139, 139, 139, 139, 139, 139, 139, 145, 145, 139, - 152, 0, 0, 0, 85, 85, 85, 85, 85, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 0, 0, 0, 50, 50, 50, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, 55, 55, 55, - 55, 55, 85, 85, 49, 49, 49, 49, 49, 49, 49, 49, 49, 46, 49, 0, 0, 0, 0, - 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 50, 50, 50, 50, 50, 50, 50, 55, 55, 55, 55, 55, 55, 86, 86, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 46, 49, 77, 77, 77, 77, 77, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 85, 85, 85, 85, 85, 85, - 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 85, 195, 89, 89, 89, 89, 89, - 83, 83, 89, 89, 89, 89, 83, 145, 195, 195, 195, 195, 195, 195, 195, 50, - 50, 50, 50, 89, 50, 50, 50, 50, 50, 50, 83, 50, 50, 145, 83, 83, 50, 0, - 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 46, 46, 77, 77, 46, 46, 46, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, + 77, 77, 77, 77, 77, 84, 84, 84, 86, 198, 91, 91, 91, 91, 91, 84, 84, 91, + 91, 91, 91, 84, 148, 198, 198, 198, 198, 198, 198, 198, 50, 50, 50, 50, + 91, 50, 50, 50, 50, 50, 50, 84, 50, 50, 148, 84, 84, 50, 77, 77, 77, 77, + 77, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53, 53, 53, 55, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 55, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 55, 53, 53, 53, 53, 53, 53, 53, 53, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 53, 53, 53, 55, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 55, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 55, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53, 53, 53, 53, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 83, 83, 89, - 83, 83, 83, 83, 83, 83, 83, 89, 83, 83, 193, 196, 89, 197, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 198, 91, - 91, 89, 199, 83, 200, 89, 83, 89, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 84, 84, 91, 84, 84, + 84, 84, 84, 84, 84, 91, 84, 84, 196, 199, 91, 200, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 201, 93, 93, 91, + 202, 84, 203, 91, 84, 91, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, @@ -1877,341 +1894,252 @@ static const unsigned short index2[] = { 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, - 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 45, 45, 45, 45, - 37, 201, 49, 49, 46, 49, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, + 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 45, 45, 45, 45, 37, 204, + 49, 49, 46, 49, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, 40, 45, - 40, 45, 40, 45, 40, 45, 46, 49, 46, 49, 46, 49, 45, 45, 45, 45, 45, 45, - 45, 45, 40, 40, 40, 40, 40, 40, 40, 40, 45, 45, 45, 45, 45, 45, 0, 0, 40, - 40, 40, 40, 40, 40, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 40, 40, 40, 40, + 40, 45, 40, 45, 46, 49, 46, 49, 46, 49, 45, 45, 45, 45, 45, 45, 45, 45, + 40, 40, 40, 40, 40, 40, 40, 40, 45, 45, 45, 45, 45, 45, 77, 77, 40, 40, + 40, 40, 40, 40, 77, 77, 45, 45, 45, 45, 45, 45, 45, 45, 40, 40, 40, 40, 40, 40, 40, 40, 45, 45, 45, 45, 45, 45, 45, 45, 40, 40, 40, 40, 40, 40, - 40, 40, 45, 45, 45, 45, 45, 45, 0, 0, 40, 40, 40, 40, 40, 40, 0, 0, 45, - 45, 45, 45, 45, 45, 45, 45, 0, 40, 0, 40, 0, 40, 0, 40, 45, 45, 45, 45, - 45, 45, 45, 45, 40, 40, 40, 40, 40, 40, 40, 40, 45, 202, 45, 202, 45, - 202, 45, 202, 45, 202, 45, 202, 45, 202, 0, 0, 45, 45, 45, 45, 45, 45, - 45, 45, 203, 203, 203, 203, 203, 203, 203, 203, 45, 45, 45, 45, 45, 45, - 45, 45, 203, 203, 203, 203, 203, 203, 203, 203, 45, 45, 45, 45, 45, 45, - 45, 45, 203, 203, 203, 203, 203, 203, 203, 203, 45, 45, 45, 45, 45, 0, - 45, 45, 40, 40, 40, 204, 203, 60, 202, 60, 60, 78, 45, 45, 45, 0, 45, 45, - 40, 204, 40, 204, 203, 78, 78, 78, 45, 45, 45, 202, 0, 0, 45, 45, 40, 40, - 40, 204, 0, 78, 78, 78, 45, 45, 45, 202, 45, 45, 45, 45, 40, 40, 40, 204, - 40, 78, 205, 205, 0, 0, 45, 45, 45, 0, 45, 45, 40, 204, 40, 204, 203, - 205, 60, 0, 206, 206, 207, 207, 207, 207, 207, 207, 207, 207, 207, 192, - 208, 209, 210, 211, 212, 213, 86, 212, 212, 212, 24, 214, 215, 216, 217, - 218, 215, 216, 217, 218, 24, 24, 24, 142, 219, 219, 219, 24, 220, 221, - 222, 223, 224, 225, 226, 23, 227, 113, 227, 228, 229, 24, 214, 214, 142, - 30, 38, 24, 230, 142, 219, 231, 231, 142, 142, 142, 232, 176, 177, 214, - 214, 230, 142, 142, 142, 142, 142, 142, 142, 142, 80, 142, 231, 142, 142, - 214, 142, 142, 142, 142, 142, 142, 142, 207, 192, 192, 192, 192, 192, - 233, 234, 235, 236, 237, 192, 192, 192, 192, 192, 192, 238, 53, 0, 0, 36, - 238, 238, 238, 238, 238, 239, 239, 240, 241, 242, 243, 238, 36, 36, 36, - 36, 238, 238, 238, 238, 238, 239, 239, 240, 241, 242, 0, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 88, 88, 88, 88, 88, 88, 88, - 88, 244, 245, 88, 88, 25, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 83, 83, 195, 195, 83, 83, 83, 83, 195, 195, 195, 83, 83, 84, 84, - 84, 84, 83, 84, 84, 84, 195, 195, 83, 89, 83, 195, 195, 89, 89, 89, 89, - 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 246, 51, 247, 87, - 247, 246, 51, 87, 247, 37, 51, 51, 51, 37, 37, 51, 51, 51, 48, 87, 51, - 247, 87, 80, 51, 51, 51, 51, 51, 87, 87, 246, 247, 248, 87, 51, 87, 249, - 87, 51, 87, 204, 249, 51, 51, 250, 37, 51, 51, 46, 51, 37, 173, 173, 173, - 173, 251, 87, 246, 37, 37, 51, 51, 252, 80, 80, 80, 80, 51, 37, 37, 37, - 37, 87, 80, 87, 87, 49, 82, 253, 253, 253, 39, 39, 253, 253, 253, 253, - 253, 253, 39, 39, 39, 39, 253, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 190, 190, 190, 46, 49, - 190, 190, 190, 190, 39, 87, 87, 0, 0, 0, 0, 42, 42, 42, 42, 256, 32, 32, - 32, 32, 32, 257, 257, 87, 87, 87, 87, 80, 87, 87, 80, 87, 87, 80, 87, 87, - 28, 28, 87, 87, 87, 257, 87, 87, 87, 87, 87, 87, 87, 87, 87, 258, 258, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 259, 257, 257, 87, 87, 42, 87, 42, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 258, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 42, - 260, 261, 261, 262, 80, 80, 42, 261, 262, 260, 261, 262, 260, 80, 42, 80, - 261, 263, 264, 80, 261, 260, 80, 80, 80, 261, 260, 260, 261, 42, 261, - 261, 260, 260, 42, 262, 42, 262, 42, 42, 42, 42, 261, 265, 252, 261, 252, - 252, 260, 260, 260, 42, 42, 42, 42, 80, 260, 80, 260, 261, 261, 260, 260, - 260, 262, 260, 260, 262, 260, 260, 262, 261, 262, 260, 260, 261, 80, 80, - 80, 80, 80, 261, 260, 260, 260, 80, 80, 80, 80, 80, 80, 80, 80, 80, 260, - 266, 42, 262, 80, 261, 261, 261, 261, 260, 260, 261, 261, 80, 262, 266, - 266, 262, 262, 260, 260, 262, 262, 260, 260, 262, 262, 260, 260, 260, - 260, 260, 260, 262, 262, 261, 261, 262, 262, 261, 261, 262, 262, 260, - 260, 260, 80, 80, 260, 260, 260, 260, 80, 80, 42, 80, 80, 260, 42, 80, - 80, 80, 80, 80, 80, 80, 80, 260, 260, 80, 42, 260, 260, 260, 260, 260, - 260, 262, 262, 262, 262, 260, 260, 260, 260, 260, 260, 260, 260, 260, 80, - 80, 80, 80, 80, 260, 261, 80, 80, 80, 80, 80, 80, 80, 80, 80, 260, 260, - 260, 260, 260, 80, 80, 260, 260, 80, 80, 80, 80, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 262, 262, 262, 262, 260, 260, 260, 260, 260, - 260, 262, 262, 262, 262, 80, 80, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 87, 87, 87, 87, 87, 87, 87, 87, - 176, 177, 176, 177, 87, 87, 87, 87, 87, 87, 258, 87, 87, 87, 87, 87, 87, - 87, 267, 267, 87, 87, 87, 87, 260, 260, 87, 87, 87, 87, 87, 87, 28, 268, - 269, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 87, 80, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 82, - 87, 87, 87, 87, 87, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 28, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 80, 80, - 80, 80, 80, 80, 87, 87, 87, 87, 87, 87, 87, 267, 267, 267, 267, 28, 28, - 28, 267, 28, 28, 267, 87, 87, 87, 87, 28, 28, 28, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, + 40, 40, 45, 45, 45, 45, 45, 45, 77, 77, 40, 40, 40, 40, 40, 40, 77, 77, + 45, 45, 45, 45, 45, 45, 45, 45, 77, 40, 77, 40, 77, 40, 77, 40, 45, 45, + 45, 45, 45, 45, 45, 45, 40, 40, 40, 40, 40, 40, 40, 40, 45, 205, 45, 205, + 45, 205, 45, 205, 45, 205, 45, 205, 45, 205, 77, 77, 45, 45, 45, 45, 45, + 45, 45, 45, 206, 206, 206, 206, 206, 206, 206, 206, 45, 45, 45, 45, 45, + 45, 45, 45, 206, 206, 206, 206, 206, 206, 206, 206, 45, 45, 45, 45, 45, + 45, 45, 45, 206, 206, 206, 206, 206, 206, 206, 206, 45, 45, 45, 45, 45, + 77, 45, 45, 40, 40, 40, 207, 206, 60, 205, 60, 60, 79, 45, 45, 45, 77, + 45, 45, 40, 207, 40, 207, 206, 79, 79, 79, 45, 45, 45, 205, 77, 77, 45, + 45, 40, 40, 40, 207, 77, 79, 79, 79, 45, 45, 45, 205, 45, 45, 45, 45, 40, + 40, 40, 207, 40, 79, 208, 208, 77, 77, 45, 45, 45, 77, 45, 45, 40, 207, + 40, 207, 206, 208, 60, 77, 209, 209, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 195, 211, 212, 213, 214, 215, 216, 87, 215, 215, 215, 24, 217, + 218, 219, 220, 221, 218, 219, 220, 221, 24, 24, 24, 145, 222, 222, 222, + 24, 223, 224, 225, 226, 227, 228, 229, 23, 230, 115, 230, 231, 232, 24, + 217, 217, 145, 30, 38, 24, 233, 145, 222, 234, 234, 145, 145, 145, 235, + 179, 180, 217, 217, 233, 145, 145, 145, 145, 145, 145, 145, 145, 81, 145, + 234, 145, 145, 217, 145, 145, 145, 145, 145, 145, 145, 210, 195, 195, + 195, 195, 195, 236, 237, 238, 239, 240, 195, 195, 195, 195, 195, 195, + 241, 53, 77, 77, 36, 241, 241, 241, 241, 241, 242, 242, 243, 244, 245, + 246, 241, 36, 36, 36, 36, 241, 241, 241, 241, 241, 242, 242, 243, 244, + 245, 77, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 77, 77, 77, + 89, 89, 89, 89, 89, 89, 89, 89, 247, 248, 89, 89, 25, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 84, 84, 198, + 198, 84, 84, 84, 84, 198, 198, 198, 84, 84, 85, 85, 85, 85, 84, 85, 85, + 85, 198, 198, 84, 91, 84, 198, 198, 91, 91, 91, 91, 84, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 250, 250, 51, 251, 88, 251, + 250, 51, 88, 251, 37, 51, 51, 51, 37, 37, 51, 51, 51, 48, 88, 51, 251, + 88, 81, 51, 51, 51, 51, 51, 88, 88, 250, 251, 252, 88, 51, 88, 253, 88, + 51, 88, 207, 253, 51, 51, 254, 37, 51, 51, 46, 51, 37, 176, 176, 176, + 176, 255, 88, 250, 37, 37, 51, 51, 256, 81, 81, 81, 81, 51, 37, 37, 37, + 37, 88, 81, 88, 88, 49, 83, 257, 257, 257, 39, 39, 257, 257, 257, 257, + 257, 257, 39, 39, 39, 39, 257, 258, 258, 258, 258, 258, 258, 258, 258, + 258, 258, 258, 258, 259, 259, 259, 259, 258, 258, 258, 258, 258, 258, + 258, 258, 258, 258, 259, 259, 259, 259, 259, 259, 193, 193, 193, 46, 49, + 193, 193, 193, 193, 39, 88, 88, 77, 77, 77, 77, 42, 42, 42, 42, 260, 32, + 32, 32, 32, 32, 261, 261, 88, 88, 88, 88, 81, 88, 88, 81, 88, 88, 81, 88, + 88, 28, 28, 88, 88, 88, 261, 88, 88, 88, 88, 88, 88, 88, 88, 88, 262, + 262, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 263, 261, 261, 88, 88, 42, 88, 42, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 262, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 42, 264, 265, 265, 266, 81, 81, 42, 265, 266, 264, 265, 266, 264, 81, 42, + 81, 265, 267, 268, 81, 265, 264, 81, 81, 81, 265, 264, 264, 265, 42, 265, + 265, 264, 264, 42, 266, 42, 266, 42, 42, 42, 42, 265, 269, 256, 265, 256, + 256, 264, 264, 264, 42, 42, 42, 42, 81, 264, 81, 264, 265, 265, 264, 264, + 264, 266, 264, 264, 266, 264, 264, 266, 265, 266, 264, 264, 265, 81, 81, + 81, 81, 81, 265, 264, 264, 264, 81, 81, 81, 81, 81, 81, 81, 81, 81, 264, + 270, 42, 266, 81, 265, 265, 265, 265, 264, 264, 265, 265, 81, 266, 270, + 270, 266, 266, 264, 264, 266, 266, 264, 264, 266, 266, 264, 264, 264, + 264, 264, 264, 266, 266, 265, 265, 266, 266, 265, 265, 266, 266, 264, + 264, 264, 81, 81, 264, 264, 264, 264, 81, 81, 42, 81, 81, 264, 42, 81, + 81, 81, 81, 81, 81, 81, 81, 264, 264, 81, 42, 264, 264, 264, 264, 264, + 264, 266, 266, 266, 266, 264, 264, 264, 264, 264, 264, 264, 264, 264, 81, + 81, 81, 81, 81, 264, 265, 81, 81, 81, 81, 81, 81, 81, 81, 81, 264, 264, + 264, 264, 264, 81, 81, 264, 264, 81, 81, 81, 81, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 266, 266, 266, 266, 264, 264, 264, 264, 264, + 264, 266, 266, 266, 266, 81, 81, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 88, 88, 88, 88, 88, 88, 88, 88, + 179, 180, 179, 180, 88, 88, 88, 88, 88, 88, 262, 88, 88, 88, 88, 88, 88, + 88, 271, 271, 88, 88, 88, 88, 264, 264, 88, 88, 88, 88, 88, 88, 28, 272, + 273, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 88, 81, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 83, + 88, 88, 88, 88, 88, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 28, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 81, 81, + 81, 81, 81, 81, 88, 88, 88, 88, 88, 88, 88, 271, 271, 271, 271, 28, 28, + 28, 271, 28, 28, 271, 88, 88, 88, 88, 28, 28, 28, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 271, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 253, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 87, 87, 87, 87, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 258, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 258, - 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 87, 87, 258, 258, 258, 258, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 258, 258, 87, 258, 258, 258, 258, 258, 258, 258, 28, 28, 87, 87, 87, 87, - 87, 87, 258, 258, 87, 87, 32, 42, 87, 87, 87, 87, 258, 258, 87, 87, 32, - 42, 87, 87, 87, 87, 258, 258, 258, 87, 87, 258, 87, 87, 258, 258, 258, - 258, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 258, - 258, 258, 258, 87, 87, 87, 87, 87, 87, 87, 87, 87, 258, 87, 87, 87, 87, - 87, 87, 87, 87, 80, 80, 80, 273, 273, 274, 274, 80, 28, 28, 28, 28, 28, - 258, 258, 87, 87, 258, 87, 87, 87, 87, 32, 258, 87, 28, 87, 87, 267, 267, - 87, 87, 28, 87, 87, 87, 258, 28, 258, 87, 28, 87, 28, 28, 87, 87, 28, 87, - 87, 87, 28, 87, 87, 87, 28, 28, 275, 275, 275, 275, 275, 275, 275, 275, - 28, 28, 28, 87, 87, 87, 87, 87, 32, 87, 32, 87, 87, 87, 87, 87, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 28, 32, 258, 87, 32, 258, 32, 28, 258, 32, 258, 258, - 87, 258, 258, 87, 42, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 28, 87, - 87, 28, 267, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 275, 275, 275, 275, - 275, 275, 87, 87, 28, 267, 28, 28, 28, 28, 87, 28, 87, 28, 28, 87, 258, - 258, 28, 267, 87, 87, 87, 87, 87, 28, 87, 87, 267, 267, 82, 87, 87, 87, - 28, 28, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 267, 267, 258, 87, - 87, 87, 87, 267, 267, 258, 258, 32, 258, 258, 258, 258, 258, 267, 32, - 258, 32, 258, 32, 267, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 258, 87, 258, 87, 87, 87, 87, 258, 32, 267, 258, 258, 258, 258, - 258, 32, 32, 267, 267, 32, 267, 258, 32, 32, 32, 267, 258, 258, 267, 258, - 258, 87, 87, 28, 87, 87, 267, 87, 87, 28, 28, 267, 267, 28, 28, 87, 28, - 87, 87, 28, 87, 28, 87, 28, 87, 87, 87, 87, 87, 87, 28, 87, 87, 87, 28, - 87, 87, 87, 87, 87, 87, 267, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 28, - 28, 87, 87, 87, 87, 87, 87, 87, 87, 258, 87, 87, 87, 87, 87, 87, 28, 87, - 87, 28, 87, 87, 87, 87, 267, 87, 267, 87, 87, 87, 87, 267, 267, 267, 87, - 267, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 28, 28, 87, 87, 87, 176, - 177, 176, 177, 176, 177, 176, 177, 176, 177, 176, 177, 176, 177, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 163, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 87, 267, 267, 267, 87, 87, 87, 87, 87, 87, 87, 87, 87, 28, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 267, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 267, 260, 80, 80, 260, 260, 176, 177, - 80, 260, 260, 80, 260, 260, 260, 80, 80, 80, 80, 80, 260, 260, 260, 260, - 80, 80, 80, 80, 80, 260, 260, 260, 80, 80, 80, 260, 260, 260, 260, 11, - 12, 11, 12, 11, 12, 11, 12, 176, 177, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 273, 273, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 176, 177, 11, 12, - 176, 177, 176, 177, 176, 177, 176, 177, 176, 177, 176, 177, 176, 177, - 176, 177, 176, 177, 80, 80, 260, 260, 260, 260, 260, 260, 80, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 80, 80, 80, - 80, 80, 80, 80, 80, 260, 80, 80, 80, 80, 80, 80, 80, 260, 260, 260, 260, - 260, 260, 80, 80, 80, 260, 80, 80, 80, 80, 260, 260, 260, 260, 260, 80, - 260, 260, 80, 80, 176, 177, 176, 177, 260, 80, 80, 80, 80, 260, 80, 260, - 260, 260, 80, 80, 260, 260, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 260, - 260, 260, 260, 260, 260, 80, 80, 176, 177, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 260, 260, 252, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 80, 260, 260, 260, 260, 80, - 80, 260, 80, 260, 80, 80, 260, 80, 260, 260, 260, 260, 80, 80, 80, 80, - 80, 260, 260, 80, 80, 80, 80, 80, 80, 260, 260, 260, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 260, 260, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 260, 260, 80, - 80, 80, 80, 260, 260, 260, 260, 80, 260, 260, 80, 80, 260, 252, 240, 240, - 80, 80, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 80, 80, 260, 260, 260, 260, 260, 260, 260, 260, 80, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 80, 80, 80, 80, 80, - 276, 80, 260, 80, 80, 80, 260, 260, 260, 260, 260, 80, 80, 80, 80, 80, - 260, 260, 260, 80, 80, 80, 80, 260, 80, 80, 80, 260, 260, 260, 260, 260, - 80, 260, 80, 80, 87, 87, 87, 87, 87, 28, 28, 28, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 267, 267, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 87, 87, 80, 80, 80, 80, 80, 80, 87, 87, 87, 267, 87, 87, 87, 87, 267, - 258, 258, 258, 258, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 0, 0, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 277, 87, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 275, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 257, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 88, 88, 88, 88, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 88, 88, 262, 262, 262, + 262, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 262, 262, 88, 262, 262, 262, + 262, 262, 262, 262, 28, 28, 88, 88, 88, 88, 88, 88, 262, 262, 88, 88, 32, + 42, 88, 88, 88, 88, 262, 262, 88, 88, 32, 42, 88, 88, 88, 88, 262, 262, + 262, 88, 88, 262, 88, 88, 262, 262, 262, 262, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 262, 262, 262, 262, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 262, 88, 88, 88, 88, 88, 88, 88, 88, 81, 81, 81, 277, + 277, 278, 278, 81, 28, 28, 28, 28, 28, 262, 262, 88, 88, 262, 88, 88, 88, + 88, 32, 262, 88, 28, 88, 88, 271, 271, 88, 88, 28, 88, 88, 88, 262, 28, + 262, 88, 28, 88, 28, 28, 88, 88, 28, 88, 88, 88, 28, 88, 88, 88, 28, 28, + 279, 279, 279, 279, 279, 279, 279, 279, 28, 28, 28, 88, 88, 88, 88, 88, + 32, 88, 32, 88, 88, 88, 88, 88, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 32, + 262, 88, 32, 262, 32, 28, 262, 32, 262, 262, 88, 262, 262, 88, 42, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 88, 88, 28, 271, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 279, 279, 279, 279, 279, 279, 88, 88, 28, + 271, 28, 28, 28, 28, 88, 28, 88, 28, 28, 88, 262, 262, 28, 271, 88, 88, + 88, 88, 88, 28, 88, 88, 271, 271, 83, 88, 88, 88, 28, 28, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 271, 271, 262, 88, 88, 88, 88, 271, 271, 262, + 262, 32, 262, 262, 262, 262, 262, 271, 32, 262, 32, 262, 32, 271, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 88, 262, 88, + 88, 88, 88, 262, 32, 271, 262, 262, 262, 262, 262, 32, 32, 271, 271, 32, + 271, 262, 32, 32, 32, 271, 262, 262, 271, 262, 262, 88, 88, 28, 88, 88, + 271, 88, 88, 28, 28, 271, 271, 28, 28, 88, 28, 88, 88, 28, 88, 28, 88, + 28, 88, 88, 88, 88, 88, 88, 28, 88, 88, 88, 28, 88, 88, 88, 88, 88, 88, + 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 28, 88, 88, 88, 88, 88, + 88, 88, 88, 262, 88, 88, 88, 88, 88, 88, 28, 88, 88, 28, 88, 88, 88, 88, + 271, 88, 271, 88, 88, 88, 88, 271, 271, 271, 88, 271, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 28, 28, 88, 88, 88, 179, 180, 179, 180, 179, 180, + 179, 180, 179, 180, 179, 180, 179, 180, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 88, 271, 271, 271, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 28, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 271, 264, 81, 81, 264, 264, 179, 180, 81, 264, 264, 81, 264, 264, + 264, 81, 81, 81, 81, 81, 264, 264, 264, 264, 81, 81, 81, 81, 81, 264, + 264, 264, 81, 81, 81, 264, 264, 264, 264, 11, 12, 11, 12, 11, 12, 11, 12, + 179, 180, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 277, 277, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 179, 180, 11, 12, 179, 180, 179, 180, 179, + 180, 179, 180, 179, 180, 179, 180, 179, 180, 179, 180, 179, 180, 81, 81, + 264, 264, 264, 264, 264, 264, 81, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 81, 81, 81, 81, 81, 81, 81, 81, 264, 81, + 81, 81, 81, 81, 81, 81, 264, 264, 264, 264, 264, 264, 81, 81, 81, 264, + 81, 81, 81, 81, 264, 264, 264, 264, 264, 81, 264, 264, 81, 81, 179, 180, + 179, 180, 264, 81, 81, 81, 81, 264, 81, 264, 264, 264, 81, 81, 264, 264, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 264, 264, 264, 264, 264, 264, 81, + 81, 179, 180, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 264, 264, + 256, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 81, 264, 264, 264, 264, 81, 81, 264, 81, 264, 81, 81, 264, + 81, 264, 264, 264, 264, 81, 81, 81, 81, 81, 264, 264, 81, 81, 81, 81, 81, + 81, 264, 264, 264, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 264, 264, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 264, 264, 81, 81, 81, 81, 264, 264, 264, 264, 81, + 264, 264, 81, 81, 264, 256, 243, 243, 81, 81, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 81, 81, 264, 264, 264, + 264, 264, 264, 264, 264, 81, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 81, 81, 81, 81, 81, 280, 81, 264, 81, 81, 81, 264, 264, + 264, 264, 264, 81, 81, 81, 81, 81, 264, 264, 264, 81, 81, 81, 81, 264, + 81, 81, 81, 264, 264, 264, 264, 264, 81, 264, 81, 81, 88, 88, 88, 88, 88, + 28, 28, 28, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 271, 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 88, 88, 81, 81, 81, 81, 81, 81, + 88, 88, 88, 271, 88, 88, 88, 88, 271, 262, 262, 262, 262, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 281, 88, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 46, 49, 46, 46, - 46, 49, 49, 46, 49, 46, 49, 46, 49, 46, 46, 46, 46, 49, 46, 49, 49, 46, - 49, 49, 49, 49, 49, 49, 53, 53, 46, 46, 46, 49, 46, 49, 46, 49, 46, 49, - 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 46, 49, 46, 46, 46, 49, 49, 46, 49, 46, 49, 46, + 49, 46, 46, 46, 46, 49, 46, 49, 49, 46, 49, 49, 49, 49, 49, 49, 53, 53, + 46, 46, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, - 46, 49, 49, 87, 87, 87, 87, 87, 87, 46, 49, 46, 49, 83, 83, 83, 46, 49, - 0, 0, 0, 0, 0, 142, 142, 142, 142, 163, 142, 142, 49, 49, 49, 49, 49, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 49, 88, 88, 88, 88, 88, + 88, 46, 49, 46, 49, 84, 84, 84, 46, 49, 77, 77, 77, 77, 77, 145, 145, + 145, 145, 166, 145, 145, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 0, 0, 0, - 0, 0, 49, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 53, 85, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 157, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, - 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 50, 50, 50, 0, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 142, 142, 30, 38, 30, 38, 142, 142, 142, 30, 38, 142, 30, 38, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 86, 142, 142, 86, 142, 30, - 38, 142, 142, 30, 38, 176, 177, 176, 177, 176, 177, 176, 177, 142, 142, - 142, 142, 142, 54, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 86, - 86, 142, 142, 142, 142, 86, 142, 217, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 87, 87, 142, 142, 142, 176, 177, 176, 177, - 176, 177, 176, 177, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 0, 275, 275, 275, 275, 278, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 278, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 279, 280, - 280, 280, 275, 281, 282, 283, 284, 285, 284, 285, 284, 285, 284, 285, - 284, 285, 275, 275, 284, 285, 284, 285, 284, 285, 284, 285, 286, 287, - 288, 288, 275, 283, 283, 283, 283, 283, 283, 283, 283, 283, 289, 290, - 291, 292, 293, 293, 294, 281, 281, 281, 281, 281, 278, 275, 295, 295, - 295, 281, 282, 296, 275, 87, 0, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, 297, - 282, 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, 282, - 297, 282, 297, 282, 297, 282, 282, 282, 282, 282, 282, 297, 297, 282, - 297, 297, 282, 297, 297, 282, 297, 297, 282, 297, 297, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 297, 282, 282, 0, 0, 298, 298, 299, 299, 281, - 300, 301, 286, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, - 297, 282, 297, 282, 297, 282, 297, 282, 297, 282, 282, 297, 282, 297, - 282, 297, 282, 282, 282, 282, 282, 282, 297, 297, 282, 297, 297, 282, - 297, 297, 282, 297, 297, 282, 297, 297, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 297, 282, 282, 297, 297, 297, 297, 280, 281, 281, 300, 301, 0, - 0, 0, 0, 0, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 0, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 0, 302, - 302, 303, 303, 303, 303, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 278, 278, 0, 303, 303, - 303, 303, 303, 303, 303, 303, 303, 303, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 305, 305, 305, 305, - 305, 305, 305, 305, 278, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 278, 278, 278, 302, 303, 303, 303, 303, - 303, 303, 303, 303, 303, 303, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 307, 304, 307, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 278, 278, 278, 278, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 278, 278, 278, 278, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 278, 278, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 278, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 49, 49, 49, 49, 49, 49, 49, 49, 77, 49, 77, 77, 77, 77, 77, 49, 77, 77, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 77, 77, 77, 77, 77, 77, 53, 86, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 160, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, + 50, 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 77, + 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, + 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 77, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 145, 145, 30, 38, 30, 38, 145, + 145, 145, 30, 38, 145, 30, 38, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 87, 145, 145, 87, 145, 30, 38, 145, 145, 30, 38, 179, 180, 179, 180, + 179, 180, 179, 180, 145, 145, 145, 145, 145, 54, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 87, 87, 145, 145, 145, 145, 87, 145, 220, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 88, 88, 145, + 145, 145, 179, 180, 179, 180, 179, 180, 179, 180, 87, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 77, 279, 279, 279, 279, 282, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 282, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, @@ -2222,991 +2150,1159 @@ static const unsigned short index2[] = { 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 281, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 0, 0, 0, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 55, 55, 55, 55, 55, 55, 85, 85, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 55, 142, 142, 142, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 50, 83, 84, 84, 84, 142, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 142, 54, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 53, 53, 83, 83, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 83, 83, 85, - 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 56, 56, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 49, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 53, 49, 49, - 49, 49, 49, 49, 49, 49, 46, 49, 46, 49, 46, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 54, 308, 308, 46, 49, 46, 49, 50, 46, 49, 46, 49, 49, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 46, 46, 46, 46, 49, 46, 46, 46, 46, 46, 49, 46, 49, 46, 49, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 46, 46, 46, 49, 46, 49, 46, 46, - 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53, 53, 46, - 49, 50, 53, 53, 49, 50, 50, 50, 50, 50, 50, 50, 139, 50, 50, 50, 157, 50, - 50, 50, 50, 139, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, 139, 139, 145, 87, 87, 87, - 87, 157, 0, 0, 0, 155, 155, 155, 155, 155, 155, 82, 82, 88, 250, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 157, 139, 0, 0, 0, 0, 0, 0, - 0, 0, 85, 85, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, - 0, 0, 0, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 50, 50, 50, 50, 50, 50, 85, 85, 85, 50, 85, 50, 50, 139, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 139, 139, 139, 139, 139, 89, 89, 89, 85, 85, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 145, 191, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 0, 0, 0, 139, 139, 139, 145, 50, 50, - 50, 50, 50, 146, 146, 146, 50, 50, 50, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 152, 145, 145, 139, 139, 139, 139, 145, 145, 139, 139, 145, 145, - 194, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 55, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 85, 85, 146, 146, - 146, 146, 146, 139, 55, 146, 146, 146, 146, 146, 146, 146, 146, 146, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 146, 146, 146, 146, 146, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 139, 139, 139, 139, 139, 139, 145, 145, 139, 139, - 145, 145, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 139, 50, 50, - 50, 50, 50, 50, 50, 50, 139, 145, 0, 0, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 0, 0, 85, 85, 85, 85, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 55, 146, 146, 146, 50, - 50, 50, 82, 82, 82, 146, 183, 139, 183, 146, 146, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 83, 50, 83, 83, 89, 50, 50, 83, 83, 50, 50, 50, - 50, 50, 83, 83, 50, 83, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 55, 85, 85, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 145, 139, 139, 145, 145, 85, 85, 50, 55, - 55, 145, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 308, 53, 53, 53, 53, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 53, 56, 56, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 50, 50, 50, - 50, 50, 50, 50, 50, 145, 145, 139, 145, 145, 139, 145, 145, 85, 145, 157, - 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 283, 284, 284, 284, 279, 285, 286, 287, 288, 289, 288, + 289, 288, 289, 288, 289, 288, 289, 279, 279, 288, 289, 288, 289, 288, + 289, 288, 289, 290, 291, 292, 292, 279, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 293, 294, 295, 296, 297, 297, 298, 285, 285, 285, 285, + 285, 282, 279, 299, 299, 299, 285, 286, 300, 279, 88, 77, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 301, 286, 301, 286, 301, 286, + 301, 286, 301, 286, 301, 286, 301, 286, 301, 286, 301, 286, 301, 286, + 301, 286, 301, 286, 286, 301, 286, 301, 286, 301, 286, 286, 286, 286, + 286, 286, 301, 301, 286, 301, 301, 286, 301, 301, 286, 301, 301, 286, + 301, 301, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 301, 286, 286, 77, 77, + 302, 302, 303, 303, 285, 304, 305, 290, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 301, 286, 301, 286, 301, 286, 301, 286, 301, + 286, 301, 286, 301, 286, 301, 286, 301, 286, 301, 286, 301, 286, 301, + 286, 286, 301, 286, 301, 286, 301, 286, 286, 286, 286, 286, 286, 301, + 301, 286, 301, 301, 286, 301, 301, 286, 301, 301, 286, 301, 301, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 301, 286, 286, 301, 301, 301, 301, + 284, 285, 285, 304, 305, 77, 77, 77, 77, 77, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 77, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 77, 306, 306, 307, 307, 307, 307, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 279, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 282, 282, 77, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 309, 309, 309, 309, 309, 309, 309, 309, 282, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 309, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 309, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 0, 0, 0, 0, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 0, 0, 0, 0, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 282, 282, - 313, 282, 313, 282, 282, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 282, 313, 282, 313, 282, 282, 313, 313, 282, 282, 282, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 37, 37, 37, 37, 37, 0, 0, 0, 0, 0, 315, 316, 315, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 239, 315, 315, 315, 315, 315, 315, 315, 315, - 315, 315, 315, 315, 315, 0, 315, 315, 315, 315, 315, 0, 315, 0, 315, 315, - 0, 315, 315, 0, 315, 315, 315, 315, 315, 315, 315, 315, 315, 317, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 318, 217, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 87, 87, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 87, 87, 87, 87, 87, 87, 87, 87, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 319, 87, - 87, 87, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 320, 320, 320, 320, 320, 320, 320, 321, 322, 320, 0, 0, 0, 0, 0, 0, 83, - 83, 83, 83, 83, 83, 83, 89, 89, 89, 89, 89, 89, 89, 83, 83, 320, 323, - 323, 324, 324, 321, 322, 321, 322, 321, 322, 321, 322, 321, 322, 321, - 322, 321, 322, 321, 322, 280, 280, 321, 322, 320, 320, 320, 320, 324, - 324, 324, 325, 320, 325, 0, 320, 325, 320, 320, 323, 326, 327, 326, 327, - 326, 327, 328, 320, 320, 329, 330, 331, 331, 332, 0, 320, 333, 328, 320, - 0, 0, 0, 0, 134, 134, 134, 121, 134, 0, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 0, 0, 192, 0, 334, 334, 335, 336, 335, 334, 334, 337, 338, - 334, 339, 340, 341, 340, 340, 342, 342, 342, 342, 342, 342, 342, 342, - 342, 342, 340, 334, 343, 344, 343, 334, 334, 345, 345, 345, 345, 345, - 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, - 345, 345, 345, 345, 345, 345, 345, 337, 334, 338, 346, 347, 346, 348, - 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 337, 344, 338, - 344, 337, 338, 349, 350, 351, 349, 349, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 352, 353, 352, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 354, 354, 352, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 0, 0, 0, - 352, 352, 352, 352, 352, 352, 0, 0, 352, 352, 352, 352, 352, 352, 0, 0, - 352, 352, 352, 352, 352, 352, 0, 0, 352, 352, 352, 0, 0, 0, 336, 336, - 344, 346, 355, 336, 336, 0, 356, 357, 357, 357, 357, 356, 356, 0, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 358, 358, 358, 87, 258, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 85, 142, 85, 0, 0, 0, 0, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 0, 0, 0, 82, 82, 82, 82, 82, 82, 82, 82, 82, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, - 359, 359, 359, 359, 359, 359, 359, 163, 163, 163, 163, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 163, 163, 87, 82, 82, - 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 0, 0, 0, 87, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 155, 155, 155, - 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 190, 50, 50, 50, 50, 50, 50, 50, - 50, 190, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 85, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 85, 190, 190, 190, 190, 190, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, - 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, - 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 159, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 159, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 53, 53, 53, 53, 53, 0, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 0, 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, - 110, 0, 0, 110, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 0, 110, 110, 0, 0, 0, 110, 0, 0, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 0, 107, 361, 361, 361, 361, 361, 361, 361, - 361, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 362, 362, 361, 361, - 361, 361, 361, 361, 361, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 0, 0, 0, 0, 0, 0, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 110, 110, 0, 0, - 0, 0, 0, 361, 361, 361, 361, 361, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 361, 361, 361, 361, 361, 361, 0, 0, 0, 142, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 0, 0, 0, 0, 0, 107, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 0, 0, 0, 0, 361, 361, 110, 110, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 0, 0, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, - 363, 139, 139, 139, 0, 139, 139, 0, 0, 0, 0, 0, 139, 89, 139, 83, 363, - 363, 363, 363, 0, 363, 363, 363, 0, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 0, 0, 83, 195, 89, 0, 0, 0, 0, - 149, 361, 361, 361, 361, 361, 361, 361, 361, 361, 0, 0, 0, 0, 0, 0, 0, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 361, 361, 107, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 361, 361, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, - 110, 110, 110, 110, 110, 362, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 83, 89, 0, 0, 0, 0, 361, 361, 361, 361, - 361, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 0, 142, 142, - 142, 142, 142, 142, 142, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, - 361, 361, 361, 361, 361, 361, 361, 361, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 0, - 0, 0, 361, 361, 361, 361, 361, 361, 361, 361, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 0, - 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, - 361, 361, 361, 361, 361, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 0, 0, 0, - 0, 0, 0, 0, 361, 361, 361, 361, 361, 361, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 110, 110, 110, 110, 141, 110, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 0, 0, 0, 83, 83, 83, 83, 83, 86, 141, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 0, 0, 0, 0, 0, 0, 0, 0, 366, 366, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 0, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 83, 83, 105, 0, 0, - 110, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 121, 121, - 123, 121, 121, 0, 0, 0, 0, 0, 0, 0, 0, 142, 87, 87, 87, 87, 87, 87, 87, - 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 89, 139, 89, 89, 89, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 361, 361, - 361, 361, 361, 361, 361, 361, 361, 361, 110, 0, 0, 0, 0, 0, 0, 0, 0, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 89, 89, 83, 83, 83, 89, 83, 89, 89, - 89, 89, 368, 368, 368, 368, 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 83, 89, - 83, 89, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 361, 361, 361, 361, 361, 361, 361, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 139, 145, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 157, 85, 85, - 85, 85, 85, 85, 85, 0, 0, 0, 0, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 157, 50, 50, 139, 139, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 157, 139, 139, 145, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 159, 50, 159, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 159, 50, 50, 50, - 50, 145, 145, 145, 139, 139, 139, 139, 145, 145, 157, 148, 85, 85, 369, - 85, 85, 85, 85, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 0, 0, 0, 0, 0, 0, 83, 83, 83, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 158, 139, 139, 139, 139, 145, 139, 160, 160, 139, 139, - 139, 149, 157, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 85, - 85, 85, 85, 146, 145, 145, 146, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 282, 282, 282, 306, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 311, + 308, 311, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 310, 310, 310, + 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 282, 282, 282, 282, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 282, + 282, 282, 282, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 282, 282, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 282, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 285, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 77, 77, 77, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, 55, 55, + 55, 55, 55, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, + 145, 145, 145, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 50, 50, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 50, 84, 85, 85, 85, 145, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 145, 54, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 53, 53, 84, 84, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 152, 85, 85, 50, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 139, 145, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 145, 145, 145, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 145, 191, 50, 166, 166, 50, 85, 85, 85, 85, 139, 152, 139, 139, 85, - 145, 139, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 50, 85, 50, - 85, 85, 85, 0, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, 145, 139, 139, 139, 145, - 145, 139, 191, 152, 139, 85, 85, 85, 85, 85, 85, 139, 50, 50, 139, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, - 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 85, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 84, 84, + 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 54, 54, 54, 54, 54, 54, 54, 54, 54, 56, 56, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 49, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 53, 49, 49, 49, 49, 49, 49, 49, 49, 46, 49, 46, 49, 46, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 54, 312, 312, 46, 49, 46, 49, 50, 46, 49, 46, 49, + 49, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 46, 46, 46, 46, 49, 46, 46, 46, 46, 46, 49, 46, 49, + 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 46, 46, 46, 49, 46, + 49, 46, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, 46, 49, + 46, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 53, 53, 53, 53, 46, 49, 50, 53, 53, 49, 50, 50, 50, 50, 50, + 50, 50, 142, 50, 50, 50, 160, 50, 50, 50, 50, 142, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 148, 148, 142, 142, 148, 88, 88, 88, 88, 160, 77, 77, 77, 158, 158, 158, + 158, 158, 158, 83, 83, 89, 254, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 139, 145, 145, 145, 139, 139, - 139, 139, 139, 139, 152, 157, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 139, 139, 145, 145, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 0, 152, 152, 50, - 153, 145, 139, 145, 145, 145, 145, 0, 0, 145, 145, 0, 0, 154, 154, 191, - 0, 0, 50, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 145, - 145, 0, 0, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 83, 83, 83, 83, 83, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 147, 146, 147, 146, 146, 146, - 146, 0, 146, 0, 0, 147, 0, 146, 147, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 0, 50, 153, 145, 145, 158, 139, 139, 139, 139, 139, 0, 153, 0, 0, - 370, 0, 370, 370, 153, 145, 0, 145, 145, 157, 191, 149, 166, 139, 50, 85, - 85, 0, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, 145, 145, 77, + 77, 77, 77, 77, 77, 77, 77, 148, 148, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, - 145, 139, 139, 139, 139, 139, 139, 139, 139, 145, 145, 157, 139, 139, - 145, 152, 50, 50, 50, 50, 85, 85, 85, 85, 85, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 85, 85, 0, 85, 83, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 160, 142, 77, 77, 77, 77, 77, 77, 77, 77, + 86, 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, + 77, 77, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 50, 50, 50, 50, 50, 50, 86, 86, 86, 50, 86, 50, 50, 142, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 153, 145, 145, 139, 139, - 139, 139, 139, 139, 145, 158, 154, 154, 153, 154, 139, 139, 145, 157, - 152, 50, 50, 85, 50, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 153, 145, 145, 139, 139, 139, 139, 0, - 0, 145, 145, 154, 154, 139, 139, 145, 157, 152, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 50, - 50, 50, 50, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 145, 145, 145, 139, 139, 139, 139, 139, 139, - 139, 139, 145, 145, 139, 145, 157, 139, 85, 85, 85, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, - 0, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 139, 145, 139, 145, 145, 139, 139, 139, 139, 139, 139, 191, - 152, 50, 85, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 139, 145, 139, 183, 183, 139, 139, 139, - 139, 145, 139, 139, 139, 139, 157, 0, 0, 0, 0, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 155, 155, 85, 85, 85, 82, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 142, 142, 142, 142, 142, 91, 91, 91, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, - 145, 139, 139, 139, 139, 139, 139, 139, 139, 139, 145, 157, 152, 85, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, + 50, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 148, 194, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 86, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 77, 77, 77, 142, 142, 142, + 148, 50, 50, 50, 50, 50, 149, 149, 149, 50, 50, 50, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 155, 148, 148, 142, 142, 142, 142, 148, 148, 142, + 142, 148, 148, 197, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 77, 55, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, + 86, 86, 149, 149, 149, 149, 149, 142, 55, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 149, + 149, 149, 149, 149, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 142, 142, 142, 142, 142, 142, + 148, 148, 142, 142, 148, 148, 142, 142, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 50, 50, 50, 142, 50, 50, 50, 50, 50, 50, 50, 50, 142, 148, 77, 77, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 86, 86, 86, 86, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 55, 149, 149, 149, 50, 50, 50, 83, 83, 83, 149, 186, 142, 186, + 149, 149, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 84, 50, 84, 84, + 91, 50, 50, 84, 84, 50, 50, 50, 50, 50, 84, 84, 50, 84, 50, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 50, 50, 55, 86, 86, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 148, 142, 142, 148, 148, 86, 86, 50, 55, 55, 148, 152, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 77, 77, 50, + 50, 50, 50, 50, 50, 77, 77, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, + 50, 77, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 155, 155, 155, 155, 155, 155, 155, 155, 155, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 146, 146, 146, 146, 146, 146, 146, - 0, 0, 146, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 0, 146, 146, 0, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 153, 145, 145, 145, - 145, 145, 0, 145, 154, 0, 0, 139, 139, 191, 149, 166, 145, 166, 145, 152, - 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, - 145, 139, 139, 139, 139, 0, 0, 139, 139, 145, 145, 145, 145, 157, 50, 85, - 50, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 146, 139, 139, 139, 139, 139, 139, 164, 164, 139, 139, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 139, 157, - 139, 139, 139, 139, 145, 50, 139, 139, 139, 139, 85, 85, 85, 85, 85, 85, - 85, 85, 149, 0, 0, 0, 0, 0, 0, 0, 0, 146, 139, 139, 139, 139, 139, 139, - 145, 145, 139, 139, 139, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 166, 166, 166, 166, 166, 166, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 145, 139, 149, 85, 85, 85, 50, - 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 139, 145, 139, 139, 139, 145, 139, 145, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 139, 139, 139, 139, 139, - 139, 139, 0, 139, 139, 139, 139, 139, 139, 145, 371, 50, 85, 85, 85, 85, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 0, 0, 0, 85, 85, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, - 145, 139, 139, 139, 139, 139, 139, 139, 145, 139, 139, 145, 139, 139, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 139, 139, 139, 139, 139, - 139, 0, 0, 0, 139, 0, 139, 139, 0, 139, 139, 139, 152, 139, 157, 157, - 166, 139, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 145, 145, 145, 145, 145, - 0, 139, 139, 0, 145, 145, 139, 145, 157, 50, 0, 0, 0, 0, 0, 0, 0, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 55, 50, 50, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 139, 139, 145, 145, 85, 85, 0, 0, 0, 0, 0, 0, 0, 139, 139, - 166, 145, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 145, 145, 139, 139, 139, 139, 139, 0, - 0, 0, 145, 145, 139, 191, 149, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 139, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 87, 87, 87, 87, 87, 87, 87, 87, - 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 0, 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 139, 50, 50, - 50, 50, 50, 50, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 158, 158, 158, 372, 372, 372, 372, 372, 372, - 372, 372, 158, 145, 145, 145, 139, 139, 157, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 0, 0, 0, 0, 85, 85, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 312, 53, 53, 53, 53, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 53, 56, 56, 77, 77, 77, 77, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 50, + 50, 50, 50, 50, 50, 50, 50, 148, 148, 142, 148, 148, 142, 148, 148, 86, + 148, 160, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, + 77, 77, 77, 77, 77, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 313, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 188, 188, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, + 188, 188, 77, 77, 77, 77, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 77, 77, 77, + 77, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 286, 286, 317, 286, 317, 286, 286, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 286, 317, 286, 317, 286, + 286, 317, 317, 286, 286, 286, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 318, 318, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 37, 37, 37, 37, 37, 37, + 37, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 37, 37, 37, 37, 37, + 77, 77, 77, 77, 77, 319, 320, 319, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 242, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 90, 319, 319, 319, 319, 319, 90, 319, 90, 319, 319, 90, 319, + 319, 90, 319, 319, 319, 319, 319, 319, 319, 319, 319, 321, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 322, 220, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 88, 88, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 88, 88, 88, 88, 88, 88, 88, 88, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 324, 88, 88, 88, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 325, 325, + 325, 325, 325, 325, 325, 326, 327, 325, 77, 77, 77, 77, 77, 77, 84, 84, + 84, 84, 84, 84, 84, 91, 91, 91, 91, 91, 91, 91, 84, 84, 325, 328, 328, + 329, 329, 326, 327, 326, 327, 326, 327, 326, 327, 326, 327, 326, 327, + 326, 327, 326, 327, 284, 284, 326, 327, 325, 325, 325, 325, 329, 329, + 329, 330, 325, 330, 77, 325, 330, 325, 325, 328, 331, 332, 331, 332, 331, + 332, 333, 325, 325, 334, 335, 336, 336, 337, 77, 325, 338, 333, 325, 77, + 77, 77, 77, 136, 136, 136, 123, 136, 139, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 139, 139, 195, 77, 339, 339, 340, 341, 340, 339, 339, 342, + 343, 339, 344, 345, 346, 345, 345, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 345, 339, 348, 349, 348, 339, 339, 350, 350, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 342, 339, 343, 351, 352, 351, + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 342, 349, + 343, 349, 342, 343, 354, 355, 356, 354, 354, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 358, 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 359, 359, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 77, + 77, 77, 357, 357, 357, 357, 357, 357, 77, 77, 357, 357, 357, 357, 357, + 357, 77, 77, 357, 357, 357, 357, 357, 357, 77, 77, 357, 357, 357, 77, 77, + 77, 341, 341, 349, 351, 360, 341, 341, 77, 361, 362, 362, 362, 362, 361, + 361, 77, 236, 236, 236, 236, 236, 236, 236, 236, 236, 363, 363, 363, 88, + 262, 323, 323, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 77, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 77, 77, 77, 77, 77, 86, 145, 86, 77, 77, 77, 77, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 77, 77, 77, 83, 83, 83, 83, 83, 83, 83, 83, 83, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 166, 166, 166, 166, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 166, 166, 88, 83, 83, + 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 77, 77, 77, 88, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 91, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 91, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 77, 77, 77, 77, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 158, 158, 158, 158, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 193, 50, 50, 50, 50, 50, 50, 50, + 50, 193, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 84, 84, 84, 84, 84, 77, 77, 77, 77, + 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 86, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, + 77, 50, 50, 50, 50, 50, 50, 50, 50, 86, 193, 193, 193, 193, 193, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 195, 195, 195, 195, 195, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 83, - 83, 83, 83, 83, 83, 83, 85, 85, 85, 85, 85, 82, 82, 82, 82, 55, 55, 55, - 55, 85, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 0, 155, 155, 155, 155, 155, 155, 155, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 185, 50, 50, 50, 186, 373, 374, 374, - 55, 55, 85, 85, 85, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, + 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, + 77, 77, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, + 46, 46, 77, 77, 77, 77, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 85, 85, 85, 85, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 49, 49, 49, 49, 49, 49, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 139, 50, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 0, 139, 139, - 139, 139, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 281, 280, 281, 375, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 376, 376, 281, 281, 283, 283, 283, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 281, 281, 281, 0, 281, - 281, 281, 281, 281, 281, 281, 0, 281, 281, 0, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 282, 282, 282, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 282, 282, 282, 282, 0, 0, 0, 0, 0, 0, 0, 0, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 86, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 77, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 77, 46, 46, 46, 46, 46, 46, 46, 77, 46, 46, 77, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 77, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 77, 49, 49, 49, 49, 49, 49, 49, 77, 49, + 49, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 162, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 162, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 0, 0, 82, 139, 195, 85, 192, 192, 192, 192, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 377, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 377, 377, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 87, 87, - 87, 0, 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 0, 0, 0, 0, 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 139, 139, 139, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 55, 53, + 53, 53, 53, 53, 77, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 77, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 112, 112, 112, 112, 112, 112, 90, 90, 112, 90, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 112, 112, 90, + 90, 90, 112, 90, 90, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 109, + 366, 366, 366, 366, 366, 366, 366, 366, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 367, 367, 366, 366, 366, 366, 366, 366, 366, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 90, 90, 90, 90, 90, 90, 90, 90, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 90, 112, 112, 90, 90, 90, 90, 90, 366, 366, 366, 366, 366, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 366, 366, 366, 366, 366, 366, 90, 90, + 90, 145, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, + 90, 90, 90, 109, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 90, 90, 90, 90, 366, 366, 112, 112, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 90, 90, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 368, 142, 142, 142, 90, 142, 142, 90, 90, 90, 90, 90, 142, 91, + 142, 84, 368, 368, 368, 368, 90, 368, 368, 368, 90, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 90, 90, 84, 198, + 91, 90, 90, 90, 90, 152, 366, 366, 366, 366, 366, 366, 366, 366, 366, 90, + 90, 90, 90, 90, 90, 90, 109, 109, 109, 109, 109, 109, 109, 109, 109, 90, + 90, 90, 90, 90, 90, 90, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 366, 366, 109, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 366, 366, 366, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 112, 112, 112, 112, 112, 112, + 112, 112, 367, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 84, 91, 90, 90, 90, 90, 366, 366, 366, 366, 366, 109, 109, + 109, 109, 109, 109, 109, 90, 90, 90, 90, 90, 90, 90, 90, 90, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, 90, 145, 145, + 145, 145, 145, 145, 145, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, + 366, 366, 366, 366, 366, 366, 366, 366, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, + 90, 90, 90, 366, 366, 366, 366, 366, 366, 366, 366, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, + 90, 90, 90, 90, 90, 90, 109, 109, 109, 109, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 366, 366, 366, 366, 366, 366, 366, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 90, 90, 90, 90, 90, 90, 90, 366, 366, 366, + 366, 366, 366, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 84, 84, 84, 84, + 139, 139, 139, 139, 139, 139, 139, 139, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 133, 139, 139, 139, 139, 139, 139, 133, 133, 133, 133, + 133, 133, 133, 133, 133, 133, 112, 112, 112, 112, 144, 112, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 90, 90, 90, 84, 84, 84, 84, 84, 87, 144, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 90, 90, 90, 90, 90, 90, 90, 90, + 371, 371, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 90, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 84, 84, + 107, 90, 90, 112, 112, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 139, 139, 123, 123, 123, 125, 123, 123, 139, 139, 139, 139, 139, + 139, 139, 139, 145, 88, 88, 88, 88, 88, 88, 88, 88, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 91, 91, 142, 91, 91, 91, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 112, 90, 90, 90, 90, 90, 90, 90, 90, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 91, 91, 84, 84, 84, 91, 84, 91, 91, 91, 91, 373, 373, + 373, 373, 118, 118, 118, 118, 118, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, - 0, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 0, 0, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 379, 379, 379, 379, 379, 379, 379, 380, 380, 195, 195, 195, 82, 82, 82, - 381, 380, 380, 380, 380, 380, 192, 192, 192, 192, 192, 192, 192, 192, 89, - 89, 89, 89, 89, 89, 89, 89, 82, 82, 83, 83, 83, 83, 83, 89, 89, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 379, 379, 379, 379, 379, 379, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 87, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 83, 83, 83, 87, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, - 382, 155, 155, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 139, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 84, 91, 84, 91, 109, 109, 109, 109, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 366, 366, 366, 366, 366, 366, 366, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 148, 142, 148, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 160, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 160, 50, 50, 142, 142, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 160, + 142, 142, 148, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 162, 50, 162, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 162, 50, 50, 50, 50, 148, 148, 148, 142, + 142, 142, 142, 148, 148, 160, 151, 86, 86, 374, 86, 86, 86, 86, 142, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 374, 77, 77, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 77, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 77, 77, 77, 77, 77, 77, 84, 84, 84, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 161, 142, 142, 142, 142, 148, 142, 163, 163, 142, 142, + 142, 152, 160, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 86, + 86, 86, 86, 149, 148, 148, 149, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 155, 86, 86, + 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 142, 142, 148, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 148, 148, 148, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 148, 194, 50, 169, 169, 50, 86, 86, 86, 86, 142, 155, + 142, 142, 86, 148, 142, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 50, 86, 50, 86, 86, 86, 77, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 148, 148, + 148, 142, 142, 142, 148, 148, 142, 194, 155, 142, 86, 86, 86, 86, 86, 86, + 142, 50, 50, 142, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, + 50, 77, 50, 77, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, + 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 142, + 148, 148, 148, 142, 142, 142, 142, 142, 142, 155, 160, 77, 77, 77, 77, + 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, + 77, 142, 142, 148, 148, 77, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 50, + 50, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, + 77, 50, 50, 50, 50, 50, 77, 155, 155, 50, 156, 148, 142, 148, 148, 148, + 148, 77, 77, 148, 148, 77, 77, 157, 157, 194, 77, 77, 50, 77, 77, 77, 77, + 77, 77, 156, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 148, 148, 77, 77, + 84, 84, 84, 84, 84, 84, 84, 77, 77, 77, 84, 84, 84, 84, 84, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 149, 149, 149, 150, 149, 150, 149, 149, + 149, 149, 77, 149, 77, 77, 150, 77, 149, 150, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 77, 50, 156, 148, 148, 161, 142, 142, 142, 142, 142, 77, + 156, 77, 77, 375, 77, 375, 375, 156, 148, 77, 148, 148, 160, 194, 152, + 169, 142, 50, 86, 86, 77, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 142, + 142, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 148, 148, 148, 142, 142, 142, + 142, 142, 142, 142, 142, 148, 148, 160, 142, 142, 148, 155, 50, 50, 50, + 50, 86, 86, 86, 86, 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 86, 86, 77, 86, 84, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 156, 148, 148, + 142, 142, 142, 142, 142, 142, 148, 161, 157, 157, 156, 157, 142, 142, + 148, 160, 155, 50, 50, 86, 50, 77, 77, 77, 77, 77, 77, 77, 77, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 156, 148, 148, 142, 142, 142, 142, 77, 77, 148, 148, + 157, 157, 142, 142, 148, 160, 155, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 50, 50, 50, 50, + 142, 142, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 148, 148, 148, 142, 142, + 142, 142, 142, 142, 142, 142, 148, 148, 142, 148, 160, 142, 86, 86, 86, + 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 142, 148, 142, 148, 148, 142, 142, 142, 142, 142, 142, 194, 155, 50, 86, + 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 142, 148, + 142, 186, 186, 142, 142, 142, 142, 148, 142, 142, 142, 142, 160, 77, 77, + 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 158, 158, 86, + 86, 86, 83, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 148, 148, 148, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 148, 160, 155, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 158, 158, 158, 158, 158, 158, 158, 158, 158, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 50, 149, 149, 149, 149, 149, 149, 149, 77, 77, + 149, 77, 77, 149, 149, 149, 149, 149, 149, 149, 149, 77, 149, 149, 77, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 156, 148, 148, 148, + 148, 148, 77, 148, 157, 77, 77, 142, 142, 194, 152, 169, 148, 169, 148, + 155, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 148, 148, 148, 142, 142, 142, 142, 77, 77, 142, 142, 148, 148, 148, 148, + 160, 50, 86, 50, 148, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 149, 142, 142, + 142, 142, 142, 142, 167, 167, 142, 142, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 142, 160, 142, 142, 142, 142, 148, 50, 142, + 142, 142, 142, 86, 86, 86, 86, 86, 86, 86, 86, 152, 77, 77, 77, 77, 77, + 77, 77, 77, 149, 142, 142, 142, 142, 142, 142, 148, 148, 142, 142, 142, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 169, 169, + 169, 169, 169, 169, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 148, 142, 152, 86, 86, 86, 50, 86, 86, 86, 86, 86, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, + 77, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 142, 148, 142, 142, 142, 148, 142, 148, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 148, 142, 142, 142, 142, 142, 142, 142, 77, 142, 142, 142, + 142, 142, 142, 148, 376, 50, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 77, 77, 77, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 77, 77, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 77, 148, 142, + 142, 142, 142, 142, 142, 142, 148, 142, 142, 148, 142, 142, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, + 50, 50, 50, 50, 50, 77, 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 142, 142, 142, 142, 142, 142, + 77, 77, 77, 142, 77, 142, 142, 77, 142, 142, 142, 155, 142, 160, 160, + 169, 142, 77, 77, 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 77, + 50, 50, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 148, + 148, 148, 148, 148, 77, 142, 142, 77, 148, 148, 142, 148, 160, 50, 77, + 77, 77, 77, 77, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, 50, 50, 77, 77, 77, 77, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 142, 142, 148, 148, 86, 86, 77, 77, 77, 77, 77, 77, + 77, 142, 142, 169, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 77, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 142, 142, 142, + 142, 142, 77, 77, 77, 148, 148, 142, 194, 152, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 142, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 86, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 77, 86, 86, 86, 86, 86, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, + 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 142, 50, 50, 50, 50, 50, 50, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 161, 161, 161, 377, 377, 377, 377, 377, 377, 377, 377, 161, 148, 148, + 148, 142, 142, 160, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, + 77, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 77, 77, 198, 198, 198, 198, 198, 86, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 84, 84, 84, 84, 84, 84, 84, 86, 86, 86, 86, 86, 83, 83, 83, 83, 55, 55, + 55, 55, 86, 83, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 77, 158, 158, 158, 158, 158, 158, 158, + 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 55, 55, 55, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 188, 50, 50, 50, 189, 378, 379, 379, 55, 55, 86, 86, + 86, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 86, 86, 86, 86, + 77, 77, 77, 77, 77, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 77, 77, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, + 142, 50, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 77, + 77, 77, 77, 77, 77, 77, 142, 142, 142, 142, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 285, 285, + 284, 285, 380, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 381, 381, 285, + 285, 287, 287, 287, 77, 77, 77, 77, 77, 77, 77, 77, 77, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 285, 285, + 285, 285, 77, 285, 285, 285, 285, 285, 285, 285, 77, 285, 285, 77, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 286, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 286, 286, + 286, 77, 77, 286, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 286, 286, 286, 286, 77, 77, 77, 77, 77, 77, 77, 77, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 77, 77, 77, 77, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, + 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 77, 77, 77, 77, 77, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 77, 77, 83, 142, 198, 86, 195, 195, 195, + 195, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 88, 88, 88, 77, 77, 77, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 77, 77, 77, 77, + 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 77, 77, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 77, 77, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 384, 384, 384, 384, 384, 384, + 384, 385, 385, 198, 198, 198, 83, 83, 83, 386, 385, 385, 385, 385, 385, + 195, 195, 195, 195, 195, 195, 195, 195, 91, 91, 91, 91, 91, 91, 91, 91, + 83, 83, 84, 84, 84, 84, 84, 91, 91, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 84, 84, 84, 84, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 384, 384, 384, 384, 384, 384, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 88, 88, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 84, 84, 84, 88, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 387, 387, 387, 387, 387, 387, 387, 387, + 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, + 387, 158, 158, 77, 77, 77, 77, 77, 77, 77, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 77, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, - 37, 37, 37, 37, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 51, 0, 51, 51, 0, 0, 51, 0, 0, 51, 51, 0, 0, 51, 51, 51, 51, - 0, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 0, 37, 0, 37, 37, 37, - 37, 37, 37, 37, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, + 37, 37, 37, 37, 37, 51, 77, 51, 51, 77, 77, 51, 77, 77, 51, 51, 77, 77, + 51, 51, 51, 51, 77, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 77, + 37, 77, 37, 37, 37, 37, 37, 37, 37, 77, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 51, 51, 77, 51, 51, 51, 51, 77, 77, 51, 51, 51, 51, 51, 51, 51, 51, + 77, 51, 51, 51, 51, 51, 51, 51, 77, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, + 51, 77, 51, 51, 51, 51, 77, 51, 51, 51, 51, 51, 77, 51, 77, 77, 77, 51, + 51, 51, 51, 51, 51, 51, 77, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 0, 51, - 51, 51, 51, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, - 51, 51, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 0, 51, 51, 51, 51, 0, - 51, 51, 51, 51, 51, 0, 51, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 0, 37, + 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, @@ -3214,469 +3310,492 @@ static const unsigned short index2[] = { 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 77, 77, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 243, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 51, 51, 51, + 37, 37, 37, 37, 256, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 51, 51, + 243, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 256, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 240, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 252, 37, 37, 37, 37, - 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 240, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 252, - 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 240, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 252, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 240, + 51, 51, 51, 51, 243, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 256, 37, 37, 37, 37, 37, + 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 243, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 256, 37, + 37, 37, 37, 37, 37, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 243, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 252, 37, 37, 37, 37, 37, 37, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 240, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 252, 37, 37, 37, 37, 37, 37, - 51, 37, 0, 0, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 82, 82, 82, 82, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 82, 82, 82, 82, 82, 82, 82, 82, 139, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 139, 82, 82, 85, 85, - 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 139, 139, - 139, 139, 0, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 50, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 83, 83, 83, 0, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 0, 0, 83, 83, 83, 83, - 83, 83, 83, 0, 83, 83, 0, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 83, - 83, 83, 83, 83, 83, 83, 55, 55, 55, 55, 55, 55, 55, 0, 0, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 0, 0, 0, 0, 50, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 83, 83, 83, 83, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 55, 198, 198, 89, 83, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 83, 89, 50, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, - 50, 50, 50, 83, 50, 50, 83, 50, 50, 50, 50, 50, 50, 50, 83, 83, 50, 50, - 50, 50, 50, 83, 0, 0, 0, 0, 0, 0, 0, 0, 50, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 110, 0, 0, 361, 361, 361, 361, 361, 361, 361, - 361, 361, 89, 89, 89, 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, - 365, 83, 83, 83, 83, 83, 83, 152, 141, 0, 0, 0, 0, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 0, 0, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 136, - 368, 368, 368, 114, 368, 368, 368, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 136, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, 134, - 134, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 0, - 134, 134, 0, 134, 0, 0, 134, 0, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 0, 134, 134, 134, 134, 0, 134, 0, 134, 0, 0, 0, 0, 0, 0, 134, - 0, 0, 0, 0, 134, 0, 134, 0, 134, 0, 134, 134, 134, 0, 134, 134, 0, 134, - 0, 0, 134, 0, 134, 0, 134, 0, 134, 0, 134, 0, 134, 134, 0, 134, 0, 0, - 134, 134, 134, 134, 0, 134, 134, 134, 134, 134, 134, 134, 0, 134, 134, - 134, 134, 0, 134, 134, 134, 134, 0, 134, 0, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, 134, 134, 134, 0, 134, - 134, 134, 134, 134, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 87, 87, 87, 87, 267, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 383, 383, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 383, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 267, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 163, 163, 87, 87, 87, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 377, 87, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 246, 246, 246, 87, 87, 87, 385, 385, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 385, 385, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 386, 384, 270, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 87, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 387, 387, 387, - 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, - 387, 387, 387, 387, 387, 387, 387, 387, 387, 304, 307, 307, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 307, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 307, 304, 304, 307, 307, 307, 307, 307, 307, 307, 307, 307, 304, 383, - 383, 383, 383, 304, 304, 304, 304, 304, 304, 304, 304, 304, 383, 383, - 383, 383, 383, 383, 383, 307, 307, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 275, 275, 275, 275, 275, 275, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 28, 87, 87, 28, 28, 28, 28, 28, 28, 28, 28, 28, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 28, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 28, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 87, 87, 28, 28, 87, 28, 28, 28, 87, 87, 28, 28, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 28, 28, 28, - 28, 267, 267, 267, 267, 267, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 87, 87, 28, 267, 28, 87, 28, 267, 267, 267, 388, 388, 388, - 388, 388, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 28, 267, 28, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 28, 87, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 28, 28, 267, 267, 267, 267, 87, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 87, 87, 87, 87, 87, 87, 87, 28, 28, 87, 87, - 28, 28, 28, 28, 28, 28, 28, 267, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 28, 87, 87, 28, 28, 28, 28, 87, 87, 28, 87, 87, 87, 87, 267, 267, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 267, 28, 87, 87, 28, - 87, 87, 87, 87, 87, 87, 87, 87, 28, 28, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 28, 87, 87, 87, 87, 87, 28, 28, 28, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 28, 28, 28, 87, 87, 87, 87, 87, 87, 87, 87, 28, 28, 28, - 87, 87, 28, 87, 28, 87, 87, 87, 87, 28, 87, 87, 87, 87, 87, 87, 28, 87, - 87, 87, 28, 87, 87, 87, 87, 87, 87, 28, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 87, 87, 87, 87, 87, 28, 267, 28, 28, 28, 267, 267, - 267, 87, 87, 267, 267, 267, 267, 383, 383, 383, 267, 267, 267, 267, 28, - 28, 28, 28, 28, 28, 87, 87, 87, 28, 87, 267, 267, 383, 383, 383, 28, 87, - 87, 28, 267, 267, 267, 267, 267, 267, 267, 267, 267, 383, 383, 383, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, - 383, 383, 383, 383, 383, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 383, 383, 383, 383, 267, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 383, 383, 383, 383, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 383, 383, 383, - 383, 383, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 383, - 383, 383, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 383, 383, 383, 383, 383, 383, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 383, 383, 383, 383, 87, 87, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 87, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 87, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 383, - 383, 383, 383, 383, 383, 383, 383, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 383, 383, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 383, 383, 383, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 383, 383, 383, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 383, 267, 383, 383, 383, - 383, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 383, 383, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 383, 383, 383, 383, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 383, 383, 383, 383, 383, 383, 383, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 0, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 87, 0, 0, 0, 0, 0, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 37, 37, 256, 37, 37, 37, 37, 37, 37, 51, 37, 77, 77, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 0, 0, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 314, 314, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 314, 314, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 0, 0, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 314, 314, 314, 314, 314, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 314, 314, 314, - 314, 314, 314, 233, 192, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 383, 383, 383, 383, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 83, 83, 83, 83, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 83, + 83, 83, 83, 83, 83, 83, 83, 142, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 142, 83, 83, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 142, 142, 142, 142, 142, 77, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 77, 77, 77, 77, 77, 77, 49, 49, 49, 49, 49, 49, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 84, 84, 84, 84, 84, 84, 84, 77, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 77, 77, + 84, 84, 84, 84, 84, 84, 84, 77, 84, 84, 77, 84, 84, 84, 84, 84, 77, 77, + 77, 77, 77, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 84, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 77, 77, 77, 84, 84, 84, 84, 84, 84, 84, 55, 55, 55, 55, + 55, 55, 55, 77, 77, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, + 77, 77, 77, 50, 83, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 84, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 84, + 84, 84, 84, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 77, 77, 77, + 77, 77, 89, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 55, 201, 201, 91, 84, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 84, 91, 50, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 77, 77, 77, 77, 86, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, + 50, 50, 50, 84, 50, 50, 84, 50, 50, 50, 50, 50, 50, 50, 84, 84, 50, 50, + 50, 50, 50, 84, 77, 77, 77, 77, 77, 77, 77, 77, 50, 55, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 50, 50, 50, 50, 50, 50, 50, 77, 50, 50, 50, 50, 77, 50, 50, 77, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 77, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 90, 90, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 91, 91, 91, 91, 91, 91, 91, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 84, 84, 84, 84, 84, 84, 155, 144, 90, 90, 90, 90, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 90, 90, 90, 90, 109, 109, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 139, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 138, 373, 373, 373, 116, 373, 373, 373, 373, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 139, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 138, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 136, 136, 136, 136, 139, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 136, + 136, 139, 136, 139, 139, 136, 139, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 139, 136, 136, 136, 136, 139, 136, 139, 136, 139, 139, + 139, 139, 139, 139, 136, 139, 139, 139, 139, 136, 139, 136, 139, 136, + 139, 136, 136, 136, 139, 136, 136, 139, 136, 139, 139, 136, 139, 136, + 139, 136, 139, 136, 139, 136, 139, 136, 136, 139, 136, 139, 139, 136, + 136, 136, 136, 139, 136, 136, 136, 136, 136, 136, 136, 139, 136, 136, + 136, 136, 139, 136, 136, 136, 136, 139, 136, 139, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 139, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, + 139, 136, 136, 136, 139, 136, 136, 136, 136, 136, 139, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 81, 81, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 88, 88, 88, 88, + 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 388, 388, 388, 388, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 388, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 271, 388, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 166, + 166, 88, 88, 88, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 382, 88, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 250, 250, 250, 88, 88, 88, 390, + 390, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, + 390, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 391, 389, 274, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 389, 389, 389, 389, 88, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 308, 311, 311, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 311, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 311, 308, 308, 311, 311, 311, 311, + 311, 311, 311, 311, 311, 308, 388, 388, 388, 388, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 388, 388, 388, 388, 388, 388, 388, 311, 311, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 279, 279, 279, 279, 279, 279, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 28, 88, 88, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 28, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 28, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 88, 88, 28, 28, 88, 28, 28, + 28, 88, 88, 28, 28, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 28, 28, 28, 28, 271, 271, 271, 271, 271, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 88, 88, 28, 271, + 28, 88, 28, 271, 271, 271, 393, 393, 393, 393, 393, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 28, 271, 28, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 28, 88, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 28, + 271, 271, 271, 271, 88, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 88, + 88, 88, 88, 88, 88, 88, 28, 28, 88, 88, 28, 28, 28, 28, 28, 28, 28, 271, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 88, 88, 28, 28, 28, + 28, 88, 88, 28, 88, 88, 88, 88, 271, 271, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 271, 28, 88, 88, 28, 88, 88, 88, 88, 88, 88, 88, 88, + 28, 28, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 88, 88, 88, 88, 88, 28, + 28, 28, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 28, 28, 88, + 88, 88, 88, 88, 88, 88, 88, 28, 28, 28, 88, 88, 28, 88, 28, 88, 88, 88, + 88, 28, 88, 88, 88, 88, 88, 88, 28, 88, 88, 88, 28, 88, 88, 88, 88, 88, + 88, 28, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 88, 88, 88, 88, + 88, 28, 271, 28, 28, 28, 271, 271, 271, 88, 88, 271, 271, 271, 271, 388, + 388, 388, 271, 271, 271, 271, 28, 28, 28, 28, 28, 28, 88, 88, 88, 28, 88, + 271, 271, 388, 388, 388, 28, 88, 88, 28, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 388, 388, 388, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 388, 388, 388, 388, 388, 388, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 388, 388, 388, 388, 271, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 388, 388, 388, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 388, 388, 388, 388, 388, 388, 388, 388, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 388, 388, 388, 388, 388, 388, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 388, + 388, 388, 388, 388, 388, 388, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 388, 388, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 388, + 388, 388, 88, 88, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 81, 81, 81, 81, 81, 81, 81, 81, 81, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 88, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 88, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 388, 388, 388, 388, 388, 388, 388, 388, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 388, 388, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 388, 388, 388, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 388, 388, 388, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 388, + 271, 388, 388, 388, 388, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 388, 388, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 388, 388, 388, 388, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 388, 388, 388, 388, 388, 388, 388, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 88, 77, 77, + 77, 77, 77, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 323, 323, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 318, 318, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 318, 318, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 323, 323, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 318, 318, 318, + 318, 318, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 318, 318, 318, 318, 318, 318, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 323, 323, 236, 195, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, @@ -3689,18 +3808,17 @@ static const unsigned short index2[] = { 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, - 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 0, - 0, + 73, 73, 73, 73, 73, 73, 73, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 323, 323, }; /* decomposition data */ diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 432dc3a68bf5ed..37d7e096769833 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -29,6 +29,7 @@ import dataclasses import os import sys +import re import zipfile from functools import partial @@ -49,6 +50,7 @@ COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt" EASTASIAN_WIDTH = "EastAsianWidth%s.txt" UNIHAN = "Unihan%s.zip" +DERIVED_BIDI_CLASS = "extracted/DerivedBidiClass%s.txt" DERIVED_CORE_PROPERTIES = "DerivedCoreProperties%s.txt" DERIVEDNORMALIZATION_PROPS = "DerivedNormalizationProps%s.txt" LINE_BREAK = "LineBreak%s.txt" @@ -79,6 +81,33 @@ "PDF", "EN", "ES", "ET", "AN", "CS", "NSM", "BN", "B", "S", "WS", "ON", "LRI", "RLI", "FSI", "PDI" ] +# https://www.unicode.org/reports/tr44/#BC_Values_Table +BIDI_LONG_NAMES = { + 'Left_To_Right': 'L', + 'Right_To_Left': 'R', + 'Arabic_Letter': 'AL', + 'European_Number': 'EN', + 'European_Separator': 'ES', + 'European_Terminator': 'ET', + 'Arabic_Number': 'AN', + 'Common_Separator': 'CS', + 'Nonspacing_Mark': 'NSM', + 'Boundary_Neutral': 'BN', + 'Paragraph_Separator': 'B', + 'Segment_Separator': 'S', + 'White_Space': 'WS', + 'Other_Neutral': 'ON', + 'Left_To_Right_Embedding': 'LRE', + 'Left_To_Right_Override': 'LRO', + 'Right_To_Left_Embedding': 'RLE', + 'Right_To_Left_Override': 'RLO', + 'Pop_Directional_Format': 'PDF', + 'Left_To_Right_Isolate': 'LRI', + 'Right_To_Left_Isolate': 'RLI', + 'First_Strong_Isolate': 'FSI', + 'Pop_Directional_Isolate': 'PDI', +} + # "Other" needs to be the first entry, see the comment in makeunicodedata GRAPHEME_CLUSTER_NAMES = [ 'Other', 'Prepend', 'CR', 'LF', 'Control', 'Extend', 'Regional_Indicator', 'SpacingMark', 'L', 'V', 'T', 'LV', 'LVT', @@ -169,11 +198,11 @@ def makeunicodedata(unicode, trace): eastasianwidth = EASTASIANWIDTH_NAMES.index(unicode.widths[char] or 'N') graphemebreak = GRAPHEME_CLUSTER_NAMES.index(unicode.grapheme_breaks[char] or 'Other') extpict = unicode.ext_picts[char] + bidirectional = BIDIRECTIONAL_NAMES.index(unicode.bidi_classes[char]) if record: # extract database properties category = CATEGORY_NAMES.index(record.general_category) combining = int(record.canonical_combining_class) - bidirectional = BIDIRECTIONAL_NAMES.index(record.bidi_class) mirrored = record.bidi_mirrored == "Y" normalizationquickcheck = record.quick_check incb = INDIC_CONJUNCT_BREAK_NAMES.index(record.incb) @@ -181,12 +210,12 @@ def makeunicodedata(unicode, trace): category, combining, bidirectional, mirrored, eastasianwidth, normalizationquickcheck, graphemebreak, incb, extpict, ) - elif eastasianwidth or graphemebreak or extpict: - # an unassigned but reserved character, with a known - # east_asian_width or grapheme_break or ext_pict - item = (0, 0, 0, 0, eastasianwidth, 0, graphemebreak, 0, extpict) else: - continue + if eastasianwidth or graphemebreak or extpict or bidirectional: + item = (0, 0, bidirectional, 0, eastasianwidth, + 0, graphemebreak, 0, extpict) + else: + continue # add entry to index and item tables i = cache.get(item) @@ -457,7 +486,7 @@ def makeunicodetype(unicode, trace): if record: # extract database properties category = record.general_category - bidirectional = record.bidi_class + bidirectional = unicode.bidi_classes[char] properties = record.binary_properties flags = 0 if category in ["Lm", "Lt", "Lu", "Ll", "Lo"]: @@ -770,6 +799,8 @@ def merge_old_version(version, new, old): # category 0 is "unassigned" category_changes[i] = 0 continue + if old.bidi_classes[i] != new.bidi_classes[i]: + bidir_changes[i] = BIDIRECTIONAL_NAMES.index(old.bidi_classes[i]) # check characters that differ if old.table[i] != new.table[i]: for k, field in enumerate(dataclasses.fields(UcdRecord)): @@ -783,7 +814,8 @@ def merge_old_version(version, new, old): elif k == 2: category_changes[i] = CATEGORY_NAMES.index(value) elif k == 4: - bidir_changes[i] = BIDIRECTIONAL_NAMES.index(value) + # bidi_class changes handled via bidi_classes + pass elif k == 5: # We assume that all normalization changes are in 1:1 mappings assert " " not in value @@ -1042,6 +1074,28 @@ def __init__(self, version, ideograph_check=True): table[i].east_asian_width = widths[i] self.widths = widths + # Read DerivedBidiClass.txt for bidi classes + # see https://www.unicode.org/reports/tr44/#Missing_Conventions + bidi_classes = [None] * 0x110000 + for i in range(0, 0x110000): + if table[i] is not None: + bidi_classes[i] = table[i].bidi_class + if version != '3.2.0': + missing_re = re.compile( + r'# @missing: ([\dA-F]+\.\.[\dA-F]+); (\w+)' + ) + with open_data(DERIVED_BIDI_CLASS, version) as f: + for l in f: + m = missing_re.match(l) + if not m: + continue + name = BIDI_LONG_NAMES[m[2]] + for i in expand_range(m[1]): + bidi_classes[i] = name + for char, (bidi,) in UcdFile(DERIVED_BIDI_CLASS, version).expanded(): + bidi_classes[char] = bidi + self.bidi_classes = bidi_classes + for char, (propname, *propinfo) in UcdFile(DERIVED_CORE_PROPERTIES, version).expanded(): if not propinfo: # binary property From 767b4d02e2d3dc9ff62c9926eea044532ac077b6 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 Feb 2026 12:58:21 +0200 Subject: [PATCH 140/498] gh-144882: Optimize name tables in unicodedata by excluding names derived by rule NR2 (GH-144883) Since the code for rule NR2 is already here, to support CJK unified ideographs and Tangut ideographs, it can also be used for other names derived by rule NR2. --- Modules/unicodename_db.h | 24184 ++++++++++++++--------------- Tools/unicode/makeunicodedata.py | 26 +- 2 files changed, 11509 insertions(+), 12701 deletions(-) diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index d9d062a2345974..5ac5ca462bdfab 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -4,381 +4,381 @@ /* name->code dictionary */ static const unsigned char packed_name_dawg[] = { - 136, 135, 5, 254, 2, 65, 246, 145, 3, 66, 206, 160, 3, 67, 146, 251, 4, - 68, 250, 135, 1, 69, 230, 157, 1, 70, 174, 55, 71, 214, 169, 1, 72, 138, - 226, 1, 73, 138, 66, 74, 142, 23, 75, 250, 138, 1, 76, 150, 164, 3, 77, - 198, 201, 3, 78, 246, 107, 79, 174, 131, 1, 80, 212, 159, 1, 2, 81, 85, + 160, 171, 4, 254, 2, 65, 246, 145, 3, 66, 206, 160, 3, 67, 146, 247, 4, + 68, 250, 135, 1, 69, 178, 153, 1, 70, 174, 55, 71, 214, 169, 1, 72, 138, + 226, 1, 73, 138, 66, 74, 142, 23, 75, 174, 135, 1, 76, 150, 164, 3, 77, + 198, 201, 3, 78, 170, 103, 79, 174, 131, 1, 80, 212, 159, 1, 2, 81, 85, 226, 7, 82, 158, 180, 1, 83, 210, 197, 4, 84, 146, 236, 2, 85, 246, 104, 86, 242, 84, 87, 246, 114, 88, 130, 5, 89, 211, 50, 90, 176, 41, 218, 2, 67, 238, 1, 68, 182, 10, 69, 172, 5, 4, 72, 79, 77, 32, 244, 6, 7, 73, 82, 80, 76, 65, 78, 69, 82, 76, 190, 36, 77, 242, 1, 78, 162, 26, 80, 162, 20, 82, 186, 150, 2, 83, 162, 3, 84, 70, 85, 214, 1, 86, 252, 197, - 1, 8, 75, 84, 73, 69, 83, 69, 76, 83, 168, 203, 10, 4, 70, 71, 72, 65, - 150, 239, 9, 66, 196, 170, 5, 2, 81, 85, 171, 215, 10, 88, 18, 132, 1, 2, - 67, 79, 46, 75, 20, 5, 85, 84, 69, 32, 65, 160, 188, 17, 6, 84, 73, 86, - 65, 84, 69, 213, 161, 23, 5, 32, 67, 85, 82, 82, 4, 186, 184, 26, 85, - 221, 152, 14, 2, 82, 68, 5, 203, 215, 34, 78, 4, 142, 252, 35, 67, 199, - 254, 3, 78, 188, 1, 232, 1, 4, 76, 65, 77, 32, 242, 7, 77, 252, 207, 13, + 1, 8, 75, 84, 73, 69, 83, 69, 76, 83, 244, 194, 10, 4, 70, 71, 72, 65, + 202, 235, 9, 66, 248, 165, 5, 2, 81, 85, 171, 215, 10, 88, 18, 132, 1, 2, + 67, 79, 46, 75, 20, 5, 85, 84, 69, 32, 65, 236, 179, 17, 6, 84, 73, 86, + 65, 84, 69, 189, 153, 23, 5, 32, 67, 85, 82, 82, 4, 182, 172, 26, 85, + 149, 148, 14, 2, 82, 68, 5, 255, 198, 34, 78, 4, 194, 235, 35, 67, 199, + 254, 3, 78, 188, 1, 232, 1, 4, 76, 65, 77, 32, 242, 7, 77, 200, 199, 13, 7, 72, 69, 83, 73, 86, 69, 32, 136, 172, 4, 19, 68, 82, 69, 83, 83, 69, - 68, 32, 84, 79, 32, 84, 72, 69, 32, 83, 85, 66, 74, 174, 245, 13, 85, + 68, 32, 84, 79, 32, 84, 72, 69, 32, 83, 85, 66, 74, 150, 237, 13, 85, 233, 185, 1, 6, 73, 32, 83, 72, 65, 75, 176, 1, 218, 1, 67, 44, 4, 83, 77, 65, 76, 168, 4, 7, 71, 69, 77, 73, 78, 65, 84, 116, 8, 73, 78, 73, - 84, 73, 65, 76, 32, 38, 78, 146, 228, 2, 72, 140, 225, 23, 4, 65, 76, 73, + 84, 73, 65, 76, 32, 38, 78, 146, 228, 2, 72, 192, 208, 23, 4, 65, 76, 73, 70, 0, 5, 86, 79, 87, 69, 76, 155, 222, 12, 68, 70, 40, 5, 65, 80, 73, 84, 65, 215, 4, 79, 68, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 68, - 142, 2, 68, 38, 71, 34, 74, 2, 77, 22, 75, 46, 78, 42, 83, 130, 176, 30, + 142, 2, 68, 38, 71, 34, 74, 2, 77, 22, 75, 46, 78, 42, 83, 182, 159, 30, 81, 142, 228, 4, 76, 142, 45, 67, 158, 204, 4, 90, 240, 9, 2, 65, 76, 170, 2, 66, 2, 89, 154, 1, 87, 198, 89, 84, 150, 14, 80, 158, 20, 70, 2, 72, 2, 82, 2, 86, 186, 2, 69, 2, 73, 2, 79, 3, 85, 4, 150, 240, 5, 65, - 239, 167, 35, 72, 4, 194, 131, 41, 66, 215, 22, 65, 2, 167, 151, 40, 73, - 6, 190, 152, 40, 65, 178, 98, 80, 191, 28, 72, 6, 214, 201, 40, 85, 170, - 77, 72, 3, 89, 4, 164, 200, 2, 6, 73, 78, 78, 89, 73, 73, 179, 206, 38, - 72, 4, 40, 4, 69, 32, 67, 79, 155, 175, 40, 73, 2, 145, 141, 40, 13, 78, - 83, 79, 78, 65, 78, 84, 32, 77, 79, 68, 73, 70, 4, 134, 252, 33, 69, 247, - 198, 4, 81, 4, 186, 150, 26, 65, 143, 228, 10, 85, 4, 230, 220, 27, 69, + 163, 151, 35, 72, 4, 246, 242, 40, 66, 215, 22, 65, 2, 219, 134, 40, 73, + 6, 242, 135, 40, 65, 178, 98, 80, 191, 28, 72, 6, 138, 185, 40, 85, 170, + 77, 72, 3, 89, 4, 164, 200, 2, 6, 73, 78, 78, 89, 73, 73, 231, 189, 38, + 72, 4, 40, 4, 69, 32, 67, 79, 207, 158, 40, 73, 2, 197, 252, 39, 13, 78, + 83, 79, 78, 65, 78, 84, 32, 77, 79, 68, 73, 70, 4, 186, 235, 33, 69, 247, + 198, 4, 81, 4, 186, 138, 26, 65, 195, 223, 10, 85, 4, 154, 204, 27, 69, 245, 177, 12, 12, 73, 83, 83, 73, 79, 78, 32, 84, 73, 67, 75, 69, 116, - 80, 5, 71, 69, 65, 78, 32, 161, 183, 34, 9, 82, 73, 65, 76, 32, 84, 82, + 80, 5, 71, 69, 65, 78, 32, 213, 166, 34, 9, 82, 73, 65, 76, 32, 84, 82, 65, 77, 114, 136, 1, 3, 68, 82, 89, 0, 6, 76, 73, 81, 85, 73, 68, 60, 8, - 77, 69, 65, 83, 85, 82, 69, 32, 26, 87, 146, 190, 27, 78, 183, 144, 12, + 77, 69, 65, 83, 85, 82, 69, 32, 26, 87, 198, 173, 27, 78, 183, 144, 12, 67, 2, 153, 2, 11, 32, 77, 69, 65, 83, 85, 82, 69, 32, 70, 73, 4, 246, 1, 83, 31, 84, 14, 100, 6, 69, 73, 71, 72, 84, 32, 241, 1, 14, 79, 82, 68, 32, 83, 69, 80, 65, 82, 65, 84, 79, 82, 32, 10, 54, 70, 66, 83, 30, 84, 65, 5, 66, 65, 83, 69, 32, 4, 38, 73, 89, 5, 79, 85, 82, 84, 72, 2, 85, 3, 82, 83, 84, 2, 49, 4, 69, 67, 79, 78, 2, 21, 3, 72, 73, 82, 2, 11, 68, - 2, 25, 4, 32, 83, 85, 66, 2, 153, 245, 40, 2, 85, 78, 4, 250, 245, 39, + 2, 25, 4, 32, 83, 85, 66, 2, 205, 228, 40, 2, 85, 78, 4, 174, 229, 39, 76, 135, 75, 68, 130, 1, 140, 2, 22, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 77, 69, 68, 73, 65, 76, 32, 88, 7, 76, 69, 84, 84, 69, 82, 32, 242, 1, 83, 168, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, - 71, 78, 32, 196, 131, 33, 8, 78, 85, 77, 66, 69, 82, 32, 84, 203, 147, 6, - 68, 6, 26, 76, 179, 140, 41, 82, 4, 140, 196, 40, 7, 73, 71, 65, 84, 73, - 78, 71, 219, 74, 65, 68, 154, 1, 65, 194, 175, 37, 68, 114, 84, 198, 208, + 71, 78, 32, 248, 242, 32, 8, 78, 85, 77, 66, 69, 82, 32, 84, 203, 147, 6, + 68, 6, 26, 76, 231, 251, 40, 82, 4, 192, 179, 40, 7, 73, 71, 65, 84, 73, + 78, 71, 219, 74, 65, 68, 154, 1, 65, 246, 158, 37, 68, 114, 84, 198, 208, 1, 76, 226, 195, 1, 78, 126, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 82, 3, 83, 9, 45, 9, 76, 84, 69, 82, 78, 65, 84, 69, - 32, 6, 166, 138, 41, 66, 2, 71, 3, 84, 10, 60, 4, 73, 71, 78, 32, 241, - 190, 23, 5, 89, 77, 66, 79, 76, 8, 50, 83, 182, 129, 26, 75, 197, 150, - 10, 2, 82, 85, 4, 160, 137, 38, 4, 77, 65, 76, 76, 203, 177, 2, 69, 22, - 66, 65, 214, 179, 37, 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 11, - 206, 138, 41, 65, 2, 73, 2, 77, 3, 87, 7, 11, 32, 4, 180, 235, 35, 3, 68, + 32, 6, 218, 249, 40, 66, 2, 71, 3, 84, 10, 60, 4, 73, 71, 78, 32, 241, + 178, 23, 5, 89, 77, 66, 79, 76, 8, 50, 83, 182, 245, 25, 75, 249, 145, + 10, 2, 82, 85, 4, 212, 248, 37, 4, 77, 65, 76, 76, 203, 177, 2, 69, 22, + 66, 65, 138, 163, 37, 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 11, + 130, 250, 40, 65, 2, 73, 2, 77, 3, 87, 7, 11, 32, 4, 232, 218, 35, 3, 68, 69, 80, 221, 205, 4, 5, 65, 82, 82, 73, 86, 152, 2, 212, 1, 4, 65, 82, 77, 32, 48, 20, 67, 72, 69, 77, 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 166, 28, 69, 60, 4, 73, 69, 78, 32, 208, 3, 2, - 76, 32, 82, 77, 109, 6, 84, 69, 82, 78, 65, 84, 4, 136, 140, 14, 3, 66, - 69, 76, 227, 137, 24, 67, 232, 1, 158, 2, 65, 246, 2, 66, 210, 1, 67, + 76, 32, 82, 77, 109, 6, 84, 69, 82, 78, 65, 84, 4, 212, 131, 14, 3, 66, + 69, 76, 203, 129, 24, 67, 232, 1, 158, 2, 65, 246, 2, 66, 210, 1, 67, 138, 3, 68, 98, 71, 38, 72, 132, 1, 4, 73, 82, 79, 78, 82, 76, 74, 77, 144, 1, 2, 78, 73, 34, 80, 176, 2, 3, 81, 85, 73, 74, 82, 146, 2, 83, - 210, 5, 84, 166, 1, 86, 200, 1, 2, 87, 65, 198, 162, 35, 85, 154, 220, 1, + 210, 5, 84, 166, 1, 86, 200, 1, 2, 87, 65, 250, 145, 35, 85, 154, 220, 1, 69, 194, 212, 1, 70, 219, 56, 79, 30, 194, 1, 76, 72, 3, 81, 85, 65, 204, - 8, 7, 78, 84, 73, 77, 79, 78, 89, 224, 157, 3, 3, 77, 65, 76, 240, 200, - 21, 3, 82, 83, 69, 204, 245, 13, 5, 85, 82, 73, 80, 73, 162, 136, 1, 83, - 183, 93, 73, 8, 224, 24, 2, 69, 77, 188, 213, 26, 4, 75, 65, 76, 73, 235, - 132, 14, 85, 10, 38, 32, 233, 136, 25, 3, 70, 79, 82, 8, 216, 7, 4, 86, - 73, 84, 65, 189, 191, 23, 4, 82, 69, 71, 73, 16, 148, 1, 7, 65, 84, 72, + 8, 7, 78, 84, 73, 77, 79, 78, 89, 224, 157, 3, 3, 77, 65, 76, 240, 188, + 21, 3, 82, 83, 69, 128, 241, 13, 5, 85, 82, 73, 80, 73, 162, 136, 1, 83, + 183, 93, 73, 8, 224, 24, 2, 69, 77, 240, 196, 26, 4, 75, 65, 76, 73, 235, + 132, 14, 85, 10, 38, 32, 233, 252, 24, 3, 70, 79, 82, 8, 216, 7, 4, 86, + 73, 84, 65, 189, 179, 23, 4, 82, 69, 71, 73, 16, 148, 1, 7, 65, 84, 72, 32, 79, 70, 32, 204, 6, 6, 73, 83, 77, 85, 84, 72, 144, 1, 4, 79, 82, 65, - 88, 164, 1, 4, 76, 65, 67, 75, 139, 198, 39, 82, 4, 218, 140, 17, 77, - 205, 227, 22, 5, 86, 65, 80, 79, 85, 28, 82, 65, 92, 6, 79, 80, 80, 69, - 82, 32, 34, 82, 201, 219, 39, 4, 73, 78, 78, 65, 6, 216, 143, 6, 2, 68, - 85, 140, 197, 33, 9, 80, 85, 84, 32, 77, 79, 82, 84, 85, 231, 28, 76, 4, - 230, 13, 65, 143, 207, 39, 79, 16, 72, 8, 79, 67, 85, 83, 32, 79, 70, 32, - 53, 6, 85, 67, 73, 66, 76, 69, 6, 228, 16, 5, 67, 79, 80, 80, 69, 171, - 198, 39, 73, 11, 11, 45, 8, 130, 254, 40, 50, 2, 51, 2, 52, 3, 53, 8, 44, - 2, 73, 83, 197, 255, 37, 3, 65, 89, 45, 6, 144, 2, 4, 83, 79, 76, 86, - 195, 255, 37, 84, 4, 170, 205, 30, 79, 247, 158, 10, 85, 8, 32, 4, 65, - 76, 70, 32, 47, 79, 4, 144, 236, 35, 2, 79, 85, 131, 211, 3, 68, 4, 200, - 137, 3, 4, 82, 83, 69, 32, 223, 185, 37, 85, 6, 56, 3, 32, 79, 82, 73, 7, - 45, 67, 79, 80, 80, 69, 82, 4, 211, 229, 26, 69, 4, 48, 3, 69, 65, 68, - 209, 233, 13, 3, 79, 68, 69, 2, 187, 141, 36, 32, 10, 120, 16, 69, 82, - 67, 85, 82, 89, 32, 83, 85, 66, 76, 73, 77, 65, 84, 69, 252, 217, 16, 4, - 65, 82, 67, 65, 191, 154, 22, 79, 7, 199, 248, 40, 45, 4, 234, 214, 39, + 88, 164, 1, 4, 76, 65, 67, 75, 191, 181, 39, 82, 4, 166, 132, 17, 77, + 181, 219, 22, 5, 86, 65, 80, 79, 85, 28, 82, 65, 92, 6, 79, 80, 80, 69, + 82, 32, 34, 82, 253, 202, 39, 4, 73, 78, 78, 65, 6, 216, 143, 6, 2, 68, + 85, 192, 180, 33, 9, 80, 85, 84, 32, 77, 79, 82, 84, 85, 231, 28, 76, 4, + 230, 13, 65, 195, 190, 39, 79, 16, 72, 8, 79, 67, 85, 83, 32, 79, 70, 32, + 53, 6, 85, 67, 73, 66, 76, 69, 6, 228, 16, 5, 67, 79, 80, 80, 69, 223, + 181, 39, 73, 11, 11, 45, 8, 182, 237, 40, 50, 2, 51, 2, 52, 3, 53, 8, 44, + 2, 73, 83, 249, 238, 37, 3, 65, 89, 45, 6, 144, 2, 4, 83, 79, 76, 86, + 247, 238, 37, 84, 4, 222, 188, 30, 79, 247, 158, 10, 85, 8, 32, 4, 65, + 76, 70, 32, 47, 79, 4, 196, 219, 35, 2, 79, 85, 131, 211, 3, 68, 4, 200, + 137, 3, 4, 82, 83, 69, 32, 147, 169, 37, 85, 6, 56, 3, 32, 79, 82, 73, 7, + 45, 67, 79, 80, 80, 69, 82, 4, 135, 213, 26, 69, 4, 48, 3, 69, 65, 68, + 157, 225, 13, 3, 79, 68, 69, 2, 239, 252, 35, 32, 10, 120, 16, 69, 82, + 67, 85, 82, 89, 32, 83, 85, 66, 76, 73, 77, 65, 84, 69, 200, 209, 16, 4, + 65, 82, 67, 65, 167, 146, 22, 79, 7, 251, 231, 40, 45, 4, 158, 198, 39, 84, 135, 120, 71, 14, 108, 11, 72, 73, 76, 79, 83, 79, 80, 72, 69, 82, - 83, 34, 79, 98, 85, 153, 177, 30, 6, 82, 69, 67, 73, 80, 73, 2, 209, 9, - 4, 32, 83, 85, 76, 6, 52, 4, 87, 68, 69, 82, 133, 189, 36, 3, 84, 32, 65, - 5, 173, 197, 39, 5, 69, 68, 32, 66, 82, 4, 252, 182, 34, 4, 84, 82, 69, - 70, 209, 174, 6, 3, 82, 73, 70, 4, 164, 229, 35, 5, 78, 84, 69, 83, 83, - 181, 247, 3, 4, 67, 75, 32, 76, 24, 58, 69, 149, 224, 26, 8, 79, 67, 75, + 83, 34, 79, 98, 85, 205, 160, 30, 6, 82, 69, 67, 73, 80, 73, 2, 209, 9, + 4, 32, 83, 85, 76, 6, 52, 4, 87, 68, 69, 82, 185, 172, 36, 3, 84, 32, 65, + 5, 225, 180, 39, 5, 69, 68, 32, 66, 82, 4, 176, 166, 34, 4, 84, 82, 69, + 70, 209, 174, 6, 3, 82, 73, 70, 4, 216, 212, 35, 5, 78, 84, 69, 83, 83, + 181, 247, 3, 4, 67, 75, 32, 76, 24, 58, 69, 201, 207, 26, 8, 79, 67, 75, 32, 83, 65, 76, 84, 20, 68, 5, 71, 85, 76, 85, 83, 164, 7, 3, 65, 76, 71, - 163, 171, 26, 84, 15, 32, 4, 32, 79, 70, 32, 71, 45, 6, 164, 223, 26, 8, - 65, 78, 84, 73, 77, 79, 78, 89, 143, 238, 12, 73, 6, 162, 244, 40, 50, 2, - 51, 3, 52, 34, 164, 1, 2, 65, 76, 194, 1, 84, 142, 1, 85, 180, 226, 17, - 2, 80, 73, 156, 186, 12, 2, 73, 76, 182, 192, 9, 79, 169, 22, 11, 67, 69, - 80, 84, 69, 82, 32, 79, 70, 32, 74, 8, 58, 84, 141, 200, 39, 8, 45, 65, + 215, 154, 26, 84, 15, 32, 4, 32, 79, 70, 32, 71, 45, 6, 216, 206, 26, 8, + 65, 78, 84, 73, 77, 79, 78, 89, 143, 238, 12, 73, 6, 214, 227, 40, 50, 2, + 51, 3, 52, 34, 164, 1, 2, 65, 76, 194, 1, 84, 142, 1, 85, 128, 218, 17, + 2, 80, 73, 132, 178, 12, 2, 73, 76, 182, 192, 9, 79, 169, 22, 11, 67, 69, + 80, 84, 69, 82, 32, 79, 70, 32, 74, 8, 58, 84, 193, 183, 39, 8, 45, 65, 77, 77, 79, 78, 73, 65, 7, 25, 4, 32, 79, 70, 32, 4, 52, 8, 67, 79, 80, - 80, 69, 82, 32, 65, 231, 5, 65, 2, 209, 171, 30, 7, 78, 84, 73, 77, 79, - 78, 73, 6, 236, 3, 8, 65, 82, 82, 69, 68, 32, 84, 82, 233, 215, 26, 19, + 80, 69, 82, 32, 65, 231, 5, 65, 2, 133, 155, 30, 7, 78, 84, 73, 77, 79, + 78, 73, 6, 236, 3, 8, 65, 82, 82, 69, 68, 32, 84, 82, 157, 199, 26, 19, 82, 65, 84, 85, 77, 32, 83, 85, 80, 69, 82, 32, 83, 84, 82, 65, 84, 85, 77, 12, 44, 6, 66, 76, 73, 77, 65, 84, 155, 1, 76, 10, 44, 5, 69, 32, 79, - 70, 32, 195, 159, 40, 73, 8, 68, 8, 83, 65, 76, 84, 32, 79, 70, 32, 130, - 3, 65, 231, 214, 27, 67, 4, 254, 2, 65, 231, 214, 27, 67, 2, 239, 245, - 39, 70, 12, 68, 3, 65, 82, 84, 32, 2, 73, 78, 34, 82, 201, 253, 38, 2, - 85, 84, 4, 11, 65, 4, 155, 216, 26, 82, 4, 254, 206, 35, 67, 187, 49, 32, - 2, 253, 169, 40, 2, 73, 68, 14, 50, 73, 209, 197, 38, 6, 69, 82, 68, 73, - 71, 82, 12, 64, 5, 78, 69, 71, 65, 82, 213, 214, 26, 5, 84, 82, 73, 79, - 76, 9, 44, 5, 32, 79, 70, 32, 65, 243, 234, 40, 45, 2, 141, 186, 24, 3, - 78, 84, 73, 4, 214, 173, 40, 84, 239, 61, 88, 6, 38, 77, 186, 213, 39, - 70, 155, 121, 82, 2, 223, 192, 39, 66, 22, 104, 7, 77, 79, 78, 83, 84, - 69, 82, 138, 1, 83, 205, 129, 36, 10, 67, 82, 65, 66, 32, 83, 84, 69, 80, + 70, 32, 247, 142, 40, 73, 8, 68, 8, 83, 65, 76, 84, 32, 79, 70, 32, 130, + 3, 65, 155, 198, 27, 67, 4, 254, 2, 65, 155, 198, 27, 67, 2, 163, 229, + 39, 70, 12, 68, 3, 65, 82, 84, 32, 2, 73, 78, 34, 82, 253, 236, 38, 2, + 85, 84, 4, 11, 65, 4, 207, 199, 26, 82, 4, 178, 190, 35, 67, 187, 49, 32, + 2, 177, 153, 40, 2, 73, 68, 14, 50, 73, 133, 181, 38, 6, 69, 82, 68, 73, + 71, 82, 12, 64, 5, 78, 69, 71, 65, 82, 137, 198, 26, 5, 84, 82, 73, 79, + 76, 9, 44, 5, 32, 79, 70, 32, 65, 167, 218, 40, 45, 2, 141, 174, 24, 3, + 78, 84, 73, 4, 138, 157, 40, 84, 239, 61, 88, 6, 38, 77, 238, 196, 39, + 70, 155, 121, 82, 2, 147, 176, 39, 66, 22, 104, 7, 77, 79, 78, 83, 84, + 69, 82, 138, 1, 83, 129, 241, 35, 10, 67, 82, 65, 66, 32, 83, 84, 69, 80, 80, 11, 11, 32, 8, 88, 6, 67, 76, 79, 83, 69, 68, 0, 4, 79, 80, 69, 78, - 173, 227, 36, 4, 83, 84, 69, 80, 2, 145, 138, 38, 3, 32, 74, 65, 8, 60, - 6, 80, 73, 68, 69, 82, 32, 57, 5, 81, 85, 73, 68, 32, 4, 196, 195, 29, 5, + 225, 210, 36, 4, 83, 84, 69, 80, 2, 197, 249, 37, 3, 32, 74, 65, 8, 60, + 6, 80, 73, 68, 69, 82, 32, 57, 5, 81, 85, 73, 68, 32, 4, 248, 178, 29, 5, 67, 82, 79, 85, 67, 175, 250, 1, 83, 4, 56, 6, 67, 76, 79, 83, 69, 68, 1, - 4, 79, 80, 69, 78, 2, 197, 249, 27, 5, 32, 84, 69, 78, 84, 4, 210, 133, - 34, 69, 253, 184, 4, 11, 65, 82, 79, 85, 78, 68, 45, 80, 82, 79, 70, 9, - 49, 10, 79, 83, 84, 32, 69, 81, 85, 65, 76, 32, 6, 32, 2, 84, 79, 247, - 198, 32, 79, 5, 219, 255, 6, 32, 4, 136, 247, 10, 3, 73, 86, 69, 221, - 195, 28, 5, 69, 32, 79, 78, 69, 12, 162, 1, 80, 128, 208, 29, 6, 69, 82, + 4, 79, 80, 69, 78, 2, 249, 232, 27, 5, 32, 84, 69, 78, 84, 4, 134, 245, + 33, 69, 253, 184, 4, 11, 65, 82, 79, 85, 78, 68, 45, 80, 82, 79, 70, 9, + 49, 10, 79, 83, 84, 32, 69, 81, 85, 65, 76, 32, 6, 32, 2, 84, 79, 171, + 182, 32, 79, 5, 219, 255, 6, 32, 4, 136, 243, 10, 3, 73, 86, 69, 145, + 183, 28, 5, 69, 32, 79, 78, 69, 12, 162, 1, 80, 180, 191, 29, 6, 69, 82, 73, 67, 65, 78, 204, 131, 6, 3, 66, 85, 76, 245, 254, 3, 16, 65, 76, 71, - 65, 77, 65, 84, 73, 79, 78, 32, 79, 82, 32, 67, 79, 6, 26, 72, 251, 144, - 37, 69, 4, 204, 254, 24, 3, 73, 84, 82, 203, 160, 15, 79, 194, 9, 92, 3, - 65, 84, 79, 182, 20, 71, 174, 1, 84, 190, 161, 25, 67, 190, 155, 12, 68, + 65, 77, 65, 84, 73, 79, 78, 32, 79, 82, 32, 67, 79, 6, 26, 72, 175, 128, + 37, 69, 4, 204, 242, 24, 3, 73, 84, 82, 255, 155, 15, 79, 194, 9, 92, 3, + 65, 84, 79, 182, 20, 71, 174, 1, 84, 190, 149, 25, 67, 242, 150, 12, 68, 223, 142, 3, 75, 144, 9, 112, 17, 76, 73, 65, 78, 32, 72, 73, 69, 82, 79, - 71, 76, 89, 80, 72, 32, 65, 145, 218, 39, 5, 77, 73, 67, 65, 76, 142, 9, + 71, 76, 89, 80, 72, 32, 65, 197, 201, 39, 5, 77, 73, 67, 65, 76, 142, 9, 70, 48, 138, 4, 49, 198, 2, 50, 162, 3, 51, 174, 5, 52, 163, 3, 53, 222, - 1, 106, 50, 102, 52, 110, 54, 102, 57, 182, 7, 51, 254, 246, 11, 49, 142, - 159, 23, 48, 130, 2, 53, 2, 55, 3, 56, 22, 158, 206, 36, 54, 242, 145, 4, - 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 28, 202, 191, - 12, 54, 242, 141, 24, 49, 2, 53, 242, 145, 4, 48, 2, 50, 2, 51, 2, 52, 2, - 55, 2, 56, 3, 57, 26, 162, 166, 12, 54, 158, 184, 28, 48, 2, 49, 2, 50, - 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 24, 234, 203, 36, 55, 2, 56, + 1, 106, 50, 102, 52, 110, 54, 102, 57, 182, 7, 51, 222, 242, 11, 49, 226, + 146, 23, 48, 130, 2, 53, 2, 55, 3, 56, 22, 210, 189, 36, 54, 242, 145, 4, + 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 28, 170, 187, + 12, 54, 198, 129, 24, 49, 2, 53, 242, 145, 4, 48, 2, 50, 2, 51, 2, 52, 2, + 55, 2, 56, 3, 57, 26, 130, 162, 12, 54, 242, 171, 28, 48, 2, 49, 2, 50, + 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 24, 158, 187, 36, 55, 2, 56, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 57, 232, 1, - 98, 48, 114, 49, 206, 170, 12, 50, 2, 51, 182, 242, 22, 52, 2, 53, 2, 54, - 2, 55, 2, 56, 3, 57, 42, 242, 163, 12, 52, 2, 55, 190, 24, 53, 242, 141, - 24, 48, 2, 49, 2, 50, 242, 145, 4, 51, 2, 54, 2, 56, 3, 57, 26, 190, 187, - 12, 48, 242, 141, 24, 53, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, - 55, 2, 56, 3, 57, 222, 1, 102, 48, 110, 49, 102, 57, 210, 1, 56, 250, - 152, 12, 50, 2, 54, 146, 255, 22, 51, 2, 52, 2, 53, 3, 55, 28, 230, 185, - 12, 50, 242, 141, 24, 55, 2, 57, 242, 145, 4, 48, 2, 49, 2, 51, 2, 52, 2, - 53, 2, 54, 3, 56, 24, 234, 198, 36, 53, 2, 54, 242, 145, 4, 48, 2, 49, 2, - 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, 24, 134, 198, 36, 52, 2, 57, 242, + 98, 48, 114, 49, 174, 166, 12, 50, 2, 51, 138, 230, 22, 52, 2, 53, 2, 54, + 2, 55, 2, 56, 3, 57, 42, 210, 159, 12, 52, 2, 55, 190, 24, 53, 198, 129, + 24, 48, 2, 49, 2, 50, 242, 145, 4, 51, 2, 54, 2, 56, 3, 57, 26, 158, 183, + 12, 48, 198, 129, 24, 53, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, + 55, 2, 56, 3, 57, 222, 1, 102, 48, 110, 49, 102, 57, 210, 1, 56, 218, + 148, 12, 50, 2, 54, 230, 242, 22, 51, 2, 52, 2, 53, 3, 55, 28, 198, 181, + 12, 50, 198, 129, 24, 55, 2, 57, 242, 145, 4, 48, 2, 49, 2, 51, 2, 52, 2, + 53, 2, 54, 3, 56, 24, 158, 182, 36, 53, 2, 54, 242, 145, 4, 48, 2, 49, 2, + 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, 24, 186, 181, 36, 52, 2, 57, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 53, 2, 54, 2, 55, 3, 56, 228, 1, 102, - 48, 2, 50, 2, 53, 102, 51, 110, 54, 102, 56, 162, 1, 57, 174, 129, 12, - 55, 138, 147, 23, 49, 3, 52, 22, 182, 196, 36, 57, 242, 145, 4, 48, 2, - 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 30, 166, 157, 12, - 54, 226, 204, 8, 50, 190, 235, 19, 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 55, - 2, 56, 3, 57, 24, 230, 194, 36, 52, 2, 56, 242, 145, 4, 48, 2, 49, 2, 50, - 2, 51, 2, 53, 2, 54, 2, 55, 3, 57, 26, 98, 51, 162, 193, 36, 49, 2, 54, - 242, 145, 4, 48, 2, 50, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 4, 196, 154, - 21, 6, 32, 82, 65, 32, 79, 82, 203, 184, 19, 65, 20, 128, 168, 40, 3, 51, + 48, 2, 50, 2, 53, 102, 51, 110, 54, 102, 56, 162, 1, 57, 142, 253, 11, + 55, 222, 134, 23, 49, 3, 52, 22, 234, 179, 36, 57, 242, 145, 4, 48, 2, + 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 30, 134, 153, 12, + 54, 130, 197, 8, 50, 242, 230, 19, 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 55, + 2, 56, 3, 57, 24, 154, 178, 36, 52, 2, 56, 242, 145, 4, 48, 2, 49, 2, 50, + 2, 51, 2, 53, 2, 54, 2, 55, 3, 57, 26, 98, 51, 214, 176, 36, 49, 2, 54, + 242, 145, 4, 48, 2, 50, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 4, 196, 142, + 21, 6, 32, 82, 65, 32, 79, 82, 255, 179, 19, 65, 20, 180, 151, 40, 3, 51, 32, 69, 210, 42, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, - 57, 202, 1, 102, 49, 210, 1, 53, 178, 241, 20, 57, 222, 159, 14, 48, 2, - 50, 2, 51, 2, 52, 2, 54, 2, 55, 3, 56, 22, 90, 48, 162, 208, 40, 49, 2, + 57, 202, 1, 102, 49, 210, 1, 53, 178, 229, 20, 57, 146, 155, 14, 48, 2, + 50, 2, 51, 2, 52, 2, 54, 2, 55, 3, 56, 22, 90, 48, 214, 191, 40, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 4, 60, 6, 32, 66, - 69, 71, 73, 78, 1, 5, 65, 32, 69, 78, 68, 2, 241, 201, 16, 8, 32, 76, 79, - 71, 79, 71, 82, 65, 24, 186, 189, 36, 48, 2, 55, 242, 145, 4, 49, 2, 50, - 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 60, 226, 167, 33, 51, 198, 230, - 1, 48, 130, 2, 49, 3, 50, 14, 96, 2, 76, 69, 182, 176, 2, 85, 128, 200, + 69, 71, 73, 78, 1, 5, 65, 32, 69, 78, 68, 2, 189, 193, 16, 8, 32, 76, 79, + 71, 79, 71, 82, 65, 24, 238, 172, 36, 48, 2, 55, 242, 145, 4, 49, 2, 50, + 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 60, 150, 151, 33, 51, 198, 230, + 1, 48, 130, 2, 49, 3, 50, 14, 96, 2, 76, 69, 182, 176, 2, 85, 180, 183, 32, 2, 83, 84, 130, 239, 3, 69, 217, 168, 1, 2, 82, 89, 7, 33, 6, 32, 87, - 73, 84, 72, 32, 4, 254, 154, 32, 83, 135, 195, 4, 85, 31, 76, 4, 69, 78, - 78, 65, 41, 11, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 32, 5, 253, 159, - 37, 5, 32, 87, 73, 84, 72, 24, 90, 84, 162, 143, 7, 67, 58, 68, 122, 71, - 138, 4, 79, 233, 163, 28, 5, 73, 78, 84, 69, 71, 12, 84, 15, 82, 73, 65, - 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 68, 32, 223, 147, 7, 79, 10, 112, + 73, 84, 72, 32, 4, 178, 138, 32, 83, 135, 195, 4, 85, 31, 76, 4, 69, 78, + 78, 65, 41, 11, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 32, 5, 177, 143, + 37, 5, 32, 87, 73, 84, 72, 24, 90, 84, 162, 139, 7, 67, 58, 68, 122, 71, + 138, 4, 79, 157, 151, 28, 5, 73, 78, 84, 69, 71, 12, 84, 15, 82, 73, 65, + 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 68, 32, 223, 143, 7, 79, 10, 112, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 12, 6, 66, 79, 84, 84, 79, 77, 0, 3, - 84, 79, 80, 131, 147, 7, 79, 2, 11, 84, 2, 209, 235, 37, 7, 32, 85, 45, + 84, 79, 80, 131, 143, 7, 79, 2, 11, 84, 2, 133, 219, 37, 7, 32, 85, 45, 83, 72, 65, 80, 160, 1, 128, 1, 20, 76, 32, 70, 85, 78, 67, 84, 73, 79, - 78, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 206, 15, 79, 38, 80, 147, - 184, 40, 67, 140, 1, 222, 2, 67, 186, 1, 68, 190, 2, 73, 44, 4, 65, 76, + 78, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 206, 15, 79, 38, 80, 199, + 167, 40, 67, 140, 1, 222, 2, 67, 186, 1, 68, 190, 2, 73, 44, 4, 65, 76, 80, 72, 0, 4, 79, 77, 69, 71, 32, 4, 74, 79, 84, 32, 36, 4, 76, 69, 70, 84, 68, 2, 81, 85, 218, 3, 82, 54, 83, 92, 4, 69, 80, 83, 73, 32, 6, 66, - 65, 67, 75, 83, 76, 76, 2, 85, 80, 172, 170, 16, 12, 71, 82, 69, 65, 84, - 69, 82, 45, 84, 72, 65, 78, 0, 5, 84, 73, 76, 68, 69, 163, 168, 20, 90, - 14, 64, 6, 73, 82, 67, 76, 69, 32, 133, 161, 39, 4, 79, 77, 77, 65, 12, - 80, 2, 83, 84, 166, 242, 19, 68, 226, 137, 6, 66, 254, 216, 10, 85, 207, - 158, 3, 74, 4, 198, 157, 39, 73, 227, 109, 65, 22, 76, 2, 69, 76, 120, 3, - 79, 87, 78, 201, 162, 32, 6, 73, 65, 77, 79, 78, 68, 10, 30, 32, 53, 3, - 84, 65, 32, 6, 146, 241, 19, 68, 142, 234, 16, 84, 131, 191, 1, 83, 4, - 186, 211, 36, 85, 179, 198, 1, 83, 10, 22, 32, 167, 9, 87, 8, 52, 5, 84, - 65, 67, 75, 32, 182, 1, 83, 227, 6, 67, 4, 198, 210, 36, 85, 207, 158, 3, - 74, 6, 40, 2, 79, 84, 185, 176, 32, 2, 45, 66, 4, 11, 65, 5, 167, 161, - 32, 32, 4, 250, 238, 19, 68, 223, 226, 16, 85, 4, 28, 2, 32, 83, 187, 7, - 87, 2, 181, 151, 38, 4, 72, 79, 69, 32, 46, 44, 2, 65, 68, 133, 3, 4, 79, + 65, 67, 75, 83, 76, 76, 2, 85, 80, 248, 161, 16, 12, 71, 82, 69, 65, 84, + 69, 82, 45, 84, 72, 65, 78, 0, 5, 84, 73, 76, 68, 69, 139, 160, 20, 90, + 14, 64, 6, 73, 82, 67, 76, 69, 32, 185, 144, 39, 4, 79, 77, 77, 65, 12, + 80, 2, 83, 84, 166, 230, 19, 68, 150, 133, 6, 66, 254, 216, 10, 85, 207, + 158, 3, 74, 4, 250, 140, 39, 73, 227, 109, 65, 22, 76, 2, 69, 76, 120, 3, + 79, 87, 78, 253, 145, 32, 6, 73, 65, 77, 79, 78, 68, 10, 30, 32, 53, 3, + 84, 65, 32, 6, 146, 229, 19, 68, 194, 229, 16, 84, 131, 191, 1, 83, 4, + 238, 194, 36, 85, 179, 198, 1, 83, 10, 22, 32, 167, 9, 87, 8, 52, 5, 84, + 65, 67, 75, 32, 182, 1, 83, 227, 6, 67, 4, 250, 193, 36, 85, 207, 158, 3, + 74, 6, 40, 2, 79, 84, 237, 159, 32, 2, 45, 66, 4, 11, 65, 5, 219, 144, + 32, 32, 4, 250, 226, 19, 68, 147, 222, 16, 85, 4, 28, 2, 32, 83, 187, 7, + 87, 2, 233, 134, 38, 4, 72, 79, 69, 32, 46, 44, 2, 65, 68, 133, 3, 4, 79, 84, 69, 32, 43, 11, 32, 40, 178, 1, 67, 38, 68, 92, 2, 85, 80, 36, 2, 76, - 69, 210, 208, 6, 81, 228, 229, 13, 3, 78, 79, 84, 22, 69, 154, 190, 5, - 66, 174, 163, 7, 83, 226, 142, 5, 71, 250, 115, 82, 199, 81, 74, 4, 246, - 233, 38, 73, 151, 132, 1, 79, 12, 54, 73, 36, 3, 79, 87, 78, 225, 128, - 37, 2, 69, 76, 4, 202, 139, 32, 86, 255, 242, 6, 65, 4, 230, 138, 4, 32, - 211, 144, 35, 87, 4, 166, 167, 38, 83, 215, 115, 70, 4, 154, 181, 12, 81, - 163, 152, 24, 85, 4, 184, 3, 5, 73, 71, 72, 84, 87, 239, 153, 40, 72, 10, - 88, 5, 69, 77, 73, 67, 79, 34, 76, 34, 84, 169, 179, 12, 7, 81, 85, 73, - 83, 72, 32, 81, 2, 181, 155, 32, 3, 76, 79, 78, 2, 149, 151, 39, 3, 65, - 83, 72, 4, 212, 170, 16, 2, 65, 82, 175, 173, 7, 73, 12, 22, 32, 171, 1, - 87, 10, 78, 67, 36, 5, 84, 65, 67, 75, 32, 221, 232, 39, 6, 83, 72, 79, - 69, 32, 74, 2, 129, 215, 23, 4, 65, 82, 69, 84, 6, 178, 231, 19, 68, 234, - 159, 17, 79, 195, 225, 2, 74, 2, 221, 151, 37, 6, 65, 82, 68, 83, 32, 86, - 4, 182, 145, 34, 83, 135, 215, 5, 76, 14, 26, 76, 93, 2, 82, 79, 4, 164, - 201, 26, 14, 73, 67, 65, 84, 73, 79, 78, 32, 80, 82, 79, 71, 82, 65, 139, - 217, 12, 69, 10, 112, 9, 88, 73, 77, 65, 84, 69, 76, 89, 32, 237, 153, + 69, 210, 208, 6, 81, 228, 217, 13, 3, 78, 79, 84, 22, 69, 206, 185, 5, + 66, 174, 163, 7, 83, 226, 142, 5, 71, 250, 115, 82, 199, 81, 74, 4, 170, + 217, 38, 73, 151, 132, 1, 79, 12, 54, 73, 36, 3, 79, 87, 78, 149, 240, + 36, 2, 69, 76, 4, 254, 250, 31, 86, 255, 242, 6, 65, 4, 230, 138, 4, 32, + 135, 128, 35, 87, 4, 218, 150, 38, 83, 215, 115, 70, 4, 230, 172, 12, 81, + 139, 144, 24, 85, 4, 184, 3, 5, 73, 71, 72, 84, 87, 163, 137, 40, 72, 10, + 88, 5, 69, 77, 73, 67, 79, 34, 76, 34, 84, 245, 170, 12, 7, 81, 85, 73, + 83, 72, 32, 81, 2, 233, 138, 32, 3, 76, 79, 78, 2, 201, 134, 39, 3, 65, + 83, 72, 4, 160, 162, 16, 2, 65, 82, 227, 169, 7, 73, 12, 22, 32, 171, 1, + 87, 10, 78, 67, 36, 5, 84, 65, 67, 75, 32, 145, 216, 39, 6, 83, 72, 79, + 69, 32, 74, 2, 129, 203, 23, 4, 65, 82, 69, 84, 6, 178, 219, 19, 68, 158, + 155, 17, 79, 195, 225, 2, 74, 2, 145, 135, 37, 6, 65, 82, 68, 83, 32, 86, + 4, 234, 128, 34, 83, 135, 215, 5, 76, 14, 26, 76, 93, 2, 82, 79, 4, 216, + 184, 26, 14, 73, 67, 65, 84, 73, 79, 78, 32, 80, 82, 79, 71, 82, 65, 139, + 217, 12, 69, 10, 112, 9, 88, 73, 77, 65, 84, 69, 76, 89, 32, 161, 137, 40, 13, 65, 67, 72, 69, 83, 32, 84, 72, 69, 32, 76, 73, 77, 8, 76, 6, 69, - 81, 85, 65, 76, 32, 137, 156, 25, 7, 66, 85, 84, 32, 78, 79, 84, 6, 32, - 2, 84, 79, 183, 150, 32, 79, 5, 237, 201, 26, 13, 32, 79, 82, 32, 84, 72, + 81, 85, 65, 76, 32, 137, 144, 25, 7, 66, 85, 84, 32, 78, 79, 84, 6, 32, + 2, 84, 79, 235, 133, 32, 79, 5, 161, 185, 26, 13, 32, 79, 82, 32, 84, 72, 69, 32, 73, 77, 65, 71, 69, 192, 23, 148, 1, 4, 65, 66, 73, 67, 240, 131, 2, 7, 77, 69, 78, 73, 65, 78, 32, 224, 12, 3, 82, 79, 87, 228, 3, 2, 84, - 73, 150, 137, 37, 73, 135, 150, 1, 67, 238, 21, 54, 32, 173, 130, 2, 7, + 73, 202, 248, 36, 73, 135, 150, 1, 67, 238, 21, 54, 32, 173, 130, 2, 7, 45, 73, 78, 68, 73, 67, 32, 210, 21, 150, 3, 66, 134, 1, 67, 238, 1, 68, 138, 3, 69, 186, 1, 70, 212, 1, 2, 72, 65, 104, 5, 75, 65, 83, 82, 65, 86, 76, 212, 180, 1, 2, 77, 65, 204, 18, 7, 78, 85, 77, 66, 69, 82, 32, 36, 5, 79, 80, 69, 78, 32, 82, 80, 238, 1, 82, 208, 2, 6, 73, 78, 86, 69, - 82, 84, 98, 83, 146, 33, 84, 202, 4, 86, 228, 206, 17, 9, 87, 65, 86, 89, - 32, 72, 65, 77, 90, 230, 142, 18, 81, 197, 198, 1, 6, 90, 87, 65, 82, 65, - 75, 4, 216, 214, 1, 7, 65, 83, 69, 76, 73, 78, 69, 233, 205, 37, 17, 73, + 82, 84, 98, 83, 146, 33, 84, 202, 4, 86, 228, 194, 17, 9, 87, 65, 86, 89, + 32, 72, 65, 77, 90, 154, 138, 18, 81, 197, 198, 1, 6, 90, 87, 65, 82, 65, + 75, 4, 216, 214, 1, 7, 65, 83, 69, 76, 73, 78, 69, 157, 189, 37, 17, 73, 66, 76, 73, 67, 65, 76, 32, 69, 78, 68, 32, 79, 70, 32, 86, 69, 16, 44, - 2, 79, 77, 81, 5, 85, 82, 76, 89, 32, 4, 192, 193, 19, 11, 66, 73, 78, - 73, 78, 71, 32, 65, 76, 69, 70, 199, 234, 20, 77, 12, 72, 4, 68, 65, 77, - 77, 0, 4, 70, 65, 84, 72, 1, 4, 75, 65, 83, 82, 4, 11, 65, 5, 251, 224, - 38, 84, 26, 158, 1, 65, 108, 5, 79, 85, 66, 76, 69, 216, 246, 23, 5, 69, - 67, 73, 77, 65, 149, 198, 9, 16, 73, 83, 80, 85, 84, 69, 68, 32, 69, 78, - 68, 32, 79, 70, 32, 65, 14, 36, 3, 77, 77, 65, 231, 223, 33, 84, 13, 22, - 32, 219, 5, 84, 6, 242, 238, 1, 73, 54, 77, 251, 149, 37, 87, 8, 22, 32, + 2, 79, 77, 81, 5, 85, 82, 76, 89, 32, 4, 192, 181, 19, 11, 66, 73, 78, + 73, 78, 71, 32, 65, 76, 69, 70, 251, 229, 20, 77, 12, 72, 4, 68, 65, 77, + 77, 0, 4, 70, 65, 84, 72, 1, 4, 75, 65, 83, 82, 4, 11, 65, 5, 175, 208, + 38, 84, 26, 158, 1, 65, 108, 5, 79, 85, 66, 76, 69, 216, 234, 23, 5, 69, + 67, 73, 77, 65, 201, 193, 9, 16, 73, 83, 80, 85, 84, 69, 68, 32, 69, 78, + 68, 32, 79, 70, 32, 65, 14, 36, 3, 77, 77, 65, 155, 207, 33, 84, 13, 22, + 32, 219, 5, 84, 6, 242, 238, 1, 73, 54, 77, 175, 133, 37, 87, 8, 22, 32, 191, 4, 68, 6, 184, 210, 1, 17, 82, 73, 71, 72, 84, 32, 65, 82, 82, 79, 87, 72, 69, 65, 68, 32, 65, 191, 30, 86, 8, 88, 12, 77, 80, 84, 89, 32, - 67, 69, 78, 84, 82, 69, 32, 57, 6, 78, 68, 32, 79, 70, 32, 4, 140, 212, - 37, 4, 72, 73, 71, 72, 1, 3, 76, 79, 87, 4, 210, 139, 30, 84, 139, 175, + 67, 69, 78, 84, 82, 69, 32, 57, 6, 78, 68, 32, 79, 70, 32, 4, 192, 195, + 37, 4, 72, 73, 71, 72, 1, 3, 76, 79, 87, 4, 134, 251, 29, 84, 139, 175, 3, 65, 22, 84, 4, 65, 84, 72, 65, 166, 222, 1, 79, 148, 232, 4, 3, 73, - 86, 69, 143, 140, 31, 85, 17, 22, 32, 139, 2, 84, 10, 52, 5, 87, 73, 84, - 72, 32, 238, 234, 1, 73, 55, 77, 6, 170, 212, 38, 84, 166, 82, 68, 203, + 86, 69, 195, 251, 30, 85, 17, 22, 32, 139, 2, 84, 10, 52, 5, 87, 73, 84, + 72, 32, 238, 234, 1, 73, 55, 77, 6, 222, 195, 38, 84, 166, 82, 68, 203, 47, 82, 6, 72, 13, 76, 70, 32, 77, 65, 68, 68, 65, 32, 79, 86, 69, 82, - 235, 16, 77, 2, 221, 238, 17, 2, 32, 77, 13, 18, 32, 43, 84, 6, 166, 72, + 235, 16, 77, 2, 221, 226, 17, 2, 32, 77, 13, 18, 32, 43, 84, 6, 166, 72, 87, 158, 161, 1, 73, 55, 77, 4, 253, 82, 2, 65, 78, 174, 16, 84, 5, 65, 82, 71, 69, 32, 146, 1, 69, 133, 91, 8, 73, 71, 65, 84, 85, 82, 69, 32, - 8, 64, 10, 82, 79, 85, 78, 68, 32, 68, 79, 84, 32, 179, 143, 11, 67, 6, - 148, 143, 11, 6, 73, 78, 83, 73, 68, 69, 146, 243, 26, 66, 131, 165, 1, - 65, 136, 8, 80, 5, 84, 84, 69, 82, 32, 137, 174, 7, 9, 70, 84, 32, 65, + 8, 64, 10, 82, 79, 85, 78, 68, 32, 68, 79, 84, 32, 179, 139, 11, 67, 6, + 148, 139, 11, 6, 73, 78, 83, 73, 68, 69, 198, 230, 26, 66, 131, 165, 1, + 65, 136, 8, 80, 5, 84, 84, 69, 82, 32, 137, 170, 7, 9, 70, 84, 32, 65, 82, 82, 79, 87, 72, 132, 8, 210, 2, 65, 240, 10, 2, 66, 69, 150, 4, 68, 186, 5, 70, 246, 4, 71, 226, 2, 72, 156, 9, 2, 74, 69, 158, 1, 75, 138, 5, 76, 226, 2, 77, 154, 1, 78, 160, 3, 3, 80, 69, 72, 176, 1, 3, 81, 65, 70, 214, 1, 82, 234, 3, 83, 162, 9, 84, 214, 8, 85, 148, 2, 2, 86, 69, 28, 3, 87, 65, 87, 202, 1, 89, 246, 3, 79, 140, 3, 2, 90, 65, 31, 69, 112, 92, 7, 70, 82, 73, 67, 65, 78, 32, 92, 2, 73, 78, 144, 2, 3, 76, 69, - 70, 207, 156, 40, 69, 8, 52, 3, 81, 65, 70, 166, 169, 33, 70, 183, 203, + 70, 131, 140, 40, 69, 8, 52, 3, 81, 65, 70, 218, 152, 33, 70, 183, 203, 3, 78, 5, 153, 64, 5, 32, 87, 73, 84, 72, 21, 11, 32, 18, 72, 6, 87, 73, 84, 72, 32, 84, 242, 172, 1, 70, 202, 43, 73, 211, 9, 77, 10, 60, 10, 72, - 82, 69, 69, 32, 68, 79, 84, 83, 32, 187, 54, 87, 6, 220, 154, 15, 17, 80, - 79, 73, 78, 84, 73, 78, 71, 32, 68, 79, 87, 78, 87, 65, 82, 68, 250, 224, + 82, 69, 69, 32, 68, 79, 84, 83, 32, 187, 54, 87, 6, 168, 146, 15, 17, 80, + 79, 73, 78, 84, 73, 78, 71, 32, 68, 79, 87, 78, 87, 65, 82, 68, 226, 216, 22, 66, 131, 165, 1, 65, 83, 11, 32, 80, 70, 87, 228, 44, 6, 77, 65, 75, 83, 85, 82, 130, 126, 70, 231, 52, 73, 70, 48, 4, 73, 84, 72, 32, 177, 44, 3, 65, 83, 76, 64, 192, 2, 9, 65, 84, 84, 65, 67, 72, 69, 68, 32, 220, 1, 19, 82, 73, 71, 72, 84, 32, 77, 73, 68, 68, 76, 69, 32, 83, 84, 82, 79, 75, 69, 188, 1, 6, 72, 65, 77, 90, 65, 32, 44, 8, 87, 65, 86, 89, - 32, 72, 65, 77, 214, 70, 69, 204, 1, 4, 77, 65, 68, 68, 180, 220, 36, 9, + 32, 72, 65, 77, 214, 70, 69, 204, 1, 4, 77, 65, 68, 68, 232, 203, 36, 9, 76, 69, 70, 84, 32, 77, 73, 68, 68, 159, 240, 1, 68, 28, 204, 1, 17, 66, 79, 84, 84, 79, 77, 32, 82, 73, 71, 72, 84, 32, 75, 65, 83, 82, 0, 14, 84, 79, 80, 32, 82, 73, 71, 72, 84, 32, 70, 65, 84, 72, 94, 82, 56, 3, - 76, 69, 70, 130, 214, 1, 75, 143, 182, 32, 70, 6, 11, 65, 7, 29, 5, 32, - 65, 78, 68, 32, 4, 196, 205, 19, 3, 76, 69, 70, 243, 200, 19, 68, 8, 52, + 76, 69, 70, 130, 214, 1, 75, 195, 165, 32, 70, 6, 11, 65, 7, 29, 5, 32, + 65, 78, 68, 32, 4, 196, 193, 19, 3, 76, 69, 70, 167, 196, 19, 68, 8, 52, 3, 73, 71, 72, 213, 227, 1, 4, 79, 85, 78, 68, 4, 17, 2, 84, 32, 4, 130, 189, 1, 82, 219, 37, 72, 12, 234, 72, 65, 37, 5, 66, 69, 76, 79, 87, 4, - 171, 224, 37, 90, 50, 22, 72, 179, 64, 69, 41, 22, 32, 155, 64, 69, 28, + 223, 207, 37, 90, 50, 22, 72, 179, 64, 69, 41, 22, 32, 155, 64, 69, 28, 68, 5, 87, 73, 84, 72, 32, 158, 163, 1, 70, 202, 43, 73, 211, 9, 77, 20, 116, 6, 83, 77, 65, 76, 76, 32, 34, 84, 254, 18, 73, 160, 33, 10, 68, 79, - 84, 32, 66, 69, 76, 79, 87, 32, 135, 21, 72, 6, 150, 39, 77, 231, 224, + 84, 32, 66, 69, 76, 79, 87, 32, 135, 21, 72, 6, 150, 39, 77, 231, 212, 23, 86, 8, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 233, 48, 7, 87, 79, 32, 68, 79, 84, 83, 6, 144, 1, 22, 80, 79, 73, 78, 84, 73, 78, 71, 32, 85, 80, 87, 65, 82, 68, 83, 32, 66, 69, 76, 79, 87, 201, 54, 8, - 72, 79, 82, 73, 90, 79, 78, 84, 5, 231, 141, 15, 32, 78, 90, 65, 136, 4, + 72, 79, 82, 73, 90, 79, 78, 84, 5, 179, 133, 15, 32, 78, 90, 65, 136, 4, 2, 68, 65, 40, 7, 79, 84, 76, 69, 83, 83, 32, 250, 27, 89, 147, 26, 85, 44, 34, 76, 254, 3, 72, 147, 46, 68, 27, 11, 32, 24, 56, 5, 87, 73, 84, 72, 32, 186, 158, 1, 70, 231, 52, 73, 20, 108, 9, 73, 78, 86, 69, 82, 84, - 69, 68, 32, 34, 84, 168, 1, 3, 68, 79, 84, 146, 145, 12, 70, 131, 171, - 27, 82, 4, 238, 14, 83, 239, 255, 39, 86, 8, 132, 1, 10, 72, 82, 69, 69, + 69, 68, 32, 34, 84, 168, 1, 3, 68, 79, 84, 222, 136, 12, 70, 235, 162, + 27, 82, 4, 238, 14, 83, 163, 239, 39, 86, 8, 132, 1, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 33, 18, 87, 79, 32, 68, 79, 84, 83, 32, 86, 69, - 82, 84, 73, 67, 65, 76, 76, 89, 4, 226, 54, 65, 231, 180, 37, 66, 4, 33, - 6, 32, 66, 69, 76, 79, 87, 5, 141, 187, 15, 11, 32, 65, 78, 68, 32, 83, - 77, 65, 76, 76, 32, 12, 22, 72, 195, 63, 76, 6, 151, 54, 65, 6, 170, 150, + 82, 84, 73, 67, 65, 76, 76, 89, 4, 226, 54, 65, 155, 164, 37, 66, 4, 33, + 6, 32, 66, 69, 76, 79, 87, 5, 217, 178, 15, 11, 32, 65, 78, 68, 32, 83, + 77, 65, 76, 76, 32, 12, 22, 72, 195, 63, 76, 6, 151, 54, 65, 6, 222, 133, 33, 66, 2, 70, 175, 244, 5, 81, 44, 60, 8, 65, 82, 83, 73, 32, 89, 69, 72, 169, 2, 2, 69, 72, 23, 11, 32, 20, 68, 5, 87, 73, 84, 72, 32, 182, 153, 1, 70, 202, 43, 73, 211, 9, 77, 12, 144, 1, 28, 69, 88, 84, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, 32, 68, 73, 71, 73, 84, 32, 30, 84, 247, 39, 73, 6, 250, 8, 70, 207, 50, 84, 4, - 190, 169, 7, 72, 199, 220, 7, 87, 23, 11, 32, 20, 68, 5, 87, 73, 84, 72, + 190, 165, 7, 72, 147, 216, 7, 87, 23, 11, 32, 20, 68, 5, 87, 73, 84, 72, 32, 142, 151, 1, 70, 202, 43, 73, 211, 9, 77, 12, 32, 4, 68, 79, 84, 32, - 51, 84, 6, 214, 40, 66, 197, 223, 15, 4, 77, 79, 86, 69, 6, 64, 10, 72, - 82, 69, 69, 32, 68, 79, 84, 83, 32, 191, 213, 37, 87, 4, 210, 17, 80, - 203, 211, 37, 66, 44, 72, 2, 65, 70, 160, 1, 4, 72, 65, 73, 78, 238, 20, - 85, 227, 238, 38, 82, 19, 11, 32, 16, 68, 5, 87, 73, 84, 72, 32, 182, - 148, 1, 70, 202, 43, 73, 211, 9, 77, 8, 242, 23, 84, 210, 156, 39, 82, + 51, 84, 6, 214, 40, 66, 145, 215, 15, 4, 77, 79, 86, 69, 6, 64, 10, 72, + 82, 69, 69, 32, 68, 79, 84, 83, 32, 243, 196, 37, 87, 4, 210, 17, 80, + 255, 194, 37, 66, 44, 72, 2, 65, 70, 160, 1, 4, 72, 65, 73, 78, 238, 20, + 85, 151, 222, 38, 82, 19, 11, 32, 16, 68, 5, 87, 73, 84, 72, 32, 182, + 148, 1, 70, 202, 43, 73, 211, 9, 77, 8, 242, 23, 84, 134, 140, 39, 82, 241, 32, 8, 73, 78, 86, 69, 82, 84, 69, 68, 15, 11, 32, 12, 68, 5, 87, 73, 84, 72, 32, 150, 147, 1, 70, 202, 43, 73, 211, 9, 77, 4, 214, 37, 84, - 135, 140, 27, 68, 82, 78, 65, 236, 5, 2, 69, 72, 161, 2, 9, 73, 71, 72, + 187, 251, 26, 68, 82, 78, 65, 236, 5, 2, 69, 72, 161, 2, 9, 73, 71, 72, 32, 72, 65, 77, 90, 65, 34, 34, 72, 201, 48, 3, 77, 90, 65, 31, 11, 32, 28, 68, 5, 87, 73, 84, 72, 32, 174, 145, 1, 70, 202, 43, 73, 211, 9, 77, 20, 132, 2, 29, 69, 88, 84, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, 32, 68, 73, 71, 73, 84, 32, 70, 30, 73, 92, 24, 83, 77, 65, 76, 76, 32, 65, 82, 65, 66, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 84, 65, 72, 32, 62, 84, 143, 53, 72, 2, 129, 199, 1, 2, 79, - 85, 2, 45, 9, 78, 86, 69, 82, 84, 69, 68, 32, 83, 2, 209, 206, 37, 6, 77, - 65, 76, 76, 32, 86, 6, 26, 65, 187, 221, 37, 66, 4, 134, 31, 78, 191, - 227, 38, 66, 8, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 33, 8, - 87, 79, 32, 68, 79, 84, 83, 32, 4, 242, 8, 80, 203, 248, 38, 65, 4, 128, - 129, 39, 8, 86, 69, 82, 84, 73, 67, 65, 76, 27, 65, 41, 11, 32, 38, 144, + 85, 2, 45, 9, 78, 86, 69, 82, 84, 69, 68, 32, 83, 2, 133, 190, 37, 6, 77, + 65, 76, 76, 32, 86, 6, 26, 65, 239, 204, 37, 66, 4, 134, 31, 78, 243, + 210, 38, 66, 8, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 33, 8, + 87, 79, 32, 68, 79, 84, 83, 32, 4, 242, 8, 80, 255, 231, 38, 65, 4, 180, + 240, 38, 8, 86, 69, 82, 84, 73, 67, 65, 76, 27, 65, 41, 11, 32, 38, 144, 1, 4, 71, 79, 65, 76, 88, 5, 87, 73, 84, 72, 32, 240, 47, 10, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 210, 90, 70, 202, 43, 73, 211, 9, 77, 13, 11, 32, 10, 164, 50, 6, 87, 73, 84, 72, 32, 72, 230, 88, 70, 202, 43, 73, 211, 9, 77, 8, 174, 26, 73, 149, 20, 3, 89, 69, 72, 9, 11, 32, 6, 174, - 246, 23, 65, 150, 143, 9, 89, 179, 247, 5, 87, 22, 28, 2, 69, 77, 247, + 234, 23, 65, 202, 138, 9, 89, 179, 247, 5, 87, 22, 28, 2, 69, 77, 247, 45, 72, 17, 11, 32, 14, 72, 6, 87, 73, 84, 72, 32, 84, 226, 136, 1, 70, - 202, 43, 73, 211, 9, 77, 6, 222, 246, 14, 87, 227, 213, 18, 72, 70, 98, + 202, 43, 73, 211, 9, 77, 6, 170, 238, 14, 87, 203, 205, 18, 72, 70, 98, 65, 208, 1, 4, 69, 72, 69, 72, 180, 2, 7, 73, 82, 71, 72, 73, 90, 32, 137, 32, 2, 72, 65, 24, 46, 70, 229, 174, 1, 5, 83, 72, 77, 73, 82, 23, 11, 32, 20, 68, 5, 87, 73, 84, 72, 32, 214, 134, 1, 70, 202, 43, 73, 211, - 9, 77, 12, 42, 84, 166, 211, 35, 68, 151, 211, 3, 82, 6, 254, 27, 87, - 203, 169, 37, 72, 25, 11, 32, 22, 68, 5, 87, 73, 84, 72, 32, 182, 133, 1, - 70, 202, 43, 73, 211, 9, 77, 14, 38, 84, 206, 42, 83, 139, 203, 38, 68, + 9, 77, 12, 42, 84, 218, 194, 35, 68, 151, 211, 3, 82, 6, 254, 27, 87, + 255, 152, 37, 72, 25, 11, 32, 22, 68, 5, 87, 73, 84, 72, 32, 182, 133, 1, + 70, 202, 43, 73, 211, 9, 77, 14, 38, 84, 206, 42, 83, 191, 186, 38, 68, 10, 60, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 167, 26, 87, 6, 42, - 80, 202, 211, 37, 66, 131, 165, 1, 65, 2, 141, 196, 37, 14, 79, 73, 78, + 80, 254, 194, 37, 66, 131, 165, 1, 65, 2, 193, 179, 37, 14, 79, 73, 78, 84, 73, 78, 71, 32, 85, 80, 87, 65, 82, 68, 12, 130, 40, 79, 13, 2, 89, 85, 26, 40, 2, 65, 77, 161, 183, 1, 2, 79, 87, 25, 11, 32, 22, 68, 5, 87, 73, 84, 72, 32, 182, 130, 1, 70, 202, 43, 73, 211, 9, 77, 14, 88, 2, 68, - 79, 36, 6, 83, 77, 65, 76, 76, 32, 148, 197, 33, 2, 84, 72, 251, 137, 5, - 66, 4, 146, 135, 18, 85, 215, 238, 20, 84, 4, 224, 27, 16, 65, 82, 65, - 66, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 84, 65, 231, 214, 39, 86, 18, - 36, 3, 69, 69, 77, 163, 176, 39, 65, 17, 11, 32, 14, 64, 5, 87, 73, 84, - 72, 32, 222, 127, 70, 202, 43, 73, 211, 9, 77, 6, 158, 18, 84, 187, 186, + 79, 36, 6, 83, 77, 65, 76, 76, 32, 200, 180, 33, 2, 84, 72, 251, 137, 5, + 66, 4, 146, 251, 17, 85, 139, 234, 20, 84, 4, 224, 27, 16, 65, 82, 65, + 66, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 84, 65, 155, 198, 39, 86, 18, + 36, 3, 69, 69, 77, 215, 159, 39, 65, 17, 11, 32, 14, 64, 5, 87, 73, 84, + 72, 32, 222, 127, 70, 202, 43, 73, 211, 9, 77, 6, 158, 18, 84, 239, 169, 35, 68, 62, 38, 71, 26, 89, 17, 3, 79, 79, 78, 21, 22, 79, 183, 122, 32, 10, 175, 27, 69, 33, 11, 32, 30, 92, 5, 71, 72, 85, 78, 78, 16, 5, 87, 73, 84, 72, 32, 242, 125, 70, 202, 43, 73, 211, 9, 77, 6, 187, 34, 65, 16, 136, 1, 6, 83, 77, 65, 76, 76, 32, 38, 84, 220, 24, 8, 73, 78, 86, - 69, 82, 84, 69, 68, 132, 151, 24, 4, 82, 73, 78, 71, 171, 235, 2, 68, 4, - 246, 255, 32, 84, 131, 238, 6, 86, 4, 250, 141, 7, 72, 143, 174, 30, 87, + 69, 82, 84, 69, 68, 132, 139, 24, 4, 82, 73, 78, 71, 223, 230, 2, 68, 4, + 170, 239, 32, 84, 131, 238, 6, 86, 4, 250, 137, 7, 72, 195, 161, 30, 87, 25, 22, 32, 187, 24, 69, 12, 88, 11, 87, 73, 84, 72, 32, 83, 77, 65, 76, - 76, 32, 170, 123, 70, 202, 43, 73, 211, 9, 77, 4, 26, 77, 163, 236, 39, - 86, 2, 153, 239, 38, 3, 69, 69, 77, 19, 11, 32, 16, 64, 5, 87, 73, 84, + 76, 32, 170, 123, 70, 202, 43, 73, 211, 9, 77, 4, 26, 77, 215, 219, 39, + 86, 2, 205, 222, 38, 3, 69, 69, 77, 19, 11, 32, 16, 64, 5, 87, 73, 84, 72, 32, 158, 122, 70, 202, 43, 73, 211, 9, 77, 8, 36, 4, 68, 79, 84, 32, - 187, 12, 84, 6, 44, 5, 66, 69, 76, 79, 87, 239, 237, 38, 65, 5, 193, 231, + 187, 12, 84, 6, 44, 5, 66, 69, 76, 79, 87, 163, 221, 38, 65, 5, 141, 223, 14, 6, 32, 65, 78, 68, 32, 78, 52, 112, 2, 69, 72, 224, 28, 3, 82, 69, 72, 156, 3, 4, 78, 79, 79, 78, 149, 130, 1, 7, 79, 72, 73, 78, 71, 89, 65, 35, 11, 32, 32, 52, 5, 87, 73, 84, 72, 32, 226, 119, 70, 231, 52, 73, - 28, 134, 1, 83, 96, 2, 84, 87, 234, 5, 73, 174, 23, 72, 246, 205, 11, 70, - 204, 141, 7, 5, 68, 79, 84, 32, 66, 234, 39, 76, 207, 245, 19, 82, 10, - 44, 5, 77, 65, 76, 76, 32, 207, 183, 39, 84, 8, 198, 6, 65, 166, 250, 6, - 78, 151, 219, 16, 86, 4, 37, 7, 79, 32, 68, 79, 84, 83, 32, 4, 166, 8, - 86, 211, 225, 38, 65, 60, 184, 1, 2, 65, 68, 120, 3, 69, 69, 78, 136, 6, + 28, 134, 1, 83, 96, 2, 84, 87, 234, 5, 73, 174, 23, 72, 194, 197, 11, 70, + 128, 138, 7, 5, 68, 79, 84, 32, 66, 234, 39, 76, 131, 241, 19, 82, 10, + 44, 5, 77, 65, 76, 76, 32, 131, 167, 39, 84, 8, 198, 6, 65, 166, 246, 6, + 78, 151, 211, 16, 86, 4, 37, 7, 79, 32, 68, 79, 84, 83, 32, 4, 166, 8, + 86, 135, 209, 38, 65, 60, 184, 1, 2, 65, 68, 120, 3, 69, 69, 78, 136, 6, 4, 72, 69, 69, 78, 232, 160, 1, 4, 85, 80, 69, 82, 160, 181, 4, 7, 84, - 82, 65, 73, 71, 72, 84, 209, 134, 33, 6, 87, 65, 83, 72, 32, 75, 17, 11, + 82, 65, 73, 71, 72, 84, 133, 246, 32, 6, 87, 65, 83, 72, 32, 75, 17, 11, 32, 14, 68, 6, 87, 73, 84, 72, 32, 84, 162, 115, 70, 202, 43, 73, 211, 9, - 77, 6, 254, 182, 33, 72, 235, 251, 3, 87, 27, 11, 32, 24, 64, 5, 87, 73, + 77, 6, 178, 166, 33, 72, 235, 251, 3, 87, 27, 11, 32, 24, 64, 5, 87, 73, 84, 72, 32, 174, 114, 70, 202, 43, 73, 211, 9, 77, 16, 232, 1, 3, 68, 79, - 84, 50, 73, 48, 7, 83, 77, 65, 76, 76, 32, 65, 110, 84, 134, 228, 11, 70, + 84, 50, 73, 48, 7, 83, 77, 65, 76, 76, 32, 65, 110, 84, 210, 219, 11, 70, 241, 159, 5, 31, 69, 88, 84, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, 32, 68, 73, 71, 73, 84, 32, 70, 79, 85, 2, - 193, 243, 18, 7, 32, 66, 69, 76, 79, 87, 32, 2, 213, 219, 17, 7, 78, 86, + 193, 231, 18, 7, 32, 66, 69, 76, 79, 87, 32, 2, 213, 207, 17, 7, 78, 86, 69, 82, 84, 69, 68, 2, 85, 19, 82, 65, 66, 73, 67, 32, 76, 69, 84, 84, - 69, 82, 32, 84, 65, 72, 32, 65, 78, 2, 147, 159, 23, 68, 6, 96, 11, 72, + 69, 82, 32, 84, 65, 72, 32, 65, 78, 2, 147, 147, 23, 68, 6, 96, 11, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 66, 105, 9, 87, 79, 32, 68, 79, 84, 83, 32, 86, 4, 25, 4, 69, 76, 79, 87, 5, 11, 32, 2, 21, 3, 65, 78, 68, 2, - 17, 2, 32, 84, 2, 247, 254, 6, 72, 2, 221, 224, 11, 8, 69, 82, 84, 73, + 17, 2, 32, 84, 2, 247, 250, 6, 72, 2, 169, 216, 11, 8, 69, 82, 84, 73, 67, 65, 76, 76, 13, 11, 32, 10, 46, 87, 186, 108, 70, 202, 43, 73, 211, - 9, 77, 2, 253, 138, 27, 5, 73, 84, 72, 32, 68, 122, 92, 2, 65, 72, 136, + 9, 77, 2, 177, 250, 26, 5, 73, 84, 72, 32, 68, 122, 92, 2, 65, 72, 136, 2, 4, 67, 72, 69, 72, 124, 2, 69, 72, 150, 3, 72, 97, 3, 84, 69, 72, 21, 11, 32, 18, 64, 5, 87, 73, 84, 72, 32, 226, 106, 70, 202, 43, 73, 211, 9, - 77, 10, 26, 84, 143, 137, 27, 68, 8, 26, 87, 139, 174, 33, 72, 4, 37, 7, - 79, 32, 68, 79, 84, 83, 32, 4, 48, 6, 86, 69, 82, 84, 73, 67, 247, 221, - 38, 65, 2, 197, 169, 37, 4, 65, 76, 76, 89, 25, 22, 32, 199, 5, 69, 12, + 77, 10, 26, 84, 195, 248, 26, 68, 8, 26, 87, 191, 157, 33, 72, 4, 37, 7, + 79, 32, 68, 79, 84, 83, 32, 4, 48, 6, 86, 69, 82, 84, 73, 67, 171, 205, + 38, 65, 2, 249, 152, 37, 4, 65, 76, 76, 89, 25, 22, 32, 199, 5, 69, 12, 64, 5, 87, 73, 84, 72, 32, 206, 104, 70, 202, 43, 73, 211, 9, 77, 4, 138, - 14, 83, 139, 203, 38, 68, 37, 22, 32, 203, 4, 69, 24, 62, 77, 116, 5, 87, + 14, 83, 191, 186, 38, 68, 37, 22, 32, 203, 4, 69, 24, 62, 77, 116, 5, 87, 73, 84, 72, 32, 226, 102, 70, 203, 43, 73, 10, 48, 6, 65, 82, 66, 85, 84, - 65, 199, 156, 1, 69, 9, 11, 32, 6, 146, 103, 70, 230, 52, 73, 213, 176, + 65, 199, 156, 1, 69, 9, 11, 32, 6, 146, 103, 70, 230, 52, 73, 137, 160, 37, 2, 71, 79, 8, 104, 6, 83, 77, 65, 76, 76, 32, 56, 12, 84, 72, 82, 69, - 69, 32, 68, 79, 84, 83, 32, 65, 207, 133, 39, 82, 4, 32, 2, 84, 69, 231, - 214, 39, 86, 2, 223, 217, 38, 72, 2, 153, 146, 28, 4, 66, 79, 86, 69, 20, - 42, 65, 16, 3, 73, 78, 32, 147, 1, 69, 6, 167, 9, 76, 4, 146, 224, 32, + 69, 32, 68, 79, 84, 83, 32, 65, 131, 245, 38, 82, 4, 32, 2, 84, 69, 155, + 198, 39, 86, 2, 147, 201, 38, 72, 2, 205, 129, 28, 4, 66, 79, 86, 69, 20, + 42, 65, 16, 3, 73, 78, 32, 147, 1, 69, 6, 167, 9, 76, 4, 198, 207, 32, 89, 183, 203, 3, 78, 23, 18, 32, 91, 69, 10, 60, 4, 87, 73, 84, 72, 230, 99, 70, 202, 43, 73, 211, 9, 77, 2, 161, 9, 2, 32, 83, 10, 163, 11, 72, 15, 158, 1, 32, 181, 92, 33, 73, 71, 72, 85, 82, 32, 75, 65, 90, 65, 75, @@ -386,21 +386,21 @@ static const unsigned char packed_name_dawg[] = { 83, 85, 82, 65, 8, 96, 16, 87, 73, 84, 72, 32, 72, 65, 77, 90, 65, 32, 65, 66, 79, 86, 69, 186, 97, 70, 231, 52, 73, 5, 155, 87, 32, 17, 254, 8, 72, 147, 88, 32, 25, 11, 32, 22, 52, 5, 87, 73, 84, 72, 32, 202, 96, 70, - 231, 52, 73, 18, 80, 4, 68, 79, 84, 32, 162, 2, 69, 182, 1, 72, 150, 202, - 14, 84, 159, 178, 24, 82, 4, 152, 197, 31, 3, 87, 73, 84, 131, 143, 7, + 231, 52, 73, 18, 80, 4, 68, 79, 84, 32, 162, 2, 69, 182, 1, 72, 226, 193, + 14, 84, 135, 170, 24, 82, 4, 204, 180, 31, 3, 87, 73, 84, 131, 143, 7, 65, 56, 28, 2, 69, 72, 227, 3, 85, 51, 11, 32, 48, 100, 6, 66, 65, 82, 82, 69, 69, 252, 2, 5, 87, 73, 84, 72, 32, 182, 91, 70, 202, 43, 73, 211, 9, 77, 17, 11, 32, 14, 52, 5, 87, 73, 84, 72, 32, 238, 93, 70, 231, 52, 73, 10, 22, 69, 183, 1, 72, 4, 121, 28, 88, 84, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, 32, 68, 73, 71, 73, 84, - 32, 84, 4, 224, 166, 36, 3, 72, 82, 69, 133, 170, 2, 2, 87, 79, 6, 21, 3, + 32, 84, 4, 148, 150, 36, 3, 72, 82, 69, 133, 170, 2, 2, 87, 79, 6, 21, 3, 65, 77, 90, 6, 11, 65, 6, 17, 2, 32, 65, 6, 21, 3, 66, 79, 86, 6, 11, 69, 7, 171, 91, 32, 24, 96, 10, 72, 65, 77, 90, 65, 32, 65, 66, 79, 86, 18, - 83, 38, 84, 241, 153, 37, 4, 70, 79, 85, 82, 10, 167, 2, 69, 2, 133, 198, + 83, 38, 84, 165, 137, 37, 4, 70, 79, 85, 82, 10, 167, 2, 69, 2, 133, 186, 17, 4, 77, 65, 76, 76, 10, 108, 18, 87, 79, 32, 68, 79, 84, 83, 32, 66, - 69, 76, 79, 87, 32, 65, 78, 68, 32, 206, 152, 37, 72, 167, 82, 65, 6, 70, - 72, 168, 227, 6, 7, 83, 77, 65, 76, 76, 32, 78, 135, 230, 31, 68, 2, 185, - 158, 34, 3, 65, 77, 90, 18, 26, 72, 17, 2, 73, 78, 11, 223, 83, 32, 9, + 69, 76, 79, 87, 32, 65, 78, 68, 32, 130, 136, 37, 72, 167, 82, 65, 6, 70, + 72, 168, 223, 6, 7, 83, 77, 65, 76, 76, 32, 78, 187, 217, 31, 68, 2, 237, + 141, 34, 3, 65, 77, 90, 18, 26, 72, 17, 2, 73, 78, 11, 223, 83, 32, 9, 11, 32, 6, 138, 88, 70, 230, 52, 73, 177, 11, 13, 87, 73, 84, 72, 32, 73, 78, 86, 69, 82, 84, 69, 68, 158, 8, 166, 5, 65, 178, 7, 66, 176, 2, 2, 68, 65, 184, 1, 9, 70, 69, 72, 32, 87, 73, 84, 72, 32, 72, 11, 71, 72, @@ -413,19 +413,19 @@ static const unsigned char packed_name_dawg[] = { 87, 73, 84, 72, 32, 65, 76, 69, 70, 32, 77, 65, 75, 83, 85, 82, 65, 205, 6, 14, 90, 65, 72, 32, 87, 73, 84, 72, 32, 77, 69, 69, 77, 32, 66, 192, 1, 8, 73, 78, 32, 87, 73, 84, 72, 32, 68, 13, 74, 74, 65, 76, 32, 65, 76, - 76, 65, 65, 72, 85, 32, 146, 1, 76, 196, 68, 4, 75, 66, 65, 82, 137, 241, + 76, 65, 65, 72, 85, 32, 146, 1, 76, 196, 68, 4, 75, 66, 65, 82, 189, 224, 36, 8, 90, 90, 65, 32, 87, 65, 32, 74, 28, 236, 23, 4, 77, 69, 69, 77, 130, 22, 74, 154, 25, 65, 255, 8, 89, 4, 54, 70, 1, 9, 84, 65, 65, 65, - 76, 65, 65, 32, 70, 2, 209, 223, 28, 17, 65, 82, 65, 74, 65, 72, 85, 32, + 76, 65, 65, 32, 70, 2, 133, 207, 28, 17, 65, 82, 65, 74, 65, 72, 85, 32, 65, 83, 72, 45, 83, 72, 65, 82, 69, 30, 56, 3, 65, 89, 72, 156, 2, 3, 69, 70, 32, 207, 16, 76, 20, 30, 73, 102, 65, 135, 67, 69, 14, 24, 2, 32, 65, - 55, 77, 6, 110, 83, 153, 208, 32, 6, 82, 45, 82, 65, 72, 77, 8, 18, 65, + 55, 77, 6, 110, 83, 205, 191, 32, 6, 82, 45, 82, 65, 72, 77, 8, 18, 65, 23, 32, 4, 17, 2, 65, 32, 4, 17, 2, 65, 83, 4, 33, 6, 45, 83, 65, 76, 65, - 65, 4, 236, 184, 33, 10, 84, 85, 32, 87, 65, 83, 45, 83, 65, 76, 135, + 65, 4, 160, 168, 33, 10, 84, 85, 32, 87, 65, 83, 45, 83, 65, 76, 135, 133, 6, 77, 8, 236, 75, 29, 77, 65, 75, 83, 85, 82, 65, 32, 87, 73, 84, 72, 32, 83, 85, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 1, 13, 87, 73, 84, 72, 32, 70, 65, 84, 72, 65, 84, 65, 78, 44, 160, 1, 8, - 69, 72, 32, 87, 73, 84, 72, 32, 241, 131, 26, 25, 73, 83, 77, 73, 76, 76, + 69, 72, 32, 87, 73, 84, 72, 32, 165, 243, 25, 25, 73, 83, 77, 73, 76, 76, 65, 72, 32, 65, 82, 45, 82, 65, 72, 77, 65, 78, 32, 65, 82, 45, 82, 65, 72, 42, 98, 72, 24, 3, 75, 72, 65, 254, 62, 65, 250, 3, 74, 78, 77, 86, 78, 78, 90, 242, 2, 82, 43, 89, 10, 22, 65, 195, 66, 69, 6, 155, 69, 72, @@ -443,7 +443,7 @@ static const unsigned char packed_name_dawg[] = { 53, 16, 83, 85, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 8, 40, 5, 87, 73, 84, 72, 32, 219, 108, 73, 4, 158, 52, 74, 3, 77, 32, 68, 4, 65, 76, 76, 65, 81, 9, 69, 69, 77, 32, 87, 73, 84, 72, 32, 4, 168, - 145, 4, 7, 74, 65, 76, 65, 76, 79, 85, 189, 190, 24, 4, 32, 87, 65, 45, + 145, 4, 7, 74, 65, 76, 65, 76, 79, 85, 241, 173, 24, 4, 32, 87, 65, 45, 28, 62, 72, 60, 5, 77, 69, 69, 77, 32, 174, 53, 65, 255, 8, 89, 8, 17, 2, 65, 72, 8, 11, 32, 8, 150, 37, 87, 179, 69, 73, 12, 40, 5, 87, 73, 84, 72, 32, 131, 106, 73, 8, 154, 45, 72, 242, 3, 65, 203, 12, 89, 66, 58, @@ -468,41 +468,41 @@ static const unsigned char packed_name_dawg[] = { 143, 12, 89, 12, 40, 5, 87, 73, 84, 72, 32, 255, 94, 73, 8, 194, 38, 77, 194, 7, 75, 14, 72, 195, 4, 89, 8, 142, 48, 87, 246, 2, 70, 203, 43, 73, 2, 11, 69, 2, 167, 40, 72, 62, 144, 1, 9, 79, 79, 78, 32, 87, 73, 84, 72, - 32, 205, 159, 13, 20, 65, 87, 87, 65, 82, 65, 32, 65, 76, 76, 65, 65, 72, + 32, 153, 151, 13, 20, 65, 87, 87, 65, 82, 65, 32, 65, 76, 76, 65, 65, 72, 85, 32, 77, 65, 82, 81, 65, 60, 134, 1, 72, 28, 5, 74, 69, 69, 77, 32, 92, 5, 77, 69, 69, 77, 32, 246, 37, 65, 154, 5, 78, 78, 90, 134, 1, 75, 238, 1, 82, 43, 89, 14, 150, 33, 65, 155, 9, 69, 16, 40, 5, 87, 73, 84, 72, 32, 167, 91, 73, 12, 190, 30, 72, 242, 3, 65, 130, 12, 77, 75, 89, 12, 194, 21, 87, 234, 25, 70, 202, 43, 73, 211, 9, 77, 36, 46, 65, 209, 2, 6, 85, 68, 68, 73, 83, 65, 28, 156, 1, 7, 70, 32, 87, 73, 84, 72, 32, - 212, 12, 4, 76, 65, 32, 85, 233, 163, 32, 18, 68, 68, 65, 83, 65, 32, 65, + 212, 12, 4, 76, 65, 32, 85, 157, 147, 32, 18, 68, 68, 65, 83, 65, 32, 65, 76, 76, 65, 65, 72, 85, 32, 83, 73, 82, 82, 24, 64, 5, 77, 69, 69, 77, 32, 174, 35, 65, 246, 6, 72, 139, 2, 89, 12, 40, 5, 87, 73, 84, 72, 32, 131, 88, 73, 8, 34, 77, 250, 26, 72, 187, 16, 89, 2, 193, 43, 3, 69, 69, 77, 8, 68, 5, 32, 83, 73, 82, 82, 45, 8, 84, 32, 65, 83, 82, 65, 65, 82, - 6, 220, 5, 3, 85, 72, 85, 215, 149, 39, 65, 2, 241, 240, 37, 2, 85, 72, + 6, 220, 5, 3, 85, 72, 85, 139, 133, 39, 65, 2, 165, 224, 37, 2, 85, 72, 44, 30, 65, 177, 30, 2, 69, 72, 42, 92, 11, 68, 73, 32, 65, 76, 76, 65, 65, 72, 85, 32, 170, 1, 72, 153, 30, 4, 83, 79, 85, 76, 18, 72, 3, 65, 78, 72, 61, 11, 84, 65, 65, 65, 76, 65, 65, 32, 65, 78, 72, 11, 26, 85, - 223, 151, 39, 65, 6, 186, 3, 77, 195, 216, 37, 78, 9, 142, 3, 85, 175, - 148, 39, 65, 22, 92, 5, 73, 77, 65, 72, 85, 149, 1, 13, 77, 65, 84, 85, + 147, 135, 39, 65, 6, 186, 3, 77, 247, 199, 37, 78, 9, 142, 3, 85, 227, + 131, 39, 65, 22, 92, 5, 73, 77, 65, 72, 85, 149, 1, 13, 77, 65, 84, 85, 32, 65, 76, 76, 65, 65, 72, 73, 32, 12, 44, 7, 32, 65, 76, 76, 65, 65, 72, 19, 77, 5, 215, 20, 32, 8, 30, 32, 1, 3, 65, 65, 32, 4, 33, 6, 65, - 76, 76, 65, 65, 72, 5, 211, 18, 85, 10, 92, 5, 65, 76, 65, 89, 72, 241, - 149, 39, 12, 84, 65, 65, 65, 76, 65, 65, 32, 65, 76, 65, 89, 9, 26, 73, - 175, 148, 39, 65, 4, 11, 77, 5, 159, 148, 39, 65, 194, 1, 134, 1, 65, + 76, 76, 65, 65, 72, 5, 211, 18, 85, 10, 92, 5, 65, 76, 65, 89, 72, 165, + 133, 39, 12, 84, 65, 65, 65, 76, 65, 65, 32, 65, 76, 65, 89, 9, 26, 73, + 227, 131, 39, 65, 4, 11, 77, 5, 211, 131, 39, 65, 194, 1, 134, 1, 65, 220, 7, 9, 69, 69, 78, 32, 87, 73, 84, 72, 32, 250, 3, 72, 201, 4, 12, 85, 66, 72, 65, 65, 78, 65, 72, 85, 32, 87, 65, 50, 48, 7, 68, 32, 87, 73, 84, 72, 32, 251, 1, 76, 32, 76, 4, 72, 65, 72, 32, 82, 77, 154, 25, 65, 138, 4, 75, 246, 4, 82, 3, 89, 10, 22, 87, 211, 78, 73, 6, 25, 4, 73, 84, 72, 32, 6, 206, 17, 72, 187, 16, 89, 8, 21, 3, 69, 69, 77, 8, 11, 32, 8, 252, 32, 6, 87, 73, 84, 72, 32, 77, 247, 44, 73, 18, 26, 65, 77, 2, - 76, 65, 4, 178, 23, 77, 137, 134, 37, 11, 65, 77, 85, 72, 85, 32, 65, 76, + 76, 65, 4, 178, 23, 77, 189, 245, 36, 11, 65, 77, 85, 72, 85, 32, 65, 76, 65, 89, 78, 14, 34, 32, 133, 1, 3, 76, 76, 65, 4, 22, 85, 187, 85, 73, 2, 245, 9, 23, 83, 69, 68, 32, 65, 83, 32, 75, 79, 82, 65, 78, 73, 67, 32, 83, 84, 79, 80, 32, 83, 73, 71, 10, 36, 4, 65, 72, 85, 32, 147, 1, 72, 4, - 212, 2, 14, 84, 65, 65, 65, 76, 65, 65, 32, 65, 76, 65, 89, 72, 73, 237, - 140, 39, 14, 65, 76, 65, 89, 72, 73, 32, 87, 65, 45, 65, 65, 76, 73, 6, + 212, 2, 14, 84, 65, 65, 65, 76, 65, 65, 32, 65, 76, 65, 89, 72, 73, 161, + 252, 38, 14, 65, 76, 65, 89, 72, 73, 32, 87, 65, 45, 65, 65, 76, 73, 6, 112, 11, 85, 32, 65, 76, 65, 89, 72, 73, 32, 87, 65, 205, 63, 12, 79, 85, 32, 65, 76, 65, 89, 72, 69, 32, 87, 65, 4, 44, 7, 45, 65, 76, 65, 65, 32, 65, 3, 65, 2, 33, 6, 65, 76, 73, 72, 69, 69, 2, 245, 62, 4, 32, 87, 65, @@ -523,7 +523,7 @@ static const unsigned char packed_name_dawg[] = { 174, 20, 70, 202, 43, 73, 211, 9, 77, 8, 140, 3, 2, 75, 72, 243, 15, 77, 2, 175, 1, 32, 122, 66, 65, 176, 2, 8, 69, 72, 32, 87, 73, 84, 72, 32, 179, 4, 72, 28, 88, 11, 66, 65, 65, 82, 65, 75, 65, 32, 87, 65, 45, 29, - 7, 72, 32, 87, 73, 84, 72, 32, 2, 129, 162, 28, 2, 84, 65, 26, 64, 5, 77, + 7, 72, 32, 87, 73, 84, 72, 32, 2, 181, 145, 28, 2, 84, 65, 26, 64, 5, 77, 69, 69, 77, 32, 194, 8, 65, 246, 6, 72, 139, 2, 89, 14, 52, 5, 87, 73, 84, 72, 32, 138, 61, 73, 211, 9, 77, 8, 34, 72, 174, 4, 77, 143, 12, 89, 4, 133, 16, 2, 65, 72, 66, 138, 1, 72, 108, 3, 75, 72, 65, 12, 4, 74, 69, @@ -557,673 +557,673 @@ static const unsigned char packed_name_dawg[] = { 70, 2, 211, 44, 78, 2, 17, 2, 69, 72, 2, 77, 2, 32, 70, 4, 11, 69, 4, 11, 72, 4, 11, 32, 4, 22, 70, 231, 52, 73, 2, 185, 53, 2, 73, 78, 6, 174, 43, 73, 211, 9, 77, 166, 2, 92, 3, 68, 68, 65, 52, 3, 82, 75, 32, 109, 11, - 84, 72, 69, 77, 65, 84, 73, 67, 65, 76, 32, 4, 244, 177, 37, 5, 32, 87, + 84, 72, 69, 77, 65, 84, 73, 67, 65, 76, 32, 4, 168, 161, 37, 5, 32, 87, 65, 65, 74, 131, 65, 72, 4, 58, 78, 1, 10, 83, 73, 68, 69, 87, 65, 89, - 83, 32, 78, 2, 201, 180, 35, 7, 79, 79, 78, 32, 71, 72, 85, 158, 2, 174, + 83, 32, 78, 2, 253, 163, 35, 7, 79, 79, 78, 32, 71, 72, 85, 158, 2, 174, 2, 68, 140, 3, 8, 73, 78, 73, 84, 73, 65, 76, 32, 222, 1, 76, 132, 2, 9, - 79, 80, 69, 82, 65, 84, 79, 82, 32, 166, 1, 83, 142, 3, 84, 130, 190, 24, + 79, 80, 69, 82, 65, 84, 79, 82, 32, 166, 1, 83, 142, 3, 84, 182, 173, 24, 65, 102, 75, 110, 90, 234, 106, 74, 2, 77, 250, 192, 6, 66, 2, 70, 2, 82, 2, 89, 222, 7, 72, 222, 58, 71, 254, 136, 3, 78, 250, 168, 2, 81, 135, 3, - 87, 62, 26, 79, 219, 233, 37, 65, 58, 88, 6, 84, 76, 69, 83, 83, 32, 61, - 12, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 75, 32, 8, 210, 245, 31, 66, + 87, 62, 26, 79, 143, 217, 37, 65, 58, 88, 6, 84, 76, 69, 83, 83, 32, 61, + 12, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 75, 32, 8, 134, 229, 31, 66, 2, 70, 182, 203, 3, 78, 251, 168, 2, 81, 50, 178, 12, 83, 174, 20, 75, - 146, 168, 24, 84, 74, 90, 234, 106, 74, 2, 77, 250, 192, 6, 66, 2, 70, 2, + 198, 151, 24, 84, 74, 90, 234, 106, 74, 2, 77, 250, 192, 6, 66, 2, 70, 2, 82, 2, 89, 222, 7, 72, 222, 58, 71, 254, 136, 3, 78, 154, 237, 1, 76, 210, 58, 68, 146, 1, 81, 222, 1, 65, 171, 1, 87, 40, 182, 1, 84, 166, 9, - 83, 254, 187, 24, 72, 30, 75, 214, 107, 74, 2, 77, 250, 192, 6, 66, 2, + 83, 178, 171, 24, 72, 30, 75, 214, 107, 74, 2, 77, 250, 192, 6, 66, 2, 70, 2, 89, 186, 66, 71, 254, 136, 3, 78, 154, 237, 1, 76, 226, 59, 81, - 222, 1, 65, 171, 57, 68, 4, 134, 242, 31, 72, 207, 244, 6, 69, 56, 48, 6, - 79, 79, 80, 69, 68, 32, 183, 214, 38, 65, 54, 202, 8, 83, 174, 20, 75, - 138, 167, 24, 65, 74, 72, 66, 84, 74, 90, 234, 106, 74, 2, 77, 250, 192, + 222, 1, 65, 171, 57, 68, 4, 186, 225, 31, 72, 207, 244, 6, 69, 56, 48, 6, + 79, 79, 80, 69, 68, 32, 235, 197, 38, 65, 54, 202, 8, 83, 174, 20, 75, + 190, 150, 24, 65, 74, 72, 66, 84, 74, 90, 234, 106, 74, 2, 77, 250, 192, 6, 66, 2, 70, 2, 82, 2, 89, 186, 66, 71, 254, 136, 3, 78, 154, 237, 1, - 76, 210, 58, 68, 146, 1, 81, 135, 3, 87, 4, 148, 161, 29, 23, 77, 69, 69, + 76, 210, 58, 68, 146, 1, 81, 135, 3, 87, 4, 200, 144, 29, 23, 77, 69, 69, 77, 32, 87, 73, 84, 72, 32, 72, 65, 72, 32, 87, 73, 84, 72, 32, 84, 65, 84, 87, 197, 174, 8, 9, 72, 65, 72, 32, 87, 73, 84, 72, 32, 52, 84, 9, - 84, 82, 69, 84, 67, 72, 69, 68, 32, 178, 141, 37, 72, 14, 69, 231, 143, - 1, 65, 46, 178, 1, 68, 86, 84, 250, 2, 83, 254, 187, 24, 72, 30, 75, 214, + 84, 82, 69, 84, 67, 72, 69, 68, 32, 230, 252, 36, 72, 14, 69, 231, 143, + 1, 65, 46, 178, 1, 68, 86, 84, 250, 2, 83, 178, 171, 24, 72, 30, 75, 214, 107, 74, 2, 77, 250, 192, 6, 66, 2, 70, 2, 89, 222, 7, 90, 222, 58, 71, 254, 136, 3, 78, 250, 168, 2, 81, 223, 1, 65, 6, 52, 7, 79, 84, 76, 69, - 83, 83, 32, 183, 155, 38, 65, 4, 246, 235, 31, 66, 3, 70, 6, 218, 235, - 31, 72, 206, 244, 6, 65, 3, 69, 38, 42, 65, 130, 191, 24, 72, 211, 160, - 14, 69, 32, 44, 5, 73, 76, 69, 68, 32, 179, 224, 38, 72, 30, 146, 1, 68, - 94, 83, 174, 20, 75, 194, 147, 25, 74, 250, 192, 6, 89, 222, 7, 72, 222, + 83, 83, 32, 235, 138, 38, 65, 4, 170, 219, 31, 66, 3, 70, 6, 142, 219, + 31, 72, 206, 244, 6, 65, 3, 69, 38, 42, 65, 182, 174, 24, 72, 211, 160, + 14, 69, 32, 44, 5, 73, 76, 69, 68, 32, 231, 207, 38, 72, 30, 146, 1, 68, + 94, 83, 174, 20, 75, 246, 130, 25, 74, 250, 192, 6, 89, 222, 7, 72, 222, 58, 71, 254, 136, 3, 78, 154, 237, 1, 76, 226, 59, 81, 223, 1, 65, 6, 52, - 7, 79, 84, 76, 69, 83, 83, 32, 199, 152, 38, 65, 4, 186, 180, 35, 78, - 251, 168, 2, 81, 6, 174, 136, 37, 72, 14, 69, 231, 143, 1, 65, 4, 250, - 219, 18, 77, 179, 251, 18, 83, 6, 192, 135, 25, 3, 75, 65, 83, 12, 4, 68, - 65, 77, 77, 1, 4, 70, 65, 84, 72, 12, 118, 69, 38, 79, 144, 217, 12, 11, - 76, 65, 67, 69, 32, 79, 70, 32, 83, 65, 74, 201, 128, 6, 6, 73, 65, 83, - 84, 82, 69, 4, 202, 189, 32, 82, 199, 233, 5, 80, 4, 224, 201, 12, 8, 69, - 84, 73, 67, 32, 86, 69, 82, 245, 143, 6, 3, 85, 78, 68, 14, 238, 1, 65, + 7, 79, 84, 76, 69, 83, 83, 32, 251, 135, 38, 65, 4, 238, 163, 35, 78, + 251, 168, 2, 81, 6, 226, 247, 36, 72, 14, 69, 231, 143, 1, 65, 4, 250, + 207, 18, 77, 231, 246, 18, 83, 6, 244, 246, 24, 3, 75, 65, 83, 12, 4, 68, + 65, 77, 77, 1, 4, 70, 65, 84, 72, 12, 118, 69, 38, 79, 220, 208, 12, 11, + 76, 65, 67, 69, 32, 79, 70, 32, 83, 65, 74, 253, 252, 5, 6, 73, 65, 83, + 84, 82, 69, 4, 254, 172, 32, 82, 199, 233, 5, 80, 4, 172, 193, 12, 8, 69, + 84, 73, 67, 32, 86, 69, 82, 169, 140, 6, 3, 85, 78, 68, 14, 238, 1, 65, 96, 5, 69, 86, 69, 82, 83, 36, 15, 73, 71, 72, 84, 32, 65, 82, 82, 79, - 87, 72, 69, 65, 68, 32, 157, 186, 23, 28, 79, 85, 78, 68, 69, 68, 32, 72, + 87, 72, 69, 65, 68, 32, 157, 174, 23, 28, 79, 85, 78, 68, 69, 68, 32, 72, 73, 71, 72, 32, 83, 84, 79, 80, 32, 87, 73, 84, 72, 32, 70, 73, 76, 76, - 69, 68, 4, 40, 4, 73, 83, 69, 68, 155, 217, 38, 89, 2, 17, 2, 32, 82, 2, - 233, 138, 37, 3, 79, 85, 78, 2, 225, 241, 21, 4, 69, 68, 32, 68, 6, 26, - 65, 187, 182, 36, 66, 4, 249, 177, 37, 3, 66, 79, 86, 206, 1, 238, 1, 69, + 69, 68, 4, 40, 4, 73, 83, 69, 68, 207, 200, 38, 89, 2, 17, 2, 32, 82, 2, + 157, 250, 36, 3, 79, 85, 78, 2, 225, 229, 21, 4, 69, 68, 32, 68, 6, 26, + 65, 239, 165, 36, 66, 4, 173, 161, 37, 3, 66, 79, 86, 206, 1, 238, 1, 69, 244, 2, 5, 72, 65, 68, 68, 65, 36, 4, 73, 71, 78, 32, 240, 4, 5, 77, 65, - 76, 76, 32, 222, 15, 85, 240, 2, 6, 89, 77, 66, 79, 76, 32, 197, 253, 36, + 76, 76, 32, 222, 15, 85, 240, 2, 6, 89, 77, 66, 79, 76, 32, 249, 236, 36, 18, 84, 65, 82, 84, 32, 79, 70, 32, 82, 85, 66, 32, 69, 76, 32, 72, 73, - 90, 20, 52, 7, 81, 85, 69, 78, 67, 69, 32, 215, 134, 35, 77, 18, 184, 1, + 90, 20, 52, 7, 81, 85, 69, 78, 67, 69, 32, 139, 246, 34, 77, 18, 184, 1, 26, 89, 69, 72, 32, 87, 73, 84, 72, 32, 72, 65, 77, 90, 65, 32, 65, 66, - 79, 86, 69, 32, 87, 73, 84, 72, 32, 193, 222, 31, 13, 78, 79, 79, 78, 32, - 87, 73, 84, 72, 32, 75, 69, 72, 16, 70, 65, 170, 213, 37, 87, 198, 89, - 89, 150, 14, 79, 214, 22, 69, 3, 85, 6, 36, 3, 76, 69, 70, 175, 211, 38, + 79, 86, 69, 32, 87, 73, 84, 72, 32, 245, 205, 31, 13, 78, 79, 79, 78, 32, + 87, 73, 84, 72, 32, 75, 69, 72, 16, 70, 65, 222, 196, 37, 87, 198, 89, + 89, 150, 14, 79, 214, 22, 69, 3, 85, 6, 36, 3, 76, 69, 70, 227, 194, 38, 69, 5, 251, 12, 32, 7, 11, 32, 4, 222, 22, 73, 55, 77, 22, 132, 1, 2, 82, 65, 158, 1, 83, 188, 1, 7, 65, 76, 65, 89, 72, 69, 32, 136, 15, 2, 77, - 73, 133, 181, 34, 6, 84, 65, 75, 72, 65, 76, 4, 132, 1, 13, 72, 77, 65, - 84, 85, 76, 76, 65, 72, 32, 65, 76, 65, 161, 218, 33, 13, 68, 73, 32, 65, - 76, 76, 65, 72, 79, 85, 32, 65, 78, 2, 219, 163, 38, 89, 12, 46, 65, 193, + 73, 185, 164, 34, 6, 84, 65, 75, 72, 65, 76, 4, 132, 1, 13, 72, 77, 65, + 84, 85, 76, 76, 65, 72, 32, 65, 76, 65, 213, 201, 33, 13, 68, 73, 32, 65, + 76, 76, 65, 72, 79, 85, 32, 65, 78, 2, 143, 147, 38, 89, 12, 46, 65, 193, 1, 6, 73, 78, 68, 72, 73, 32, 8, 136, 1, 18, 76, 76, 65, 76, 76, 65, 72, - 79, 85, 32, 65, 76, 65, 89, 72, 69, 32, 87, 154, 225, 31, 78, 218, 240, - 4, 70, 249, 115, 2, 77, 86, 2, 17, 2, 65, 83, 2, 141, 242, 15, 3, 83, 65, - 76, 4, 160, 227, 20, 12, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 78, - 205, 152, 14, 2, 65, 77, 110, 120, 2, 70, 65, 32, 5, 72, 73, 71, 72, 32, - 134, 11, 89, 88, 4, 76, 79, 87, 32, 118, 75, 158, 217, 21, 68, 215, 232, - 15, 87, 4, 166, 3, 82, 191, 204, 36, 84, 74, 212, 2, 17, 68, 79, 84, 76, + 79, 85, 32, 65, 76, 65, 89, 72, 69, 32, 87, 206, 208, 31, 78, 218, 240, + 4, 70, 249, 115, 2, 77, 86, 2, 17, 2, 65, 83, 2, 217, 233, 15, 3, 83, 65, + 76, 4, 160, 215, 20, 12, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 78, + 129, 148, 14, 2, 65, 77, 110, 120, 2, 70, 65, 32, 5, 72, 73, 71, 72, 32, + 134, 11, 89, 88, 4, 76, 79, 87, 32, 118, 75, 158, 205, 21, 68, 139, 228, + 15, 87, 4, 166, 3, 82, 243, 187, 36, 84, 74, 212, 2, 17, 68, 79, 84, 76, 69, 83, 83, 32, 72, 69, 65, 68, 32, 79, 70, 32, 75, 22, 70, 102, 76, 142, - 3, 77, 118, 83, 78, 84, 38, 87, 198, 2, 89, 142, 1, 78, 180, 195, 14, 18, + 3, 77, 118, 83, 78, 84, 38, 87, 198, 2, 89, 142, 1, 78, 128, 187, 14, 18, 85, 80, 82, 73, 71, 72, 84, 32, 82, 69, 67, 84, 65, 78, 71, 85, 76, 65, - 252, 220, 8, 7, 82, 79, 85, 78, 68, 69, 68, 242, 126, 90, 234, 106, 74, - 166, 181, 12, 81, 223, 1, 65, 2, 147, 220, 31, 72, 4, 24, 2, 65, 82, 31, - 79, 2, 11, 83, 2, 175, 2, 73, 2, 233, 209, 26, 6, 79, 84, 78, 79, 84, 69, + 176, 217, 8, 7, 82, 79, 85, 78, 68, 69, 68, 166, 122, 90, 234, 106, 74, + 166, 181, 12, 81, 223, 1, 65, 2, 199, 203, 31, 72, 4, 24, 2, 65, 82, 31, + 79, 2, 11, 83, 2, 175, 2, 73, 2, 157, 193, 26, 6, 79, 84, 78, 79, 84, 69, 10, 60, 8, 73, 71, 65, 84, 85, 82, 69, 32, 225, 11, 2, 65, 77, 8, 88, 10, 65, 76, 69, 70, 32, 87, 73, 84, 72, 32, 116, 3, 81, 65, 70, 1, 3, 83, 65, - 68, 4, 84, 8, 76, 65, 77, 32, 87, 73, 84, 72, 253, 212, 36, 7, 89, 69, - 72, 32, 66, 65, 82, 2, 201, 209, 31, 2, 32, 89, 2, 89, 20, 32, 87, 73, + 68, 4, 84, 8, 76, 65, 77, 32, 87, 73, 84, 72, 177, 196, 36, 7, 89, 69, + 72, 32, 66, 65, 82, 2, 253, 192, 31, 2, 32, 89, 2, 89, 20, 32, 87, 73, 84, 72, 32, 76, 65, 77, 32, 87, 73, 84, 72, 32, 65, 76, 69, 70, 32, 2, - 133, 173, 22, 3, 77, 65, 75, 6, 26, 69, 191, 142, 16, 65, 4, 17, 2, 69, + 133, 161, 22, 3, 77, 65, 75, 6, 26, 69, 191, 130, 16, 65, 4, 17, 2, 69, 77, 4, 17, 2, 32, 73, 4, 22, 78, 147, 9, 83, 2, 205, 9, 2, 73, 84, 6, - 240, 199, 36, 7, 73, 71, 78, 32, 83, 65, 70, 166, 39, 69, 231, 143, 1, - 65, 4, 166, 224, 23, 72, 155, 227, 14, 65, 20, 40, 4, 79, 82, 68, 32, - 227, 197, 37, 65, 18, 74, 65, 172, 1, 2, 83, 65, 168, 201, 25, 3, 87, 65, - 81, 247, 246, 11, 81, 10, 244, 137, 7, 3, 76, 45, 74, 188, 200, 18, 3, + 164, 183, 36, 7, 73, 71, 78, 32, 83, 65, 70, 166, 39, 69, 231, 143, 1, + 65, 4, 162, 212, 23, 72, 211, 222, 14, 65, 20, 40, 4, 79, 82, 68, 32, + 151, 181, 37, 65, 18, 74, 65, 172, 1, 2, 83, 65, 220, 184, 25, 3, 87, 65, + 81, 247, 246, 11, 81, 10, 244, 133, 7, 3, 76, 45, 74, 240, 187, 18, 3, 82, 45, 82, 240, 230, 6, 7, 84, 72, 45, 84, 72, 65, 76, 236, 136, 5, 5, - 78, 45, 78, 73, 83, 161, 92, 5, 83, 45, 83, 65, 74, 4, 186, 157, 38, 75, - 207, 36, 72, 4, 17, 2, 69, 72, 5, 157, 196, 10, 12, 32, 66, 65, 82, 82, - 69, 69, 32, 87, 73, 84, 72, 22, 50, 78, 98, 87, 170, 137, 25, 77, 199, + 78, 45, 78, 73, 83, 161, 92, 5, 83, 45, 83, 65, 74, 4, 238, 140, 38, 75, + 207, 36, 72, 4, 17, 2, 69, 72, 5, 233, 187, 10, 12, 32, 66, 65, 82, 82, + 69, 69, 32, 87, 73, 84, 72, 22, 50, 78, 98, 87, 222, 248, 24, 77, 199, 224, 11, 83, 4, 21, 3, 79, 79, 78, 5, 37, 7, 32, 87, 73, 84, 72, 32, 75, - 2, 11, 65, 2, 207, 251, 37, 83, 14, 40, 4, 79, 82, 68, 32, 179, 193, 37, - 65, 12, 106, 73, 162, 135, 16, 77, 128, 182, 9, 3, 84, 65, 83, 208, 228, - 8, 2, 83, 65, 153, 228, 3, 3, 81, 65, 83, 4, 168, 168, 13, 2, 77, 65, - 181, 145, 19, 3, 83, 72, 77, 12, 138, 1, 66, 64, 3, 75, 85, 78, 141, 139, - 25, 22, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 32, 77, - 79, 75, 72, 65, 83, 83, 2, 33, 6, 83, 67, 82, 73, 80, 84, 2, 137, 184, - 22, 2, 32, 65, 9, 11, 32, 6, 34, 73, 54, 77, 147, 154, 36, 66, 2, 11, 83, - 2, 209, 237, 31, 5, 79, 76, 65, 84, 69, 2, 11, 69, 2, 11, 68, 2, 11, 73, - 2, 245, 188, 37, 2, 65, 76, 34, 156, 1, 2, 68, 79, 126, 84, 188, 183, 5, - 8, 83, 77, 65, 76, 76, 32, 84, 65, 200, 212, 26, 4, 70, 79, 85, 82, 224, + 2, 11, 65, 2, 131, 235, 37, 83, 14, 40, 4, 79, 82, 68, 32, 231, 176, 37, + 65, 12, 106, 73, 162, 251, 15, 77, 180, 177, 9, 3, 84, 65, 83, 208, 228, + 8, 2, 83, 65, 153, 228, 3, 3, 81, 65, 83, 4, 244, 159, 13, 2, 77, 65, + 157, 137, 19, 3, 83, 72, 77, 12, 138, 1, 66, 64, 3, 75, 85, 78, 193, 250, + 24, 22, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 32, 77, + 79, 75, 72, 65, 83, 83, 2, 33, 6, 83, 67, 82, 73, 80, 84, 2, 137, 172, + 22, 2, 32, 65, 9, 11, 32, 6, 34, 73, 54, 77, 199, 137, 36, 66, 2, 11, 83, + 2, 133, 221, 31, 5, 79, 76, 65, 84, 69, 2, 11, 69, 2, 11, 68, 2, 11, 73, + 2, 169, 172, 37, 2, 65, 76, 34, 156, 1, 2, 68, 79, 126, 84, 188, 179, 5, + 8, 83, 77, 65, 76, 76, 32, 84, 65, 252, 199, 26, 4, 70, 79, 85, 82, 224, 129, 1, 4, 87, 65, 83, 76, 187, 218, 4, 82, 6, 48, 6, 85, 66, 76, 69, 32, - 86, 215, 151, 36, 84, 2, 49, 10, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, - 2, 155, 136, 36, 82, 16, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, - 121, 8, 87, 79, 32, 68, 79, 84, 83, 32, 8, 192, 139, 32, 17, 80, 79, 73, + 86, 139, 135, 36, 84, 2, 49, 10, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, + 2, 207, 247, 35, 82, 16, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, + 121, 8, 87, 79, 32, 68, 79, 84, 83, 32, 8, 244, 250, 31, 17, 80, 79, 73, 78, 84, 73, 78, 71, 32, 68, 79, 87, 78, 87, 65, 82, 68, 150, 139, 4, 66, - 131, 165, 1, 65, 8, 128, 186, 10, 9, 86, 69, 82, 84, 73, 67, 65, 76, 76, - 222, 219, 25, 66, 131, 165, 1, 65, 30, 202, 1, 65, 152, 2, 4, 79, 78, 69, - 32, 164, 130, 11, 12, 82, 73, 80, 76, 69, 32, 68, 79, 84, 32, 80, 85, - 144, 205, 6, 8, 85, 82, 78, 69, 68, 32, 68, 65, 197, 154, 14, 8, 72, 79, - 85, 83, 65, 78, 68, 83, 12, 68, 5, 84, 87, 69, 69, 76, 177, 150, 36, 6, + 131, 165, 1, 65, 8, 204, 177, 10, 9, 86, 69, 82, 84, 73, 67, 65, 76, 76, + 198, 211, 25, 66, 131, 165, 1, 65, 30, 202, 1, 65, 152, 2, 4, 79, 78, 69, + 32, 240, 249, 10, 12, 82, 73, 80, 76, 69, 32, 68, 79, 84, 32, 80, 85, + 196, 201, 6, 8, 85, 82, 78, 69, 68, 32, 68, 65, 249, 149, 14, 8, 72, 79, + 85, 83, 65, 78, 68, 83, 12, 68, 5, 84, 87, 69, 69, 76, 229, 133, 36, 6, 73, 76, 32, 70, 82, 65, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 112, 11, - 79, 86, 69, 82, 83, 84, 82, 85, 67, 75, 32, 140, 205, 5, 7, 70, 65, 84, - 72, 65, 84, 65, 159, 233, 4, 84, 4, 26, 72, 131, 181, 37, 87, 2, 133, - 133, 30, 2, 65, 77, 12, 68, 3, 79, 78, 69, 194, 166, 30, 84, 245, 233, 5, - 4, 76, 79, 79, 80, 4, 173, 142, 34, 2, 32, 68, 8, 64, 10, 79, 87, 69, 76, - 32, 83, 73, 71, 78, 32, 255, 164, 24, 69, 6, 72, 10, 73, 78, 86, 69, 82, - 84, 69, 68, 32, 83, 2, 83, 211, 222, 25, 68, 2, 25, 4, 77, 65, 76, 76, 2, - 249, 179, 37, 2, 32, 86, 28, 104, 4, 80, 69, 82, 32, 236, 253, 5, 3, 67, - 85, 66, 204, 138, 5, 5, 70, 79, 85, 82, 84, 187, 179, 25, 68, 4, 234, - 169, 25, 77, 31, 84, 188, 1, 222, 1, 65, 34, 67, 138, 3, 69, 60, 7, 83, - 77, 65, 76, 76, 32, 76, 200, 155, 21, 17, 77, 79, 68, 73, 70, 73, 69, 82, - 32, 76, 69, 84, 84, 69, 82, 32, 76, 222, 253, 8, 72, 140, 188, 2, 3, 68, - 82, 65, 178, 255, 2, 70, 83, 81, 4, 218, 236, 31, 66, 143, 26, 80, 78, - 80, 14, 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, 191, 215, + 79, 86, 69, 82, 83, 84, 82, 85, 67, 75, 32, 140, 201, 5, 7, 70, 65, 84, + 72, 65, 84, 65, 235, 228, 4, 84, 4, 26, 72, 183, 164, 37, 87, 2, 185, + 244, 29, 2, 65, 77, 12, 68, 3, 79, 78, 69, 246, 149, 30, 84, 245, 233, 5, + 4, 76, 79, 79, 80, 4, 225, 253, 33, 2, 32, 68, 8, 64, 10, 79, 87, 69, 76, + 32, 83, 73, 71, 78, 32, 179, 148, 24, 69, 6, 72, 10, 73, 78, 86, 69, 82, + 84, 69, 68, 32, 83, 2, 83, 135, 206, 25, 68, 2, 25, 4, 77, 65, 76, 76, 2, + 173, 163, 37, 2, 32, 86, 28, 104, 4, 80, 69, 82, 32, 236, 249, 5, 3, 67, + 85, 66, 152, 134, 5, 5, 70, 79, 85, 82, 84, 163, 171, 25, 68, 4, 158, + 153, 25, 77, 31, 84, 188, 1, 222, 1, 65, 34, 67, 138, 3, 69, 60, 7, 83, + 77, 65, 76, 76, 32, 76, 200, 143, 21, 17, 77, 79, 68, 73, 70, 73, 69, 82, + 32, 76, 69, 84, 84, 69, 82, 32, 76, 146, 249, 8, 72, 140, 188, 2, 3, 68, + 82, 65, 178, 255, 2, 70, 83, 81, 4, 142, 220, 31, 66, 143, 26, 80, 78, + 80, 14, 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, 243, 198, 35, 79, 76, 250, 1, 84, 36, 2, 89, 73, 150, 3, 67, 38, 82, 34, 69, 42, - 71, 34, 74, 38, 75, 22, 80, 38, 83, 106, 65, 22, 86, 158, 1, 76, 246, - 173, 31, 70, 2, 88, 134, 241, 1, 73, 214, 174, 3, 66, 2, 77, 222, 57, 78, - 230, 28, 90, 210, 96, 72, 190, 28, 68, 171, 1, 79, 4, 214, 212, 36, 73, - 179, 214, 1, 79, 5, 131, 219, 37, 87, 4, 162, 134, 32, 88, 233, 210, 4, + 71, 34, 74, 38, 75, 22, 80, 38, 83, 106, 65, 22, 86, 158, 1, 76, 170, + 157, 31, 70, 2, 88, 134, 241, 1, 73, 214, 174, 3, 66, 2, 77, 222, 57, 78, + 230, 28, 90, 210, 96, 72, 190, 28, 68, 171, 1, 79, 4, 138, 196, 36, 73, + 179, 214, 1, 79, 5, 183, 202, 37, 87, 4, 214, 245, 31, 88, 233, 210, 4, 6, 77, 80, 72, 65, 83, 73, 92, 76, 6, 69, 84, 84, 69, 82, 32, 157, 5, 8, 73, 71, 65, 84, 85, 82, 69, 32, 80, 242, 1, 67, 38, 82, 34, 69, 42, 71, 34, 74, 38, 75, 22, 80, 38, 83, 34, 84, 74, 65, 22, 86, 32, 2, 89, 73, - 126, 76, 246, 173, 31, 70, 2, 88, 134, 241, 1, 73, 214, 174, 3, 66, 2, + 126, 76, 170, 157, 31, 70, 2, 88, 134, 241, 1, 73, 214, 174, 3, 66, 2, 77, 222, 57, 78, 230, 28, 90, 210, 96, 72, 190, 28, 68, 171, 1, 79, 8, - 34, 72, 174, 167, 38, 65, 3, 79, 4, 154, 166, 38, 69, 147, 1, 65, 6, 250, - 165, 38, 67, 146, 1, 72, 3, 84, 4, 182, 224, 37, 72, 215, 53, 73, 4, 230, - 176, 31, 72, 223, 245, 6, 65, 4, 223, 250, 33, 69, 4, 214, 251, 3, 73, - 167, 169, 34, 69, 4, 174, 163, 38, 72, 171, 1, 69, 6, 68, 7, 85, 82, 78, - 69, 68, 32, 65, 210, 206, 36, 73, 179, 214, 1, 79, 2, 135, 231, 36, 89, - 4, 202, 166, 37, 69, 163, 126, 79, 7, 194, 195, 21, 32, 171, 145, 16, 87, - 12, 84, 5, 69, 67, 72, 32, 89, 20, 4, 77, 69, 78, 32, 221, 142, 30, 4, - 86, 69, 87, 32, 2, 159, 205, 36, 73, 8, 222, 173, 31, 88, 134, 241, 1, + 34, 72, 226, 150, 38, 65, 3, 79, 4, 206, 149, 38, 69, 147, 1, 65, 6, 174, + 149, 38, 67, 146, 1, 72, 3, 84, 4, 234, 207, 37, 72, 215, 53, 73, 4, 154, + 160, 31, 72, 223, 245, 6, 65, 4, 147, 234, 33, 69, 4, 214, 251, 3, 73, + 219, 152, 34, 69, 4, 226, 146, 38, 72, 171, 1, 69, 6, 68, 7, 85, 82, 78, + 69, 68, 32, 65, 134, 190, 36, 73, 179, 214, 1, 79, 2, 187, 214, 36, 89, + 4, 254, 149, 37, 69, 163, 126, 79, 7, 194, 183, 21, 32, 223, 140, 16, 87, + 12, 84, 5, 69, 67, 72, 32, 89, 20, 4, 77, 69, 78, 32, 145, 254, 29, 4, + 86, 69, 87, 32, 2, 211, 188, 36, 73, 8, 146, 157, 31, 88, 134, 241, 1, 73, 178, 232, 3, 78, 131, 122, 69, 14, 108, 10, 32, 80, 79, 73, 78, 84, - 73, 78, 71, 32, 137, 226, 36, 11, 72, 69, 65, 68, 45, 83, 72, 65, 80, 69, + 73, 78, 71, 32, 189, 209, 36, 11, 72, 69, 65, 68, 45, 83, 72, 65, 80, 69, 68, 12, 156, 2, 24, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 32, 84, 72, 69, 78, 32, 67, 85, 82, 86, 73, 78, 71, 32, 48, 16, 85, 80, 87, 65, 82, - 68, 83, 32, 84, 72, 69, 78, 32, 78, 79, 82, 197, 189, 35, 22, 68, 79, 87, + 68, 83, 32, 84, 72, 69, 78, 32, 78, 79, 82, 249, 172, 35, 22, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, 72, 69, 78, 32, 67, 85, 82, 86, 73, 78, - 71, 6, 44, 3, 83, 79, 85, 222, 237, 26, 68, 35, 85, 2, 153, 173, 34, 4, - 84, 72, 32, 87, 4, 176, 217, 31, 11, 67, 85, 76, 65, 84, 69, 68, 32, 76, - 79, 82, 189, 252, 4, 6, 83, 84, 32, 80, 65, 76, 24, 58, 67, 38, 84, 206, - 180, 23, 89, 145, 202, 9, 2, 83, 69, 4, 242, 181, 8, 69, 167, 194, 11, + 71, 6, 44, 3, 83, 79, 85, 146, 221, 26, 68, 35, 85, 2, 205, 156, 34, 4, + 84, 72, 32, 87, 4, 228, 200, 31, 11, 67, 85, 76, 65, 84, 69, 68, 32, 76, + 79, 82, 189, 252, 4, 6, 83, 84, 32, 80, 65, 76, 24, 58, 67, 38, 84, 202, + 168, 23, 89, 201, 197, 9, 2, 83, 69, 4, 242, 177, 8, 69, 167, 186, 11, 73, 16, 48, 4, 69, 82, 73, 83, 36, 2, 79, 78, 31, 82, 6, 174, 227, 2, 75, - 239, 185, 35, 77, 2, 237, 138, 14, 2, 73, 83, 8, 104, 20, 79, 78, 79, 77, - 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 211, 138, - 14, 65, 4, 164, 227, 25, 13, 65, 83, 84, 69, 82, 79, 73, 68, 32, 80, 82, - 79, 83, 205, 175, 10, 2, 85, 82, 4, 164, 197, 19, 6, 72, 76, 69, 84, 73, - 67, 165, 192, 17, 2, 79, 77, 10, 68, 2, 84, 79, 160, 249, 21, 2, 83, 84, - 209, 169, 2, 3, 66, 69, 82, 6, 54, 77, 161, 155, 37, 7, 32, 82, 73, 67, - 75, 83, 72, 4, 162, 162, 24, 79, 209, 202, 5, 12, 65, 84, 69, 68, 32, 84, - 69, 76, 76, 69, 82, 32, 112, 56, 6, 69, 83, 84, 65, 78, 32, 169, 231, 4, - 2, 79, 67, 110, 52, 7, 76, 69, 84, 84, 69, 82, 32, 223, 214, 31, 65, 108, - 234, 1, 65, 58, 71, 42, 72, 34, 78, 50, 88, 42, 83, 42, 89, 34, 84, 254, - 188, 34, 85, 206, 141, 1, 79, 238, 60, 73, 166, 140, 1, 66, 2, 68, 2, 90, + 163, 169, 35, 77, 2, 185, 130, 14, 2, 73, 83, 8, 104, 20, 79, 78, 79, 77, + 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 159, 130, + 14, 65, 4, 216, 210, 25, 13, 65, 83, 84, 69, 82, 79, 73, 68, 32, 80, 82, + 79, 83, 205, 175, 10, 2, 85, 82, 4, 164, 185, 19, 6, 72, 76, 69, 84, 73, + 67, 217, 187, 17, 2, 79, 77, 10, 68, 2, 84, 79, 160, 237, 21, 2, 83, 84, + 133, 165, 2, 3, 66, 69, 82, 6, 54, 77, 213, 138, 37, 7, 32, 82, 73, 67, + 75, 83, 72, 4, 214, 145, 24, 79, 209, 202, 5, 12, 65, 84, 69, 68, 32, 84, + 69, 76, 76, 69, 82, 32, 112, 56, 6, 69, 83, 84, 65, 78, 32, 169, 227, 4, + 2, 79, 67, 110, 52, 7, 76, 69, 84, 84, 69, 82, 32, 147, 198, 31, 65, 108, + 234, 1, 65, 58, 71, 42, 72, 34, 78, 50, 88, 42, 83, 42, 89, 34, 84, 178, + 172, 34, 85, 206, 141, 1, 79, 238, 60, 73, 166, 140, 1, 66, 2, 68, 2, 90, 130, 64, 69, 206, 41, 67, 2, 70, 2, 74, 2, 75, 2, 76, 2, 77, 2, 80, 2, - 82, 3, 86, 17, 182, 198, 35, 65, 194, 143, 2, 69, 162, 64, 78, 3, 79, 6, - 138, 255, 37, 71, 2, 72, 215, 22, 69, 4, 226, 254, 37, 77, 215, 22, 69, - 12, 46, 71, 150, 254, 37, 78, 2, 89, 215, 22, 69, 6, 146, 254, 37, 86, 2, - 89, 215, 22, 69, 8, 38, 72, 142, 231, 37, 83, 143, 45, 69, 4, 194, 253, - 37, 89, 215, 22, 69, 6, 162, 253, 37, 72, 2, 84, 215, 22, 69, 178, 42, + 82, 3, 86, 17, 234, 181, 35, 65, 194, 143, 2, 69, 162, 64, 78, 3, 79, 6, + 190, 238, 37, 71, 2, 72, 215, 22, 69, 4, 150, 238, 37, 77, 215, 22, 69, + 12, 46, 71, 202, 237, 37, 78, 2, 89, 215, 22, 69, 6, 198, 237, 37, 86, 2, + 89, 215, 22, 69, 8, 38, 72, 194, 214, 37, 83, 143, 45, 69, 4, 246, 236, + 37, 89, 215, 22, 69, 6, 214, 236, 37, 72, 2, 84, 215, 22, 69, 178, 42, 178, 1, 65, 194, 171, 1, 69, 244, 21, 9, 72, 65, 73, 75, 83, 85, 75, 73, 32, 202, 6, 73, 130, 3, 76, 182, 45, 79, 138, 70, 82, 246, 18, 85, 138, - 8, 89, 214, 183, 35, 80, 147, 1, 83, 198, 14, 132, 1, 2, 66, 89, 94, 67, + 8, 89, 138, 167, 35, 80, 147, 1, 83, 198, 14, 132, 1, 2, 66, 89, 94, 67, 206, 2, 68, 146, 1, 71, 106, 76, 192, 29, 4, 77, 85, 77, 32, 190, 115, - 78, 178, 1, 82, 98, 83, 223, 6, 84, 11, 11, 32, 8, 226, 253, 12, 67, 222, - 248, 5, 66, 144, 133, 14, 3, 65, 78, 71, 135, 128, 4, 83, 16, 62, 75, - 244, 135, 9, 5, 84, 82, 73, 65, 78, 159, 184, 28, 79, 12, 42, 32, 46, 83, - 145, 236, 10, 2, 45, 84, 4, 214, 137, 10, 87, 253, 237, 20, 2, 79, 70, 6, + 78, 178, 1, 82, 98, 83, 223, 6, 84, 11, 11, 32, 8, 174, 245, 12, 67, 146, + 245, 5, 66, 196, 128, 14, 3, 65, 78, 71, 135, 128, 4, 83, 16, 62, 75, + 244, 131, 9, 5, 84, 82, 73, 65, 78, 211, 171, 28, 79, 12, 42, 32, 46, 83, + 221, 227, 10, 2, 45, 84, 4, 162, 129, 10, 87, 229, 229, 20, 2, 79, 70, 6, 132, 1, 26, 76, 65, 78, 84, 69, 68, 32, 83, 79, 85, 84, 72, 32, 65, 82, - 82, 79, 87, 32, 87, 73, 84, 72, 32, 72, 79, 139, 209, 37, 80, 4, 138, - 221, 29, 82, 165, 193, 5, 2, 79, 75, 4, 224, 155, 35, 27, 77, 73, 78, 84, + 82, 79, 87, 32, 87, 73, 84, 72, 32, 72, 79, 191, 192, 37, 80, 4, 190, + 204, 29, 82, 165, 193, 5, 2, 79, 75, 4, 148, 139, 35, 27, 77, 73, 78, 84, 79, 78, 32, 82, 65, 67, 81, 85, 69, 84, 32, 65, 78, 68, 32, 83, 72, 85, - 84, 84, 76, 69, 67, 151, 180, 2, 71, 6, 224, 130, 31, 6, 85, 69, 84, 84, + 84, 84, 76, 69, 67, 151, 180, 2, 71, 6, 148, 242, 30, 6, 85, 69, 84, 84, 69, 32, 162, 254, 5, 69, 129, 9, 8, 71, 65, 71, 69, 32, 67, 76, 65, 156, 2, 44, 6, 73, 78, 69, 83, 69, 32, 183, 25, 76, 254, 1, 132, 3, 6, 67, 65, 82, 73, 75, 32, 84, 15, 73, 78, 86, 69, 82, 84, 69, 68, 32, 67, 65, 82, 73, 75, 32, 68, 7, 76, 69, 84, 84, 69, 82, 32, 224, 8, 15, 77, 85, 83, 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 196, 6, 2, 80, 65, 184, 1, 5, 83, 73, 71, 78, 32, 176, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, - 78, 32, 220, 184, 14, 5, 65, 68, 69, 71, 32, 130, 159, 19, 87, 167, 169, - 2, 68, 6, 32, 2, 80, 65, 167, 136, 3, 83, 4, 86, 82, 177, 153, 31, 5, 77, - 85, 78, 71, 75, 4, 36, 3, 80, 65, 82, 207, 135, 3, 83, 2, 169, 177, 36, + 78, 32, 168, 176, 14, 5, 65, 68, 69, 71, 32, 234, 150, 19, 87, 167, 169, + 2, 68, 6, 32, 2, 80, 65, 167, 136, 3, 83, 4, 86, 82, 229, 136, 31, 5, 77, + 85, 78, 71, 75, 4, 36, 3, 80, 65, 82, 207, 135, 3, 83, 2, 221, 160, 36, 2, 69, 82, 110, 166, 2, 65, 112, 2, 66, 65, 32, 2, 67, 65, 32, 2, 68, 65, 110, 69, 32, 2, 71, 65, 30, 73, 2, 79, 2, 85, 36, 2, 74, 65, 30, 75, 68, 2, 76, 65, 18, 78, 72, 2, 80, 65, 36, 2, 82, 65, 16, 2, 83, 65, 54, 84, - 128, 1, 2, 86, 69, 0, 3, 90, 65, 76, 154, 252, 37, 72, 2, 77, 2, 87, 3, - 89, 10, 226, 2, 75, 184, 3, 5, 83, 89, 85, 82, 65, 184, 182, 15, 8, 82, - 67, 72, 65, 73, 67, 32, 74, 187, 255, 3, 73, 5, 197, 142, 19, 3, 32, 75, - 69, 5, 161, 152, 31, 3, 32, 76, 65, 9, 17, 2, 32, 77, 6, 44, 5, 85, 82, - 68, 65, 32, 231, 229, 33, 65, 4, 254, 195, 14, 77, 25, 3, 65, 76, 80, 4, - 254, 3, 70, 135, 186, 37, 75, 5, 217, 141, 35, 2, 32, 71, 4, 11, 75, 4, - 161, 15, 2, 65, 82, 5, 249, 239, 35, 2, 32, 74, 8, 34, 65, 225, 2, 3, 72, - 79, 84, 7, 222, 2, 70, 207, 191, 14, 32, 7, 131, 13, 32, 8, 34, 65, 166, - 254, 37, 71, 3, 89, 5, 233, 151, 27, 4, 32, 82, 65, 77, 5, 217, 244, 36, - 4, 32, 75, 65, 80, 7, 167, 12, 32, 7, 21, 3, 32, 83, 65, 4, 178, 253, 37, - 71, 3, 80, 10, 30, 65, 97, 3, 90, 73, 82, 9, 11, 32, 6, 156, 192, 14, 6, - 77, 85, 82, 68, 65, 32, 212, 7, 3, 76, 65, 84, 203, 189, 18, 84, 2, 189, - 188, 14, 2, 32, 83, 56, 168, 1, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, + 128, 1, 2, 86, 69, 0, 3, 90, 65, 76, 206, 235, 37, 72, 2, 77, 2, 87, 3, + 89, 10, 226, 2, 75, 184, 3, 5, 83, 89, 85, 82, 65, 184, 170, 15, 8, 82, + 67, 72, 65, 73, 67, 32, 74, 187, 255, 3, 73, 5, 197, 130, 19, 3, 32, 75, + 69, 5, 213, 135, 31, 3, 32, 76, 65, 9, 17, 2, 32, 77, 6, 44, 5, 85, 82, + 68, 65, 32, 155, 213, 33, 65, 4, 202, 187, 14, 77, 25, 3, 65, 76, 80, 4, + 254, 3, 70, 187, 169, 37, 75, 5, 141, 253, 34, 2, 32, 71, 4, 11, 75, 4, + 161, 15, 2, 65, 82, 5, 173, 223, 35, 2, 32, 74, 8, 34, 65, 225, 2, 3, 72, + 79, 84, 7, 222, 2, 70, 155, 183, 14, 32, 7, 131, 13, 32, 8, 34, 65, 218, + 237, 37, 71, 3, 89, 5, 157, 135, 27, 4, 32, 82, 65, 77, 5, 141, 228, 36, + 4, 32, 75, 65, 80, 7, 167, 12, 32, 7, 21, 3, 32, 83, 65, 4, 230, 236, 37, + 71, 3, 80, 10, 30, 65, 97, 3, 90, 73, 82, 9, 11, 32, 6, 232, 183, 14, 6, + 77, 85, 82, 68, 65, 32, 212, 7, 3, 76, 65, 84, 179, 181, 18, 84, 2, 137, + 180, 14, 2, 32, 83, 56, 168, 1, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 246, 1, 68, 172, 1, 10, 76, 69, 70, 84, 45, 72, 65, 78, 68, 32, 117, 11, 82, 73, 71, 72, 84, 45, 72, 65, 78, 68, 32, 18, 132, 1, 4, 75, 69, - 77, 80, 78, 74, 168, 158, 20, 2, 66, 69, 168, 187, 7, 3, 69, 78, 68, 136, + 77, 80, 78, 74, 168, 146, 20, 2, 66, 69, 220, 182, 7, 3, 69, 78, 68, 136, 172, 3, 3, 84, 69, 71, 207, 174, 4, 71, 8, 32, 2, 76, 73, 1, 2, 85, 76, - 5, 37, 7, 32, 87, 73, 84, 72, 32, 74, 2, 185, 182, 14, 3, 69, 71, 79, 20, - 50, 65, 90, 69, 146, 169, 37, 73, 2, 79, 3, 85, 10, 40, 2, 78, 71, 190, - 169, 37, 69, 3, 73, 7, 11, 32, 4, 218, 4, 83, 171, 135, 11, 71, 4, 142, - 169, 37, 85, 167, 80, 78, 10, 76, 6, 79, 80, 69, 78, 32, 80, 113, 9, 67, - 76, 79, 83, 69, 68, 32, 80, 76, 6, 158, 168, 37, 65, 2, 73, 3, 85, 8, 72, - 8, 67, 76, 79, 83, 69, 68, 32, 84, 29, 6, 79, 80, 69, 78, 32, 68, 4, 142, - 245, 37, 65, 3, 85, 4, 182, 247, 37, 65, 3, 85, 12, 30, 77, 69, 3, 78, - 84, 73, 6, 44, 3, 65, 68, 65, 193, 176, 35, 2, 69, 78, 5, 69, 2, 32, 76, - 7, 11, 32, 4, 38, 76, 209, 189, 35, 3, 66, 65, 87, 2, 129, 158, 37, 3, - 65, 78, 84, 12, 106, 83, 20, 4, 85, 76, 85, 32, 202, 128, 31, 67, 240, 6, - 3, 66, 73, 83, 133, 255, 1, 4, 82, 69, 82, 69, 2, 171, 131, 25, 85, 4, - 210, 221, 20, 67, 185, 133, 17, 3, 82, 73, 67, 30, 120, 3, 76, 65, 32, + 5, 37, 7, 32, 87, 73, 84, 72, 32, 74, 2, 133, 174, 14, 3, 69, 71, 79, 20, + 50, 65, 90, 69, 198, 152, 37, 73, 2, 79, 3, 85, 10, 40, 2, 78, 71, 242, + 152, 37, 69, 3, 73, 7, 11, 32, 4, 218, 4, 83, 247, 254, 10, 71, 4, 194, + 152, 37, 85, 167, 80, 78, 10, 76, 6, 79, 80, 69, 78, 32, 80, 113, 9, 67, + 76, 79, 83, 69, 68, 32, 80, 76, 6, 210, 151, 37, 65, 2, 73, 3, 85, 8, 72, + 8, 67, 76, 79, 83, 69, 68, 32, 84, 29, 6, 79, 80, 69, 78, 32, 68, 4, 194, + 228, 37, 65, 3, 85, 4, 234, 230, 37, 65, 3, 85, 12, 30, 77, 69, 3, 78, + 84, 73, 6, 44, 3, 65, 68, 65, 245, 159, 35, 2, 69, 78, 5, 69, 2, 32, 76, + 7, 11, 32, 4, 38, 76, 133, 173, 35, 3, 66, 65, 87, 2, 181, 141, 37, 3, + 65, 78, 84, 12, 106, 83, 20, 4, 85, 76, 85, 32, 254, 239, 30, 67, 240, 6, + 3, 66, 73, 83, 133, 255, 1, 4, 82, 69, 82, 69, 2, 223, 242, 24, 85, 4, + 210, 209, 20, 67, 237, 128, 17, 3, 82, 73, 67, 30, 120, 3, 76, 65, 32, 32, 3, 82, 65, 32, 12, 4, 83, 85, 75, 85, 34, 84, 104, 5, 80, 69, 80, 69, - 84, 53, 3, 85, 76, 85, 4, 165, 1, 4, 76, 69, 78, 71, 4, 115, 82, 5, 141, - 250, 36, 3, 32, 73, 76, 10, 36, 5, 65, 76, 73, 78, 71, 99, 69, 9, 11, 32, + 84, 53, 3, 85, 76, 85, 4, 165, 1, 4, 76, 69, 78, 71, 4, 115, 82, 5, 193, + 233, 36, 3, 32, 73, 76, 10, 36, 5, 65, 76, 73, 78, 71, 99, 69, 9, 11, 32, 6, 18, 82, 55, 84, 4, 17, 2, 69, 80, 4, 11, 65, 5, 17, 2, 32, 84, 2, 11, - 69, 2, 251, 254, 30, 68, 5, 213, 134, 31, 3, 32, 83, 65, 30, 86, 79, 208, - 174, 23, 5, 32, 79, 70, 32, 89, 217, 172, 13, 6, 69, 84, 32, 83, 72, 79, - 26, 32, 2, 79, 78, 21, 2, 84, 32, 5, 135, 217, 35, 45, 22, 44, 2, 66, 79, - 246, 1, 83, 211, 238, 37, 88, 18, 38, 88, 205, 1, 4, 76, 68, 32, 83, 17, - 33, 6, 32, 87, 73, 84, 72, 32, 14, 82, 66, 86, 83, 184, 230, 12, 4, 76, - 73, 71, 72, 134, 189, 10, 67, 151, 203, 14, 88, 6, 52, 4, 79, 76, 68, 32, - 181, 158, 37, 3, 65, 76, 76, 4, 26, 83, 191, 163, 23, 67, 2, 181, 230, + 69, 2, 175, 238, 30, 68, 5, 137, 246, 30, 3, 32, 83, 65, 30, 86, 79, 132, + 158, 23, 5, 32, 79, 70, 32, 89, 217, 172, 13, 6, 69, 84, 32, 83, 72, 79, + 26, 32, 2, 79, 78, 21, 2, 84, 32, 5, 187, 200, 35, 45, 22, 44, 2, 66, 79, + 246, 1, 83, 135, 222, 37, 88, 18, 38, 88, 205, 1, 4, 76, 68, 32, 83, 17, + 33, 6, 32, 87, 73, 84, 72, 32, 14, 82, 66, 86, 83, 132, 222, 12, 4, 76, + 73, 71, 72, 238, 180, 10, 67, 151, 203, 14, 88, 6, 52, 4, 79, 76, 68, 32, + 233, 141, 37, 3, 65, 76, 76, 4, 26, 83, 243, 146, 23, 67, 2, 129, 222, 12, 4, 67, 82, 73, 80, 172, 10, 120, 2, 67, 79, 180, 1, 7, 76, 69, 84, - 84, 69, 82, 32, 208, 92, 3, 78, 74, 65, 194, 238, 28, 83, 182, 203, 5, - 70, 83, 81, 8, 26, 77, 167, 157, 37, 76, 6, 72, 12, 66, 73, 78, 73, 78, - 71, 32, 77, 65, 82, 75, 32, 143, 234, 37, 77, 4, 184, 242, 21, 6, 84, 85, - 75, 87, 69, 78, 217, 173, 3, 4, 75, 79, 81, 78, 156, 10, 170, 1, 70, 58, + 84, 69, 82, 32, 208, 92, 3, 78, 74, 65, 246, 221, 28, 83, 182, 203, 5, + 70, 83, 81, 8, 26, 77, 219, 140, 37, 76, 6, 72, 12, 66, 73, 78, 73, 78, + 71, 32, 77, 65, 82, 75, 32, 195, 217, 37, 77, 4, 184, 230, 21, 6, 84, 85, + 75, 87, 69, 78, 141, 169, 3, 4, 75, 79, 81, 78, 156, 10, 170, 1, 70, 58, 75, 170, 1, 76, 66, 77, 102, 78, 234, 1, 80, 166, 104, 82, 102, 83, 134, - 1, 84, 54, 89, 162, 225, 2, 87, 170, 131, 34, 69, 214, 22, 65, 2, 73, 2, - 79, 3, 85, 8, 170, 80, 65, 202, 131, 37, 69, 254, 5, 79, 219, 16, 85, 22, - 78, 69, 46, 79, 246, 246, 35, 89, 234, 239, 1, 80, 186, 2, 65, 2, 73, 3, - 85, 6, 254, 218, 36, 85, 194, 142, 1, 78, 3, 84, 7, 162, 244, 35, 86, - 141, 228, 1, 2, 71, 72, 10, 154, 103, 69, 182, 158, 26, 79, 154, 227, 10, - 65, 2, 73, 3, 85, 19, 62, 69, 254, 101, 66, 238, 129, 37, 65, 2, 73, 2, - 79, 3, 85, 4, 198, 245, 35, 69, 163, 242, 1, 78, 30, 102, 71, 50, 74, 50, - 84, 238, 101, 85, 234, 130, 35, 83, 246, 7, 68, 222, 225, 1, 89, 218, 19, - 65, 3, 73, 6, 134, 247, 32, 75, 158, 237, 4, 71, 187, 2, 65, 6, 182, 233, - 26, 85, 162, 230, 10, 69, 171, 4, 65, 4, 146, 193, 37, 85, 151, 14, 69, - 136, 9, 76, 5, 72, 65, 83, 69, 45, 170, 101, 69, 138, 2, 85, 218, 253, + 1, 84, 54, 89, 162, 225, 2, 87, 222, 242, 33, 69, 214, 22, 65, 2, 73, 2, + 79, 3, 85, 8, 170, 80, 65, 254, 242, 36, 69, 254, 5, 79, 219, 16, 85, 22, + 78, 69, 46, 79, 170, 230, 35, 89, 234, 239, 1, 80, 186, 2, 65, 2, 73, 3, + 85, 6, 178, 202, 36, 85, 194, 142, 1, 78, 3, 84, 7, 214, 227, 35, 86, + 141, 228, 1, 2, 71, 72, 10, 154, 103, 69, 234, 141, 26, 79, 154, 227, 10, + 65, 2, 73, 3, 85, 19, 62, 69, 254, 101, 66, 162, 241, 36, 65, 2, 73, 2, + 79, 3, 85, 4, 250, 228, 35, 69, 163, 242, 1, 78, 30, 102, 71, 50, 74, 50, + 84, 238, 101, 85, 158, 242, 34, 83, 246, 7, 68, 222, 225, 1, 89, 218, 19, + 65, 3, 73, 6, 186, 230, 32, 75, 158, 237, 4, 71, 187, 2, 65, 6, 234, 216, + 26, 85, 162, 230, 10, 69, 171, 4, 65, 4, 198, 176, 37, 85, 151, 14, 69, + 136, 9, 76, 5, 72, 65, 83, 69, 45, 170, 101, 69, 138, 2, 85, 142, 237, 36, 65, 3, 73, 252, 8, 116, 2, 65, 32, 168, 18, 2, 66, 32, 180, 13, 2, 67, 32, 180, 20, 2, 68, 32, 172, 18, 2, 69, 32, 153, 25, 2, 70, 32, 176, 1, 158, 1, 71, 106, 75, 130, 1, 76, 102, 77, 198, 3, 78, 210, 4, 80, 146, - 2, 83, 190, 2, 84, 154, 1, 85, 216, 230, 30, 2, 70, 73, 174, 249, 4, 86, + 2, 83, 190, 2, 84, 154, 1, 85, 140, 214, 30, 2, 70, 73, 174, 249, 4, 86, 191, 225, 1, 82, 6, 60, 5, 72, 69, 85, 65, 69, 153, 47, 5, 66, 73, 69, - 69, 32, 4, 220, 27, 2, 71, 72, 215, 201, 26, 82, 12, 38, 65, 34, 69, 214, - 67, 80, 3, 85, 4, 158, 223, 37, 70, 187, 2, 81, 4, 188, 129, 34, 5, 85, - 75, 69, 85, 84, 251, 223, 3, 84, 10, 78, 85, 166, 66, 79, 232, 186, 26, - 2, 65, 80, 213, 233, 9, 4, 69, 84, 32, 75, 5, 203, 190, 27, 65, 36, 142, + 69, 32, 4, 220, 27, 2, 71, 72, 139, 185, 26, 82, 12, 38, 65, 34, 69, 214, + 67, 80, 3, 85, 4, 210, 206, 37, 70, 187, 2, 81, 4, 240, 240, 33, 5, 85, + 75, 69, 85, 84, 251, 223, 3, 84, 10, 78, 85, 166, 66, 79, 156, 170, 26, + 2, 65, 80, 213, 233, 9, 4, 69, 84, 32, 75, 5, 255, 173, 27, 65, 36, 142, 1, 65, 176, 1, 2, 66, 65, 38, 79, 76, 6, 86, 69, 85, 65, 69, 78, 180, 71, - 8, 69, 85, 78, 74, 79, 77, 78, 68, 229, 217, 34, 2, 71, 66, 20, 62, 69, - 236, 49, 2, 78, 83, 169, 148, 32, 4, 80, 32, 80, 73, 16, 58, 77, 142, - 190, 12, 75, 138, 176, 7, 78, 167, 220, 17, 83, 11, 230, 24, 66, 14, 71, - 214, 44, 86, 203, 252, 27, 75, 4, 222, 237, 19, 78, 255, 239, 17, 81, 6, - 36, 2, 79, 77, 237, 1, 2, 78, 32, 4, 242, 143, 13, 80, 207, 211, 23, 69, - 2, 219, 159, 36, 71, 48, 122, 65, 32, 2, 68, 65, 54, 71, 98, 75, 32, 2, - 83, 72, 38, 84, 102, 89, 74, 90, 170, 155, 36, 74, 178, 109, 69, 251, 70, - 73, 4, 250, 8, 65, 227, 210, 37, 81, 4, 22, 65, 203, 22, 32, 2, 217, 44, - 3, 78, 71, 71, 8, 52, 3, 75, 85, 69, 170, 226, 32, 65, 167, 162, 3, 71, - 4, 250, 7, 32, 201, 174, 12, 2, 78, 90, 4, 166, 26, 65, 143, 229, 19, 73, - 4, 230, 231, 35, 73, 163, 242, 1, 65, 8, 40, 2, 65, 80, 185, 189, 28, 2, - 79, 81, 7, 11, 32, 4, 244, 227, 35, 2, 77, 70, 1, 2, 78, 84, 6, 26, 73, - 187, 188, 37, 69, 5, 193, 13, 7, 84, 32, 77, 79, 78, 71, 75, 4, 214, 5, - 65, 137, 179, 12, 4, 85, 78, 32, 77, 22, 58, 65, 80, 3, 79, 78, 32, 210, - 186, 37, 69, 163, 28, 85, 10, 42, 65, 198, 18, 32, 142, 18, 77, 15, 83, - 4, 170, 218, 26, 82, 247, 252, 10, 77, 8, 56, 4, 77, 70, 79, 78, 1, 6, + 8, 69, 85, 78, 74, 79, 77, 78, 68, 153, 201, 34, 2, 71, 66, 20, 62, 69, + 236, 49, 2, 78, 83, 221, 131, 32, 4, 80, 32, 80, 73, 16, 58, 77, 218, + 181, 12, 75, 190, 172, 7, 78, 219, 215, 17, 83, 11, 230, 24, 66, 14, 71, + 214, 44, 86, 255, 235, 27, 75, 4, 222, 225, 19, 78, 179, 235, 17, 81, 6, + 36, 2, 79, 77, 237, 1, 2, 78, 32, 4, 190, 135, 13, 80, 183, 203, 23, 69, + 2, 143, 143, 36, 71, 48, 122, 65, 32, 2, 68, 65, 54, 71, 98, 75, 32, 2, + 83, 72, 38, 84, 102, 89, 74, 90, 222, 138, 36, 74, 178, 109, 69, 251, 70, + 73, 4, 250, 8, 65, 151, 194, 37, 81, 4, 22, 65, 203, 22, 32, 2, 217, 44, + 3, 78, 71, 71, 8, 52, 3, 75, 85, 69, 222, 209, 32, 65, 167, 162, 3, 71, + 4, 250, 7, 32, 149, 166, 12, 2, 78, 90, 4, 166, 26, 65, 143, 217, 19, 73, + 4, 154, 215, 35, 73, 163, 242, 1, 65, 8, 40, 2, 65, 80, 237, 172, 28, 2, + 79, 81, 7, 11, 32, 4, 168, 211, 35, 2, 77, 70, 1, 2, 78, 84, 6, 26, 73, + 239, 171, 37, 69, 5, 193, 13, 7, 84, 32, 77, 79, 78, 71, 75, 4, 214, 5, + 65, 213, 170, 12, 4, 85, 78, 32, 77, 22, 58, 65, 80, 3, 79, 78, 32, 134, + 170, 37, 69, 163, 28, 85, 10, 42, 65, 198, 18, 32, 142, 18, 77, 15, 83, + 4, 222, 201, 26, 82, 247, 252, 10, 77, 8, 56, 4, 77, 70, 79, 78, 1, 6, 80, 65, 32, 78, 74, 73, 4, 37, 7, 32, 80, 73, 80, 65, 69, 77, 4, 250, 16, - 71, 231, 194, 37, 66, 22, 70, 72, 194, 1, 79, 144, 67, 2, 69, 85, 250, - 235, 36, 85, 167, 34, 73, 10, 74, 73, 70, 85, 253, 168, 36, 10, 79, 81, - 32, 78, 83, 72, 85, 84, 32, 89, 4, 238, 215, 26, 82, 237, 220, 6, 8, 78, - 68, 65, 32, 80, 65, 32, 78, 4, 204, 11, 4, 69, 78, 83, 72, 211, 200, 37, - 77, 6, 220, 150, 36, 2, 78, 74, 146, 189, 1, 81, 3, 84, 10, 44, 2, 69, - 85, 44, 3, 73, 84, 65, 31, 85, 4, 134, 253, 35, 65, 1, 4, 84, 69, 85, 87, - 2, 11, 32, 2, 195, 31, 77, 4, 234, 26, 32, 247, 149, 27, 65, 4, 228, 3, - 5, 32, 89, 85, 81, 32, 245, 134, 28, 3, 78, 75, 78, 116, 164, 1, 7, 71, + 71, 155, 178, 37, 66, 22, 70, 72, 194, 1, 79, 144, 67, 2, 69, 85, 174, + 219, 36, 85, 167, 34, 73, 10, 74, 73, 70, 85, 177, 152, 36, 10, 79, 81, + 32, 78, 83, 72, 85, 84, 32, 89, 4, 162, 199, 26, 82, 237, 220, 6, 8, 78, + 68, 65, 32, 80, 65, 32, 78, 4, 204, 11, 4, 69, 78, 83, 72, 135, 184, 37, + 77, 6, 144, 134, 36, 2, 78, 74, 146, 189, 1, 81, 3, 84, 10, 44, 2, 69, + 85, 44, 3, 73, 84, 65, 31, 85, 4, 186, 236, 35, 65, 1, 4, 84, 69, 85, 87, + 2, 11, 32, 2, 195, 31, 77, 4, 234, 26, 32, 171, 133, 27, 65, 4, 228, 3, + 5, 32, 89, 85, 81, 32, 169, 246, 27, 3, 78, 75, 78, 116, 164, 1, 7, 71, 72, 69, 85, 71, 72, 69, 34, 75, 126, 76, 122, 77, 154, 3, 78, 250, 2, 80, - 118, 83, 178, 1, 84, 106, 89, 210, 22, 87, 220, 46, 2, 70, 69, 215, 219, - 11, 86, 4, 134, 57, 85, 183, 151, 37, 78, 12, 40, 2, 69, 85, 50, 73, 235, - 190, 37, 65, 6, 166, 55, 89, 174, 203, 12, 80, 243, 186, 24, 65, 4, 146, - 189, 37, 69, 175, 18, 81, 8, 46, 65, 192, 70, 2, 79, 77, 135, 236, 36, - 69, 4, 50, 65, 209, 61, 7, 77, 32, 78, 83, 72, 85, 84, 2, 199, 209, 26, + 118, 83, 178, 1, 84, 106, 89, 210, 22, 87, 220, 46, 2, 70, 69, 163, 211, + 11, 86, 4, 134, 57, 85, 235, 134, 37, 78, 12, 40, 2, 69, 85, 50, 73, 159, + 174, 37, 65, 6, 166, 55, 89, 250, 194, 12, 80, 219, 178, 24, 65, 4, 198, + 172, 37, 69, 175, 18, 81, 8, 46, 65, 192, 70, 2, 79, 77, 187, 219, 36, + 69, 4, 50, 65, 209, 61, 7, 77, 32, 78, 83, 72, 85, 84, 2, 251, 192, 26, 78, 26, 70, 65, 74, 66, 140, 1, 2, 69, 85, 58, 70, 193, 23, 3, 79, 78, - 84, 7, 21, 3, 32, 78, 74, 4, 210, 238, 18, 85, 209, 160, 17, 3, 69, 85, - 65, 10, 90, 65, 218, 46, 85, 152, 178, 30, 2, 69, 85, 133, 153, 6, 7, 73, - 84, 32, 77, 66, 65, 65, 4, 198, 12, 65, 213, 218, 19, 4, 32, 77, 65, 69, - 4, 208, 179, 32, 5, 84, 32, 78, 71, 71, 187, 152, 5, 81, 4, 48, 4, 79, - 78, 32, 84, 253, 231, 26, 2, 73, 89, 2, 243, 65, 69, 26, 110, 71, 182, 1, - 83, 50, 89, 200, 23, 8, 84, 73, 69, 69, 32, 83, 72, 69, 193, 187, 35, 5, - 68, 85, 32, 78, 74, 14, 70, 71, 196, 208, 36, 8, 75, 73, 78, 68, 73, 32, - 77, 86, 191, 104, 79, 10, 76, 3, 85, 79, 81, 244, 237, 19, 2, 69, 85, - 134, 158, 16, 65, 187, 172, 1, 79, 5, 205, 212, 28, 2, 32, 76, 4, 26, 72, - 243, 248, 36, 69, 2, 183, 147, 37, 85, 4, 168, 46, 2, 65, 69, 227, 17, - 73, 10, 76, 3, 85, 78, 71, 252, 213, 10, 2, 69, 69, 178, 177, 12, 65, - 243, 163, 14, 73, 4, 194, 194, 31, 71, 247, 199, 4, 65, 12, 88, 2, 65, - 75, 16, 2, 72, 69, 156, 212, 19, 2, 69, 84, 254, 255, 15, 73, 207, 219, - 1, 85, 2, 231, 25, 69, 4, 144, 227, 26, 4, 84, 32, 78, 74, 221, 138, 5, - 4, 85, 65, 69, 81, 6, 32, 2, 85, 32, 195, 136, 36, 65, 4, 36, 4, 77, 65, + 84, 7, 21, 3, 32, 78, 74, 4, 210, 226, 18, 85, 133, 156, 17, 3, 69, 85, + 65, 10, 90, 65, 218, 46, 85, 204, 161, 30, 2, 69, 85, 133, 153, 6, 7, 73, + 84, 32, 77, 66, 65, 65, 4, 198, 12, 65, 213, 206, 19, 4, 32, 77, 65, 69, + 4, 132, 163, 32, 5, 84, 32, 78, 71, 71, 187, 152, 5, 81, 4, 48, 4, 79, + 78, 32, 84, 177, 215, 26, 2, 73, 89, 2, 243, 65, 69, 26, 110, 71, 182, 1, + 83, 50, 89, 200, 23, 8, 84, 73, 69, 69, 32, 83, 72, 69, 245, 170, 35, 5, + 68, 85, 32, 78, 74, 14, 70, 71, 248, 191, 36, 8, 75, 73, 78, 68, 73, 32, + 77, 86, 191, 104, 79, 10, 76, 3, 85, 79, 81, 244, 225, 19, 2, 69, 85, + 186, 153, 16, 65, 187, 172, 1, 79, 5, 129, 196, 28, 2, 32, 76, 4, 26, 72, + 167, 232, 36, 69, 2, 235, 130, 37, 85, 4, 168, 46, 2, 65, 69, 227, 17, + 73, 10, 76, 3, 85, 78, 71, 200, 205, 10, 2, 69, 69, 154, 169, 12, 65, + 243, 163, 14, 73, 4, 246, 177, 31, 71, 247, 199, 4, 65, 12, 88, 2, 65, + 75, 16, 2, 72, 69, 156, 200, 19, 2, 69, 84, 178, 251, 15, 73, 207, 219, + 1, 85, 2, 231, 25, 69, 4, 196, 210, 26, 4, 84, 32, 78, 74, 221, 138, 5, + 4, 85, 65, 69, 81, 6, 32, 2, 85, 32, 247, 247, 35, 65, 4, 36, 4, 77, 65, 69, 77, 143, 7, 78, 2, 11, 71, 2, 139, 7, 66, 4, 44, 4, 65, 70, 85, 32, - 233, 4, 2, 69, 85, 2, 253, 202, 32, 6, 76, 69, 69, 82, 65, 69, 198, 1, + 233, 4, 2, 69, 85, 2, 177, 186, 32, 6, 76, 69, 69, 82, 65, 69, 198, 1, 174, 1, 71, 82, 75, 206, 2, 76, 50, 77, 250, 3, 78, 238, 6, 80, 78, 83, - 134, 1, 84, 176, 1, 3, 86, 69, 85, 46, 87, 62, 89, 170, 189, 30, 66, 226, - 227, 2, 70, 247, 234, 3, 82, 6, 40, 2, 72, 65, 213, 210, 19, 2, 66, 65, - 4, 218, 197, 26, 82, 247, 252, 10, 80, 22, 66, 69, 182, 1, 85, 144, 221, - 26, 3, 80, 65, 82, 239, 224, 10, 65, 14, 40, 2, 78, 32, 54, 85, 139, 193, - 37, 84, 4, 208, 177, 33, 4, 70, 65, 84, 73, 191, 145, 3, 76, 8, 42, 83, - 186, 221, 26, 75, 167, 227, 10, 77, 4, 248, 14, 3, 72, 69, 85, 255, 53, - 69, 4, 48, 6, 79, 80, 32, 78, 75, 65, 131, 192, 37, 84, 2, 11, 65, 2, - 255, 194, 26, 82, 8, 234, 47, 65, 222, 172, 26, 73, 155, 227, 10, 85, 38, - 82, 65, 130, 1, 66, 234, 192, 26, 85, 208, 25, 4, 71, 66, 65, 83, 135, - 241, 8, 73, 8, 18, 32, 79, 69, 4, 42, 78, 141, 252, 17, 4, 75, 69, 85, - 65, 2, 11, 83, 2, 239, 203, 35, 73, 4, 210, 144, 37, 77, 211, 25, 83, 24, - 34, 65, 114, 69, 82, 73, 35, 85, 6, 32, 2, 65, 32, 155, 205, 19, 78, 4, - 192, 243, 31, 8, 67, 65, 66, 66, 65, 71, 69, 45, 253, 246, 4, 2, 80, 73, - 8, 50, 85, 162, 191, 26, 82, 189, 228, 5, 2, 69, 75, 4, 146, 188, 37, 77, - 3, 88, 7, 226, 7, 82, 151, 180, 37, 84, 4, 170, 169, 37, 65, 175, 18, 69, + 134, 1, 84, 176, 1, 3, 86, 69, 85, 46, 87, 62, 89, 222, 172, 30, 66, 226, + 227, 2, 70, 247, 234, 3, 82, 6, 40, 2, 72, 65, 213, 198, 19, 2, 66, 65, + 4, 142, 181, 26, 82, 247, 252, 10, 80, 22, 66, 69, 182, 1, 85, 196, 204, + 26, 3, 80, 65, 82, 239, 224, 10, 65, 14, 40, 2, 78, 32, 54, 85, 191, 176, + 37, 84, 4, 132, 161, 33, 4, 70, 65, 84, 73, 191, 145, 3, 76, 8, 42, 83, + 238, 204, 26, 75, 167, 227, 10, 77, 4, 248, 14, 3, 72, 69, 85, 255, 53, + 69, 4, 48, 6, 79, 80, 32, 78, 75, 65, 183, 175, 37, 84, 2, 11, 65, 2, + 179, 178, 26, 82, 8, 234, 47, 65, 146, 156, 26, 73, 155, 227, 10, 85, 38, + 82, 65, 130, 1, 66, 158, 176, 26, 85, 208, 25, 4, 71, 66, 65, 83, 135, + 241, 8, 73, 8, 18, 32, 79, 69, 4, 42, 78, 141, 240, 17, 4, 75, 69, 85, + 65, 2, 11, 83, 2, 163, 187, 35, 73, 4, 134, 128, 37, 77, 211, 25, 83, 24, + 34, 65, 114, 69, 82, 73, 35, 85, 6, 32, 2, 65, 32, 155, 193, 19, 78, 4, + 244, 226, 31, 8, 67, 65, 66, 66, 65, 71, 69, 45, 253, 246, 4, 2, 80, 73, + 8, 50, 85, 214, 174, 26, 82, 189, 228, 5, 2, 69, 75, 4, 198, 171, 37, 77, + 3, 88, 7, 226, 7, 82, 203, 163, 37, 84, 4, 222, 152, 37, 65, 175, 18, 69, 72, 130, 1, 65, 54, 68, 110, 71, 222, 1, 74, 102, 83, 130, 1, 84, 102, - 90, 253, 7, 12, 89, 73, 82, 32, 77, 75, 80, 65, 82, 65, 81, 32, 4, 140, - 215, 26, 4, 78, 83, 65, 78, 167, 227, 10, 81, 12, 60, 2, 69, 85, 206, 41, - 65, 238, 180, 19, 79, 135, 182, 17, 73, 4, 144, 199, 35, 2, 65, 69, 175, - 242, 1, 84, 20, 50, 71, 98, 75, 234, 212, 26, 65, 195, 210, 10, 79, 12, - 26, 85, 231, 232, 36, 69, 11, 212, 39, 3, 65, 69, 78, 142, 193, 36, 79, - 202, 26, 69, 155, 53, 77, 4, 36, 3, 85, 69, 32, 195, 212, 26, 65, 2, 249, - 205, 19, 3, 77, 65, 69, 10, 34, 65, 34, 69, 199, 233, 12, 85, 4, 186, - 166, 37, 69, 219, 16, 77, 4, 210, 196, 35, 69, 227, 99, 85, 12, 78, 85, - 226, 210, 26, 72, 220, 243, 5, 2, 69, 85, 242, 222, 4, 79, 219, 16, 65, - 4, 208, 162, 37, 4, 79, 84, 32, 78, 179, 19, 78, 8, 54, 69, 228, 152, 37, - 4, 85, 32, 77, 66, 131, 26, 65, 4, 176, 201, 19, 2, 85, 78, 235, 235, 17, - 78, 4, 202, 137, 36, 69, 167, 171, 1, 65, 6, 26, 73, 211, 228, 36, 69, 4, - 26, 82, 151, 180, 37, 78, 2, 131, 222, 35, 73, 12, 30, 69, 30, 72, 163, - 7, 85, 4, 78, 84, 211, 164, 36, 85, 6, 48, 2, 69, 84, 226, 229, 12, 85, - 155, 234, 13, 73, 2, 163, 227, 36, 70, 10, 40, 2, 65, 65, 34, 69, 41, 2, - 73, 84, 2, 11, 83, 2, 207, 181, 26, 72, 4, 228, 25, 2, 85, 84, 203, 152, - 37, 84, 4, 38, 85, 133, 162, 33, 3, 65, 32, 89, 2, 251, 143, 27, 65, 4, - 200, 149, 28, 2, 65, 69, 131, 156, 9, 88, 4, 40, 4, 65, 78, 71, 75, 235, - 176, 37, 85, 2, 143, 19, 85, 10, 42, 85, 158, 227, 12, 69, 231, 202, 24, - 65, 6, 210, 18, 87, 212, 3, 4, 32, 77, 85, 79, 147, 154, 37, 77, 234, 1, + 90, 253, 7, 12, 89, 73, 82, 32, 77, 75, 80, 65, 82, 65, 81, 32, 4, 192, + 198, 26, 4, 78, 83, 65, 78, 167, 227, 10, 81, 12, 60, 2, 69, 85, 206, 41, + 65, 238, 168, 19, 79, 187, 177, 17, 73, 4, 196, 182, 35, 2, 65, 69, 175, + 242, 1, 84, 20, 50, 71, 98, 75, 158, 196, 26, 65, 195, 210, 10, 79, 12, + 26, 85, 155, 216, 36, 69, 11, 212, 39, 3, 65, 69, 78, 194, 176, 36, 79, + 202, 26, 69, 155, 53, 77, 4, 36, 3, 85, 69, 32, 247, 195, 26, 65, 2, 249, + 193, 19, 3, 77, 65, 69, 10, 34, 65, 34, 69, 147, 225, 12, 85, 4, 238, + 149, 37, 69, 219, 16, 77, 4, 134, 180, 35, 69, 227, 99, 85, 12, 78, 85, + 150, 194, 26, 72, 220, 243, 5, 2, 69, 85, 242, 222, 4, 79, 219, 16, 65, + 4, 132, 146, 37, 4, 79, 84, 32, 78, 179, 19, 78, 8, 54, 69, 152, 136, 37, + 4, 85, 32, 77, 66, 131, 26, 65, 4, 176, 189, 19, 2, 85, 78, 159, 231, 17, + 78, 4, 254, 248, 35, 69, 167, 171, 1, 65, 6, 26, 73, 135, 212, 36, 69, 4, + 26, 82, 203, 163, 37, 78, 2, 183, 205, 35, 73, 12, 30, 69, 30, 72, 163, + 7, 85, 4, 78, 84, 135, 148, 36, 85, 6, 48, 2, 69, 84, 174, 221, 12, 85, + 131, 226, 13, 73, 2, 215, 210, 36, 70, 10, 40, 2, 65, 65, 34, 69, 41, 2, + 73, 84, 2, 11, 83, 2, 131, 165, 26, 72, 4, 228, 25, 2, 85, 84, 255, 135, + 37, 84, 4, 38, 85, 185, 145, 33, 3, 65, 32, 89, 2, 175, 255, 26, 65, 4, + 252, 132, 28, 2, 65, 69, 131, 156, 9, 88, 4, 40, 4, 65, 78, 71, 75, 159, + 160, 37, 85, 2, 143, 19, 85, 10, 42, 85, 234, 218, 12, 69, 207, 194, 24, + 65, 6, 210, 18, 87, 212, 3, 4, 32, 77, 85, 79, 199, 137, 37, 77, 234, 1, 134, 1, 70, 68, 2, 71, 72, 34, 75, 254, 1, 76, 142, 1, 77, 130, 3, 78, 130, 5, 80, 122, 82, 90, 83, 190, 1, 84, 158, 1, 87, 39, 89, 4, 36, 3, - 69, 85, 70, 147, 172, 37, 65, 2, 11, 69, 2, 151, 2, 85, 4, 202, 1, 69, - 171, 170, 37, 65, 22, 46, 69, 146, 1, 85, 42, 87, 135, 186, 35, 89, 10, - 26, 85, 195, 173, 37, 84, 8, 72, 3, 65, 69, 84, 20, 5, 79, 84, 32, 77, - 66, 226, 172, 37, 77, 3, 80, 2, 207, 140, 12, 77, 2, 235, 175, 26, 85, 9, - 242, 155, 37, 79, 218, 16, 78, 3, 81, 2, 139, 247, 36, 65, 14, 58, 69, - 190, 200, 26, 79, 250, 240, 8, 73, 203, 225, 1, 85, 8, 42, 85, 138, 185, - 35, 69, 163, 242, 1, 84, 4, 194, 137, 27, 65, 231, 161, 10, 77, 41, 94, - 65, 58, 66, 66, 69, 38, 70, 80, 2, 71, 66, 226, 163, 32, 79, 198, 139, 4, - 86, 151, 121, 85, 4, 144, 232, 17, 2, 76, 69, 249, 140, 19, 3, 69, 78, - 74, 6, 32, 2, 65, 65, 215, 138, 37, 85, 5, 133, 135, 29, 2, 32, 83, 6, - 202, 202, 18, 85, 195, 236, 16, 69, 10, 44, 2, 69, 85, 238, 170, 35, 79, - 207, 11, 73, 4, 130, 146, 37, 65, 215, 22, 84, 6, 150, 182, 35, 73, 252, + 69, 85, 70, 199, 155, 37, 65, 2, 11, 69, 2, 151, 2, 85, 4, 202, 1, 69, + 223, 153, 37, 65, 22, 46, 69, 146, 1, 85, 42, 87, 187, 169, 35, 89, 10, + 26, 85, 247, 156, 37, 84, 8, 72, 3, 65, 69, 84, 20, 5, 79, 84, 32, 77, + 66, 150, 156, 37, 77, 3, 80, 2, 155, 132, 12, 77, 2, 159, 159, 26, 85, 9, + 166, 139, 37, 79, 218, 16, 78, 3, 81, 2, 191, 230, 36, 65, 14, 58, 69, + 242, 183, 26, 79, 250, 240, 8, 73, 203, 225, 1, 85, 8, 42, 85, 190, 168, + 35, 69, 163, 242, 1, 84, 4, 246, 248, 26, 65, 231, 161, 10, 77, 41, 94, + 65, 58, 66, 66, 69, 38, 70, 80, 2, 71, 66, 150, 147, 32, 79, 198, 139, 4, + 86, 151, 121, 85, 4, 144, 220, 17, 2, 76, 69, 173, 136, 19, 3, 69, 78, + 74, 6, 32, 2, 65, 65, 139, 250, 36, 85, 5, 185, 246, 28, 2, 32, 83, 6, + 202, 190, 18, 85, 247, 231, 16, 69, 10, 44, 2, 69, 85, 162, 154, 35, 79, + 207, 11, 73, 4, 182, 129, 37, 65, 215, 22, 84, 6, 202, 165, 35, 73, 252, 70, 2, 79, 70, 247, 42, 69, 72, 78, 68, 46, 71, 226, 1, 74, 98, 83, 110, - 84, 34, 89, 190, 163, 37, 73, 3, 85, 8, 210, 39, 69, 130, 176, 36, 79, - 139, 63, 65, 24, 18, 71, 99, 75, 12, 54, 65, 218, 42, 69, 158, 140, 32, - 87, 231, 222, 4, 85, 6, 168, 38, 2, 65, 77, 147, 128, 37, 80, 12, 68, 2, - 69, 85, 174, 179, 35, 73, 2, 89, 194, 162, 1, 85, 215, 79, 65, 4, 154, - 216, 12, 65, 219, 185, 24, 82, 12, 60, 2, 69, 85, 230, 15, 73, 214, 199, - 12, 85, 167, 205, 24, 65, 4, 186, 146, 37, 65, 175, 18, 84, 10, 46, 72, - 32, 3, 73, 69, 69, 163, 147, 37, 85, 4, 234, 135, 37, 85, 219, 5, 69, 4, - 246, 163, 37, 80, 3, 84, 6, 130, 14, 69, 243, 240, 36, 85, 8, 142, 135, - 37, 69, 218, 5, 85, 254, 5, 65, 219, 16, 73, 12, 42, 69, 46, 85, 162, - 162, 37, 65, 3, 73, 4, 224, 165, 26, 2, 85, 84, 247, 252, 10, 69, 4, 254, - 133, 37, 85, 175, 28, 81, 8, 48, 3, 69, 78, 32, 130, 142, 37, 73, 175, 1, - 65, 4, 138, 242, 26, 79, 155, 141, 10, 77, 26, 58, 72, 90, 85, 202, 16, - 65, 174, 6, 69, 131, 237, 36, 79, 12, 54, 69, 170, 189, 26, 79, 194, 207, - 10, 73, 219, 19, 85, 6, 214, 7, 85, 235, 152, 37, 69, 6, 202, 137, 37, - 65, 214, 22, 69, 3, 85, 18, 62, 69, 74, 85, 218, 187, 26, 79, 198, 204, - 10, 65, 215, 22, 73, 8, 26, 85, 255, 172, 35, 69, 6, 150, 201, 35, 65, - 134, 214, 1, 78, 3, 84, 5, 195, 130, 37, 79, 4, 146, 175, 32, 85, 191, - 239, 4, 65, 10, 40, 2, 65, 69, 18, 85, 159, 206, 36, 69, 2, 251, 3, 77, - 6, 22, 87, 243, 13, 79, 2, 203, 186, 26, 79, 188, 2, 178, 1, 70, 154, 1, + 84, 34, 89, 242, 146, 37, 73, 3, 85, 8, 210, 39, 69, 182, 159, 36, 79, + 139, 63, 65, 24, 18, 71, 99, 75, 12, 54, 65, 218, 42, 69, 210, 251, 31, + 87, 231, 222, 4, 85, 6, 168, 38, 2, 65, 77, 199, 239, 36, 80, 12, 68, 2, + 69, 85, 226, 162, 35, 73, 2, 89, 194, 162, 1, 85, 215, 79, 65, 4, 230, + 207, 12, 65, 195, 177, 24, 82, 12, 60, 2, 69, 85, 230, 15, 73, 162, 191, + 12, 85, 143, 197, 24, 65, 4, 238, 129, 37, 65, 175, 18, 84, 10, 46, 72, + 32, 3, 73, 69, 69, 215, 130, 37, 85, 4, 158, 247, 36, 85, 219, 5, 69, 4, + 170, 147, 37, 80, 3, 84, 6, 130, 14, 69, 167, 224, 36, 85, 8, 194, 246, + 36, 69, 218, 5, 85, 254, 5, 65, 219, 16, 73, 12, 42, 69, 46, 85, 214, + 145, 37, 65, 3, 73, 4, 148, 149, 26, 2, 85, 84, 247, 252, 10, 69, 4, 178, + 245, 36, 85, 175, 28, 81, 8, 48, 3, 69, 78, 32, 182, 253, 36, 73, 175, 1, + 65, 4, 190, 225, 26, 79, 155, 141, 10, 77, 26, 58, 72, 90, 85, 202, 16, + 65, 174, 6, 69, 183, 220, 36, 79, 12, 54, 69, 222, 172, 26, 79, 194, 207, + 10, 73, 219, 19, 85, 6, 214, 7, 85, 159, 136, 37, 69, 6, 254, 248, 36, + 65, 214, 22, 69, 3, 85, 18, 62, 69, 74, 85, 142, 171, 26, 79, 198, 204, + 10, 65, 215, 22, 73, 8, 26, 85, 179, 156, 35, 69, 6, 202, 184, 35, 65, + 134, 214, 1, 78, 3, 84, 5, 247, 241, 36, 79, 4, 198, 158, 32, 85, 191, + 239, 4, 65, 10, 40, 2, 65, 69, 18, 85, 211, 189, 36, 69, 2, 251, 3, 77, + 6, 22, 87, 243, 13, 79, 2, 255, 169, 26, 79, 188, 2, 178, 1, 70, 154, 1, 71, 202, 1, 75, 170, 1, 76, 158, 1, 77, 134, 2, 78, 206, 7, 80, 166, 2, - 82, 78, 83, 166, 1, 84, 246, 1, 86, 66, 87, 34, 89, 190, 134, 37, 65, 2, - 73, 3, 79, 18, 54, 85, 158, 156, 23, 65, 242, 232, 13, 69, 255, 5, 79, - 10, 26, 32, 239, 178, 31, 69, 6, 156, 255, 23, 4, 82, 69, 77, 69, 242, - 145, 11, 67, 183, 138, 2, 73, 16, 24, 2, 66, 69, 39, 72, 4, 162, 140, 36, - 85, 195, 142, 1, 84, 12, 34, 65, 34, 69, 167, 137, 37, 79, 2, 11, 65, 2, - 155, 157, 26, 77, 8, 26, 85, 227, 153, 37, 84, 6, 138, 131, 37, 65, 214, - 22, 78, 3, 88, 18, 50, 69, 62, 80, 18, 85, 186, 152, 37, 73, 3, 79, 6, - 26, 85, 235, 152, 37, 84, 4, 146, 130, 37, 65, 215, 22, 88, 2, 227, 28, - 69, 6, 138, 252, 36, 69, 162, 28, 79, 15, 84, 18, 50, 65, 40, 2, 69, 85, - 22, 79, 163, 151, 37, 85, 6, 130, 135, 37, 65, 218, 16, 80, 3, 81, 2, - 135, 133, 37, 65, 8, 190, 184, 18, 79, 226, 222, 18, 77, 3, 81, 32, 110, - 65, 44, 2, 66, 69, 34, 70, 20, 2, 71, 66, 34, 73, 146, 152, 26, 85, 150, - 173, 10, 69, 2, 79, 139, 60, 86, 11, 218, 140, 18, 69, 170, 137, 19, 80, - 3, 81, 4, 254, 132, 37, 85, 219, 16, 69, 2, 155, 200, 12, 69, 4, 194, - 197, 36, 69, 227, 79, 65, 5, 175, 254, 36, 69, 82, 114, 68, 170, 1, 71, - 154, 3, 74, 112, 2, 83, 72, 58, 84, 32, 3, 89, 73, 32, 54, 90, 162, 205, - 36, 65, 191, 47, 75, 12, 34, 65, 98, 73, 155, 195, 36, 85, 6, 32, 2, 65, - 32, 183, 147, 37, 80, 4, 208, 190, 18, 3, 77, 89, 32, 189, 188, 13, 3, - 83, 79, 70, 4, 222, 175, 26, 65, 155, 227, 10, 81, 38, 78, 71, 66, 85, - 122, 75, 118, 79, 128, 240, 11, 3, 69, 85, 82, 219, 159, 25, 65, 14, 34, - 69, 50, 85, 167, 145, 37, 79, 6, 26, 85, 167, 159, 35, 69, 4, 167, 171, - 24, 65, 6, 64, 6, 65, 69, 83, 72, 65, 69, 250, 147, 26, 82, 247, 252, 10, - 80, 2, 11, 32, 2, 191, 215, 23, 78, 12, 34, 65, 20, 2, 69, 85, 35, 85, 5, - 195, 252, 36, 65, 4, 230, 253, 36, 65, 175, 18, 88, 4, 242, 143, 37, 77, - 3, 80, 4, 214, 143, 37, 80, 3, 81, 8, 18, 65, 31, 69, 2, 197, 139, 32, 2, - 69, 77, 6, 26, 69, 179, 128, 36, 85, 5, 197, 236, 36, 4, 32, 69, 80, 79, - 6, 26, 85, 147, 156, 35, 73, 4, 162, 142, 37, 79, 15, 69, 4, 186, 253, - 36, 85, 207, 16, 65, 4, 180, 186, 26, 4, 67, 76, 69, 65, 167, 248, 1, 66, - 4, 166, 170, 26, 65, 3, 85, 34, 42, 65, 90, 69, 58, 73, 50, 79, 23, 85, - 8, 32, 2, 32, 80, 175, 131, 18, 65, 4, 252, 179, 28, 2, 69, 79, 237, 204, - 7, 2, 76, 85, 6, 26, 85, 175, 251, 36, 69, 4, 130, 140, 37, 84, 3, 88, 7, - 11, 69, 4, 194, 168, 26, 69, 155, 227, 10, 84, 5, 215, 187, 36, 79, 11, - 82, 65, 210, 138, 37, 69, 3, 77, 8, 46, 65, 238, 14, 69, 253, 143, 19, 2, - 73, 77, 4, 206, 138, 37, 69, 3, 81, 18, 62, 69, 30, 72, 146, 154, 32, 85, - 242, 222, 4, 79, 163, 14, 65, 4, 242, 137, 37, 69, 3, 84, 8, 42, 69, 234, - 137, 23, 79, 175, 156, 3, 73, 2, 249, 187, 12, 2, 85, 65, 28, 34, 65, 94, - 69, 50, 79, 39, 85, 10, 56, 2, 69, 78, 238, 136, 23, 65, 198, 255, 13, - 77, 3, 81, 2, 161, 228, 11, 3, 32, 78, 84, 6, 26, 85, 247, 135, 37, 78, - 5, 195, 186, 12, 65, 6, 242, 137, 35, 79, 239, 253, 1, 81, 6, 170, 7, 77, - 191, 233, 36, 65, 6, 26, 69, 171, 246, 36, 79, 4, 138, 138, 26, 85, 247, - 252, 10, 69, 6, 246, 10, 69, 255, 223, 32, 85, 26, 68, 2, 69, 85, 46, 73, - 32, 3, 79, 81, 32, 54, 85, 235, 132, 37, 65, 8, 214, 159, 24, 65, 158, - 230, 12, 77, 3, 88, 4, 242, 238, 36, 69, 215, 22, 84, 4, 168, 214, 12, 4, - 83, 87, 73, 77, 143, 205, 9, 67, 8, 218, 161, 26, 69, 150, 141, 9, 65, + 82, 78, 83, 166, 1, 84, 246, 1, 86, 66, 87, 34, 89, 242, 245, 36, 65, 2, + 73, 3, 79, 18, 54, 85, 210, 139, 23, 65, 242, 232, 13, 69, 255, 5, 79, + 10, 26, 32, 163, 162, 31, 69, 6, 208, 238, 23, 4, 82, 69, 77, 69, 242, + 145, 11, 67, 183, 138, 2, 73, 16, 24, 2, 66, 69, 39, 72, 4, 214, 251, 35, + 85, 195, 142, 1, 84, 12, 34, 65, 34, 69, 219, 248, 36, 79, 2, 11, 65, 2, + 207, 140, 26, 77, 8, 26, 85, 151, 137, 37, 84, 6, 190, 242, 36, 65, 214, + 22, 78, 3, 88, 18, 50, 69, 62, 80, 18, 85, 238, 135, 37, 73, 3, 79, 6, + 26, 85, 159, 136, 37, 84, 4, 198, 241, 36, 65, 215, 22, 88, 2, 227, 28, + 69, 6, 190, 235, 36, 69, 162, 28, 79, 15, 84, 18, 50, 65, 40, 2, 69, 85, + 22, 79, 215, 134, 37, 85, 6, 182, 246, 36, 65, 218, 16, 80, 3, 81, 2, + 187, 244, 36, 65, 8, 190, 172, 18, 79, 150, 218, 18, 77, 3, 81, 32, 110, + 65, 44, 2, 66, 69, 34, 70, 20, 2, 71, 66, 34, 73, 198, 135, 26, 85, 150, + 173, 10, 69, 2, 79, 139, 60, 86, 11, 218, 128, 18, 69, 222, 132, 19, 80, + 3, 81, 4, 178, 244, 36, 85, 219, 16, 69, 2, 231, 191, 12, 69, 4, 246, + 180, 36, 69, 227, 79, 65, 5, 227, 237, 36, 69, 82, 114, 68, 170, 1, 71, + 154, 3, 74, 112, 2, 83, 72, 58, 84, 32, 3, 89, 73, 32, 54, 90, 214, 188, + 36, 65, 191, 47, 75, 12, 34, 65, 98, 73, 207, 178, 36, 85, 6, 32, 2, 65, + 32, 235, 130, 37, 80, 4, 208, 178, 18, 3, 77, 89, 32, 241, 183, 13, 3, + 83, 79, 70, 4, 146, 159, 26, 65, 155, 227, 10, 81, 38, 78, 71, 66, 85, + 122, 75, 118, 79, 204, 231, 11, 3, 69, 85, 82, 195, 151, 25, 65, 14, 34, + 69, 50, 85, 219, 128, 37, 79, 6, 26, 85, 219, 142, 35, 69, 4, 219, 154, + 24, 65, 6, 64, 6, 65, 69, 83, 72, 65, 69, 174, 131, 26, 82, 247, 252, 10, + 80, 2, 11, 32, 2, 243, 198, 23, 78, 12, 34, 65, 20, 2, 69, 85, 35, 85, 5, + 247, 235, 36, 65, 4, 154, 237, 36, 65, 175, 18, 88, 4, 166, 255, 36, 77, + 3, 80, 4, 138, 255, 36, 80, 3, 81, 8, 18, 65, 31, 69, 2, 249, 250, 31, 2, + 69, 77, 6, 26, 69, 231, 239, 35, 85, 5, 249, 219, 36, 4, 32, 69, 80, 79, + 6, 26, 85, 199, 139, 35, 73, 4, 214, 253, 36, 79, 15, 69, 4, 238, 236, + 36, 85, 207, 16, 65, 4, 232, 169, 26, 4, 67, 76, 69, 65, 167, 248, 1, 66, + 4, 218, 153, 26, 65, 3, 85, 34, 42, 65, 90, 69, 58, 73, 50, 79, 23, 85, + 8, 32, 2, 32, 80, 175, 247, 17, 65, 4, 176, 163, 28, 2, 69, 79, 237, 204, + 7, 2, 76, 85, 6, 26, 85, 227, 234, 36, 69, 4, 182, 251, 36, 84, 3, 88, 7, + 11, 69, 4, 246, 151, 26, 69, 155, 227, 10, 84, 5, 139, 171, 36, 79, 11, + 82, 65, 134, 250, 36, 69, 3, 77, 8, 46, 65, 238, 14, 69, 253, 131, 19, 2, + 73, 77, 4, 130, 250, 36, 69, 3, 81, 18, 62, 69, 30, 72, 198, 137, 32, 85, + 242, 222, 4, 79, 163, 14, 65, 4, 166, 249, 36, 69, 3, 84, 8, 42, 69, 158, + 249, 22, 79, 175, 156, 3, 73, 2, 197, 179, 12, 2, 85, 65, 28, 34, 65, 94, + 69, 50, 79, 39, 85, 10, 56, 2, 69, 78, 162, 248, 22, 65, 198, 255, 13, + 77, 3, 81, 2, 237, 219, 11, 3, 32, 78, 84, 6, 26, 85, 171, 247, 36, 78, + 5, 143, 178, 12, 65, 6, 166, 249, 34, 79, 239, 253, 1, 81, 6, 170, 7, 77, + 243, 216, 36, 65, 6, 26, 69, 223, 229, 36, 79, 4, 190, 249, 25, 85, 247, + 252, 10, 69, 6, 246, 10, 69, 179, 207, 32, 85, 26, 68, 2, 69, 85, 46, 73, + 32, 3, 79, 81, 32, 54, 85, 159, 244, 36, 65, 8, 138, 143, 24, 65, 158, + 230, 12, 77, 3, 88, 4, 166, 222, 36, 69, 215, 22, 84, 4, 244, 205, 12, 4, + 83, 87, 73, 77, 191, 201, 9, 67, 8, 142, 145, 26, 69, 150, 141, 9, 65, 134, 214, 1, 78, 3, 81, 108, 162, 1, 75, 82, 76, 46, 77, 98, 78, 190, 1, - 80, 66, 82, 50, 83, 110, 84, 38, 89, 130, 228, 2, 87, 204, 204, 9, 2, 86, - 85, 222, 182, 24, 69, 242, 5, 70, 231, 16, 85, 14, 178, 164, 18, 69, 194, - 236, 16, 89, 234, 239, 1, 80, 186, 2, 65, 2, 79, 3, 85, 6, 170, 159, 26, - 79, 154, 227, 10, 65, 3, 73, 13, 42, 66, 34, 69, 206, 129, 37, 65, 3, 79, - 4, 138, 178, 36, 69, 171, 77, 65, 2, 171, 143, 35, 69, 22, 94, 71, 38, - 74, 38, 85, 234, 130, 35, 83, 246, 7, 68, 150, 3, 84, 202, 222, 1, 89, - 219, 19, 73, 4, 130, 145, 32, 75, 159, 237, 4, 71, 4, 190, 131, 26, 85, - 203, 234, 10, 65, 5, 187, 233, 36, 65, 6, 26, 69, 239, 130, 26, 85, 4, - 158, 241, 35, 85, 195, 142, 1, 69, 12, 186, 2, 69, 178, 146, 9, 73, 211, - 234, 27, 85, 14, 66, 72, 230, 2, 69, 138, 146, 19, 65, 246, 196, 17, 85, - 235, 36, 73, 6, 238, 234, 36, 73, 218, 19, 79, 3, 85, 6, 214, 167, 21, - 65, 159, 186, 15, 69, 4, 226, 154, 26, 79, 155, 227, 10, 65, 4, 130, 231, - 36, 65, 215, 22, 69, 14, 54, 69, 178, 146, 9, 73, 254, 211, 27, 65, 215, - 22, 85, 6, 190, 238, 35, 85, 194, 142, 1, 69, 3, 78, 16, 62, 72, 50, 69, - 138, 146, 19, 65, 246, 196, 17, 85, 235, 36, 73, 8, 46, 69, 142, 232, 36, - 73, 218, 19, 79, 3, 85, 2, 163, 237, 35, 85, 10, 238, 156, 18, 69, 154, - 136, 3, 65, 203, 214, 15, 73, 6, 130, 152, 26, 79, 2, 85, 155, 227, 10, - 65, 14, 42, 75, 174, 188, 35, 65, 167, 159, 1, 74, 11, 49, 10, 78, 79, - 84, 69, 32, 87, 73, 84, 72, 32, 8, 224, 220, 9, 2, 80, 79, 198, 1, 89, - 148, 190, 12, 2, 69, 85, 187, 182, 6, 68, 6, 38, 32, 149, 137, 17, 3, 66, - 69, 82, 4, 198, 233, 29, 67, 201, 252, 5, 5, 79, 70, 32, 83, 79, 78, 72, - 3, 75, 69, 84, 60, 7, 83, 65, 32, 86, 65, 72, 32, 155, 237, 34, 69, 5, - 193, 177, 16, 10, 66, 65, 76, 76, 32, 65, 78, 68, 32, 72, 72, 104, 10, + 80, 66, 82, 50, 83, 110, 84, 38, 89, 130, 228, 2, 87, 152, 196, 9, 2, 86, + 85, 198, 174, 24, 69, 242, 5, 70, 231, 16, 85, 14, 178, 152, 18, 69, 246, + 231, 16, 89, 234, 239, 1, 80, 186, 2, 65, 2, 79, 3, 85, 6, 222, 142, 26, + 79, 154, 227, 10, 65, 3, 73, 13, 42, 66, 34, 69, 130, 241, 36, 65, 3, 79, + 4, 190, 161, 36, 69, 171, 77, 65, 2, 223, 254, 34, 69, 22, 94, 71, 38, + 74, 38, 85, 158, 242, 34, 83, 246, 7, 68, 150, 3, 84, 202, 222, 1, 89, + 219, 19, 73, 4, 182, 128, 32, 75, 159, 237, 4, 71, 4, 242, 242, 25, 85, + 203, 234, 10, 65, 5, 239, 216, 36, 65, 6, 26, 69, 163, 242, 25, 85, 4, + 210, 224, 35, 85, 195, 142, 1, 69, 12, 186, 2, 69, 254, 137, 9, 73, 187, + 226, 27, 85, 14, 66, 72, 230, 2, 69, 138, 134, 19, 65, 170, 192, 17, 85, + 235, 36, 73, 6, 162, 218, 36, 73, 218, 19, 79, 3, 85, 6, 214, 155, 21, + 65, 211, 181, 15, 69, 4, 150, 138, 26, 79, 155, 227, 10, 65, 4, 182, 214, + 36, 65, 215, 22, 69, 14, 54, 69, 254, 137, 9, 73, 230, 203, 27, 65, 215, + 22, 85, 6, 242, 221, 35, 85, 194, 142, 1, 69, 3, 78, 16, 62, 72, 50, 69, + 138, 134, 19, 65, 170, 192, 17, 85, 235, 36, 73, 8, 46, 69, 194, 215, 36, + 73, 218, 19, 79, 3, 85, 2, 215, 220, 35, 85, 10, 238, 144, 18, 69, 154, + 136, 3, 65, 255, 209, 15, 73, 6, 182, 135, 26, 79, 2, 85, 155, 227, 10, + 65, 14, 42, 75, 226, 171, 35, 65, 167, 159, 1, 74, 11, 49, 10, 78, 79, + 84, 69, 32, 87, 73, 84, 72, 32, 8, 172, 212, 9, 2, 80, 79, 198, 1, 89, + 192, 186, 12, 2, 69, 85, 247, 177, 6, 68, 6, 38, 32, 149, 253, 16, 3, 66, + 69, 82, 4, 250, 216, 29, 67, 201, 252, 5, 5, 79, 70, 32, 83, 79, 78, 72, + 3, 75, 69, 84, 60, 7, 83, 65, 32, 86, 65, 72, 32, 207, 220, 34, 69, 5, + 193, 165, 16, 10, 66, 65, 76, 76, 32, 65, 78, 68, 32, 72, 72, 104, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 164, 1, 7, 76, 69, 84, 84, 69, - 82, 32, 151, 160, 34, 70, 10, 52, 4, 72, 73, 71, 72, 44, 3, 76, 79, 87, - 39, 77, 4, 136, 246, 21, 2, 45, 76, 255, 138, 11, 32, 4, 32, 2, 45, 77, - 187, 128, 33, 32, 2, 169, 128, 33, 2, 73, 68, 60, 238, 1, 68, 38, 69, 38, - 71, 34, 75, 38, 85, 20, 2, 87, 65, 22, 89, 164, 132, 30, 2, 72, 87, 154, + 82, 32, 203, 143, 34, 70, 10, 52, 4, 72, 73, 71, 72, 44, 3, 76, 79, 87, + 39, 77, 4, 136, 234, 21, 2, 45, 76, 179, 134, 11, 32, 4, 32, 2, 45, 77, + 239, 239, 32, 32, 2, 221, 239, 32, 2, 73, 68, 60, 238, 1, 68, 38, 69, 38, + 71, 34, 75, 38, 85, 20, 2, 87, 65, 22, 89, 216, 243, 29, 2, 72, 87, 154, 197, 1, 77, 186, 223, 2, 79, 202, 164, 2, 86, 246, 5, 74, 2, 84, 2, 90, - 162, 8, 67, 2, 83, 158, 20, 66, 2, 70, 2, 80, 186, 2, 65, 3, 73, 4, 138, - 173, 34, 72, 207, 198, 2, 79, 7, 218, 238, 31, 78, 219, 132, 5, 69, 4, - 166, 206, 36, 66, 219, 35, 65, 4, 238, 132, 30, 80, 131, 238, 6, 65, 5, - 227, 205, 36, 87, 5, 179, 205, 36, 68, 4, 206, 242, 35, 69, 131, 105, 73, - 121, 48, 3, 65, 75, 32, 230, 10, 72, 179, 200, 22, 84, 112, 196, 1, 15, + 162, 8, 67, 2, 83, 158, 20, 66, 2, 70, 2, 80, 186, 2, 65, 3, 73, 4, 190, + 156, 34, 72, 207, 198, 2, 79, 7, 142, 222, 31, 78, 219, 132, 5, 69, 4, + 218, 189, 36, 66, 219, 35, 65, 4, 162, 244, 29, 80, 131, 238, 6, 65, 5, + 151, 189, 36, 87, 5, 231, 188, 36, 68, 4, 130, 226, 35, 69, 131, 105, 73, + 121, 48, 3, 65, 75, 32, 230, 10, 72, 231, 183, 22, 84, 112, 196, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 28, 7, 76, 69, 84, 84, 69, 82, 32, 248, 4, 3, 80, 65, 78, 50, 83, 141, 2, 11, 86, - 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 4, 178, 239, 36, 78, 87, 72, 76, - 194, 1, 77, 114, 78, 68, 2, 80, 65, 38, 83, 192, 248, 18, 4, 75, 65, 82, - 79, 218, 241, 17, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 76, 2, 82, 2, - 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 10, 26, 65, 215, 235, 36, 66, 9, 45, - 9, 78, 68, 65, 73, 76, 73, 78, 71, 32, 6, 162, 235, 36, 72, 2, 78, 3, 83, - 10, 152, 2, 2, 79, 82, 230, 232, 36, 68, 2, 71, 2, 89, 187, 2, 65, 5, - 221, 142, 21, 4, 75, 80, 65, 75, 24, 80, 10, 73, 77, 65, 76, 85, 78, 71, - 85, 78, 32, 96, 2, 79, 85, 159, 235, 36, 65, 20, 194, 233, 36, 71, 2, 72, - 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 87, 2, 89, 187, 2, 65, 2, 233, 248, - 18, 5, 84, 72, 69, 82, 78, 4, 166, 2, 71, 249, 248, 18, 4, 79, 78, 71, - 79, 10, 96, 12, 89, 77, 66, 79, 76, 32, 66, 73, 78, 68, 85, 32, 189, 198, - 10, 6, 73, 71, 78, 32, 84, 79, 8, 78, 80, 220, 177, 11, 3, 74, 85, 68, - 145, 180, 25, 6, 78, 65, 32, 77, 69, 84, 4, 64, 3, 65, 78, 71, 249, 182, - 23, 7, 73, 78, 65, 82, 66, 79, 82, 2, 131, 255, 25, 79, 18, 122, 85, 136, - 175, 26, 6, 80, 65, 75, 80, 65, 75, 152, 254, 2, 5, 75, 65, 82, 79, 32, - 254, 249, 6, 69, 162, 64, 73, 3, 79, 5, 249, 218, 30, 15, 32, 70, 79, 82, - 32, 83, 73, 77, 65, 76, 85, 78, 71, 85, 78, 5, 235, 245, 23, 84, 228, 2, + 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 4, 230, 222, 36, 78, 87, 72, 76, + 194, 1, 77, 114, 78, 68, 2, 80, 65, 38, 83, 192, 236, 18, 4, 75, 65, 82, + 79, 142, 237, 17, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 76, 2, 82, 2, + 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 10, 26, 65, 139, 219, 36, 66, 9, 45, + 9, 78, 68, 65, 73, 76, 73, 78, 71, 32, 6, 214, 218, 36, 72, 2, 78, 3, 83, + 10, 152, 2, 2, 79, 82, 154, 216, 36, 68, 2, 71, 2, 89, 187, 2, 65, 5, + 221, 130, 21, 4, 75, 80, 65, 75, 24, 80, 10, 73, 77, 65, 76, 85, 78, 71, + 85, 78, 32, 96, 2, 79, 85, 211, 218, 36, 65, 20, 246, 216, 36, 71, 2, 72, + 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 87, 2, 89, 187, 2, 65, 2, 233, 236, + 18, 5, 84, 72, 69, 82, 78, 4, 166, 2, 71, 249, 236, 18, 4, 79, 78, 71, + 79, 10, 96, 12, 89, 77, 66, 79, 76, 32, 66, 73, 78, 68, 85, 32, 137, 190, + 10, 6, 73, 71, 78, 32, 84, 79, 8, 78, 80, 168, 169, 11, 3, 74, 85, 68, + 249, 171, 25, 6, 78, 65, 32, 77, 69, 84, 4, 64, 3, 65, 78, 71, 173, 166, + 23, 7, 73, 78, 65, 82, 66, 79, 82, 2, 183, 238, 25, 79, 18, 122, 85, 188, + 158, 26, 6, 80, 65, 75, 80, 65, 75, 152, 254, 2, 5, 75, 65, 82, 79, 32, + 254, 249, 6, 69, 162, 64, 73, 3, 79, 5, 173, 202, 30, 15, 32, 70, 79, 82, + 32, 83, 73, 77, 65, 76, 85, 78, 71, 85, 78, 5, 159, 229, 23, 84, 228, 2, 182, 1, 65, 230, 2, 69, 50, 76, 146, 1, 78, 188, 10, 9, 82, 73, 65, 32, - 69, 82, 70, 69, 32, 186, 5, 84, 228, 136, 33, 2, 67, 65, 176, 185, 2, 5, + 69, 82, 70, 69, 32, 186, 5, 84, 152, 248, 32, 2, 67, 65, 176, 185, 2, 5, 86, 69, 82, 65, 71, 243, 142, 1, 68, 20, 136, 1, 4, 77, 69, 68, 32, 170, - 1, 82, 140, 176, 3, 10, 67, 72, 32, 87, 73, 84, 72, 32, 85, 77, 194, 169, - 7, 84, 178, 203, 25, 86, 19, 78, 8, 86, 65, 0, 2, 68, 69, 52, 4, 69, 73, - 71, 72, 1, 7, 83, 73, 88, 84, 69, 69, 78, 2, 169, 190, 20, 8, 83, 67, 69, - 78, 68, 73, 78, 71, 2, 161, 190, 20, 2, 84, 72, 4, 168, 222, 32, 3, 68, - 69, 68, 171, 199, 3, 32, 4, 152, 209, 8, 3, 82, 32, 77, 227, 234, 26, 84, - 15, 11, 76, 13, 54, 32, 200, 182, 25, 3, 72, 79, 80, 231, 236, 9, 79, 6, - 162, 204, 12, 80, 236, 172, 16, 6, 87, 73, 84, 72, 32, 67, 139, 211, 6, + 1, 82, 140, 172, 3, 10, 67, 72, 32, 87, 73, 84, 72, 32, 85, 77, 142, 165, + 7, 84, 154, 195, 25, 86, 19, 78, 8, 86, 65, 0, 2, 68, 69, 52, 4, 69, 73, + 71, 72, 1, 7, 83, 73, 88, 84, 69, 69, 78, 2, 169, 178, 20, 8, 83, 67, 69, + 78, 68, 73, 78, 71, 2, 161, 178, 20, 2, 84, 72, 4, 220, 205, 32, 3, 68, + 69, 68, 171, 199, 3, 32, 4, 228, 200, 8, 3, 82, 32, 77, 203, 226, 26, 84, + 15, 11, 76, 13, 54, 32, 252, 165, 25, 3, 72, 79, 80, 231, 236, 9, 79, 6, + 238, 195, 12, 80, 212, 164, 16, 6, 87, 73, 84, 72, 32, 67, 139, 211, 6, 83, 208, 1, 84, 5, 71, 65, 76, 73, 32, 158, 9, 84, 37, 9, 90, 69, 78, 69, 32, 82, 73, 78, 71, 200, 1, 210, 1, 65, 40, 9, 67, 85, 82, 82, 69, 78, 67, 89, 32, 148, 2, 7, 76, 69, 84, 84, 69, 82, 32, 204, 3, 6, 82, 85, 80, - 69, 69, 32, 34, 83, 246, 239, 22, 73, 134, 4, 86, 158, 240, 11, 68, 225, - 110, 3, 71, 65, 78, 6, 138, 190, 32, 66, 50, 78, 135, 63, 85, 12, 120, - 10, 78, 85, 77, 69, 82, 65, 84, 79, 82, 32, 153, 196, 23, 14, 68, 69, 78, - 79, 77, 73, 78, 65, 84, 79, 82, 32, 83, 73, 10, 52, 3, 79, 78, 69, 158, - 193, 31, 70, 135, 169, 3, 84, 5, 173, 208, 29, 19, 32, 76, 69, 83, 83, + 69, 69, 32, 34, 83, 170, 223, 22, 73, 134, 4, 86, 158, 240, 11, 68, 225, + 110, 3, 71, 65, 78, 6, 190, 173, 32, 66, 50, 78, 135, 63, 85, 12, 120, + 10, 78, 85, 77, 69, 82, 65, 84, 79, 82, 32, 205, 179, 23, 14, 68, 69, 78, + 79, 77, 73, 78, 65, 84, 79, 82, 32, 83, 73, 10, 52, 3, 79, 78, 69, 210, + 176, 31, 70, 135, 169, 3, 84, 5, 225, 191, 29, 19, 32, 76, 69, 83, 83, 32, 84, 72, 65, 78, 32, 84, 72, 69, 32, 68, 69, 78, 79, 108, 226, 1, 75, - 90, 82, 238, 209, 21, 86, 190, 143, 8, 89, 178, 154, 3, 65, 38, 68, 114, + 90, 82, 238, 197, 21, 86, 242, 138, 8, 89, 178, 154, 3, 65, 38, 68, 114, 84, 230, 5, 85, 186, 202, 1, 73, 138, 196, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 80, 138, 69, 72, 2, 76, 2, 77, 186, 2, 69, 3, 79, 8, 26, - 72, 139, 218, 36, 65, 6, 26, 65, 215, 145, 14, 73, 5, 185, 231, 18, 3, - 78, 68, 65, 10, 34, 65, 242, 214, 36, 72, 3, 82, 7, 33, 6, 32, 87, 73, - 84, 72, 32, 4, 232, 174, 25, 5, 76, 79, 87, 69, 82, 1, 6, 77, 73, 68, 68, - 76, 69, 4, 210, 209, 35, 83, 191, 69, 77, 20, 116, 19, 69, 81, 85, 69, - 78, 67, 69, 32, 70, 79, 82, 32, 76, 69, 84, 84, 69, 82, 32, 158, 154, 26, - 65, 227, 158, 6, 73, 6, 154, 242, 22, 82, 175, 226, 13, 89, 4, 134, 174, - 26, 32, 151, 154, 9, 79, 5, 197, 220, 33, 3, 32, 87, 73, 100, 56, 6, 67, + 72, 191, 201, 36, 65, 6, 26, 65, 215, 133, 14, 73, 5, 185, 219, 18, 3, + 78, 68, 65, 10, 34, 65, 166, 198, 36, 72, 3, 82, 7, 33, 6, 32, 87, 73, + 84, 72, 32, 4, 156, 158, 25, 5, 76, 79, 87, 69, 82, 1, 6, 77, 73, 68, 68, + 76, 69, 4, 134, 193, 35, 83, 191, 69, 77, 20, 116, 19, 69, 81, 85, 69, + 78, 67, 69, 32, 70, 79, 82, 32, 76, 69, 84, 84, 69, 82, 32, 210, 137, 26, + 65, 227, 158, 6, 73, 6, 206, 225, 22, 82, 175, 226, 13, 89, 4, 186, 157, + 26, 32, 151, 154, 9, 79, 5, 249, 203, 33, 3, 32, 87, 73, 100, 56, 6, 67, 65, 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 50, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 50, 182, 2, 65, 50, 68, 42, 69, 82, 71, 38, 78, 38, 83, - 154, 143, 17, 77, 136, 235, 1, 6, 72, 73, 82, 68, 69, 65, 0, 2, 75, 79, - 172, 199, 13, 6, 84, 65, 84, 65, 83, 79, 196, 209, 2, 5, 66, 65, 83, 73, + 154, 131, 17, 77, 136, 235, 1, 6, 72, 73, 82, 68, 69, 65, 0, 2, 75, 79, + 224, 194, 13, 6, 84, 65, 84, 65, 83, 79, 196, 209, 2, 5, 66, 65, 83, 73, 71, 244, 50, 3, 87, 65, 83, 164, 108, 3, 70, 73, 84, 0, 3, 76, 65, 75, - 170, 11, 79, 2, 80, 2, 85, 219, 19, 73, 4, 26, 82, 255, 210, 36, 89, 2, - 215, 157, 23, 75, 4, 160, 223, 31, 3, 65, 82, 66, 3, 74, 6, 40, 4, 82, - 73, 71, 79, 151, 210, 36, 72, 5, 245, 184, 20, 4, 32, 84, 65, 77, 4, 158, - 243, 29, 79, 155, 220, 6, 78, 4, 242, 204, 31, 73, 187, 246, 3, 71, 4, - 194, 175, 26, 72, 155, 182, 3, 69, 4, 242, 250, 34, 87, 219, 64, 32, 194, + 170, 11, 79, 2, 80, 2, 85, 219, 19, 73, 4, 26, 82, 179, 194, 36, 89, 2, + 139, 141, 23, 75, 4, 212, 206, 31, 3, 65, 82, 66, 3, 74, 6, 40, 4, 82, + 73, 71, 79, 203, 193, 36, 72, 5, 245, 172, 20, 4, 32, 84, 65, 77, 4, 210, + 226, 29, 79, 155, 220, 6, 78, 4, 166, 188, 31, 73, 187, 246, 3, 71, 4, + 246, 158, 26, 72, 155, 182, 3, 69, 4, 166, 234, 34, 87, 219, 64, 32, 194, 1, 184, 2, 7, 76, 69, 84, 84, 69, 82, 32, 244, 1, 7, 78, 85, 77, 66, 69, 82, 32, 72, 5, 83, 73, 71, 78, 32, 48, 11, 86, 79, 87, 69, 76, 32, 83, - 73, 71, 78, 32, 190, 138, 26, 68, 198, 247, 3, 87, 208, 195, 2, 10, 71, + 73, 71, 78, 32, 242, 249, 25, 68, 198, 247, 3, 87, 208, 195, 2, 10, 71, 65, 80, 32, 70, 73, 76, 76, 69, 82, 161, 187, 3, 12, 72, 85, 78, 68, 82, - 69, 68, 83, 32, 85, 78, 73, 92, 210, 1, 86, 222, 238, 32, 65, 38, 68, + 69, 68, 83, 32, 85, 78, 73, 92, 210, 1, 86, 146, 222, 32, 65, 38, 68, 114, 84, 230, 5, 85, 186, 202, 1, 73, 138, 196, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 82, 2, 89, - 186, 2, 69, 3, 79, 8, 234, 1, 79, 231, 202, 36, 65, 36, 142, 126, 69, 38, - 70, 66, 78, 26, 83, 182, 193, 21, 84, 195, 240, 12, 79, 10, 134, 174, 32, - 67, 158, 67, 65, 187, 151, 3, 86, 24, 80, 2, 86, 79, 198, 243, 32, 65, + 186, 2, 69, 3, 79, 8, 234, 1, 79, 155, 186, 36, 65, 36, 142, 126, 69, 38, + 70, 66, 78, 26, 83, 234, 176, 21, 84, 195, 240, 12, 79, 10, 186, 157, 32, + 67, 158, 67, 65, 187, 151, 3, 86, 24, 80, 2, 86, 79, 250, 226, 32, 65, 38, 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 6, 33, 6, 67, 65, 76, - 73, 67, 32, 6, 162, 244, 32, 82, 159, 214, 3, 76, 26, 148, 1, 4, 67, 89, - 67, 76, 36, 2, 71, 32, 28, 2, 76, 76, 46, 82, 66, 84, 224, 186, 19, 4, - 79, 72, 65, 90, 160, 136, 12, 2, 75, 73, 239, 180, 4, 83, 4, 142, 219, - 32, 73, 247, 237, 3, 69, 4, 174, 175, 34, 82, 67, 83, 4, 164, 228, 9, 2, - 69, 68, 131, 131, 24, 73, 4, 236, 219, 32, 7, 84, 72, 68, 65, 89, 32, 67, - 171, 236, 3, 68, 4, 244, 224, 13, 2, 67, 79, 169, 229, 22, 4, 73, 78, 71, + 73, 67, 32, 6, 214, 227, 32, 82, 159, 214, 3, 76, 26, 148, 1, 4, 67, 89, + 67, 76, 36, 2, 71, 32, 28, 2, 76, 76, 46, 82, 66, 84, 224, 174, 19, 4, + 79, 72, 65, 90, 212, 131, 12, 2, 75, 73, 239, 180, 4, 83, 4, 194, 202, + 32, 73, 247, 237, 3, 69, 4, 226, 158, 34, 82, 67, 83, 4, 240, 219, 9, 2, + 69, 68, 235, 250, 23, 73, 4, 160, 203, 32, 7, 84, 72, 68, 65, 89, 32, 67, + 171, 236, 3, 68, 4, 192, 216, 13, 2, 67, 79, 145, 221, 22, 4, 73, 78, 71, 32, 196, 7, 42, 65, 174, 33, 79, 165, 11, 2, 85, 69, 246, 2, 32, 2, 67, - 75, 207, 128, 18, 78, 244, 2, 22, 32, 223, 31, 45, 228, 2, 210, 1, 67, + 75, 207, 244, 17, 78, 244, 2, 22, 32, 223, 31, 45, 228, 2, 210, 1, 67, 254, 4, 68, 174, 2, 70, 102, 72, 82, 76, 186, 4, 77, 250, 2, 78, 38, 80, - 46, 82, 150, 4, 83, 154, 4, 84, 82, 85, 248, 2, 3, 86, 69, 82, 210, 141, - 12, 79, 164, 228, 20, 3, 66, 79, 87, 187, 249, 1, 81, 102, 196, 1, 5, 73, - 82, 67, 76, 69, 200, 1, 6, 85, 82, 86, 69, 68, 32, 244, 145, 26, 12, 82, + 46, 82, 150, 4, 83, 154, 4, 84, 82, 85, 248, 2, 3, 86, 69, 82, 158, 133, + 12, 79, 140, 220, 20, 3, 66, 79, 87, 187, 249, 1, 81, 102, 196, 1, 5, 73, + 82, 67, 76, 69, 200, 1, 6, 85, 82, 86, 69, 68, 32, 168, 129, 26, 12, 82, 79, 83, 83, 32, 79, 78, 32, 83, 72, 73, 69, 248, 161, 3, 5, 69, 78, 84, 82, 69, 254, 172, 5, 72, 159, 14, 76, 11, 11, 32, 8, 72, 5, 87, 73, 84, - 72, 32, 189, 250, 16, 7, 70, 79, 82, 32, 82, 69, 67, 6, 140, 69, 8, 87, - 72, 73, 84, 69, 32, 68, 79, 218, 134, 19, 68, 181, 146, 2, 8, 84, 87, 79, + 72, 32, 189, 238, 16, 7, 70, 79, 82, 32, 82, 69, 67, 6, 140, 69, 8, 87, + 72, 73, 84, 69, 32, 68, 79, 218, 250, 18, 68, 177, 146, 2, 8, 84, 87, 79, 32, 87, 72, 73, 84, 16, 84, 4, 68, 79, 87, 78, 0, 2, 85, 80, 56, 3, 76, - 69, 70, 1, 4, 82, 73, 71, 72, 4, 153, 155, 32, 9, 87, 65, 82, 68, 83, 32, + 69, 70, 1, 4, 82, 73, 71, 72, 4, 205, 138, 32, 9, 87, 65, 82, 68, 83, 32, 65, 78, 68, 4, 53, 11, 84, 87, 65, 82, 68, 83, 32, 65, 78, 68, 32, 4, - 194, 163, 21, 85, 203, 170, 12, 68, 30, 64, 6, 73, 65, 77, 79, 78, 68, - 152, 1, 3, 79, 87, 78, 43, 82, 13, 11, 32, 10, 154, 19, 67, 172, 136, 13, - 10, 77, 73, 78, 85, 83, 32, 87, 72, 73, 84, 244, 172, 6, 6, 87, 73, 84, - 72, 32, 68, 254, 178, 15, 79, 135, 13, 83, 12, 214, 19, 32, 62, 45, 151, - 199, 31, 87, 6, 196, 219, 34, 2, 79, 80, 179, 21, 65, 8, 18, 76, 39, 79, - 4, 142, 132, 28, 79, 179, 184, 8, 65, 4, 184, 219, 2, 2, 85, 82, 223, - 189, 31, 76, 12, 38, 69, 158, 244, 34, 65, 251, 2, 79, 6, 228, 245, 34, + 194, 151, 21, 85, 255, 165, 12, 68, 30, 64, 6, 73, 65, 77, 79, 78, 68, + 152, 1, 3, 79, 87, 78, 43, 82, 13, 11, 32, 10, 154, 19, 67, 248, 255, 12, + 10, 77, 73, 78, 85, 83, 32, 87, 72, 73, 84, 168, 169, 6, 6, 87, 73, 84, + 72, 32, 68, 178, 174, 15, 79, 135, 13, 83, 12, 214, 19, 32, 62, 45, 203, + 182, 31, 87, 6, 248, 202, 34, 2, 79, 80, 179, 21, 65, 8, 18, 76, 39, 79, + 4, 194, 243, 27, 79, 179, 184, 8, 65, 4, 184, 219, 2, 2, 85, 82, 147, + 173, 31, 76, 12, 38, 69, 210, 227, 34, 65, 251, 2, 79, 6, 152, 229, 34, 2, 65, 82, 247, 11, 88, 40, 64, 5, 65, 82, 71, 69, 32, 140, 2, 3, 69, 70, - 84, 203, 1, 79, 12, 48, 6, 67, 73, 82, 67, 76, 69, 159, 152, 35, 83, 11, + 84, 203, 1, 79, 12, 48, 6, 67, 73, 82, 67, 76, 69, 211, 135, 35, 83, 11, 37, 7, 32, 77, 73, 78, 85, 83, 32, 8, 54, 76, 36, 4, 82, 73, 71, 72, 13, 3, 85, 80, 80, 4, 32, 2, 69, 70, 13, 2, 79, 87, 2, 31, 84, 2, 17, 2, 69, - 82, 2, 177, 183, 33, 8, 32, 81, 85, 65, 82, 84, 69, 82, 22, 96, 10, 45, - 80, 79, 73, 78, 84, 73, 78, 71, 32, 64, 6, 87, 65, 82, 68, 83, 32, 175, - 245, 34, 32, 12, 146, 7, 68, 190, 8, 73, 130, 233, 34, 80, 206, 24, 83, - 51, 84, 4, 250, 200, 33, 69, 231, 140, 1, 66, 6, 158, 15, 87, 243, 240, - 34, 90, 30, 76, 6, 69, 68, 73, 85, 77, 32, 153, 243, 21, 7, 79, 79, 78, + 82, 2, 229, 166, 33, 8, 32, 81, 85, 65, 82, 84, 69, 82, 22, 96, 10, 45, + 80, 79, 73, 78, 84, 73, 78, 71, 32, 64, 6, 87, 65, 82, 68, 83, 32, 227, + 228, 34, 32, 12, 146, 7, 68, 190, 8, 73, 182, 216, 34, 80, 206, 24, 83, + 51, 84, 4, 174, 184, 33, 69, 231, 140, 1, 66, 6, 158, 15, 87, 167, 224, + 34, 90, 30, 76, 6, 69, 68, 73, 85, 77, 32, 205, 226, 21, 7, 79, 79, 78, 32, 76, 73, 76, 28, 66, 68, 42, 76, 36, 4, 82, 73, 71, 72, 12, 2, 85, 80, - 111, 83, 6, 84, 3, 79, 87, 78, 231, 246, 34, 73, 6, 32, 2, 69, 70, 135, - 254, 34, 79, 4, 11, 84, 4, 81, 18, 45, 80, 79, 73, 78, 84, 73, 78, 71, + 111, 83, 6, 84, 3, 79, 87, 78, 155, 230, 34, 73, 6, 32, 2, 69, 70, 187, + 237, 34, 79, 4, 11, 84, 4, 81, 18, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 84, 82, 73, 65, 78, 71, 76, 69, 5, 145, 9, 2, 32, 67, 8, 198, 13, 77, - 203, 132, 35, 81, 4, 194, 165, 17, 69, 139, 209, 17, 73, 8, 234, 156, 25, - 85, 230, 217, 9, 65, 87, 69, 34, 52, 4, 73, 71, 72, 84, 238, 161, 34, 79, + 255, 243, 34, 81, 4, 194, 153, 17, 69, 191, 204, 17, 73, 8, 158, 140, 25, + 85, 230, 217, 9, 65, 87, 69, 34, 52, 4, 73, 71, 72, 84, 162, 145, 34, 79, 239, 85, 69, 30, 94, 32, 84, 10, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 245, 1, 6, 87, 65, 82, 68, 83, 32, 6, 60, 9, 84, 82, 73, 65, 78, 71, 76, - 69, 32, 239, 136, 35, 80, 2, 243, 210, 6, 67, 16, 90, 68, 88, 8, 84, 82, - 73, 65, 78, 71, 76, 69, 230, 7, 73, 134, 238, 34, 80, 203, 19, 83, 4, 65, - 14, 79, 85, 66, 76, 69, 32, 84, 82, 73, 65, 78, 71, 76, 69, 5, 227, 202, - 12, 32, 5, 241, 249, 20, 11, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, - 8, 250, 178, 19, 65, 150, 142, 14, 69, 231, 140, 1, 66, 40, 158, 2, 77, - 148, 1, 5, 81, 85, 65, 82, 69, 128, 150, 26, 3, 85, 78, 32, 160, 224, 1, + 69, 32, 163, 248, 34, 80, 2, 243, 206, 6, 67, 16, 90, 68, 88, 8, 84, 82, + 73, 65, 78, 71, 76, 69, 230, 7, 73, 186, 221, 34, 80, 203, 19, 83, 4, 65, + 14, 79, 85, 66, 76, 69, 32, 84, 82, 73, 65, 78, 71, 76, 69, 5, 175, 194, + 12, 32, 5, 241, 237, 20, 11, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, + 8, 250, 166, 19, 65, 202, 137, 14, 69, 231, 140, 1, 66, 40, 158, 2, 77, + 148, 1, 5, 81, 85, 65, 82, 69, 180, 133, 26, 3, 85, 78, 32, 160, 224, 1, 5, 75, 85, 76, 76, 32, 228, 183, 3, 3, 78, 79, 87, 168, 228, 1, 5, 65, 70, 69, 84, 89, 184, 131, 1, 13, 76, 73, 71, 72, 84, 76, 89, 32, 83, 77, 65, 76, 76, 198, 93, 67, 50, 72, 222, 1, 80, 191, 19, 84, 12, 40, 4, 65, - 76, 76, 32, 143, 246, 34, 73, 10, 154, 238, 34, 68, 150, 7, 76, 70, 83, + 76, 76, 32, 195, 229, 34, 73, 10, 206, 221, 34, 68, 150, 7, 76, 70, 83, 213, 15, 13, 85, 80, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 67, 9, 11, - 32, 6, 54, 67, 216, 214, 33, 3, 70, 79, 82, 223, 159, 1, 66, 2, 193, 151, - 31, 3, 69, 78, 84, 14, 192, 4, 3, 73, 78, 89, 162, 195, 23, 82, 174, 182, - 11, 79, 54, 69, 135, 2, 87, 18, 38, 80, 233, 249, 32, 3, 78, 73, 86, 16, - 46, 32, 62, 45, 170, 1, 80, 239, 197, 31, 87, 2, 173, 129, 35, 10, 80, + 32, 6, 54, 67, 140, 198, 33, 3, 70, 79, 82, 223, 159, 1, 66, 2, 245, 134, + 31, 3, 69, 78, 84, 14, 192, 4, 3, 73, 78, 89, 214, 178, 23, 82, 174, 182, + 11, 79, 54, 69, 135, 2, 87, 18, 38, 80, 157, 233, 32, 3, 78, 73, 86, 16, + 46, 32, 62, 45, 170, 1, 80, 163, 181, 31, 87, 2, 225, 240, 34, 10, 80, 79, 73, 78, 84, 73, 78, 71, 32, 66, 8, 45, 9, 80, 79, 73, 78, 84, 73, 78, - 71, 32, 8, 66, 73, 224, 253, 34, 5, 68, 79, 85, 66, 76, 238, 3, 83, 51, - 84, 2, 217, 254, 33, 8, 83, 79, 83, 67, 69, 76, 69, 83, 4, 21, 3, 69, 82, - 32, 4, 130, 204, 24, 76, 163, 178, 9, 82, 10, 56, 6, 84, 73, 67, 65, 76, - 32, 41, 4, 89, 32, 83, 77, 4, 220, 235, 34, 2, 82, 69, 235, 22, 69, 6, - 21, 3, 65, 76, 76, 6, 11, 32, 6, 254, 231, 34, 68, 150, 7, 76, 135, 21, + 71, 32, 8, 66, 73, 148, 237, 34, 5, 68, 79, 85, 66, 76, 238, 3, 83, 51, + 84, 2, 141, 238, 33, 8, 83, 79, 83, 67, 69, 76, 69, 83, 4, 21, 3, 69, 82, + 32, 4, 182, 187, 24, 76, 163, 178, 9, 82, 10, 56, 6, 84, 73, 67, 65, 76, + 32, 41, 4, 89, 32, 83, 77, 4, 144, 219, 34, 2, 82, 69, 235, 22, 69, 6, + 21, 3, 65, 76, 76, 6, 11, 32, 6, 178, 215, 34, 68, 150, 7, 76, 135, 21, 83, 16, 84, 15, 76, 69, 84, 84, 69, 82, 32, 67, 65, 80, 73, 84, 65, 76, - 32, 171, 159, 11, 70, 10, 242, 165, 36, 67, 2, 72, 2, 73, 2, 82, 3, 90, - 200, 4, 52, 3, 67, 75, 32, 186, 151, 2, 83, 219, 214, 10, 87, 196, 4, 80, + 32, 247, 150, 11, 70, 10, 166, 149, 36, 67, 2, 72, 2, 73, 2, 82, 3, 90, + 200, 4, 52, 3, 67, 75, 32, 186, 151, 2, 83, 167, 206, 10, 87, 196, 4, 80, 7, 79, 67, 84, 65, 78, 84, 45, 149, 7, 8, 83, 69, 88, 84, 65, 78, 84, 45, 204, 3, 58, 49, 130, 3, 50, 114, 53, 50, 54, 18, 51, 215, 1, 52, 234, 1, - 74, 50, 246, 1, 51, 174, 91, 52, 46, 53, 38, 54, 30, 55, 147, 197, 35, - 56, 116, 62, 51, 226, 92, 52, 46, 53, 38, 54, 30, 55, 147, 197, 35, 56, - 55, 54, 52, 214, 92, 53, 38, 54, 30, 55, 147, 197, 35, 56, 22, 50, 53, - 166, 2, 54, 190, 90, 55, 147, 197, 35, 56, 11, 42, 54, 150, 246, 28, 55, - 179, 171, 7, 56, 4, 194, 161, 36, 55, 3, 56, 56, 170, 1, 53, 50, 54, 210, - 89, 52, 110, 55, 147, 197, 35, 56, 118, 62, 52, 254, 89, 51, 98, 53, 38, - 54, 30, 55, 147, 197, 35, 56, 24, 46, 53, 50, 54, 190, 90, 55, 147, 197, - 35, 56, 13, 206, 1, 54, 254, 242, 28, 55, 179, 171, 7, 56, 7, 187, 90, - 55, 61, 54, 52, 118, 53, 230, 88, 54, 30, 55, 147, 197, 35, 56, 31, 46, - 53, 170, 89, 54, 30, 55, 147, 197, 35, 56, 15, 38, 54, 158, 89, 55, 147, - 197, 35, 56, 7, 170, 158, 36, 55, 3, 56, 14, 226, 88, 54, 30, 55, 147, - 197, 35, 56, 31, 46, 54, 234, 87, 53, 66, 55, 147, 197, 35, 56, 6, 166, - 88, 55, 147, 197, 35, 56, 120, 70, 49, 238, 1, 50, 238, 209, 25, 51, 38, - 52, 30, 53, 187, 200, 10, 54, 61, 58, 50, 126, 51, 198, 210, 25, 52, 30, - 53, 187, 200, 10, 54, 31, 50, 51, 142, 211, 25, 52, 30, 53, 187, 200, 10, - 54, 15, 42, 52, 254, 210, 25, 53, 187, 200, 10, 54, 7, 178, 155, 36, 53, - 3, 54, 15, 194, 210, 25, 52, 186, 157, 3, 53, 159, 171, 7, 54, 31, 50, - 52, 186, 209, 25, 51, 66, 53, 187, 200, 10, 54, 7, 247, 209, 25, 53, 6, - 226, 173, 22, 32, 213, 206, 8, 4, 66, 69, 82, 82, 232, 4, 200, 1, 3, 76, + 74, 50, 246, 1, 51, 174, 91, 52, 46, 53, 38, 54, 30, 55, 199, 180, 35, + 56, 116, 62, 51, 226, 92, 52, 46, 53, 38, 54, 30, 55, 199, 180, 35, 56, + 55, 54, 52, 214, 92, 53, 38, 54, 30, 55, 199, 180, 35, 56, 22, 50, 53, + 166, 2, 54, 190, 90, 55, 199, 180, 35, 56, 11, 42, 54, 202, 229, 28, 55, + 179, 171, 7, 56, 4, 246, 144, 36, 55, 3, 56, 56, 170, 1, 53, 50, 54, 210, + 89, 52, 110, 55, 199, 180, 35, 56, 118, 62, 52, 254, 89, 51, 98, 53, 38, + 54, 30, 55, 199, 180, 35, 56, 24, 46, 53, 50, 54, 190, 90, 55, 199, 180, + 35, 56, 13, 206, 1, 54, 178, 226, 28, 55, 179, 171, 7, 56, 7, 187, 90, + 55, 61, 54, 52, 118, 53, 230, 88, 54, 30, 55, 199, 180, 35, 56, 31, 46, + 53, 170, 89, 54, 30, 55, 199, 180, 35, 56, 15, 38, 54, 158, 89, 55, 199, + 180, 35, 56, 7, 222, 141, 36, 55, 3, 56, 14, 226, 88, 54, 30, 55, 199, + 180, 35, 56, 31, 46, 54, 234, 87, 53, 66, 55, 199, 180, 35, 56, 6, 166, + 88, 55, 199, 180, 35, 56, 120, 70, 49, 238, 1, 50, 162, 193, 25, 51, 38, + 52, 30, 53, 187, 200, 10, 54, 61, 58, 50, 126, 51, 250, 193, 25, 52, 30, + 53, 187, 200, 10, 54, 31, 50, 51, 194, 194, 25, 52, 30, 53, 187, 200, 10, + 54, 15, 42, 52, 178, 194, 25, 53, 187, 200, 10, 54, 7, 230, 138, 36, 53, + 3, 54, 15, 246, 193, 25, 52, 186, 157, 3, 53, 159, 171, 7, 54, 31, 50, + 52, 238, 192, 25, 51, 66, 53, 187, 200, 10, 54, 7, 171, 193, 25, 53, 6, + 150, 157, 22, 32, 213, 206, 8, 4, 66, 69, 82, 82, 232, 4, 200, 1, 3, 76, 68, 32, 78, 79, 104, 7, 80, 79, 77, 79, 70, 79, 32, 188, 6, 2, 84, 84, - 216, 6, 5, 85, 81, 85, 69, 84, 54, 87, 198, 1, 88, 182, 221, 5, 77, 146, - 175, 3, 89, 186, 194, 26, 65, 139, 34, 78, 14, 190, 197, 8, 83, 190, 212, - 7, 69, 202, 228, 17, 70, 234, 2, 87, 203, 11, 71, 10, 26, 75, 135, 165, - 23, 77, 9, 40, 4, 77, 65, 82, 75, 135, 151, 36, 83, 5, 189, 191, 23, 3, + 216, 6, 5, 85, 81, 85, 69, 84, 54, 87, 198, 1, 88, 182, 217, 5, 77, 222, + 170, 3, 89, 162, 186, 26, 65, 139, 34, 78, 14, 138, 189, 8, 83, 242, 208, + 7, 69, 254, 223, 17, 70, 234, 2, 87, 203, 11, 71, 10, 26, 75, 187, 148, + 23, 77, 9, 40, 4, 77, 65, 82, 75, 187, 134, 36, 83, 5, 241, 174, 23, 3, 32, 84, 65, 150, 1, 96, 13, 70, 73, 78, 65, 76, 32, 76, 69, 84, 84, 69, - 82, 32, 53, 7, 76, 69, 84, 84, 69, 82, 32, 10, 250, 149, 36, 71, 2, 72, + 82, 32, 53, 7, 76, 69, 84, 84, 69, 82, 32, 10, 174, 133, 36, 71, 2, 72, 2, 75, 2, 80, 3, 84, 140, 1, 234, 1, 65, 54, 85, 22, 69, 82, 71, 46, 73, - 70, 78, 38, 79, 98, 90, 190, 160, 7, 75, 178, 223, 24, 67, 2, 76, 2, 83, + 70, 78, 38, 79, 98, 90, 190, 156, 7, 75, 230, 210, 24, 67, 2, 76, 2, 83, 230, 57, 66, 186, 202, 1, 74, 198, 140, 2, 68, 2, 70, 2, 72, 2, 77, 2, - 80, 2, 81, 2, 82, 2, 84, 2, 86, 3, 88, 21, 50, 73, 2, 85, 74, 78, 222, - 146, 36, 72, 3, 77, 5, 195, 195, 35, 78, 17, 50, 78, 222, 146, 36, 69, 2, - 72, 2, 73, 3, 82, 7, 218, 146, 36, 71, 3, 78, 11, 190, 146, 36, 72, 2, - 78, 2, 85, 3, 87, 15, 164, 148, 34, 2, 78, 78, 238, 253, 1, 72, 2, 77, 2, - 82, 3, 85, 9, 206, 147, 34, 71, 131, 254, 1, 78, 17, 66, 78, 230, 143, - 35, 32, 134, 129, 1, 69, 2, 77, 2, 79, 3, 85, 4, 230, 144, 36, 71, 3, 78, - 9, 202, 144, 36, 72, 2, 73, 3, 89, 66, 104, 3, 79, 77, 32, 221, 199, 21, + 80, 2, 81, 2, 82, 2, 84, 2, 86, 3, 88, 21, 50, 73, 2, 85, 74, 78, 146, + 130, 36, 72, 3, 77, 5, 247, 178, 35, 78, 17, 50, 78, 146, 130, 36, 69, 2, + 72, 2, 73, 3, 82, 7, 142, 130, 36, 71, 3, 78, 11, 242, 129, 36, 72, 2, + 78, 2, 85, 3, 87, 15, 216, 131, 34, 2, 78, 78, 238, 253, 1, 72, 2, 77, 2, + 82, 3, 85, 9, 130, 131, 34, 71, 131, 254, 1, 78, 17, 66, 78, 154, 255, + 34, 32, 134, 129, 1, 69, 2, 77, 2, 79, 3, 85, 4, 154, 128, 36, 71, 3, 78, + 9, 254, 255, 35, 72, 2, 73, 3, 89, 66, 104, 3, 79, 77, 32, 145, 183, 21, 17, 76, 69, 32, 87, 73, 84, 72, 32, 80, 79, 80, 80, 73, 78, 71, 32, 67, 64, 152, 2, 5, 72, 65, 76, 70, 32, 232, 1, 5, 76, 69, 70, 84, 32, 88, 6, 82, 73, 71, 72, 84, 32, 88, 14, 83, 81, 85, 65, 82, 69, 32, 66, 82, 65, - 67, 75, 69, 84, 210, 228, 15, 65, 226, 154, 16, 67, 210, 3, 80, 140, 3, + 67, 75, 69, 84, 210, 216, 15, 65, 150, 150, 16, 67, 210, 3, 80, 140, 3, 13, 74, 85, 83, 84, 73, 70, 73, 69, 68, 32, 85, 80, 80, 135, 5, 84, 32, 148, 1, 16, 70, 79, 82, 87, 65, 82, 68, 45, 70, 65, 67, 73, 78, 71, 32, - 82, 134, 132, 32, 76, 22, 82, 252, 2, 2, 83, 84, 174, 5, 66, 211, 245, 1, - 73, 10, 196, 179, 29, 11, 85, 78, 78, 69, 82, 32, 70, 82, 65, 77, 69, - 155, 210, 2, 79, 8, 196, 137, 32, 13, 74, 85, 83, 84, 73, 70, 73, 69, 68, - 32, 85, 80, 80, 126, 67, 51, 72, 8, 234, 137, 32, 67, 50, 72, 33, 13, 74, - 85, 83, 84, 73, 70, 73, 69, 68, 32, 85, 80, 80, 5, 129, 236, 23, 9, 32, - 79, 86, 69, 82, 32, 84, 79, 80, 5, 209, 248, 34, 8, 32, 79, 70, 32, 70, - 76, 79, 87, 14, 58, 76, 116, 3, 84, 73, 69, 149, 170, 33, 3, 32, 65, 78, - 6, 26, 32, 207, 183, 35, 73, 4, 224, 195, 9, 7, 79, 70, 32, 72, 89, 71, - 73, 173, 154, 23, 6, 87, 73, 84, 72, 32, 83, 7, 211, 231, 32, 32, 218, 2, - 88, 10, 32, 68, 82, 65, 87, 73, 78, 71, 83, 32, 153, 138, 35, 6, 73, 78, + 82, 186, 243, 31, 76, 22, 82, 252, 2, 2, 83, 84, 174, 5, 66, 211, 245, 1, + 73, 10, 248, 162, 29, 11, 85, 78, 78, 69, 82, 32, 70, 82, 65, 77, 69, + 155, 210, 2, 79, 8, 248, 248, 31, 13, 74, 85, 83, 84, 73, 70, 73, 69, 68, + 32, 85, 80, 80, 126, 67, 51, 72, 8, 158, 249, 31, 67, 50, 72, 33, 13, 74, + 85, 83, 84, 73, 70, 73, 69, 68, 32, 85, 80, 80, 5, 181, 219, 23, 9, 32, + 79, 86, 69, 82, 32, 84, 79, 80, 5, 133, 232, 34, 8, 32, 79, 70, 32, 70, + 76, 79, 87, 14, 58, 76, 116, 3, 84, 73, 69, 201, 153, 33, 3, 32, 65, 78, + 6, 26, 32, 131, 167, 35, 73, 4, 172, 187, 9, 7, 79, 70, 32, 72, 89, 71, + 73, 149, 146, 23, 6, 87, 73, 84, 72, 32, 83, 7, 135, 215, 32, 32, 218, 2, + 88, 10, 32, 68, 82, 65, 87, 73, 78, 71, 83, 32, 205, 249, 34, 6, 73, 78, 71, 32, 71, 76, 216, 2, 176, 1, 2, 68, 79, 228, 6, 6, 72, 69, 65, 86, 89, 32, 254, 2, 76, 204, 25, 6, 82, 73, 71, 72, 84, 32, 144, 4, 3, 85, 80, 32, 245, 3, 9, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 52, 5, 85, 66, 76, 69, 32, 165, 3, 3, 87, 78, 32, 30, 58, 68, 216, 2, 2, 85, 80, 234, 5, 86, - 203, 188, 29, 72, 14, 64, 8, 73, 65, 71, 79, 78, 65, 76, 32, 149, 2, 3, + 255, 171, 29, 72, 14, 64, 8, 73, 65, 71, 79, 78, 65, 76, 32, 149, 2, 3, 79, 87, 78, 8, 104, 6, 85, 80, 80, 69, 82, 32, 205, 14, 15, 76, 79, 87, 69, 82, 32, 76, 69, 70, 84, 32, 84, 79, 32, 77, 6, 76, 8, 76, 69, 70, 84, 32, 84, 79, 32, 237, 24, 6, 82, 73, 71, 72, 84, 32, 4, 204, 23, 14, 77, - 73, 68, 68, 76, 69, 32, 67, 69, 78, 84, 82, 69, 32, 191, 194, 23, 76, 6, + 73, 68, 68, 76, 69, 32, 67, 69, 78, 84, 82, 69, 32, 243, 177, 23, 76, 6, 199, 26, 32, 36, 128, 1, 10, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 132, 1, 10, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 210, 38, 68, 131, 4, 83, 12, 76, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 228, 35, 2, 85, 80, 151, 5, - 72, 4, 17, 2, 84, 32, 4, 230, 32, 85, 199, 180, 35, 76, 12, 76, 3, 76, + 72, 4, 17, 2, 84, 32, 4, 230, 32, 85, 251, 163, 35, 76, 12, 76, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 156, 36, 2, 85, 80, 235, 4, 72, 4, 17, 2, 84, 32, 4, 198, 32, 85, 135, 9, 72, 46, 136, 1, 4, 76, 69, 70, 84, 68, 2, - 85, 80, 130, 1, 86, 172, 20, 2, 68, 79, 170, 2, 81, 100, 2, 84, 82, 146, - 165, 29, 72, 247, 148, 6, 82, 5, 45, 9, 32, 65, 78, 68, 32, 76, 73, 71, - 72, 2, 255, 169, 34, 84, 11, 29, 5, 32, 65, 78, 68, 32, 8, 42, 76, 254, - 188, 29, 72, 247, 148, 6, 82, 4, 220, 195, 24, 4, 73, 71, 72, 84, 131, + 85, 80, 130, 1, 86, 172, 20, 2, 68, 79, 170, 2, 81, 100, 2, 84, 82, 198, + 148, 29, 72, 247, 148, 6, 82, 5, 45, 9, 32, 65, 78, 68, 32, 76, 73, 71, + 72, 2, 179, 153, 34, 84, 11, 29, 5, 32, 65, 78, 68, 32, 8, 42, 76, 178, + 172, 29, 72, 247, 148, 6, 82, 4, 144, 179, 24, 4, 73, 71, 72, 84, 131, 142, 11, 69, 8, 209, 20, 7, 69, 82, 84, 73, 67, 65, 76, 156, 1, 56, 4, 69, 70, 84, 32, 169, 2, 5, 73, 71, 72, 84, 32, 16, 160, 27, 19, 68, 79, 87, 78, 32, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 82, 73, 71, 72, 24, @@ -1232,150 +1232,150 @@ static const unsigned char packed_name_dawg[] = { 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 82, 73, 71, 72, 140, 1, 248, 1, 4, 65, 82, 67, 32, 30, 68, 248, 15, 10, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 112, 4, 76, 69, 70, 84, 62, 81, 34, 84, 172, 1, 2, 85, 80, 120, - 8, 86, 69, 82, 84, 73, 67, 65, 76, 156, 211, 13, 7, 66, 79, 84, 84, 79, - 77, 32, 139, 229, 21, 82, 8, 166, 222, 17, 68, 67, 85, 80, 52, 8, 73, 65, + 8, 86, 69, 82, 84, 73, 67, 65, 76, 156, 199, 13, 7, 66, 79, 84, 84, 79, + 77, 32, 191, 224, 21, 82, 8, 166, 210, 17, 68, 67, 85, 80, 52, 8, 73, 65, 71, 79, 78, 65, 76, 32, 199, 14, 79, 68, 168, 1, 14, 76, 79, 87, 69, 82, 32, 76, 69, 70, 84, 32, 84, 79, 32, 96, 7, 77, 73, 68, 68, 76, 69, 32, - 136, 3, 6, 85, 80, 80, 69, 82, 32, 230, 173, 34, 67, 183, 4, 68, 4, 38, + 136, 3, 6, 85, 80, 80, 69, 82, 32, 154, 157, 34, 67, 183, 4, 68, 4, 38, 77, 33, 5, 85, 80, 80, 69, 82, 2, 29, 5, 73, 68, 68, 76, 69, 2, 129, 12, 2, 32, 67, 16, 88, 8, 76, 69, 70, 84, 32, 84, 79, 32, 213, 1, 9, 82, 73, 71, 72, 84, 32, 84, 79, 32, 10, 156, 1, 6, 76, 79, 87, 69, 82, 32, 33, 28, 85, 80, 80, 69, 82, 32, 67, 69, 78, 84, 82, 69, 32, 84, 79, 32, 77, - 73, 68, 68, 76, 69, 32, 82, 73, 71, 72, 84, 6, 246, 3, 67, 215, 195, 35, - 82, 5, 171, 211, 20, 32, 6, 232, 4, 15, 85, 80, 80, 69, 82, 32, 67, 69, + 73, 68, 68, 76, 69, 32, 82, 73, 71, 72, 84, 6, 246, 3, 67, 139, 179, 35, + 82, 5, 171, 199, 20, 32, 6, 232, 4, 15, 85, 80, 80, 69, 82, 32, 67, 69, 78, 84, 82, 69, 32, 84, 79, 235, 3, 76, 44, 144, 1, 10, 67, 69, 78, 84, 82, 69, 32, 84, 79, 32, 248, 3, 8, 76, 69, 70, 84, 32, 84, 79, 32, 193, 2, 9, 82, 73, 71, 72, 84, 32, 84, 79, 32, 20, 52, 7, 77, 73, 68, 68, 76, - 69, 32, 203, 197, 23, 76, 16, 56, 4, 76, 69, 70, 84, 165, 1, 5, 82, 73, + 69, 32, 255, 180, 23, 76, 16, 56, 4, 76, 69, 70, 84, 165, 1, 5, 82, 73, 71, 72, 84, 9, 11, 32, 6, 84, 10, 84, 79, 32, 76, 79, 87, 69, 82, 32, 67, - 141, 207, 20, 5, 65, 78, 68, 32, 77, 4, 29, 5, 69, 78, 84, 82, 69, 5, - 137, 232, 32, 3, 32, 84, 79, 9, 11, 32, 6, 88, 3, 65, 78, 68, 65, 15, 84, - 79, 32, 76, 79, 87, 69, 82, 32, 67, 69, 78, 84, 82, 69, 2, 149, 206, 20, - 11, 32, 77, 73, 68, 68, 76, 69, 32, 76, 69, 70, 5, 133, 224, 10, 9, 32, + 141, 195, 20, 5, 65, 78, 68, 32, 77, 4, 29, 5, 69, 78, 84, 82, 69, 5, + 189, 215, 32, 3, 32, 84, 79, 9, 11, 32, 6, 88, 3, 65, 78, 68, 65, 15, 84, + 79, 32, 76, 79, 87, 69, 82, 32, 67, 69, 78, 84, 82, 69, 2, 149, 194, 20, + 11, 32, 77, 73, 68, 68, 76, 69, 32, 76, 69, 70, 5, 209, 215, 10, 9, 32, 84, 79, 32, 77, 73, 68, 68, 76, 14, 68, 6, 76, 79, 87, 69, 82, 32, 97, 7, - 77, 73, 68, 68, 76, 69, 32, 6, 48, 6, 67, 69, 78, 84, 82, 69, 187, 192, + 77, 73, 68, 68, 76, 69, 32, 6, 48, 6, 67, 69, 78, 84, 82, 69, 239, 175, 35, 82, 5, 11, 32, 2, 233, 4, 4, 84, 79, 32, 85, 8, 76, 10, 67, 69, 78, 84, 82, 69, 32, 84, 79, 32, 33, 5, 82, 73, 71, 72, 84, 4, 250, 3, 85, - 231, 214, 13, 76, 5, 11, 32, 2, 157, 218, 13, 2, 84, 79, 10, 46, 76, 69, - 7, 77, 73, 68, 68, 76, 69, 32, 4, 29, 5, 79, 87, 69, 82, 32, 4, 202, 227, + 231, 202, 13, 76, 5, 11, 32, 2, 157, 206, 13, 2, 84, 79, 10, 46, 76, 69, + 7, 77, 73, 68, 68, 76, 69, 32, 4, 29, 5, 79, 87, 69, 82, 32, 4, 254, 210, 32, 67, 191, 218, 2, 76, 6, 34, 67, 37, 4, 76, 69, 70, 84, 2, 45, 6, 69, - 78, 84, 82, 69, 32, 5, 11, 32, 2, 165, 191, 23, 2, 84, 79, 12, 36, 2, 87, - 78, 253, 2, 2, 85, 66, 9, 11, 32, 6, 25, 4, 65, 78, 68, 32, 6, 202, 167, + 78, 84, 82, 69, 32, 5, 11, 32, 2, 217, 174, 23, 2, 84, 79, 12, 36, 2, 87, + 78, 253, 2, 2, 85, 66, 9, 11, 32, 6, 25, 4, 65, 78, 68, 32, 6, 254, 150, 29, 72, 218, 148, 6, 76, 31, 82, 9, 11, 32, 6, 40, 4, 65, 78, 68, 32, - 187, 181, 35, 87, 4, 26, 85, 211, 189, 23, 76, 2, 225, 189, 23, 2, 80, - 80, 5, 209, 146, 34, 10, 32, 65, 78, 68, 32, 72, 69, 65, 86, 89, 4, 109, - 5, 85, 65, 68, 82, 85, 6, 66, 82, 189, 213, 13, 10, 79, 80, 32, 65, 78, + 239, 164, 35, 87, 4, 26, 85, 135, 173, 23, 76, 2, 149, 173, 23, 2, 80, + 80, 5, 133, 130, 34, 10, 32, 65, 78, 68, 32, 72, 69, 65, 86, 89, 4, 109, + 5, 85, 65, 68, 82, 85, 6, 66, 82, 189, 201, 13, 10, 79, 80, 32, 65, 78, 68, 32, 85, 80, 80, 4, 11, 73, 4, 11, 80, 4, 41, 8, 76, 69, 32, 68, 65, - 83, 72, 32, 4, 166, 193, 16, 86, 167, 227, 12, 72, 11, 29, 5, 32, 65, 78, - 68, 32, 8, 34, 72, 190, 184, 35, 76, 31, 82, 4, 196, 170, 24, 4, 69, 65, - 86, 89, 171, 249, 4, 79, 17, 29, 5, 32, 65, 78, 68, 32, 14, 230, 168, 28, + 83, 72, 32, 4, 166, 181, 16, 86, 219, 222, 12, 72, 11, 29, 5, 32, 65, 78, + 68, 32, 8, 34, 72, 242, 167, 35, 76, 31, 82, 4, 248, 153, 24, 4, 69, 65, + 86, 89, 171, 249, 4, 79, 17, 29, 5, 32, 65, 78, 68, 32, 14, 154, 152, 28, 66, 42, 84, 130, 122, 72, 218, 148, 6, 76, 31, 82, 16, 148, 2, 18, 68, 79, 87, 78, 32, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 76, 69, 70, 24, 13, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 76, 69, 70, 100, 13, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 76, 69, 70, 97, 16, 85, 80, 32, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 76, 69, 70, 2, 101, 3, 84, 32, 85, 6, 17, 2, 84, 32, 6, 58, 85, 178, 3, 68, 245, 4, 6, 86, 69, 82, 84, 73, 67, 2, - 179, 194, 33, 80, 6, 17, 2, 84, 32, 6, 58, 85, 134, 4, 68, 205, 4, 6, 86, + 231, 177, 33, 80, 6, 17, 2, 84, 32, 6, 58, 85, 134, 4, 68, 205, 4, 6, 86, 69, 82, 84, 73, 67, 2, 239, 8, 80, 2, 185, 2, 3, 84, 32, 68, 36, 128, 1, 10, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 188, 1, 10, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 186, 2, 68, 131, 4, 83, 12, 80, 4, 68, 79, 87, 78, 24, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 255, 4, 72, 2, 145, 5, 2, - 32, 72, 4, 17, 2, 84, 32, 4, 26, 68, 151, 177, 35, 76, 2, 129, 191, 33, + 32, 72, 4, 17, 2, 84, 32, 4, 26, 68, 203, 160, 35, 76, 2, 181, 174, 33, 3, 79, 87, 78, 12, 80, 4, 68, 79, 87, 78, 24, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 211, 4, 72, 2, 229, 4, 2, 32, 72, 4, 17, 2, 84, 32, 4, 22, 68, 131, 5, 72, 2, 233, 4, 3, 79, 87, 78, 24, 130, 1, 68, 188, 1, 10, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 144, 1, 10, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 183, 1, 83, 6, 49, 10, 79, 85, 66, 76, 69, 32, 65, 78, 68, 32, 6, 92, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 13, 10, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 2, 11, 84, 2, 169, 129, 27, 2, 32, 83, 6, 54, + 73, 90, 79, 78, 84, 65, 76, 2, 11, 84, 2, 221, 240, 26, 2, 32, 83, 6, 54, 72, 68, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 37, 7, 79, 82, 73, 90, - 79, 78, 84, 2, 141, 186, 33, 2, 65, 76, 2, 243, 185, 33, 84, 6, 54, 72, + 79, 78, 84, 2, 193, 169, 33, 2, 65, 76, 2, 167, 169, 33, 84, 6, 54, 72, 60, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 37, 7, 79, 82, 73, 90, 79, - 78, 84, 2, 29, 2, 65, 76, 2, 11, 84, 2, 17, 2, 32, 72, 2, 225, 195, 35, + 78, 84, 2, 29, 2, 65, 76, 2, 11, 84, 2, 17, 2, 32, 72, 2, 149, 179, 35, 3, 69, 65, 86, 6, 49, 10, 73, 78, 71, 76, 69, 32, 65, 78, 68, 32, 6, 96, - 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 177, 197, 26, 9, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 2, 187, 197, 26, 84, 134, 6, 46, 65, 178, 14, 69, 150, 1, + 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 229, 180, 26, 9, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 2, 239, 180, 26, 84, 134, 6, 46, 65, 178, 14, 69, 150, 1, 73, 179, 1, 79, 232, 5, 36, 4, 72, 77, 73, 32, 247, 9, 73, 230, 1, 192, 1, 7, 76, 69, 84, 84, 69, 82, 32, 196, 2, 7, 78, 85, 77, 66, 69, 82, 32, 144, 2, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 84, 5, 83, - 73, 71, 78, 32, 122, 86, 159, 138, 25, 68, 108, 210, 1, 79, 242, 241, 31, + 73, 71, 78, 32, 122, 86, 211, 249, 24, 68, 108, 210, 1, 79, 166, 225, 31, 65, 38, 68, 114, 84, 46, 86, 186, 5, 85, 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 82, 2, 89, 187, 2, 69, 15, 45, 9, 76, 68, 32, 84, 65, 77, - 73, 76, 32, 12, 150, 152, 29, 76, 142, 155, 2, 83, 210, 97, 78, 131, 246, - 2, 82, 42, 82, 69, 38, 70, 66, 78, 26, 83, 182, 193, 21, 84, 130, 234, 5, - 79, 227, 227, 7, 74, 4, 129, 189, 31, 4, 73, 71, 72, 84, 8, 26, 79, 143, - 168, 21, 73, 4, 254, 221, 33, 82, 135, 183, 1, 85, 4, 65, 3, 73, 78, 69, - 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 5, 175, 187, 35, 84, 10, 46, 76, - 130, 222, 12, 68, 177, 16, 2, 67, 82, 4, 242, 210, 19, 79, 147, 222, 14, - 73, 12, 174, 174, 31, 67, 228, 67, 9, 79, 76, 68, 32, 84, 65, 77, 73, 76, + 73, 76, 32, 12, 202, 135, 29, 76, 142, 155, 2, 83, 210, 97, 78, 131, 246, + 2, 82, 42, 82, 69, 38, 70, 66, 78, 26, 83, 234, 176, 21, 84, 130, 234, 5, + 79, 227, 227, 7, 74, 4, 181, 172, 31, 4, 73, 71, 72, 84, 8, 26, 79, 195, + 151, 21, 73, 4, 178, 205, 33, 82, 135, 183, 1, 85, 4, 65, 3, 73, 78, 69, + 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 5, 227, 170, 35, 84, 10, 46, 76, + 206, 213, 12, 68, 177, 16, 2, 67, 82, 4, 242, 198, 19, 79, 199, 217, 14, + 73, 12, 226, 157, 31, 67, 228, 67, 9, 79, 76, 68, 32, 84, 65, 77, 73, 76, 246, 157, 1, 74, 158, 2, 86, 122, 85, 255, 243, 1, 65, 34, 64, 10, 79, - 87, 69, 76, 32, 83, 73, 71, 78, 32, 187, 142, 33, 73, 32, 138, 1, 79, - 228, 199, 29, 11, 66, 72, 65, 84, 84, 73, 80, 82, 79, 76, 85, 198, 170, - 2, 65, 38, 85, 22, 86, 166, 202, 1, 73, 199, 140, 2, 69, 7, 181, 173, 31, + 87, 69, 76, 32, 83, 73, 71, 78, 32, 239, 253, 32, 73, 32, 138, 1, 79, + 152, 183, 29, 11, 66, 72, 65, 84, 84, 73, 80, 82, 79, 76, 85, 198, 170, + 2, 65, 38, 85, 22, 86, 166, 202, 1, 73, 199, 140, 2, 69, 7, 233, 156, 31, 10, 76, 68, 32, 84, 65, 77, 73, 76, 32, 83, 130, 4, 72, 12, 76, 76, 69, - 32, 80, 65, 84, 84, 69, 82, 78, 32, 191, 200, 35, 78, 128, 4, 44, 5, 68, - 79, 84, 83, 45, 207, 250, 6, 66, 254, 3, 74, 49, 74, 50, 66, 51, 54, 52, - 46, 53, 38, 54, 30, 55, 147, 197, 35, 56, 129, 2, 66, 50, 66, 51, 54, 52, - 46, 53, 38, 54, 30, 55, 147, 197, 35, 56, 129, 1, 58, 51, 54, 52, 46, 53, - 38, 54, 30, 55, 147, 197, 35, 56, 65, 50, 52, 46, 53, 38, 54, 30, 55, - 147, 197, 35, 56, 33, 42, 53, 38, 54, 30, 55, 147, 197, 35, 56, 17, 34, - 54, 30, 55, 147, 197, 35, 56, 9, 26, 55, 147, 197, 35, 56, 5, 143, 197, - 35, 56, 8, 26, 65, 143, 174, 35, 86, 6, 196, 205, 20, 11, 75, 32, 80, 69, - 82, 77, 73, 84, 84, 69, 68, 228, 176, 8, 6, 83, 84, 45, 70, 69, 69, 183, - 198, 6, 68, 10, 42, 68, 96, 2, 69, 70, 199, 191, 35, 67, 4, 212, 197, 32, + 32, 80, 65, 84, 84, 69, 82, 78, 32, 243, 183, 35, 78, 128, 4, 44, 5, 68, + 79, 84, 83, 45, 175, 246, 6, 66, 254, 3, 74, 49, 74, 50, 66, 51, 54, 52, + 46, 53, 38, 54, 30, 55, 199, 180, 35, 56, 129, 2, 66, 50, 66, 51, 54, 52, + 46, 53, 38, 54, 30, 55, 199, 180, 35, 56, 129, 1, 58, 51, 54, 52, 46, 53, + 38, 54, 30, 55, 199, 180, 35, 56, 65, 50, 52, 46, 53, 38, 54, 30, 55, + 199, 180, 35, 56, 33, 42, 53, 38, 54, 30, 55, 199, 180, 35, 56, 17, 34, + 54, 30, 55, 199, 180, 35, 56, 9, 26, 55, 199, 180, 35, 56, 5, 195, 180, + 35, 56, 8, 26, 65, 195, 157, 35, 86, 6, 196, 193, 20, 11, 75, 32, 80, 69, + 82, 77, 73, 84, 84, 69, 68, 152, 172, 8, 6, 83, 84, 45, 70, 69, 69, 183, + 198, 6, 68, 10, 42, 68, 96, 2, 69, 70, 251, 174, 35, 67, 4, 136, 181, 32, 6, 71, 69, 32, 65, 84, 32, 149, 158, 1, 9, 69, 32, 87, 73, 84, 72, 32, - 86, 69, 4, 190, 153, 32, 67, 159, 169, 3, 83, 12, 84, 4, 75, 69, 78, 32, - 244, 204, 8, 2, 67, 67, 176, 237, 25, 2, 87, 78, 231, 118, 79, 6, 196, - 199, 27, 17, 67, 73, 82, 67, 76, 69, 32, 87, 73, 84, 72, 32, 78, 79, 82, + 86, 69, 4, 242, 136, 32, 67, 159, 169, 3, 83, 12, 84, 4, 75, 69, 78, 32, + 192, 196, 8, 2, 67, 67, 152, 229, 25, 2, 87, 78, 231, 118, 79, 6, 248, + 182, 27, 17, 67, 73, 82, 67, 76, 69, 32, 87, 73, 84, 72, 32, 78, 79, 82, 84, 72, 222, 214, 6, 66, 151, 28, 72, 134, 1, 208, 1, 4, 66, 66, 76, 69, 46, 71, 156, 4, 4, 72, 73, 68, 32, 36, 2, 76, 76, 122, 83, 56, 4, 84, 84, - 69, 82, 164, 134, 11, 10, 73, 76, 68, 73, 78, 71, 32, 67, 79, 78, 144, - 226, 16, 2, 82, 82, 255, 253, 6, 67, 4, 144, 171, 28, 2, 32, 84, 131, + 69, 82, 240, 253, 10, 10, 73, 76, 68, 73, 78, 71, 32, 67, 79, 78, 248, + 217, 16, 2, 82, 82, 255, 253, 6, 67, 4, 196, 154, 28, 2, 32, 84, 131, 148, 7, 83, 63, 33, 6, 73, 78, 69, 83, 69, 32, 60, 144, 1, 7, 76, 69, 84, 84, 69, 82, 32, 172, 2, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, - 146, 196, 16, 69, 141, 253, 13, 4, 80, 65, 76, 76, 46, 154, 1, 77, 34, - 78, 190, 185, 35, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, - 80, 2, 82, 2, 83, 2, 84, 2, 86, 2, 89, 187, 2, 65, 4, 218, 185, 35, 80, - 187, 2, 65, 12, 46, 71, 34, 89, 238, 184, 35, 82, 187, 2, 65, 4, 138, - 185, 35, 75, 187, 2, 65, 4, 234, 184, 35, 67, 187, 2, 65, 10, 174, 164, - 35, 65, 214, 22, 69, 2, 73, 2, 79, 3, 85, 40, 230, 164, 10, 76, 167, 253, - 18, 86, 10, 56, 2, 69, 84, 20, 4, 72, 79, 82, 78, 175, 175, 9, 83, 5, - 179, 246, 31, 32, 5, 189, 210, 27, 5, 32, 87, 73, 84, 72, 9, 26, 84, 147, - 228, 32, 32, 4, 182, 210, 27, 83, 15, 32, 5, 199, 149, 35, 70, 240, 3, + 146, 184, 16, 69, 193, 248, 13, 4, 80, 65, 76, 76, 46, 154, 1, 77, 34, + 78, 242, 168, 35, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, + 80, 2, 82, 2, 83, 2, 84, 2, 86, 2, 89, 187, 2, 65, 4, 142, 169, 35, 80, + 187, 2, 65, 12, 46, 71, 34, 89, 162, 168, 35, 82, 187, 2, 65, 4, 190, + 168, 35, 75, 187, 2, 65, 4, 158, 168, 35, 67, 187, 2, 65, 10, 226, 147, + 35, 65, 214, 22, 69, 2, 73, 2, 79, 3, 85, 40, 178, 156, 10, 76, 143, 245, + 18, 86, 10, 56, 2, 69, 84, 20, 4, 72, 79, 82, 78, 251, 166, 9, 83, 5, + 231, 229, 31, 32, 5, 241, 193, 27, 5, 32, 87, 73, 84, 72, 9, 26, 84, 199, + 211, 32, 32, 4, 234, 193, 27, 83, 15, 32, 5, 251, 132, 35, 70, 240, 3, 140, 1, 23, 90, 65, 78, 84, 73, 78, 69, 32, 77, 85, 83, 73, 67, 65, 76, - 32, 83, 89, 77, 66, 79, 76, 32, 153, 200, 20, 5, 84, 69, 32, 79, 82, 238, + 32, 83, 89, 77, 66, 79, 76, 32, 149, 188, 20, 5, 84, 69, 32, 79, 82, 238, 3, 154, 2, 65, 128, 7, 2, 67, 72, 170, 1, 68, 158, 5, 69, 206, 2, 70, 166, 8, 71, 202, 3, 73, 162, 2, 75, 142, 5, 76, 190, 2, 77, 250, 4, 79, 114, 80, 174, 4, 82, 42, 83, 194, 5, 84, 196, 5, 2, 86, 65, 250, 1, 89, - 178, 196, 32, 78, 201, 146, 2, 9, 88, 73, 82, 79, 78, 32, 75, 76, 65, 62, + 230, 179, 32, 78, 201, 146, 2, 9, 88, 73, 82, 79, 78, 32, 75, 76, 65, 62, 60, 5, 71, 79, 71, 73, 32, 222, 1, 78, 118, 80, 199, 2, 82, 16, 70, 65, 0, 2, 71, 79, 64, 2, 77, 69, 37, 5, 80, 79, 76, 73, 32, 4, 17, 2, 82, 71, - 4, 128, 242, 15, 2, 79, 84, 147, 194, 19, 73, 4, 158, 164, 9, 84, 243, - 251, 25, 83, 4, 26, 65, 1, 2, 71, 79, 2, 239, 222, 17, 82, 6, 72, 6, 84, - 73, 75, 69, 78, 79, 161, 145, 35, 6, 65, 84, 82, 73, 67, 72, 4, 168, 32, - 2, 75, 89, 231, 143, 35, 77, 22, 52, 5, 69, 83, 79, 32, 69, 38, 79, 239, - 157, 35, 76, 4, 204, 1, 2, 88, 79, 147, 55, 75, 16, 80, 6, 83, 84, 82, + 4, 128, 230, 15, 2, 79, 84, 199, 189, 19, 73, 4, 234, 155, 9, 84, 219, + 243, 25, 83, 4, 26, 65, 1, 2, 71, 79, 2, 239, 210, 17, 82, 6, 72, 6, 84, + 73, 75, 69, 78, 79, 213, 128, 35, 6, 65, 84, 82, 73, 67, 72, 4, 168, 32, + 2, 75, 89, 155, 255, 34, 77, 22, 52, 5, 69, 83, 79, 32, 69, 38, 79, 163, + 141, 35, 76, 4, 204, 1, 2, 88, 79, 147, 55, 75, 16, 80, 6, 83, 84, 82, 79, 70, 79, 188, 40, 3, 68, 69, 82, 237, 129, 1, 2, 84, 72, 10, 24, 2, 73, 32, 79, 83, 4, 56, 9, 83, 89, 78, 68, 69, 83, 77, 79, 83, 195, 24, - 84, 2, 143, 44, 32, 7, 11, 32, 4, 214, 60, 68, 183, 166, 22, 78, 18, 48, - 2, 71, 79, 33, 6, 75, 84, 73, 75, 79, 32, 4, 170, 21, 83, 255, 153, 35, - 78, 14, 130, 216, 27, 86, 146, 184, 7, 90, 162, 8, 75, 254, 2, 68, 2, 78, + 84, 2, 143, 44, 32, 7, 11, 32, 4, 214, 60, 68, 235, 149, 22, 78, 18, 48, + 2, 71, 79, 33, 6, 75, 84, 73, 75, 79, 32, 4, 170, 21, 83, 179, 137, 35, + 78, 14, 182, 199, 27, 86, 146, 184, 7, 90, 162, 8, 75, 254, 2, 68, 2, 78, 162, 17, 71, 3, 80, 14, 80, 4, 82, 79, 65, 32, 168, 37, 4, 79, 82, 69, - 86, 221, 2, 4, 65, 77, 73, 76, 6, 132, 235, 19, 2, 83, 80, 232, 192, 3, - 3, 90, 89, 71, 205, 204, 10, 3, 75, 76, 73, 42, 50, 73, 244, 231, 8, 2, - 65, 83, 239, 165, 26, 89, 38, 122, 65, 200, 1, 5, 69, 83, 73, 83, 32, 70, - 71, 208, 1, 3, 80, 76, 73, 249, 208, 27, 8, 70, 84, 79, 71, 71, 79, 83, - 32, 10, 48, 6, 83, 84, 79, 76, 73, 32, 243, 240, 33, 82, 8, 80, 6, 65, - 80, 76, 73, 32, 77, 174, 55, 68, 185, 241, 22, 5, 84, 72, 69, 83, 69, 4, - 40, 2, 69, 71, 217, 190, 28, 2, 73, 75, 2, 195, 166, 30, 65, 12, 38, 84, + 86, 221, 2, 4, 65, 77, 73, 76, 6, 132, 223, 19, 2, 83, 80, 156, 188, 3, + 3, 90, 89, 71, 205, 204, 10, 3, 75, 76, 73, 42, 50, 73, 192, 223, 8, 2, + 65, 83, 215, 157, 26, 89, 38, 122, 65, 200, 1, 5, 69, 83, 73, 83, 32, 70, + 71, 208, 1, 3, 80, 76, 73, 173, 192, 27, 8, 70, 84, 79, 71, 71, 79, 83, + 32, 10, 48, 6, 83, 84, 79, 76, 73, 32, 167, 224, 33, 82, 8, 80, 6, 65, + 80, 76, 73, 32, 77, 174, 55, 68, 237, 224, 22, 5, 84, 72, 69, 83, 69, 4, + 40, 2, 69, 71, 141, 174, 28, 2, 73, 75, 2, 247, 149, 30, 65, 12, 38, 84, 246, 50, 65, 42, 68, 63, 77, 6, 194, 10, 69, 239, 41, 82, 10, 72, 5, 79, - 82, 71, 79, 78, 173, 168, 35, 7, 82, 65, 77, 77, 65, 32, 71, 9, 69, 15, + 82, 71, 79, 78, 225, 151, 35, 7, 82, 65, 77, 77, 65, 32, 71, 9, 69, 15, 32, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 78, 32, 6, 222, 38, 68, 137, 10, 8, 65, 82, 73, 83, 84, 69, 82, 65, 5, 175, 47, 32, 16, 166, - 1, 78, 116, 6, 84, 69, 82, 79, 78, 32, 188, 44, 4, 88, 79, 32, 69, 136, - 147, 33, 4, 80, 69, 71, 69, 236, 48, 6, 75, 83, 84, 82, 69, 80, 237, 13, - 3, 76, 65, 70, 4, 224, 22, 3, 68, 79, 70, 221, 184, 27, 18, 65, 82, 88, + 1, 78, 116, 6, 84, 69, 82, 79, 78, 32, 188, 44, 4, 88, 79, 32, 69, 188, + 130, 33, 4, 80, 69, 71, 69, 236, 48, 6, 75, 83, 84, 82, 69, 80, 237, 13, + 3, 76, 65, 70, 4, 224, 22, 3, 68, 79, 70, 145, 168, 27, 18, 65, 82, 88, 73, 83, 32, 75, 65, 73, 32, 70, 84, 72, 79, 82, 65, 32, 86, 4, 208, 11, 5, 65, 82, 71, 79, 83, 151, 20, 80, 44, 180, 1, 9, 65, 78, 69, 82, 79, 83, 73, 83, 32, 52, 6, 84, 72, 79, 82, 65, 32, 165, 6, 22, 72, 84, 79, @@ -1384,3129 +1384,3108 @@ static const unsigned char packed_name_dawg[] = { 82, 67, 72, 65, 73, 79, 78, 80, 10, 68, 73, 65, 84, 79, 78, 73, 75, 73, 32, 96, 11, 73, 32, 89, 70, 69, 83, 73, 83, 32, 84, 69, 32, 15, 77, 65, 76, 65, 75, 79, 78, 32, 67, 72, 82, 79, 77, 65, 32, 74, 78, 40, 8, 83, - 75, 76, 73, 82, 79, 78, 32, 157, 229, 18, 18, 69, 78, 65, 82, 77, 79, 78, + 75, 76, 73, 82, 79, 78, 32, 157, 217, 18, 18, 69, 78, 65, 82, 77, 79, 78, 73, 79, 83, 32, 65, 78, 84, 73, 70, 79, 78, 5, 57, 12, 32, 68, 69, 89, - 84, 69, 82, 79, 85, 32, 73, 67, 2, 147, 201, 27, 72, 14, 62, 78, 210, - 128, 35, 90, 162, 8, 75, 254, 2, 68, 163, 17, 80, 6, 242, 39, 73, 187, - 185, 33, 65, 2, 237, 42, 4, 84, 65, 82, 84, 4, 18, 68, 15, 77, 2, 35, 73, - 2, 21, 3, 79, 78, 79, 2, 151, 19, 70, 4, 166, 19, 65, 193, 128, 33, 2, - 69, 78, 6, 84, 7, 67, 72, 82, 79, 77, 65, 32, 193, 169, 17, 8, 68, 73, - 65, 84, 79, 78, 79, 78, 4, 42, 86, 169, 173, 17, 4, 83, 89, 78, 65, 2, - 251, 245, 32, 65, 22, 80, 6, 69, 78, 73, 75, 73, 32, 44, 2, 79, 82, 185, - 26, 5, 82, 79, 78, 84, 72, 4, 192, 149, 31, 2, 68, 73, 1, 2, 89, 70, 16, + 84, 69, 82, 79, 85, 32, 73, 67, 2, 199, 184, 27, 72, 14, 62, 78, 134, + 240, 34, 90, 162, 8, 75, 254, 2, 68, 163, 17, 80, 6, 242, 39, 73, 239, + 168, 33, 65, 2, 237, 42, 4, 84, 65, 82, 84, 4, 18, 68, 15, 77, 2, 35, 73, + 2, 21, 3, 79, 78, 79, 2, 151, 19, 70, 4, 166, 19, 65, 245, 239, 32, 2, + 69, 78, 6, 84, 7, 67, 72, 82, 79, 77, 65, 32, 193, 157, 17, 8, 68, 73, + 65, 84, 79, 78, 79, 78, 4, 42, 86, 169, 161, 17, 4, 83, 89, 78, 65, 2, + 175, 229, 32, 65, 22, 80, 6, 69, 78, 73, 75, 73, 32, 44, 2, 79, 82, 185, + 26, 5, 82, 79, 78, 84, 72, 4, 244, 132, 31, 2, 68, 73, 1, 2, 89, 70, 16, 68, 2, 71, 79, 225, 1, 10, 84, 72, 77, 73, 75, 79, 78, 32, 78, 32, 12, 28, 2, 78, 32, 155, 1, 83, 10, 96, 14, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 78, 32, 242, 33, 65, 113, 3, 78, 69, 79, 4, 214, 24, 68, - 229, 239, 32, 5, 65, 82, 73, 83, 84, 2, 217, 228, 33, 5, 89, 78, 84, 72, - 69, 4, 142, 28, 65, 1, 2, 68, 73, 16, 56, 2, 77, 73, 114, 83, 181, 152, + 153, 223, 32, 5, 65, 82, 73, 83, 84, 2, 141, 212, 33, 5, 89, 78, 84, 72, + 69, 4, 142, 28, 65, 1, 2, 68, 73, 16, 56, 2, 77, 73, 114, 83, 233, 135, 34, 4, 67, 72, 65, 68, 8, 34, 70, 169, 28, 3, 68, 73, 65, 6, 40, 4, 84, - 72, 79, 82, 251, 139, 34, 79, 4, 198, 200, 34, 79, 227, 79, 65, 6, 44, 6, - 65, 75, 73, 65, 32, 84, 231, 13, 79, 2, 165, 221, 21, 12, 69, 76, 79, 85, + 72, 79, 82, 175, 251, 33, 79, 4, 250, 183, 34, 79, 227, 79, 65, 6, 44, 6, + 65, 75, 73, 65, 32, 84, 231, 13, 79, 2, 217, 204, 21, 12, 69, 76, 79, 85, 83, 32, 73, 67, 72, 73, 77, 65, 54, 108, 2, 65, 84, 96, 6, 69, 78, 84, 73, 77, 65, 140, 1, 5, 76, 65, 83, 77, 65, 18, 79, 98, 82, 175, 1, 89, 6, 40, 3, 65, 86, 65, 201, 3, 2, 72, 73, 4, 140, 29, 5, 32, 84, 82, 79, 77, - 219, 215, 34, 83, 18, 24, 2, 84, 65, 15, 32, 11, 11, 32, 8, 36, 4, 78, - 69, 79, 32, 183, 28, 65, 6, 208, 166, 28, 2, 77, 69, 170, 222, 2, 75, - 235, 230, 3, 65, 7, 243, 28, 32, 8, 64, 6, 78, 84, 69, 86, 77, 65, 146, - 225, 8, 82, 163, 145, 26, 85, 5, 145, 181, 14, 2, 32, 65, 14, 44, 4, 65, - 84, 73, 77, 105, 3, 69, 77, 65, 12, 18, 65, 35, 79, 8, 182, 23, 32, 151, - 249, 34, 84, 4, 134, 12, 75, 181, 220, 31, 5, 89, 80, 79, 82, 82, 2, 175, - 166, 27, 83, 2, 243, 240, 34, 76, 14, 22, 69, 147, 22, 89, 12, 44, 5, 73, - 77, 77, 65, 32, 191, 154, 30, 77, 10, 72, 2, 69, 78, 0, 5, 73, 77, 73, - 83, 69, 54, 84, 69, 3, 68, 89, 79, 2, 237, 185, 27, 8, 79, 83, 32, 67, + 143, 199, 34, 83, 18, 24, 2, 84, 65, 15, 32, 11, 11, 32, 8, 36, 4, 78, + 69, 79, 32, 183, 28, 65, 6, 132, 150, 28, 2, 77, 69, 170, 222, 2, 75, + 235, 230, 3, 65, 7, 243, 28, 32, 8, 64, 6, 78, 84, 69, 86, 77, 65, 222, + 216, 8, 82, 139, 137, 26, 85, 5, 145, 169, 14, 2, 32, 65, 14, 44, 4, 65, + 84, 73, 77, 105, 3, 69, 77, 65, 12, 18, 65, 35, 79, 8, 182, 23, 32, 203, + 232, 34, 84, 4, 134, 12, 75, 233, 203, 31, 5, 89, 80, 79, 82, 82, 2, 227, + 149, 27, 83, 2, 167, 224, 34, 76, 14, 22, 69, 147, 22, 89, 12, 44, 5, 73, + 77, 77, 65, 32, 243, 137, 30, 77, 10, 72, 2, 69, 78, 0, 5, 73, 77, 73, + 83, 69, 54, 84, 69, 3, 68, 89, 79, 2, 161, 169, 27, 8, 79, 83, 32, 67, 72, 82, 79, 78, 4, 44, 5, 69, 83, 83, 65, 82, 1, 2, 82, 73, 2, 17, 2, 79, - 78, 2, 25, 4, 32, 67, 72, 82, 2, 175, 131, 34, 79, 28, 84, 8, 65, 82, 84, - 89, 82, 73, 65, 32, 229, 138, 31, 7, 73, 75, 82, 79, 78, 32, 73, 26, 72, + 78, 2, 25, 4, 32, 67, 72, 82, 2, 227, 242, 33, 79, 28, 84, 8, 65, 82, 84, + 89, 82, 73, 65, 32, 153, 250, 30, 7, 73, 75, 82, 79, 78, 32, 73, 26, 72, 5, 65, 76, 76, 73, 32, 38, 68, 38, 80, 134, 1, 86, 30, 84, 87, 76, 4, 34, 68, 177, 2, 3, 80, 82, 79, 2, 237, 2, 5, 69, 89, 84, 69, 82, 8, 60, 7, 76, 65, 71, 73, 79, 83, 32, 45, 4, 82, 79, 84, 79, 4, 200, 1, 5, 84, 69, 84, 65, 82, 111, 73, 4, 22, 86, 227, 1, 83, 2, 209, 1, 3, 65, 82, 89, 8, 56, 8, 69, 84, 65, 82, 84, 79, 83, 32, 61, 2, 82, 73, 4, 22, 76, 135, 1, - 73, 2, 21, 3, 69, 71, 69, 2, 63, 84, 4, 18, 70, 35, 84, 2, 221, 217, 21, - 3, 79, 78, 73, 2, 11, 79, 2, 11, 83, 2, 17, 2, 32, 73, 2, 199, 132, 23, + 73, 2, 21, 3, 69, 71, 69, 2, 63, 84, 4, 18, 70, 35, 84, 2, 145, 201, 21, + 3, 79, 78, 73, 2, 11, 79, 2, 11, 83, 2, 17, 2, 32, 73, 2, 251, 243, 22, 67, 18, 92, 4, 76, 73, 71, 79, 180, 1, 5, 89, 82, 65, 78, 73, 210, 14, - 88, 249, 169, 34, 2, 77, 65, 4, 211, 1, 78, 42, 60, 2, 65, 82, 100, 2, - 73, 65, 90, 69, 169, 1, 2, 83, 73, 12, 40, 2, 65, 75, 161, 190, 17, 2, + 88, 173, 153, 34, 2, 77, 65, 4, 211, 1, 78, 42, 60, 2, 65, 82, 100, 2, + 73, 65, 90, 69, 169, 1, 2, 83, 73, 12, 40, 2, 65, 75, 161, 178, 17, 2, 73, 67, 10, 52, 3, 65, 76, 69, 45, 6, 76, 73, 84, 73, 75, 73, 4, 11, 83, - 4, 17, 2, 77, 65, 4, 23, 32, 7, 11, 32, 4, 198, 15, 65, 211, 171, 22, 78, - 12, 72, 3, 84, 65, 83, 136, 3, 6, 76, 65, 83, 84, 79, 78, 135, 229, 8, - 82, 6, 26, 84, 203, 132, 35, 77, 4, 32, 2, 79, 75, 223, 134, 35, 73, 2, - 165, 229, 34, 2, 79, 85, 14, 36, 5, 70, 73, 83, 84, 79, 67, 76, 10, 46, - 80, 214, 1, 78, 170, 8, 76, 187, 1, 83, 2, 135, 11, 65, 4, 246, 181, 34, - 79, 227, 79, 73, 4, 178, 5, 69, 221, 222, 34, 2, 65, 80, 42, 120, 5, 69, + 4, 17, 2, 77, 65, 4, 23, 32, 7, 11, 32, 4, 198, 15, 65, 135, 155, 22, 78, + 12, 72, 3, 84, 65, 83, 136, 3, 6, 76, 65, 83, 84, 79, 78, 211, 220, 8, + 82, 6, 26, 84, 255, 243, 34, 77, 4, 32, 2, 79, 75, 147, 246, 34, 73, 2, + 217, 212, 34, 2, 79, 85, 14, 36, 5, 70, 73, 83, 84, 79, 67, 76, 10, 46, + 80, 214, 1, 78, 170, 8, 76, 187, 1, 83, 2, 135, 11, 65, 4, 170, 165, 34, + 79, 227, 79, 73, 4, 178, 5, 69, 145, 206, 34, 2, 65, 80, 42, 120, 5, 69, 73, 83, 77, 65, 32, 8, 73, 77, 65, 78, 83, 73, 83, 32, 182, 1, 84, 154, - 1, 89, 229, 243, 1, 3, 65, 88, 73, 5, 11, 32, 2, 151, 183, 22, 78, 16, + 1, 89, 229, 239, 1, 3, 65, 88, 73, 5, 11, 32, 2, 203, 166, 22, 78, 16, 36, 2, 65, 82, 1, 3, 84, 72, 69, 8, 25, 4, 83, 69, 79, 83, 9, 11, 32, 6, - 18, 84, 39, 68, 4, 34, 82, 13, 4, 69, 84, 82, 65, 2, 11, 73, 2, 217, 171, + 18, 84, 39, 68, 4, 34, 82, 13, 4, 69, 84, 82, 65, 2, 11, 73, 2, 141, 155, 27, 3, 83, 73, 77, 8, 68, 5, 65, 86, 82, 79, 83, 52, 4, 82, 65, 71, 71, - 251, 218, 16, 73, 5, 29, 5, 32, 65, 80, 79, 68, 2, 199, 232, 8, 69, 2, - 253, 243, 1, 2, 73, 83, 12, 34, 78, 149, 1, 3, 82, 77, 65, 8, 36, 5, 65, - 71, 77, 65, 32, 91, 69, 6, 154, 8, 65, 210, 171, 22, 78, 237, 245, 4, 10, - 77, 69, 84, 65, 32, 83, 84, 65, 86, 82, 2, 243, 222, 34, 86, 5, 11, 84, - 2, 243, 137, 17, 73, 40, 42, 69, 70, 72, 218, 1, 82, 227, 2, 73, 6, 136, - 12, 3, 84, 82, 65, 186, 174, 8, 76, 237, 178, 24, 2, 83, 83, 12, 26, 69, - 251, 217, 34, 73, 10, 64, 2, 77, 65, 217, 231, 33, 8, 83, 32, 75, 65, 73, + 251, 206, 16, 73, 5, 29, 5, 32, 65, 80, 79, 68, 2, 147, 224, 8, 69, 2, + 253, 239, 1, 2, 73, 83, 12, 34, 78, 149, 1, 3, 82, 77, 65, 8, 36, 5, 65, + 71, 77, 65, 32, 91, 69, 6, 154, 8, 65, 134, 155, 22, 78, 237, 245, 4, 10, + 77, 69, 84, 65, 32, 83, 84, 65, 86, 82, 2, 167, 206, 34, 86, 5, 11, 84, + 2, 243, 253, 16, 73, 40, 42, 69, 70, 72, 218, 1, 82, 227, 2, 73, 6, 136, + 12, 3, 84, 82, 65, 134, 166, 8, 76, 213, 170, 24, 2, 83, 83, 12, 26, 69, + 175, 201, 34, 73, 10, 64, 2, 77, 65, 141, 215, 33, 8, 83, 32, 75, 65, 73, 32, 65, 80, 9, 56, 2, 32, 65, 33, 8, 84, 73, 83, 77, 79, 83, 32, 69, 2, - 145, 253, 33, 3, 80, 76, 79, 4, 174, 222, 34, 83, 3, 88, 20, 38, 73, 73, - 5, 79, 77, 73, 75, 79, 6, 48, 2, 71, 79, 206, 248, 29, 80, 227, 131, 5, - 65, 2, 247, 193, 33, 82, 14, 42, 76, 32, 2, 78, 32, 62, 80, 95, 83, 2, - 11, 89, 2, 183, 218, 34, 71, 6, 26, 65, 195, 174, 22, 78, 4, 250, 2, 82, - 231, 213, 34, 76, 4, 46, 65, 193, 197, 33, 5, 83, 73, 70, 73, 83, 2, 193, - 217, 34, 6, 82, 65, 75, 65, 76, 69, 2, 11, 89, 2, 217, 211, 16, 2, 78, - 65, 10, 26, 82, 175, 216, 34, 84, 8, 21, 3, 69, 73, 65, 8, 26, 32, 113, - 2, 73, 32, 6, 38, 69, 242, 5, 68, 183, 166, 22, 78, 2, 11, 75, 2, 29, 5, - 70, 79, 78, 73, 84, 2, 249, 168, 34, 2, 73, 75, 2, 11, 65, 2, 11, 82, 2, - 237, 167, 34, 3, 67, 72, 65, 22, 28, 2, 70, 69, 231, 3, 80, 14, 34, 78, - 49, 4, 83, 73, 83, 32, 4, 11, 32, 4, 202, 231, 30, 75, 235, 230, 3, 65, + 197, 236, 33, 3, 80, 76, 79, 4, 226, 205, 34, 83, 3, 88, 20, 38, 73, 73, + 5, 79, 77, 73, 75, 79, 6, 48, 2, 71, 79, 130, 232, 29, 80, 227, 131, 5, + 65, 2, 171, 177, 33, 82, 14, 42, 76, 32, 2, 78, 32, 62, 80, 95, 83, 2, + 11, 89, 2, 235, 201, 34, 71, 6, 26, 65, 247, 157, 22, 78, 4, 250, 2, 82, + 155, 197, 34, 76, 4, 46, 65, 245, 180, 33, 5, 83, 73, 70, 73, 83, 2, 245, + 200, 34, 6, 82, 65, 75, 65, 76, 69, 2, 11, 89, 2, 217, 199, 16, 2, 78, + 65, 10, 26, 82, 227, 199, 34, 84, 8, 21, 3, 69, 73, 65, 8, 26, 32, 113, + 2, 73, 32, 6, 38, 69, 242, 5, 68, 235, 149, 22, 78, 2, 11, 75, 2, 29, 5, + 70, 79, 78, 73, 84, 2, 173, 152, 34, 2, 73, 75, 2, 11, 65, 2, 11, 82, 2, + 161, 151, 34, 3, 67, 72, 65, 22, 28, 2, 70, 69, 231, 3, 80, 14, 34, 78, + 49, 4, 83, 73, 83, 32, 4, 11, 32, 4, 254, 214, 30, 75, 235, 230, 3, 65, 10, 42, 65, 42, 68, 62, 77, 89, 2, 84, 82, 2, 133, 2, 6, 80, 76, 73, 32, 68, 89, 2, 233, 1, 11, 73, 71, 82, 65, 77, 77, 79, 83, 32, 69, 88, 2, 173, 1, 18, 79, 78, 79, 71, 82, 65, 77, 77, 79, 83, 32, 84, 69, 83, 83, 69, 82, 65, 4, 11, 73, 4, 60, 11, 71, 82, 65, 77, 77, 79, 83, 32, 79, 75, - 84, 59, 84, 2, 11, 79, 2, 153, 180, 2, 6, 32, 68, 79, 68, 69, 75, 2, 237, - 163, 34, 4, 73, 77, 79, 82, 8, 26, 79, 139, 240, 29, 83, 6, 56, 6, 75, - 82, 73, 83, 73, 83, 181, 252, 29, 2, 82, 82, 5, 17, 2, 32, 68, 2, 11, 73, - 2, 183, 239, 29, 80, 232, 82, 182, 1, 65, 250, 71, 69, 230, 1, 72, 222, - 32, 73, 208, 41, 3, 74, 75, 32, 138, 26, 76, 186, 18, 79, 238, 117, 82, - 234, 7, 85, 150, 128, 2, 89, 134, 180, 19, 71, 190, 235, 10, 83, 203, 18, + 84, 59, 84, 2, 11, 79, 2, 153, 176, 2, 6, 32, 68, 79, 68, 69, 75, 2, 161, + 147, 34, 4, 73, 77, 79, 82, 8, 26, 79, 191, 223, 29, 83, 6, 56, 6, 75, + 82, 73, 83, 73, 83, 233, 235, 29, 2, 82, 82, 5, 17, 2, 32, 68, 2, 11, 73, + 2, 235, 222, 29, 80, 252, 66, 182, 1, 65, 250, 71, 69, 230, 1, 72, 222, + 32, 73, 208, 41, 3, 74, 75, 32, 138, 22, 76, 186, 18, 79, 238, 117, 82, + 234, 7, 85, 150, 128, 2, 89, 186, 167, 19, 71, 190, 235, 10, 83, 203, 18, 67, 198, 13, 110, 68, 58, 76, 50, 77, 90, 78, 174, 51, 80, 62, 82, 198, - 7, 84, 138, 1, 85, 162, 185, 18, 67, 227, 208, 6, 83, 4, 34, 85, 205, - 164, 27, 2, 65, 32, 2, 147, 229, 7, 67, 4, 248, 219, 9, 3, 76, 32, 77, - 231, 218, 19, 69, 6, 36, 3, 69, 82, 65, 195, 158, 34, 80, 5, 237, 202, + 7, 84, 138, 1, 85, 162, 173, 18, 67, 151, 204, 6, 83, 4, 34, 85, 129, + 148, 27, 2, 65, 32, 2, 223, 220, 7, 67, 4, 196, 211, 9, 3, 76, 32, 77, + 207, 210, 19, 69, 6, 36, 3, 69, 82, 65, 247, 141, 34, 80, 5, 161, 186, 27, 7, 32, 87, 73, 84, 72, 32, 70, 193, 11, 148, 1, 16, 65, 68, 73, 65, 78, 32, 83, 89, 76, 76, 65, 66, 73, 67, 83, 32, 148, 49, 2, 67, 69, 94, - 68, 140, 249, 23, 3, 78, 69, 68, 171, 172, 10, 79, 172, 11, 226, 1, 65, + 68, 192, 232, 23, 3, 78, 69, 68, 171, 172, 10, 79, 172, 11, 226, 1, 65, 190, 1, 66, 162, 2, 67, 242, 8, 69, 50, 70, 198, 4, 72, 38, 73, 30, 75, 134, 1, 76, 82, 77, 174, 1, 78, 202, 4, 81, 178, 1, 79, 194, 1, 80, 70, - 82, 142, 1, 83, 194, 4, 84, 246, 3, 87, 254, 5, 89, 143, 225, 17, 71, 21, - 90, 65, 30, 73, 40, 10, 84, 72, 65, 80, 65, 83, 67, 65, 78, 32, 242, 234, - 34, 78, 3, 89, 7, 178, 235, 34, 73, 3, 89, 5, 169, 242, 23, 5, 86, 73, - 76, 73, 75, 4, 238, 234, 34, 77, 3, 83, 42, 156, 1, 9, 76, 65, 67, 75, - 70, 79, 79, 84, 32, 212, 171, 19, 9, 73, 66, 76, 69, 45, 67, 82, 69, 69, - 137, 208, 7, 10, 69, 65, 86, 69, 82, 32, 68, 69, 78, 69, 36, 82, 87, 162, - 242, 11, 75, 2, 78, 194, 246, 22, 65, 2, 69, 2, 73, 2, 79, 3, 83, 11, - 222, 232, 34, 65, 2, 69, 2, 73, 3, 79, 141, 3, 82, 65, 186, 42, 87, 222, - 181, 8, 72, 154, 190, 23, 79, 238, 60, 73, 199, 140, 2, 69, 241, 2, 48, - 6, 82, 82, 73, 69, 82, 32, 227, 218, 32, 65, 234, 2, 170, 1, 68, 122, 71, + 82, 142, 1, 83, 194, 4, 84, 246, 3, 87, 254, 5, 89, 143, 213, 17, 71, 21, + 90, 65, 30, 73, 40, 10, 84, 72, 65, 80, 65, 83, 67, 65, 78, 32, 166, 218, + 34, 78, 3, 89, 7, 230, 218, 34, 73, 3, 89, 5, 221, 225, 23, 5, 86, 73, + 76, 73, 75, 4, 162, 218, 34, 77, 3, 83, 42, 156, 1, 9, 76, 65, 67, 75, + 70, 79, 79, 84, 32, 212, 159, 19, 9, 73, 66, 76, 69, 45, 67, 82, 69, 69, + 189, 203, 7, 10, 69, 65, 86, 69, 82, 32, 68, 69, 78, 69, 36, 82, 87, 238, + 233, 11, 75, 2, 78, 170, 238, 22, 65, 2, 69, 2, 73, 2, 79, 3, 83, 11, + 146, 216, 34, 65, 2, 69, 2, 73, 3, 79, 141, 3, 82, 65, 186, 42, 87, 170, + 173, 8, 72, 130, 182, 23, 79, 238, 60, 73, 199, 140, 2, 69, 241, 2, 48, + 6, 82, 82, 73, 69, 82, 32, 151, 202, 32, 65, 234, 2, 170, 1, 68, 122, 71, 94, 72, 46, 73, 46, 74, 82, 75, 30, 78, 66, 83, 66, 80, 2, 90, 58, 84, - 38, 76, 132, 1, 2, 67, 72, 2, 77, 2, 82, 2, 87, 2, 89, 171, 201, 34, 69, - 32, 46, 69, 202, 5, 76, 2, 90, 255, 223, 34, 73, 6, 26, 78, 171, 229, 34, - 69, 4, 134, 154, 17, 69, 249, 211, 6, 2, 84, 65, 30, 254, 4, 72, 202, - 186, 21, 87, 198, 147, 9, 65, 210, 209, 3, 69, 162, 64, 73, 2, 79, 3, 85, - 19, 162, 4, 87, 170, 201, 34, 69, 215, 22, 73, 5, 197, 150, 14, 6, 78, - 73, 84, 73, 65, 76, 26, 202, 3, 74, 222, 159, 34, 69, 234, 61, 87, 186, - 2, 65, 2, 73, 2, 79, 3, 85, 26, 154, 1, 75, 227, 1, 72, 14, 186, 162, 34, - 69, 162, 64, 65, 2, 71, 2, 73, 2, 79, 3, 85, 26, 62, 72, 190, 161, 34, - 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 15, 186, 161, 34, 69, 162, 64, 65, + 38, 76, 132, 1, 2, 67, 72, 2, 77, 2, 82, 2, 87, 2, 89, 223, 184, 34, 69, + 32, 46, 69, 202, 5, 76, 2, 90, 179, 207, 34, 73, 6, 26, 78, 223, 212, 34, + 69, 4, 134, 142, 17, 69, 173, 207, 6, 2, 84, 65, 30, 254, 4, 72, 254, + 169, 21, 87, 198, 147, 9, 65, 210, 209, 3, 69, 162, 64, 73, 2, 79, 3, 85, + 19, 162, 4, 87, 222, 184, 34, 69, 215, 22, 73, 5, 197, 138, 14, 6, 78, + 73, 84, 73, 65, 76, 26, 202, 3, 74, 146, 143, 34, 69, 234, 61, 87, 186, + 2, 65, 2, 73, 2, 79, 3, 85, 26, 154, 1, 75, 227, 1, 72, 14, 238, 145, 34, + 69, 162, 64, 65, 2, 71, 2, 73, 2, 79, 3, 85, 26, 62, 72, 242, 144, 34, + 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 15, 238, 144, 34, 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 72, 34, 76, 70, 84, 66, 72, 3, 83, 24, 130, 1, 72, - 222, 159, 34, 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 24, 62, 83, 222, 159, - 34, 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 12, 218, 159, 34, 69, 162, 64, - 65, 2, 73, 2, 79, 3, 85, 7, 236, 29, 4, 65, 83, 84, 69, 215, 193, 34, 78, - 51, 74, 65, 22, 73, 142, 137, 32, 85, 250, 11, 79, 254, 83, 87, 183, 245, - 1, 69, 7, 131, 210, 32, 65, 33, 40, 4, 78, 65, 76, 32, 139, 222, 34, 73, - 28, 160, 1, 2, 68, 79, 134, 1, 82, 78, 83, 138, 148, 14, 71, 186, 2, 65, - 180, 182, 3, 6, 66, 79, 84, 84, 79, 77, 0, 3, 84, 79, 80, 150, 131, 13, - 80, 175, 247, 2, 77, 6, 44, 5, 85, 66, 76, 69, 32, 235, 184, 24, 87, 4, - 164, 205, 6, 12, 83, 72, 79, 82, 84, 32, 86, 69, 82, 84, 73, 67, 187, - 202, 7, 65, 6, 38, 73, 149, 141, 33, 3, 65, 73, 83, 4, 254, 204, 17, 71, - 231, 141, 17, 78, 4, 240, 171, 25, 4, 77, 65, 76, 76, 133, 135, 7, 4, 72, - 79, 82, 84, 4, 234, 201, 26, 89, 231, 144, 8, 75, 7, 170, 218, 34, 73, 3, - 78, 39, 66, 87, 234, 27, 65, 182, 244, 31, 79, 238, 60, 73, 199, 140, 2, - 69, 19, 210, 156, 12, 65, 202, 243, 19, 79, 238, 60, 73, 199, 140, 2, 69, - 49, 142, 7, 72, 154, 20, 65, 66, 87, 246, 243, 31, 79, 238, 60, 73, 199, - 140, 2, 69, 43, 70, 69, 38, 79, 238, 25, 65, 66, 87, 226, 176, 32, 73, - 199, 140, 2, 72, 7, 153, 234, 26, 4, 68, 73, 65, 76, 7, 11, 79, 5, 193, - 144, 33, 8, 83, 69, 45, 67, 82, 69, 69, 32, 149, 1, 164, 1, 8, 45, 67, + 146, 143, 34, 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 24, 62, 83, 146, 143, + 34, 69, 162, 64, 65, 2, 73, 2, 79, 3, 85, 12, 142, 143, 34, 69, 162, 64, + 65, 2, 73, 2, 79, 3, 85, 7, 236, 29, 4, 65, 83, 84, 69, 139, 177, 34, 78, + 51, 74, 65, 22, 73, 194, 248, 31, 85, 250, 11, 79, 254, 83, 87, 183, 245, + 1, 69, 7, 183, 193, 32, 65, 33, 40, 4, 78, 65, 76, 32, 191, 205, 34, 73, + 28, 160, 1, 2, 68, 79, 134, 1, 82, 78, 83, 138, 136, 14, 71, 186, 2, 65, + 180, 182, 3, 6, 66, 79, 84, 84, 79, 77, 0, 3, 84, 79, 80, 202, 254, 12, + 80, 175, 247, 2, 77, 6, 44, 5, 85, 66, 76, 69, 32, 159, 168, 24, 87, 4, + 240, 196, 6, 12, 83, 72, 79, 82, 84, 32, 86, 69, 82, 84, 73, 67, 239, + 198, 7, 65, 6, 38, 73, 201, 252, 32, 3, 65, 73, 83, 4, 254, 192, 17, 71, + 155, 137, 17, 78, 4, 164, 155, 25, 4, 77, 65, 76, 76, 133, 135, 7, 4, 72, + 79, 82, 84, 4, 158, 185, 26, 89, 231, 144, 8, 75, 7, 222, 201, 34, 73, 3, + 78, 39, 66, 87, 234, 27, 65, 234, 227, 31, 79, 238, 60, 73, 199, 140, 2, + 69, 19, 210, 144, 12, 65, 254, 238, 19, 79, 238, 60, 73, 199, 140, 2, 69, + 49, 142, 7, 72, 154, 20, 65, 66, 87, 170, 227, 31, 79, 238, 60, 73, 199, + 140, 2, 69, 43, 70, 69, 38, 79, 238, 25, 65, 66, 87, 150, 160, 32, 73, + 199, 140, 2, 72, 7, 205, 217, 26, 4, 68, 73, 65, 76, 7, 11, 79, 5, 245, + 255, 32, 8, 83, 69, 45, 67, 82, 69, 69, 32, 149, 1, 164, 1, 8, 45, 67, 82, 69, 69, 32, 84, 72, 38, 65, 250, 2, 71, 76, 2, 78, 71, 48, 4, 85, 78, - 65, 86, 142, 20, 79, 30, 87, 226, 176, 32, 73, 198, 140, 2, 69, 3, 72, 6, - 158, 201, 32, 73, 199, 140, 2, 69, 63, 104, 6, 83, 75, 65, 80, 73, 32, - 188, 1, 7, 84, 84, 73, 76, 73, 75, 32, 214, 198, 32, 65, 199, 140, 2, 89, + 65, 86, 142, 20, 79, 30, 87, 150, 160, 32, 73, 198, 140, 2, 69, 3, 72, 6, + 210, 184, 32, 73, 199, 140, 2, 69, 63, 104, 6, 83, 75, 65, 80, 73, 32, + 188, 1, 7, 84, 84, 73, 76, 73, 75, 32, 138, 182, 32, 65, 199, 140, 2, 89, 30, 70, 83, 86, 87, 210, 17, 67, 2, 75, 2, 77, 2, 78, 2, 84, 3, 89, 14, - 174, 218, 29, 67, 2, 80, 2, 84, 236, 103, 2, 75, 87, 190, 156, 2, 87, - 151, 119, 45, 4, 194, 180, 34, 79, 191, 28, 65, 24, 30, 72, 1, 3, 83, 72, - 82, 12, 134, 193, 30, 65, 194, 200, 1, 79, 239, 60, 73, 19, 38, 65, 242, - 136, 32, 79, 239, 60, 73, 9, 218, 197, 32, 65, 199, 140, 2, 73, 15, 138, - 192, 30, 65, 194, 200, 1, 79, 239, 60, 73, 18, 224, 9, 3, 73, 75, 32, - 185, 207, 23, 2, 85, 84, 33, 68, 7, 74, 73, 66, 87, 65, 89, 32, 210, 208, - 34, 78, 2, 79, 3, 89, 24, 74, 78, 166, 191, 30, 83, 226, 144, 4, 67, 2, - 75, 2, 77, 2, 80, 3, 84, 11, 11, 87, 8, 198, 134, 32, 79, 239, 60, 73, - 39, 206, 4, 87, 166, 13, 65, 38, 79, 254, 176, 32, 73, 199, 140, 2, 69, - 39, 104, 7, 45, 67, 82, 69, 69, 32, 82, 146, 14, 87, 182, 2, 65, 182, - 244, 31, 79, 238, 60, 73, 199, 140, 2, 69, 4, 210, 183, 34, 87, 215, 22, - 69, 125, 94, 65, 218, 1, 72, 138, 1, 79, 238, 2, 87, 158, 209, 11, 80, - 254, 233, 20, 73, 199, 140, 2, 69, 43, 26, 89, 203, 192, 32, 65, 37, 25, - 4, 73, 83, 73, 32, 34, 70, 72, 54, 74, 218, 4, 83, 198, 179, 34, 89, 202, - 18, 84, 147, 1, 77, 10, 246, 130, 32, 79, 178, 201, 2, 65, 2, 69, 3, 73, - 6, 246, 244, 30, 85, 255, 214, 3, 73, 37, 70, 87, 202, 13, 79, 202, 128, - 12, 65, 182, 176, 20, 73, 199, 140, 2, 69, 16, 198, 13, 79, 210, 171, 30, + 226, 201, 29, 67, 2, 80, 2, 84, 236, 103, 2, 75, 87, 190, 156, 2, 87, + 151, 119, 45, 4, 246, 163, 34, 79, 191, 28, 65, 24, 30, 72, 1, 3, 83, 72, + 82, 12, 186, 176, 30, 65, 194, 200, 1, 79, 239, 60, 73, 19, 38, 65, 166, + 248, 31, 79, 239, 60, 73, 9, 142, 181, 32, 65, 199, 140, 2, 73, 15, 190, + 175, 30, 65, 194, 200, 1, 79, 239, 60, 73, 18, 224, 9, 3, 73, 75, 32, + 237, 190, 23, 2, 85, 84, 33, 68, 7, 74, 73, 66, 87, 65, 89, 32, 134, 192, + 34, 78, 2, 79, 3, 89, 24, 74, 78, 218, 174, 30, 83, 226, 144, 4, 67, 2, + 75, 2, 77, 2, 80, 3, 84, 11, 11, 87, 8, 250, 245, 31, 79, 239, 60, 73, + 39, 206, 4, 87, 166, 13, 65, 38, 79, 178, 160, 32, 73, 199, 140, 2, 69, + 39, 104, 7, 45, 67, 82, 69, 69, 32, 82, 146, 14, 87, 182, 2, 65, 234, + 227, 31, 79, 238, 60, 73, 199, 140, 2, 69, 4, 134, 167, 34, 87, 215, 22, + 69, 125, 94, 65, 218, 1, 72, 138, 1, 79, 238, 2, 87, 234, 200, 11, 80, + 230, 225, 20, 73, 199, 140, 2, 69, 43, 26, 89, 255, 175, 32, 65, 37, 25, + 4, 73, 83, 73, 32, 34, 70, 72, 54, 74, 218, 4, 83, 250, 162, 34, 89, 202, + 18, 84, 147, 1, 77, 10, 170, 242, 31, 79, 178, 201, 2, 65, 2, 69, 3, 73, + 6, 170, 228, 30, 85, 255, 214, 3, 73, 37, 70, 87, 202, 13, 79, 202, 244, + 11, 65, 234, 171, 20, 73, 199, 140, 2, 69, 16, 198, 13, 79, 134, 155, 30, 65, 174, 133, 2, 73, 199, 140, 2, 69, 15, 80, 12, 85, 84, 72, 45, 83, 76, - 65, 86, 69, 89, 32, 75, 246, 201, 34, 79, 3, 89, 8, 226, 200, 34, 65, 2, + 65, 86, 69, 89, 32, 75, 170, 185, 34, 79, 3, 89, 8, 150, 184, 34, 65, 2, 69, 2, 73, 3, 79, 117, 110, 72, 190, 1, 76, 78, 84, 238, 8, 65, 66, 87, - 230, 198, 11, 89, 146, 173, 20, 79, 238, 60, 73, 199, 140, 2, 69, 39, - 108, 7, 45, 67, 82, 69, 69, 32, 84, 226, 4, 87, 154, 177, 30, 65, 194, - 200, 1, 79, 238, 60, 73, 199, 140, 2, 69, 16, 11, 72, 17, 234, 181, 30, - 65, 194, 200, 1, 79, 238, 60, 73, 199, 140, 2, 69, 12, 11, 72, 12, 222, - 253, 31, 79, 222, 178, 2, 87, 214, 22, 65, 2, 69, 3, 73, 24, 50, 72, 158, - 198, 34, 65, 2, 69, 2, 73, 3, 79, 17, 170, 180, 30, 65, 194, 200, 1, 79, + 178, 190, 11, 89, 250, 164, 20, 79, 238, 60, 73, 199, 140, 2, 69, 39, + 108, 7, 45, 67, 82, 69, 69, 32, 84, 226, 4, 87, 206, 160, 30, 65, 194, + 200, 1, 79, 238, 60, 73, 199, 140, 2, 69, 16, 11, 72, 17, 158, 165, 30, + 65, 194, 200, 1, 79, 238, 60, 73, 199, 140, 2, 69, 12, 11, 72, 12, 146, + 237, 31, 79, 222, 178, 2, 87, 214, 22, 65, 2, 69, 3, 73, 24, 50, 72, 210, + 181, 34, 65, 2, 69, 2, 73, 3, 79, 17, 222, 163, 30, 65, 194, 200, 1, 79, 222, 178, 2, 87, 214, 22, 69, 3, 73, 224, 1, 54, 69, 218, 3, 79, 202, - 132, 12, 65, 183, 176, 20, 73, 185, 1, 17, 2, 83, 84, 182, 1, 44, 6, 45, + 248, 11, 65, 235, 171, 20, 73, 185, 1, 17, 2, 83, 84, 182, 1, 44, 6, 45, 67, 82, 69, 69, 32, 251, 2, 69, 180, 1, 110, 76, 66, 77, 2, 80, 2, 89, 16, 2, 78, 87, 38, 82, 62, 83, 26, 67, 2, 75, 18, 84, 26, 70, 199, 4, 87, - 27, 178, 6, 87, 182, 171, 30, 65, 194, 200, 1, 79, 179, 201, 2, 69, 17, - 243, 5, 87, 6, 150, 177, 30, 65, 243, 145, 4, 69, 13, 174, 205, 32, 87, + 27, 178, 6, 87, 234, 154, 30, 65, 194, 200, 1, 79, 179, 201, 2, 69, 17, + 243, 5, 87, 6, 202, 160, 30, 65, 243, 145, 4, 69, 13, 226, 188, 32, 87, 182, 245, 1, 65, 2, 69, 2, 73, 3, 79, 28, 22, 72, 239, 4, 87, 14, 235, 4, - 87, 16, 22, 72, 199, 4, 87, 2, 179, 204, 32, 87, 2, 171, 204, 23, 82, 31, + 87, 16, 22, 72, 199, 4, 87, 2, 231, 187, 32, 87, 2, 223, 187, 23, 82, 31, 11, 79, 29, 41, 8, 68, 83, 45, 67, 82, 69, 69, 32, 26, 56, 2, 84, 72, - 213, 187, 32, 6, 70, 73, 78, 65, 76, 32, 25, 50, 87, 154, 192, 34, 65, 2, - 69, 2, 73, 3, 79, 14, 166, 174, 30, 65, 194, 200, 1, 79, 238, 60, 73, + 137, 171, 32, 6, 70, 73, 78, 65, 76, 32, 25, 50, 87, 206, 175, 34, 65, 2, + 69, 2, 73, 3, 79, 14, 218, 157, 30, 65, 194, 200, 1, 79, 238, 60, 73, 243, 245, 1, 69, 61, 92, 6, 45, 67, 82, 69, 69, 32, 150, 1, 65, 38, 79, - 30, 87, 226, 176, 32, 73, 199, 140, 2, 69, 24, 110, 80, 146, 243, 31, 67, + 30, 87, 150, 160, 32, 73, 199, 140, 2, 69, 24, 110, 80, 198, 226, 31, 67, 2, 75, 2, 76, 2, 77, 2, 78, 2, 83, 2, 84, 2, 89, 134, 172, 2, 79, 247, - 30, 87, 4, 210, 200, 32, 87, 195, 214, 1, 79, 9, 158, 177, 32, 65, 199, - 140, 2, 89, 7, 190, 189, 34, 79, 3, 89, 14, 178, 171, 30, 65, 194, 200, - 1, 79, 238, 60, 73, 199, 140, 2, 69, 10, 26, 76, 203, 188, 34, 82, 9, 26, - 32, 231, 193, 9, 76, 4, 218, 171, 22, 67, 231, 164, 10, 84, 4, 178, 165, - 34, 76, 215, 22, 89, 4, 180, 191, 15, 3, 73, 84, 85, 161, 134, 8, 3, 82, + 30, 87, 4, 134, 184, 32, 87, 195, 214, 1, 79, 9, 210, 160, 32, 65, 199, + 140, 2, 89, 7, 242, 172, 34, 79, 3, 89, 14, 230, 154, 30, 65, 194, 200, + 1, 79, 238, 60, 73, 199, 140, 2, 69, 10, 26, 76, 255, 171, 34, 82, 9, 26, + 32, 179, 185, 9, 76, 4, 142, 155, 22, 67, 231, 164, 10, 84, 4, 230, 148, + 34, 76, 215, 22, 89, 4, 180, 179, 15, 3, 73, 84, 85, 213, 129, 8, 3, 82, 73, 67, 124, 140, 1, 2, 68, 32, 102, 69, 72, 11, 73, 65, 78, 32, 76, 69, - 84, 84, 69, 82, 32, 210, 3, 79, 62, 80, 90, 82, 217, 237, 27, 4, 32, 83, - 76, 73, 6, 52, 5, 73, 78, 68, 69, 88, 233, 170, 33, 2, 70, 73, 5, 229, - 168, 33, 6, 32, 68, 73, 86, 73, 68, 6, 26, 84, 151, 211, 21, 32, 5, 193, - 169, 10, 6, 32, 73, 78, 83, 69, 82, 98, 196, 1, 2, 67, 45, 38, 76, 22, - 77, 50, 78, 38, 83, 46, 84, 22, 85, 166, 219, 3, 65, 2, 68, 2, 69, 2, 71, - 2, 75, 2, 80, 158, 132, 27, 82, 218, 201, 1, 73, 198, 140, 2, 66, 2, 79, - 2, 81, 3, 88, 4, 246, 139, 27, 49, 155, 177, 3, 51, 7, 203, 220, 3, 68, - 11, 11, 66, 9, 226, 182, 34, 50, 2, 51, 3, 52, 9, 190, 182, 34, 68, 2, - 71, 3, 78, 13, 226, 219, 3, 72, 2, 84, 187, 218, 30, 83, 7, 183, 219, 3, - 84, 13, 11, 85, 11, 11, 85, 9, 194, 181, 34, 50, 2, 51, 3, 85, 4, 224, - 169, 33, 6, 85, 83, 69, 76, 32, 72, 191, 139, 1, 78, 4, 172, 215, 27, 6, + 84, 84, 69, 82, 32, 210, 3, 79, 62, 80, 90, 82, 141, 221, 27, 4, 32, 83, + 76, 73, 6, 52, 5, 73, 78, 68, 69, 88, 157, 154, 33, 2, 70, 73, 5, 153, + 152, 33, 6, 32, 68, 73, 86, 73, 68, 6, 26, 84, 203, 194, 21, 32, 5, 141, + 161, 10, 6, 32, 73, 78, 83, 69, 82, 98, 196, 1, 2, 67, 45, 38, 76, 22, + 77, 50, 78, 38, 83, 46, 84, 22, 85, 166, 215, 3, 65, 2, 68, 2, 69, 2, 71, + 2, 75, 2, 80, 210, 247, 26, 82, 218, 201, 1, 73, 198, 140, 2, 66, 2, 79, + 2, 81, 3, 88, 4, 170, 251, 26, 49, 155, 177, 3, 51, 7, 203, 216, 3, 68, + 11, 11, 66, 9, 150, 166, 34, 50, 2, 51, 3, 52, 9, 242, 165, 34, 68, 2, + 71, 3, 78, 13, 226, 215, 3, 72, 2, 84, 239, 205, 30, 83, 7, 183, 215, 3, + 84, 13, 11, 85, 11, 11, 85, 9, 246, 164, 34, 50, 2, 51, 3, 85, 4, 148, + 153, 33, 6, 85, 83, 69, 76, 32, 72, 191, 139, 1, 78, 4, 224, 198, 27, 6, 32, 83, 84, 82, 69, 65, 137, 223, 5, 7, 69, 78, 84, 82, 89, 32, 83, 4, - 218, 225, 27, 73, 135, 182, 6, 79, 9, 29, 5, 32, 70, 65, 67, 69, 7, 33, - 6, 32, 87, 73, 84, 72, 32, 4, 148, 242, 6, 2, 84, 69, 197, 152, 25, 6, + 142, 209, 27, 73, 135, 182, 6, 79, 9, 29, 5, 32, 70, 65, 67, 69, 7, 33, + 6, 32, 87, 73, 84, 72, 32, 4, 224, 233, 6, 2, 84, 69, 173, 144, 25, 6, 87, 82, 89, 32, 83, 77, 108, 88, 16, 67, 65, 83, 73, 65, 78, 32, 65, 76, - 66, 65, 78, 73, 65, 78, 32, 243, 172, 30, 84, 106, 60, 7, 76, 69, 84, 84, - 69, 82, 32, 161, 147, 28, 2, 67, 73, 104, 170, 2, 65, 34, 67, 146, 1, 68, + 66, 65, 78, 73, 65, 78, 32, 167, 156, 30, 84, 106, 60, 7, 76, 69, 84, 84, + 69, 82, 32, 213, 130, 28, 2, 67, 73, 104, 170, 2, 65, 34, 67, 146, 1, 68, 78, 69, 34, 71, 46, 73, 46, 74, 34, 75, 34, 76, 34, 80, 34, 83, 74, 84, - 62, 89, 46, 90, 148, 133, 17, 2, 81, 65, 190, 193, 6, 77, 252, 132, 9, 3, + 62, 89, 46, 90, 148, 249, 16, 2, 81, 65, 242, 188, 6, 77, 252, 132, 9, 3, 86, 69, 89, 154, 33, 70, 128, 19, 3, 78, 79, 87, 226, 32, 82, 186, 11, - 88, 154, 46, 79, 202, 26, 66, 237, 24, 3, 72, 69, 89, 4, 186, 246, 33, - 79, 179, 28, 76, 16, 34, 65, 34, 72, 49, 2, 89, 65, 4, 242, 222, 33, 89, - 227, 79, 82, 8, 218, 197, 28, 65, 146, 215, 5, 79, 203, 17, 73, 4, 130, - 174, 34, 87, 3, 89, 8, 42, 90, 162, 225, 32, 89, 243, 175, 1, 65, 4, 154, - 159, 33, 89, 219, 124, 65, 4, 186, 221, 33, 89, 227, 79, 66, 4, 212, 254, - 32, 2, 72, 69, 207, 157, 1, 73, 6, 214, 238, 32, 82, 154, 110, 87, 135, - 77, 78, 4, 214, 157, 33, 72, 227, 16, 65, 4, 226, 173, 33, 73, 199, 69, - 65, 4, 130, 220, 33, 65, 171, 51, 89, 4, 142, 1, 73, 215, 218, 33, 69, 8, - 34, 72, 233, 167, 34, 2, 69, 89, 6, 234, 171, 20, 65, 207, 237, 13, 79, - 6, 38, 73, 150, 156, 33, 89, 199, 80, 65, 2, 215, 241, 33, 87, 4, 252, - 227, 33, 2, 65, 89, 1, 2, 79, 87, 6, 242, 166, 16, 72, 131, 186, 4, 65, - 16, 72, 2, 68, 73, 32, 2, 78, 84, 204, 193, 32, 3, 76, 84, 73, 151, 81, - 82, 4, 142, 162, 33, 32, 223, 100, 76, 8, 32, 2, 82, 69, 207, 161, 33, - 32, 6, 44, 5, 76, 73, 78, 69, 32, 167, 232, 4, 32, 4, 246, 234, 21, 76, + 88, 154, 46, 79, 202, 26, 66, 237, 24, 3, 72, 69, 89, 4, 238, 229, 33, + 79, 179, 28, 76, 16, 34, 65, 34, 72, 49, 2, 89, 65, 4, 166, 206, 33, 89, + 227, 79, 82, 8, 142, 181, 28, 65, 146, 215, 5, 79, 203, 17, 73, 4, 182, + 157, 34, 87, 3, 89, 8, 42, 90, 214, 208, 32, 89, 243, 175, 1, 65, 4, 206, + 142, 33, 89, 219, 124, 65, 4, 238, 204, 33, 89, 227, 79, 66, 4, 136, 238, + 32, 2, 72, 69, 207, 157, 1, 73, 6, 138, 222, 32, 82, 154, 110, 87, 135, + 77, 78, 4, 138, 141, 33, 72, 227, 16, 65, 4, 150, 157, 33, 73, 199, 69, + 65, 4, 182, 203, 33, 65, 171, 51, 89, 4, 142, 1, 73, 139, 202, 33, 69, 8, + 34, 72, 157, 151, 34, 2, 69, 89, 6, 158, 155, 20, 65, 207, 237, 13, 79, + 6, 38, 73, 202, 139, 33, 89, 199, 80, 65, 2, 139, 225, 33, 87, 4, 176, + 211, 33, 2, 65, 89, 1, 2, 79, 87, 6, 242, 154, 16, 72, 183, 181, 4, 65, + 16, 72, 2, 68, 73, 32, 2, 78, 84, 128, 177, 32, 3, 76, 84, 73, 151, 81, + 82, 4, 194, 145, 33, 32, 223, 100, 76, 8, 32, 2, 82, 69, 131, 145, 33, + 32, 6, 44, 5, 76, 73, 78, 69, 32, 167, 228, 4, 32, 4, 170, 218, 21, 76, 207, 210, 10, 79, 130, 6, 102, 65, 170, 17, 69, 162, 8, 73, 190, 2, 79, - 188, 205, 13, 6, 82, 73, 83, 84, 77, 65, 155, 137, 10, 85, 198, 2, 66, - 73, 32, 4, 75, 77, 65, 32, 148, 6, 2, 77, 32, 131, 8, 82, 4, 218, 232, + 188, 193, 13, 6, 82, 73, 83, 84, 77, 65, 207, 132, 10, 85, 198, 2, 66, + 73, 32, 4, 75, 77, 65, 32, 148, 6, 2, 77, 32, 131, 8, 82, 4, 142, 216, 33, 78, 223, 61, 82, 142, 1, 156, 1, 7, 76, 69, 84, 84, 69, 82, 32, 142, - 3, 83, 98, 86, 142, 224, 23, 68, 154, 236, 7, 81, 176, 95, 5, 77, 65, 65, + 3, 83, 98, 86, 194, 207, 23, 68, 154, 236, 7, 81, 176, 95, 5, 77, 65, 65, 89, 89, 240, 179, 1, 2, 65, 85, 3, 79, 76, 202, 1, 68, 54, 78, 54, 84, - 54, 89, 178, 153, 29, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 76, 2, 80, 170, + 54, 89, 230, 136, 29, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 76, 2, 80, 170, 147, 3, 72, 2, 77, 2, 82, 2, 83, 2, 86, 2, 87, 254, 242, 1, 65, 186, 2, - 69, 2, 73, 3, 85, 8, 202, 154, 29, 68, 170, 147, 3, 72, 255, 242, 1, 65, - 8, 190, 173, 32, 71, 2, 78, 2, 89, 255, 242, 1, 65, 8, 226, 153, 29, 84, - 170, 147, 3, 72, 255, 242, 1, 65, 4, 214, 172, 32, 89, 255, 242, 1, 65, - 8, 40, 4, 73, 71, 78, 32, 195, 142, 22, 69, 6, 218, 131, 30, 67, 246, + 69, 2, 73, 3, 85, 8, 254, 137, 29, 68, 170, 147, 3, 72, 255, 242, 1, 65, + 8, 242, 156, 32, 71, 2, 78, 2, 89, 255, 242, 1, 65, 8, 150, 137, 29, 84, + 170, 147, 3, 72, 255, 242, 1, 65, 4, 138, 156, 32, 89, 255, 242, 1, 65, + 8, 40, 4, 73, 71, 78, 32, 247, 253, 21, 69, 6, 142, 243, 29, 67, 246, 227, 1, 86, 247, 244, 1, 65, 26, 64, 10, 79, 87, 69, 76, 32, 83, 73, 71, - 78, 32, 171, 228, 31, 73, 24, 206, 194, 30, 65, 250, 6, 85, 186, 202, 1, + 78, 32, 223, 211, 31, 73, 24, 130, 178, 30, 65, 250, 6, 85, 186, 202, 1, 69, 2, 73, 3, 79, 166, 1, 236, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 112, 7, 76, 69, 84, 84, 69, 82, 32, 152, 4, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 60, 11, 86, 79, 87, 69, - 76, 32, 83, 73, 71, 78, 32, 199, 164, 32, 68, 14, 72, 6, 70, 73, 78, 65, - 76, 32, 142, 155, 34, 76, 2, 82, 2, 87, 3, 89, 6, 238, 156, 34, 78, 86, + 76, 32, 83, 73, 71, 78, 32, 251, 147, 32, 68, 14, 72, 6, 70, 73, 78, 65, + 76, 32, 194, 138, 34, 76, 2, 82, 2, 87, 3, 89, 6, 162, 140, 34, 78, 86, 72, 3, 77, 104, 132, 2, 6, 70, 73, 78, 65, 76, 32, 110, 78, 50, 77, 78, - 80, 174, 229, 11, 66, 226, 141, 6, 68, 158, 145, 12, 83, 198, 136, 2, 65, + 80, 174, 217, 11, 66, 226, 141, 6, 68, 210, 140, 12, 83, 198, 136, 2, 65, 132, 197, 1, 2, 67, 72, 2, 71, 2, 74, 2, 75, 2, 84, 138, 69, 72, 2, 76, - 2, 82, 2, 86, 2, 89, 186, 2, 69, 2, 73, 2, 79, 3, 85, 22, 150, 157, 32, + 2, 82, 2, 86, 2, 89, 186, 2, 69, 2, 73, 2, 79, 3, 85, 22, 202, 140, 32, 78, 166, 192, 1, 83, 206, 60, 67, 146, 1, 71, 2, 75, 2, 76, 2, 80, 2, 82, - 2, 84, 3, 89, 14, 46, 71, 34, 72, 138, 131, 34, 85, 215, 22, 65, 4, 166, - 131, 34, 85, 215, 22, 65, 6, 134, 131, 34, 85, 158, 20, 74, 187, 2, 65, - 6, 246, 150, 34, 72, 2, 80, 187, 2, 65, 8, 182, 170, 11, 83, 134, 142, - 19, 68, 45, 4, 84, 82, 73, 80, 20, 170, 193, 30, 65, 222, 202, 1, 73, + 2, 84, 3, 89, 14, 46, 71, 34, 72, 190, 242, 33, 85, 215, 22, 65, 4, 218, + 242, 33, 85, 215, 22, 65, 6, 186, 242, 33, 85, 158, 20, 74, 187, 2, 65, + 6, 170, 134, 34, 72, 2, 80, 187, 2, 65, 8, 130, 162, 11, 83, 238, 133, + 19, 68, 45, 4, 84, 82, 73, 80, 20, 222, 176, 30, 65, 222, 202, 1, 73, 166, 204, 1, 79, 2, 85, 203, 44, 69, 14, 72, 7, 65, 67, 84, 69, 82, 32, - 84, 49, 7, 84, 32, 87, 73, 84, 72, 32, 8, 244, 255, 9, 3, 65, 66, 85, - 239, 128, 24, 73, 6, 128, 1, 13, 85, 80, 87, 65, 82, 68, 83, 32, 84, 82, - 69, 78, 68, 161, 186, 25, 12, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, - 82, 5, 153, 250, 6, 6, 32, 65, 78, 68, 32, 89, 236, 2, 80, 2, 67, 75, 82, - 69, 90, 82, 176, 253, 4, 2, 83, 84, 133, 166, 15, 2, 81, 85, 6, 56, 8, - 69, 82, 32, 66, 79, 65, 82, 68, 143, 211, 33, 32, 5, 227, 152, 31, 32, 4, - 224, 202, 27, 4, 83, 69, 32, 87, 221, 156, 5, 9, 82, 73, 78, 71, 32, 77, + 84, 49, 7, 84, 32, 87, 73, 84, 72, 32, 8, 192, 247, 9, 3, 65, 66, 85, + 215, 248, 23, 73, 6, 128, 1, 13, 85, 80, 87, 65, 82, 68, 83, 32, 84, 82, + 69, 78, 68, 213, 169, 25, 12, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, + 82, 5, 229, 241, 6, 6, 32, 65, 78, 68, 32, 89, 236, 2, 80, 2, 67, 75, 82, + 69, 90, 82, 176, 249, 4, 2, 83, 84, 185, 153, 15, 2, 81, 85, 6, 56, 8, + 69, 82, 32, 66, 79, 65, 82, 68, 195, 194, 33, 32, 5, 151, 136, 31, 32, 4, + 148, 186, 27, 4, 83, 69, 32, 87, 221, 156, 5, 9, 82, 73, 78, 71, 32, 77, 69, 71, 65, 222, 2, 40, 5, 79, 75, 69, 69, 32, 143, 5, 82, 216, 2, 46, 76, 1, 7, 83, 77, 65, 76, 76, 32, 76, 172, 1, 33, 6, 69, 84, 84, 69, 82, 32, 172, 1, 170, 1, 68, 74, 72, 74, 78, 70, 83, 62, 84, 54, 71, 2, 76, 2, - 77, 0, 2, 81, 85, 2, 87, 2, 89, 162, 140, 34, 75, 186, 2, 65, 2, 69, 2, - 73, 2, 79, 2, 85, 3, 86, 14, 226, 142, 34, 76, 186, 2, 65, 2, 69, 2, 73, - 2, 79, 2, 85, 3, 86, 14, 154, 142, 34, 78, 186, 2, 65, 2, 69, 2, 73, 2, - 79, 2, 85, 3, 86, 14, 170, 255, 29, 65, 226, 144, 4, 69, 2, 73, 2, 79, 2, - 85, 3, 86, 15, 198, 143, 34, 65, 2, 69, 2, 73, 2, 79, 2, 85, 3, 86, 30, - 50, 76, 2, 83, 218, 142, 34, 65, 2, 69, 3, 73, 12, 214, 142, 34, 65, 2, - 69, 2, 73, 2, 79, 2, 85, 3, 86, 6, 32, 2, 89, 32, 247, 247, 32, 73, 4, - 40, 4, 66, 76, 79, 83, 163, 248, 32, 83, 2, 231, 252, 33, 83, 16, 152, 1, - 2, 76, 68, 48, 11, 78, 69, 83, 69, 32, 83, 77, 65, 76, 76, 32, 206, 247, - 7, 32, 184, 247, 2, 2, 80, 77, 228, 198, 21, 2, 67, 75, 155, 134, 1, 82, - 5, 173, 247, 28, 7, 82, 69, 78, 32, 67, 82, 79, 4, 248, 224, 19, 10, 83, + 77, 0, 2, 81, 85, 2, 87, 2, 89, 214, 251, 33, 75, 186, 2, 65, 2, 69, 2, + 73, 2, 79, 2, 85, 3, 86, 14, 150, 254, 33, 76, 186, 2, 65, 2, 69, 2, 73, + 2, 79, 2, 85, 3, 86, 14, 206, 253, 33, 78, 186, 2, 65, 2, 69, 2, 73, 2, + 79, 2, 85, 3, 86, 14, 222, 238, 29, 65, 226, 144, 4, 69, 2, 73, 2, 79, 2, + 85, 3, 86, 15, 250, 254, 33, 65, 2, 69, 2, 73, 2, 79, 2, 85, 3, 86, 30, + 50, 76, 2, 83, 142, 254, 33, 65, 2, 69, 3, 73, 12, 138, 254, 33, 65, 2, + 69, 2, 73, 2, 79, 2, 85, 3, 86, 6, 32, 2, 89, 32, 171, 231, 32, 73, 4, + 40, 4, 66, 76, 79, 83, 215, 231, 32, 83, 2, 155, 236, 33, 83, 16, 152, 1, + 2, 76, 68, 48, 11, 78, 69, 83, 69, 32, 83, 77, 65, 76, 76, 32, 154, 239, + 7, 32, 184, 247, 2, 2, 80, 77, 204, 190, 21, 2, 67, 75, 155, 134, 1, 82, + 5, 225, 230, 28, 7, 82, 69, 78, 32, 67, 82, 79, 4, 172, 208, 19, 10, 83, 73, 77, 80, 76, 73, 70, 73, 69, 68, 1, 11, 84, 82, 65, 68, 73, 84, 73, - 79, 78, 65, 76, 60, 92, 8, 82, 65, 83, 77, 73, 65, 78, 32, 254, 130, 5, - 80, 197, 141, 12, 5, 67, 79, 76, 65, 84, 56, 52, 7, 76, 69, 84, 84, 69, - 82, 32, 199, 214, 21, 78, 42, 224, 1, 6, 67, 85, 82, 76, 69, 68, 30, 83, - 158, 211, 21, 68, 34, 76, 134, 206, 1, 82, 142, 220, 2, 65, 50, 71, 90, + 79, 78, 65, 76, 60, 92, 8, 82, 65, 83, 77, 73, 65, 78, 32, 254, 254, 4, + 80, 197, 133, 12, 5, 67, 79, 76, 65, 84, 56, 52, 7, 76, 69, 84, 84, 69, + 82, 32, 251, 197, 21, 78, 42, 224, 1, 6, 67, 85, 82, 76, 69, 68, 30, 83, + 210, 194, 21, 68, 34, 76, 134, 206, 1, 82, 142, 220, 2, 65, 50, 71, 90, 90, 98, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, - 134, 2, 84, 2, 87, 218, 103, 80, 171, 4, 77, 2, 209, 137, 33, 2, 32, 87, - 6, 132, 211, 21, 6, 77, 65, 76, 76, 32, 65, 232, 243, 5, 2, 65, 77, 163, + 134, 2, 84, 2, 87, 218, 103, 80, 171, 4, 77, 2, 133, 249, 32, 2, 32, 87, + 6, 184, 194, 21, 6, 77, 65, 76, 76, 32, 65, 232, 243, 5, 2, 65, 77, 163, 193, 5, 72, 232, 4, 66, 78, 20, 2, 82, 67, 201, 40, 7, 84, 89, 83, 67, - 65, 80, 69, 2, 183, 229, 33, 69, 226, 4, 28, 2, 76, 69, 207, 39, 85, 220, + 65, 80, 69, 2, 235, 212, 33, 69, 226, 4, 28, 2, 76, 69, 207, 39, 85, 220, 4, 30, 32, 185, 6, 2, 68, 32, 24, 244, 1, 5, 87, 73, 84, 72, 32, 161, - 205, 18, 49, 68, 73, 86, 73, 68, 69, 68, 32, 66, 89, 32, 72, 79, 82, 73, + 193, 18, 49, 68, 73, 86, 73, 68, 69, 68, 32, 66, 89, 32, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 66, 65, 82, 32, 65, 78, 68, 32, 84, 79, 80, 32, 72, 65, 76, 70, 32, 68, 73, 86, 73, 68, 69, 68, 32, 66, 89, 22, 146, 2, 76, 46, 83, 108, 22, 84, 87, 79, 32, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 83, 84, 82, 79, 75, 69, 83, 44, 6, 85, 80, 80, 69, 82, 32, 44, 17, 65, 76, 76, 32, 66, 85, 84, 32, 85, 80, 80, 69, 82, 32, 76, 69, - 70, 190, 205, 26, 86, 242, 146, 4, 82, 183, 251, 1, 72, 4, 142, 226, 30, + 70, 242, 188, 26, 86, 242, 146, 4, 82, 183, 251, 1, 72, 4, 194, 209, 30, 69, 49, 4, 79, 87, 69, 82, 4, 104, 11, 77, 65, 76, 76, 32, 67, 73, 82, - 67, 76, 69, 221, 5, 10, 85, 80, 69, 82, 73, 77, 80, 79, 83, 69, 2, 225, - 251, 30, 6, 32, 84, 79, 32, 84, 72, 4, 40, 4, 82, 73, 71, 72, 231, 224, - 30, 72, 2, 249, 224, 30, 10, 84, 32, 81, 85, 65, 68, 82, 65, 78, 84, 196, + 67, 76, 69, 221, 5, 10, 85, 80, 69, 82, 73, 77, 80, 79, 83, 69, 2, 149, + 235, 30, 6, 32, 84, 79, 32, 84, 72, 4, 40, 4, 82, 73, 71, 72, 155, 208, + 30, 72, 2, 173, 208, 30, 10, 84, 32, 81, 85, 65, 68, 82, 65, 78, 84, 196, 4, 230, 2, 65, 186, 1, 66, 58, 67, 230, 1, 68, 246, 1, 72, 230, 2, 73, 194, 10, 75, 190, 2, 76, 38, 77, 136, 1, 7, 78, 85, 77, 66, 69, 82, 32, 192, 4, 17, 79, 80, 69, 78, 32, 67, 69, 78, 84, 82, 69, 32, 69, 73, 71, - 72, 84, 54, 80, 114, 82, 50, 84, 78, 87, 192, 132, 10, 4, 90, 69, 82, 79, - 158, 196, 16, 69, 182, 188, 4, 86, 146, 68, 71, 150, 115, 83, 227, 162, - 1, 88, 6, 100, 12, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 157, - 184, 30, 7, 83, 84, 69, 82, 73, 83, 75, 4, 212, 249, 8, 11, 45, 82, 79, - 84, 65, 84, 69, 68, 32, 68, 73, 191, 229, 23, 32, 4, 32, 2, 79, 76, 219, - 152, 32, 85, 2, 223, 221, 14, 68, 16, 60, 4, 82, 79, 83, 83, 210, 2, 32, - 202, 247, 33, 67, 3, 68, 10, 26, 32, 199, 197, 1, 73, 8, 64, 6, 70, 79, - 82, 77, 69, 69, 153, 135, 32, 4, 80, 79, 77, 77, 7, 33, 6, 32, 87, 73, - 84, 72, 32, 4, 158, 210, 31, 70, 135, 84, 84, 30, 34, 73, 70, 79, 135, - 141, 32, 65, 24, 168, 192, 4, 8, 86, 73, 83, 73, 79, 78, 32, 83, 183, - 196, 27, 71, 4, 64, 10, 76, 76, 65, 82, 32, 83, 73, 71, 78, 32, 135, 180, - 30, 84, 2, 173, 175, 19, 13, 87, 73, 84, 72, 32, 79, 86, 69, 82, 76, 65, - 73, 68, 64, 192, 1, 6, 65, 78, 71, 85, 76, 32, 252, 203, 12, 20, 79, 82, + 72, 84, 54, 80, 114, 82, 50, 84, 78, 87, 140, 252, 9, 4, 90, 69, 82, 79, + 134, 188, 16, 69, 182, 188, 4, 86, 146, 68, 71, 150, 115, 83, 227, 162, + 1, 88, 6, 100, 12, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 209, + 167, 30, 7, 83, 84, 69, 82, 73, 83, 75, 4, 160, 241, 8, 11, 45, 82, 79, + 84, 65, 84, 69, 68, 32, 68, 73, 167, 221, 23, 32, 4, 32, 2, 79, 76, 143, + 136, 32, 85, 2, 223, 209, 14, 68, 16, 60, 4, 82, 79, 83, 83, 210, 2, 32, + 254, 230, 33, 67, 3, 68, 10, 26, 32, 199, 193, 1, 73, 8, 64, 6, 70, 79, + 82, 77, 69, 69, 205, 246, 31, 4, 80, 79, 77, 77, 7, 33, 6, 32, 87, 73, + 84, 72, 32, 4, 210, 193, 31, 70, 135, 84, 84, 30, 34, 73, 70, 79, 187, + 252, 31, 65, 24, 168, 188, 4, 8, 86, 73, 83, 73, 79, 78, 32, 83, 235, + 183, 27, 71, 4, 64, 10, 76, 76, 65, 82, 32, 83, 73, 71, 78, 32, 187, 163, + 30, 84, 2, 225, 158, 19, 13, 87, 73, 84, 72, 32, 79, 86, 69, 82, 76, 65, + 73, 68, 64, 192, 1, 6, 65, 78, 71, 85, 76, 32, 252, 191, 12, 20, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 66, 65, 82, 32, 87, 73, 84, 72, 32, 78, - 204, 217, 9, 4, 85, 77, 65, 78, 145, 1, 4, 69, 65, 86, 89, 58, 110, 67, - 140, 207, 20, 5, 73, 69, 85, 78, 71, 42, 72, 30, 75, 66, 77, 34, 78, 34, - 80, 62, 82, 30, 83, 27, 84, 8, 234, 206, 20, 72, 157, 3, 4, 73, 69, 85, + 128, 213, 9, 4, 85, 77, 65, 78, 145, 1, 4, 69, 65, 86, 89, 58, 110, 67, + 192, 190, 20, 5, 73, 69, 85, 78, 71, 42, 72, 30, 75, 66, 77, 34, 78, 34, + 80, 62, 82, 30, 83, 27, 84, 8, 158, 190, 20, 72, 157, 3, 4, 73, 69, 85, 67, 116, 220, 1, 9, 68, 69, 79, 71, 82, 65, 80, 72, 32, 196, 8, 27, 84, 65, 76, 73, 67, 32, 76, 65, 84, 73, 78, 32, 67, 65, 80, 73, 84, 65, 76, - 32, 76, 69, 84, 84, 69, 82, 32, 169, 162, 27, 9, 78, 70, 79, 82, 77, 65, + 32, 76, 69, 84, 84, 69, 82, 32, 221, 145, 27, 9, 78, 70, 79, 82, 77, 65, 84, 73, 79, 110, 174, 1, 65, 110, 67, 90, 69, 86, 70, 62, 72, 38, 75, 70, - 76, 50, 77, 86, 78, 62, 81, 30, 82, 74, 83, 198, 178, 6, 80, 162, 157, - 14, 84, 50, 87, 202, 215, 1, 73, 163, 168, 10, 79, 8, 242, 207, 20, 76, + 76, 50, 77, 86, 78, 62, 81, 30, 82, 74, 83, 146, 170, 6, 80, 138, 149, + 14, 84, 50, 87, 202, 215, 1, 73, 163, 168, 10, 79, 8, 166, 191, 20, 76, 200, 134, 1, 3, 67, 67, 69, 184, 249, 6, 3, 84, 84, 69, 249, 17, 5, 68, - 86, 65, 78, 84, 8, 26, 79, 235, 234, 30, 69, 6, 236, 212, 10, 2, 82, 82, - 190, 250, 9, 78, 147, 143, 13, 80, 8, 190, 207, 20, 78, 174, 179, 9, 65, - 180, 169, 3, 5, 88, 67, 69, 76, 76, 231, 24, 73, 10, 202, 207, 20, 73, - 144, 190, 5, 2, 69, 77, 199, 232, 6, 79, 4, 146, 193, 29, 73, 211, 176, - 3, 65, 4, 228, 166, 7, 8, 73, 78, 68, 69, 82, 71, 65, 82, 167, 212, 22, - 79, 6, 218, 206, 20, 65, 214, 160, 12, 79, 195, 83, 69, 8, 38, 69, 190, - 198, 32, 65, 211, 86, 79, 4, 184, 209, 32, 3, 68, 73, 67, 227, 15, 84, 6, - 26, 73, 195, 210, 32, 65, 4, 246, 193, 33, 71, 231, 19, 78, 2, 233, 208, - 28, 2, 85, 69, 8, 26, 69, 151, 193, 33, 73, 6, 226, 205, 20, 83, 217, - 136, 8, 2, 76, 73, 22, 90, 69, 38, 85, 184, 161, 14, 2, 67, 72, 130, 172, - 6, 79, 22, 80, 34, 84, 131, 142, 12, 73, 4, 238, 164, 10, 67, 223, 239, - 21, 86, 6, 182, 206, 20, 80, 146, 128, 2, 73, 231, 155, 11, 78, 4, 246, - 233, 33, 67, 3, 82, 98, 116, 8, 65, 84, 65, 75, 65, 78, 65, 32, 133, 1, + 86, 65, 78, 84, 8, 26, 79, 159, 218, 30, 69, 6, 184, 204, 10, 2, 82, 82, + 166, 242, 9, 78, 147, 143, 13, 80, 8, 242, 190, 20, 78, 174, 179, 9, 65, + 180, 169, 3, 5, 88, 67, 69, 76, 76, 231, 24, 73, 10, 254, 190, 20, 73, + 144, 190, 5, 2, 69, 77, 199, 232, 6, 79, 4, 198, 176, 29, 73, 211, 176, + 3, 65, 4, 176, 158, 7, 8, 73, 78, 68, 69, 82, 71, 65, 82, 143, 204, 22, + 79, 6, 142, 190, 20, 65, 214, 160, 12, 79, 195, 83, 69, 8, 38, 69, 242, + 181, 32, 65, 211, 86, 79, 4, 236, 192, 32, 3, 68, 73, 67, 227, 15, 84, 6, + 26, 73, 247, 193, 32, 65, 4, 170, 177, 33, 71, 231, 19, 78, 2, 157, 192, + 28, 2, 85, 69, 8, 26, 69, 203, 176, 33, 73, 6, 150, 189, 20, 83, 217, + 136, 8, 2, 76, 73, 22, 90, 69, 38, 85, 184, 149, 14, 2, 67, 72, 182, 167, + 6, 79, 22, 80, 34, 84, 131, 142, 12, 73, 4, 186, 156, 10, 67, 199, 231, + 21, 86, 6, 234, 189, 20, 80, 146, 128, 2, 73, 231, 155, 11, 78, 4, 170, + 217, 33, 67, 3, 82, 98, 116, 8, 65, 84, 65, 75, 65, 78, 65, 32, 133, 1, 16, 79, 82, 69, 65, 78, 32, 67, 72, 65, 82, 65, 67, 84, 69, 82, 32, 94, - 166, 241, 10, 72, 2, 75, 2, 77, 2, 78, 2, 82, 2, 83, 2, 84, 126, 87, 46, - 89, 150, 246, 22, 65, 2, 69, 2, 73, 2, 79, 3, 85, 4, 152, 157, 16, 3, 74, - 85, 69, 197, 171, 17, 4, 67, 72, 65, 77, 106, 222, 196, 27, 65, 255, 140, + 242, 232, 10, 72, 2, 75, 2, 77, 2, 78, 2, 82, 2, 83, 2, 84, 126, 87, 46, + 89, 254, 237, 22, 65, 2, 69, 2, 73, 2, 79, 3, 85, 4, 152, 145, 16, 3, 74, + 85, 69, 249, 166, 17, 4, 67, 72, 65, 77, 106, 146, 180, 27, 65, 255, 140, 4, 69, 4, 100, 19, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 78, - 32, 83, 73, 71, 78, 32, 167, 221, 31, 73, 2, 209, 85, 4, 87, 73, 84, 72, - 98, 50, 69, 46, 70, 98, 83, 94, 84, 147, 202, 20, 78, 6, 180, 1, 3, 73, - 71, 72, 203, 193, 25, 76, 30, 28, 3, 73, 70, 84, 35, 79, 6, 214, 1, 89, - 155, 141, 32, 69, 24, 142, 2, 82, 251, 201, 20, 85, 8, 40, 4, 69, 86, 69, - 78, 1, 2, 73, 88, 4, 11, 84, 4, 104, 2, 89, 32, 143, 141, 32, 69, 52, 56, - 2, 69, 78, 32, 4, 72, 73, 82, 84, 29, 2, 87, 69, 5, 11, 32, 2, 139, 223, - 25, 79, 24, 74, 89, 175, 140, 32, 69, 24, 26, 78, 243, 229, 32, 76, 22, - 17, 2, 84, 89, 23, 11, 32, 20, 72, 2, 79, 78, 206, 238, 31, 70, 30, 83, - 42, 84, 142, 87, 78, 239, 112, 69, 4, 230, 221, 25, 32, 243, 131, 8, 69, - 2, 193, 199, 31, 8, 32, 80, 79, 73, 78, 84, 69, 68, 8, 248, 217, 17, 3, - 79, 83, 84, 190, 251, 6, 65, 228, 203, 2, 8, 69, 82, 80, 69, 78, 68, 73, - 67, 131, 183, 4, 76, 4, 200, 156, 30, 3, 73, 78, 71, 163, 170, 1, 69, 6, - 52, 7, 82, 73, 65, 78, 71, 76, 69, 143, 199, 26, 73, 5, 211, 166, 22, 32, - 6, 44, 5, 72, 73, 84, 69, 32, 231, 222, 33, 90, 4, 194, 252, 31, 66, 215, - 25, 83, 6, 154, 184, 27, 77, 184, 190, 4, 6, 76, 65, 84, 73, 79, 78, 201, - 164, 1, 3, 83, 32, 84, 5, 233, 150, 32, 6, 32, 65, 84, 32, 68, 85, 158, - 18, 192, 1, 24, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 89, 32, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 144, 3, 8, 82, 65, 68, 73, 67, - 65, 76, 32, 245, 17, 7, 83, 84, 82, 79, 75, 69, 32, 236, 15, 24, 2, 50, - 70, 75, 70, 188, 8, 34, 65, 170, 130, 11, 56, 3, 57, 60, 202, 1, 49, 243, - 254, 18, 48, 176, 7, 26, 65, 235, 129, 11, 57, 176, 3, 134, 1, 54, 242, - 254, 18, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 2, 57, 2, - 65, 2, 66, 2, 67, 215, 156, 9, 68, 28, 226, 217, 33, 48, 2, 49, 2, 50, 2, - 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 3, 68, - 230, 1, 210, 1, 66, 126, 67, 226, 4, 68, 62, 69, 50, 70, 34, 71, 50, 72, - 86, 74, 154, 1, 76, 62, 77, 130, 1, 80, 46, 82, 78, 83, 182, 3, 84, 82, - 87, 164, 230, 10, 2, 78, 69, 156, 17, 4, 75, 78, 73, 70, 203, 160, 12, - 79, 14, 74, 79, 188, 134, 11, 4, 82, 85, 83, 72, 162, 240, 4, 65, 143, - 208, 13, 76, 6, 182, 173, 10, 76, 186, 146, 23, 78, 215, 22, 88, 56, 104, - 12, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 68, 32, 162, 3, 73, 50, 76, - 186, 211, 32, 79, 191, 78, 72, 44, 114, 69, 38, 70, 50, 71, 38, 76, 34, - 83, 94, 84, 182, 217, 14, 87, 42, 68, 130, 244, 16, 66, 170, 121, 72, - 163, 4, 67, 4, 174, 254, 31, 86, 219, 185, 1, 65, 6, 134, 233, 31, 73, - 194, 217, 1, 76, 235, 16, 82, 4, 146, 164, 23, 79, 187, 230, 8, 65, 4, - 138, 210, 32, 69, 187, 48, 79, 10, 162, 230, 6, 73, 146, 199, 17, 65, + 32, 83, 73, 71, 78, 32, 219, 204, 31, 73, 2, 209, 81, 4, 87, 73, 84, 72, + 98, 50, 69, 46, 70, 98, 83, 94, 84, 199, 185, 20, 78, 6, 180, 1, 3, 73, + 71, 72, 255, 176, 25, 76, 30, 28, 3, 73, 70, 84, 35, 79, 6, 214, 1, 89, + 207, 252, 31, 69, 24, 142, 2, 82, 175, 185, 20, 85, 8, 40, 4, 69, 86, 69, + 78, 1, 2, 73, 88, 4, 11, 84, 4, 104, 2, 89, 32, 195, 252, 31, 69, 52, 56, + 2, 69, 78, 32, 4, 72, 73, 82, 84, 29, 2, 87, 69, 5, 11, 32, 2, 191, 206, + 25, 79, 24, 74, 89, 227, 251, 31, 69, 24, 26, 78, 167, 213, 32, 76, 22, + 17, 2, 84, 89, 23, 11, 32, 20, 72, 2, 79, 78, 130, 222, 31, 70, 30, 83, + 42, 84, 142, 87, 78, 239, 112, 69, 4, 154, 205, 25, 32, 243, 131, 8, 69, + 2, 245, 182, 31, 8, 32, 80, 79, 73, 78, 84, 69, 68, 8, 248, 205, 17, 3, + 79, 83, 84, 242, 246, 6, 65, 228, 203, 2, 8, 69, 82, 80, 69, 78, 68, 73, + 67, 131, 183, 4, 76, 4, 252, 139, 30, 3, 73, 78, 71, 163, 170, 1, 69, 6, + 52, 7, 82, 73, 65, 78, 71, 76, 69, 195, 182, 26, 73, 5, 135, 150, 22, 32, + 6, 44, 5, 72, 73, 84, 69, 32, 155, 206, 33, 90, 4, 246, 235, 31, 66, 215, + 25, 83, 6, 206, 167, 27, 77, 184, 190, 4, 6, 76, 65, 84, 73, 79, 78, 201, + 164, 1, 3, 83, 32, 84, 5, 157, 134, 32, 6, 32, 65, 84, 32, 68, 85, 178, + 2, 80, 8, 82, 65, 68, 73, 67, 65, 76, 32, 245, 17, 7, 83, 84, 82, 79, 75, + 69, 32, 230, 1, 210, 1, 66, 126, 67, 226, 4, 68, 62, 69, 50, 70, 34, 71, + 50, 72, 86, 74, 154, 1, 76, 62, 77, 130, 1, 80, 46, 82, 78, 83, 182, 3, + 84, 82, 87, 240, 225, 10, 2, 78, 69, 208, 13, 4, 75, 78, 73, 70, 255, + 155, 12, 79, 14, 74, 79, 188, 254, 10, 4, 82, 85, 83, 72, 162, 240, 4, + 65, 195, 203, 13, 76, 6, 130, 169, 10, 76, 162, 138, 23, 78, 215, 22, 88, + 56, 104, 12, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 68, 32, 162, 3, 73, + 50, 76, 238, 198, 32, 79, 191, 78, 72, 44, 114, 69, 38, 70, 50, 71, 38, + 76, 34, 83, 94, 84, 182, 209, 14, 87, 42, 68, 182, 239, 16, 66, 170, 121, + 72, 163, 4, 67, 4, 226, 241, 31, 86, 219, 185, 1, 65, 6, 186, 220, 31, + 73, 194, 217, 1, 76, 235, 16, 82, 4, 198, 151, 23, 79, 187, 230, 8, 65, + 4, 190, 197, 32, 69, 187, 48, 79, 10, 238, 225, 6, 73, 250, 190, 17, 65, 194, 194, 1, 72, 128, 193, 7, 3, 80, 69, 69, 215, 11, 69, 6, 214, 10, 85, - 148, 188, 10, 2, 65, 78, 235, 164, 4, 79, 4, 128, 229, 20, 3, 86, 73, 76, - 191, 219, 12, 84, 4, 150, 233, 17, 73, 167, 210, 14, 79, 6, 240, 172, 24, - 2, 73, 86, 222, 240, 2, 69, 147, 179, 6, 79, 10, 196, 6, 2, 65, 84, 222, - 179, 33, 87, 3, 89, 4, 138, 174, 32, 73, 135, 82, 79, 8, 244, 5, 4, 82, - 65, 83, 83, 179, 220, 29, 72, 10, 48, 2, 69, 65, 226, 188, 28, 79, 211, - 130, 4, 65, 6, 186, 8, 82, 139, 199, 33, 68, 10, 72, 12, 45, 83, 73, 77, - 80, 76, 73, 70, 73, 69, 68, 32, 231, 187, 31, 65, 8, 42, 84, 202, 213, - 14, 68, 143, 134, 17, 69, 4, 194, 6, 85, 255, 224, 14, 79, 12, 128, 254, - 10, 3, 79, 78, 71, 205, 129, 16, 3, 65, 77, 69, 14, 18, 69, 35, 79, 4, - 142, 177, 33, 65, 159, 27, 83, 10, 144, 253, 10, 3, 85, 78, 68, 182, 174, - 13, 84, 138, 217, 7, 82, 239, 120, 79, 6, 196, 252, 10, 2, 65, 87, 239, - 203, 18, 69, 8, 34, 65, 197, 194, 32, 2, 69, 80, 6, 158, 252, 32, 73, + 224, 183, 10, 2, 65, 78, 159, 161, 4, 79, 4, 180, 216, 20, 3, 86, 73, 76, + 191, 219, 12, 84, 4, 150, 225, 17, 73, 219, 205, 14, 79, 6, 164, 160, 24, + 2, 73, 86, 222, 240, 2, 69, 147, 179, 6, 79, 10, 196, 6, 2, 65, 84, 146, + 167, 33, 87, 3, 89, 4, 190, 161, 32, 73, 135, 82, 79, 8, 244, 5, 4, 82, + 65, 83, 83, 231, 207, 29, 72, 10, 48, 2, 69, 65, 150, 176, 28, 79, 211, + 130, 4, 65, 6, 186, 8, 82, 191, 186, 33, 68, 10, 72, 12, 45, 83, 73, 77, + 80, 76, 73, 70, 73, 69, 68, 32, 155, 175, 31, 65, 8, 42, 84, 202, 205, + 14, 68, 195, 129, 17, 69, 4, 194, 6, 85, 255, 216, 14, 79, 12, 128, 246, + 10, 3, 79, 78, 71, 129, 253, 15, 3, 65, 77, 69, 14, 18, 69, 35, 79, 4, + 194, 164, 33, 65, 159, 27, 83, 10, 144, 245, 10, 3, 85, 78, 68, 234, 169, + 13, 84, 138, 217, 7, 82, 239, 120, 79, 6, 196, 244, 10, 2, 65, 87, 163, + 199, 18, 69, 8, 34, 65, 249, 181, 32, 2, 69, 80, 6, 210, 239, 32, 73, 226, 79, 77, 3, 80, 38, 122, 69, 90, 73, 186, 1, 78, 196, 1, 4, 80, 73, - 82, 73, 128, 247, 10, 4, 77, 65, 76, 76, 166, 158, 12, 72, 135, 226, 9, - 85, 8, 40, 4, 67, 79, 78, 68, 227, 190, 32, 65, 6, 11, 32, 6, 218, 215, - 31, 84, 155, 87, 79, 12, 60, 9, 77, 80, 76, 73, 70, 73, 69, 68, 32, 175, - 198, 33, 76, 10, 34, 72, 50, 87, 131, 194, 10, 89, 4, 136, 172, 10, 3, - 65, 76, 70, 179, 138, 18, 79, 4, 246, 219, 6, 65, 191, 227, 25, 72, 6, - 192, 1, 2, 79, 85, 179, 151, 33, 65, 8, 58, 85, 150, 241, 24, 65, 242, - 204, 1, 72, 191, 184, 3, 73, 2, 135, 159, 24, 82, 12, 26, 65, 49, 2, 69, - 83, 8, 172, 247, 10, 2, 76, 75, 1, 3, 84, 69, 82, 4, 255, 246, 10, 84, - 76, 110, 72, 182, 1, 80, 38, 83, 194, 198, 31, 84, 152, 253, 1, 2, 66, - 88, 2, 87, 2, 88, 86, 68, 2, 78, 3, 81, 31, 42, 80, 22, 88, 30, 90, 171, - 197, 33, 71, 5, 131, 197, 33, 87, 4, 238, 196, 33, 87, 87, 71, 19, 50, - 90, 246, 198, 31, 87, 130, 254, 1, 71, 3, 84, 9, 242, 198, 31, 90, 131, - 254, 1, 80, 9, 206, 196, 33, 68, 2, 71, 3, 90, 23, 50, 87, 30, 90, 222, - 195, 33, 71, 2, 80, 3, 84, 7, 246, 195, 33, 71, 3, 90, 9, 134, 195, 33, - 87, 86, 80, 3, 90, 124, 62, 65, 194, 1, 73, 114, 79, 181, 132, 21, 4, 69, + 82, 73, 128, 239, 10, 4, 77, 65, 76, 76, 218, 153, 12, 72, 135, 226, 9, + 85, 8, 40, 4, 67, 79, 78, 68, 151, 178, 32, 65, 6, 11, 32, 6, 142, 203, + 31, 84, 155, 87, 79, 12, 60, 9, 77, 80, 76, 73, 70, 73, 69, 68, 32, 227, + 185, 33, 76, 10, 34, 72, 50, 87, 207, 189, 10, 89, 4, 212, 167, 10, 3, + 65, 76, 70, 155, 130, 18, 79, 4, 194, 215, 6, 65, 167, 219, 25, 72, 6, + 192, 1, 2, 79, 85, 231, 138, 33, 65, 8, 58, 85, 202, 228, 24, 65, 242, + 204, 1, 72, 191, 184, 3, 73, 2, 187, 146, 24, 82, 12, 26, 65, 49, 2, 69, + 83, 8, 172, 239, 10, 2, 76, 75, 1, 3, 84, 69, 82, 4, 255, 238, 10, 84, + 76, 110, 72, 182, 1, 80, 38, 83, 246, 185, 31, 84, 152, 253, 1, 2, 66, + 88, 2, 87, 2, 88, 86, 68, 2, 78, 3, 81, 31, 42, 80, 22, 88, 30, 90, 223, + 184, 33, 71, 5, 183, 184, 33, 87, 4, 162, 184, 33, 87, 87, 71, 19, 50, + 90, 170, 186, 31, 87, 130, 254, 1, 71, 3, 84, 9, 166, 186, 31, 90, 131, + 254, 1, 80, 9, 130, 184, 33, 68, 2, 71, 3, 90, 23, 50, 87, 30, 90, 146, + 183, 33, 71, 2, 80, 3, 84, 7, 170, 183, 33, 71, 3, 90, 9, 186, 182, 33, + 87, 86, 80, 3, 90, 124, 62, 65, 194, 1, 73, 114, 79, 233, 247, 20, 4, 69, 65, 82, 32, 8, 132, 1, 2, 80, 80, 128, 217, 3, 6, 83, 83, 73, 67, 65, 76, - 129, 188, 28, 14, 77, 83, 72, 69, 76, 76, 32, 77, 79, 66, 73, 76, 69, 32, - 4, 180, 208, 19, 5, 73, 78, 71, 32, 72, 227, 228, 1, 69, 6, 48, 6, 78, - 75, 73, 78, 71, 32, 247, 167, 32, 80, 4, 194, 169, 25, 71, 149, 189, 3, + 181, 175, 28, 14, 77, 83, 72, 69, 76, 76, 32, 77, 79, 66, 73, 76, 69, 32, + 4, 232, 195, 19, 5, 73, 78, 71, 32, 72, 227, 228, 1, 69, 6, 48, 6, 78, + 75, 73, 78, 71, 32, 171, 155, 32, 80, 4, 246, 156, 25, 71, 149, 189, 3, 6, 66, 69, 69, 82, 32, 77, 108, 72, 2, 67, 75, 140, 10, 2, 83, 69, 236, - 3, 2, 85, 68, 207, 187, 30, 87, 70, 64, 6, 32, 70, 65, 67, 69, 32, 237, + 3, 2, 85, 68, 131, 175, 30, 87, 70, 64, 6, 32, 70, 65, 67, 69, 32, 237, 2, 5, 87, 73, 83, 69, 32, 48, 58, 69, 46, 70, 36, 2, 78, 73, 2, 79, 18, 83, 51, 84, 8, 120, 2, 76, 69, 125, 4, 73, 71, 72, 84, 8, 178, 1, 73, 25, 3, 79, 85, 82, 4, 155, 1, 78, 8, 26, 69, 125, 2, 73, 88, 4, 57, 2, 86, 69, 16, 38, 69, 14, 87, 41, 3, 72, 82, 69, 4, 63, 78, 8, 24, 2, 69, 76, - 27, 79, 4, 11, 86, 4, 11, 69, 4, 176, 153, 29, 2, 32, 79, 193, 179, 2, 3, + 27, 79, 4, 11, 86, 4, 11, 69, 4, 228, 140, 29, 2, 32, 79, 193, 179, 2, 3, 45, 84, 72, 22, 90, 67, 58, 68, 122, 71, 48, 5, 82, 73, 71, 72, 84, 226, - 2, 84, 122, 79, 195, 172, 31, 73, 4, 196, 1, 3, 76, 79, 83, 181, 103, 4, + 2, 84, 122, 79, 247, 159, 31, 73, 4, 196, 1, 3, 76, 79, 83, 181, 103, 4, 79, 78, 84, 79, 2, 141, 3, 26, 79, 87, 78, 87, 65, 82, 68, 83, 32, 65, 78, 68, 32, 85, 80, 87, 65, 82, 68, 83, 32, 79, 80, 69, 78, 32, 2, 21, 3, 65, 80, 80, 2, 133, 4, 2, 69, 68, 6, 228, 1, 14, 32, 65, 78, 68, 32, 76, 69, 70, 84, 32, 83, 69, 77, 73, 45, 38, 87, 65, 82, 68, 83, 32, 65, 78, 68, 32, 76, 69, 70, 84, 87, 65, 82, 68, 83, 32, 79, 80, 69, 78, 32, 67, - 73, 82, 67, 76, 69, 32, 65, 82, 82, 79, 87, 83, 2, 133, 217, 30, 6, 67, + 73, 82, 67, 76, 69, 32, 65, 82, 82, 79, 87, 83, 2, 185, 204, 30, 6, 67, 73, 82, 67, 76, 69, 5, 253, 85, 15, 32, 87, 73, 84, 72, 32, 67, 73, 82, 67, 76, 69, 68, 32, 79, 4, 82, 79, 37, 16, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 68, 32, 79, 2, 69, 6, 80, 32, 83, 69, 77, 73, 2, - 21, 3, 80, 69, 78, 2, 11, 32, 2, 165, 215, 30, 4, 67, 73, 82, 67, 26, 32, - 2, 68, 32, 219, 191, 32, 32, 24, 216, 1, 2, 83, 85, 66, 85, 162, 194, 19, + 21, 3, 80, 69, 78, 2, 11, 32, 2, 217, 202, 30, 4, 67, 73, 82, 67, 26, 32, + 2, 68, 32, 143, 179, 32, 32, 24, 216, 1, 2, 83, 85, 66, 85, 214, 181, 19, 77, 180, 3, 9, 76, 79, 67, 75, 32, 87, 73, 84, 72, 238, 151, 12, 66, 149, 152, 1, 23, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 78, 32, 87, 73, - 84, 72, 32, 83, 69, 82, 73, 70, 8, 30, 66, 1, 3, 80, 69, 82, 4, 185, 148, + 84, 72, 32, 83, 69, 82, 73, 70, 8, 30, 66, 1, 3, 80, 69, 82, 4, 237, 135, 25, 3, 83, 69, 84, 6, 82, 77, 33, 16, 78, 73, 79, 78, 32, 87, 73, 84, 72, - 32, 83, 69, 82, 73, 70, 83, 2, 149, 247, 24, 3, 66, 82, 69, 5, 237, 160, + 32, 83, 69, 82, 73, 70, 83, 2, 201, 234, 24, 3, 66, 82, 69, 5, 161, 148, 32, 9, 32, 65, 78, 68, 32, 83, 77, 65, 83, 11, 33, 6, 32, 87, 73, 84, 72, - 32, 8, 72, 4, 84, 79, 82, 78, 190, 172, 5, 76, 250, 239, 19, 83, 251, - 229, 6, 82, 2, 211, 241, 25, 65, 152, 10, 158, 1, 67, 82, 76, 98, 77, - 202, 86, 78, 220, 5, 2, 79, 75, 58, 80, 154, 19, 82, 138, 1, 85, 246, - 149, 28, 87, 232, 167, 3, 2, 70, 70, 246, 47, 73, 183, 51, 65, 6, 26, 75, - 155, 153, 4, 79, 4, 202, 244, 8, 82, 153, 161, 23, 4, 84, 65, 73, 76, 8, - 44, 2, 79, 78, 185, 158, 25, 3, 76, 73, 83, 7, 11, 32, 4, 150, 152, 26, + 32, 8, 72, 4, 84, 79, 82, 78, 138, 168, 5, 76, 226, 231, 19, 83, 251, + 229, 6, 82, 2, 135, 229, 25, 65, 152, 10, 158, 1, 67, 82, 76, 98, 77, + 202, 86, 78, 220, 5, 2, 79, 75, 58, 80, 154, 19, 82, 138, 1, 85, 170, + 137, 28, 87, 232, 167, 3, 2, 70, 70, 246, 47, 73, 183, 51, 65, 6, 26, 75, + 155, 153, 4, 79, 4, 150, 240, 8, 82, 129, 153, 23, 4, 84, 65, 73, 76, 8, + 44, 2, 79, 78, 237, 145, 25, 3, 76, 73, 83, 7, 11, 32, 4, 202, 139, 26, 69, 211, 143, 6, 83, 212, 6, 72, 7, 66, 73, 78, 73, 78, 71, 32, 206, 84, - 77, 94, 80, 139, 188, 32, 69, 196, 6, 210, 2, 65, 186, 2, 66, 118, 67, + 77, 94, 80, 191, 175, 32, 69, 196, 6, 210, 2, 65, 186, 2, 66, 118, 67, 246, 12, 68, 226, 10, 69, 142, 2, 70, 70, 71, 156, 9, 2, 72, 79, 82, 73, 248, 1, 2, 75, 65, 162, 1, 76, 158, 14, 77, 178, 2, 78, 78, 79, 138, 2, 80, 182, 1, 82, 248, 4, 5, 90, 73, 71, 90, 65, 138, 2, 83, 162, 4, 84, 238, 2, 85, 168, 1, 8, 86, 69, 82, 84, 73, 67, 65, 76, 204, 1, 2, 87, 73, - 171, 1, 88, 26, 148, 1, 4, 67, 85, 84, 69, 98, 78, 136, 156, 25, 6, 83, + 171, 1, 88, 26, 148, 1, 4, 67, 85, 84, 69, 98, 78, 188, 143, 25, 6, 83, 84, 69, 82, 73, 83, 241, 234, 5, 14, 76, 77, 79, 83, 84, 32, 69, 81, 85, - 65, 76, 32, 84, 79, 12, 22, 45, 231, 34, 32, 6, 186, 57, 86, 184, 160, + 65, 76, 32, 84, 79, 12, 22, 45, 231, 34, 32, 6, 186, 57, 86, 184, 152, 12, 6, 71, 82, 65, 86, 69, 45, 251, 210, 3, 77, 6, 228, 2, 4, 84, 73, 67, - 76, 237, 183, 3, 4, 78, 85, 73, 84, 12, 42, 82, 137, 247, 30, 4, 73, 78, - 68, 85, 10, 32, 3, 69, 86, 69, 243, 37, 73, 7, 210, 177, 12, 45, 159, - 197, 18, 32, 142, 1, 142, 1, 65, 34, 76, 98, 79, 116, 8, 89, 82, 73, 76, + 76, 237, 183, 3, 4, 78, 85, 73, 84, 12, 42, 82, 189, 234, 30, 4, 73, 78, + 68, 85, 10, 32, 3, 69, 86, 69, 243, 37, 73, 7, 210, 169, 12, 45, 211, + 192, 18, 32, 142, 1, 142, 1, 65, 34, 76, 98, 79, 116, 8, 89, 82, 73, 76, 76, 73, 67, 32, 252, 29, 11, 73, 82, 67, 85, 77, 70, 76, 69, 88, 32, 65, - 171, 162, 12, 69, 6, 222, 19, 82, 159, 245, 28, 78, 4, 41, 8, 79, 67, 75, - 87, 73, 83, 69, 32, 4, 248, 184, 12, 4, 82, 73, 78, 71, 139, 239, 16, 65, + 171, 154, 12, 69, 6, 222, 19, 82, 211, 232, 28, 78, 4, 41, 8, 79, 67, 75, + 87, 73, 83, 69, 32, 4, 248, 176, 12, 4, 82, 73, 78, 71, 191, 234, 16, 65, 10, 76, 4, 77, 77, 65, 32, 249, 17, 10, 78, 74, 79, 73, 78, 73, 78, 71, - 32, 77, 6, 142, 161, 13, 65, 251, 225, 17, 66, 116, 252, 1, 8, 72, 85, + 32, 77, 6, 142, 153, 13, 65, 175, 221, 17, 66, 116, 252, 1, 8, 72, 85, 78, 68, 82, 69, 68, 32, 32, 7, 76, 69, 84, 84, 69, 82, 32, 166, 5, 80, - 116, 5, 68, 65, 83, 73, 65, 38, 84, 106, 77, 230, 247, 2, 75, 220, 152, - 13, 15, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 66, 89, 169, - 213, 16, 2, 86, 90, 4, 194, 7, 77, 247, 162, 3, 84, 84, 238, 1, 66, 38, + 116, 5, 68, 65, 83, 73, 65, 38, 84, 106, 77, 230, 247, 2, 75, 220, 144, + 13, 15, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 66, 89, 221, + 208, 16, 2, 86, 90, 4, 194, 7, 77, 247, 162, 3, 84, 84, 238, 1, 66, 38, 68, 50, 69, 82, 73, 106, 79, 22, 83, 66, 85, 30, 89, 238, 141, 3, 76, - 140, 5, 5, 77, 79, 78, 79, 71, 150, 18, 72, 154, 241, 12, 84, 130, 135, + 140, 5, 5, 77, 79, 78, 79, 71, 150, 18, 72, 154, 233, 12, 84, 182, 130, 16, 90, 150, 83, 67, 2, 71, 182, 8, 70, 134, 14, 80, 2, 86, 158, 20, 75, - 187, 2, 65, 4, 142, 173, 6, 73, 179, 243, 26, 69, 4, 136, 130, 26, 3, 74, - 69, 82, 147, 158, 7, 69, 14, 58, 83, 178, 159, 33, 70, 2, 76, 2, 77, 2, - 78, 3, 82, 5, 155, 214, 31, 45, 11, 56, 8, 79, 84, 73, 70, 73, 69, 68, - 32, 227, 158, 33, 69, 6, 162, 171, 6, 66, 190, 243, 26, 65, 3, 69, 5, - 175, 217, 25, 77, 6, 26, 72, 139, 152, 16, 79, 4, 218, 160, 31, 67, 171, - 253, 1, 65, 5, 225, 157, 3, 2, 75, 82, 8, 198, 219, 28, 69, 210, 165, 4, - 65, 174, 28, 73, 3, 85, 8, 66, 65, 48, 4, 83, 73, 76, 73, 141, 230, 29, - 4, 79, 75, 82, 89, 4, 194, 250, 2, 89, 169, 242, 12, 3, 76, 65, 84, 2, + 187, 2, 65, 4, 218, 168, 6, 73, 155, 235, 26, 69, 4, 188, 245, 25, 3, 74, + 69, 82, 147, 158, 7, 69, 14, 58, 83, 230, 146, 33, 70, 2, 76, 2, 77, 2, + 78, 3, 82, 5, 207, 201, 31, 45, 11, 56, 8, 79, 84, 73, 70, 73, 69, 68, + 32, 151, 146, 33, 69, 6, 238, 166, 6, 66, 166, 235, 26, 65, 3, 69, 5, + 227, 204, 25, 77, 6, 26, 72, 139, 144, 16, 79, 4, 142, 148, 31, 67, 171, + 253, 1, 65, 5, 225, 157, 3, 2, 75, 82, 8, 250, 206, 28, 69, 210, 165, 4, + 65, 174, 28, 73, 3, 85, 8, 66, 65, 48, 4, 83, 73, 76, 73, 193, 217, 29, + 4, 79, 75, 82, 89, 4, 194, 250, 2, 89, 169, 234, 12, 3, 76, 65, 84, 2, 209, 14, 5, 32, 80, 78, 69, 85, 10, 80, 2, 69, 78, 0, 7, 72, 79, 85, 83, - 65, 78, 68, 237, 9, 4, 73, 84, 76, 79, 2, 17, 2, 32, 77, 2, 201, 254, 21, + 65, 78, 68, 237, 9, 4, 73, 84, 76, 79, 2, 17, 2, 32, 77, 2, 253, 241, 21, 5, 73, 76, 76, 73, 79, 124, 66, 69, 244, 1, 8, 73, 65, 69, 82, 69, 83, - 73, 83, 131, 1, 79, 38, 68, 9, 86, 65, 78, 65, 71, 65, 82, 73, 32, 177, - 176, 32, 2, 76, 69, 36, 92, 7, 76, 69, 84, 84, 69, 82, 32, 248, 155, 26, - 6, 83, 73, 71, 78, 32, 65, 251, 136, 5, 68, 14, 158, 133, 33, 86, 162, - 17, 75, 2, 78, 2, 80, 2, 82, 186, 2, 65, 3, 85, 9, 26, 32, 207, 130, 28, - 45, 4, 162, 246, 30, 66, 189, 142, 1, 16, 87, 73, 84, 72, 32, 82, 65, 73, + 73, 83, 131, 1, 79, 38, 68, 9, 86, 65, 78, 65, 71, 65, 82, 73, 32, 229, + 163, 32, 2, 76, 69, 36, 92, 7, 76, 69, 84, 84, 69, 82, 32, 172, 143, 26, + 6, 83, 73, 71, 78, 32, 65, 251, 136, 5, 68, 14, 210, 248, 32, 86, 162, + 17, 75, 2, 78, 2, 80, 2, 82, 186, 2, 65, 3, 85, 9, 26, 32, 131, 246, 27, + 45, 4, 214, 233, 30, 66, 189, 142, 1, 16, 87, 73, 84, 72, 32, 82, 65, 73, 83, 69, 68, 32, 76, 69, 70, 84, 78, 58, 84, 164, 1, 4, 85, 66, 76, 69, - 169, 5, 2, 87, 78, 16, 74, 32, 232, 186, 10, 5, 45, 65, 78, 68, 45, 161, - 226, 5, 3, 84, 69, 68, 10, 64, 5, 65, 66, 79, 86, 69, 217, 189, 6, 5, 66, - 69, 76, 79, 87, 7, 223, 234, 32, 32, 56, 22, 32, 247, 4, 68, 54, 222, 1, + 169, 5, 2, 87, 78, 16, 74, 32, 180, 182, 10, 5, 45, 65, 78, 68, 45, 213, + 222, 5, 3, 84, 69, 68, 10, 64, 5, 65, 66, 79, 86, 69, 165, 185, 6, 5, 66, + 69, 76, 79, 87, 7, 147, 222, 32, 32, 56, 22, 32, 247, 4, 68, 54, 222, 1, 65, 34, 66, 0, 10, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 26, 67, 34, 77, 54, 79, 34, 80, 68, 2, 82, 73, 48, 5, 84, 73, 76, 68, 69, 80, 9, 86, - 69, 82, 84, 73, 67, 65, 76, 32, 146, 152, 16, 71, 191, 187, 4, 76, 6, - 226, 17, 82, 131, 137, 16, 67, 4, 145, 17, 2, 82, 69, 4, 230, 235, 31, - 65, 135, 42, 73, 4, 21, 3, 65, 67, 82, 4, 165, 135, 17, 2, 79, 78, 4, - 138, 37, 80, 255, 130, 31, 86, 6, 146, 38, 76, 177, 233, 7, 9, 65, 82, - 69, 78, 84, 72, 69, 83, 69, 6, 240, 52, 4, 71, 72, 84, 87, 207, 129, 10, - 78, 7, 11, 32, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 219, 236, - 30, 84, 6, 182, 163, 12, 83, 175, 187, 14, 76, 2, 201, 146, 16, 2, 32, - 67, 6, 138, 51, 32, 207, 187, 31, 87, 18, 72, 9, 78, 67, 76, 79, 83, 73, + 69, 82, 84, 73, 67, 65, 76, 32, 146, 144, 16, 71, 243, 182, 4, 76, 6, + 226, 17, 82, 131, 129, 16, 67, 4, 145, 17, 2, 82, 69, 4, 154, 223, 31, + 65, 135, 42, 73, 4, 21, 3, 65, 67, 82, 4, 165, 255, 16, 2, 79, 78, 4, + 138, 37, 80, 179, 246, 30, 86, 6, 146, 38, 76, 253, 228, 7, 9, 65, 82, + 69, 78, 84, 72, 69, 83, 69, 6, 240, 52, 4, 71, 72, 84, 87, 155, 253, 9, + 78, 7, 11, 32, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 143, 224, + 30, 84, 6, 182, 155, 12, 83, 227, 182, 14, 76, 2, 201, 138, 16, 2, 32, + 67, 6, 138, 51, 32, 131, 175, 31, 87, 18, 72, 9, 78, 67, 76, 79, 83, 73, 78, 71, 32, 177, 35, 4, 81, 85, 65, 76, 14, 132, 1, 6, 67, 73, 82, 67, - 76, 69, 22, 83, 140, 170, 6, 3, 75, 69, 89, 240, 216, 19, 7, 85, 80, 87, - 65, 82, 68, 32, 171, 204, 5, 68, 5, 163, 198, 18, 32, 4, 182, 239, 25, - 67, 147, 252, 5, 81, 6, 48, 2, 69, 82, 206, 145, 5, 79, 251, 134, 12, 76, + 76, 69, 22, 83, 216, 165, 6, 3, 75, 69, 89, 216, 208, 19, 7, 85, 80, 87, + 65, 82, 68, 32, 171, 204, 5, 68, 5, 215, 185, 18, 32, 4, 234, 226, 25, + 67, 147, 252, 5, 81, 6, 48, 2, 69, 82, 154, 141, 5, 79, 175, 131, 12, 76, 2, 255, 76, 77, 128, 1, 88, 17, 76, 65, 71, 79, 76, 73, 84, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 143, 3, 82, 76, 238, 1, 68, 30, 73, 46, 83, - 50, 84, 210, 146, 6, 65, 22, 66, 94, 67, 134, 1, 70, 38, 71, 238, 2, 77, + 50, 84, 158, 142, 6, 65, 22, 66, 94, 67, 134, 1, 70, 38, 71, 238, 2, 77, 32, 2, 76, 74, 34, 78, 88, 2, 80, 79, 30, 82, 194, 2, 86, 22, 89, 90, 90, - 234, 145, 19, 72, 190, 133, 2, 85, 162, 177, 5, 79, 235, 5, 75, 4, 138, - 149, 6, 74, 31, 79, 11, 150, 150, 6, 78, 54, 79, 243, 198, 26, 90, 8, - 246, 150, 6, 77, 130, 4, 76, 247, 218, 22, 72, 4, 170, 155, 6, 86, 235, - 218, 26, 83, 52, 38, 65, 185, 3, 4, 69, 69, 75, 32, 38, 84, 5, 78, 84, - 72, 65, 32, 196, 1, 2, 86, 69, 137, 216, 28, 5, 80, 72, 69, 77, 69, 24, + 210, 137, 19, 72, 190, 133, 2, 85, 162, 177, 5, 79, 235, 5, 75, 4, 214, + 144, 6, 74, 31, 79, 11, 226, 145, 6, 78, 54, 79, 219, 190, 26, 90, 8, + 194, 146, 6, 77, 130, 4, 76, 223, 210, 22, 72, 4, 246, 150, 6, 86, 211, + 210, 26, 83, 52, 38, 65, 185, 3, 4, 69, 69, 75, 32, 38, 84, 5, 78, 84, + 72, 65, 32, 196, 1, 2, 86, 69, 189, 203, 28, 5, 80, 72, 69, 77, 69, 24, 68, 6, 68, 73, 71, 73, 84, 32, 65, 7, 76, 69, 84, 84, 69, 82, 32, 14, - 170, 247, 16, 83, 202, 157, 14, 70, 70, 84, 62, 90, 223, 86, 79, 10, 230, - 243, 32, 86, 162, 17, 75, 2, 78, 2, 80, 187, 2, 65, 12, 18, 32, 67, 45, - 6, 26, 65, 131, 184, 16, 84, 4, 237, 147, 4, 4, 67, 67, 69, 78, 6, 150, - 22, 86, 168, 250, 11, 6, 65, 67, 85, 84, 69, 45, 139, 249, 3, 77, 14, - 148, 1, 8, 77, 85, 83, 73, 67, 65, 76, 32, 130, 155, 4, 75, 170, 202, 2, - 80, 174, 4, 89, 217, 239, 3, 11, 68, 73, 65, 76, 89, 84, 73, 75, 65, 32, - 84, 6, 26, 84, 255, 203, 15, 80, 4, 214, 204, 15, 69, 35, 82, 6, 146, - 130, 13, 79, 128, 133, 19, 8, 77, 79, 84, 72, 69, 84, 73, 67, 167, 45, - 82, 16, 26, 78, 151, 210, 30, 83, 14, 52, 7, 86, 69, 82, 84, 69, 68, 32, - 243, 209, 28, 70, 12, 60, 2, 66, 82, 69, 9, 68, 79, 85, 66, 76, 69, 32, - 65, 82, 8, 18, 69, 23, 73, 4, 203, 232, 11, 86, 4, 233, 223, 30, 2, 68, - 71, 4, 11, 67, 4, 207, 223, 30, 72, 8, 128, 1, 16, 84, 65, 75, 65, 78, - 65, 45, 72, 73, 82, 65, 71, 65, 78, 65, 32, 229, 250, 17, 9, 86, 89, 75, - 65, 32, 65, 66, 79, 86, 4, 242, 139, 10, 83, 35, 86, 162, 1, 80, 5, 65, + 170, 239, 16, 83, 254, 152, 14, 70, 70, 84, 62, 90, 223, 86, 79, 10, 154, + 231, 32, 86, 162, 17, 75, 2, 78, 2, 80, 187, 2, 65, 12, 18, 32, 67, 45, + 6, 26, 65, 131, 176, 16, 84, 4, 237, 147, 4, 4, 67, 67, 69, 78, 6, 150, + 22, 86, 168, 242, 11, 6, 65, 67, 85, 84, 69, 45, 139, 249, 3, 77, 14, + 148, 1, 8, 77, 85, 83, 73, 67, 65, 76, 32, 130, 155, 4, 75, 246, 197, 2, + 80, 174, 4, 89, 141, 236, 3, 11, 68, 73, 65, 76, 89, 84, 73, 75, 65, 32, + 84, 6, 26, 84, 255, 195, 15, 80, 4, 214, 196, 15, 69, 35, 82, 6, 146, + 250, 12, 79, 180, 128, 19, 8, 77, 79, 84, 72, 69, 84, 73, 67, 167, 45, + 82, 16, 26, 78, 203, 197, 30, 83, 14, 52, 7, 86, 69, 82, 84, 69, 68, 32, + 167, 197, 28, 70, 12, 60, 2, 66, 82, 69, 9, 68, 79, 85, 66, 76, 69, 32, + 65, 82, 8, 18, 69, 23, 73, 4, 203, 224, 11, 86, 4, 157, 211, 30, 2, 68, + 71, 4, 11, 67, 4, 131, 211, 30, 72, 8, 128, 1, 16, 84, 65, 75, 65, 78, + 65, 45, 72, 73, 82, 65, 71, 65, 78, 65, 32, 229, 242, 17, 9, 86, 89, 75, + 65, 32, 65, 66, 79, 86, 4, 190, 135, 10, 83, 35, 86, 162, 1, 80, 5, 65, 84, 73, 78, 32, 164, 8, 3, 69, 70, 84, 232, 3, 2, 73, 71, 83, 79, 106, 156, 1, 21, 76, 69, 84, 84, 69, 82, 32, 83, 77, 65, 76, 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, 53, 13, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, - 69, 82, 32, 10, 182, 254, 32, 71, 2, 76, 2, 77, 2, 78, 3, 82, 96, 226, 1, + 69, 82, 32, 10, 234, 241, 32, 71, 2, 76, 2, 77, 2, 78, 3, 82, 96, 226, 1, 65, 70, 67, 34, 69, 30, 70, 78, 73, 86, 76, 106, 79, 2, 85, 134, 1, 82, - 50, 84, 158, 183, 12, 83, 162, 151, 2, 66, 238, 157, 2, 87, 190, 139, 16, + 50, 84, 158, 175, 12, 83, 162, 151, 2, 66, 238, 157, 2, 87, 242, 134, 16, 68, 2, 71, 2, 72, 2, 75, 2, 77, 2, 78, 2, 80, 2, 86, 2, 88, 3, 90, 13, - 182, 246, 2, 32, 226, 169, 26, 76, 138, 220, 3, 69, 2, 79, 3, 86, 5, 173, - 151, 12, 3, 32, 67, 69, 7, 170, 250, 32, 83, 3, 84, 5, 225, 207, 27, 14, + 182, 246, 2, 32, 150, 157, 26, 76, 138, 220, 3, 69, 2, 79, 3, 86, 5, 173, + 143, 12, 3, 32, 67, 69, 7, 222, 237, 32, 83, 3, 84, 5, 149, 195, 27, 14, 76, 65, 84, 84, 69, 78, 69, 68, 32, 79, 80, 69, 78, 32, 11, 37, 7, 78, - 83, 85, 76, 65, 82, 32, 8, 170, 250, 32, 68, 2, 71, 2, 82, 3, 84, 7, 148, - 151, 16, 14, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, 69, 32, 77, 133, - 233, 12, 3, 79, 78, 71, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 146, 167, - 12, 68, 209, 233, 12, 15, 76, 73, 71, 72, 84, 32, 67, 69, 78, 84, 82, 65, - 76, 73, 90, 7, 11, 32, 4, 210, 133, 12, 82, 203, 208, 18, 66, 5, 201, - 198, 30, 7, 85, 82, 78, 69, 68, 32, 87, 36, 46, 32, 133, 3, 6, 87, 65, + 83, 85, 76, 65, 82, 32, 8, 222, 237, 32, 68, 2, 71, 2, 82, 3, 84, 7, 148, + 143, 16, 14, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, 69, 32, 77, 185, + 228, 12, 3, 79, 78, 71, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 146, 159, + 12, 68, 133, 229, 12, 15, 76, 73, 71, 72, 84, 32, 67, 69, 78, 84, 82, 65, + 76, 73, 90, 7, 11, 32, 4, 210, 253, 11, 82, 255, 203, 18, 66, 5, 253, + 185, 30, 7, 85, 82, 78, 69, 68, 32, 87, 36, 46, 32, 133, 3, 6, 87, 65, 82, 68, 83, 32, 32, 122, 65, 192, 1, 12, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 32, 166, 13, 72, 154, 10, 84, 57, 5, 82, 73, 71, 72, 84, 14, 52, 5, 78, 71, 76, 69, 32, 77, 4, 82, 82, 79, 87, 6, 140, 253, 3, 6, 67, - 69, 78, 84, 82, 69, 214, 214, 26, 66, 131, 165, 1, 65, 8, 26, 72, 227, - 210, 30, 32, 4, 209, 210, 30, 3, 69, 65, 68, 4, 144, 232, 7, 4, 65, 66, - 79, 86, 241, 217, 24, 5, 66, 69, 76, 79, 87, 4, 142, 14, 72, 245, 248, + 69, 78, 84, 82, 69, 138, 202, 26, 66, 131, 165, 1, 65, 8, 26, 72, 151, + 198, 30, 32, 4, 133, 198, 30, 3, 69, 65, 68, 4, 220, 227, 7, 4, 65, 66, + 79, 86, 217, 209, 24, 5, 66, 69, 76, 79, 87, 4, 142, 14, 72, 245, 240, 11, 5, 65, 82, 82, 79, 87, 10, 52, 6, 65, 84, 85, 82, 69, 32, 129, 18, 2, - 72, 84, 8, 234, 1, 76, 23, 82, 10, 36, 3, 78, 71, 32, 131, 215, 31, 87, + 72, 84, 8, 234, 1, 76, 23, 82, 10, 36, 3, 78, 71, 32, 183, 202, 31, 87, 8, 236, 7, 7, 68, 79, 85, 66, 76, 69, 32, 242, 7, 83, 71, 86, 26, 48, 5, 65, 67, 82, 79, 78, 205, 5, 2, 73, 78, 23, 18, 32, 127, 45, 10, 34, 76, - 22, 82, 171, 207, 30, 66, 4, 41, 2, 69, 70, 4, 21, 3, 73, 71, 72, 4, 189, - 229, 16, 6, 84, 32, 72, 65, 76, 70, 10, 54, 86, 250, 20, 65, 150, 148, - 12, 71, 235, 176, 3, 66, 2, 205, 212, 31, 8, 69, 82, 84, 73, 67, 65, 76, - 45, 4, 164, 9, 9, 85, 77, 66, 69, 82, 32, 83, 73, 71, 129, 223, 11, 2, + 22, 82, 223, 194, 30, 66, 4, 41, 2, 69, 70, 4, 21, 3, 73, 71, 72, 4, 189, + 221, 16, 6, 84, 32, 72, 65, 76, 70, 10, 54, 86, 250, 20, 65, 150, 140, + 12, 71, 235, 176, 3, 66, 2, 129, 200, 31, 8, 69, 82, 84, 73, 67, 65, 76, + 45, 4, 164, 9, 9, 85, 77, 66, 69, 82, 32, 83, 73, 71, 129, 215, 11, 2, 79, 84, 18, 136, 1, 17, 76, 68, 32, 80, 69, 82, 77, 73, 67, 32, 76, 69, - 84, 84, 69, 82, 32, 82, 80, 216, 166, 12, 4, 71, 79, 78, 69, 167, 220, - 18, 86, 10, 198, 45, 90, 142, 163, 18, 78, 182, 166, 9, 68, 186, 176, 2, - 83, 239, 246, 1, 65, 2, 229, 224, 24, 6, 69, 78, 32, 77, 65, 82, 12, 18, - 65, 107, 76, 8, 220, 7, 9, 82, 69, 78, 84, 72, 69, 83, 69, 83, 173, 216, - 24, 9, 76, 65, 84, 65, 76, 73, 90, 69, 68, 4, 11, 85, 4, 241, 201, 30, 6, + 84, 84, 69, 82, 32, 82, 80, 216, 158, 12, 4, 71, 79, 78, 69, 219, 215, + 18, 86, 10, 198, 45, 90, 194, 150, 18, 78, 182, 166, 9, 68, 186, 176, 2, + 83, 239, 246, 1, 65, 2, 153, 212, 24, 6, 69, 78, 32, 77, 65, 82, 12, 18, + 65, 107, 76, 8, 220, 7, 9, 82, 69, 78, 84, 72, 69, 83, 69, 83, 225, 203, + 24, 9, 76, 65, 84, 65, 76, 73, 90, 69, 68, 4, 11, 85, 4, 165, 189, 30, 6, 83, 32, 83, 73, 71, 78, 40, 18, 69, 127, 73, 6, 72, 5, 86, 69, 82, 83, - 69, 141, 222, 24, 7, 84, 82, 79, 70, 76, 69, 88, 4, 22, 32, 251, 12, 68, + 69, 193, 209, 24, 7, 84, 82, 79, 70, 76, 69, 88, 4, 22, 32, 251, 12, 68, 2, 137, 8, 2, 83, 79, 34, 40, 3, 71, 72, 84, 133, 5, 2, 78, 71, 28, 50, 32, 253, 3, 7, 87, 65, 82, 68, 83, 32, 72, 26, 108, 5, 65, 82, 82, 79, 87, 218, 1, 72, 124, 12, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 32, - 159, 9, 84, 12, 44, 5, 72, 69, 65, 68, 32, 199, 198, 30, 32, 8, 26, 65, - 199, 198, 30, 66, 6, 36, 3, 78, 68, 32, 171, 235, 31, 66, 4, 40, 4, 68, - 79, 87, 78, 1, 2, 85, 80, 2, 249, 231, 8, 9, 32, 65, 82, 82, 79, 87, 72, + 159, 9, 84, 12, 44, 5, 72, 69, 65, 68, 32, 251, 185, 30, 32, 8, 26, 65, + 251, 185, 30, 66, 6, 36, 3, 78, 68, 32, 223, 222, 31, 66, 4, 40, 4, 68, + 79, 87, 78, 1, 2, 85, 80, 2, 197, 227, 8, 9, 32, 65, 82, 82, 79, 87, 72, 69, 65, 6, 11, 65, 6, 48, 6, 76, 70, 32, 82, 73, 78, 21, 2, 82, 80, 4, - 207, 196, 30, 71, 2, 17, 2, 79, 79, 2, 183, 233, 31, 78, 4, 146, 228, 9, - 65, 245, 174, 21, 5, 66, 69, 76, 79, 87, 2, 185, 161, 21, 16, 65, 82, 80, + 131, 184, 30, 71, 2, 17, 2, 79, 79, 2, 235, 220, 31, 78, 4, 222, 223, 9, + 65, 221, 166, 21, 5, 66, 69, 76, 79, 87, 2, 237, 148, 21, 16, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, 72, 32, 66, 65, 82, 66, 6, 11, 32, 6, 166, - 248, 11, 79, 254, 202, 18, 66, 131, 165, 1, 65, 24, 166, 1, 72, 204, 1, + 240, 11, 79, 178, 198, 18, 66, 131, 165, 1, 65, 24, 166, 1, 72, 204, 1, 6, 81, 85, 65, 82, 69, 32, 84, 5, 84, 82, 79, 78, 71, 128, 195, 3, 2, 85, - 83, 236, 145, 21, 2, 78, 65, 149, 234, 5, 6, 69, 65, 71, 85, 76, 76, 8, - 40, 4, 79, 82, 84, 32, 187, 194, 16, 65, 6, 18, 83, 71, 86, 4, 26, 79, - 187, 245, 11, 84, 2, 217, 245, 11, 5, 76, 73, 68, 85, 83, 2, 49, 10, 69, - 82, 84, 73, 67, 65, 76, 32, 76, 73, 2, 243, 244, 11, 78, 6, 26, 66, 227, - 228, 31, 65, 4, 216, 222, 7, 5, 82, 65, 67, 75, 69, 147, 225, 22, 69, 2, - 209, 212, 24, 17, 32, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, 84, 73, 79, + 83, 160, 133, 21, 2, 78, 65, 149, 234, 5, 6, 69, 65, 71, 85, 76, 76, 8, + 40, 4, 79, 82, 84, 32, 187, 186, 16, 65, 6, 18, 83, 71, 86, 4, 26, 79, + 187, 237, 11, 84, 2, 217, 237, 11, 5, 76, 73, 68, 85, 83, 2, 49, 10, 69, + 82, 84, 73, 67, 65, 76, 32, 76, 73, 2, 243, 236, 11, 78, 6, 26, 66, 151, + 216, 31, 65, 4, 164, 218, 7, 5, 82, 65, 67, 75, 69, 251, 216, 22, 69, 2, + 133, 200, 24, 17, 32, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, 84, 73, 79, 78, 32, 83, 20, 98, 72, 32, 4, 73, 76, 68, 69, 136, 1, 6, 82, 73, 80, 76, - 69, 32, 69, 5, 85, 82, 78, 69, 68, 2, 205, 220, 7, 3, 82, 69, 69, 11, 11, - 32, 8, 76, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 246, 241, 11, 79, 255, - 202, 18, 66, 2, 193, 173, 30, 6, 84, 32, 72, 65, 76, 70, 6, 178, 229, 15, - 65, 216, 229, 15, 5, 85, 78, 68, 69, 82, 239, 66, 68, 2, 249, 191, 15, 2, - 32, 67, 12, 34, 80, 170, 224, 31, 82, 3, 83, 8, 18, 32, 43, 87, 4, 11, - 84, 4, 133, 208, 24, 2, 65, 67, 4, 25, 4, 65, 82, 68, 83, 4, 189, 186, + 69, 32, 69, 5, 85, 82, 78, 69, 68, 2, 153, 216, 7, 3, 82, 69, 69, 11, 11, + 32, 8, 76, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 246, 233, 11, 79, 179, + 198, 18, 66, 2, 245, 160, 30, 6, 84, 32, 72, 65, 76, 70, 6, 178, 221, 15, + 65, 140, 225, 15, 5, 85, 78, 68, 69, 82, 239, 66, 68, 2, 249, 183, 15, 2, + 32, 67, 12, 34, 80, 222, 211, 31, 82, 3, 83, 8, 18, 32, 43, 87, 4, 11, + 84, 4, 185, 195, 24, 2, 65, 67, 4, 25, 4, 65, 82, 68, 83, 4, 241, 173, 30, 6, 32, 65, 82, 82, 79, 87, 16, 42, 32, 37, 6, 45, 76, 73, 78, 69, 45, - 6, 250, 169, 26, 76, 175, 202, 2, 84, 10, 54, 65, 48, 5, 71, 82, 65, 86, - 69, 139, 222, 15, 77, 4, 25, 4, 67, 85, 84, 69, 5, 147, 229, 11, 45, 5, - 143, 139, 12, 45, 6, 52, 3, 68, 69, 32, 137, 238, 11, 4, 71, 71, 76, 89, - 4, 132, 206, 24, 14, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 82, 73, 68, - 71, 149, 229, 4, 5, 66, 82, 73, 68, 71, 6, 194, 245, 11, 45, 235, 193, - 18, 32, 6, 52, 7, 69, 82, 67, 73, 65, 76, 32, 219, 216, 32, 65, 4, 166, - 166, 29, 77, 135, 150, 3, 65, 8, 158, 166, 8, 82, 228, 161, 16, 3, 79, + 6, 174, 157, 26, 76, 175, 202, 2, 84, 10, 54, 65, 48, 5, 71, 82, 65, 86, + 69, 139, 214, 15, 77, 4, 25, 4, 67, 85, 84, 69, 5, 147, 221, 11, 45, 5, + 143, 131, 12, 45, 6, 52, 3, 68, 69, 32, 137, 230, 11, 4, 71, 71, 76, 89, + 4, 184, 193, 24, 14, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 82, 73, 68, + 71, 149, 229, 4, 5, 66, 82, 73, 68, 71, 6, 194, 237, 11, 45, 159, 189, + 18, 32, 6, 52, 7, 69, 82, 67, 73, 65, 76, 32, 143, 204, 32, 65, 4, 218, + 153, 29, 77, 135, 150, 3, 65, 8, 234, 161, 8, 82, 204, 153, 16, 3, 79, 83, 73, 250, 244, 2, 76, 231, 130, 4, 65, 38, 214, 1, 70, 84, 10, 83, 84, 82, 85, 67, 84, 73, 79, 78, 32, 46, 84, 252, 235, 2, 8, 86, 69, 78, 73, - 69, 78, 67, 69, 204, 195, 18, 6, 73, 67, 65, 76, 32, 84, 234, 189, 9, 74, - 217, 102, 7, 71, 82, 85, 69, 78, 84, 32, 6, 140, 173, 27, 4, 69, 84, 84, - 73, 150, 242, 1, 85, 245, 163, 2, 4, 79, 85, 78, 68, 4, 240, 221, 20, 2, + 69, 78, 67, 69, 128, 183, 18, 6, 73, 67, 65, 76, 32, 84, 234, 189, 9, 74, + 217, 102, 7, 71, 82, 85, 69, 78, 84, 32, 6, 192, 160, 27, 4, 69, 84, 84, + 73, 150, 242, 1, 85, 245, 163, 2, 4, 79, 85, 78, 68, 4, 164, 209, 20, 2, 87, 79, 223, 240, 10, 83, 20, 80, 5, 65, 73, 78, 83, 32, 198, 1, 79, 28, 4, 82, 79, 76, 32, 183, 146, 3, 73, 12, 48, 3, 65, 83, 32, 93, 5, 87, 73, - 84, 72, 32, 6, 186, 172, 24, 77, 181, 8, 15, 78, 79, 82, 77, 65, 76, 32, - 83, 85, 66, 71, 82, 79, 85, 80, 6, 250, 195, 4, 76, 202, 233, 19, 86, - 239, 243, 4, 79, 2, 229, 200, 30, 2, 85, 82, 4, 144, 251, 19, 3, 75, 78, + 84, 72, 32, 6, 238, 159, 24, 77, 181, 8, 15, 78, 79, 82, 77, 65, 76, 32, + 83, 85, 66, 71, 82, 79, 85, 80, 6, 198, 191, 4, 76, 178, 225, 19, 86, + 239, 243, 4, 79, 2, 153, 188, 30, 2, 85, 82, 4, 196, 238, 19, 3, 75, 78, 79, 173, 134, 4, 8, 83, 69, 81, 85, 69, 78, 67, 69, 6, 26, 73, 147, 158, - 2, 69, 4, 150, 209, 32, 78, 87, 69, 206, 2, 36, 4, 84, 73, 67, 32, 175, + 2, 69, 4, 202, 196, 32, 78, 87, 69, 206, 2, 36, 4, 84, 73, 67, 32, 175, 18, 89, 202, 2, 186, 1, 67, 204, 1, 6, 69, 80, 65, 67, 84, 32, 86, 70, - 36, 11, 79, 76, 68, 32, 78, 85, 66, 73, 65, 78, 32, 110, 83, 213, 146, + 36, 11, 79, 76, 68, 32, 78, 85, 66, 73, 65, 78, 32, 110, 83, 137, 134, 29, 13, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 76, 126, 76, 9, 79, 77, 66, 73, 78, 73, 78, 71, 32, 161, 3, 5, 65, 80, 73, 84, 65, 6, 68, - 9, 83, 80, 73, 82, 73, 84, 85, 83, 32, 201, 209, 31, 2, 78, 73, 4, 128, - 156, 6, 2, 76, 69, 181, 144, 17, 2, 65, 83, 56, 158, 188, 21, 78, 170, - 198, 2, 68, 141, 250, 6, 8, 84, 72, 79, 85, 83, 65, 78, 68, 4, 218, 187, - 18, 82, 195, 188, 11, 85, 8, 58, 68, 0, 3, 73, 78, 68, 146, 15, 86, 163, - 232, 29, 70, 2, 253, 247, 29, 7, 73, 82, 69, 67, 84, 32, 81, 134, 1, 56, + 9, 83, 80, 73, 82, 73, 84, 85, 83, 32, 253, 196, 31, 2, 78, 73, 4, 204, + 151, 6, 2, 76, 69, 157, 136, 17, 2, 65, 83, 56, 210, 175, 21, 78, 170, + 198, 2, 68, 141, 250, 6, 8, 84, 72, 79, 85, 83, 65, 78, 68, 4, 142, 175, + 18, 82, 195, 188, 11, 85, 8, 58, 68, 0, 3, 73, 78, 68, 146, 15, 86, 215, + 219, 29, 70, 2, 177, 235, 29, 7, 73, 82, 69, 67, 84, 32, 81, 134, 1, 56, 3, 77, 65, 76, 197, 11, 6, 89, 77, 66, 79, 76, 32, 120, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 120, 138, 2, 65, 48, 6, 66, 79, 72, 65, 73, 82, 32, 2, 67, 82, 170, 1, 68, 160, 1, 2, 71, 65, 34, 72, 38, 75, 46, 70, - 34, 76, 66, 79, 138, 3, 83, 90, 84, 46, 90, 202, 218, 5, 86, 214, 54, 80, - 170, 211, 3, 73, 142, 189, 22, 82, 198, 3, 69, 218, 7, 77, 2, 78, 163, - 17, 85, 4, 44, 5, 75, 72, 77, 73, 77, 171, 208, 19, 76, 2, 177, 1, 4, 73, + 34, 76, 66, 79, 138, 3, 83, 90, 84, 46, 90, 150, 214, 5, 86, 214, 54, 80, + 170, 211, 3, 73, 246, 180, 22, 82, 198, 3, 69, 218, 7, 77, 2, 78, 163, + 17, 85, 4, 44, 5, 75, 72, 77, 73, 77, 223, 195, 19, 76, 2, 177, 1, 4, 73, 67, 32, 75, 10, 92, 12, 89, 80, 84, 79, 71, 82, 65, 77, 77, 73, 67, 32, - 53, 7, 79, 83, 83, 69, 68, 32, 83, 8, 50, 83, 226, 4, 71, 198, 167, 32, - 69, 219, 7, 78, 2, 187, 240, 24, 72, 12, 80, 9, 73, 65, 76, 69, 67, 84, - 45, 80, 32, 232, 161, 32, 2, 65, 76, 175, 17, 69, 8, 206, 163, 8, 72, - 174, 158, 8, 65, 200, 199, 12, 2, 75, 65, 211, 169, 3, 78, 4, 190, 3, 78, - 211, 161, 32, 77, 4, 178, 218, 25, 79, 187, 162, 5, 65, 8, 42, 72, 138, - 136, 29, 65, 211, 169, 3, 83, 4, 214, 177, 32, 69, 219, 19, 73, 4, 252, - 205, 19, 7, 45, 83, 72, 65, 80, 69, 68, 239, 251, 7, 65, 35, 36, 3, 76, - 68, 32, 195, 159, 32, 79, 30, 76, 7, 67, 79, 80, 84, 73, 67, 32, 193, 1, + 53, 7, 79, 83, 83, 69, 68, 32, 83, 8, 50, 83, 226, 4, 71, 250, 154, 32, + 69, 219, 7, 78, 2, 239, 227, 24, 72, 12, 80, 9, 73, 65, 76, 69, 67, 84, + 45, 80, 32, 156, 149, 32, 2, 65, 76, 175, 17, 69, 8, 154, 159, 8, 72, + 226, 154, 8, 65, 252, 194, 12, 2, 75, 65, 211, 169, 3, 78, 4, 190, 3, 78, + 135, 149, 32, 77, 4, 230, 205, 25, 79, 187, 162, 5, 65, 8, 42, 72, 190, + 251, 28, 65, 211, 169, 3, 83, 4, 138, 165, 32, 69, 219, 19, 73, 4, 176, + 193, 19, 7, 45, 83, 72, 65, 80, 69, 68, 239, 251, 7, 65, 35, 36, 3, 76, + 68, 32, 247, 146, 32, 79, 30, 76, 7, 67, 79, 80, 84, 73, 67, 32, 193, 1, 7, 78, 85, 66, 73, 65, 78, 32, 22, 98, 71, 42, 72, 188, 1, 2, 83, 72, - 162, 236, 14, 68, 238, 253, 9, 79, 254, 235, 5, 69, 183, 107, 65, 2, 17, - 2, 65, 78, 2, 231, 137, 16, 71, 8, 254, 214, 25, 79, 246, 130, 1, 65, - 131, 213, 5, 69, 8, 50, 78, 172, 192, 16, 2, 83, 72, 223, 158, 5, 87, 4, - 138, 174, 32, 71, 3, 89, 10, 54, 72, 238, 157, 6, 65, 190, 254, 25, 79, - 219, 3, 73, 4, 254, 159, 32, 73, 187, 13, 69, 4, 224, 147, 32, 3, 72, 69, - 84, 167, 8, 65, 2, 247, 155, 32, 65, 14, 62, 75, 30, 77, 2, 80, 22, 83, - 133, 132, 28, 3, 84, 65, 85, 4, 26, 72, 255, 171, 32, 65, 2, 151, 132, - 28, 73, 4, 132, 190, 16, 6, 72, 73, 77, 65, 32, 83, 193, 255, 3, 3, 84, - 65, 85, 4, 164, 220, 24, 3, 76, 69, 70, 133, 151, 2, 4, 82, 73, 71, 72, - 6, 96, 6, 78, 73, 83, 72, 32, 86, 188, 220, 25, 8, 82, 69, 83, 80, 79, - 78, 68, 83, 203, 213, 5, 65, 2, 241, 131, 29, 4, 69, 82, 83, 69, 44, 104, - 2, 78, 84, 192, 132, 3, 6, 67, 72, 32, 65, 78, 68, 201, 176, 28, 8, 80, + 162, 228, 14, 68, 162, 249, 9, 79, 254, 235, 5, 69, 183, 107, 65, 2, 17, + 2, 65, 78, 2, 231, 129, 16, 71, 8, 178, 202, 25, 79, 246, 130, 1, 65, + 131, 213, 5, 69, 8, 50, 78, 172, 184, 16, 2, 83, 72, 147, 154, 5, 87, 4, + 190, 161, 32, 71, 3, 89, 10, 54, 72, 186, 153, 6, 65, 166, 246, 25, 79, + 219, 3, 73, 4, 178, 147, 32, 73, 187, 13, 69, 4, 148, 135, 32, 3, 72, 69, + 84, 167, 8, 65, 2, 171, 143, 32, 65, 14, 62, 75, 30, 77, 2, 80, 22, 83, + 185, 247, 27, 3, 84, 65, 85, 4, 26, 72, 179, 159, 32, 65, 2, 203, 247, + 27, 73, 4, 132, 182, 16, 6, 72, 73, 77, 65, 32, 83, 245, 250, 3, 3, 84, + 65, 85, 4, 216, 207, 24, 3, 76, 69, 70, 133, 151, 2, 4, 82, 73, 71, 72, + 6, 96, 6, 78, 73, 83, 72, 32, 86, 240, 207, 25, 8, 82, 69, 83, 80, 79, + 78, 68, 83, 203, 213, 5, 65, 2, 165, 247, 28, 4, 69, 82, 83, 69, 44, 104, + 2, 78, 84, 192, 132, 3, 6, 67, 72, 32, 65, 78, 68, 253, 163, 28, 8, 80, 76, 69, 32, 87, 73, 84, 72, 40, 56, 2, 69, 82, 37, 8, 73, 78, 71, 32, 82, - 79, 68, 32, 4, 246, 206, 27, 66, 167, 136, 1, 83, 36, 48, 4, 84, 69, 78, - 83, 1, 4, 85, 78, 73, 84, 18, 221, 239, 23, 2, 32, 68, 51, 82, 69, 76, 5, - 73, 67, 75, 69, 84, 34, 79, 198, 5, 85, 50, 89, 235, 245, 30, 65, 4, 240, - 175, 8, 3, 68, 73, 84, 165, 224, 20, 7, 83, 67, 69, 78, 84, 32, 77, 5, - 205, 144, 27, 3, 32, 66, 65, 28, 84, 2, 83, 83, 180, 144, 30, 3, 67, 79, + 79, 68, 32, 4, 170, 194, 27, 66, 167, 136, 1, 83, 36, 48, 4, 84, 69, 78, + 83, 1, 4, 85, 78, 73, 84, 18, 145, 227, 23, 2, 32, 68, 51, 82, 69, 76, 5, + 73, 67, 75, 69, 84, 34, 79, 198, 5, 85, 50, 89, 159, 233, 30, 65, 4, 188, + 171, 8, 3, 68, 73, 84, 141, 216, 20, 7, 83, 67, 69, 78, 84, 32, 77, 5, + 129, 132, 27, 3, 32, 66, 65, 28, 84, 2, 83, 83, 232, 131, 30, 3, 67, 79, 68, 208, 156, 1, 3, 73, 83, 83, 155, 60, 87, 22, 46, 32, 184, 2, 3, 69, - 68, 32, 223, 1, 73, 14, 44, 3, 79, 70, 32, 82, 80, 163, 246, 31, 77, 4, - 216, 202, 28, 6, 74, 69, 82, 85, 83, 65, 133, 210, 2, 5, 76, 79, 82, 82, + 68, 32, 223, 1, 73, 14, 44, 3, 79, 70, 32, 82, 80, 215, 233, 31, 77, 4, + 140, 190, 28, 6, 74, 69, 82, 85, 83, 65, 133, 210, 2, 5, 76, 79, 82, 82, 65, 8, 76, 10, 65, 84, 84, 89, 32, 87, 73, 84, 72, 32, 41, 5, 79, 77, 77, - 69, 69, 4, 206, 173, 10, 82, 25, 3, 76, 69, 70, 5, 225, 161, 3, 11, 32, - 87, 73, 84, 72, 32, 72, 65, 76, 70, 45, 6, 168, 152, 25, 37, 78, 69, 71, + 69, 69, 4, 206, 165, 10, 82, 25, 3, 76, 69, 70, 5, 225, 161, 3, 11, 32, + 87, 73, 84, 72, 32, 72, 65, 76, 70, 45, 6, 220, 139, 25, 37, 78, 69, 71, 65, 84, 73, 86, 69, 32, 83, 81, 85, 65, 82, 69, 68, 32, 76, 65, 84, 73, 78, 32, 67, 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 248, 226, - 2, 2, 70, 76, 177, 216, 2, 3, 83, 87, 79, 2, 233, 254, 23, 5, 78, 71, 32, - 76, 65, 4, 184, 214, 17, 3, 90, 69, 73, 175, 187, 14, 84, 6, 214, 234, + 2, 2, 70, 76, 177, 216, 2, 3, 83, 87, 79, 2, 157, 242, 23, 5, 78, 71, 32, + 76, 65, 4, 176, 206, 17, 3, 90, 69, 73, 235, 182, 14, 84, 6, 138, 222, 19, 73, 141, 160, 7, 4, 83, 84, 65, 76, 206, 19, 154, 1, 66, 20, 8, 78, 69, 73, 70, 79, 82, 77, 32, 154, 250, 1, 80, 114, 82, 180, 3, 2, 83, 84, - 226, 234, 15, 67, 161, 191, 13, 6, 84, 32, 79, 70, 32, 77, 2, 179, 182, + 150, 222, 15, 67, 161, 191, 13, 6, 84, 32, 79, 70, 32, 77, 2, 255, 177, 5, 69, 170, 19, 176, 1, 13, 78, 85, 77, 69, 82, 73, 67, 32, 83, 73, 71, 78, 32, 184, 20, 17, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 83, 73, 71, 78, 32, 233, 1, 5, 83, 73, 71, 78, 32, 222, 1, 78, 69, 166, 2, 70, 152, 3, 2, 78, 73, 154, 2, 79, 130, 3, 83, 151, 4, 84, 24, 68, 5, 73, 71, 72, 84, 32, 153, 1, 7, 76, 65, 77, 73, 84, 69, 32, 16, 142, 14, 83, 230, 113, 85, 238, 50, 71, 136, 56, 17, 86, 65, 82, 73, 65, 78, 84, 32, - 70, 79, 82, 77, 32, 85, 83, 83, 85, 242, 223, 26, 68, 199, 249, 1, 65, 8, - 252, 155, 21, 5, 79, 78, 69, 32, 84, 234, 160, 9, 70, 175, 14, 84, 58, + 70, 79, 82, 77, 32, 85, 83, 83, 85, 166, 211, 26, 68, 199, 249, 1, 65, 8, + 176, 143, 21, 5, 79, 78, 69, 32, 84, 234, 160, 9, 70, 175, 14, 84, 58, 48, 4, 73, 86, 69, 32, 125, 4, 79, 85, 82, 32, 26, 70, 83, 206, 1, 66, - 250, 12, 65, 82, 71, 138, 110, 85, 231, 202, 27, 68, 6, 182, 15, 72, 245, - 158, 19, 5, 73, 88, 84, 72, 83, 32, 150, 1, 66, 44, 18, 86, 65, 82, 73, + 250, 12, 65, 82, 71, 138, 110, 85, 155, 190, 27, 68, 6, 182, 15, 72, 169, + 146, 19, 5, 73, 88, 84, 72, 83, 32, 150, 1, 66, 44, 18, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 76, 73, 77, 77, 85, 206, 12, 65, 82, - 71, 26, 83, 242, 109, 85, 231, 202, 27, 68, 6, 204, 123, 3, 65, 78, 50, - 183, 237, 26, 85, 9, 206, 211, 12, 32, 135, 215, 19, 52, 24, 44, 4, 71, - 73, 68, 65, 33, 3, 78, 69, 32, 4, 246, 190, 30, 69, 183, 107, 77, 20, + 71, 26, 83, 242, 109, 85, 155, 190, 27, 68, 6, 204, 123, 3, 65, 78, 50, + 235, 224, 26, 85, 9, 206, 203, 12, 32, 187, 210, 19, 52, 24, 44, 4, 71, + 73, 68, 65, 33, 3, 78, 69, 32, 4, 170, 178, 30, 69, 183, 107, 77, 20, 156, 1, 19, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 73, 76, - 73, 77, 77, 85, 174, 7, 83, 230, 113, 85, 238, 50, 71, 250, 151, 27, 68, - 199, 249, 1, 65, 9, 134, 166, 32, 32, 186, 2, 51, 3, 52, 28, 92, 16, 76, + 73, 77, 77, 85, 174, 7, 83, 230, 113, 85, 238, 50, 71, 174, 139, 27, 68, + 199, 249, 1, 65, 9, 186, 153, 32, 32, 186, 2, 51, 3, 52, 28, 92, 16, 76, 68, 32, 65, 83, 83, 89, 82, 73, 65, 78, 32, 79, 78, 69, 32, 37, 3, 78, - 69, 32, 4, 246, 208, 18, 83, 219, 208, 11, 81, 24, 166, 1, 69, 52, 8, 81, + 69, 32, 4, 170, 196, 18, 83, 219, 208, 11, 81, 24, 166, 1, 69, 52, 8, 81, 85, 65, 82, 84, 69, 82, 32, 206, 7, 66, 54, 71, 84, 5, 84, 72, 73, 82, - 68, 164, 214, 24, 2, 83, 72, 237, 205, 6, 6, 72, 65, 76, 70, 32, 71, 4, - 158, 8, 83, 205, 164, 1, 5, 73, 71, 72, 84, 72, 4, 174, 186, 30, 65, 183, + 68, 216, 201, 24, 2, 83, 72, 237, 205, 6, 6, 72, 65, 76, 70, 32, 71, 4, + 158, 8, 83, 205, 164, 1, 5, 73, 71, 72, 84, 72, 4, 226, 173, 30, 65, 183, 114, 71, 38, 144, 1, 5, 69, 86, 69, 78, 32, 188, 1, 20, 72, 65, 82, 50, 32, 84, 73, 77, 69, 83, 32, 71, 65, 76, 32, 80, 76, 85, 83, 32, 37, 3, 73, 88, 32, 18, 148, 1, 17, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, - 77, 32, 73, 77, 73, 78, 218, 1, 83, 230, 113, 85, 238, 50, 71, 250, 151, - 27, 68, 199, 249, 1, 65, 6, 230, 203, 12, 32, 135, 215, 19, 51, 4, 250, - 189, 28, 68, 251, 228, 2, 77, 16, 142, 1, 83, 142, 3, 65, 218, 110, 85, - 238, 50, 71, 172, 130, 27, 16, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, + 77, 32, 73, 77, 73, 78, 218, 1, 83, 230, 113, 85, 238, 50, 71, 174, 139, + 27, 68, 199, 249, 1, 65, 6, 230, 195, 12, 32, 187, 210, 19, 51, 4, 174, + 177, 28, 68, 251, 228, 2, 77, 16, 142, 1, 83, 142, 3, 65, 218, 110, 85, + 238, 50, 71, 224, 245, 26, 16, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 65, 83, 72, 207, 21, 68, 2, 227, 61, 72, 50, 52, 5, 72, 82, 69, 69, 32, 241, 1, 3, 87, 79, 32, 28, 142, 1, 66, 40, 4, 83, 72, 65, 82, 24, 16, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 69, 83, 72, - 118, 65, 82, 71, 239, 184, 28, 68, 6, 136, 112, 3, 85, 82, 85, 199, 10, - 65, 8, 226, 111, 50, 3, 85, 4, 222, 243, 24, 49, 203, 3, 50, 22, 82, 65, + 118, 65, 82, 71, 163, 172, 28, 68, 6, 136, 112, 3, 85, 82, 85, 199, 10, + 65, 8, 226, 111, 50, 3, 85, 4, 146, 231, 24, 49, 203, 3, 50, 22, 82, 65, 30, 66, 32, 2, 69, 83, 22, 71, 26, 83, 61, 6, 84, 72, 73, 82, 68, 83, 4, - 225, 184, 1, 2, 83, 72, 4, 254, 120, 65, 243, 226, 26, 85, 2, 211, 246, - 24, 72, 4, 53, 3, 69, 83, 72, 4, 11, 72, 4, 17, 2, 65, 82, 4, 254, 156, - 32, 50, 3, 85, 4, 11, 32, 4, 216, 211, 27, 12, 86, 65, 82, 73, 65, 78, + 225, 184, 1, 2, 83, 72, 4, 254, 120, 65, 167, 214, 26, 85, 2, 135, 234, + 24, 72, 4, 53, 3, 69, 83, 72, 4, 11, 72, 4, 17, 2, 65, 82, 4, 178, 144, + 32, 50, 3, 85, 4, 11, 32, 4, 140, 199, 27, 12, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 179, 100, 68, 10, 160, 1, 9, 68, 73, 65, 71, 79, - 78, 65, 76, 32, 220, 222, 25, 6, 86, 69, 82, 84, 73, 67, 145, 130, 3, 14, - 79, 76, 68, 32, 65, 83, 83, 89, 82, 73, 65, 78, 32, 87, 6, 220, 203, 28, + 78, 65, 76, 32, 144, 210, 25, 6, 86, 69, 82, 84, 73, 67, 145, 130, 3, 14, + 79, 76, 68, 32, 65, 83, 83, 89, 82, 73, 65, 78, 32, 87, 6, 144, 191, 28, 2, 84, 82, 244, 254, 2, 4, 81, 85, 65, 68, 15, 67, 194, 17, 202, 1, 65, 186, 15, 66, 170, 5, 68, 190, 15, 69, 202, 10, 71, 182, 30, 72, 238, 3, 73, 238, 4, 75, 154, 20, 76, 134, 37, 77, 134, 6, 78, 226, 17, 80, 210, 3, 82, 42, 83, 238, 19, 84, 186, 8, 85, 207, 20, 90, 141, 1, 160, 1, 7, 32, 84, 73, 77, 69, 83, 32, 142, 1, 66, 250, 3, 68, 38, 75, 90, 76, 212, - 1, 3, 77, 65, 82, 78, 78, 134, 2, 82, 42, 83, 138, 141, 31, 80, 215, 127, - 50, 16, 144, 173, 1, 5, 76, 65, 71, 65, 82, 226, 23, 71, 254, 253, 12, - 73, 174, 197, 13, 77, 162, 163, 2, 83, 194, 165, 1, 66, 246, 67, 72, 187, + 1, 3, 77, 65, 82, 78, 78, 134, 2, 82, 42, 83, 190, 128, 31, 80, 215, 127, + 50, 16, 144, 173, 1, 5, 76, 65, 71, 65, 82, 226, 23, 71, 254, 245, 12, + 73, 226, 192, 13, 77, 162, 163, 2, 83, 194, 165, 1, 66, 246, 67, 72, 187, 2, 65, 45, 22, 32, 219, 2, 50, 28, 48, 6, 84, 73, 77, 69, 83, 32, 139, 203, 1, 71, 26, 180, 1, 2, 71, 65, 38, 73, 36, 2, 83, 72, 128, 113, 8, 85, 32, 80, 76, 85, 83, 32, 85, 188, 56, 4, 68, 85, 78, 51, 166, 2, 65, - 204, 2, 3, 78, 85, 78, 242, 27, 76, 255, 198, 30, 72, 4, 194, 210, 1, 78, - 215, 193, 30, 76, 4, 210, 169, 1, 71, 207, 234, 29, 77, 4, 142, 236, 24, + 204, 2, 3, 78, 85, 78, 242, 27, 76, 179, 186, 30, 72, 4, 194, 210, 1, 78, + 139, 181, 30, 76, 4, 210, 169, 1, 71, 131, 222, 29, 77, 4, 194, 223, 24, 85, 187, 188, 5, 69, 15, 37, 7, 32, 84, 73, 77, 69, 83, 32, 12, 206, 133, - 1, 77, 130, 59, 71, 194, 9, 83, 234, 10, 84, 148, 210, 28, 2, 66, 65, + 1, 77, 130, 59, 71, 194, 9, 83, 234, 10, 84, 200, 197, 28, 2, 66, 65, 251, 235, 1, 65, 5, 249, 51, 5, 32, 84, 73, 77, 69, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, 252, 27, 5, 83, 72, 73, 84, 65, 215, 80, 69, 23, 68, - 7, 32, 84, 73, 77, 69, 83, 32, 234, 221, 25, 69, 155, 227, 5, 65, 16, - 102, 75, 156, 173, 1, 2, 68, 73, 146, 254, 26, 71, 198, 249, 1, 85, 186, - 95, 65, 198, 94, 83, 215, 42, 72, 4, 130, 158, 1, 65, 247, 241, 30, 73, - 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, 142, 254, 3, 75, 147, 228, 27, - 83, 13, 26, 32, 227, 225, 31, 83, 8, 128, 1, 10, 80, 76, 85, 83, 32, 78, - 65, 71, 65, 32, 172, 192, 8, 7, 84, 72, 82, 69, 69, 32, 84, 141, 131, 6, + 7, 32, 84, 73, 77, 69, 83, 32, 158, 209, 25, 69, 155, 227, 5, 65, 16, + 102, 75, 156, 173, 1, 2, 68, 73, 198, 241, 26, 71, 198, 249, 1, 85, 186, + 95, 65, 198, 94, 83, 215, 42, 72, 4, 130, 158, 1, 65, 171, 229, 30, 73, + 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, 218, 249, 3, 75, 251, 219, 27, + 83, 13, 26, 32, 151, 213, 31, 83, 8, 128, 1, 10, 80, 76, 85, 83, 32, 78, + 65, 71, 65, 32, 248, 187, 8, 7, 84, 72, 82, 69, 69, 32, 84, 193, 255, 5, 4, 79, 86, 69, 82, 4, 144, 140, 1, 16, 79, 80, 80, 79, 83, 73, 78, 71, - 32, 65, 78, 32, 80, 76, 85, 83, 215, 195, 23, 83, 6, 200, 49, 2, 65, 68, - 151, 166, 18, 75, 18, 26, 72, 139, 173, 12, 65, 17, 42, 32, 242, 214, 18, + 32, 65, 78, 32, 80, 76, 85, 83, 139, 183, 23, 83, 6, 200, 49, 2, 65, 68, + 203, 153, 18, 75, 18, 26, 72, 139, 165, 12, 65, 17, 42, 32, 166, 202, 18, 71, 167, 181, 13, 50, 10, 68, 9, 79, 86, 69, 82, 32, 65, 83, 72, 32, 174, 97, 90, 135, 112, 75, 6, 176, 1, 8, 79, 86, 69, 82, 32, 65, 83, 72, 157, 143, 1, 29, 84, 85, 71, 50, 32, 79, 86, 69, 82, 32, 84, 85, 71, 50, 32, 84, 85, 71, 50, 32, 79, 86, 69, 82, 32, 84, 85, 71, 50, 5, 149, 145, 1, 27, 32, 67, 82, 79, 83, 83, 73, 78, 71, 32, 65, 83, 72, 32, 79, 86, 69, 82, 32, 65, 83, 72, 32, 79, 86, 69, 82, 52, 30, 65, 158, 2, 73, 95, 85, - 27, 66, 68, 44, 4, 72, 65, 82, 50, 90, 76, 66, 82, 151, 140, 28, 71, 5, + 27, 66, 68, 44, 4, 72, 65, 82, 50, 90, 76, 66, 82, 203, 255, 27, 71, 5, 145, 208, 1, 6, 32, 84, 73, 77, 69, 83, 9, 37, 7, 32, 84, 73, 77, 69, 83, - 32, 6, 238, 164, 1, 65, 154, 207, 30, 78, 163, 17, 90, 7, 208, 251, 30, - 7, 32, 79, 86, 69, 82, 32, 66, 139, 139, 1, 65, 5, 175, 223, 24, 65, 9, - 37, 7, 32, 84, 73, 77, 69, 83, 32, 6, 134, 156, 1, 73, 242, 198, 29, 71, + 32, 6, 238, 164, 1, 65, 206, 194, 30, 78, 163, 17, 90, 7, 132, 239, 30, + 7, 32, 79, 86, 69, 82, 32, 66, 139, 139, 1, 65, 5, 227, 210, 24, 65, 9, + 37, 7, 32, 84, 73, 77, 69, 83, 32, 6, 134, 156, 1, 73, 166, 186, 29, 71, 191, 163, 1, 65, 19, 50, 32, 168, 1, 3, 76, 85, 71, 239, 169, 1, 82, 8, - 88, 8, 79, 86, 69, 82, 32, 66, 85, 32, 149, 208, 27, 8, 67, 82, 79, 83, - 83, 73, 78, 71, 6, 160, 207, 12, 7, 84, 73, 77, 69, 83, 32, 78, 214, 247, - 17, 65, 155, 110, 85, 5, 249, 242, 3, 8, 32, 79, 86, 69, 82, 32, 66, 85, + 88, 8, 79, 86, 69, 82, 32, 66, 85, 32, 201, 195, 27, 8, 67, 82, 79, 83, + 83, 73, 78, 71, 6, 160, 199, 12, 7, 84, 73, 77, 69, 83, 32, 78, 138, 243, + 17, 65, 155, 110, 85, 5, 197, 238, 3, 8, 32, 79, 86, 69, 82, 32, 66, 85, 180, 1, 34, 65, 222, 5, 73, 195, 2, 85, 67, 50, 71, 150, 5, 82, 146, 49, - 32, 243, 204, 31, 77, 55, 26, 32, 251, 130, 32, 51, 50, 76, 13, 75, 73, + 32, 167, 192, 31, 77, 55, 26, 32, 175, 246, 31, 51, 50, 76, 13, 75, 73, 83, 73, 77, 53, 32, 84, 73, 77, 69, 83, 32, 227, 198, 1, 84, 48, 146, 1, 65, 30, 66, 38, 71, 112, 2, 73, 82, 42, 76, 94, 85, 182, 131, 1, 80, 162, - 61, 84, 134, 133, 28, 75, 182, 162, 2, 78, 254, 2, 83, 163, 17, 72, 4, - 110, 32, 235, 220, 30, 77, 4, 254, 148, 30, 65, 251, 235, 1, 73, 10, 34, - 65, 58, 73, 219, 185, 31, 85, 5, 11, 32, 2, 141, 149, 30, 6, 80, 76, 85, - 83, 32, 77, 5, 183, 216, 24, 82, 5, 129, 142, 14, 5, 32, 80, 76, 85, 83, - 8, 26, 85, 163, 255, 31, 65, 7, 160, 151, 1, 7, 32, 80, 76, 85, 83, 32, - 77, 255, 231, 30, 77, 6, 52, 7, 50, 32, 80, 76, 85, 83, 32, 155, 253, 31, - 83, 4, 128, 27, 2, 71, 73, 147, 248, 29, 77, 7, 187, 202, 12, 65, 25, 54, - 77, 150, 1, 78, 76, 2, 83, 72, 215, 251, 31, 66, 13, 44, 7, 32, 84, 73, - 77, 69, 83, 32, 59, 50, 6, 220, 69, 2, 85, 32, 238, 226, 13, 73, 175, - 167, 17, 83, 5, 205, 166, 13, 6, 32, 84, 73, 77, 69, 83, 5, 253, 253, 18, + 61, 84, 186, 248, 27, 75, 182, 162, 2, 78, 254, 2, 83, 163, 17, 72, 4, + 110, 32, 159, 208, 30, 77, 4, 178, 136, 30, 65, 251, 235, 1, 73, 10, 34, + 65, 58, 73, 143, 173, 31, 85, 5, 11, 32, 2, 193, 136, 30, 6, 80, 76, 85, + 83, 32, 77, 5, 235, 203, 24, 82, 5, 129, 134, 14, 5, 32, 80, 76, 85, 83, + 8, 26, 85, 215, 242, 31, 65, 7, 160, 151, 1, 7, 32, 80, 76, 85, 83, 32, + 77, 179, 219, 30, 77, 6, 52, 7, 50, 32, 80, 76, 85, 83, 32, 207, 240, 31, + 83, 4, 128, 27, 2, 71, 73, 199, 235, 29, 77, 7, 187, 194, 12, 65, 25, 54, + 77, 150, 1, 78, 76, 2, 83, 72, 139, 239, 31, 66, 13, 44, 7, 32, 84, 73, + 77, 69, 83, 32, 59, 50, 6, 220, 69, 2, 85, 32, 238, 218, 13, 73, 227, + 162, 17, 83, 5, 205, 158, 13, 6, 32, 84, 73, 77, 69, 83, 5, 177, 241, 18, 14, 32, 75, 65, 83, 75, 65, 76, 32, 85, 32, 71, 85, 78, 85, 5, 245, 157, - 1, 5, 32, 80, 76, 85, 83, 91, 70, 32, 66, 66, 94, 71, 234, 4, 78, 162, - 205, 24, 82, 195, 167, 7, 72, 6, 154, 176, 1, 71, 170, 3, 83, 181, 211, - 12, 4, 79, 86, 69, 82, 9, 52, 7, 32, 84, 73, 77, 69, 83, 32, 239, 249, - 31, 50, 4, 250, 145, 1, 69, 231, 186, 30, 83, 61, 52, 7, 32, 84, 73, 77, - 69, 83, 32, 243, 178, 31, 85, 56, 122, 65, 58, 68, 30, 71, 74, 75, 90, - 76, 110, 77, 50, 83, 130, 80, 69, 218, 58, 73, 130, 213, 16, 72, 214, - 129, 14, 78, 3, 80, 6, 32, 2, 83, 72, 219, 202, 31, 78, 5, 251, 220, 14, - 32, 4, 250, 167, 31, 73, 3, 85, 8, 26, 73, 167, 247, 31, 65, 7, 140, 141, - 1, 2, 82, 50, 135, 233, 30, 83, 8, 26, 85, 211, 185, 1, 65, 6, 40, 4, 83, - 72, 85, 50, 179, 246, 31, 82, 5, 175, 26, 32, 8, 26, 65, 45, 2, 85, 72, - 6, 202, 26, 77, 169, 178, 24, 3, 75, 45, 48, 2, 225, 57, 5, 32, 80, 76, - 85, 83, 6, 170, 138, 30, 65, 174, 173, 1, 69, 223, 61, 73, 4, 238, 138, - 1, 73, 195, 211, 30, 72, 11, 26, 51, 199, 244, 31, 52, 7, 143, 9, 32, + 1, 5, 32, 80, 76, 85, 83, 91, 70, 32, 66, 66, 94, 71, 234, 4, 78, 214, + 192, 24, 82, 195, 167, 7, 72, 6, 154, 176, 1, 71, 170, 3, 83, 181, 203, + 12, 4, 79, 86, 69, 82, 9, 52, 7, 32, 84, 73, 77, 69, 83, 32, 163, 237, + 31, 50, 4, 250, 145, 1, 69, 155, 174, 30, 83, 61, 52, 7, 32, 84, 73, 77, + 69, 83, 32, 167, 166, 31, 85, 56, 122, 65, 58, 68, 30, 71, 74, 75, 90, + 76, 110, 77, 50, 83, 130, 80, 69, 218, 58, 73, 182, 200, 16, 72, 214, + 129, 14, 78, 3, 80, 6, 32, 2, 83, 72, 143, 190, 31, 78, 5, 251, 212, 14, + 32, 4, 174, 155, 31, 73, 3, 85, 8, 26, 73, 219, 234, 31, 65, 7, 140, 141, + 1, 2, 82, 50, 187, 220, 30, 83, 8, 26, 85, 211, 185, 1, 65, 6, 40, 4, 83, + 72, 85, 50, 231, 233, 31, 82, 5, 175, 26, 32, 8, 26, 65, 45, 2, 85, 72, + 6, 202, 26, 77, 221, 165, 24, 3, 75, 45, 48, 2, 225, 57, 5, 32, 80, 76, + 85, 83, 6, 222, 253, 29, 65, 174, 173, 1, 69, 223, 61, 73, 4, 238, 138, + 1, 73, 247, 198, 30, 72, 11, 26, 51, 251, 231, 31, 52, 7, 143, 9, 32, 117, 130, 1, 32, 90, 50, 210, 1, 78, 202, 1, 82, 60, 3, 83, 72, 50, 52, - 3, 90, 69, 78, 242, 239, 18, 71, 142, 255, 11, 68, 215, 127, 76, 4, 168, + 3, 90, 69, 78, 166, 227, 18, 71, 142, 255, 11, 68, 215, 127, 76, 4, 168, 25, 11, 79, 86, 69, 82, 32, 69, 32, 78, 85, 78, 32, 253, 94, 4, 84, 73, 77, 69, 19, 37, 7, 32, 84, 73, 77, 69, 83, 32, 16, 134, 1, 83, 144, 168, - 1, 10, 65, 32, 80, 76, 85, 83, 32, 72, 65, 32, 222, 165, 29, 71, 182, 16, - 80, 182, 26, 75, 254, 100, 77, 219, 19, 85, 4, 214, 229, 30, 65, 255, + 1, 10, 65, 32, 80, 76, 85, 83, 32, 72, 65, 32, 146, 153, 29, 71, 182, 16, + 80, 182, 26, 75, 254, 100, 77, 219, 19, 85, 4, 138, 217, 30, 65, 255, 116, 72, 15, 11, 32, 12, 96, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 36, - 6, 84, 73, 77, 69, 83, 32, 247, 177, 24, 83, 2, 245, 160, 14, 4, 83, 73, - 78, 71, 6, 204, 138, 1, 4, 71, 65, 78, 50, 211, 206, 30, 77, 6, 36, 3, - 73, 78, 50, 187, 159, 31, 69, 5, 215, 224, 30, 32, 5, 229, 16, 9, 32, 67, + 6, 84, 73, 77, 69, 83, 32, 171, 165, 24, 83, 2, 245, 152, 14, 4, 83, 73, + 78, 71, 6, 204, 138, 1, 4, 71, 65, 78, 50, 135, 194, 30, 77, 6, 36, 3, + 73, 78, 50, 239, 146, 31, 69, 5, 139, 212, 30, 32, 5, 229, 16, 9, 32, 67, 82, 79, 83, 83, 73, 78, 71, 63, 11, 32, 60, 96, 14, 83, 72, 69, 83, 72, 73, 71, 32, 84, 73, 77, 69, 83, 32, 97, 6, 84, 73, 77, 69, 83, 32, 16, - 178, 131, 1, 73, 254, 224, 2, 77, 170, 158, 26, 65, 220, 110, 2, 76, 65, + 178, 131, 1, 73, 202, 220, 2, 77, 146, 150, 26, 65, 220, 110, 2, 76, 65, 198, 87, 83, 147, 17, 72, 44, 134, 1, 65, 68, 5, 68, 85, 78, 51, 32, 26, - 75, 58, 76, 62, 83, 34, 85, 222, 127, 73, 204, 31, 2, 72, 65, 242, 156, + 75, 58, 76, 62, 83, 34, 85, 222, 127, 73, 204, 31, 2, 72, 65, 166, 144, 29, 71, 199, 103, 66, 9, 244, 86, 9, 32, 80, 76, 85, 83, 32, 76, 65, 76, - 131, 149, 31, 78, 4, 217, 32, 2, 71, 85, 6, 132, 173, 24, 5, 65, 83, 75, - 65, 76, 187, 195, 3, 85, 8, 34, 65, 194, 234, 31, 73, 3, 85, 5, 201, 85, - 2, 76, 32, 4, 210, 211, 31, 72, 215, 22, 85, 4, 134, 234, 31, 50, 3, 68, + 183, 136, 31, 78, 4, 217, 32, 2, 71, 85, 6, 184, 160, 24, 5, 65, 83, 75, + 65, 76, 187, 195, 3, 85, 8, 34, 65, 246, 221, 31, 73, 3, 85, 5, 201, 85, + 2, 76, 32, 4, 134, 199, 31, 72, 215, 22, 85, 4, 186, 221, 31, 50, 3, 68, 160, 2, 42, 65, 166, 19, 69, 122, 73, 135, 5, 85, 191, 1, 114, 50, 144, - 16, 2, 66, 65, 94, 68, 22, 76, 38, 78, 206, 140, 1, 32, 154, 6, 82, 166, - 175, 28, 83, 155, 149, 2, 77, 153, 1, 11, 32, 150, 1, 68, 6, 84, 73, 77, + 16, 2, 66, 65, 94, 68, 22, 76, 38, 78, 206, 140, 1, 32, 154, 6, 82, 218, + 162, 28, 83, 155, 149, 2, 77, 153, 1, 11, 32, 150, 1, 68, 6, 84, 73, 77, 69, 83, 32, 153, 128, 1, 5, 79, 86, 69, 82, 32, 148, 1, 202, 1, 65, 162, 2, 66, 154, 1, 68, 178, 1, 69, 58, 71, 178, 1, 72, 230, 1, 73, 70, 75, - 194, 1, 76, 62, 77, 50, 78, 130, 1, 83, 142, 1, 85, 222, 154, 1, 84, 204, - 150, 23, 3, 90, 73, 90, 139, 165, 7, 80, 18, 132, 1, 6, 32, 80, 76, 85, - 83, 32, 50, 78, 52, 2, 83, 72, 137, 175, 18, 14, 66, 50, 32, 84, 69, 78, - 85, 32, 80, 76, 85, 83, 32, 84, 6, 202, 58, 68, 142, 214, 13, 73, 131, - 210, 17, 72, 5, 185, 61, 9, 32, 80, 76, 85, 83, 32, 75, 65, 75, 7, 11, + 194, 1, 76, 62, 77, 50, 78, 130, 1, 83, 142, 1, 85, 222, 154, 1, 84, 128, + 138, 23, 3, 90, 73, 90, 139, 165, 7, 80, 18, 132, 1, 6, 32, 80, 76, 85, + 83, 32, 50, 78, 52, 2, 83, 72, 189, 162, 18, 14, 66, 50, 32, 84, 69, 78, + 85, 32, 80, 76, 85, 83, 32, 84, 6, 202, 58, 68, 142, 206, 13, 73, 183, + 205, 17, 72, 5, 185, 61, 9, 32, 80, 76, 85, 83, 32, 75, 65, 75, 7, 11, 50, 5, 133, 90, 6, 32, 80, 76, 85, 83, 32, 10, 26, 65, 77, 2, 85, 82, 6, - 42, 72, 44, 2, 82, 32, 135, 227, 31, 68, 2, 11, 65, 2, 227, 187, 24, 82, - 5, 11, 32, 2, 169, 152, 31, 4, 80, 76, 85, 83, 14, 34, 73, 54, 85, 139, - 226, 31, 65, 7, 17, 2, 77, 32, 4, 146, 22, 84, 207, 129, 1, 71, 6, 56, 8, - 71, 32, 84, 73, 77, 69, 83, 32, 207, 225, 31, 66, 4, 158, 119, 73, 151, - 45, 75, 10, 38, 78, 254, 2, 76, 139, 136, 30, 82, 5, 243, 28, 32, 18, 18, + 42, 72, 44, 2, 82, 32, 187, 214, 31, 68, 2, 11, 65, 2, 151, 175, 24, 82, + 5, 11, 32, 2, 221, 139, 31, 4, 80, 76, 85, 83, 14, 34, 73, 54, 85, 191, + 213, 31, 65, 7, 17, 2, 77, 32, 4, 146, 22, 84, 207, 129, 1, 71, 6, 56, 8, + 71, 32, 84, 73, 77, 69, 83, 32, 131, 213, 31, 66, 4, 158, 119, 73, 151, + 45, 75, 10, 38, 78, 254, 2, 76, 191, 251, 29, 82, 5, 243, 28, 32, 18, 18, 65, 99, 73, 11, 26, 82, 247, 158, 1, 78, 7, 33, 6, 32, 80, 76, 85, 83, - 32, 4, 206, 201, 31, 78, 255, 2, 68, 9, 174, 122, 52, 253, 242, 12, 7, - 82, 50, 32, 80, 76, 85, 83, 12, 62, 65, 154, 124, 85, 233, 240, 12, 6, + 32, 4, 130, 189, 31, 78, 255, 2, 68, 9, 174, 122, 52, 253, 234, 12, 7, + 82, 50, 32, 80, 76, 85, 83, 12, 62, 65, 154, 124, 85, 233, 232, 12, 6, 73, 32, 80, 76, 85, 83, 8, 40, 6, 32, 80, 76, 85, 83, 32, 83, 76, 4, 48, - 6, 76, 85, 32, 80, 76, 85, 171, 222, 31, 65, 2, 11, 83, 2, 215, 97, 32, - 5, 149, 236, 13, 5, 32, 80, 76, 85, 83, 4, 176, 100, 10, 83, 72, 32, 80, + 6, 76, 85, 32, 80, 76, 85, 223, 209, 31, 65, 2, 11, 83, 2, 215, 97, 32, + 5, 149, 228, 13, 5, 32, 80, 76, 85, 83, 4, 176, 100, 10, 83, 72, 32, 80, 76, 85, 83, 32, 72, 85, 147, 15, 71, 12, 34, 65, 36, 2, 73, 68, 27, 85, - 4, 234, 224, 24, 83, 147, 252, 6, 75, 5, 225, 77, 2, 32, 80, 4, 60, 5, + 4, 158, 212, 24, 83, 147, 252, 6, 75, 5, 225, 77, 2, 32, 80, 4, 60, 5, 83, 72, 85, 50, 32, 197, 127, 5, 51, 32, 80, 76, 85, 2, 205, 158, 1, 3, - 80, 76, 85, 8, 26, 65, 183, 218, 31, 85, 7, 11, 77, 5, 227, 159, 1, 32, - 6, 250, 77, 69, 162, 162, 29, 85, 139, 235, 1, 73, 10, 26, 69, 73, 2, 85, - 78, 7, 33, 6, 32, 80, 76, 85, 83, 32, 4, 242, 178, 24, 69, 235, 147, 7, - 71, 5, 11, 32, 2, 187, 101, 79, 14, 42, 72, 254, 235, 23, 65, 247, 220, - 7, 85, 8, 18, 69, 51, 73, 5, 221, 224, 30, 7, 32, 80, 76, 85, 83, 32, 84, - 4, 130, 217, 31, 68, 3, 77, 7, 11, 68, 5, 237, 228, 13, 5, 32, 80, 76, - 85, 83, 7, 11, 32, 4, 206, 249, 29, 82, 177, 177, 1, 11, 67, 82, 79, 83, - 83, 73, 78, 71, 32, 71, 65, 5, 191, 131, 1, 32, 7, 134, 131, 1, 32, 231, - 195, 30, 65, 11, 11, 50, 9, 11, 32, 6, 80, 8, 67, 82, 79, 83, 83, 73, 78, - 71, 0, 4, 79, 86, 69, 82, 239, 207, 26, 84, 2, 197, 49, 3, 32, 71, 65, 8, - 44, 5, 83, 72, 84, 73, 78, 171, 174, 24, 50, 7, 37, 7, 32, 84, 73, 77, - 69, 83, 32, 4, 234, 220, 30, 75, 215, 120, 85, 49, 70, 32, 94, 52, 114, - 82, 190, 1, 83, 130, 207, 30, 68, 211, 130, 1, 71, 6, 152, 133, 9, 6, 84, + 80, 76, 85, 8, 26, 65, 235, 205, 31, 85, 7, 11, 77, 5, 227, 159, 1, 32, + 6, 250, 77, 69, 214, 149, 29, 85, 139, 235, 1, 73, 10, 26, 69, 73, 2, 85, + 78, 7, 33, 6, 32, 80, 76, 85, 83, 32, 4, 166, 166, 24, 69, 235, 147, 7, + 71, 5, 11, 32, 2, 187, 101, 79, 14, 42, 72, 178, 223, 23, 65, 247, 220, + 7, 85, 8, 18, 69, 51, 73, 5, 145, 212, 30, 7, 32, 80, 76, 85, 83, 32, 84, + 4, 182, 204, 31, 68, 3, 77, 7, 11, 68, 5, 237, 220, 13, 5, 32, 80, 76, + 85, 83, 7, 11, 32, 4, 130, 237, 29, 82, 177, 177, 1, 11, 67, 82, 79, 83, + 83, 73, 78, 71, 32, 71, 65, 5, 191, 131, 1, 32, 7, 134, 131, 1, 32, 155, + 183, 30, 65, 11, 11, 50, 9, 11, 32, 6, 80, 8, 67, 82, 79, 83, 83, 73, 78, + 71, 0, 4, 79, 86, 69, 82, 163, 195, 26, 84, 2, 197, 49, 3, 32, 71, 65, 8, + 44, 5, 83, 72, 84, 73, 78, 223, 161, 24, 50, 7, 37, 7, 32, 84, 73, 77, + 69, 83, 32, 4, 158, 208, 30, 75, 215, 120, 85, 49, 70, 32, 94, 52, 114, + 82, 190, 1, 83, 182, 194, 30, 68, 211, 130, 1, 71, 6, 152, 253, 8, 6, 84, 73, 77, 69, 83, 32, 249, 250, 4, 8, 67, 82, 79, 83, 83, 73, 78, 71, 7, 11, 32, 4, 64, 8, 67, 82, 79, 83, 83, 73, 78, 71, 1, 4, 79, 86, 69, 82, - 2, 197, 170, 24, 3, 32, 71, 73, 16, 26, 51, 147, 136, 1, 50, 13, 37, 7, + 2, 249, 157, 24, 3, 32, 71, 73, 16, 26, 51, 147, 136, 1, 50, 13, 37, 7, 32, 84, 73, 77, 69, 83, 32, 10, 70, 65, 0, 2, 76, 85, 206, 127, 71, 254, - 253, 12, 73, 131, 210, 17, 80, 2, 197, 253, 13, 7, 32, 80, 76, 85, 83, - 32, 73, 14, 26, 72, 231, 197, 30, 65, 13, 11, 32, 10, 22, 84, 247, 20, - 67, 8, 44, 5, 73, 77, 69, 83, 32, 239, 171, 31, 69, 6, 192, 20, 6, 71, - 73, 83, 72, 32, 67, 146, 126, 84, 227, 247, 29, 66, 43, 110, 50, 174, 1, - 68, 218, 1, 77, 54, 82, 152, 250, 13, 9, 32, 67, 82, 79, 83, 83, 73, 78, - 71, 223, 209, 17, 76, 15, 11, 32, 12, 48, 6, 84, 73, 77, 69, 83, 32, 167, + 245, 12, 73, 183, 205, 17, 80, 2, 197, 245, 13, 7, 32, 80, 76, 85, 83, + 32, 73, 14, 26, 72, 155, 185, 30, 65, 13, 11, 32, 10, 22, 84, 247, 20, + 67, 8, 44, 5, 73, 77, 69, 83, 32, 163, 159, 31, 69, 6, 192, 20, 6, 71, + 73, 83, 72, 32, 67, 146, 126, 84, 151, 235, 29, 66, 43, 110, 50, 174, 1, + 68, 218, 1, 77, 54, 82, 152, 242, 13, 9, 32, 67, 82, 79, 83, 83, 73, 78, + 71, 147, 205, 17, 76, 15, 11, 32, 12, 48, 6, 84, 73, 77, 69, 83, 32, 167, 132, 1, 71, 10, 252, 24, 3, 75, 65, 75, 194, 75, 73, 152, 20, 10, 83, 65, - 76, 32, 80, 76, 85, 83, 32, 84, 231, 213, 29, 78, 11, 11, 32, 8, 128, 1, + 76, 32, 80, 76, 85, 83, 32, 84, 155, 201, 29, 78, 11, 11, 32, 8, 128, 1, 10, 80, 76, 85, 83, 32, 71, 73, 83, 72, 32, 16, 6, 84, 73, 77, 69, 83, 32, 177, 66, 8, 79, 86, 69, 82, 32, 71, 85, 68, 2, 135, 121, 84, 4, 172, - 145, 1, 5, 65, 32, 80, 76, 85, 223, 194, 29, 75, 5, 17, 2, 32, 84, 2, - 241, 42, 4, 73, 77, 69, 83, 9, 26, 85, 219, 203, 31, 55, 4, 198, 202, 31, - 83, 147, 1, 78, 50, 30, 65, 82, 73, 215, 1, 85, 11, 26, 32, 255, 202, 31, + 145, 1, 5, 65, 32, 80, 76, 85, 147, 182, 29, 75, 5, 17, 2, 32, 84, 2, + 241, 42, 4, 73, 77, 69, 83, 9, 26, 85, 143, 191, 31, 55, 4, 250, 189, 31, + 83, 147, 1, 78, 50, 30, 65, 82, 73, 215, 1, 85, 11, 26, 32, 179, 190, 31, 76, 6, 32, 2, 84, 69, 147, 128, 1, 71, 4, 235, 127, 78, 23, 37, 7, 32, - 84, 73, 77, 69, 83, 32, 20, 104, 3, 65, 83, 72, 234, 228, 27, 68, 158, + 84, 73, 77, 69, 83, 32, 20, 104, 3, 65, 83, 72, 158, 216, 27, 68, 158, 228, 2, 78, 94, 75, 170, 57, 66, 2, 71, 162, 25, 83, 143, 45, 85, 7, 224, - 55, 8, 32, 79, 86, 69, 82, 32, 72, 73, 211, 145, 31, 50, 19, 48, 2, 66, - 50, 130, 161, 24, 76, 179, 166, 7, 83, 13, 37, 7, 32, 84, 73, 77, 69, 83, - 32, 10, 254, 138, 1, 75, 206, 216, 26, 76, 242, 216, 2, 72, 254, 59, 65, - 195, 9, 85, 49, 104, 3, 68, 73, 77, 94, 71, 214, 1, 76, 62, 77, 190, 193, + 55, 8, 32, 79, 86, 69, 82, 32, 72, 73, 135, 133, 31, 50, 19, 48, 2, 66, + 50, 182, 148, 24, 76, 179, 166, 7, 83, 13, 37, 7, 32, 84, 73, 77, 69, 83, + 32, 10, 254, 138, 1, 75, 130, 204, 26, 76, 242, 216, 2, 72, 254, 59, 65, + 195, 9, 85, 49, 104, 3, 68, 73, 77, 94, 71, 214, 1, 76, 62, 77, 242, 180, 31, 32, 170, 1, 83, 146, 1, 66, 2, 78, 3, 82, 7, 53, 11, 32, 79, 86, 69, - 82, 32, 73, 68, 73, 77, 32, 4, 166, 136, 24, 83, 175, 197, 6, 66, 13, 11, - 73, 11, 11, 32, 8, 162, 123, 71, 204, 244, 11, 31, 79, 86, 69, 82, 32, + 82, 32, 73, 68, 73, 77, 32, 4, 218, 251, 23, 83, 175, 197, 6, 66, 13, 11, + 73, 11, 11, 32, 8, 162, 123, 71, 204, 236, 11, 31, 79, 86, 69, 82, 32, 73, 71, 73, 32, 83, 72, 73, 82, 32, 79, 86, 69, 82, 32, 83, 72, 73, 82, - 32, 85, 68, 32, 79, 86, 69, 82, 250, 151, 17, 68, 175, 170, 1, 82, 7, 26, - 32, 151, 196, 31, 50, 2, 169, 72, 4, 84, 73, 77, 69, 13, 26, 32, 251, - 243, 30, 73, 8, 76, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 162, 111, - 84, 235, 149, 23, 83, 2, 181, 192, 30, 5, 83, 73, 78, 71, 32, 224, 1, 78, - 65, 146, 15, 73, 242, 1, 85, 158, 73, 69, 193, 188, 23, 4, 87, 85, 51, + 32, 85, 68, 32, 79, 86, 69, 82, 174, 147, 17, 68, 175, 170, 1, 82, 7, 26, + 32, 203, 183, 31, 50, 2, 169, 72, 4, 84, 73, 77, 69, 13, 26, 32, 175, + 231, 30, 73, 8, 76, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 162, 111, + 84, 159, 137, 23, 83, 2, 233, 179, 30, 5, 83, 73, 78, 71, 32, 224, 1, 78, + 65, 146, 15, 73, 242, 1, 85, 158, 73, 69, 245, 175, 23, 4, 87, 85, 51, 49, 177, 1, 164, 1, 7, 32, 84, 73, 77, 69, 83, 32, 210, 9, 50, 66, 68, - 102, 75, 50, 76, 98, 77, 28, 4, 83, 75, 65, 76, 184, 207, 15, 6, 80, 32, - 69, 76, 65, 77, 139, 229, 15, 66, 134, 1, 170, 1, 65, 94, 66, 82, 69, 30, + 102, 75, 50, 76, 98, 77, 28, 4, 83, 75, 65, 76, 184, 199, 15, 6, 80, 32, + 69, 76, 65, 77, 191, 224, 15, 66, 134, 1, 170, 1, 65, 94, 66, 82, 69, 30, 71, 182, 2, 73, 34, 75, 34, 76, 38, 77, 170, 1, 83, 118, 84, 34, 85, 214, - 8, 72, 246, 51, 78, 162, 230, 16, 80, 198, 240, 13, 82, 147, 17, 90, 13, - 46, 68, 234, 145, 31, 78, 165, 44, 2, 83, 72, 5, 229, 50, 7, 32, 80, 76, - 85, 83, 32, 75, 10, 34, 65, 178, 190, 31, 73, 3, 85, 6, 194, 210, 29, 76, + 8, 72, 246, 51, 78, 214, 217, 16, 80, 198, 240, 13, 82, 147, 17, 90, 13, + 46, 68, 158, 133, 31, 78, 165, 44, 2, 83, 72, 5, 229, 50, 7, 32, 80, 76, + 85, 83, 32, 75, 10, 34, 65, 230, 177, 31, 73, 3, 85, 6, 246, 197, 29, 76, 238, 235, 1, 68, 3, 82, 4, 138, 25, 82, 151, 61, 83, 26, 30, 65, 98, 73, - 147, 1, 85, 11, 38, 82, 206, 123, 78, 215, 193, 30, 76, 5, 249, 21, 10, - 32, 80, 76, 85, 83, 32, 83, 72, 65, 51, 11, 32, 2, 83, 72, 135, 149, 24, + 147, 1, 85, 11, 38, 82, 206, 123, 78, 139, 181, 30, 76, 5, 249, 21, 10, + 32, 80, 76, 85, 83, 32, 83, 72, 65, 51, 11, 32, 2, 83, 72, 187, 136, 24, 82, 7, 11, 32, 4, 26, 67, 255, 130, 1, 80, 2, 37, 7, 82, 79, 83, 83, 73, - 78, 71, 2, 165, 215, 27, 2, 32, 71, 7, 210, 193, 27, 82, 135, 250, 3, 68, - 4, 218, 167, 31, 71, 219, 19, 77, 8, 250, 8, 73, 135, 179, 17, 65, 6, - 202, 177, 12, 85, 171, 137, 19, 73, 12, 18, 69, 83, 73, 9, 33, 6, 32, 80, - 76, 85, 83, 32, 6, 174, 149, 31, 68, 150, 14, 84, 255, 2, 71, 5, 45, 9, - 32, 80, 76, 85, 83, 32, 78, 85, 78, 2, 147, 219, 29, 85, 18, 62, 72, 206, - 226, 27, 65, 200, 221, 2, 2, 85, 72, 131, 120, 73, 10, 186, 188, 30, 85, - 142, 54, 73, 162, 70, 65, 3, 69, 4, 214, 255, 30, 65, 223, 56, 85, 17, - 110, 32, 238, 92, 82, 200, 167, 26, 9, 77, 85, 77, 32, 84, 73, 77, 69, - 83, 226, 177, 4, 83, 146, 1, 50, 3, 68, 2, 207, 156, 21, 85, 5, 193, 129, - 12, 11, 32, 67, 82, 79, 83, 83, 73, 78, 71, 32, 75, 10, 42, 53, 166, 182, - 31, 50, 2, 51, 3, 52, 5, 221, 140, 24, 9, 32, 79, 86, 69, 82, 32, 75, 65, - 68, 5, 189, 75, 8, 32, 84, 73, 77, 69, 83, 32, 73, 9, 26, 32, 203, 164, - 31, 65, 4, 166, 105, 84, 233, 207, 23, 9, 67, 82, 79, 83, 83, 73, 78, 71, - 32, 4, 218, 180, 31, 50, 3, 52, 7, 11, 32, 4, 70, 76, 1, 13, 79, 86, 69, + 78, 71, 2, 217, 202, 27, 2, 32, 71, 7, 134, 181, 27, 82, 135, 250, 3, 68, + 4, 142, 155, 31, 71, 219, 19, 77, 8, 250, 8, 73, 187, 166, 17, 65, 6, + 202, 169, 12, 85, 223, 132, 19, 73, 12, 18, 69, 83, 73, 9, 33, 6, 32, 80, + 76, 85, 83, 32, 6, 226, 136, 31, 68, 150, 14, 84, 255, 2, 71, 5, 45, 9, + 32, 80, 76, 85, 83, 32, 78, 85, 78, 2, 199, 206, 29, 85, 18, 62, 72, 130, + 214, 27, 65, 200, 221, 2, 2, 85, 72, 131, 120, 73, 10, 238, 175, 30, 85, + 142, 54, 73, 162, 70, 65, 3, 69, 4, 138, 243, 30, 65, 223, 56, 85, 17, + 110, 32, 238, 92, 82, 252, 154, 26, 9, 77, 85, 77, 32, 84, 73, 77, 69, + 83, 226, 177, 4, 83, 146, 1, 50, 3, 68, 2, 131, 144, 21, 85, 5, 193, 249, + 11, 11, 32, 67, 82, 79, 83, 83, 73, 78, 71, 32, 75, 10, 42, 53, 218, 169, + 31, 50, 2, 51, 3, 52, 5, 145, 128, 24, 9, 32, 79, 86, 69, 82, 32, 75, 65, + 68, 5, 189, 75, 8, 32, 84, 73, 77, 69, 83, 32, 73, 9, 26, 32, 255, 151, + 31, 65, 4, 166, 105, 84, 157, 195, 23, 9, 67, 82, 79, 83, 83, 73, 78, 71, + 32, 4, 142, 168, 31, 50, 3, 52, 7, 11, 32, 4, 70, 76, 1, 13, 79, 86, 69, 82, 32, 75, 65, 83, 75, 65, 76, 32, 76, 2, 173, 116, 24, 65, 71, 65, 66, 32, 84, 73, 77, 69, 83, 32, 85, 32, 79, 86, 69, 82, 32, 76, 65, 71, 65, - 66, 32, 21, 68, 7, 32, 84, 73, 77, 69, 83, 32, 50, 83, 134, 178, 31, 68, - 3, 78, 6, 26, 85, 239, 235, 30, 66, 5, 151, 178, 31, 68, 8, 52, 3, 73, - 77, 53, 254, 165, 30, 65, 211, 139, 1, 72, 5, 133, 136, 24, 11, 32, 79, + 66, 32, 21, 68, 7, 32, 84, 73, 77, 69, 83, 32, 50, 83, 186, 165, 31, 68, + 3, 78, 6, 26, 85, 163, 223, 30, 66, 5, 203, 165, 31, 68, 8, 52, 3, 73, + 77, 53, 178, 153, 30, 65, 211, 139, 1, 72, 5, 185, 251, 23, 11, 32, 79, 86, 69, 82, 32, 75, 73, 83, 73, 77, 25, 200, 1, 29, 32, 79, 86, 69, 82, 32, 72, 73, 32, 84, 73, 77, 69, 83, 32, 65, 83, 72, 50, 32, 75, 85, 32, - 79, 86, 69, 82, 32, 72, 18, 52, 54, 82, 186, 98, 83, 230, 1, 76, 226, - 202, 30, 51, 2, 55, 3, 78, 2, 155, 71, 73, 5, 205, 176, 30, 8, 32, 86, + 79, 86, 69, 82, 32, 72, 18, 52, 54, 82, 186, 98, 83, 230, 1, 76, 150, + 190, 30, 51, 2, 55, 3, 78, 2, 155, 71, 73, 5, 129, 164, 30, 8, 32, 86, 65, 82, 73, 65, 78, 84, 5, 213, 115, 9, 32, 79, 80, 80, 79, 83, 73, 78, 71, 240, 2, 30, 65, 174, 26, 73, 59, 85, 141, 2, 68, 2, 71, 65, 252, 12, 2, 75, 45, 222, 11, 76, 46, 77, 135, 55, 72, 118, 22, 66, 131, 11, 82, - 109, 11, 32, 106, 48, 6, 84, 73, 77, 69, 83, 32, 131, 239, 23, 83, 104, + 109, 11, 32, 106, 48, 6, 84, 73, 77, 69, 83, 32, 183, 226, 23, 83, 104, 190, 1, 65, 186, 1, 66, 34, 71, 70, 72, 66, 73, 94, 75, 118, 76, 46, 77, - 46, 83, 138, 2, 84, 126, 85, 156, 172, 4, 8, 90, 85, 32, 79, 86, 69, 82, - 32, 226, 211, 25, 68, 222, 83, 69, 143, 57, 78, 15, 80, 6, 32, 80, 76, - 85, 83, 32, 76, 4, 83, 72, 32, 90, 162, 170, 31, 76, 3, 78, 6, 38, 68, - 138, 135, 30, 71, 227, 23, 76, 2, 201, 62, 5, 65, 32, 80, 76, 85, 2, 149, - 112, 2, 73, 68, 4, 230, 227, 30, 65, 163, 70, 73, 10, 48, 2, 85, 68, 154, - 211, 27, 65, 159, 214, 3, 73, 5, 191, 105, 32, 6, 204, 252, 17, 7, 73, + 46, 83, 138, 2, 84, 126, 85, 232, 167, 4, 8, 90, 85, 32, 79, 86, 69, 82, + 32, 202, 203, 25, 68, 222, 83, 69, 143, 57, 78, 15, 80, 6, 32, 80, 76, + 85, 83, 32, 76, 4, 83, 72, 32, 90, 214, 157, 31, 76, 3, 78, 6, 38, 68, + 190, 250, 29, 71, 227, 23, 76, 2, 201, 62, 5, 65, 32, 80, 76, 85, 2, 149, + 112, 2, 73, 68, 4, 154, 215, 30, 65, 163, 70, 73, 10, 48, 2, 85, 68, 206, + 198, 27, 65, 159, 214, 3, 73, 5, 191, 105, 32, 6, 128, 240, 17, 7, 73, 32, 84, 73, 77, 69, 83, 171, 176, 12, 65, 8, 22, 77, 175, 62, 71, 7, 33, - 6, 32, 80, 76, 85, 83, 32, 4, 190, 131, 31, 76, 179, 34, 72, 10, 26, 85, - 131, 170, 29, 73, 6, 26, 76, 211, 167, 31, 51, 5, 41, 8, 32, 80, 76, 85, - 83, 32, 72, 73, 2, 219, 65, 32, 8, 198, 100, 65, 198, 215, 28, 73, 223, - 110, 85, 6, 26, 69, 199, 187, 29, 85, 5, 175, 25, 32, 12, 26, 72, 203, - 149, 31, 85, 10, 100, 14, 73, 84, 65, 32, 80, 76, 85, 83, 32, 71, 73, 83, + 6, 32, 80, 76, 85, 83, 32, 4, 242, 246, 30, 76, 179, 34, 72, 10, 26, 85, + 183, 157, 29, 73, 6, 26, 76, 135, 155, 31, 51, 5, 41, 8, 32, 80, 76, 85, + 83, 32, 72, 73, 2, 219, 65, 32, 8, 198, 100, 65, 250, 202, 28, 73, 223, + 110, 85, 6, 26, 69, 251, 174, 29, 85, 5, 175, 25, 32, 12, 26, 72, 255, + 136, 31, 85, 10, 100, 14, 73, 84, 65, 32, 80, 76, 85, 83, 32, 71, 73, 83, 72, 32, 96, 2, 85, 50, 217, 3, 2, 69, 32, 4, 48, 6, 80, 76, 85, 83, 32, - 69, 191, 158, 26, 84, 2, 11, 82, 2, 11, 73, 2, 171, 253, 23, 78, 5, 189, + 69, 243, 145, 26, 84, 2, 11, 82, 2, 11, 73, 2, 223, 240, 23, 78, 5, 189, 73, 5, 32, 80, 76, 85, 83, 6, 86, 65, 189, 30, 16, 69, 32, 80, 76, 85, - 83, 32, 65, 32, 80, 76, 85, 83, 32, 83, 85, 4, 246, 250, 23, 75, 231, - 168, 7, 71, 13, 72, 6, 32, 80, 76, 85, 83, 32, 190, 41, 50, 162, 248, 30, - 83, 147, 1, 68, 4, 26, 85, 211, 162, 31, 65, 2, 255, 40, 32, 11, 11, 32, + 83, 32, 65, 32, 80, 76, 85, 83, 32, 83, 85, 4, 170, 238, 23, 75, 231, + 168, 7, 71, 13, 72, 6, 32, 80, 76, 85, 83, 32, 190, 41, 50, 214, 235, 30, + 83, 147, 1, 68, 4, 26, 85, 135, 150, 31, 65, 2, 255, 40, 32, 11, 11, 32, 8, 68, 4, 71, 85, 78, 85, 97, 9, 84, 73, 77, 69, 83, 32, 83, 72, 69, 5, 73, 16, 32, 79, 86, 69, 82, 32, 76, 65, 71, 65, 82, 32, 71, 85, 78, 85, - 2, 135, 244, 30, 32, 5, 11, 32, 2, 201, 210, 14, 4, 80, 76, 85, 83, 136, + 2, 187, 231, 30, 32, 5, 11, 32, 2, 201, 202, 14, 4, 80, 76, 85, 83, 136, 1, 82, 48, 146, 2, 49, 30, 50, 114, 51, 82, 52, 222, 2, 54, 154, 4, 55, 243, 24, 53, 22, 158, 1, 50, 30, 56, 180, 52, 15, 55, 57, 32, 79, 86, 69, - 82, 32, 76, 65, 75, 45, 48, 55, 57, 254, 254, 10, 53, 218, 195, 12, 54, - 2, 57, 94, 51, 139, 172, 3, 48, 4, 226, 158, 31, 49, 3, 53, 4, 228, 246, + 82, 32, 76, 65, 75, 45, 48, 55, 57, 254, 246, 10, 53, 142, 191, 12, 54, + 2, 57, 94, 51, 139, 172, 3, 48, 4, 150, 146, 31, 49, 3, 53, 4, 152, 234, 23, 12, 49, 32, 79, 86, 69, 82, 32, 76, 65, 75, 45, 48, 227, 167, 7, 48, - 4, 178, 246, 23, 52, 95, 51, 16, 46, 50, 38, 54, 186, 239, 23, 49, 159, - 2, 51, 6, 166, 157, 31, 48, 2, 53, 3, 56, 4, 130, 157, 31, 53, 3, 54, 12, - 42, 52, 250, 232, 11, 56, 227, 140, 12, 57, 6, 186, 156, 31, 51, 2, 55, - 3, 56, 30, 62, 52, 214, 1, 53, 30, 57, 134, 243, 23, 55, 139, 172, 3, 56, - 14, 26, 57, 191, 155, 31, 49, 13, 37, 7, 32, 84, 73, 77, 69, 83, 32, 10, - 116, 9, 80, 65, 80, 32, 80, 76, 85, 83, 32, 140, 166, 13, 7, 85, 50, 32, - 80, 76, 85, 83, 218, 31, 73, 211, 175, 17, 71, 4, 210, 13, 80, 51, 76, 4, - 130, 154, 31, 48, 3, 55, 8, 230, 153, 31, 48, 2, 50, 2, 51, 3, 53, 46, - 60, 2, 49, 55, 240, 1, 2, 52, 56, 222, 235, 23, 48, 23, 51, 23, 37, 7, + 4, 230, 233, 23, 52, 95, 51, 16, 46, 50, 38, 54, 238, 226, 23, 49, 159, + 2, 51, 6, 218, 144, 31, 48, 2, 53, 3, 56, 4, 182, 144, 31, 53, 3, 54, 12, + 42, 52, 250, 224, 11, 56, 151, 136, 12, 57, 6, 238, 143, 31, 51, 2, 55, + 3, 56, 30, 62, 52, 214, 1, 53, 30, 57, 186, 230, 23, 55, 139, 172, 3, 56, + 14, 26, 57, 243, 142, 31, 49, 13, 37, 7, 32, 84, 73, 77, 69, 83, 32, 10, + 116, 9, 80, 65, 80, 32, 80, 76, 85, 83, 32, 140, 158, 13, 7, 85, 50, 32, + 80, 76, 85, 83, 218, 31, 73, 135, 171, 17, 71, 4, 210, 13, 80, 51, 76, 4, + 182, 141, 31, 48, 3, 55, 8, 154, 141, 31, 48, 2, 50, 2, 51, 3, 53, 46, + 60, 2, 49, 55, 240, 1, 2, 52, 56, 146, 223, 23, 48, 23, 51, 23, 37, 7, 32, 84, 73, 77, 69, 83, 32, 20, 122, 84, 34, 85, 162, 11, 75, 132, 34, 9, - 68, 85, 78, 51, 32, 71, 85, 78, 85, 142, 255, 28, 65, 222, 164, 1, 66, - 247, 67, 76, 4, 250, 222, 30, 65, 223, 56, 69, 6, 222, 213, 14, 82, 218, - 193, 16, 50, 3, 68, 21, 37, 7, 32, 84, 73, 77, 69, 83, 32, 18, 154, 1, - 85, 220, 8, 4, 80, 65, 80, 32, 146, 45, 73, 224, 233, 12, 10, 83, 72, 69, - 83, 72, 32, 80, 76, 85, 83, 254, 132, 5, 68, 170, 221, 12, 78, 163, 17, - 71, 4, 238, 211, 14, 82, 219, 193, 16, 68, 4, 190, 236, 23, 50, 207, 174, + 68, 85, 78, 51, 32, 71, 85, 78, 85, 194, 242, 28, 65, 222, 164, 1, 66, + 247, 67, 76, 4, 174, 210, 30, 65, 223, 56, 69, 6, 222, 205, 14, 82, 142, + 189, 16, 50, 3, 68, 21, 37, 7, 32, 84, 73, 77, 69, 83, 32, 18, 154, 1, + 85, 220, 8, 4, 80, 65, 80, 32, 146, 45, 73, 224, 225, 12, 10, 83, 72, 69, + 83, 72, 32, 80, 76, 85, 83, 178, 128, 5, 68, 170, 221, 12, 78, 163, 17, + 71, 4, 238, 203, 14, 82, 143, 189, 16, 68, 4, 242, 223, 23, 50, 207, 174, 3, 52, 5, 11, 32, 2, 145, 6, 4, 84, 73, 77, 69, 7, 49, 10, 32, 84, 73, - 77, 69, 83, 32, 75, 85, 82, 5, 221, 215, 11, 5, 32, 80, 76, 85, 83, 9, - 200, 215, 11, 2, 77, 77, 158, 187, 19, 83, 147, 1, 76, 93, 90, 50, 212, - 7, 3, 71, 65, 76, 142, 1, 77, 130, 62, 32, 134, 204, 30, 51, 2, 72, 3, + 77, 69, 83, 32, 75, 85, 82, 5, 221, 207, 11, 5, 32, 80, 76, 85, 83, 9, + 200, 207, 11, 2, 77, 77, 210, 182, 19, 83, 147, 1, 76, 93, 90, 50, 212, + 7, 3, 71, 65, 76, 142, 1, 77, 130, 62, 32, 186, 191, 30, 51, 2, 72, 3, 76, 69, 11, 32, 66, 88, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 44, 4, - 71, 85, 78, 85, 38, 83, 35, 84, 2, 205, 213, 11, 6, 83, 73, 78, 71, 32, - 76, 2, 193, 24, 5, 32, 84, 73, 77, 69, 6, 250, 68, 72, 191, 142, 23, 81, - 54, 44, 5, 73, 77, 69, 83, 32, 235, 235, 30, 69, 52, 188, 1, 4, 69, 83, + 71, 85, 78, 85, 38, 83, 35, 84, 2, 205, 205, 11, 6, 83, 73, 78, 71, 32, + 76, 2, 193, 24, 5, 32, 84, 73, 77, 69, 6, 250, 68, 72, 243, 129, 23, 81, + 54, 44, 5, 73, 77, 69, 83, 32, 159, 223, 30, 69, 52, 188, 1, 4, 69, 83, 72, 50, 94, 72, 42, 75, 68, 2, 76, 65, 34, 77, 60, 3, 80, 65, 80, 118, - 83, 90, 84, 250, 56, 71, 250, 130, 8, 78, 242, 234, 18, 68, 254, 216, 2, - 65, 166, 69, 66, 215, 53, 73, 7, 11, 32, 4, 26, 80, 175, 136, 26, 84, 2, - 17, 2, 76, 85, 2, 129, 131, 30, 3, 83, 32, 76, 4, 184, 66, 2, 73, 32, - 183, 192, 29, 65, 8, 32, 2, 65, 68, 247, 141, 31, 73, 6, 226, 19, 51, - 147, 250, 30, 50, 4, 174, 20, 32, 131, 196, 17, 71, 2, 11, 69, 2, 11, 32, - 2, 249, 189, 13, 4, 80, 76, 85, 83, 5, 11, 32, 2, 33, 6, 80, 76, 85, 83, - 32, 80, 2, 45, 9, 65, 80, 32, 80, 76, 85, 83, 32, 76, 2, 187, 145, 27, - 85, 6, 26, 73, 131, 231, 30, 72, 4, 194, 18, 32, 201, 196, 26, 7, 75, 50, + 83, 90, 84, 250, 56, 71, 250, 250, 7, 78, 166, 230, 18, 68, 254, 216, 2, + 65, 166, 69, 66, 215, 53, 73, 7, 11, 32, 4, 26, 80, 227, 251, 25, 84, 2, + 17, 2, 76, 85, 2, 181, 246, 29, 3, 83, 32, 76, 4, 184, 66, 2, 73, 32, + 235, 179, 29, 65, 8, 32, 2, 65, 68, 171, 129, 31, 73, 6, 226, 19, 51, + 199, 237, 30, 50, 4, 174, 20, 32, 183, 183, 17, 71, 2, 11, 69, 2, 11, 32, + 2, 249, 181, 13, 4, 80, 76, 85, 83, 5, 11, 32, 2, 33, 6, 80, 76, 85, 83, + 32, 80, 2, 45, 9, 65, 80, 32, 80, 76, 85, 83, 32, 76, 2, 239, 132, 27, + 85, 6, 26, 73, 183, 218, 30, 72, 4, 194, 18, 32, 253, 183, 26, 7, 75, 50, 32, 80, 76, 85, 83, 4, 162, 53, 85, 139, 24, 65, 9, 11, 32, 6, 22, 79, 207, 67, 83, 4, 56, 7, 80, 80, 79, 83, 73, 78, 71, 1, 3, 86, 69, 82, 2, - 21, 3, 32, 76, 85, 2, 187, 254, 29, 71, 7, 45, 9, 32, 79, 86, 69, 82, 32, + 21, 3, 32, 76, 85, 2, 239, 241, 29, 71, 7, 45, 9, 32, 79, 86, 69, 82, 32, 76, 85, 77, 5, 187, 59, 32, 70, 34, 65, 70, 69, 22, 73, 71, 85, 17, 170, - 45, 32, 188, 1, 2, 83, 72, 186, 218, 30, 50, 2, 72, 3, 82, 7, 251, 247, - 26, 83, 7, 192, 142, 27, 8, 32, 80, 76, 85, 83, 32, 90, 65, 135, 250, 3, - 78, 43, 104, 2, 83, 72, 186, 60, 71, 140, 142, 11, 5, 32, 79, 86, 69, 82, - 40, 2, 82, 71, 173, 203, 6, 2, 78, 83, 31, 22, 32, 183, 2, 51, 16, 136, + 45, 32, 188, 1, 2, 83, 72, 238, 205, 30, 50, 2, 72, 3, 82, 7, 175, 235, + 26, 83, 7, 244, 129, 27, 8, 32, 80, 76, 85, 83, 32, 90, 65, 135, 250, 3, + 78, 43, 104, 2, 83, 72, 186, 60, 71, 140, 134, 11, 5, 32, 79, 86, 69, 82, + 40, 2, 82, 71, 225, 198, 6, 2, 78, 83, 31, 22, 32, 183, 2, 51, 16, 136, 1, 9, 79, 86, 69, 82, 32, 77, 85, 83, 72, 124, 6, 84, 73, 77, 69, 83, 32, - 237, 245, 26, 10, 67, 82, 79, 83, 83, 73, 78, 71, 32, 77, 9, 37, 7, 32, - 84, 73, 77, 69, 83, 32, 6, 42, 65, 154, 204, 28, 75, 211, 182, 2, 71, 2, - 237, 197, 11, 5, 32, 80, 76, 85, 83, 6, 162, 140, 30, 75, 158, 118, 90, + 161, 233, 26, 10, 67, 82, 79, 83, 83, 73, 78, 71, 32, 77, 9, 37, 7, 32, + 84, 73, 77, 69, 83, 32, 6, 42, 65, 206, 191, 28, 75, 211, 182, 2, 71, 2, + 237, 189, 11, 5, 32, 80, 76, 85, 83, 6, 214, 255, 29, 75, 158, 118, 90, 187, 2, 65, 13, 11, 32, 10, 44, 6, 84, 73, 77, 69, 83, 32, 203, 57, 71, - 8, 38, 65, 146, 240, 30, 68, 163, 17, 90, 5, 233, 143, 13, 5, 32, 80, 76, + 8, 38, 65, 198, 227, 30, 68, 163, 17, 90, 5, 233, 135, 13, 5, 32, 80, 76, 85, 83, 158, 1, 42, 65, 134, 2, 69, 94, 73, 199, 7, 85, 23, 52, 2, 71, - 65, 166, 1, 77, 182, 129, 31, 50, 3, 52, 11, 26, 32, 191, 130, 31, 82, 6, + 65, 166, 1, 77, 234, 244, 30, 50, 3, 52, 11, 26, 32, 243, 245, 30, 82, 6, 100, 8, 79, 80, 80, 79, 83, 73, 78, 71, 146, 59, 73, 197, 14, 9, 84, 73, - 77, 69, 83, 32, 83, 72, 85, 2, 141, 191, 30, 3, 32, 78, 65, 7, 204, 21, - 2, 32, 78, 231, 235, 30, 50, 9, 11, 32, 6, 44, 6, 84, 73, 77, 69, 83, 32, - 179, 57, 83, 4, 174, 186, 30, 85, 163, 70, 65, 73, 90, 77, 78, 78, 212, - 198, 20, 6, 32, 84, 73, 77, 69, 83, 202, 204, 8, 83, 239, 235, 1, 50, 7, + 77, 69, 83, 32, 83, 72, 85, 2, 193, 178, 30, 3, 32, 78, 65, 7, 204, 21, + 2, 32, 78, 155, 223, 30, 50, 9, 11, 32, 6, 44, 6, 84, 73, 77, 69, 83, 32, + 179, 57, 83, 4, 226, 173, 30, 85, 163, 70, 65, 73, 90, 77, 78, 78, 136, + 186, 20, 6, 32, 84, 73, 77, 69, 83, 202, 204, 8, 83, 239, 235, 1, 50, 7, 45, 9, 32, 84, 73, 77, 69, 83, 32, 71, 65, 4, 158, 3, 82, 179, 58, 78, - 59, 36, 3, 68, 65, 50, 227, 254, 30, 57, 55, 37, 7, 32, 84, 73, 77, 69, + 59, 36, 3, 68, 65, 50, 151, 242, 30, 57, 55, 37, 7, 32, 84, 73, 77, 69, 83, 32, 52, 162, 1, 65, 34, 71, 50, 75, 16, 5, 76, 65, 75, 45, 48, 22, 77, 86, 78, 34, 80, 76, 3, 83, 72, 69, 94, 85, 240, 15, 3, 68, 73, 77, - 186, 222, 29, 66, 135, 120, 72, 6, 246, 2, 83, 159, 250, 30, 78, 8, 26, - 73, 167, 250, 29, 85, 5, 199, 251, 30, 83, 2, 211, 20, 69, 2, 207, 213, - 23, 53, 4, 26, 69, 255, 144, 29, 65, 2, 25, 4, 32, 80, 76, 85, 2, 177, - 41, 3, 83, 32, 71, 4, 234, 171, 30, 85, 227, 79, 69, 2, 33, 6, 65, 80, - 32, 80, 76, 85, 2, 11, 83, 2, 241, 231, 29, 2, 32, 80, 9, 37, 7, 32, 80, - 76, 85, 83, 32, 65, 6, 26, 83, 131, 174, 29, 32, 4, 11, 72, 5, 107, 32, - 11, 50, 32, 34, 50, 218, 183, 14, 82, 203, 192, 16, 83, 2, 217, 156, 14, - 3, 80, 76, 85, 2, 11, 32, 2, 21, 3, 80, 76, 85, 2, 11, 83, 2, 235, 141, + 238, 209, 29, 66, 135, 120, 72, 6, 246, 2, 83, 211, 237, 30, 78, 8, 26, + 73, 219, 237, 29, 85, 5, 251, 238, 30, 83, 2, 211, 20, 69, 2, 131, 201, + 23, 53, 4, 26, 69, 179, 132, 29, 65, 2, 25, 4, 32, 80, 76, 85, 2, 177, + 41, 3, 83, 32, 71, 4, 158, 159, 30, 85, 227, 79, 69, 2, 33, 6, 65, 80, + 32, 80, 76, 85, 2, 11, 83, 2, 165, 219, 29, 2, 32, 80, 9, 37, 7, 32, 80, + 76, 85, 83, 32, 65, 6, 26, 83, 183, 161, 29, 32, 4, 11, 72, 5, 107, 32, + 11, 50, 32, 34, 50, 218, 175, 14, 82, 255, 187, 16, 83, 2, 217, 148, 14, + 3, 80, 76, 85, 2, 11, 32, 2, 21, 3, 80, 76, 85, 2, 11, 83, 2, 159, 129, 29, 32, 57, 24, 2, 49, 49, 99, 78, 9, 11, 32, 6, 200, 25, 9, 79, 86, 69, - 82, 32, 78, 85, 49, 49, 178, 216, 25, 84, 243, 167, 3, 82, 47, 30, 32, + 82, 32, 78, 85, 49, 49, 230, 203, 25, 84, 243, 167, 3, 82, 47, 30, 32, 169, 3, 2, 85, 90, 18, 144, 1, 12, 67, 82, 79, 83, 83, 73, 78, 71, 32, 78, 85, 78, 72, 12, 76, 65, 71, 65, 82, 32, 84, 73, 77, 69, 83, 32, 174, - 1, 79, 131, 238, 25, 84, 5, 209, 40, 14, 32, 76, 65, 71, 65, 82, 32, 79, - 86, 69, 82, 32, 76, 65, 10, 56, 3, 83, 65, 76, 166, 138, 29, 77, 14, 85, - 207, 71, 71, 5, 217, 233, 29, 23, 32, 79, 86, 69, 82, 32, 78, 85, 78, 32, - 76, 65, 71, 65, 82, 32, 84, 73, 77, 69, 83, 32, 83, 2, 241, 199, 17, 3, + 1, 79, 183, 225, 25, 84, 5, 209, 40, 14, 32, 76, 65, 71, 65, 82, 32, 79, + 86, 69, 82, 32, 76, 65, 10, 56, 3, 83, 65, 76, 218, 253, 28, 77, 14, 85, + 207, 71, 71, 5, 141, 221, 29, 23, 32, 79, 86, 69, 82, 32, 78, 85, 78, 32, + 76, 65, 71, 65, 82, 32, 84, 73, 77, 69, 83, 32, 83, 2, 165, 187, 17, 3, 86, 69, 82, 27, 11, 32, 24, 120, 10, 65, 66, 50, 32, 84, 73, 77, 69, 83, 32, 205, 37, 15, 75, 73, 83, 73, 77, 53, 32, 84, 73, 77, 69, 83, 32, 66, - 73, 20, 168, 1, 2, 75, 65, 202, 7, 73, 212, 39, 2, 65, 83, 190, 177, 2, - 68, 168, 215, 8, 3, 83, 73, 76, 182, 146, 12, 85, 210, 249, 5, 71, 158, - 151, 1, 78, 254, 2, 66, 163, 17, 76, 2, 151, 247, 26, 68, 46, 42, 65, 36, - 4, 69, 83, 72, 50, 23, 73, 9, 178, 241, 30, 68, 2, 78, 3, 80, 5, 211, - 217, 28, 32, 35, 22, 32, 151, 1, 82, 20, 80, 6, 84, 73, 77, 69, 83, 32, - 141, 146, 18, 8, 67, 82, 79, 83, 83, 73, 78, 71, 18, 214, 21, 85, 150, - 48, 65, 2, 73, 238, 233, 29, 66, 187, 64, 69, 12, 32, 2, 73, 71, 175, - 239, 30, 50, 11, 11, 32, 8, 96, 6, 84, 73, 77, 69, 83, 32, 217, 178, 26, - 12, 79, 80, 80, 79, 83, 73, 78, 71, 32, 80, 73, 82, 6, 222, 226, 29, 75, - 190, 69, 85, 235, 67, 90, 8, 234, 67, 65, 166, 170, 30, 73, 3, 85, 202, + 73, 20, 168, 1, 2, 75, 65, 202, 7, 73, 212, 39, 2, 65, 83, 138, 173, 2, + 68, 220, 211, 8, 3, 83, 73, 76, 234, 141, 12, 85, 210, 249, 5, 71, 158, + 151, 1, 78, 254, 2, 66, 163, 17, 76, 2, 203, 234, 26, 68, 46, 42, 65, 36, + 4, 69, 83, 72, 50, 23, 73, 9, 230, 228, 30, 68, 2, 78, 3, 80, 5, 135, + 205, 28, 32, 35, 22, 32, 151, 1, 82, 20, 80, 6, 84, 73, 77, 69, 83, 32, + 193, 133, 18, 8, 67, 82, 79, 83, 83, 73, 78, 71, 18, 214, 21, 85, 150, + 48, 65, 2, 73, 162, 221, 29, 66, 187, 64, 69, 12, 32, 2, 73, 71, 227, + 226, 30, 50, 11, 11, 32, 8, 96, 6, 84, 73, 77, 69, 83, 32, 141, 166, 26, + 12, 79, 80, 80, 79, 83, 73, 78, 71, 32, 80, 73, 82, 6, 146, 214, 29, 75, + 190, 69, 85, 235, 67, 90, 8, 234, 67, 65, 218, 157, 30, 73, 3, 85, 202, 1, 46, 65, 250, 5, 72, 150, 11, 73, 163, 1, 85, 63, 46, 71, 190, 4, 76, - 122, 78, 211, 231, 30, 82, 53, 11, 32, 50, 92, 4, 71, 85, 78, 85, 54, 78, + 122, 78, 135, 219, 30, 82, 53, 11, 32, 50, 92, 4, 71, 85, 78, 85, 54, 78, 32, 6, 84, 73, 77, 69, 83, 32, 241, 21, 4, 79, 86, 69, 82, 5, 29, 5, 32, - 84, 73, 77, 69, 2, 231, 244, 17, 83, 2, 185, 189, 25, 3, 85, 84, 73, 42, + 84, 73, 77, 69, 2, 155, 232, 17, 83, 2, 237, 176, 25, 3, 85, 84, 73, 42, 150, 1, 73, 42, 75, 34, 83, 64, 2, 84, 65, 38, 85, 220, 62, 2, 68, 85, - 130, 255, 28, 76, 246, 42, 78, 210, 48, 69, 138, 60, 77, 162, 17, 72, - 187, 2, 65, 2, 11, 71, 2, 11, 73, 2, 191, 31, 32, 4, 166, 177, 30, 85, - 199, 53, 65, 6, 26, 72, 251, 221, 29, 65, 4, 198, 206, 13, 69, 227, 212, - 16, 73, 4, 190, 192, 23, 75, 231, 168, 7, 66, 10, 238, 231, 30, 83, 146, + 182, 242, 28, 76, 246, 42, 78, 210, 48, 69, 138, 60, 77, 162, 17, 72, + 187, 2, 65, 2, 11, 71, 2, 11, 73, 2, 191, 31, 32, 4, 218, 164, 30, 85, + 199, 53, 65, 6, 26, 72, 175, 209, 29, 65, 4, 198, 198, 13, 69, 151, 208, + 16, 73, 4, 242, 179, 23, 75, 231, 168, 7, 66, 10, 162, 219, 30, 83, 146, 1, 50, 2, 66, 2, 77, 3, 82, 5, 33, 6, 32, 76, 65, 71, 65, 66, 2, 37, 7, - 32, 84, 73, 77, 69, 83, 32, 2, 11, 65, 2, 11, 83, 2, 163, 192, 23, 72, 2, - 131, 178, 11, 71, 106, 46, 65, 250, 1, 69, 242, 2, 73, 239, 3, 85, 29, - 50, 51, 182, 1, 54, 138, 186, 23, 66, 223, 3, 82, 19, 37, 7, 32, 84, 73, - 77, 69, 83, 32, 16, 90, 85, 146, 25, 83, 250, 231, 26, 71, 250, 235, 2, - 84, 170, 50, 66, 218, 47, 78, 215, 22, 65, 5, 11, 32, 2, 201, 156, 26, 4, - 80, 76, 85, 83, 5, 175, 45, 32, 27, 62, 32, 140, 2, 2, 83, 72, 178, 232, + 32, 84, 73, 77, 69, 83, 32, 2, 11, 65, 2, 11, 83, 2, 215, 179, 23, 72, 2, + 131, 170, 11, 71, 106, 46, 65, 250, 1, 69, 242, 2, 73, 239, 3, 85, 29, + 50, 51, 182, 1, 54, 190, 173, 23, 66, 223, 3, 82, 19, 37, 7, 32, 84, 73, + 77, 69, 83, 32, 16, 90, 85, 146, 25, 83, 174, 219, 26, 71, 250, 235, 2, + 84, 170, 50, 66, 218, 47, 78, 215, 22, 65, 5, 11, 32, 2, 253, 143, 26, 4, + 80, 76, 85, 83, 5, 175, 45, 32, 27, 62, 32, 140, 2, 2, 83, 72, 230, 219, 26, 71, 155, 250, 3, 78, 14, 84, 8, 79, 86, 69, 82, 32, 83, 72, 69, 88, - 5, 80, 76, 85, 83, 32, 191, 190, 30, 72, 7, 11, 32, 4, 190, 15, 71, 141, + 5, 80, 76, 85, 83, 32, 243, 177, 30, 72, 7, 11, 32, 4, 190, 15, 71, 141, 6, 12, 84, 65, 66, 32, 79, 86, 69, 82, 32, 84, 65, 66, 6, 48, 2, 72, 85, - 20, 2, 78, 65, 163, 191, 29, 83, 2, 175, 187, 23, 66, 2, 155, 187, 23, - 77, 7, 182, 165, 29, 76, 147, 189, 1, 50, 40, 62, 68, 74, 77, 218, 1, 82, - 226, 163, 26, 78, 175, 185, 4, 84, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, - 4, 226, 208, 30, 73, 219, 16, 65, 25, 37, 7, 32, 84, 73, 77, 69, 83, 32, - 22, 114, 66, 38, 73, 130, 19, 75, 194, 187, 2, 77, 234, 217, 2, 76, 250, - 147, 24, 71, 226, 23, 83, 138, 12, 68, 215, 127, 65, 4, 214, 206, 2, 85, - 219, 133, 27, 65, 4, 249, 20, 2, 71, 73, 7, 11, 32, 4, 60, 9, 79, 86, 69, - 82, 32, 83, 72, 73, 82, 179, 216, 25, 84, 2, 161, 230, 29, 11, 32, 66, + 20, 2, 78, 65, 215, 178, 29, 83, 2, 227, 174, 23, 66, 2, 207, 174, 23, + 77, 7, 234, 152, 29, 76, 147, 189, 1, 50, 40, 62, 68, 74, 77, 218, 1, 82, + 150, 151, 26, 78, 175, 185, 4, 84, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, + 4, 150, 196, 30, 73, 219, 16, 65, 25, 37, 7, 32, 84, 73, 77, 69, 83, 32, + 22, 114, 66, 38, 73, 130, 19, 75, 142, 183, 2, 77, 234, 217, 2, 76, 226, + 139, 24, 71, 226, 23, 83, 138, 12, 68, 215, 127, 65, 4, 162, 202, 2, 85, + 195, 253, 26, 65, 4, 249, 20, 2, 71, 73, 7, 11, 32, 4, 60, 9, 79, 86, 69, + 82, 32, 83, 72, 73, 82, 231, 203, 25, 84, 2, 213, 217, 29, 11, 32, 66, 85, 82, 32, 79, 86, 69, 82, 32, 66, 13, 88, 14, 32, 79, 86, 69, 82, 32, - 73, 78, 86, 69, 82, 84, 69, 68, 34, 50, 235, 228, 29, 66, 2, 11, 32, 2, - 135, 231, 25, 83, 7, 33, 6, 32, 80, 76, 85, 83, 32, 4, 88, 7, 69, 50, 32, - 84, 73, 77, 69, 173, 161, 11, 9, 68, 85, 71, 32, 84, 73, 77, 69, 83, 2, - 139, 146, 13, 83, 17, 50, 32, 30, 71, 230, 161, 11, 76, 183, 146, 12, 75, + 73, 78, 86, 69, 82, 84, 69, 68, 34, 50, 159, 216, 29, 66, 2, 11, 32, 2, + 187, 218, 25, 83, 7, 33, 6, 32, 80, 76, 85, 83, 32, 4, 88, 7, 69, 50, 32, + 84, 73, 77, 69, 173, 153, 11, 9, 68, 85, 71, 32, 84, 73, 77, 69, 83, 2, + 139, 138, 13, 83, 17, 50, 32, 30, 71, 230, 153, 11, 76, 235, 141, 12, 75, 4, 138, 8, 84, 163, 9, 71, 7, 11, 52, 5, 49, 10, 32, 79, 86, 69, 82, 32, - 83, 73, 71, 52, 2, 199, 14, 32, 19, 78, 68, 22, 77, 22, 82, 184, 231, 12, - 5, 32, 79, 86, 69, 82, 135, 250, 16, 72, 5, 183, 218, 30, 50, 5, 155, - 239, 28, 65, 5, 143, 218, 30, 57, 72, 46, 65, 150, 4, 73, 250, 1, 85, - 227, 8, 69, 37, 66, 32, 94, 66, 166, 1, 71, 148, 1, 2, 75, 52, 247, 213, - 30, 82, 8, 60, 6, 84, 73, 77, 69, 83, 32, 130, 14, 71, 155, 179, 28, 65, - 4, 238, 196, 30, 72, 3, 77, 7, 11, 32, 4, 252, 217, 17, 29, 79, 86, 69, + 83, 73, 71, 52, 2, 199, 14, 32, 19, 78, 68, 22, 77, 22, 82, 184, 223, 12, + 5, 32, 79, 86, 69, 82, 187, 245, 16, 72, 5, 235, 205, 30, 50, 5, 207, + 226, 28, 65, 5, 195, 205, 30, 57, 72, 46, 65, 150, 4, 73, 250, 1, 85, + 227, 8, 69, 37, 66, 32, 94, 66, 166, 1, 71, 148, 1, 2, 75, 52, 171, 201, + 30, 82, 8, 60, 6, 84, 73, 77, 69, 83, 32, 130, 14, 71, 207, 166, 28, 65, + 4, 162, 184, 30, 72, 3, 77, 7, 11, 32, 4, 176, 205, 17, 29, 79, 86, 69, 82, 32, 84, 65, 66, 32, 78, 73, 32, 79, 86, 69, 82, 32, 78, 73, 32, 68, 73, 83, 72, 32, 79, 86, 69, 82, 163, 192, 5, 83, 15, 37, 7, 32, 84, 73, - 77, 69, 83, 32, 12, 74, 84, 216, 134, 8, 2, 83, 72, 206, 161, 21, 71, - 210, 103, 85, 203, 50, 66, 2, 11, 85, 2, 199, 174, 23, 71, 5, 29, 5, 32, - 80, 76, 85, 83, 2, 229, 233, 28, 2, 32, 83, 17, 46, 82, 150, 29, 32, 246, - 183, 30, 50, 3, 76, 9, 11, 32, 6, 48, 8, 79, 86, 69, 82, 32, 84, 73, 82, + 77, 69, 83, 32, 12, 74, 84, 216, 254, 7, 2, 83, 72, 130, 157, 21, 71, + 210, 103, 85, 203, 50, 66, 2, 11, 85, 2, 251, 161, 23, 71, 5, 29, 5, 32, + 80, 76, 85, 83, 2, 153, 221, 28, 2, 32, 83, 17, 46, 82, 150, 29, 32, 170, + 171, 30, 50, 3, 76, 9, 11, 32, 6, 48, 8, 79, 86, 69, 82, 32, 84, 73, 82, 99, 84, 5, 11, 32, 2, 11, 71, 2, 21, 3, 65, 68, 32, 2, 241, 5, 8, 79, 86, 69, 82, 32, 71, 65, 68, 2, 217, 21, 6, 73, 77, 69, 83, 32, 84, 17, 50, - 77, 114, 82, 222, 170, 23, 71, 195, 167, 7, 75, 7, 37, 7, 32, 84, 73, 77, - 69, 83, 32, 4, 46, 71, 149, 212, 17, 5, 84, 72, 82, 69, 69, 2, 221, 16, - 2, 65, 78, 5, 137, 148, 11, 17, 32, 79, 86, 69, 82, 32, 84, 85, 82, 32, + 77, 114, 82, 146, 158, 23, 71, 195, 167, 7, 75, 7, 37, 7, 32, 84, 73, 77, + 69, 83, 32, 4, 46, 71, 201, 199, 17, 5, 84, 72, 82, 69, 69, 2, 221, 16, + 2, 65, 78, 5, 137, 140, 11, 17, 32, 79, 86, 69, 82, 32, 84, 85, 82, 32, 90, 65, 32, 79, 86, 69, 82, 179, 1, 138, 1, 32, 246, 2, 68, 226, 2, 78, - 46, 77, 158, 2, 82, 128, 9, 2, 83, 72, 174, 1, 90, 252, 199, 12, 2, 84, - 85, 242, 245, 17, 50, 3, 66, 12, 64, 7, 79, 86, 69, 82, 32, 85, 32, 158, - 2, 85, 231, 159, 29, 71, 6, 200, 1, 10, 80, 65, 32, 79, 86, 69, 82, 32, - 80, 65, 220, 167, 9, 19, 85, 32, 82, 69, 86, 69, 82, 83, 69, 68, 32, 79, - 86, 69, 82, 32, 85, 32, 82, 245, 173, 20, 10, 83, 85, 82, 32, 79, 86, 69, + 46, 77, 158, 2, 82, 128, 9, 2, 83, 72, 174, 1, 90, 252, 191, 12, 2, 84, + 85, 166, 241, 17, 50, 3, 66, 12, 64, 7, 79, 86, 69, 82, 32, 85, 32, 158, + 2, 85, 155, 147, 29, 71, 6, 200, 1, 10, 80, 65, 32, 79, 86, 69, 82, 32, + 80, 65, 220, 159, 9, 19, 85, 32, 82, 69, 86, 69, 82, 83, 69, 68, 32, 79, + 86, 69, 82, 32, 85, 32, 82, 169, 169, 20, 10, 83, 85, 82, 32, 79, 86, 69, 82, 32, 83, 2, 11, 32, 2, 45, 9, 71, 65, 82, 32, 79, 86, 69, 82, 32, 2, - 171, 170, 29, 71, 5, 235, 168, 30, 32, 21, 26, 32, 211, 204, 30, 85, 16, + 223, 157, 29, 71, 5, 159, 156, 30, 32, 21, 26, 32, 135, 192, 30, 85, 16, 70, 75, 44, 2, 83, 72, 100, 6, 84, 73, 77, 69, 83, 32, 135, 1, 71, 2, 11, - 85, 2, 11, 83, 2, 151, 144, 11, 72, 4, 29, 5, 69, 83, 72, 73, 71, 5, 11, - 32, 2, 11, 84, 2, 201, 133, 30, 6, 73, 77, 69, 83, 32, 66, 8, 92, 14, 85, - 32, 80, 76, 85, 83, 32, 85, 32, 80, 76, 85, 83, 32, 194, 132, 30, 66, - 215, 50, 77, 4, 11, 85, 5, 11, 32, 2, 11, 71, 2, 211, 165, 30, 85, 21, - 72, 7, 32, 84, 73, 77, 69, 83, 32, 136, 1, 2, 85, 77, 143, 201, 29, 66, - 10, 50, 76, 16, 2, 77, 69, 50, 83, 247, 200, 30, 85, 2, 231, 6, 65, 5, - 11, 32, 2, 221, 138, 26, 4, 80, 76, 85, 83, 2, 255, 142, 11, 72, 7, 37, - 7, 32, 84, 73, 77, 69, 83, 32, 4, 158, 11, 75, 227, 186, 30, 80, 93, 54, - 32, 102, 50, 194, 2, 73, 22, 85, 171, 196, 30, 52, 4, 62, 83, 205, 206, - 29, 9, 67, 82, 79, 83, 83, 73, 78, 71, 32, 2, 185, 139, 26, 4, 72, 69, - 83, 72, 23, 11, 32, 20, 42, 73, 37, 6, 84, 73, 77, 69, 83, 32, 2, 181, - 149, 24, 4, 78, 86, 69, 82, 18, 46, 65, 82, 85, 242, 196, 29, 78, 251, - 125, 72, 6, 48, 6, 32, 80, 76, 85, 83, 32, 191, 197, 30, 76, 4, 130, 195, - 30, 72, 3, 78, 8, 26, 50, 135, 197, 30, 68, 7, 33, 6, 32, 80, 76, 85, 83, - 32, 4, 214, 217, 28, 65, 179, 215, 1, 66, 5, 187, 196, 30, 51, 59, 56, 7, + 85, 2, 11, 83, 2, 151, 136, 11, 72, 4, 29, 5, 69, 83, 72, 73, 71, 5, 11, + 32, 2, 11, 84, 2, 253, 248, 29, 6, 73, 77, 69, 83, 32, 66, 8, 92, 14, 85, + 32, 80, 76, 85, 83, 32, 85, 32, 80, 76, 85, 83, 32, 246, 247, 29, 66, + 215, 50, 77, 4, 11, 85, 5, 11, 32, 2, 11, 71, 2, 135, 153, 30, 85, 21, + 72, 7, 32, 84, 73, 77, 69, 83, 32, 136, 1, 2, 85, 77, 195, 188, 29, 66, + 10, 50, 76, 16, 2, 77, 69, 50, 83, 171, 188, 30, 85, 2, 231, 6, 65, 5, + 11, 32, 2, 145, 254, 25, 4, 80, 76, 85, 83, 2, 255, 134, 11, 72, 7, 37, + 7, 32, 84, 73, 77, 69, 83, 32, 4, 158, 11, 75, 151, 174, 30, 80, 93, 54, + 32, 102, 50, 194, 2, 73, 22, 85, 223, 183, 30, 52, 4, 62, 83, 129, 194, + 29, 9, 67, 82, 79, 83, 83, 73, 78, 71, 32, 2, 237, 254, 25, 4, 72, 69, + 83, 72, 23, 11, 32, 20, 42, 73, 37, 6, 84, 73, 77, 69, 83, 32, 2, 233, + 136, 24, 4, 78, 86, 69, 82, 18, 46, 65, 82, 85, 166, 184, 29, 78, 251, + 125, 72, 6, 48, 6, 32, 80, 76, 85, 83, 32, 243, 184, 30, 76, 4, 182, 182, + 30, 72, 3, 78, 8, 26, 50, 187, 184, 30, 68, 7, 33, 6, 32, 80, 76, 85, 83, + 32, 4, 138, 205, 28, 65, 179, 215, 1, 66, 5, 239, 183, 30, 51, 59, 56, 7, 32, 84, 73, 77, 69, 83, 32, 165, 4, 2, 68, 65, 52, 134, 1, 65, 46, 68, - 38, 71, 82, 73, 46, 76, 78, 83, 46, 85, 230, 156, 29, 66, 234, 35, 77, + 38, 71, 82, 73, 46, 76, 78, 83, 46, 85, 154, 144, 29, 66, 234, 35, 77, 238, 90, 84, 146, 17, 75, 162, 17, 72, 3, 80, 5, 11, 83, 2, 11, 72, 2, - 167, 141, 17, 71, 4, 186, 135, 11, 65, 159, 235, 18, 85, 10, 26, 65, 251, - 193, 30, 85, 9, 34, 78, 214, 193, 30, 76, 3, 82, 2, 211, 9, 50, 6, 234, - 173, 30, 71, 202, 18, 83, 147, 1, 77, 6, 46, 85, 185, 149, 23, 5, 65, 75, - 45, 54, 54, 4, 230, 192, 30, 51, 3, 77, 4, 228, 151, 23, 2, 73, 71, 147, - 146, 7, 72, 6, 42, 32, 158, 254, 13, 82, 219, 193, 16, 68, 2, 129, 146, - 29, 6, 80, 76, 85, 83, 32, 71, 5, 11, 32, 2, 197, 226, 13, 4, 84, 73, 77, - 69, 17, 84, 7, 32, 84, 73, 77, 69, 83, 32, 128, 176, 29, 2, 85, 77, 194, - 142, 1, 50, 3, 88, 8, 50, 84, 240, 231, 26, 2, 75, 85, 159, 214, 3, 65, - 2, 11, 65, 2, 155, 149, 23, 75, 6, 26, 51, 211, 189, 30, 85, 5, 29, 5, - 32, 84, 73, 77, 69, 2, 21, 3, 83, 32, 75, 2, 11, 65, 2, 251, 192, 23, 83, - 42, 50, 65, 190, 1, 73, 146, 1, 85, 187, 146, 23, 69, 13, 50, 32, 210, - 173, 29, 77, 194, 142, 1, 55, 3, 71, 4, 56, 8, 83, 81, 85, 65, 82, 69, - 68, 32, 143, 181, 25, 84, 2, 11, 84, 2, 21, 3, 73, 77, 69, 2, 11, 83, 2, - 205, 194, 29, 2, 32, 75, 15, 86, 66, 184, 249, 22, 6, 32, 79, 86, 69, 82, + 219, 128, 17, 71, 4, 186, 255, 10, 65, 211, 230, 18, 85, 10, 26, 65, 175, + 181, 30, 85, 9, 34, 78, 138, 181, 30, 76, 3, 82, 2, 211, 9, 50, 6, 158, + 161, 30, 71, 202, 18, 83, 147, 1, 77, 6, 46, 85, 237, 136, 23, 5, 65, 75, + 45, 54, 54, 4, 154, 180, 30, 51, 3, 77, 4, 152, 139, 23, 2, 73, 71, 147, + 146, 7, 72, 6, 42, 32, 158, 246, 13, 82, 143, 189, 16, 68, 2, 181, 133, + 29, 6, 80, 76, 85, 83, 32, 71, 5, 11, 32, 2, 197, 218, 13, 4, 84, 73, 77, + 69, 17, 84, 7, 32, 84, 73, 77, 69, 83, 32, 180, 163, 29, 2, 85, 77, 194, + 142, 1, 50, 3, 88, 8, 50, 84, 164, 219, 26, 2, 75, 85, 159, 214, 3, 65, + 2, 11, 65, 2, 207, 136, 23, 75, 6, 26, 51, 135, 177, 30, 85, 5, 29, 5, + 32, 84, 73, 77, 69, 2, 21, 3, 83, 32, 75, 2, 11, 65, 2, 175, 180, 23, 83, + 42, 50, 65, 190, 1, 73, 146, 1, 85, 239, 133, 23, 69, 13, 50, 32, 134, + 161, 29, 77, 194, 142, 1, 55, 3, 71, 4, 56, 8, 83, 81, 85, 65, 82, 69, + 68, 32, 195, 168, 25, 84, 2, 11, 84, 2, 21, 3, 73, 77, 69, 2, 11, 83, 2, + 129, 182, 29, 2, 32, 75, 15, 86, 66, 236, 236, 22, 6, 32, 79, 86, 69, 82, 32, 186, 25, 90, 194, 167, 7, 51, 3, 71, 5, 17, 2, 32, 75, 2, 17, 2, 65, 66, 2, 135, 2, 65, 15, 84, 10, 32, 79, 86, 69, 82, 32, 90, 85, 32, 80, - 42, 53, 166, 192, 29, 66, 215, 120, 77, 2, 225, 149, 29, 5, 76, 85, 83, + 42, 53, 218, 179, 29, 66, 215, 120, 77, 2, 149, 137, 29, 5, 76, 85, 83, 32, 83, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, 44, 5, 84, 72, 82, 69, - 69, 163, 184, 30, 65, 2, 29, 5, 32, 68, 73, 83, 72, 2, 11, 32, 2, 171, - 177, 25, 84, 8, 42, 32, 246, 247, 22, 73, 155, 211, 3, 67, 4, 174, 179, + 69, 215, 171, 30, 65, 2, 29, 5, 32, 68, 73, 83, 72, 2, 11, 32, 2, 223, + 164, 25, 84, 8, 42, 32, 170, 235, 22, 73, 155, 211, 3, 67, 4, 226, 166, 22, 79, 217, 133, 7, 8, 87, 73, 84, 72, 32, 83, 84, 82, 18, 134, 1, 76, - 162, 1, 82, 233, 240, 29, 23, 86, 69, 68, 32, 83, 84, 69, 77, 32, 80, 65, - 82, 65, 71, 82, 65, 80, 72, 32, 83, 73, 71, 78, 10, 48, 2, 89, 32, 185, - 164, 3, 4, 73, 78, 71, 32, 8, 68, 2, 76, 79, 221, 145, 28, 9, 66, 82, 65, - 67, 75, 69, 84, 32, 69, 6, 242, 239, 26, 71, 239, 196, 3, 79, 6, 52, 5, - 69, 78, 67, 89, 32, 53, 4, 89, 32, 65, 78, 4, 248, 144, 25, 4, 69, 88, - 67, 72, 175, 156, 4, 83, 2, 133, 252, 19, 3, 68, 32, 82, 4, 234, 132, 3, - 79, 227, 149, 26, 65, 240, 8, 128, 1, 2, 80, 82, 140, 9, 7, 82, 73, 76, - 76, 73, 67, 32, 152, 248, 25, 7, 76, 73, 78, 68, 82, 73, 67, 149, 132, 3, + 162, 1, 82, 157, 228, 29, 23, 86, 69, 68, 32, 83, 84, 69, 77, 32, 80, 65, + 82, 65, 71, 82, 65, 80, 72, 32, 83, 73, 71, 78, 10, 48, 2, 89, 32, 133, + 160, 3, 4, 73, 78, 71, 32, 8, 68, 2, 76, 79, 145, 133, 28, 9, 66, 82, 65, + 67, 75, 69, 84, 32, 69, 6, 166, 227, 26, 71, 239, 196, 3, 79, 6, 52, 5, + 69, 78, 67, 89, 32, 53, 4, 89, 32, 65, 78, 4, 172, 132, 25, 4, 69, 88, + 67, 72, 175, 156, 4, 83, 2, 185, 239, 19, 3, 68, 32, 82, 4, 182, 128, 3, + 79, 203, 141, 26, 65, 240, 8, 128, 1, 2, 80, 82, 140, 9, 7, 82, 73, 76, + 76, 73, 67, 32, 204, 235, 25, 7, 76, 73, 78, 68, 82, 73, 67, 149, 132, 3, 2, 67, 76, 180, 2, 140, 1, 13, 73, 79, 84, 32, 83, 89, 76, 76, 65, 66, 76, 69, 32, 169, 1, 16, 79, 45, 77, 73, 78, 79, 65, 78, 32, 83, 73, 71, - 78, 32, 67, 77, 110, 190, 185, 7, 75, 2, 76, 2, 77, 2, 78, 2, 80, 2, 82, - 2, 83, 2, 84, 126, 87, 150, 42, 74, 2, 90, 230, 245, 6, 88, 202, 214, 15, - 65, 2, 69, 2, 73, 2, 79, 3, 85, 198, 1, 46, 48, 146, 5, 49, 181, 164, 26, + 78, 32, 67, 77, 110, 138, 181, 7, 75, 2, 76, 2, 77, 2, 78, 2, 80, 2, 82, + 2, 83, 2, 84, 126, 87, 202, 38, 74, 2, 90, 230, 245, 6, 88, 254, 209, 15, + 65, 2, 69, 2, 73, 2, 79, 3, 85, 198, 1, 46, 48, 146, 5, 49, 233, 151, 26, 2, 51, 48, 170, 1, 102, 48, 78, 49, 74, 50, 78, 51, 78, 52, 62, 53, 86, - 55, 198, 195, 10, 57, 190, 3, 54, 219, 165, 14, 56, 16, 178, 174, 30, 49, - 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 16, 194, 3, 50, 166, - 170, 30, 48, 2, 49, 2, 51, 2, 53, 2, 55, 3, 57, 16, 158, 173, 30, 49, 2, - 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 16, 210, 172, 30, 48, 2, - 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 12, 134, 172, 30, 48, 2, - 49, 2, 52, 2, 54, 2, 55, 3, 57, 18, 202, 171, 30, 48, 2, 49, 2, 50, 2, - 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 20, 82, 53, 166, 170, 30, 48, 2, - 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 56, 3, 57, 5, 163, 170, 30, 66, 24, - 18, 48, 87, 49, 18, 250, 169, 30, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, - 2, 55, 2, 56, 3, 57, 6, 166, 169, 30, 48, 2, 50, 3, 52, 184, 6, 140, 1, + 55, 198, 187, 10, 57, 190, 3, 54, 143, 161, 14, 56, 16, 230, 161, 30, 49, + 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 16, 194, 3, 50, 218, + 157, 30, 48, 2, 49, 2, 51, 2, 53, 2, 55, 3, 57, 16, 210, 160, 30, 49, 2, + 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 16, 134, 160, 30, 48, 2, + 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 12, 186, 159, 30, 48, 2, + 49, 2, 52, 2, 54, 2, 55, 3, 57, 18, 254, 158, 30, 48, 2, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 20, 82, 53, 218, 157, 30, 48, 2, + 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 56, 3, 57, 5, 215, 157, 30, 66, 24, + 18, 48, 87, 49, 18, 174, 157, 30, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 55, 2, 56, 3, 57, 6, 218, 156, 30, 48, 2, 50, 3, 52, 184, 6, 140, 1, 9, 67, 65, 80, 73, 84, 65, 76, 32, 76, 202, 4, 75, 32, 7, 76, 69, 84, 84, 69, 82, 32, 132, 1, 3, 80, 65, 89, 30, 83, 211, 41, 84, 242, 2, 44, 6, 69, 84, 84, 69, 82, 32, 175, 43, 73, 236, 2, 150, 2, 76, 46, 78, 34, 80, 34, 82, 58, 84, 62, 85, 190, 5, 65, 214, 1, 66, 242, 1, 67, 150, 1, 68, 254, 1, 69, 206, 2, 71, 130, 1, 72, 134, 1, 73, 230, 3, 75, 226, 3, 77, - 218, 1, 79, 226, 2, 83, 218, 7, 89, 166, 1, 90, 146, 217, 29, 70, 134, - 14, 74, 2, 86, 2, 87, 159, 20, 81, 6, 222, 25, 73, 238, 244, 29, 74, 159, - 20, 72, 4, 134, 27, 69, 155, 243, 29, 74, 8, 134, 34, 69, 247, 238, 29, - 83, 12, 220, 9, 3, 79, 85, 78, 226, 18, 69, 191, 133, 30, 72, 20, 174, - 33, 69, 106, 83, 218, 212, 29, 67, 186, 22, 74, 3, 87, 13, 198, 34, 32, - 115, 75, 2, 189, 154, 30, 3, 65, 86, 89, 6, 248, 10, 5, 77, 85, 76, 84, - 73, 244, 143, 13, 2, 80, 65, 233, 242, 11, 14, 83, 77, 65, 76, 76, 32, - 67, 65, 80, 73, 84, 65, 76, 32, 2, 161, 248, 29, 2, 69, 82, 186, 3, 136, + 218, 1, 79, 226, 2, 83, 218, 7, 89, 166, 1, 90, 198, 204, 29, 70, 134, + 14, 74, 2, 86, 2, 87, 159, 20, 81, 6, 222, 25, 73, 162, 232, 29, 74, 159, + 20, 72, 4, 134, 27, 69, 207, 230, 29, 74, 8, 134, 34, 69, 171, 226, 29, + 83, 12, 220, 9, 3, 79, 85, 78, 226, 18, 69, 243, 248, 29, 72, 20, 174, + 33, 69, 106, 83, 142, 200, 29, 67, 186, 22, 74, 3, 87, 13, 198, 34, 32, + 115, 75, 2, 241, 141, 30, 3, 65, 86, 89, 6, 248, 10, 5, 77, 85, 76, 84, + 73, 244, 135, 13, 2, 80, 65, 157, 238, 11, 14, 83, 77, 65, 76, 76, 32, + 67, 65, 80, 73, 84, 65, 76, 32, 2, 213, 235, 29, 2, 69, 82, 186, 3, 136, 1, 6, 77, 65, 76, 76, 32, 76, 201, 37, 22, 85, 66, 83, 67, 82, 73, 80, 84, 32, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 134, 3, 44, 6, 69, 84, 84, 69, 82, 32, 151, 36, 73, 128, 3, 154, 2, 65, 214, 1, 66, 242, 1, 67, 150, 1, 68, 254, 1, 69, 206, 2, 71, 130, 1, 72, 134, 1, 73, 230, 3, 75, 222, 2, 76, 134, 1, 77, 114, 78, 106, 79, 110, 80, 50, 82, - 198, 1, 83, 218, 2, 84, 218, 2, 85, 246, 1, 87, 54, 89, 166, 1, 90, 146, - 217, 29, 70, 134, 14, 74, 2, 86, 159, 20, 81, 17, 108, 6, 32, 87, 73, 84, - 72, 32, 36, 9, 66, 75, 72, 65, 83, 73, 65, 78, 32, 149, 167, 12, 4, 76, - 69, 85, 84, 4, 178, 203, 9, 68, 191, 187, 3, 66, 8, 216, 147, 13, 3, 67, - 72, 69, 158, 215, 6, 68, 195, 175, 10, 72, 18, 110, 65, 78, 73, 32, 3, - 82, 79, 65, 200, 167, 3, 6, 76, 69, 78, 68, 69, 68, 194, 232, 9, 89, 207, - 138, 17, 69, 6, 200, 21, 6, 82, 82, 69, 68, 32, 79, 153, 144, 12, 5, 83, - 72, 75, 73, 82, 4, 230, 2, 78, 131, 165, 3, 71, 2, 163, 188, 10, 68, 14, - 76, 2, 72, 69, 246, 9, 76, 136, 161, 13, 4, 82, 79, 83, 83, 235, 193, 16, - 67, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 150, 29, 68, 239, 203, 29, 86, - 26, 96, 2, 74, 69, 20, 6, 79, 85, 66, 76, 69, 32, 66, 90, 234, 234, 29, - 67, 186, 22, 87, 215, 22, 69, 5, 183, 250, 22, 82, 4, 36, 3, 77, 79, 78, - 143, 152, 30, 79, 2, 153, 13, 2, 79, 67, 12, 46, 69, 166, 151, 29, 90, - 206, 105, 72, 3, 87, 5, 207, 248, 29, 76, 41, 86, 76, 98, 78, 110, 82, - 166, 15, 32, 214, 252, 12, 83, 178, 209, 14, 77, 231, 183, 2, 70, 11, 33, - 6, 32, 87, 73, 84, 72, 32, 8, 166, 20, 77, 174, 249, 12, 68, 190, 209, + 198, 1, 83, 218, 2, 84, 218, 2, 85, 246, 1, 87, 54, 89, 166, 1, 90, 198, + 204, 29, 70, 134, 14, 74, 2, 86, 159, 20, 81, 17, 108, 6, 32, 87, 73, 84, + 72, 32, 36, 9, 66, 75, 72, 65, 83, 73, 65, 78, 32, 149, 159, 12, 4, 76, + 69, 85, 84, 4, 178, 195, 9, 68, 191, 187, 3, 66, 8, 216, 139, 13, 3, 67, + 72, 69, 210, 210, 6, 68, 195, 175, 10, 72, 18, 110, 65, 78, 73, 32, 3, + 82, 79, 65, 148, 163, 3, 6, 76, 69, 78, 68, 69, 68, 246, 228, 9, 89, 131, + 134, 17, 69, 6, 200, 21, 6, 82, 82, 69, 68, 32, 79, 153, 136, 12, 5, 83, + 72, 75, 73, 82, 4, 230, 2, 78, 207, 160, 3, 71, 2, 163, 180, 10, 68, 14, + 76, 2, 72, 69, 246, 9, 76, 136, 153, 13, 4, 82, 79, 83, 83, 159, 189, 16, + 67, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 150, 29, 68, 163, 191, 29, 86, + 26, 96, 2, 74, 69, 20, 6, 79, 85, 66, 76, 69, 32, 66, 90, 158, 222, 29, + 67, 186, 22, 87, 215, 22, 69, 5, 235, 237, 22, 82, 4, 36, 3, 77, 79, 78, + 195, 139, 30, 79, 2, 153, 13, 2, 79, 67, 12, 46, 69, 218, 138, 29, 90, + 206, 105, 72, 3, 87, 5, 131, 236, 29, 76, 41, 86, 76, 98, 78, 110, 82, + 166, 15, 32, 214, 244, 12, 83, 230, 204, 14, 77, 231, 183, 2, 70, 11, 33, + 6, 32, 87, 73, 84, 72, 32, 8, 166, 20, 77, 174, 241, 12, 68, 242, 204, 14, 84, 183, 97, 72, 13, 33, 6, 32, 87, 73, 84, 72, 32, 10, 198, 19, 77, - 174, 249, 12, 68, 202, 52, 76, 246, 156, 14, 84, 183, 97, 72, 5, 225, - 226, 28, 5, 32, 87, 73, 84, 72, 14, 32, 2, 72, 69, 239, 253, 29, 74, 13, - 33, 6, 32, 87, 73, 84, 72, 32, 10, 142, 18, 77, 146, 15, 85, 158, 234, - 12, 68, 155, 31, 83, 12, 26, 65, 247, 252, 29, 87, 11, 48, 6, 32, 87, 73, - 84, 72, 32, 215, 167, 28, 82, 6, 178, 138, 13, 68, 242, 178, 15, 72, 247, + 174, 241, 12, 68, 202, 52, 76, 170, 152, 14, 84, 183, 97, 72, 5, 149, + 214, 28, 5, 32, 87, 73, 84, 72, 14, 32, 2, 72, 69, 163, 241, 29, 74, 13, + 33, 6, 32, 87, 73, 84, 72, 32, 10, 142, 18, 77, 146, 15, 85, 158, 226, + 12, 68, 155, 31, 83, 12, 26, 65, 171, 240, 29, 87, 11, 48, 6, 32, 87, 73, + 84, 72, 32, 139, 155, 28, 82, 6, 178, 130, 13, 68, 166, 174, 15, 72, 247, 165, 1, 83, 35, 84, 6, 32, 87, 73, 84, 72, 32, 50, 69, 74, 79, 201, 1, 6, - 90, 72, 73, 84, 83, 65, 6, 166, 192, 9, 68, 214, 10, 71, 167, 202, 3, 77, - 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 166, 202, 9, 71, 235, 176, 3, 66, - 17, 11, 84, 14, 48, 6, 73, 70, 73, 69, 68, 32, 211, 144, 30, 65, 12, 80, - 2, 67, 76, 38, 76, 158, 156, 3, 66, 142, 234, 25, 89, 178, 137, 1, 65, 3, - 69, 2, 33, 6, 79, 83, 69, 68, 32, 76, 2, 151, 4, 73, 5, 241, 150, 13, 14, + 90, 72, 73, 84, 83, 65, 6, 166, 184, 9, 68, 214, 10, 71, 167, 202, 3, 77, + 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 166, 194, 9, 71, 235, 176, 3, 66, + 17, 11, 84, 14, 48, 6, 73, 70, 73, 69, 68, 32, 135, 132, 30, 65, 12, 80, + 2, 67, 76, 38, 76, 234, 151, 3, 66, 246, 225, 25, 89, 178, 137, 1, 65, 3, + 69, 2, 33, 6, 79, 83, 69, 68, 32, 76, 2, 151, 4, 73, 5, 241, 142, 13, 14, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, 69, 32, 71, 34, 102, 65, 98, - 79, 180, 219, 17, 10, 72, 65, 75, 65, 83, 83, 73, 65, 78, 32, 174, 155, - 12, 74, 255, 2, 83, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 142, 133, 13, - 68, 242, 178, 15, 72, 170, 165, 1, 86, 79, 83, 18, 36, 3, 77, 73, 32, - 231, 207, 26, 80, 16, 58, 68, 254, 174, 12, 76, 2, 78, 2, 83, 2, 84, 3, - 90, 6, 250, 174, 12, 90, 130, 199, 17, 74, 215, 22, 69, 8, 94, 73, 224, - 209, 10, 10, 79, 78, 71, 45, 76, 69, 71, 71, 69, 68, 142, 163, 19, 74, - 159, 20, 72, 2, 177, 152, 3, 4, 84, 84, 76, 69, 4, 21, 3, 79, 78, 79, 4, - 18, 67, 39, 71, 2, 165, 147, 19, 4, 85, 76, 65, 82, 2, 245, 10, 4, 82, - 65, 80, 72, 6, 62, 69, 164, 146, 19, 5, 65, 82, 82, 79, 87, 247, 224, 10, - 74, 2, 209, 131, 13, 5, 85, 84, 82, 65, 76, 11, 52, 4, 77, 69, 71, 65, - 166, 3, 32, 235, 133, 30, 84, 5, 157, 224, 29, 8, 32, 87, 73, 84, 72, 32, - 84, 73, 10, 138, 6, 69, 182, 250, 12, 65, 195, 244, 16, 83, 14, 50, 69, - 100, 4, 79, 85, 78, 68, 219, 132, 30, 72, 8, 37, 7, 86, 69, 82, 83, 69, - 68, 32, 8, 210, 213, 19, 68, 214, 166, 9, 84, 190, 102, 89, 151, 14, 90, - 4, 234, 168, 10, 32, 153, 249, 1, 2, 69, 68, 34, 108, 4, 67, 72, 87, 65, - 34, 72, 132, 1, 4, 79, 70, 84, 32, 130, 253, 12, 84, 213, 1, 5, 69, 77, - 73, 83, 79, 5, 11, 32, 2, 219, 245, 5, 87, 16, 92, 4, 79, 82, 84, 32, - 224, 251, 12, 2, 72, 65, 238, 139, 15, 67, 214, 230, 1, 87, 215, 22, 65, - 6, 142, 205, 27, 73, 231, 183, 2, 85, 8, 38, 69, 194, 253, 28, 83, 151, - 112, 68, 4, 166, 132, 30, 76, 3, 77, 28, 140, 1, 4, 65, 76, 76, 32, 50, - 69, 106, 83, 232, 149, 12, 11, 72, 82, 69, 69, 45, 76, 69, 71, 71, 69, - 68, 242, 190, 17, 67, 186, 22, 74, 3, 87, 6, 130, 246, 12, 72, 202, 131, - 16, 89, 223, 114, 84, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 26, 77, 175, - 249, 12, 68, 2, 165, 136, 22, 5, 73, 68, 68, 76, 69, 8, 142, 235, 29, 72, + 79, 232, 206, 17, 10, 72, 65, 75, 65, 83, 83, 73, 65, 78, 32, 174, 155, + 12, 74, 255, 2, 83, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 142, 253, 12, + 68, 166, 174, 15, 72, 170, 165, 1, 86, 79, 83, 18, 36, 3, 77, 73, 32, + 155, 195, 26, 80, 16, 58, 68, 254, 166, 12, 76, 2, 78, 2, 83, 2, 84, 3, + 90, 6, 250, 166, 12, 90, 182, 194, 17, 74, 215, 22, 69, 8, 94, 73, 224, + 201, 10, 10, 79, 78, 71, 45, 76, 69, 71, 71, 69, 68, 194, 158, 19, 74, + 159, 20, 72, 2, 253, 147, 3, 4, 84, 84, 76, 69, 4, 21, 3, 79, 78, 79, 4, + 18, 67, 39, 71, 2, 217, 134, 19, 4, 85, 76, 65, 82, 2, 245, 10, 4, 82, + 65, 80, 72, 6, 62, 69, 216, 133, 19, 5, 65, 82, 82, 79, 87, 247, 224, 10, + 74, 2, 209, 251, 12, 5, 85, 84, 82, 65, 76, 11, 52, 4, 77, 69, 71, 65, + 166, 3, 32, 159, 249, 29, 84, 5, 209, 211, 29, 8, 32, 87, 73, 84, 72, 32, + 84, 73, 10, 138, 6, 69, 182, 242, 12, 65, 247, 239, 16, 83, 14, 50, 69, + 100, 4, 79, 85, 78, 68, 143, 248, 29, 72, 8, 37, 7, 86, 69, 82, 83, 69, + 68, 32, 8, 134, 201, 19, 68, 214, 166, 9, 84, 190, 102, 89, 151, 14, 90, + 4, 234, 160, 10, 32, 153, 249, 1, 2, 69, 68, 34, 108, 4, 67, 72, 87, 65, + 34, 72, 132, 1, 4, 79, 70, 84, 32, 130, 245, 12, 84, 213, 1, 5, 69, 77, + 73, 83, 79, 5, 11, 32, 2, 167, 241, 5, 87, 16, 92, 4, 79, 82, 84, 32, + 224, 243, 12, 2, 72, 65, 162, 135, 15, 67, 214, 230, 1, 87, 215, 22, 65, + 6, 194, 192, 27, 73, 231, 183, 2, 85, 8, 38, 69, 246, 240, 28, 83, 151, + 112, 68, 4, 218, 247, 29, 76, 3, 77, 28, 140, 1, 4, 65, 76, 76, 32, 50, + 69, 106, 83, 232, 141, 12, 11, 72, 82, 69, 69, 45, 76, 69, 71, 71, 69, + 68, 166, 186, 17, 67, 186, 22, 74, 3, 87, 6, 130, 238, 12, 72, 254, 254, + 15, 89, 223, 114, 84, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 26, 77, 175, + 241, 12, 68, 2, 217, 251, 21, 5, 73, 68, 68, 76, 69, 8, 194, 222, 29, 72, 2, 83, 2, 87, 215, 22, 69, 15, 58, 32, 114, 75, 53, 8, 78, 66, 76, 69, - 78, 68, 69, 68, 6, 29, 5, 87, 73, 84, 72, 32, 6, 26, 68, 215, 131, 13, - 77, 4, 204, 176, 9, 5, 79, 85, 66, 76, 69, 187, 8, 73, 5, 11, 82, 2, 213, - 4, 6, 65, 73, 78, 73, 65, 78, 2, 235, 129, 25, 32, 4, 184, 233, 28, 4, - 73, 68, 69, 32, 135, 150, 1, 69, 18, 62, 65, 28, 3, 69, 82, 85, 178, 254, - 29, 73, 2, 78, 3, 85, 7, 202, 254, 29, 69, 3, 84, 7, 33, 6, 32, 87, 73, - 84, 72, 32, 4, 170, 172, 9, 68, 179, 203, 3, 66, 18, 18, 69, 71, 72, 9, - 156, 1, 7, 32, 87, 73, 84, 72, 32, 68, 217, 249, 29, 2, 77, 76, 10, 26, - 69, 163, 230, 29, 87, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 26, 68, 147, - 230, 12, 66, 4, 254, 180, 9, 73, 227, 190, 3, 69, 6, 37, 7, 71, 65, 84, - 85, 82, 69, 32, 6, 66, 65, 128, 213, 15, 2, 84, 69, 153, 249, 13, 4, 69, - 78, 32, 71, 2, 243, 223, 29, 32, 52, 198, 1, 66, 38, 68, 38, 69, 36, 3, - 71, 72, 69, 38, 72, 234, 156, 22, 89, 170, 222, 5, 83, 134, 114, 84, 134, + 78, 68, 69, 68, 6, 29, 5, 87, 73, 84, 72, 32, 6, 26, 68, 215, 251, 12, + 77, 4, 204, 168, 9, 5, 79, 85, 66, 76, 69, 187, 8, 73, 5, 11, 82, 2, 213, + 4, 6, 65, 73, 78, 73, 65, 78, 2, 159, 245, 24, 32, 4, 236, 220, 28, 4, + 73, 68, 69, 32, 135, 150, 1, 69, 18, 62, 65, 28, 3, 69, 82, 85, 230, 241, + 29, 73, 2, 78, 3, 85, 7, 254, 241, 29, 69, 3, 84, 7, 33, 6, 32, 87, 73, + 84, 72, 32, 4, 170, 164, 9, 68, 179, 203, 3, 66, 18, 18, 69, 71, 72, 9, + 156, 1, 7, 32, 87, 73, 84, 72, 32, 68, 141, 237, 29, 2, 77, 76, 10, 26, + 69, 215, 217, 29, 87, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 26, 68, 147, + 222, 12, 66, 4, 254, 172, 9, 73, 227, 190, 3, 69, 6, 37, 7, 71, 65, 84, + 85, 82, 69, 32, 6, 66, 65, 180, 200, 15, 2, 84, 69, 153, 249, 13, 4, 69, + 78, 32, 71, 2, 167, 211, 29, 32, 52, 198, 1, 66, 38, 68, 38, 69, 36, 3, + 71, 72, 69, 38, 72, 158, 144, 22, 89, 170, 222, 5, 83, 134, 114, 84, 134, 11, 90, 130, 64, 73, 150, 19, 67, 186, 22, 80, 2, 86, 158, 20, 75, 186, - 2, 65, 2, 79, 3, 85, 4, 250, 238, 12, 89, 207, 138, 17, 69, 6, 130, 249, - 28, 90, 163, 128, 1, 69, 6, 254, 248, 29, 70, 2, 76, 3, 83, 5, 201, 5, 5, - 32, 87, 73, 84, 72, 4, 11, 65, 5, 235, 140, 28, 82, 2, 221, 134, 16, 4, + 2, 65, 2, 79, 3, 85, 4, 250, 230, 12, 89, 131, 134, 17, 69, 6, 182, 236, + 28, 90, 163, 128, 1, 69, 6, 178, 236, 29, 70, 2, 76, 3, 83, 5, 201, 5, 5, + 32, 87, 73, 84, 72, 4, 11, 65, 5, 159, 128, 28, 82, 2, 145, 250, 15, 4, 72, 79, 85, 83, 214, 15, 178, 1, 65, 138, 4, 67, 54, 69, 154, 35, 73, - 166, 23, 79, 154, 45, 82, 174, 3, 85, 172, 246, 12, 13, 78, 65, 32, 68, - 79, 85, 66, 76, 69, 32, 72, 69, 76, 182, 202, 15, 86, 207, 47, 76, 30, + 166, 23, 79, 154, 45, 82, 174, 3, 85, 172, 238, 12, 13, 78, 65, 32, 68, + 79, 85, 66, 76, 69, 32, 72, 69, 76, 234, 197, 15, 86, 207, 47, 76, 30, 116, 4, 71, 71, 69, 82, 146, 1, 78, 32, 4, 82, 75, 32, 83, 36, 2, 83, 72, - 160, 145, 22, 2, 76, 69, 131, 145, 1, 84, 9, 11, 32, 6, 44, 5, 87, 73, - 84, 72, 32, 171, 218, 6, 75, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, - 2, 217, 219, 28, 4, 84, 32, 71, 85, 4, 198, 182, 29, 67, 251, 30, 71, 4, - 190, 220, 21, 85, 155, 157, 5, 72, 10, 30, 32, 105, 3, 69, 68, 32, 4, 60, - 9, 87, 73, 84, 72, 32, 76, 69, 70, 84, 231, 221, 28, 83, 2, 17, 2, 32, - 85, 2, 239, 160, 23, 80, 6, 206, 240, 4, 84, 130, 197, 12, 76, 207, 210, - 10, 79, 10, 178, 242, 29, 49, 2, 50, 2, 51, 2, 52, 3, 83, 180, 4, 222, 1, + 212, 132, 22, 2, 76, 69, 131, 145, 1, 84, 9, 11, 32, 6, 44, 5, 87, 73, + 84, 72, 32, 247, 213, 6, 75, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, + 2, 141, 207, 28, 4, 84, 32, 71, 85, 4, 250, 169, 29, 67, 251, 30, 71, 4, + 242, 207, 21, 85, 155, 157, 5, 72, 10, 30, 32, 105, 3, 69, 68, 32, 4, 60, + 9, 87, 73, 84, 72, 32, 76, 69, 70, 84, 155, 209, 28, 83, 2, 17, 2, 32, + 85, 2, 163, 148, 23, 80, 6, 154, 236, 4, 84, 234, 188, 12, 76, 207, 210, + 10, 79, 10, 230, 229, 29, 49, 2, 50, 2, 51, 2, 52, 3, 83, 180, 4, 222, 1, 67, 248, 1, 5, 71, 82, 69, 69, 32, 98, 76, 82, 78, 228, 3, 8, 80, 65, 82, 84, 77, 69, 78, 84, 32, 12, 82, 69, 76, 73, 67, 84, 32, 72, 79, 85, 83, - 69, 42, 83, 174, 6, 86, 224, 221, 25, 2, 65, 70, 227, 203, 3, 69, 8, 50, - 73, 225, 129, 6, 6, 82, 69, 65, 83, 69, 32, 6, 56, 4, 77, 65, 76, 32, - 237, 177, 9, 4, 68, 85, 79, 85, 4, 88, 9, 83, 69, 80, 65, 82, 65, 84, 79, - 82, 129, 140, 22, 7, 69, 88, 80, 79, 78, 69, 78, 2, 21, 3, 32, 75, 69, 2, - 243, 216, 28, 89, 6, 240, 213, 22, 4, 67, 69, 76, 83, 202, 145, 6, 83, - 177, 106, 8, 70, 65, 72, 82, 69, 78, 72, 69, 9, 196, 137, 17, 5, 73, 86, + 69, 42, 83, 174, 6, 86, 148, 209, 25, 2, 65, 70, 227, 203, 3, 69, 8, 50, + 73, 173, 253, 5, 6, 82, 69, 65, 83, 69, 32, 6, 56, 4, 77, 65, 76, 32, + 237, 169, 9, 4, 68, 85, 79, 85, 4, 88, 9, 83, 69, 80, 65, 82, 65, 84, 79, + 82, 181, 255, 21, 7, 69, 88, 80, 79, 78, 69, 78, 2, 21, 3, 32, 75, 69, 2, + 167, 204, 28, 89, 6, 164, 201, 22, 4, 67, 69, 76, 83, 202, 145, 6, 83, + 177, 106, 8, 70, 65, 72, 82, 69, 78, 72, 69, 9, 248, 252, 16, 5, 73, 86, 69, 82, 89, 160, 130, 6, 2, 84, 65, 203, 152, 5, 69, 34, 104, 20, 84, 73, 83, 84, 82, 89, 32, 83, 89, 77, 66, 79, 76, 32, 76, 73, 71, 72, 84, 32, - 243, 128, 22, 83, 30, 88, 4, 68, 79, 87, 78, 0, 2, 85, 80, 153, 1, 9, 86, + 167, 244, 21, 83, 30, 88, 4, 68, 79, 87, 78, 0, 2, 85, 80, 153, 1, 9, 86, 69, 82, 84, 73, 67, 65, 76, 32, 8, 69, 15, 32, 65, 78, 68, 32, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 162, - 252, 27, 87, 134, 26, 67, 167, 45, 84, 14, 52, 4, 65, 78, 68, 32, 45, 5, - 87, 73, 84, 72, 32, 10, 238, 175, 22, 66, 42, 84, 171, 203, 5, 87, 4, - 150, 149, 28, 67, 167, 45, 84, 2, 253, 251, 24, 3, 32, 83, 84, 2, 185, - 162, 23, 5, 32, 66, 85, 73, 76, 170, 1, 64, 2, 67, 69, 48, 2, 69, 82, - 129, 5, 5, 75, 84, 79, 80, 32, 2, 253, 212, 27, 7, 78, 68, 73, 78, 71, + 82, 73, 90, 79, 78, 84, 65, 76, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 214, + 239, 27, 87, 134, 26, 67, 167, 45, 84, 14, 52, 4, 65, 78, 68, 32, 45, 5, + 87, 73, 84, 72, 32, 10, 162, 163, 22, 66, 42, 84, 171, 203, 5, 87, 4, + 202, 136, 28, 67, 167, 45, 84, 2, 177, 239, 24, 3, 32, 83, 84, 2, 237, + 149, 23, 5, 32, 66, 85, 73, 76, 170, 1, 64, 2, 67, 69, 48, 2, 69, 82, + 129, 5, 5, 75, 84, 79, 80, 32, 2, 177, 200, 27, 7, 78, 68, 73, 78, 71, 32, 78, 164, 1, 32, 3, 69, 84, 32, 183, 4, 84, 160, 1, 56, 6, 67, 65, 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 80, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 80, 218, 1, 69, 96, 4, 76, 79, 78, 71, 0, 5, 83, 72, 79, 82, 84, - 74, 79, 30, 84, 2, 90, 158, 245, 11, 67, 222, 251, 15, 66, 2, 68, 2, 74, + 74, 79, 30, 84, 2, 90, 158, 237, 11, 67, 146, 247, 15, 66, 2, 68, 2, 74, 2, 80, 2, 86, 2, 89, 130, 100, 71, 2, 75, 186, 105, 87, 162, 19, 65, 203, - 17, 72, 20, 250, 211, 25, 83, 226, 146, 2, 78, 242, 252, 1, 84, 146, 1, - 70, 2, 76, 2, 77, 2, 82, 3, 87, 12, 11, 32, 12, 142, 211, 25, 65, 178, - 199, 1, 79, 178, 201, 2, 69, 3, 73, 4, 178, 227, 29, 73, 3, 87, 4, 246, - 240, 27, 72, 207, 219, 1, 69, 5, 209, 210, 28, 4, 32, 73, 83, 76, 4, 154, - 228, 26, 67, 141, 226, 1, 4, 87, 73, 78, 68, 202, 2, 100, 8, 65, 78, 65, + 17, 72, 20, 174, 199, 25, 83, 226, 146, 2, 78, 242, 252, 1, 84, 146, 1, + 70, 2, 76, 2, 77, 2, 82, 3, 87, 12, 11, 32, 12, 194, 198, 25, 65, 178, + 199, 1, 79, 178, 201, 2, 69, 3, 73, 4, 230, 214, 29, 73, 3, 87, 4, 170, + 228, 27, 72, 207, 219, 1, 69, 5, 133, 198, 28, 4, 32, 73, 83, 76, 4, 206, + 215, 26, 67, 141, 226, 1, 4, 87, 73, 78, 68, 202, 2, 100, 8, 65, 78, 65, 71, 65, 82, 73, 32, 133, 18, 12, 73, 67, 69, 32, 67, 79, 78, 84, 82, 79, 76, 32, 192, 2, 222, 1, 65, 38, 67, 22, 71, 36, 4, 72, 69, 65, 68, 96, 7, 76, 69, 84, 84, 69, 82, 32, 202, 5, 83, 148, 7, 11, 86, 79, 87, 69, 76, - 32, 83, 73, 71, 78, 32, 186, 144, 19, 68, 160, 139, 6, 4, 74, 65, 73, 78, - 135, 165, 4, 79, 4, 218, 230, 12, 67, 187, 216, 12, 66, 2, 199, 153, 6, - 65, 4, 202, 230, 12, 82, 151, 238, 1, 65, 6, 44, 5, 32, 77, 65, 82, 75, - 199, 174, 29, 83, 5, 217, 158, 19, 7, 32, 87, 73, 84, 72, 32, 72, 158, 1, + 32, 83, 73, 71, 78, 32, 238, 131, 19, 68, 160, 139, 6, 4, 74, 65, 73, 78, + 135, 165, 4, 79, 4, 218, 222, 12, 67, 239, 211, 12, 66, 2, 147, 149, 6, + 65, 4, 202, 222, 12, 82, 151, 238, 1, 65, 6, 44, 5, 32, 77, 65, 82, 75, + 251, 161, 29, 83, 5, 141, 146, 19, 7, 32, 87, 73, 84, 72, 32, 72, 158, 1, 162, 2, 65, 54, 67, 62, 68, 50, 71, 62, 72, 52, 2, 77, 65, 46, 83, 170, - 165, 7, 66, 150, 131, 5, 75, 206, 202, 3, 82, 150, 173, 3, 79, 238, 192, + 157, 7, 66, 150, 131, 5, 75, 130, 198, 3, 82, 150, 173, 3, 79, 238, 192, 3, 89, 214, 118, 85, 250, 35, 78, 138, 199, 1, 74, 174, 57, 76, 70, 84, 46, 86, 242, 207, 1, 73, 134, 197, 1, 80, 2, 90, 138, 69, 70, 2, 81, 187, - 2, 69, 13, 230, 219, 29, 65, 2, 73, 2, 85, 2, 87, 3, 89, 10, 26, 65, 227, - 216, 29, 72, 9, 185, 2, 4, 78, 68, 82, 65, 12, 166, 253, 25, 68, 154, - 219, 3, 72, 187, 2, 65, 10, 134, 252, 12, 76, 130, 151, 16, 72, 138, 69, - 71, 187, 2, 65, 4, 136, 225, 16, 4, 69, 65, 86, 89, 131, 249, 12, 65, 5, - 157, 162, 7, 6, 82, 87, 65, 82, 73, 32, 12, 38, 72, 206, 214, 29, 83, - 187, 2, 65, 8, 36, 3, 79, 82, 84, 223, 216, 29, 65, 6, 167, 150, 12, 32, + 2, 69, 13, 154, 207, 29, 65, 2, 73, 2, 85, 2, 87, 3, 89, 10, 26, 65, 151, + 204, 29, 72, 9, 185, 2, 4, 78, 68, 82, 65, 12, 218, 240, 25, 68, 154, + 219, 3, 72, 187, 2, 65, 10, 134, 244, 12, 76, 182, 146, 16, 72, 138, 69, + 71, 187, 2, 65, 4, 188, 212, 16, 4, 69, 65, 86, 89, 131, 249, 12, 65, 5, + 157, 154, 7, 6, 82, 87, 65, 82, 73, 32, 12, 38, 72, 130, 202, 29, 83, + 187, 2, 65, 8, 36, 3, 79, 82, 84, 147, 204, 29, 65, 6, 167, 142, 12, 32, 68, 168, 1, 19, 69, 81, 85, 69, 78, 67, 69, 32, 70, 79, 82, 32, 76, 69, - 84, 84, 69, 82, 32, 104, 4, 73, 71, 78, 32, 137, 156, 27, 10, 84, 82, 69, - 83, 83, 32, 83, 73, 71, 78, 16, 210, 223, 3, 71, 2, 75, 160, 250, 23, 3, + 84, 84, 69, 82, 32, 104, 4, 73, 71, 78, 32, 189, 143, 27, 10, 84, 82, 69, + 83, 83, 32, 83, 73, 71, 78, 16, 158, 219, 3, 71, 2, 75, 136, 242, 23, 3, 68, 68, 68, 2, 82, 206, 250, 1, 89, 38, 70, 2, 81, 3, 90, 48, 178, 3, 66, 0, 10, 69, 88, 84, 69, 78, 68, 69, 68, 32, 66, 36, 11, 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 64, 8, 87, 69, 83, 84, 69, 82, 78, 32, 32, - 10, 82, 69, 86, 69, 82, 83, 69, 68, 32, 78, 138, 208, 6, 83, 182, 198, + 10, 82, 69, 86, 69, 82, 83, 69, 68, 32, 78, 214, 203, 6, 83, 158, 190, 12, 73, 150, 158, 6, 77, 46, 78, 190, 66, 65, 72, 18, 68, 79, 85, 66, 76, 69, 32, 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 62, 80, 144, 198, 2, 12, 72, 73, 71, 72, 32, 83, 80, 65, 67, 73, 78, 71, 167, 80, 86, 4, 245, - 236, 12, 4, 72, 65, 76, 69, 11, 11, 32, 8, 206, 213, 22, 65, 154, 163, 3, + 228, 12, 4, 72, 65, 76, 69, 11, 11, 32, 8, 130, 201, 22, 65, 154, 163, 3, 86, 163, 231, 1, 84, 4, 30, 78, 21, 3, 70, 73, 86, 2, 17, 2, 73, 78, 2, - 193, 240, 21, 8, 69, 45, 76, 73, 75, 69, 32, 66, 50, 150, 1, 65, 52, 7, - 67, 65, 78, 68, 82, 65, 32, 218, 150, 19, 79, 34, 80, 162, 183, 4, 85, - 194, 229, 1, 83, 170, 69, 86, 166, 202, 1, 73, 199, 140, 2, 69, 10, 154, - 208, 29, 65, 2, 73, 2, 85, 2, 87, 3, 89, 6, 176, 151, 19, 4, 76, 79, 78, - 71, 182, 184, 10, 69, 3, 79, 10, 222, 179, 24, 70, 136, 6, 2, 83, 84, + 245, 227, 21, 8, 69, 45, 76, 73, 75, 69, 32, 66, 50, 150, 1, 65, 52, 7, + 67, 65, 78, 68, 82, 65, 32, 142, 138, 19, 79, 34, 80, 162, 183, 4, 85, + 194, 229, 1, 83, 170, 69, 86, 166, 202, 1, 73, 199, 140, 2, 69, 10, 206, + 195, 29, 65, 2, 73, 2, 85, 2, 87, 3, 89, 6, 228, 138, 19, 4, 76, 79, 78, + 71, 182, 184, 10, 69, 3, 79, 10, 146, 167, 24, 70, 136, 6, 2, 83, 84, 254, 162, 3, 84, 155, 87, 79, 232, 2, 182, 2, 65, 150, 2, 69, 74, 71, 224, 4, 6, 78, 71, 66, 65, 84, 32, 248, 1, 5, 82, 69, 67, 84, 32, 98, 83, - 206, 2, 86, 200, 7, 2, 89, 65, 32, 4, 90, 90, 89, 32, 232, 179, 5, 2, 84, - 84, 228, 168, 15, 10, 70, 70, 69, 82, 69, 78, 67, 69, 32, 66, 197, 219, + 206, 2, 86, 200, 7, 2, 89, 65, 32, 4, 90, 90, 89, 32, 180, 175, 5, 2, 84, + 84, 204, 160, 15, 10, 70, 70, 69, 82, 69, 78, 67, 69, 32, 66, 197, 219, 7, 12, 77, 69, 78, 83, 73, 79, 78, 32, 79, 82, 73, 71, 20, 42, 77, 226, - 132, 9, 69, 155, 145, 13, 71, 16, 40, 4, 79, 78, 68, 32, 171, 159, 3, 69, - 14, 128, 1, 5, 87, 73, 84, 72, 32, 198, 179, 18, 84, 232, 228, 2, 12, 83, - 72, 65, 80, 69, 32, 87, 73, 84, 72, 32, 65, 251, 238, 4, 79, 8, 146, 148, - 22, 66, 182, 2, 84, 174, 148, 4, 76, 27, 82, 14, 184, 138, 5, 5, 32, 70, - 65, 67, 69, 213, 173, 17, 4, 83, 69, 76, 32, 78, 64, 3, 73, 84, 32, 149, + 252, 8, 69, 207, 140, 13, 71, 16, 40, 4, 79, 78, 68, 32, 247, 154, 3, 69, + 14, 128, 1, 5, 87, 73, 84, 72, 32, 250, 166, 18, 84, 232, 228, 2, 12, 83, + 72, 65, 80, 69, 32, 87, 73, 84, 72, 32, 65, 251, 238, 4, 79, 8, 198, 135, + 22, 66, 182, 2, 84, 174, 148, 4, 76, 27, 82, 14, 132, 134, 5, 5, 32, 70, + 65, 67, 69, 189, 165, 17, 4, 83, 69, 76, 32, 78, 64, 3, 73, 84, 32, 149, 2, 8, 82, 65, 77, 32, 70, 79, 82, 32, 60, 98, 70, 44, 2, 78, 73, 2, 79, 14, 83, 46, 84, 44, 3, 90, 69, 82, 13, 5, 69, 73, 71, 72, 84, 12, 128, 1, 2, 73, 86, 25, 3, 79, 85, 82, 6, 87, 78, 12, 96, 4, 69, 86, 69, 78, 1, 2, - 73, 88, 12, 28, 3, 72, 82, 69, 15, 87, 6, 23, 69, 6, 11, 79, 7, 219, 133, - 17, 32, 18, 88, 5, 69, 65, 82, 84, 72, 64, 5, 71, 82, 69, 65, 84, 0, 4, - 76, 69, 83, 83, 39, 72, 7, 25, 4, 76, 89, 32, 72, 4, 214, 199, 24, 85, - 239, 145, 1, 69, 4, 193, 146, 13, 4, 69, 82, 32, 89, 4, 200, 155, 5, 7, + 73, 88, 12, 28, 3, 72, 82, 69, 15, 87, 6, 23, 69, 6, 11, 79, 7, 143, 249, + 16, 32, 18, 88, 5, 69, 65, 82, 84, 72, 64, 5, 71, 82, 69, 65, 84, 0, 4, + 76, 69, 83, 83, 39, 72, 7, 25, 4, 76, 89, 32, 72, 4, 138, 187, 24, 85, + 239, 145, 1, 69, 4, 193, 138, 13, 4, 69, 82, 32, 89, 4, 148, 151, 5, 7, 69, 65, 86, 69, 78, 76, 89, 1, 4, 85, 77, 65, 78, 64, 120, 17, 78, 69, 71, 65, 84, 73, 86, 69, 32, 67, 73, 82, 67, 76, 69, 68, 32, 41, 9, 67, - 73, 82, 67, 76, 69, 68, 32, 83, 42, 38, 83, 182, 32, 78, 203, 215, 20, + 73, 82, 67, 76, 69, 68, 32, 83, 42, 38, 83, 182, 32, 78, 255, 202, 20, 68, 22, 49, 10, 65, 78, 83, 45, 83, 69, 82, 73, 70, 32, 22, 254, 31, 78, - 147, 175, 27, 68, 4, 132, 174, 27, 15, 67, 85, 82, 82, 69, 78, 84, 32, + 199, 162, 27, 68, 4, 184, 161, 27, 15, 67, 85, 82, 82, 69, 78, 84, 32, 83, 89, 77, 66, 79, 76, 32, 187, 248, 1, 72, 12, 98, 65, 144, 1, 5, 67, - 79, 78, 84, 73, 192, 240, 15, 3, 84, 79, 82, 253, 152, 10, 3, 71, 85, 73, - 6, 76, 9, 80, 80, 79, 73, 78, 84, 69, 68, 32, 245, 161, 27, 4, 66, 76, - 69, 68, 4, 144, 175, 17, 7, 66, 85, 84, 32, 82, 69, 76, 203, 212, 11, 70, - 2, 53, 11, 78, 85, 79, 85, 83, 32, 85, 78, 68, 69, 82, 2, 157, 145, 17, + 79, 78, 84, 73, 244, 227, 15, 3, 84, 79, 82, 253, 152, 10, 3, 71, 85, 73, + 6, 76, 9, 80, 80, 79, 73, 78, 84, 69, 68, 32, 169, 149, 27, 4, 66, 76, + 69, 68, 4, 196, 162, 17, 7, 66, 85, 84, 32, 82, 69, 76, 203, 212, 11, 70, + 2, 53, 11, 78, 85, 79, 85, 83, 32, 85, 78, 68, 69, 82, 2, 209, 132, 17, 3, 76, 73, 78, 156, 1, 80, 9, 69, 83, 32, 65, 75, 85, 82, 85, 32, 238, 5, - 73, 177, 138, 17, 2, 79, 82, 144, 1, 142, 2, 68, 36, 7, 76, 69, 84, 84, - 69, 82, 32, 236, 1, 5, 83, 73, 71, 78, 32, 58, 86, 240, 170, 9, 6, 77, - 69, 68, 73, 65, 76, 234, 132, 5, 71, 134, 237, 4, 69, 148, 209, 4, 12, + 73, 229, 253, 16, 2, 79, 82, 144, 1, 142, 2, 68, 36, 7, 76, 69, 84, 84, + 69, 82, 32, 236, 1, 5, 83, 73, 71, 78, 32, 58, 86, 240, 162, 9, 6, 77, + 69, 68, 73, 65, 76, 234, 132, 5, 71, 186, 232, 4, 69, 148, 209, 4, 12, 80, 82, 69, 70, 73, 88, 69, 68, 32, 78, 65, 83, 209, 129, 5, 7, 73, 78, - 73, 84, 73, 65, 76, 22, 166, 220, 25, 79, 191, 236, 1, 73, 84, 218, 208, - 10, 84, 190, 243, 11, 89, 182, 230, 2, 65, 162, 52, 68, 214, 6, 85, 186, + 73, 84, 73, 65, 76, 22, 218, 207, 25, 79, 191, 236, 1, 73, 84, 218, 200, + 10, 84, 242, 238, 11, 89, 182, 230, 2, 65, 162, 52, 68, 214, 6, 85, 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 75, 2, 80, 138, 69, 72, 2, 74, 2, 77, 2, 82, 2, 86, 2, 90, 186, 2, 69, 3, 79, - 8, 158, 242, 24, 72, 210, 42, 67, 98, 78, 139, 216, 3, 65, 18, 64, 10, - 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 187, 253, 26, 73, 16, 166, 164, + 8, 210, 229, 24, 72, 210, 42, 67, 98, 78, 139, 216, 3, 65, 18, 64, 10, + 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 239, 240, 26, 73, 16, 218, 151, 15, 65, 178, 190, 10, 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 10, - 68, 5, 83, 73, 79, 78, 32, 136, 242, 1, 2, 78, 71, 183, 176, 26, 68, 6, - 26, 83, 235, 234, 5, 84, 4, 142, 205, 27, 76, 187, 100, 73, 2, 253, 150, - 19, 3, 32, 76, 65, 4, 182, 162, 28, 83, 167, 88, 70, 212, 5, 188, 2, 6, + 68, 5, 83, 73, 79, 78, 32, 212, 237, 1, 2, 78, 71, 159, 168, 26, 68, 6, + 26, 83, 183, 230, 5, 84, 4, 194, 192, 27, 76, 187, 100, 73, 2, 177, 138, + 19, 3, 32, 76, 65, 4, 234, 149, 28, 83, 167, 88, 70, 212, 5, 188, 2, 6, 67, 85, 77, 69, 78, 84, 124, 7, 69, 83, 32, 78, 79, 84, 32, 194, 3, 71, 202, 3, 76, 36, 10, 77, 73, 78, 79, 32, 84, 73, 76, 69, 32, 226, 1, 78, - 38, 84, 246, 2, 85, 204, 17, 2, 87, 78, 212, 203, 16, 8, 32, 78, 79, 84, + 38, 84, 246, 2, 85, 204, 17, 2, 87, 78, 136, 191, 16, 8, 32, 78, 79, 84, 32, 76, 73, 84, 184, 141, 12, 8, 86, 69, 32, 79, 70, 32, 80, 69, 174, 4, 79, 235, 25, 68, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 40, 4, 84, 69, 88, - 84, 175, 143, 2, 80, 5, 169, 143, 2, 6, 32, 65, 78, 68, 32, 80, 22, 164, + 84, 251, 138, 2, 80, 5, 245, 138, 2, 6, 32, 65, 78, 68, 32, 80, 22, 164, 1, 11, 67, 79, 78, 84, 65, 73, 78, 32, 65, 83, 32, 92, 6, 68, 73, 86, 73, - 68, 69, 112, 2, 80, 82, 48, 7, 83, 85, 67, 67, 69, 69, 68, 185, 233, 22, + 68, 69, 112, 2, 80, 82, 48, 7, 83, 85, 67, 67, 69, 69, 68, 237, 220, 22, 2, 70, 79, 6, 248, 1, 15, 78, 79, 82, 77, 65, 76, 32, 83, 85, 66, 71, 82, - 79, 85, 80, 155, 137, 21, 77, 5, 145, 141, 22, 23, 32, 87, 73, 84, 72, + 79, 85, 80, 207, 252, 20, 77, 5, 197, 128, 22, 23, 32, 87, 73, 84, 72, 32, 82, 69, 86, 69, 82, 83, 69, 68, 32, 78, 69, 71, 65, 84, 73, 79, 78, - 6, 44, 5, 69, 67, 69, 68, 69, 143, 180, 28, 79, 5, 205, 167, 9, 2, 32, - 79, 125, 36, 3, 82, 65, 32, 139, 243, 28, 32, 120, 120, 7, 76, 69, 84, + 6, 44, 5, 69, 67, 69, 68, 69, 195, 167, 28, 79, 5, 205, 159, 9, 2, 32, + 79, 125, 36, 3, 82, 65, 32, 191, 230, 28, 32, 120, 120, 7, 76, 69, 84, 84, 69, 82, 32, 208, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, - 254, 185, 23, 65, 187, 2, 83, 88, 170, 209, 25, 65, 38, 68, 82, 82, 34, + 178, 173, 23, 65, 187, 2, 83, 88, 222, 196, 25, 65, 38, 68, 82, 82, 34, 84, 230, 5, 85, 186, 202, 1, 73, 138, 196, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 86, 2, 89, 186, - 2, 69, 3, 79, 22, 130, 159, 19, 86, 174, 183, 6, 65, 38, 85, 186, 202, 1, - 73, 198, 140, 2, 69, 3, 79, 4, 142, 161, 21, 80, 199, 193, 2, 76, 200, 1, + 2, 69, 3, 79, 22, 182, 146, 19, 86, 174, 183, 6, 65, 38, 85, 186, 202, 1, + 73, 198, 140, 2, 69, 3, 79, 4, 194, 148, 21, 80, 199, 193, 2, 76, 200, 1, 72, 8, 72, 79, 82, 73, 90, 79, 78, 84, 1, 6, 86, 69, 82, 84, 73, 67, 100, - 17, 2, 65, 76, 100, 32, 2, 45, 48, 155, 148, 24, 32, 98, 58, 48, 2, 49, - 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 14, 149, 186, 20, 2, 45, 48, 4, 158, - 141, 27, 75, 219, 150, 1, 71, 26, 34, 32, 57, 4, 84, 69, 68, 32, 8, 162, - 159, 25, 80, 34, 77, 194, 71, 79, 195, 198, 2, 65, 18, 214, 1, 67, 34, - 83, 128, 160, 16, 3, 76, 73, 78, 148, 134, 1, 4, 79, 66, 69, 76, 244, 9, + 17, 2, 65, 76, 100, 32, 2, 45, 48, 207, 135, 24, 32, 98, 58, 48, 2, 49, + 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 14, 201, 173, 20, 2, 45, 48, 4, 210, + 128, 27, 75, 219, 150, 1, 71, 26, 34, 32, 57, 4, 84, 69, 68, 32, 8, 214, + 146, 25, 80, 34, 77, 194, 71, 79, 195, 198, 2, 65, 18, 214, 1, 67, 34, + 83, 180, 147, 16, 3, 76, 73, 78, 148, 134, 1, 4, 79, 66, 69, 76, 244, 9, 9, 84, 82, 65, 78, 83, 80, 79, 83, 73, 202, 230, 6, 70, 161, 41, 14, 82, - 73, 71, 72, 84, 45, 80, 79, 73, 78, 84, 73, 78, 71, 4, 146, 212, 27, 73, - 239, 16, 82, 4, 246, 144, 27, 79, 183, 116, 81, 162, 1, 40, 3, 66, 76, + 73, 71, 72, 84, 45, 80, 79, 73, 78, 84, 73, 78, 71, 4, 198, 199, 27, 73, + 239, 16, 82, 4, 170, 132, 27, 79, 183, 116, 81, 162, 1, 40, 3, 66, 76, 69, 137, 17, 2, 71, 72, 160, 1, 42, 32, 190, 10, 45, 241, 5, 2, 68, 32, 106, 226, 2, 67, 174, 1, 68, 38, 72, 32, 4, 73, 78, 84, 69, 38, 76, 144, 1, 7, 78, 69, 83, 84, 69, 68, 32, 74, 80, 66, 83, 130, 2, 85, 36, 9, 86, - 69, 82, 84, 73, 67, 65, 76, 32, 188, 168, 6, 6, 79, 66, 76, 73, 81, 85, - 144, 191, 2, 9, 82, 73, 71, 72, 84, 32, 65, 82, 67, 134, 189, 3, 65, 166, - 221, 9, 69, 246, 198, 4, 81, 153, 106, 6, 87, 65, 86, 89, 32, 79, 24, - 100, 7, 73, 82, 67, 76, 69, 68, 32, 140, 215, 7, 4, 85, 82, 76, 89, 253, - 197, 1, 4, 79, 76, 79, 78, 20, 26, 78, 203, 215, 20, 68, 2, 221, 219, 2, - 5, 85, 77, 66, 69, 82, 4, 150, 255, 18, 79, 167, 210, 6, 65, 4, 250, 209, - 20, 73, 239, 63, 89, 4, 146, 160, 26, 82, 179, 246, 1, 71, 12, 54, 79, - 165, 171, 17, 7, 69, 70, 84, 32, 65, 82, 67, 10, 26, 87, 191, 220, 25, - 71, 6, 26, 45, 211, 133, 28, 32, 4, 226, 208, 20, 82, 211, 1, 57, 6, 132, - 153, 17, 9, 76, 69, 83, 83, 45, 84, 72, 65, 78, 255, 241, 9, 71, 8, 26, - 82, 179, 151, 27, 76, 6, 138, 158, 1, 69, 219, 250, 15, 73, 18, 80, 6, - 81, 85, 65, 82, 69, 32, 30, 84, 50, 85, 173, 229, 13, 4, 79, 76, 73, 68, - 4, 222, 235, 25, 73, 55, 85, 4, 212, 205, 12, 3, 65, 67, 75, 163, 202, 4, - 82, 8, 58, 83, 170, 156, 1, 67, 146, 156, 21, 80, 175, 247, 4, 66, 2, - 245, 180, 28, 4, 80, 69, 78, 83, 4, 174, 250, 18, 80, 255, 210, 9, 78, - 10, 36, 3, 66, 65, 82, 235, 129, 28, 76, 9, 11, 32, 6, 52, 7, 68, 79, 85, - 66, 76, 69, 32, 143, 243, 26, 76, 4, 138, 243, 26, 76, 51, 82, 48, 112, - 5, 76, 73, 78, 69, 32, 220, 1, 7, 83, 84, 82, 85, 67, 75, 32, 133, 235, + 69, 82, 84, 73, 67, 65, 76, 32, 136, 164, 6, 6, 79, 66, 76, 73, 81, 85, + 196, 187, 2, 9, 82, 73, 71, 72, 84, 32, 65, 82, 67, 134, 189, 3, 65, 218, + 216, 9, 69, 246, 198, 4, 81, 153, 106, 6, 87, 65, 86, 89, 32, 79, 24, + 100, 7, 73, 82, 67, 76, 69, 68, 32, 140, 207, 7, 4, 85, 82, 76, 89, 253, + 197, 1, 4, 79, 76, 79, 78, 20, 26, 78, 255, 202, 20, 68, 2, 169, 215, 2, + 5, 85, 77, 66, 69, 82, 4, 202, 242, 18, 79, 167, 210, 6, 65, 4, 174, 197, + 20, 73, 239, 63, 89, 4, 198, 147, 26, 82, 179, 246, 1, 71, 12, 54, 79, + 217, 158, 17, 7, 69, 70, 84, 32, 65, 82, 67, 10, 26, 87, 243, 207, 25, + 71, 6, 26, 45, 135, 249, 27, 32, 4, 150, 196, 20, 82, 211, 1, 57, 6, 184, + 140, 17, 9, 76, 69, 83, 83, 45, 84, 72, 65, 78, 255, 241, 9, 71, 8, 26, + 82, 231, 138, 27, 76, 6, 214, 153, 1, 69, 195, 242, 15, 73, 18, 80, 6, + 81, 85, 65, 82, 69, 32, 30, 84, 50, 85, 173, 221, 13, 4, 79, 76, 73, 68, + 4, 146, 223, 25, 73, 55, 85, 4, 212, 197, 12, 3, 65, 67, 75, 215, 197, 4, + 82, 8, 58, 83, 246, 151, 1, 67, 250, 147, 21, 80, 175, 247, 4, 66, 2, + 169, 168, 28, 4, 80, 69, 78, 83, 4, 226, 237, 18, 80, 255, 210, 9, 78, + 10, 36, 3, 66, 65, 82, 159, 245, 27, 76, 9, 11, 32, 6, 52, 7, 68, 79, 85, + 66, 76, 69, 32, 195, 230, 26, 76, 4, 190, 230, 26, 76, 51, 82, 48, 112, + 5, 76, 73, 78, 69, 32, 220, 1, 7, 83, 84, 82, 85, 67, 75, 32, 133, 227, 8, 7, 69, 78, 68, 69, 68, 32, 77, 12, 48, 8, 83, 76, 65, 78, 84, 69, 68, 32, 75, 69, 8, 70, 69, 56, 7, 71, 82, 69, 65, 84, 69, 82, 1, 4, 76, 69, - 83, 83, 4, 237, 198, 20, 9, 81, 85, 65, 76, 32, 84, 79, 32, 79, 2, 249, - 179, 14, 5, 45, 84, 72, 65, 78, 34, 160, 1, 8, 67, 65, 80, 73, 84, 65, + 83, 83, 4, 161, 186, 20, 9, 81, 85, 65, 76, 32, 84, 79, 32, 79, 2, 245, + 171, 14, 5, 45, 84, 72, 65, 78, 34, 160, 1, 8, 67, 65, 80, 73, 84, 65, 76, 32, 92, 7, 73, 84, 65, 76, 73, 67, 32, 124, 6, 83, 77, 65, 76, 76, - 32, 141, 223, 13, 8, 78, 45, 65, 82, 89, 32, 83, 85, 18, 206, 177, 12, - 71, 190, 218, 14, 80, 198, 140, 2, 67, 2, 72, 2, 78, 2, 81, 2, 82, 3, 90, - 10, 76, 6, 83, 77, 65, 76, 76, 32, 129, 250, 21, 7, 67, 65, 80, 73, 84, - 65, 76, 8, 162, 151, 29, 68, 2, 69, 2, 73, 3, 74, 4, 246, 175, 12, 71, - 171, 211, 16, 80, 6, 166, 175, 10, 70, 26, 77, 235, 209, 17, 83, 2, 215, - 156, 28, 78, 166, 1, 50, 32, 158, 1, 45, 189, 1, 4, 87, 65, 82, 68, 10, - 60, 4, 84, 65, 67, 75, 218, 236, 25, 70, 30, 82, 195, 79, 65, 5, 29, 5, - 32, 87, 73, 84, 72, 2, 11, 32, 2, 11, 67, 2, 197, 136, 21, 4, 73, 82, 67, - 76, 28, 60, 9, 80, 79, 73, 78, 84, 73, 78, 71, 32, 203, 237, 25, 70, 24, - 62, 83, 238, 239, 25, 65, 86, 69, 62, 70, 46, 82, 207, 1, 84, 4, 178, - 195, 17, 84, 161, 175, 8, 6, 77, 65, 76, 76, 32, 82, 128, 1, 56, 8, 32, + 32, 141, 215, 13, 8, 78, 45, 65, 82, 89, 32, 83, 85, 18, 206, 169, 12, + 71, 242, 213, 14, 80, 198, 140, 2, 67, 2, 72, 2, 78, 2, 81, 2, 82, 3, 90, + 10, 76, 6, 83, 77, 65, 76, 76, 32, 181, 237, 21, 7, 67, 65, 80, 73, 84, + 65, 76, 8, 214, 138, 29, 68, 2, 69, 2, 73, 3, 74, 4, 246, 167, 12, 71, + 223, 206, 16, 80, 6, 166, 167, 10, 70, 26, 77, 159, 205, 17, 83, 2, 139, + 144, 28, 78, 166, 1, 50, 32, 158, 1, 45, 189, 1, 4, 87, 65, 82, 68, 10, + 60, 4, 84, 65, 67, 75, 142, 224, 25, 70, 30, 82, 195, 79, 65, 5, 29, 5, + 32, 87, 73, 84, 72, 2, 11, 32, 2, 11, 67, 2, 249, 251, 20, 4, 73, 82, 67, + 76, 28, 60, 9, 80, 79, 73, 78, 84, 73, 78, 71, 32, 255, 224, 25, 70, 24, + 62, 83, 162, 227, 25, 65, 86, 69, 62, 70, 46, 82, 207, 1, 84, 4, 230, + 182, 17, 84, 161, 175, 8, 6, 77, 65, 76, 76, 32, 82, 128, 1, 56, 8, 32, 70, 65, 67, 73, 78, 71, 32, 89, 2, 83, 32, 8, 54, 72, 1, 9, 78, 79, 84, - 67, 72, 69, 68, 32, 72, 4, 237, 235, 27, 3, 79, 79, 75, 120, 178, 1, 65, - 200, 2, 6, 66, 76, 65, 67, 75, 32, 38, 84, 144, 246, 8, 2, 87, 72, 214, - 160, 8, 90, 178, 137, 9, 68, 50, 70, 82, 72, 150, 4, 67, 46, 81, 42, 82, - 22, 83, 247, 7, 80, 34, 40, 4, 82, 82, 79, 87, 175, 155, 26, 78, 33, 11, - 32, 30, 144, 1, 5, 87, 73, 84, 72, 32, 184, 242, 13, 14, 76, 69, 70, 84, - 87, 65, 82, 68, 83, 32, 79, 70, 32, 85, 138, 169, 12, 65, 178, 10, 70, - 179, 5, 84, 22, 192, 190, 5, 6, 67, 79, 82, 78, 69, 82, 170, 223, 20, 68, - 58, 76, 42, 77, 38, 78, 58, 83, 66, 69, 250, 12, 84, 135, 58, 72, 6, 246, - 149, 21, 65, 231, 137, 5, 67, 36, 36, 2, 82, 73, 161, 2, 2, 87, 79, 32, - 44, 5, 65, 78, 71, 76, 69, 139, 174, 26, 80, 30, 56, 8, 45, 72, 69, 65, - 68, 69, 68, 32, 199, 179, 26, 32, 28, 68, 5, 65, 82, 82, 79, 87, 138, - 149, 17, 90, 254, 150, 9, 68, 39, 80, 23, 11, 32, 20, 180, 167, 26, 15, + 67, 72, 69, 68, 32, 72, 4, 161, 223, 27, 3, 79, 79, 75, 120, 178, 1, 65, + 200, 2, 6, 66, 76, 65, 67, 75, 32, 38, 84, 144, 238, 8, 2, 87, 72, 138, + 156, 8, 90, 178, 137, 9, 68, 50, 70, 82, 72, 150, 4, 67, 46, 81, 42, 82, + 22, 83, 247, 7, 80, 34, 40, 4, 82, 82, 79, 87, 227, 142, 26, 78, 33, 11, + 32, 30, 144, 1, 5, 87, 73, 84, 72, 32, 184, 234, 13, 14, 76, 69, 70, 84, + 87, 65, 82, 68, 83, 32, 79, 70, 32, 85, 190, 164, 12, 65, 178, 10, 70, + 179, 5, 84, 22, 140, 186, 5, 6, 67, 79, 82, 78, 69, 82, 146, 215, 20, 68, + 58, 76, 42, 77, 38, 78, 58, 83, 66, 69, 250, 12, 84, 135, 58, 72, 6, 170, + 137, 21, 65, 231, 137, 5, 67, 36, 36, 2, 82, 73, 161, 2, 2, 87, 79, 32, + 44, 5, 65, 78, 71, 76, 69, 191, 161, 26, 80, 30, 56, 8, 45, 72, 69, 65, + 68, 69, 68, 32, 251, 166, 26, 32, 28, 68, 5, 65, 82, 82, 79, 87, 190, + 136, 17, 90, 254, 150, 9, 68, 39, 80, 23, 11, 32, 20, 232, 154, 26, 15, 76, 69, 70, 84, 87, 65, 82, 68, 83, 32, 79, 70, 32, 85, 80, 98, 84, 23, - 87, 4, 130, 173, 26, 32, 105, 15, 45, 72, 69, 65, 68, 69, 68, 32, 65, 82, + 87, 4, 182, 160, 26, 32, 105, 15, 45, 72, 69, 65, 68, 69, 68, 32, 65, 82, 82, 79, 87, 32, 87, 22, 138, 1, 65, 106, 79, 152, 1, 12, 85, 77, 32, 87, - 73, 84, 72, 32, 68, 82, 85, 77, 196, 129, 17, 6, 73, 86, 69, 32, 83, 76, - 139, 237, 10, 69, 8, 174, 209, 2, 67, 128, 150, 6, 10, 70, 84, 73, 78, - 71, 32, 80, 79, 73, 78, 181, 250, 15, 3, 71, 79, 78, 8, 56, 6, 77, 69, - 68, 65, 82, 89, 34, 80, 215, 208, 27, 79, 2, 157, 254, 20, 3, 32, 67, 65, - 4, 240, 196, 18, 6, 32, 79, 70, 32, 66, 76, 211, 141, 10, 76, 2, 213, - 231, 12, 3, 83, 84, 73, 162, 2, 76, 7, 80, 76, 79, 89, 65, 78, 32, 188, - 152, 20, 2, 77, 80, 219, 234, 8, 67, 158, 2, 212, 2, 6, 65, 70, 70, 73, - 88, 32, 160, 7, 7, 76, 69, 84, 84, 69, 82, 32, 232, 194, 1, 16, 84, 72, + 73, 84, 72, 32, 68, 82, 85, 77, 248, 244, 16, 6, 73, 86, 69, 32, 83, 76, + 139, 237, 10, 69, 8, 250, 204, 2, 67, 180, 146, 6, 10, 70, 84, 73, 78, + 71, 32, 80, 79, 73, 78, 233, 245, 15, 3, 71, 79, 78, 8, 56, 6, 77, 69, + 68, 65, 82, 89, 34, 80, 139, 196, 27, 79, 2, 209, 241, 20, 3, 32, 67, 65, + 4, 164, 184, 18, 6, 32, 79, 70, 32, 66, 76, 211, 141, 10, 76, 2, 213, + 223, 12, 3, 83, 84, 73, 162, 2, 76, 7, 80, 76, 79, 89, 65, 78, 32, 240, + 139, 20, 2, 77, 80, 219, 234, 8, 67, 158, 2, 212, 2, 6, 65, 70, 70, 73, + 88, 32, 160, 7, 7, 76, 69, 84, 84, 69, 82, 32, 180, 190, 1, 16, 84, 72, 73, 67, 75, 32, 76, 69, 84, 84, 69, 82, 32, 83, 69, 76, 232, 180, 3, 4, - 68, 79, 85, 66, 144, 243, 16, 19, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, + 68, 79, 85, 66, 248, 234, 16, 19, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 67, 72, 73, 78, 79, 79, 75, 145, 206, 5, 11, 83, 73, 71, 78, 32, 79, 32, 87, 73, 84, 72, 64, 140, 1, 9, 65, 84, 84, 65, 67, 72, 69, 68, 32, 184, 1, 5, 72, 73, 71, 72, 32, 106, 76, 40, 4, 82, 73, 71, 72, 173, 2, 4, 77, 73, 68, 32, 14, 112, 2, 84, 65, 232, 4, 13, 76, 69, 70, 84, 45, - 84, 79, 45, 82, 73, 71, 72, 84, 26, 83, 234, 130, 21, 69, 3, 73, 6, 44, - 5, 78, 71, 69, 78, 84, 207, 245, 27, 73, 5, 195, 135, 21, 32, 20, 174, 2, - 76, 50, 84, 38, 86, 250, 182, 8, 71, 186, 2, 65, 186, 214, 18, 87, 134, + 84, 79, 45, 82, 73, 71, 72, 84, 26, 83, 158, 246, 20, 69, 3, 73, 6, 44, + 5, 78, 71, 69, 78, 84, 131, 233, 27, 73, 5, 247, 250, 20, 32, 20, 174, 2, + 76, 50, 84, 38, 86, 250, 174, 8, 71, 186, 2, 65, 238, 209, 18, 87, 134, 26, 67, 227, 131, 1, 68, 24, 36, 2, 69, 70, 29, 3, 79, 87, 32, 2, 213, 2, - 3, 84, 32, 72, 22, 94, 65, 38, 76, 50, 84, 38, 86, 250, 182, 8, 71, 242, - 216, 18, 87, 134, 26, 67, 227, 131, 1, 68, 4, 134, 249, 21, 67, 195, 233, - 5, 82, 4, 216, 136, 8, 3, 79, 78, 71, 207, 218, 19, 73, 2, 185, 174, 8, + 3, 84, 32, 72, 22, 94, 65, 38, 76, 50, 84, 38, 86, 250, 174, 8, 71, 166, + 212, 18, 87, 134, 26, 67, 227, 131, 1, 68, 4, 186, 236, 21, 67, 195, 233, + 5, 82, 4, 216, 128, 8, 3, 79, 78, 71, 131, 214, 19, 73, 2, 185, 166, 8, 4, 73, 71, 72, 84, 4, 37, 7, 69, 82, 84, 73, 67, 65, 76, 5, 131, 1, 32, 4, 42, 72, 41, 6, 86, 69, 82, 84, 73, 67, 2, 37, 7, 79, 82, 73, 90, 79, - 78, 84, 2, 17, 2, 65, 76, 2, 11, 32, 2, 11, 83, 2, 209, 240, 27, 2, 69, + 78, 84, 2, 17, 2, 65, 76, 2, 11, 32, 2, 11, 83, 2, 133, 228, 27, 2, 69, 67, 214, 1, 222, 1, 65, 22, 68, 34, 69, 30, 70, 22, 71, 22, 74, 170, 1, 75, 66, 76, 50, 77, 62, 78, 134, 1, 79, 50, 80, 86, 82, 74, 83, 210, 2, - 84, 66, 85, 42, 86, 38, 87, 70, 88, 230, 243, 27, 72, 142, 60, 73, 206, - 41, 89, 215, 22, 66, 5, 227, 213, 28, 79, 7, 218, 188, 28, 32, 223, 61, - 72, 7, 150, 250, 28, 69, 3, 85, 5, 155, 170, 28, 32, 5, 247, 255, 24, 32, + 84, 66, 85, 42, 86, 38, 87, 70, 88, 154, 231, 27, 72, 142, 60, 73, 206, + 41, 89, 215, 22, 66, 5, 151, 201, 28, 79, 7, 142, 176, 28, 32, 223, 61, + 72, 7, 202, 237, 28, 69, 3, 85, 5, 207, 157, 28, 32, 5, 171, 243, 24, 32, 19, 11, 32, 16, 76, 8, 87, 73, 84, 72, 32, 68, 79, 84, 238, 5, 77, 2, 78, - 243, 204, 27, 83, 5, 53, 11, 83, 32, 73, 78, 83, 73, 68, 69, 32, 65, 78, - 2, 187, 251, 27, 68, 9, 26, 32, 147, 248, 28, 75, 4, 170, 254, 24, 82, - 231, 249, 3, 77, 9, 224, 223, 22, 3, 79, 78, 71, 139, 152, 6, 72, 11, 11, - 32, 8, 162, 4, 78, 138, 205, 27, 87, 135, 166, 1, 83, 19, 38, 32, 49, 5, - 65, 83, 65, 76, 32, 8, 202, 3, 77, 138, 205, 27, 87, 135, 166, 1, 83, 8, - 166, 246, 28, 65, 2, 73, 2, 79, 3, 85, 11, 234, 244, 28, 79, 146, 1, 65, - 2, 85, 3, 87, 9, 52, 7, 69, 82, 78, 73, 78, 32, 65, 183, 165, 28, 32, 4, - 146, 245, 28, 77, 3, 78, 11, 224, 220, 22, 6, 79, 77, 65, 78, 73, 65, + 167, 192, 27, 83, 5, 53, 11, 83, 32, 73, 78, 83, 73, 68, 69, 32, 65, 78, + 2, 239, 238, 27, 68, 9, 26, 32, 199, 235, 28, 75, 4, 222, 241, 24, 82, + 231, 249, 3, 77, 9, 148, 211, 22, 3, 79, 78, 71, 139, 152, 6, 72, 11, 11, + 32, 8, 162, 4, 78, 190, 192, 27, 87, 135, 166, 1, 83, 19, 38, 32, 49, 5, + 65, 83, 65, 76, 32, 8, 202, 3, 77, 190, 192, 27, 87, 135, 166, 1, 83, 8, + 218, 233, 28, 65, 2, 73, 2, 79, 3, 85, 11, 158, 232, 28, 79, 146, 1, 65, + 2, 85, 3, 87, 9, 52, 7, 69, 82, 78, 73, 78, 32, 65, 235, 152, 28, 32, 4, + 198, 232, 28, 77, 3, 78, 11, 148, 208, 22, 6, 79, 77, 65, 78, 73, 65, 186, 218, 5, 32, 223, 61, 72, 49, 58, 32, 164, 1, 5, 76, 79, 65, 78, 32, - 239, 185, 6, 72, 26, 102, 74, 22, 75, 2, 80, 2, 84, 20, 7, 87, 73, 84, - 72, 32, 68, 79, 230, 242, 28, 77, 2, 78, 3, 83, 5, 175, 181, 28, 32, 5, - 155, 186, 28, 32, 4, 167, 231, 12, 84, 18, 74, 69, 138, 203, 5, 79, 158, - 215, 22, 65, 210, 78, 68, 146, 1, 74, 3, 85, 6, 130, 242, 28, 69, 2, 72, - 3, 78, 9, 26, 32, 199, 241, 28, 72, 4, 222, 247, 24, 82, 231, 249, 3, 83, - 9, 190, 161, 28, 32, 226, 79, 72, 3, 73, 5, 137, 157, 7, 4, 79, 67, 65, - 76, 17, 66, 79, 182, 183, 28, 32, 134, 37, 69, 218, 19, 65, 2, 72, 3, 73, - 5, 143, 240, 28, 87, 194, 91, 234, 2, 65, 188, 3, 10, 68, 73, 84, 79, 82, - 73, 65, 76, 32, 67, 22, 71, 240, 79, 4, 73, 71, 72, 84, 146, 2, 76, 194, + 239, 177, 6, 72, 26, 102, 74, 22, 75, 2, 80, 2, 84, 20, 7, 87, 73, 84, + 72, 32, 68, 79, 154, 230, 28, 77, 2, 78, 3, 83, 5, 227, 168, 28, 32, 5, + 207, 173, 28, 32, 4, 167, 223, 12, 84, 18, 74, 69, 214, 198, 5, 79, 134, + 207, 22, 65, 210, 78, 68, 146, 1, 74, 3, 85, 6, 182, 229, 28, 69, 2, 72, + 3, 78, 9, 26, 32, 251, 228, 28, 72, 4, 146, 235, 24, 82, 231, 249, 3, 83, + 9, 242, 148, 28, 32, 226, 79, 72, 3, 73, 5, 137, 149, 7, 4, 79, 67, 65, + 76, 17, 66, 79, 234, 170, 28, 32, 134, 37, 69, 218, 19, 65, 2, 72, 3, 73, + 5, 195, 227, 28, 87, 140, 29, 234, 2, 65, 188, 3, 10, 68, 73, 84, 79, 82, + 73, 65, 76, 32, 67, 22, 71, 188, 75, 4, 73, 71, 72, 84, 146, 2, 76, 194, 9, 77, 214, 5, 78, 246, 3, 79, 36, 2, 81, 85, 182, 8, 82, 222, 1, 83, 118, 84, 242, 31, 85, 226, 1, 88, 128, 5, 2, 89, 69, 208, 86, 4, 45, 77, - 65, 73, 156, 153, 19, 3, 74, 69, 67, 244, 152, 2, 8, 86, 69, 82, 71, 82, - 69, 69, 78, 167, 199, 5, 80, 22, 38, 82, 166, 133, 27, 83, 135, 65, 71, - 19, 30, 32, 137, 1, 2, 84, 72, 6, 88, 3, 79, 70, 32, 233, 236, 4, 13, 87, - 73, 84, 72, 32, 72, 69, 65, 82, 73, 78, 71, 32, 4, 132, 204, 11, 2, 77, - 65, 143, 232, 6, 82, 11, 17, 2, 32, 71, 8, 44, 5, 76, 79, 66, 69, 32, - 187, 178, 25, 82, 6, 70, 65, 249, 254, 21, 11, 69, 85, 82, 79, 80, 69, - 45, 65, 70, 82, 73, 4, 244, 150, 10, 4, 77, 69, 82, 73, 193, 154, 2, 11, - 83, 73, 65, 45, 65, 85, 83, 84, 82, 65, 76, 2, 239, 182, 2, 79, 230, 79, - 108, 17, 89, 80, 84, 73, 65, 78, 32, 72, 73, 69, 82, 79, 71, 76, 89, 80, - 72, 130, 217, 2, 69, 203, 143, 26, 71, 226, 79, 30, 32, 197, 74, 2, 45, - 49, 172, 17, 146, 3, 65, 178, 4, 66, 52, 2, 67, 48, 224, 1, 2, 68, 48, - 170, 4, 69, 178, 3, 70, 164, 4, 2, 71, 48, 210, 3, 72, 214, 1, 73, 238, - 2, 76, 122, 77, 222, 8, 78, 210, 5, 79, 140, 5, 2, 80, 48, 120, 2, 82, - 48, 232, 1, 2, 83, 48, 190, 3, 84, 220, 2, 2, 85, 48, 250, 2, 86, 134, 5, - 87, 236, 2, 3, 88, 48, 48, 88, 3, 89, 48, 48, 84, 2, 90, 48, 208, 221, 3, - 3, 75, 48, 48, 153, 159, 15, 3, 81, 48, 48, 228, 1, 30, 48, 133, 3, 2, - 65, 48, 160, 1, 86, 48, 98, 49, 102, 52, 166, 55, 51, 194, 132, 21, 55, - 198, 232, 1, 50, 2, 53, 3, 54, 24, 170, 68, 54, 242, 141, 24, 53, 242, - 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, 24, 186, 209, 24, - 52, 2, 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 53, 2, 54, 2, 56, 3, - 57, 28, 214, 208, 24, 48, 2, 50, 2, 51, 2, 53, 242, 145, 4, 49, 2, 52, 2, - 54, 2, 55, 2, 56, 3, 57, 68, 46, 48, 246, 54, 51, 162, 236, 22, 49, 3, - 50, 22, 210, 65, 55, 226, 159, 28, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, - 2, 56, 3, 57, 26, 148, 9, 4, 69, 71, 73, 78, 185, 25, 2, 48, 48, 56, 34, - 48, 90, 49, 251, 252, 8, 50, 24, 230, 39, 50, 158, 184, 28, 49, 2, 51, 2, - 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 22, 186, 205, 24, 48, 242, 145, 4, - 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 184, 1, 70, - 48, 94, 51, 102, 52, 102, 53, 106, 54, 194, 29, 50, 147, 255, 22, 49, 20, - 138, 204, 24, 56, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, - 55, 3, 57, 24, 174, 203, 24, 49, 2, 52, 242, 145, 4, 48, 2, 50, 2, 51, 2, - 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, 202, 202, 24, 54, 2, 56, 242, 145, 4, - 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 3, 57, 42, 214, 60, 48, - 146, 141, 24, 50, 2, 52, 242, 145, 4, 49, 2, 51, 2, 53, 2, 54, 2, 55, 2, - 56, 3, 57, 32, 194, 60, 55, 174, 158, 28, 48, 2, 49, 2, 50, 2, 51, 2, 52, - 2, 53, 3, 54, 94, 30, 48, 189, 2, 2, 78, 68, 88, 38, 48, 94, 50, 102, 51, - 215, 7, 49, 22, 230, 199, 24, 56, 2, 57, 242, 145, 4, 49, 2, 50, 2, 51, - 2, 52, 2, 53, 2, 54, 3, 55, 24, 138, 199, 24, 48, 2, 56, 242, 145, 4, 49, - 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 18, 166, 198, 24, 52, - 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 54, 2, 55, 3, 56, 6, 11, 32, 6, - 156, 187, 5, 6, 87, 65, 76, 76, 69, 68, 210, 19, 69, 143, 234, 20, 83, - 132, 1, 42, 48, 133, 9, 5, 85, 76, 76, 32, 66, 130, 1, 54, 48, 94, 49, - 102, 51, 102, 52, 102, 53, 215, 1, 50, 20, 146, 196, 24, 49, 242, 145, 4, - 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 22, 182, 195, 24, - 51, 242, 145, 4, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, - 57, 26, 210, 194, 24, 49, 2, 55, 2, 56, 242, 145, 4, 48, 2, 50, 2, 51, 2, - 52, 2, 53, 2, 54, 3, 57, 26, 238, 193, 24, 53, 2, 54, 2, 55, 242, 145, 4, - 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 56, 3, 57, 14, 222, 26, 49, 158, 184, - 28, 48, 2, 50, 3, 51, 128, 1, 62, 48, 98, 49, 102, 51, 102, 52, 210, 27, - 50, 223, 209, 8, 53, 24, 166, 50, 55, 242, 141, 24, 54, 242, 145, 4, 49, - 2, 50, 2, 51, 2, 52, 2, 53, 2, 56, 3, 57, 22, 182, 191, 24, 49, 242, 145, - 4, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, 210, - 190, 24, 54, 2, 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, - 2, 56, 3, 57, 24, 238, 189, 24, 51, 2, 53, 242, 145, 4, 48, 2, 49, 2, 50, - 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 24, 80, 2, 48, 48, 84, 4, 65, 76, 70, - 32, 161, 40, 7, 79, 82, 73, 90, 79, 78, 84, 18, 182, 188, 24, 54, 242, - 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 3, 56, 4, 22, 66, 255, 42, - 76, 2, 235, 253, 16, 76, 52, 58, 48, 181, 1, 9, 78, 83, 69, 82, 84, 32, - 65, 84, 32, 38, 18, 48, 95, 49, 22, 230, 186, 24, 53, 2, 57, 242, 145, 4, - 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 3, 56, 16, 138, 186, 24, 48, 2, - 49, 242, 145, 4, 50, 2, 51, 2, 52, 3, 53, 14, 68, 6, 66, 79, 84, 84, 79, - 77, 0, 3, 84, 79, 80, 243, 231, 19, 77, 7, 11, 32, 4, 206, 186, 27, 69, - 249, 8, 2, 83, 84, 22, 32, 2, 48, 48, 211, 235, 15, 79, 20, 166, 184, 24, - 50, 2, 54, 242, 145, 4, 49, 2, 51, 2, 52, 2, 53, 2, 55, 3, 56, 164, 1, - 118, 48, 128, 4, 15, 79, 68, 73, 70, 73, 69, 82, 32, 68, 65, 77, 65, 71, - 69, 68, 173, 130, 25, 5, 73, 82, 82, 79, 82, 132, 1, 42, 48, 98, 49, 106, - 50, 102, 51, 107, 52, 24, 182, 40, 49, 242, 141, 24, 51, 242, 145, 4, 50, - 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 44, 138, 41, 50, 190, 140, 24, - 48, 2, 53, 2, 54, 2, 55, 242, 145, 4, 49, 2, 51, 2, 52, 2, 56, 3, 57, 26, - 222, 180, 24, 50, 2, 52, 2, 56, 242, 145, 4, 48, 2, 49, 2, 51, 2, 53, 2, - 54, 2, 55, 3, 57, 26, 138, 38, 51, 242, 141, 24, 49, 242, 145, 4, 48, 2, - 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 12, 146, 179, 24, 48, 242, - 145, 4, 49, 2, 50, 2, 51, 3, 52, 31, 25, 4, 32, 65, 84, 32, 28, 96, 6, - 66, 79, 84, 84, 79, 77, 120, 5, 83, 84, 65, 82, 84, 68, 3, 84, 79, 80, - 251, 177, 27, 69, 11, 11, 32, 8, 56, 5, 83, 84, 65, 82, 84, 186, 1, 65, - 183, 177, 27, 69, 5, 129, 2, 8, 32, 65, 78, 68, 32, 84, 79, 80, 7, 29, 5, - 32, 65, 78, 68, 32, 4, 138, 211, 24, 66, 147, 246, 2, 84, 11, 11, 32, 8, - 54, 65, 20, 5, 83, 84, 65, 82, 84, 163, 177, 27, 69, 2, 73, 2, 78, 68, 5, - 53, 11, 32, 65, 78, 68, 32, 66, 79, 84, 84, 79, 77, 2, 151, 229, 19, 32, - 194, 1, 50, 48, 128, 2, 2, 76, 48, 229, 1, 2, 85, 48, 98, 58, 49, 98, 51, - 194, 14, 50, 150, 6, 52, 163, 234, 22, 48, 24, 146, 32, 56, 226, 159, 28, - 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 28, 162, 173, - 24, 51, 2, 52, 2, 53, 2, 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 54, 2, 56, - 3, 57, 44, 34, 48, 94, 49, 207, 150, 21, 50, 20, 154, 172, 24, 53, 242, - 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 22, 190, - 171, 24, 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, - 2, 56, 3, 57, 52, 34, 49, 102, 50, 167, 251, 22, 48, 26, 182, 170, 24, - 48, 2, 49, 2, 56, 242, 145, 4, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, - 57, 8, 210, 169, 24, 50, 242, 145, 4, 48, 3, 49, 152, 1, 50, 48, 193, - 138, 19, 6, 86, 69, 82, 76, 65, 89, 150, 1, 66, 48, 154, 1, 49, 138, 1, - 50, 102, 51, 106, 53, 143, 248, 22, 52, 34, 90, 54, 206, 167, 24, 49, 2, - 53, 242, 145, 4, 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, 15, 186, 185, 28, - 65, 2, 66, 2, 67, 2, 68, 2, 69, 3, 70, 28, 98, 48, 174, 166, 24, 57, 242, - 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 9, 154, 184, - 28, 65, 2, 66, 3, 67, 28, 134, 166, 24, 48, 2, 52, 2, 53, 2, 57, 242, - 145, 4, 49, 2, 50, 2, 51, 2, 54, 2, 55, 3, 56, 32, 134, 23, 54, 158, 142, - 24, 48, 2, 51, 242, 145, 4, 49, 2, 50, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, - 8, 202, 22, 48, 227, 159, 28, 49, 26, 26, 48, 219, 202, 8, 49, 22, 254, - 163, 24, 49, 2, 51, 242, 145, 4, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, - 3, 57, 68, 34, 48, 98, 49, 243, 245, 22, 50, 24, 142, 21, 51, 242, 141, - 24, 50, 242, 145, 4, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, - 158, 162, 24, 48, 2, 54, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, - 55, 2, 56, 3, 57, 108, 50, 48, 94, 49, 106, 50, 98, 51, 219, 191, 19, 52, - 22, 134, 161, 24, 50, 2, 54, 242, 145, 4, 49, 2, 51, 2, 52, 2, 53, 2, 55, - 2, 56, 3, 57, 26, 186, 18, 52, 242, 141, 24, 55, 242, 145, 4, 48, 2, 49, - 2, 50, 2, 51, 2, 53, 2, 54, 2, 56, 3, 57, 24, 210, 17, 54, 226, 159, 28, - 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 22, 226, 158, - 24, 53, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, - 3, 57, 90, 34, 48, 249, 12, 3, 65, 76, 76, 88, 42, 48, 94, 49, 102, 51, - 195, 239, 22, 50, 26, 174, 157, 24, 51, 2, 55, 2, 56, 2, 57, 242, 145, 4, - 49, 2, 50, 2, 52, 2, 53, 3, 54, 24, 210, 156, 24, 49, 2, 54, 242, 145, 4, - 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 18, 238, 155, 24, - 50, 2, 51, 242, 145, 4, 48, 2, 49, 2, 52, 2, 53, 3, 54, 94, 50, 48, 90, - 50, 102, 51, 102, 52, 163, 236, 22, 49, 22, 254, 12, 54, 226, 159, 28, - 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 24, 150, 154, 24, - 51, 2, 57, 242, 145, 4, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 3, - 56, 22, 178, 153, 24, 50, 242, 145, 4, 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, - 54, 2, 55, 2, 56, 3, 57, 6, 190, 170, 28, 48, 2, 49, 3, 50, 158, 1, 42, - 48, 185, 4, 5, 69, 82, 84, 73, 67, 156, 1, 62, 48, 98, 49, 98, 50, 210, - 1, 51, 169, 148, 24, 2, 52, 48, 42, 198, 9, 55, 98, 49, 146, 141, 24, 50, - 242, 145, 4, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 32, 186, 8, 49, 46, - 50, 226, 159, 28, 48, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, - 50, 98, 48, 150, 149, 24, 51, 2, 56, 2, 57, 242, 145, 4, 49, 2, 50, 2, - 52, 2, 53, 2, 54, 3, 55, 27, 130, 167, 28, 65, 2, 66, 2, 67, 2, 68, 2, - 69, 2, 70, 2, 71, 2, 72, 2, 73, 2, 74, 2, 75, 3, 76, 28, 166, 148, 24, - 48, 2, 49, 2, 51, 2, 55, 242, 145, 4, 50, 2, 52, 2, 53, 2, 54, 2, 56, 3, - 57, 2, 181, 246, 23, 2, 65, 76, 66, 34, 48, 161, 2, 3, 73, 68, 69, 64, - 26, 48, 94, 49, 103, 50, 22, 230, 146, 24, 51, 2, 57, 242, 145, 4, 49, 2, - 50, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 28, 138, 146, 24, 48, 2, 52, 2, - 55, 2, 56, 242, 145, 4, 49, 2, 50, 2, 51, 2, 53, 2, 54, 3, 57, 14, 166, - 145, 24, 52, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 3, 53, 2, 17, 2, 32, - 76, 2, 247, 195, 15, 79, 24, 202, 2, 52, 242, 141, 24, 54, 2, 56, 242, - 145, 4, 49, 2, 50, 2, 51, 2, 53, 3, 55, 18, 226, 143, 24, 49, 242, 145, - 4, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 82, 22, 48, 167, 1, 49, - 34, 90, 50, 46, 51, 242, 141, 24, 52, 2, 53, 242, 145, 4, 49, 2, 54, 2, - 55, 2, 56, 3, 57, 11, 138, 160, 28, 65, 2, 66, 2, 67, 3, 68, 7, 222, 159, - 28, 65, 3, 66, 48, 66, 53, 86, 54, 174, 158, 28, 48, 2, 49, 2, 50, 2, 51, - 3, 52, 21, 254, 158, 28, 65, 2, 66, 2, 67, 2, 68, 2, 69, 2, 70, 2, 71, 2, - 72, 3, 73, 19, 170, 158, 28, 65, 2, 66, 2, 67, 2, 68, 2, 69, 2, 70, 2, - 71, 3, 72, 182, 62, 22, 51, 211, 1, 52, 192, 46, 106, 52, 206, 195, 5, - 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, 68, 2, 69, 3, 70, - 192, 2, 218, 193, 13, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, - 68, 2, 69, 3, 70, 246, 15, 42, 51, 190, 194, 5, 48, 2, 49, 3, 50, 246, 3, - 142, 1, 70, 190, 191, 13, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, - 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, 68, 3, 69, 22, 174, 154, 28, - 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 3, 65, - 18, 26, 32, 235, 241, 15, 72, 16, 70, 80, 124, 5, 82, 65, 89, 83, 32, - 226, 152, 3, 84, 155, 231, 22, 83, 8, 222, 152, 3, 79, 233, 198, 16, 22, - 69, 84, 65, 76, 76, 69, 68, 32, 79, 85, 84, 76, 73, 78, 69, 68, 32, 66, - 76, 65, 67, 75, 4, 148, 254, 18, 2, 73, 78, 1, 3, 79, 85, 84, 160, 1, - 132, 1, 13, 66, 65, 83, 65, 78, 32, 76, 69, 84, 84, 69, 82, 32, 166, 3, - 69, 176, 4, 7, 89, 77, 65, 73, 67, 32, 76, 223, 142, 28, 70, 80, 230, 1, - 71, 78, 76, 34, 78, 50, 82, 234, 134, 26, 69, 166, 140, 1, 67, 2, 68, 2, - 75, 2, 83, 2, 84, 2, 90, 206, 105, 66, 2, 70, 2, 72, 2, 74, 2, 77, 2, 80, - 2, 81, 2, 86, 2, 88, 214, 22, 65, 2, 73, 2, 79, 2, 85, 3, 89, 8, 38, 72, - 206, 253, 27, 74, 215, 22, 69, 4, 214, 190, 25, 65, 203, 213, 2, 69, 4, - 166, 253, 27, 76, 215, 22, 69, 8, 134, 253, 27, 68, 2, 74, 214, 22, 65, - 3, 69, 4, 214, 252, 27, 82, 215, 22, 69, 32, 96, 5, 67, 84, 82, 73, 67, - 160, 1, 7, 77, 69, 78, 84, 32, 79, 70, 134, 133, 27, 80, 135, 83, 86, 10, - 26, 32, 155, 159, 24, 65, 8, 98, 80, 128, 221, 17, 2, 84, 79, 176, 246, - 8, 9, 76, 73, 71, 72, 84, 32, 66, 85, 76, 187, 33, 65, 2, 11, 76, 2, 199, - 144, 28, 85, 19, 11, 32, 16, 72, 5, 87, 73, 84, 72, 32, 177, 222, 16, 7, - 79, 80, 69, 78, 73, 78, 71, 12, 130, 1, 76, 32, 12, 84, 87, 79, 32, 72, - 79, 82, 73, 90, 79, 78, 84, 170, 233, 19, 86, 226, 182, 4, 85, 142, 61, - 79, 175, 177, 2, 68, 2, 141, 231, 25, 3, 79, 78, 71, 2, 197, 227, 14, 7, - 65, 76, 32, 83, 84, 82, 79, 46, 238, 175, 4, 69, 189, 214, 15, 15, 73, - 71, 65, 84, 85, 82, 69, 32, 90, 65, 89, 73, 78, 45, 89, 53, 48, 4, 79, - 74, 73, 32, 218, 2, 80, 163, 3, 32, 18, 164, 1, 10, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 32, 109, 26, 77, 79, 68, 73, 70, 73, 69, 82, 32, 70, 73, - 84, 90, 80, 65, 84, 82, 73, 67, 75, 32, 84, 89, 80, 69, 45, 8, 140, 141, - 15, 2, 82, 69, 12, 5, 67, 85, 82, 76, 89, 0, 5, 87, 72, 73, 84, 69, 185, - 207, 2, 2, 66, 65, 10, 240, 227, 20, 2, 49, 45, 194, 167, 7, 51, 2, 52, - 2, 53, 3, 54, 26, 44, 3, 84, 89, 32, 149, 251, 3, 2, 72, 65, 24, 82, 78, - 60, 3, 80, 65, 71, 20, 3, 83, 69, 84, 233, 197, 27, 4, 68, 79, 67, 85, 8, - 36, 3, 79, 84, 69, 211, 155, 24, 69, 7, 203, 166, 13, 32, 4, 215, 255, - 25, 69, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 138, 144, 14, 82, 24, 3, - 76, 69, 70, 224, 166, 1, 2, 83, 77, 255, 159, 9, 79, 38, 86, 32, 64, 2, - 68, 32, 214, 1, 81, 20, 6, 86, 69, 76, 79, 80, 69, 223, 235, 15, 84, 6, - 42, 81, 146, 156, 26, 68, 235, 172, 1, 83, 2, 247, 192, 27, 85, 20, 32, - 3, 79, 70, 32, 131, 1, 87, 18, 88, 3, 80, 82, 79, 150, 241, 20, 71, 56, - 2, 83, 69, 166, 71, 77, 30, 84, 203, 177, 5, 76, 4, 214, 241, 20, 84, - 151, 147, 6, 79, 2, 217, 130, 20, 7, 73, 84, 72, 32, 76, 69, 70, 5, 143, - 185, 21, 85, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 42, 76, 177, 134, 24, - 4, 68, 79, 87, 78, 2, 185, 228, 22, 4, 73, 71, 72, 84, 6, 178, 132, 28, - 76, 2, 77, 3, 84, 46, 28, 2, 65, 76, 231, 6, 73, 40, 30, 32, 133, 2, 2, - 83, 32, 12, 56, 3, 84, 79, 32, 181, 155, 13, 5, 65, 78, 68, 32, 80, 10, - 68, 3, 79, 82, 32, 145, 177, 27, 8, 66, 89, 32, 68, 69, 70, 73, 78, 8, - 64, 3, 80, 82, 69, 28, 3, 83, 85, 67, 250, 235, 25, 71, 39, 76, 2, 213, - 170, 15, 2, 67, 69, 2, 181, 159, 26, 3, 67, 69, 69, 28, 72, 4, 83, 73, - 71, 78, 184, 233, 25, 4, 87, 73, 84, 72, 199, 199, 1, 67, 25, 11, 32, 22, - 42, 65, 201, 1, 5, 87, 73, 84, 72, 32, 12, 112, 5, 66, 79, 86, 69, 32, - 65, 19, 78, 68, 32, 83, 76, 65, 78, 84, 69, 68, 32, 80, 65, 82, 65, 76, - 76, 69, 76, 8, 206, 151, 21, 80, 210, 5, 84, 146, 189, 2, 76, 171, 131, - 3, 82, 5, 187, 247, 6, 32, 10, 160, 1, 4, 66, 85, 77, 80, 20, 7, 73, 78, - 70, 73, 78, 73, 84, 20, 18, 84, 87, 79, 32, 68, 79, 84, 83, 32, 65, 66, - 79, 86, 69, 32, 65, 78, 68, 235, 170, 15, 68, 2, 215, 128, 27, 89, 4, - 179, 219, 25, 89, 2, 17, 2, 32, 84, 2, 211, 203, 25, 87, 6, 80, 7, 86, - 65, 76, 69, 78, 84, 32, 161, 155, 21, 7, 65, 78, 71, 85, 76, 65, 82, 4, - 48, 6, 87, 73, 84, 72, 32, 70, 147, 221, 27, 84, 2, 11, 79, 2, 237, 248, - 2, 2, 85, 82, 20, 152, 1, 11, 82, 79, 82, 45, 66, 65, 82, 82, 69, 68, 32, - 184, 170, 5, 7, 73, 83, 32, 70, 79, 82, 77, 161, 202, 7, 9, 65, 83, 69, - 32, 84, 79, 32, 84, 72, 12, 216, 227, 5, 4, 87, 72, 73, 84, 13, 5, 66, - 76, 65, 67, 75, 10, 58, 67, 20, 6, 84, 73, 77, 65, 84, 69, 179, 249, 27, - 65, 5, 235, 175, 26, 65, 4, 234, 227, 26, 68, 199, 149, 1, 83, 154, 8, - 60, 7, 72, 73, 79, 80, 73, 67, 32, 202, 248, 27, 66, 3, 88, 150, 8, 204, - 1, 2, 67, 79, 232, 1, 7, 78, 85, 77, 66, 69, 82, 32, 114, 80, 54, 83, - 156, 24, 11, 84, 79, 78, 65, 76, 32, 77, 65, 82, 75, 32, 254, 143, 19, - 68, 158, 246, 5, 70, 82, 81, 173, 150, 2, 4, 87, 79, 82, 68, 10, 26, 77, - 239, 166, 27, 76, 8, 52, 7, 66, 73, 78, 73, 78, 71, 32, 235, 243, 27, 77, - 6, 60, 11, 71, 69, 77, 73, 78, 65, 84, 73, 79, 78, 32, 51, 86, 4, 44, 5, - 65, 78, 68, 32, 86, 135, 180, 27, 77, 2, 169, 148, 24, 4, 79, 87, 69, 76, - 22, 66, 84, 158, 152, 22, 72, 238, 234, 3, 69, 30, 70, 42, 78, 39, 83, 8, - 154, 214, 16, 69, 158, 174, 9, 72, 27, 87, 4, 202, 119, 65, 169, 172, 26, - 5, 82, 69, 70, 65, 67, 198, 7, 50, 69, 37, 8, 89, 76, 76, 65, 66, 76, 69, - 32, 4, 170, 164, 24, 77, 223, 229, 2, 67, 194, 7, 210, 1, 66, 90, 67, - 246, 1, 68, 186, 1, 70, 90, 71, 214, 2, 72, 162, 1, 75, 102, 77, 90, 78, - 90, 80, 138, 2, 81, 174, 1, 82, 86, 83, 210, 1, 84, 122, 74, 2, 76, 138, - 1, 87, 2, 89, 66, 88, 134, 1, 90, 95, 86, 38, 194, 12, 87, 230, 8, 66, - 158, 202, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, 85, 78, 94, 67, - 254, 15, 72, 146, 206, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, - 2, 73, 3, 85, 42, 70, 72, 198, 221, 23, 65, 210, 209, 3, 69, 162, 64, 73, - 2, 79, 3, 85, 28, 166, 19, 72, 158, 202, 23, 65, 210, 209, 3, 69, 162, - 64, 73, 2, 79, 3, 85, 60, 94, 68, 214, 14, 90, 198, 205, 23, 65, 2, 79, - 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 30, 210, 14, 72, 198, - 205, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 24, - 190, 8, 87, 130, 211, 23, 65, 210, 209, 3, 69, 234, 61, 89, 186, 2, 73, - 2, 79, 3, 85, 118, 142, 1, 85, 226, 7, 71, 232, 3, 7, 76, 79, 84, 84, 65, - 76, 32, 158, 2, 87, 218, 1, 89, 158, 202, 23, 65, 2, 79, 210, 209, 3, 69, - 163, 64, 73, 39, 29, 5, 82, 65, 71, 69, 32, 36, 74, 66, 2, 70, 2, 77, 2, - 80, 46, 71, 2, 75, 2, 81, 195, 144, 12, 72, 4, 11, 87, 4, 250, 211, 27, - 69, 215, 22, 73, 6, 11, 87, 6, 130, 170, 27, 69, 163, 64, 73, 52, 70, 72, - 206, 215, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, 85, 36, 202, 4, - 87, 230, 8, 89, 158, 202, 23, 65, 210, 209, 3, 69, 162, 64, 73, 2, 79, 3, - 85, 64, 250, 4, 88, 134, 6, 87, 218, 1, 89, 158, 202, 23, 65, 2, 79, 210, - 209, 3, 69, 162, 64, 73, 3, 85, 26, 142, 3, 87, 130, 211, 23, 65, 2, 79, - 210, 209, 3, 69, 234, 61, 89, 186, 2, 73, 3, 85, 36, 166, 7, 89, 146, - 206, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 56, - 82, 72, 142, 1, 87, 130, 211, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, - 73, 3, 85, 32, 74, 65, 194, 211, 23, 79, 210, 209, 3, 69, 234, 61, 87, - 186, 2, 73, 3, 85, 19, 160, 9, 8, 82, 89, 78, 71, 69, 65, 76, 32, 143, - 220, 27, 65, 8, 206, 164, 27, 69, 162, 64, 65, 3, 73, 64, 94, 72, 134, 6, - 87, 218, 1, 89, 158, 202, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, - 85, 24, 130, 6, 87, 246, 203, 23, 65, 210, 209, 3, 69, 162, 64, 73, 2, - 79, 3, 85, 20, 170, 209, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 2, - 89, 186, 2, 73, 3, 85, 74, 102, 69, 226, 1, 72, 170, 3, 90, 78, 83, 158, - 202, 23, 65, 2, 79, 186, 143, 4, 87, 186, 2, 73, 3, 85, 13, 56, 8, 66, - 65, 84, 66, 69, 73, 84, 32, 167, 225, 27, 69, 8, 198, 231, 22, 66, 2, 70, - 2, 77, 3, 80, 80, 118, 72, 76, 2, 84, 72, 62, 90, 162, 2, 83, 234, 202, - 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 18, 142, - 206, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 12, - 146, 159, 27, 69, 234, 61, 65, 186, 2, 73, 2, 79, 3, 85, 16, 134, 205, - 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, 85, 40, 82, 87, 218, 1, - 89, 158, 202, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, 85, 10, - 242, 203, 23, 65, 210, 209, 3, 69, 163, 64, 73, 48, 90, 72, 78, 90, 158, - 202, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 16, - 230, 202, 23, 65, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 2, 79, 3, 85, - 14, 154, 202, 23, 65, 210, 209, 3, 69, 162, 64, 73, 2, 79, 3, 85, 20, - 130, 1, 68, 74, 72, 30, 75, 42, 82, 0, 7, 83, 72, 79, 82, 84, 32, 82, - 220, 147, 4, 3, 67, 72, 73, 201, 144, 23, 3, 89, 73, 90, 6, 48, 4, 69, - 82, 69, 84, 229, 208, 26, 2, 73, 70, 5, 17, 2, 45, 72, 2, 229, 164, 27, - 2, 73, 68, 4, 176, 208, 26, 2, 69, 78, 163, 2, 85, 2, 137, 162, 4, 3, 73, - 75, 82, 12, 96, 2, 82, 79, 192, 159, 11, 3, 78, 79, 77, 129, 173, 15, 9, - 76, 69, 82, 32, 67, 79, 78, 83, 84, 8, 92, 5, 80, 69, 65, 78, 32, 144, - 161, 24, 8, 45, 67, 85, 82, 82, 69, 78, 67, 215, 175, 2, 32, 4, 202, 142, - 4, 67, 19, 80, 50, 30, 67, 102, 80, 187, 1, 84, 6, 60, 9, 76, 65, 77, 65, - 84, 73, 79, 78, 32, 139, 190, 26, 69, 4, 246, 129, 25, 81, 187, 147, 2, - 77, 10, 96, 7, 76, 79, 83, 73, 79, 78, 32, 181, 152, 27, 11, 82, 69, 83, - 83, 73, 79, 78, 76, 69, 83, 83, 8, 212, 223, 11, 4, 70, 82, 65, 77, 145, - 166, 15, 8, 65, 84, 32, 72, 79, 82, 73, 90, 34, 98, 82, 233, 197, 21, 18, - 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, - 14, 140, 1, 12, 69, 77, 69, 76, 89, 32, 72, 69, 65, 86, 89, 32, 137, 253, - 25, 16, 65, 84, 69, 82, 82, 69, 83, 84, 82, 73, 65, 76, 32, 65, 76, 73, - 12, 50, 83, 134, 185, 25, 70, 234, 2, 87, 203, 11, 71, 4, 150, 186, 25, - 65, 43, 73, 7, 250, 186, 19, 71, 195, 151, 8, 83, 152, 4, 142, 1, 65, - 130, 19, 69, 190, 1, 73, 134, 8, 76, 138, 6, 79, 142, 7, 82, 130, 5, 85, - 252, 201, 20, 2, 86, 83, 242, 203, 4, 83, 199, 140, 2, 70, 92, 122, 67, - 178, 15, 76, 176, 2, 2, 88, 32, 170, 148, 3, 77, 252, 253, 5, 2, 82, 83, - 140, 251, 1, 2, 84, 72, 151, 235, 9, 73, 70, 72, 2, 69, 32, 180, 187, 16, - 4, 83, 73, 77, 73, 165, 206, 4, 2, 84, 79, 66, 226, 1, 83, 160, 1, 4, 87, - 73, 84, 72, 196, 136, 13, 2, 80, 65, 252, 136, 2, 2, 77, 65, 164, 162, - 11, 13, 84, 72, 82, 79, 87, 73, 78, 71, 32, 65, 32, 75, 73, 201, 1, 14, - 72, 79, 76, 68, 73, 78, 71, 32, 66, 65, 67, 75, 32, 84, 4, 216, 138, 17, - 18, 65, 86, 79, 85, 82, 73, 78, 71, 32, 68, 69, 76, 73, 67, 73, 79, 85, - 83, 141, 138, 5, 13, 67, 82, 69, 65, 77, 73, 78, 71, 32, 73, 78, 32, 70, - 54, 38, 32, 141, 167, 24, 3, 79, 85, 84, 52, 196, 4, 2, 67, 79, 44, 5, - 72, 69, 65, 68, 45, 38, 77, 98, 79, 92, 7, 78, 79, 32, 71, 79, 79, 68, - 238, 1, 80, 164, 1, 16, 83, 84, 85, 67, 75, 45, 79, 85, 84, 32, 84, 79, - 78, 71, 85, 69, 110, 84, 204, 183, 1, 9, 66, 65, 71, 83, 32, 85, 78, 68, - 69, 212, 171, 17, 22, 70, 73, 78, 71, 69, 82, 32, 67, 79, 86, 69, 82, 73, - 78, 71, 32, 67, 76, 79, 83, 69, 68, 244, 67, 3, 82, 79, 76, 180, 231, 1, - 13, 76, 79, 79, 75, 32, 79, 70, 32, 84, 82, 73, 85, 77, 244, 141, 3, 8, - 68, 73, 65, 71, 79, 78, 65, 76, 1, 20, 85, 78, 69, 86, 69, 78, 32, 69, - 89, 69, 83, 32, 65, 78, 68, 32, 87, 65, 86, 89, 4, 252, 4, 3, 87, 66, 79, - 227, 167, 19, 76, 2, 249, 183, 22, 4, 66, 65, 78, 68, 4, 60, 6, 69, 68, - 73, 67, 65, 76, 185, 242, 25, 3, 79, 78, 79, 2, 181, 255, 25, 3, 32, 77, - 65, 12, 90, 75, 36, 4, 80, 69, 78, 32, 213, 180, 20, 10, 78, 69, 32, 69, - 89, 69, 66, 82, 79, 87, 2, 241, 166, 22, 4, 32, 71, 69, 83, 8, 116, 5, - 77, 79, 85, 84, 72, 157, 159, 24, 18, 69, 89, 69, 83, 32, 65, 78, 68, 32, - 72, 65, 78, 68, 32, 79, 86, 69, 82, 7, 11, 32, 4, 184, 137, 10, 3, 86, - 79, 77, 221, 159, 9, 5, 65, 78, 68, 32, 67, 6, 132, 1, 18, 65, 82, 84, - 89, 32, 72, 79, 82, 78, 32, 65, 78, 68, 32, 80, 65, 82, 84, 100, 2, 69, - 69, 197, 167, 19, 4, 76, 69, 65, 68, 2, 229, 208, 22, 2, 89, 32, 7, 29, - 5, 32, 65, 78, 68, 32, 4, 36, 3, 87, 73, 78, 231, 167, 19, 84, 2, 169, - 183, 1, 4, 75, 73, 78, 71, 4, 50, 69, 193, 212, 22, 6, 72, 69, 82, 77, - 79, 77, 2, 181, 175, 27, 8, 65, 82, 83, 32, 79, 70, 32, 74, 10, 34, 76, - 133, 171, 22, 2, 65, 70, 8, 84, 13, 73, 78, 71, 32, 68, 73, 65, 71, 79, - 78, 65, 76, 32, 129, 242, 23, 2, 69, 78, 6, 128, 1, 9, 67, 82, 79, 83, - 83, 73, 78, 71, 32, 201, 186, 19, 16, 73, 78, 32, 87, 72, 73, 84, 69, 32, - 67, 73, 82, 67, 76, 69, 32, 4, 164, 148, 16, 3, 82, 73, 83, 227, 173, 3, - 78, 4, 218, 130, 15, 73, 131, 143, 4, 77, 14, 50, 65, 50, 77, 44, 2, 82, - 82, 147, 236, 18, 78, 4, 232, 174, 8, 3, 82, 70, 85, 147, 237, 9, 84, 4, - 228, 246, 8, 2, 73, 78, 179, 178, 7, 65, 4, 220, 246, 7, 2, 73, 83, 151, - 198, 19, 89, 58, 138, 1, 71, 90, 76, 178, 1, 78, 98, 82, 182, 2, 83, 164, - 14, 4, 86, 69, 32, 68, 217, 255, 4, 10, 69, 76, 68, 32, 72, 79, 67, 75, - 69, 89, 6, 48, 4, 85, 82, 69, 32, 245, 140, 26, 2, 72, 84, 4, 242, 207, - 25, 68, 235, 172, 1, 83, 10, 32, 2, 69, 32, 65, 2, 77, 32, 6, 242, 200, - 13, 70, 140, 155, 2, 3, 67, 65, 66, 147, 165, 8, 83, 4, 52, 4, 80, 82, - 79, 74, 173, 161, 20, 3, 70, 82, 65, 2, 251, 217, 15, 69, 4, 72, 4, 71, - 69, 82, 80, 221, 174, 25, 8, 73, 84, 69, 32, 80, 65, 82, 84, 2, 195, 141, - 16, 82, 22, 34, 69, 189, 1, 3, 83, 84, 32, 13, 56, 2, 32, 69, 68, 4, 87, - 79, 82, 75, 251, 184, 15, 67, 4, 222, 192, 13, 78, 193, 213, 4, 8, 88, - 84, 73, 78, 71, 85, 73, 83, 4, 216, 201, 23, 6, 32, 83, 80, 65, 82, 75, - 215, 237, 3, 83, 10, 186, 177, 5, 81, 172, 184, 10, 8, 83, 84, 82, 79, - 78, 71, 32, 73, 223, 225, 6, 80, 10, 38, 72, 165, 229, 23, 3, 84, 69, 68, - 9, 128, 255, 3, 13, 73, 78, 71, 32, 80, 79, 76, 69, 32, 65, 78, 68, 32, - 174, 209, 5, 69, 213, 222, 16, 19, 32, 67, 65, 75, 69, 32, 87, 73, 84, - 72, 32, 83, 87, 73, 82, 76, 32, 68, 69, 46, 50, 65, 170, 1, 69, 98, 79, - 194, 1, 85, 39, 89, 12, 114, 84, 236, 163, 4, 5, 80, 80, 73, 78, 71, 192, - 159, 3, 6, 71, 32, 73, 78, 32, 72, 161, 224, 17, 3, 77, 73, 78, 6, 190, - 221, 8, 32, 250, 203, 11, 66, 135, 241, 5, 78, 4, 196, 250, 23, 8, 88, - 69, 68, 32, 66, 73, 67, 69, 153, 145, 1, 7, 85, 82, 45, 68, 69, 45, 76, - 12, 52, 2, 82, 65, 20, 3, 87, 69, 82, 139, 234, 25, 80, 5, 147, 170, 26, - 76, 7, 17, 2, 32, 80, 4, 58, 85, 209, 207, 24, 8, 76, 65, 89, 73, 78, 71, - 32, 67, 2, 181, 199, 26, 4, 78, 67, 84, 85, 4, 190, 158, 3, 83, 183, 251, - 23, 84, 15, 25, 4, 73, 78, 71, 32, 12, 64, 6, 83, 65, 85, 67, 69, 82, - 210, 143, 10, 68, 155, 136, 10, 69, 9, 11, 32, 6, 40, 4, 87, 73, 84, 72, - 227, 153, 26, 83, 4, 34, 32, 1, 4, 79, 85, 84, 32, 2, 21, 3, 66, 69, 65, - 2, 243, 240, 26, 77, 56, 102, 71, 20, 2, 76, 68, 68, 2, 79, 84, 22, 82, - 142, 2, 85, 128, 155, 23, 2, 78, 68, 191, 210, 3, 88, 5, 139, 156, 27, - 71, 4, 156, 205, 9, 8, 73, 78, 71, 32, 72, 65, 78, 68, 199, 167, 17, 69, - 5, 195, 161, 14, 80, 18, 78, 75, 132, 1, 3, 84, 85, 78, 134, 224, 20, 77, - 222, 192, 4, 32, 179, 116, 67, 8, 80, 10, 32, 65, 78, 68, 32, 75, 78, 73, - 70, 69, 242, 164, 15, 69, 223, 181, 11, 73, 5, 201, 222, 15, 7, 32, 87, - 73, 84, 72, 32, 80, 4, 224, 143, 27, 6, 69, 32, 67, 79, 79, 75, 179, 27, - 65, 22, 26, 82, 199, 190, 23, 78, 20, 38, 32, 218, 2, 84, 223, 239, 18, - 45, 16, 110, 67, 174, 1, 68, 182, 170, 2, 66, 216, 155, 10, 7, 76, 69, - 65, 70, 32, 67, 76, 186, 111, 84, 235, 215, 11, 80, 4, 148, 183, 13, 3, - 76, 85, 66, 181, 86, 32, 79, 82, 78, 69, 82, 32, 65, 82, 82, 79, 87, 83, - 32, 67, 73, 82, 67, 76, 73, 78, 71, 32, 65, 78, 84, 73, 67, 76, 79, 67, - 75, 87, 4, 21, 3, 79, 84, 32, 4, 246, 225, 23, 80, 195, 132, 3, 77, 2, - 231, 43, 72, 30, 78, 65, 250, 1, 69, 98, 79, 133, 131, 17, 8, 73, 69, 68, - 32, 83, 72, 82, 73, 12, 96, 6, 67, 84, 73, 79, 78, 32, 68, 8, 77, 69, 32, - 87, 73, 84, 72, 32, 193, 242, 10, 2, 71, 73, 4, 166, 129, 20, 83, 177, 6, - 9, 78, 85, 77, 69, 82, 65, 84, 79, 82, 6, 50, 80, 218, 170, 2, 65, 149, - 185, 21, 2, 84, 73, 2, 185, 134, 22, 2, 73, 67, 6, 48, 6, 78, 67, 72, 32, - 70, 82, 139, 142, 19, 69, 4, 174, 142, 26, 73, 133, 15, 3, 65, 78, 67, - 10, 52, 3, 78, 84, 45, 116, 2, 87, 78, 191, 229, 26, 71, 4, 70, 84, 217, - 143, 2, 11, 70, 65, 67, 73, 78, 71, 32, 66, 65, 66, 89, 2, 189, 191, 12, - 6, 73, 76, 84, 69, 68, 32, 5, 185, 147, 8, 6, 73, 78, 71, 32, 70, 65, - 226, 1, 80, 2, 76, 76, 134, 6, 78, 208, 250, 16, 5, 69, 76, 32, 80, 85, - 179, 138, 10, 83, 216, 1, 42, 32, 73, 6, 87, 73, 68, 84, 72, 32, 10, 234, - 140, 12, 77, 136, 171, 3, 2, 79, 85, 170, 247, 8, 66, 151, 29, 83, 206, - 1, 242, 1, 67, 42, 76, 78, 78, 30, 80, 66, 82, 142, 1, 83, 38, 89, 130, - 159, 10, 77, 174, 213, 10, 65, 158, 2, 68, 58, 69, 98, 71, 118, 72, 202, - 4, 81, 198, 153, 2, 87, 182, 29, 84, 162, 146, 1, 70, 224, 177, 1, 6, 66, - 82, 79, 75, 69, 78, 211, 7, 86, 10, 162, 248, 20, 73, 62, 79, 131, 81, - 69, 116, 42, 69, 214, 251, 20, 65, 231, 183, 4, 79, 10, 162, 1, 70, 199, - 253, 20, 83, 4, 166, 210, 21, 79, 35, 85, 6, 42, 79, 198, 254, 20, 69, - 211, 236, 2, 76, 2, 223, 177, 25, 85, 10, 36, 3, 73, 71, 72, 207, 131, - 25, 69, 8, 17, 2, 84, 32, 8, 140, 181, 20, 5, 87, 72, 73, 84, 69, 246, - 220, 2, 67, 210, 3, 80, 239, 7, 83, 4, 250, 204, 23, 69, 139, 184, 1, 79, - 2, 223, 159, 25, 69, 6, 128, 205, 11, 8, 67, 84, 73, 79, 78, 32, 65, 80, - 208, 252, 8, 5, 69, 82, 65, 76, 32, 211, 188, 1, 78, 130, 21, 114, 65, - 250, 6, 69, 222, 22, 73, 162, 1, 76, 134, 15, 79, 198, 6, 82, 178, 92, - 85, 138, 155, 22, 72, 131, 238, 3, 83, 142, 1, 42, 82, 149, 254, 26, 4, - 77, 69, 32, 68, 140, 1, 36, 3, 65, 89, 32, 255, 238, 25, 76, 138, 1, 166, - 1, 67, 210, 1, 83, 192, 2, 6, 86, 79, 87, 69, 76, 32, 172, 178, 8, 6, 82, - 69, 68, 85, 80, 76, 194, 208, 10, 72, 238, 168, 1, 80, 214, 181, 3, 77, - 171, 190, 1, 68, 52, 42, 79, 205, 1, 5, 65, 80, 73, 84, 65, 8, 88, 10, - 77, 66, 73, 78, 73, 78, 71, 32, 68, 79, 37, 8, 78, 83, 79, 78, 65, 78, - 84, 32, 4, 234, 148, 12, 85, 247, 132, 14, 84, 4, 178, 149, 12, 78, 171, - 161, 11, 71, 46, 36, 3, 77, 65, 76, 171, 146, 22, 85, 44, 45, 9, 76, 32, - 76, 69, 84, 84, 69, 82, 32, 44, 200, 1, 4, 79, 76, 68, 32, 214, 155, 20, - 78, 238, 245, 6, 66, 2, 67, 2, 68, 2, 70, 2, 71, 2, 72, 2, 74, 2, 75, 2, - 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, 2, 88, 2, 89, 187, 2, 65, - 4, 190, 145, 27, 75, 3, 78, 12, 44, 5, 83, 73, 71, 78, 32, 179, 209, 26, - 76, 10, 138, 211, 26, 69, 162, 64, 65, 2, 73, 3, 79, 146, 3, 112, 2, 65, - 82, 110, 77, 50, 79, 160, 218, 23, 9, 82, 77, 65, 78, 32, 80, 69, 78, 78, - 174, 177, 2, 84, 239, 105, 78, 7, 29, 5, 32, 87, 73, 84, 72, 4, 224, 160, - 14, 5, 79, 85, 84, 32, 72, 233, 175, 9, 5, 32, 72, 65, 78, 68, 4, 26, 32, - 167, 140, 22, 73, 2, 207, 155, 23, 83, 130, 3, 46, 77, 245, 5, 6, 82, 71, - 73, 65, 78, 32, 38, 92, 13, 65, 78, 84, 73, 67, 32, 70, 73, 71, 85, 82, - 69, 32, 205, 4, 5, 69, 84, 82, 73, 67, 32, 158, 1, 65, 82, 67, 172, 1, 9, - 70, 79, 82, 84, 85, 78, 65, 32, 77, 44, 3, 76, 65, 69, 0, 4, 84, 82, 73, - 83, 34, 80, 80, 3, 82, 85, 66, 167, 210, 10, 86, 6, 216, 1, 6, 67, 81, - 85, 73, 83, 73, 12, 4, 77, 73, 83, 83, 235, 166, 23, 76, 8, 42, 65, 97, - 6, 79, 78, 74, 85, 78, 67, 6, 56, 3, 80, 85, 84, 0, 3, 85, 68, 65, 155, - 188, 18, 82, 2, 165, 90, 5, 32, 68, 82, 65, 67, 2, 11, 84, 2, 215, 237, - 26, 73, 4, 206, 167, 2, 73, 129, 172, 24, 2, 65, 74, 2, 145, 211, 10, 3, - 84, 73, 84, 6, 44, 2, 85, 69, 177, 128, 23, 3, 79, 80, 85, 4, 162, 233, - 26, 76, 155, 34, 82, 2, 183, 130, 25, 69, 6, 252, 135, 20, 4, 65, 76, 76, - 89, 137, 228, 1, 5, 32, 80, 82, 79, 80, 220, 2, 228, 1, 6, 67, 65, 80, - 73, 84, 65, 0, 4, 83, 77, 65, 76, 172, 3, 7, 76, 69, 84, 84, 69, 82, 32, - 180, 2, 24, 77, 84, 65, 86, 82, 85, 76, 73, 32, 67, 65, 80, 73, 84, 65, - 76, 32, 76, 69, 84, 84, 69, 82, 32, 165, 6, 2, 80, 65, 80, 45, 9, 76, 32, - 76, 69, 84, 84, 69, 82, 32, 80, 142, 2, 65, 34, 72, 166, 5, 67, 118, 71, - 130, 1, 74, 34, 75, 82, 80, 34, 83, 94, 90, 252, 181, 5, 2, 84, 65, 162, - 149, 8, 76, 226, 180, 2, 82, 218, 176, 9, 66, 2, 77, 2, 88, 226, 40, 78, - 2, 81, 234, 35, 86, 234, 47, 68, 14, 69, 2, 73, 2, 79, 2, 85, 2, 89, 143, - 57, 87, 4, 178, 182, 26, 69, 227, 79, 78, 10, 46, 65, 242, 238, 26, 73, - 2, 79, 215, 22, 69, 4, 194, 133, 27, 69, 3, 82, 94, 254, 1, 85, 178, 2, - 65, 42, 67, 74, 69, 46, 71, 34, 72, 98, 74, 34, 75, 34, 76, 50, 80, 34, - 83, 34, 84, 62, 90, 254, 255, 15, 82, 218, 176, 9, 66, 2, 77, 2, 88, 226, - 40, 78, 2, 81, 234, 35, 86, 234, 47, 68, 14, 73, 2, 79, 2, 89, 142, 57, - 87, 255, 2, 70, 4, 136, 139, 22, 4, 45, 66, 82, 74, 159, 248, 4, 78, 92, - 250, 1, 65, 42, 67, 74, 69, 46, 71, 34, 72, 98, 74, 34, 75, 34, 76, 50, - 80, 34, 83, 34, 84, 62, 90, 254, 255, 15, 82, 218, 176, 9, 66, 2, 77, 2, - 88, 226, 40, 78, 2, 81, 234, 35, 86, 234, 47, 68, 14, 73, 2, 79, 2, 85, - 2, 89, 142, 57, 87, 255, 2, 70, 6, 150, 177, 26, 69, 2, 73, 227, 79, 78, - 8, 38, 72, 218, 244, 25, 73, 243, 59, 65, 4, 198, 176, 26, 73, 135, 23, - 65, 4, 156, 144, 9, 2, 76, 73, 235, 239, 17, 78, 4, 190, 179, 25, 72, - 191, 124, 65, 12, 46, 65, 186, 232, 26, 73, 2, 79, 215, 22, 69, 6, 26, - 82, 243, 254, 26, 69, 5, 239, 247, 25, 68, 4, 190, 178, 25, 72, 207, 64, - 73, 4, 254, 218, 25, 72, 223, 83, 65, 4, 11, 65, 4, 198, 218, 15, 66, - 203, 163, 11, 83, 4, 174, 218, 25, 72, 227, 106, 65, 4, 246, 253, 25, 72, - 247, 47, 65, 6, 176, 184, 3, 6, 85, 82, 78, 69, 68, 32, 135, 254, 1, 65, - 4, 178, 217, 25, 72, 223, 83, 69, 2, 181, 179, 20, 7, 82, 65, 71, 82, 65, - 80, 72, 10, 48, 2, 77, 69, 20, 4, 78, 71, 69, 82, 31, 82, 2, 167, 230, - 25, 76, 2, 133, 197, 18, 2, 32, 82, 6, 38, 76, 149, 243, 13, 3, 65, 70, - 70, 5, 207, 229, 25, 83, 202, 1, 66, 65, 214, 13, 79, 185, 171, 26, 7, - 69, 73, 67, 72, 32, 83, 84, 194, 1, 84, 8, 71, 79, 76, 73, 84, 73, 67, - 32, 229, 12, 8, 83, 83, 32, 79, 70, 32, 77, 73, 192, 1, 56, 6, 67, 65, - 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 96, 45, 9, 76, 32, 76, 69, 84, 84, - 69, 82, 32, 96, 206, 1, 65, 22, 66, 42, 67, 94, 68, 94, 70, 38, 71, 46, - 73, 138, 2, 76, 58, 77, 66, 78, 34, 79, 30, 80, 58, 82, 30, 83, 186, 1, - 84, 110, 86, 22, 89, 90, 90, 234, 145, 19, 72, 190, 133, 2, 85, 139, 183, - 5, 75, 2, 179, 210, 26, 90, 4, 214, 3, 73, 233, 225, 26, 2, 85, 75, 4, - 48, 8, 65, 85, 68, 65, 84, 69, 32, 67, 15, 72, 2, 11, 72, 2, 233, 135, - 20, 2, 82, 73, 6, 42, 74, 30, 79, 237, 210, 26, 2, 90, 69, 2, 161, 135, - 20, 2, 69, 82, 2, 187, 131, 25, 66, 4, 210, 156, 21, 82, 139, 180, 5, 73, - 2, 21, 3, 76, 65, 71, 2, 139, 241, 21, 79, 13, 38, 78, 54, 79, 141, 1, 2, - 90, 72, 2, 161, 199, 26, 8, 73, 84, 73, 65, 76, 32, 73, 90, 4, 33, 6, 84, - 65, 84, 69, 68, 32, 4, 26, 66, 25, 2, 83, 77, 2, 11, 73, 2, 35, 71, 2, - 21, 3, 65, 76, 76, 2, 165, 234, 24, 2, 32, 89, 4, 158, 240, 26, 73, 211, - 2, 69, 4, 52, 9, 65, 84, 73, 78, 65, 84, 69, 32, 77, 35, 74, 2, 141, 141, - 11, 3, 89, 83, 76, 2, 161, 148, 9, 3, 85, 68, 73, 2, 11, 65, 2, 211, 153, - 21, 83, 4, 206, 204, 26, 78, 3, 84, 4, 26, 79, 131, 241, 26, 69, 2, 245, - 208, 22, 2, 75, 79, 2, 237, 253, 21, 2, 73, 84, 14, 106, 72, 58, 76, 148, - 248, 13, 6, 80, 73, 68, 69, 82, 89, 173, 191, 10, 8, 77, 65, 76, 76, 32, - 89, 85, 83, 6, 32, 2, 84, 65, 187, 239, 26, 65, 5, 155, 197, 25, 80, 2, - 255, 131, 20, 79, 6, 78, 86, 196, 165, 22, 9, 82, 79, 75, 85, 84, 65, 83, - 84, 73, 167, 181, 4, 83, 2, 253, 174, 19, 2, 82, 73, 2, 175, 219, 24, 69, - 12, 50, 69, 222, 129, 19, 65, 130, 236, 7, 79, 3, 85, 6, 146, 149, 21, - 83, 147, 152, 5, 82, 4, 196, 152, 9, 3, 69, 77, 76, 221, 139, 16, 4, 72, - 73, 86, 69, 2, 223, 233, 26, 76, 6, 196, 246, 11, 13, 66, 69, 32, 87, 73, - 84, 72, 32, 77, 69, 82, 73, 68, 230, 200, 4, 87, 183, 151, 9, 86, 68, - 162, 1, 65, 44, 12, 84, 72, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 222, - 174, 18, 82, 222, 102, 71, 228, 141, 5, 3, 78, 71, 71, 238, 187, 1, 79, - 185, 77, 2, 76, 70, 4, 196, 191, 15, 2, 76, 32, 147, 171, 11, 84, 54, - 210, 2, 65, 50, 72, 46, 73, 46, 78, 46, 80, 2, 81, 40, 2, 82, 65, 22, 84, - 236, 144, 9, 2, 87, 73, 194, 152, 12, 85, 244, 69, 3, 70, 65, 73, 204, 7, - 4, 66, 65, 73, 82, 248, 21, 2, 79, 84, 150, 30, 68, 166, 128, 1, 77, 198, - 147, 1, 69, 164, 30, 3, 76, 65, 71, 148, 41, 3, 83, 65, 85, 230, 161, 1, - 74, 196, 16, 2, 71, 73, 141, 12, 2, 75, 85, 4, 240, 222, 24, 3, 73, 72, - 86, 163, 134, 2, 72, 4, 186, 232, 13, 87, 157, 243, 11, 2, 65, 71, 4, - 138, 146, 9, 85, 241, 245, 14, 2, 71, 71, 6, 202, 214, 15, 73, 241, 140, - 9, 2, 65, 85, 2, 225, 161, 26, 5, 65, 73, 82, 84, 72, 2, 247, 192, 26, - 73, 4, 248, 192, 23, 2, 72, 73, 237, 69, 2, 69, 73, 234, 9, 46, 65, 198, - 5, 69, 206, 82, 73, 151, 3, 79, 152, 1, 96, 7, 68, 85, 65, 84, 73, 79, - 78, 32, 5, 78, 84, 72, 65, 32, 162, 192, 20, 86, 219, 141, 5, 80, 2, 11, - 32, 2, 135, 209, 25, 67, 146, 1, 120, 7, 76, 69, 84, 84, 69, 82, 32, 212, - 2, 5, 83, 73, 71, 78, 32, 154, 255, 22, 65, 248, 8, 2, 86, 79, 195, 199, - 3, 79, 100, 214, 1, 86, 178, 131, 23, 65, 38, 68, 114, 84, 230, 5, 85, - 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, - 2, 74, 2, 75, 2, 80, 206, 40, 79, 162, 8, 69, 158, 20, 72, 2, 77, 2, 82, - 3, 89, 14, 60, 5, 69, 68, 73, 67, 32, 138, 138, 23, 79, 223, 214, 3, 65, - 4, 188, 167, 24, 6, 68, 79, 85, 66, 76, 69, 175, 244, 1, 65, 16, 66, 67, - 230, 194, 22, 78, 190, 66, 65, 182, 1, 80, 135, 150, 3, 86, 4, 238, 245, - 7, 79, 163, 204, 14, 65, 192, 8, 76, 10, 65, 84, 69, 82, 45, 84, 72, 65, - 78, 32, 206, 7, 69, 231, 207, 25, 89, 56, 134, 1, 65, 150, 3, 66, 62, 79, - 216, 2, 11, 69, 81, 85, 65, 76, 32, 84, 79, 32, 79, 82, 130, 208, 6, 67, - 138, 4, 87, 207, 252, 18, 83, 16, 44, 5, 66, 79, 86, 69, 32, 223, 212, 6, - 78, 12, 150, 1, 83, 180, 1, 19, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, - 69, 32, 69, 81, 85, 65, 76, 32, 65, 132, 207, 6, 4, 76, 69, 83, 83, 235, - 233, 18, 82, 6, 148, 1, 7, 73, 77, 73, 76, 65, 82, 32, 133, 210, 6, 23, - 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, 32, 65, 66, 79, 86, 69, - 32, 76, 69, 83, 83, 4, 26, 65, 219, 209, 6, 79, 2, 65, 3, 66, 79, 86, 6, - 40, 4, 69, 83, 73, 68, 195, 210, 6, 85, 2, 231, 2, 69, 20, 40, 2, 82, 32, - 245, 1, 3, 86, 69, 82, 16, 120, 16, 83, 76, 65, 78, 84, 69, 68, 32, 69, - 81, 85, 65, 76, 32, 84, 79, 138, 212, 6, 65, 242, 129, 13, 69, 167, 237, - 4, 76, 9, 49, 10, 32, 87, 73, 84, 72, 32, 68, 79, 84, 32, 6, 44, 5, 65, - 66, 79, 86, 69, 151, 166, 18, 73, 5, 207, 165, 26, 32, 4, 52, 7, 76, 65, - 80, 80, 73, 78, 71, 239, 245, 19, 32, 2, 233, 193, 24, 2, 32, 76, 134, 8, - 36, 2, 75, 32, 185, 73, 2, 78, 32, 254, 7, 130, 3, 65, 216, 15, 8, 67, - 65, 80, 73, 84, 65, 76, 32, 182, 11, 68, 134, 1, 70, 68, 2, 73, 78, 222, - 3, 75, 138, 1, 76, 174, 3, 78, 66, 77, 84, 3, 88, 69, 83, 22, 79, 202, 1, - 80, 90, 82, 182, 1, 83, 130, 22, 84, 200, 2, 13, 85, 80, 83, 73, 76, 79, - 78, 32, 87, 73, 84, 72, 32, 150, 1, 86, 142, 2, 89, 178, 232, 7, 66, 212, - 176, 3, 4, 71, 82, 65, 77, 204, 23, 2, 90, 69, 243, 136, 12, 81, 112, 92, - 10, 67, 82, 79, 80, 72, 79, 78, 73, 67, 32, 172, 14, 6, 78, 79, 32, 84, - 69, 76, 23, 82, 106, 188, 2, 6, 65, 84, 84, 73, 67, 32, 222, 5, 67, 92, - 3, 78, 65, 88, 32, 12, 68, 69, 76, 80, 72, 73, 67, 32, 70, 73, 86, 69, 0, - 14, 83, 84, 82, 65, 84, 73, 65, 78, 32, 70, 73, 70, 84, 89, 40, 11, 69, - 80, 73, 68, 65, 85, 82, 69, 65, 78, 32, 112, 3, 72, 69, 82, 164, 1, 9, - 77, 69, 83, 83, 69, 78, 73, 65, 78, 35, 84, 48, 72, 2, 70, 73, 180, 2, 4, - 79, 78, 69, 32, 205, 1, 4, 84, 69, 78, 32, 26, 36, 3, 70, 84, 89, 105, 2, - 86, 69, 11, 11, 32, 8, 22, 84, 171, 4, 83, 6, 48, 7, 72, 79, 85, 83, 65, - 78, 68, 215, 3, 65, 5, 231, 3, 32, 17, 11, 32, 14, 56, 7, 72, 85, 78, 68, - 82, 69, 68, 18, 84, 143, 3, 83, 7, 131, 2, 32, 6, 48, 7, 72, 79, 85, 83, - 65, 78, 68, 187, 2, 65, 5, 213, 1, 2, 32, 84, 14, 98, 72, 48, 7, 84, 72, - 79, 85, 83, 65, 78, 210, 198, 24, 81, 217, 228, 1, 5, 68, 82, 65, 67, 72, - 6, 44, 5, 85, 78, 68, 82, 69, 179, 198, 24, 65, 4, 17, 2, 68, 32, 4, 22, - 84, 131, 1, 83, 2, 95, 65, 8, 30, 84, 86, 83, 175, 1, 77, 4, 50, 65, 21, - 8, 72, 79, 85, 83, 65, 78, 68, 32, 2, 187, 186, 16, 76, 2, 11, 83, 2, - 181, 199, 24, 2, 84, 65, 4, 88, 5, 65, 82, 89, 83, 84, 145, 1, 12, 89, - 82, 69, 78, 65, 73, 67, 32, 84, 87, 79, 32, 2, 101, 5, 73, 65, 78, 32, - 70, 2, 17, 2, 32, 77, 2, 139, 152, 13, 78, 6, 30, 70, 29, 3, 84, 87, 79, - 2, 225, 186, 15, 2, 73, 86, 5, 11, 32, 2, 185, 152, 10, 5, 68, 82, 65, - 67, 72, 8, 112, 8, 77, 73, 79, 78, 73, 65, 78, 32, 181, 160, 25, 14, 65, - 69, 85, 77, 32, 79, 78, 69, 32, 80, 76, 69, 84, 72, 6, 206, 193, 12, 70, - 150, 176, 12, 84, 215, 58, 79, 2, 11, 32, 2, 167, 241, 24, 84, 32, 92, 8, - 72, 69, 83, 80, 73, 65, 78, 32, 129, 1, 10, 82, 79, 69, 90, 69, 78, 73, - 65, 78, 32, 20, 40, 2, 70, 73, 38, 84, 251, 163, 18, 79, 6, 182, 233, 20, - 86, 247, 236, 3, 70, 8, 250, 182, 15, 72, 142, 191, 10, 69, 239, 48, 87, - 12, 36, 2, 70, 73, 209, 24, 2, 84, 69, 8, 146, 189, 18, 86, 213, 136, 7, - 3, 70, 84, 89, 2, 231, 139, 10, 69, 4, 168, 239, 22, 2, 79, 85, 153, 181, - 1, 3, 84, 65, 66, 154, 2, 66, 76, 174, 45, 82, 66, 68, 220, 233, 7, 2, - 75, 65, 135, 6, 84, 144, 2, 44, 6, 69, 84, 84, 69, 82, 32, 239, 45, 85, - 142, 2, 198, 2, 65, 190, 1, 69, 28, 4, 73, 79, 84, 65, 128, 1, 2, 79, 77, - 156, 3, 3, 82, 72, 79, 46, 83, 48, 7, 85, 80, 83, 73, 76, 79, 78, 146, - 33, 80, 170, 2, 84, 222, 185, 5, 68, 252, 180, 2, 2, 75, 65, 238, 192, 1, - 71, 138, 143, 11, 67, 230, 154, 2, 66, 2, 72, 2, 90, 166, 1, 76, 186, - 235, 2, 89, 210, 43, 77, 2, 78, 147, 17, 88, 48, 68, 4, 76, 80, 72, 65, - 213, 28, 8, 82, 67, 72, 65, 73, 67, 32, 83, 47, 33, 6, 32, 87, 73, 84, - 72, 32, 44, 242, 2, 68, 30, 80, 226, 29, 86, 226, 5, 79, 238, 237, 3, 84, - 191, 174, 5, 77, 62, 186, 1, 84, 131, 27, 80, 31, 33, 6, 32, 87, 73, 84, - 72, 32, 28, 186, 5, 68, 136, 25, 2, 80, 83, 158, 1, 86, 226, 5, 79, 238, - 237, 3, 84, 191, 174, 5, 77, 62, 28, 2, 69, 71, 235, 34, 73, 42, 11, 65, - 43, 33, 6, 32, 87, 73, 84, 72, 32, 40, 54, 68, 30, 80, 194, 35, 79, 22, - 86, 219, 237, 3, 84, 16, 65, 4, 65, 83, 73, 65, 18, 36, 4, 83, 73, 76, - 73, 211, 16, 82, 17, 29, 5, 32, 65, 78, 68, 32, 14, 44, 2, 79, 88, 0, 3, - 86, 65, 82, 23, 80, 4, 81, 2, 73, 65, 6, 60, 10, 69, 82, 73, 83, 80, 79, - 77, 69, 78, 73, 175, 15, 82, 5, 169, 15, 7, 32, 65, 78, 68, 32, 80, 82, - 5, 161, 35, 7, 32, 87, 73, 84, 72, 32, 68, 6, 222, 147, 8, 73, 238, 214, - 17, 65, 239, 48, 72, 23, 33, 6, 32, 87, 73, 84, 72, 32, 20, 66, 68, 166, - 26, 86, 226, 5, 79, 238, 237, 3, 84, 191, 174, 5, 77, 10, 130, 24, 65, - 237, 199, 22, 5, 73, 65, 76, 89, 84, 18, 76, 9, 73, 65, 76, 89, 84, 73, - 75, 65, 32, 32, 3, 82, 65, 67, 227, 22, 65, 8, 174, 24, 65, 191, 244, 3, - 84, 2, 207, 194, 11, 72, 4, 40, 3, 73, 86, 69, 1, 3, 79, 85, 82, 2, 205, - 37, 2, 32, 79, 76, 144, 1, 27, 83, 84, 82, 85, 77, 69, 78, 84, 65, 76, - 32, 78, 79, 84, 65, 84, 73, 79, 78, 32, 83, 89, 77, 66, 79, 76, 45, 217, - 176, 22, 2, 68, 73, 74, 70, 49, 70, 50, 62, 51, 62, 52, 170, 37, 53, 218, - 142, 26, 55, 3, 56, 17, 186, 181, 26, 49, 2, 50, 2, 51, 2, 52, 2, 55, 2, - 56, 3, 57, 15, 246, 180, 26, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 12, - 186, 180, 26, 48, 2, 50, 2, 54, 2, 55, 2, 56, 3, 57, 17, 254, 179, 26, - 48, 2, 50, 2, 51, 2, 53, 2, 55, 2, 56, 3, 57, 8, 54, 65, 38, 79, 169, 32, - 6, 89, 65, 84, 72, 79, 83, 4, 134, 134, 8, 80, 187, 151, 17, 73, 2, 11, - 82, 2, 11, 79, 2, 191, 139, 24, 78, 32, 128, 1, 6, 69, 84, 84, 69, 82, - 32, 168, 2, 6, 79, 87, 69, 82, 32, 78, 32, 6, 85, 78, 65, 84, 69, 32, - 201, 217, 22, 2, 73, 84, 24, 94, 83, 140, 13, 9, 65, 82, 67, 72, 65, 73, - 67, 32, 75, 2, 75, 182, 11, 68, 219, 199, 25, 89, 16, 88, 13, 77, 65, 76, - 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, 210, 12, 65, 247, 250, 7, 84, 12, - 74, 80, 170, 200, 9, 71, 242, 161, 9, 79, 154, 212, 2, 82, 139, 181, 1, - 76, 4, 206, 155, 26, 83, 219, 19, 73, 2, 161, 142, 10, 3, 85, 77, 69, 4, - 222, 25, 83, 215, 231, 7, 69, 4, 80, 4, 69, 84, 82, 69, 173, 216, 23, 10, - 85, 83, 73, 67, 65, 76, 32, 76, 69, 73, 2, 235, 212, 2, 84, 12, 88, 3, - 78, 69, 32, 142, 244, 9, 88, 252, 155, 5, 3, 85, 78, 75, 225, 208, 5, 2, - 66, 79, 6, 64, 8, 72, 65, 76, 70, 32, 83, 73, 71, 21, 4, 81, 85, 65, 82, - 4, 151, 173, 25, 78, 2, 147, 225, 20, 84, 16, 62, 82, 206, 11, 83, 114, - 69, 154, 243, 7, 72, 195, 150, 17, 73, 2, 217, 29, 2, 79, 83, 6, 100, 3, - 72, 79, 32, 165, 253, 7, 16, 69, 86, 69, 82, 83, 69, 68, 32, 76, 85, 78, - 65, 84, 69, 32, 69, 4, 136, 252, 13, 10, 87, 73, 84, 72, 32, 83, 84, 82, - 79, 75, 163, 153, 11, 83, 226, 2, 220, 1, 5, 77, 65, 76, 76, 32, 192, 19, - 22, 85, 66, 83, 67, 82, 73, 80, 84, 32, 83, 77, 65, 76, 76, 32, 76, 69, - 84, 84, 69, 82, 32, 72, 10, 89, 77, 66, 79, 76, 32, 84, 65, 85, 32, 225, - 168, 24, 6, 73, 78, 85, 83, 79, 73, 212, 2, 56, 7, 76, 69, 84, 84, 69, - 82, 32, 202, 17, 82, 67, 68, 206, 2, 178, 2, 65, 162, 2, 68, 38, 69, 52, - 4, 73, 79, 84, 65, 0, 7, 85, 80, 83, 73, 76, 79, 78, 254, 3, 75, 28, 2, - 79, 77, 182, 5, 80, 112, 3, 82, 72, 79, 94, 83, 94, 84, 244, 237, 7, 2, - 70, 73, 210, 193, 1, 71, 138, 143, 11, 67, 230, 154, 2, 66, 2, 72, 2, 90, - 166, 1, 76, 138, 151, 3, 77, 2, 78, 147, 17, 88, 58, 64, 4, 76, 80, 72, - 65, 149, 1, 7, 82, 67, 72, 65, 73, 67, 32, 55, 33, 6, 32, 87, 73, 84, 72, - 32, 52, 82, 86, 226, 6, 68, 30, 80, 114, 79, 142, 1, 89, 218, 239, 3, 84, - 191, 174, 5, 77, 6, 154, 5, 82, 155, 3, 65, 4, 18, 75, 23, 83, 2, 215, - 251, 7, 79, 2, 11, 65, 2, 171, 197, 13, 77, 4, 150, 230, 7, 73, 151, 128, - 15, 69, 70, 22, 80, 215, 4, 84, 20, 249, 7, 3, 83, 73, 76, 41, 33, 6, 32, - 87, 73, 84, 72, 32, 38, 78, 68, 166, 1, 80, 178, 1, 86, 226, 5, 79, 238, - 237, 3, 84, 191, 174, 5, 77, 18, 50, 65, 29, 8, 73, 65, 76, 89, 84, 73, - 75, 65, 8, 153, 1, 3, 83, 73, 65, 11, 29, 5, 32, 65, 78, 68, 32, 8, 170, - 1, 80, 154, 6, 79, 22, 86, 219, 237, 3, 84, 10, 18, 83, 115, 69, 8, 21, - 3, 73, 76, 73, 9, 17, 2, 32, 65, 6, 21, 3, 78, 68, 32, 6, 30, 80, 154, 6, - 79, 23, 86, 2, 11, 69, 2, 11, 82, 2, 181, 17, 4, 73, 83, 80, 79, 4, 22, - 82, 147, 15, 65, 2, 145, 253, 25, 2, 65, 67, 4, 206, 246, 7, 65, 3, 79, - 70, 28, 2, 69, 71, 151, 3, 73, 50, 11, 65, 51, 33, 6, 32, 87, 73, 84, 72, - 32, 48, 58, 68, 30, 80, 114, 79, 62, 86, 82, 89, 219, 239, 3, 84, 16, 61, - 4, 65, 83, 73, 65, 20, 32, 4, 83, 73, 76, 73, 91, 69, 17, 29, 5, 32, 65, - 78, 68, 32, 14, 42, 79, 12, 2, 80, 69, 50, 86, 83, 89, 4, 83, 88, 4, 89, - 9, 82, 73, 83, 80, 79, 77, 69, 78, 73, 4, 11, 65, 4, 11, 82, 4, 17, 2, - 73, 65, 5, 33, 6, 32, 65, 78, 68, 32, 89, 2, 243, 12, 80, 20, 17, 2, 67, - 82, 20, 17, 2, 79, 78, 21, 33, 6, 32, 87, 73, 84, 72, 32, 18, 88, 5, 68, - 65, 83, 73, 65, 0, 5, 80, 83, 73, 76, 73, 54, 79, 22, 86, 219, 237, 3, - 84, 7, 29, 5, 32, 65, 78, 68, 32, 4, 18, 79, 23, 86, 2, 151, 224, 9, 88, - 2, 179, 9, 65, 8, 88, 11, 65, 77, 80, 72, 89, 76, 73, 65, 78, 32, 68, - 186, 132, 26, 72, 2, 83, 219, 19, 73, 2, 151, 219, 7, 73, 7, 33, 6, 32, - 87, 73, 84, 72, 32, 4, 34, 68, 201, 147, 21, 2, 80, 83, 2, 151, 205, 8, - 65, 10, 54, 65, 186, 238, 7, 84, 230, 1, 73, 219, 135, 18, 72, 4, 238, - 184, 13, 77, 251, 221, 12, 78, 4, 174, 217, 22, 72, 175, 152, 3, 65, 4, - 41, 8, 69, 86, 69, 82, 83, 69, 68, 32, 4, 18, 68, 43, 76, 2, 37, 7, 79, - 84, 84, 69, 68, 32, 76, 2, 11, 85, 2, 33, 6, 78, 65, 84, 69, 32, 83, 2, - 169, 239, 7, 3, 73, 71, 77, 10, 230, 173, 9, 71, 138, 143, 11, 67, 2, 80, - 130, 103, 82, 231, 179, 1, 66, 2, 167, 163, 21, 82, 16, 106, 72, 104, 7, - 82, 89, 66, 76, 73, 79, 78, 44, 3, 87, 79, 32, 246, 230, 3, 79, 133, 214, - 16, 2, 65, 76, 6, 40, 4, 82, 69, 69, 32, 143, 237, 7, 69, 4, 146, 1, 79, - 213, 223, 22, 7, 81, 85, 65, 82, 84, 69, 82, 2, 21, 3, 32, 66, 65, 2, - 151, 242, 23, 83, 4, 42, 79, 189, 160, 12, 4, 84, 72, 73, 82, 2, 157, - 237, 19, 2, 66, 79, 6, 80, 5, 65, 67, 85, 84, 69, 0, 9, 68, 73, 65, 69, - 82, 69, 83, 73, 83, 39, 72, 2, 33, 6, 32, 65, 78, 68, 32, 72, 2, 209, - 202, 7, 2, 79, 79, 60, 102, 65, 21, 21, 79, 67, 65, 76, 32, 78, 79, 84, - 65, 84, 73, 79, 78, 32, 83, 89, 77, 66, 79, 76, 45, 2, 207, 214, 9, 82, - 58, 90, 50, 2, 53, 214, 202, 23, 49, 134, 196, 2, 51, 2, 52, 2, 54, 2, - 55, 2, 56, 3, 57, 13, 214, 142, 26, 48, 2, 49, 2, 50, 2, 51, 3, 52, 4, - 26, 80, 227, 195, 20, 69, 2, 11, 79, 2, 33, 6, 71, 69, 71, 82, 65, 77, 2, - 253, 136, 21, 2, 77, 69, 8, 254, 245, 13, 65, 206, 193, 10, 66, 202, 78, - 72, 253, 64, 3, 83, 65, 76, 12, 60, 6, 78, 78, 73, 78, 71, 32, 149, 132, - 25, 3, 77, 65, 67, 10, 100, 4, 70, 65, 67, 69, 137, 241, 17, 15, 67, 65, - 84, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 83, 9, 33, 6, 32, 87, 73, - 84, 72, 32, 6, 108, 23, 79, 78, 69, 32, 76, 65, 82, 71, 69, 32, 65, 78, - 68, 32, 79, 78, 69, 32, 83, 77, 65, 76, 76, 35, 83, 2, 11, 32, 2, 227, - 164, 8, 69, 4, 32, 2, 84, 65, 191, 239, 17, 77, 2, 247, 138, 23, 82, 6, - 28, 3, 85, 80, 32, 39, 87, 4, 142, 216, 22, 83, 135, 240, 2, 77, 2, 231, - 157, 18, 73, 220, 4, 136, 1, 2, 65, 82, 70, 73, 52, 7, 74, 65, 82, 65, - 84, 73, 32, 184, 6, 12, 78, 74, 65, 76, 65, 32, 71, 79, 78, 68, 73, 32, - 143, 3, 82, 4, 34, 65, 173, 137, 21, 2, 68, 83, 2, 11, 78, 2, 199, 128, - 25, 73, 4, 246, 227, 24, 84, 221, 162, 1, 4, 68, 69, 32, 68, 182, 1, 168, - 1, 7, 76, 69, 84, 84, 69, 82, 32, 220, 1, 5, 83, 73, 71, 78, 32, 160, 2, - 6, 86, 79, 87, 69, 76, 32, 130, 142, 20, 65, 154, 24, 82, 182, 231, 3, - 68, 179, 227, 1, 79, 98, 218, 167, 22, 65, 38, 68, 114, 84, 46, 86, 186, - 5, 85, 186, 202, 1, 73, 42, 76, 246, 14, 90, 238, 180, 1, 78, 46, 83, 82, - 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 82, 2, 89, - 186, 2, 69, 3, 79, 24, 98, 67, 28, 3, 77, 65, 68, 22, 84, 130, 203, 3, - 83, 226, 154, 18, 78, 190, 66, 65, 187, 151, 3, 86, 4, 118, 73, 199, 228, - 21, 65, 2, 243, 148, 19, 68, 4, 68, 5, 87, 79, 45, 67, 73, 29, 8, 72, 82, - 69, 69, 45, 68, 79, 84, 2, 25, 4, 82, 67, 76, 69, 2, 189, 214, 20, 5, 32, - 78, 85, 75, 84, 34, 44, 5, 83, 73, 71, 78, 32, 239, 199, 15, 67, 30, 234, - 199, 15, 67, 154, 226, 6, 65, 38, 85, 22, 86, 166, 202, 1, 73, 198, 140, - 2, 69, 3, 79, 126, 108, 7, 76, 69, 84, 84, 69, 82, 32, 216, 1, 5, 83, 73, - 71, 78, 32, 38, 86, 214, 137, 24, 68, 179, 227, 1, 79, 80, 210, 137, 22, - 78, 146, 24, 65, 38, 68, 114, 84, 230, 5, 85, 186, 202, 1, 73, 42, 76, - 222, 196, 1, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 206, 40, 79, 162, 8, - 69, 158, 20, 72, 2, 77, 2, 82, 2, 83, 2, 86, 3, 89, 4, 146, 196, 23, 86, - 247, 244, 1, 65, 20, 190, 7, 79, 131, 186, 23, 73, 160, 2, 84, 6, 77, 85, - 75, 72, 73, 32, 189, 7, 10, 85, 78, 71, 32, 75, 72, 69, 77, 65, 32, 172, - 1, 194, 1, 65, 44, 7, 76, 69, 84, 84, 69, 82, 32, 238, 1, 83, 228, 2, 2, - 86, 79, 164, 152, 13, 3, 84, 73, 80, 174, 242, 5, 73, 252, 175, 2, 5, 69, - 75, 32, 79, 78, 202, 199, 2, 68, 203, 175, 1, 85, 4, 222, 218, 21, 66, - 177, 231, 1, 2, 68, 68, 96, 250, 201, 8, 71, 2, 75, 254, 210, 13, 65, 38, - 68, 82, 82, 34, 84, 230, 5, 85, 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, - 126, 66, 2, 67, 2, 74, 2, 80, 2, 83, 206, 40, 79, 162, 8, 69, 158, 20, - 70, 2, 72, 2, 77, 2, 86, 2, 89, 3, 90, 26, 108, 19, 69, 81, 85, 69, 78, - 67, 69, 32, 70, 79, 82, 32, 76, 69, 84, 84, 69, 82, 32, 93, 4, 73, 71, - 78, 32, 12, 70, 71, 2, 75, 162, 250, 23, 83, 146, 219, 1, 76, 226, 31, - 70, 3, 90, 2, 159, 250, 23, 72, 14, 128, 1, 6, 65, 68, 65, 75, 32, 66, 2, - 66, 244, 148, 15, 2, 85, 68, 190, 196, 6, 78, 236, 177, 2, 3, 89, 65, 75, - 139, 168, 1, 86, 2, 187, 155, 8, 73, 18, 45, 9, 87, 69, 76, 32, 83, 73, - 71, 78, 32, 18, 202, 158, 22, 65, 38, 85, 186, 202, 1, 73, 210, 237, 1, - 79, 163, 8, 69, 116, 216, 1, 22, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, - 83, 73, 71, 78, 32, 77, 69, 68, 73, 65, 76, 32, 44, 7, 76, 69, 84, 84, - 69, 82, 32, 168, 1, 5, 83, 73, 71, 78, 32, 56, 6, 86, 79, 87, 69, 76, 32, - 183, 253, 23, 68, 8, 142, 241, 25, 72, 2, 82, 2, 86, 3, 89, 60, 150, 253, - 21, 78, 182, 24, 68, 114, 84, 162, 149, 3, 66, 2, 67, 2, 71, 2, 74, 2, - 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 82, 2, 83, 2, 86, 2, 89, 187, 2, - 65, 4, 250, 172, 25, 65, 233, 35, 6, 84, 72, 79, 76, 72, 79, 24, 174, - 166, 20, 83, 147, 137, 5, 76, 168, 23, 110, 65, 214, 95, 69, 150, 104, - 73, 146, 9, 79, 158, 12, 84, 30, 85, 130, 1, 89, 249, 244, 12, 4, 82, 89, - 86, 78, 140, 11, 236, 1, 2, 73, 82, 100, 8, 76, 70, 87, 73, 68, 84, 72, - 32, 242, 10, 77, 210, 1, 78, 236, 76, 21, 80, 80, 89, 32, 80, 69, 82, 83, - 79, 78, 32, 82, 65, 73, 83, 73, 78, 71, 32, 79, 78, 22, 82, 38, 84, 232, - 255, 17, 2, 85, 77, 255, 253, 5, 68, 8, 66, 32, 164, 207, 20, 6, 89, 32, - 67, 82, 69, 65, 251, 164, 4, 67, 4, 218, 187, 24, 80, 231, 115, 83, 244, - 1, 140, 2, 7, 72, 65, 78, 71, 85, 76, 32, 216, 4, 8, 75, 65, 84, 65, 75, - 65, 78, 65, 204, 3, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 152, 192, 6, 11, - 70, 79, 82, 77, 83, 32, 76, 73, 71, 72, 84, 202, 134, 4, 85, 198, 218, 2, - 73, 142, 190, 4, 66, 166, 238, 4, 87, 215, 35, 68, 104, 52, 7, 76, 69, - 84, 84, 69, 82, 32, 239, 224, 10, 70, 102, 206, 1, 75, 28, 5, 78, 73, 69, - 85, 78, 42, 80, 24, 5, 82, 73, 69, 85, 76, 86, 83, 98, 89, 202, 61, 67, - 54, 69, 30, 73, 242, 4, 77, 138, 1, 84, 206, 3, 87, 198, 1, 72, 226, 221, - 24, 65, 2, 79, 163, 64, 85, 6, 222, 65, 72, 155, 3, 73, 7, 11, 45, 4, - 134, 72, 67, 131, 3, 72, 6, 146, 69, 72, 35, 73, 17, 11, 45, 14, 206, 49, - 84, 226, 14, 80, 130, 4, 77, 194, 3, 75, 218, 2, 72, 99, 83, 12, 40, 4, - 83, 65, 78, 71, 235, 229, 13, 73, 10, 210, 70, 67, 42, 75, 74, 80, 34, - 84, 211, 2, 83, 14, 238, 157, 23, 69, 146, 137, 2, 65, 162, 64, 73, 2, - 79, 3, 85, 118, 70, 32, 157, 241, 2, 11, 45, 72, 73, 82, 65, 71, 65, 78, - 65, 32, 80, 116, 76, 7, 76, 69, 84, 84, 69, 82, 32, 242, 240, 2, 83, 34, - 86, 219, 224, 21, 77, 110, 146, 1, 83, 230, 234, 2, 78, 150, 2, 72, 2, - 75, 2, 77, 2, 82, 2, 84, 170, 1, 89, 234, 41, 87, 174, 204, 22, 65, 2, - 69, 2, 73, 2, 79, 3, 85, 28, 76, 5, 77, 65, 76, 76, 32, 230, 227, 25, 65, - 2, 69, 2, 73, 2, 79, 3, 85, 18, 206, 237, 2, 89, 174, 209, 22, 84, 234, - 36, 65, 2, 69, 2, 73, 2, 79, 3, 85, 4, 11, 84, 4, 180, 165, 13, 2, 32, - 67, 135, 156, 11, 87, 14, 56, 3, 77, 69, 82, 106, 83, 145, 144, 22, 3, - 66, 85, 82, 9, 29, 5, 32, 65, 78, 68, 32, 6, 220, 177, 12, 3, 87, 82, 69, - 212, 233, 3, 2, 83, 73, 191, 148, 8, 80, 4, 148, 164, 25, 3, 84, 69, 82, - 163, 61, 65, 194, 8, 118, 68, 202, 2, 71, 128, 66, 13, 73, 70, 73, 32, - 82, 79, 72, 73, 78, 71, 89, 65, 32, 165, 5, 5, 85, 78, 79, 79, 32, 10, - 100, 12, 32, 87, 73, 84, 72, 32, 73, 78, 68, 69, 88, 32, 188, 1, 2, 66, - 65, 197, 241, 21, 2, 83, 72, 4, 156, 1, 18, 65, 78, 68, 32, 77, 73, 68, - 68, 76, 69, 32, 70, 73, 78, 71, 69, 82, 83, 1, 16, 70, 73, 78, 71, 69, - 82, 32, 65, 78, 68, 32, 84, 72, 85, 77, 66, 2, 225, 147, 16, 2, 32, 67, - 4, 154, 210, 24, 76, 211, 139, 1, 71, 170, 7, 84, 3, 85, 76, 32, 217, 64, - 13, 90, 72, 79, 85, 32, 78, 85, 77, 69, 82, 65, 76, 32, 146, 7, 164, 1, - 9, 67, 72, 79, 83, 69, 79, 78, 71, 32, 244, 15, 4, 68, 79, 85, 66, 0, 4, - 83, 73, 78, 71, 46, 74, 180, 31, 7, 76, 69, 84, 84, 69, 82, 32, 219, 161, - 10, 70, 250, 1, 246, 1, 67, 172, 2, 5, 73, 69, 85, 78, 71, 146, 1, 75, - 132, 1, 5, 77, 73, 69, 85, 77, 56, 5, 78, 73, 69, 85, 78, 74, 80, 172, 2, - 5, 82, 73, 69, 85, 76, 210, 1, 83, 166, 3, 84, 124, 2, 89, 69, 200, 40, - 5, 72, 73, 69, 85, 72, 143, 153, 10, 70, 30, 76, 2, 72, 73, 84, 7, 69, - 79, 78, 71, 67, 72, 73, 121, 4, 73, 69, 85, 67, 16, 40, 4, 69, 85, 67, - 72, 41, 2, 84, 85, 7, 11, 45, 4, 202, 31, 75, 243, 26, 72, 10, 21, 3, 69, - 85, 77, 10, 22, 83, 155, 46, 67, 6, 40, 4, 83, 65, 78, 71, 219, 213, 13, - 73, 4, 194, 54, 67, 227, 3, 83, 5, 215, 30, 45, 27, 11, 45, 24, 90, 80, - 234, 30, 82, 242, 13, 67, 194, 5, 77, 138, 1, 84, 186, 2, 75, 218, 2, 72, - 99, 83, 6, 214, 50, 72, 214, 3, 73, 207, 2, 65, 16, 80, 7, 65, 80, 89, - 69, 79, 85, 78, 228, 20, 5, 73, 89, 69, 79, 75, 131, 25, 72, 10, 234, 29, - 82, 178, 15, 80, 30, 83, 231, 3, 77, 11, 11, 45, 8, 158, 52, 75, 74, 80, - 34, 84, 211, 2, 83, 15, 11, 45, 12, 190, 51, 67, 42, 75, 74, 80, 34, 84, - 242, 1, 72, 99, 83, 42, 68, 6, 72, 73, 69, 85, 80, 72, 40, 4, 73, 69, 85, - 80, 223, 53, 65, 7, 11, 45, 4, 158, 51, 80, 147, 2, 72, 35, 11, 45, 32, - 82, 83, 234, 20, 80, 214, 7, 75, 162, 12, 67, 202, 6, 84, 226, 2, 78, - 179, 2, 72, 14, 32, 3, 73, 79, 83, 251, 3, 83, 13, 11, 45, 10, 242, 46, - 84, 146, 2, 67, 42, 75, 75, 80, 29, 11, 45, 26, 78, 75, 42, 83, 190, 44, - 77, 154, 3, 67, 82, 78, 34, 80, 34, 84, 243, 1, 72, 6, 170, 22, 65, 130, - 19, 72, 135, 7, 73, 8, 40, 4, 83, 65, 78, 71, 191, 206, 13, 73, 6, 206, - 47, 75, 74, 80, 35, 84, 58, 48, 3, 73, 79, 83, 217, 1, 4, 83, 65, 78, 71, - 33, 11, 45, 30, 130, 1, 80, 44, 2, 83, 83, 210, 22, 82, 210, 1, 75, 162, - 12, 67, 194, 5, 77, 138, 1, 84, 226, 2, 78, 178, 2, 72, 187, 170, 18, 73, - 6, 184, 23, 4, 73, 69, 85, 80, 179, 19, 72, 2, 233, 48, 3, 65, 78, 71, - 26, 236, 17, 5, 67, 73, 69, 85, 67, 172, 3, 4, 83, 73, 79, 83, 154, 1, - 82, 186, 20, 84, 54, 89, 134, 2, 75, 42, 78, 34, 80, 146, 2, 72, 187, - 170, 18, 73, 16, 40, 5, 73, 75, 69, 85, 84, 195, 41, 72, 15, 11, 45, 12, - 226, 20, 82, 178, 19, 77, 154, 3, 67, 42, 75, 74, 80, 243, 2, 83, 4, 150, - 19, 83, 139, 22, 79, 2, 225, 252, 8, 6, 76, 69, 32, 68, 79, 84, 216, 3, - 92, 9, 79, 78, 71, 83, 69, 79, 78, 71, 32, 165, 21, 9, 85, 78, 71, 83, - 69, 79, 78, 71, 32, 154, 2, 226, 1, 67, 80, 5, 72, 73, 69, 85, 72, 60, 5, - 73, 69, 85, 78, 71, 46, 75, 220, 1, 5, 77, 73, 69, 85, 77, 188, 1, 5, 78, - 73, 69, 85, 78, 94, 80, 240, 2, 5, 82, 73, 69, 85, 76, 190, 4, 83, 194, - 3, 84, 213, 1, 2, 89, 69, 8, 36, 4, 73, 69, 85, 67, 239, 30, 72, 7, 11, - 45, 4, 162, 32, 83, 239, 7, 80, 11, 11, 45, 8, 174, 16, 82, 178, 19, 77, - 234, 3, 78, 35, 80, 9, 11, 45, 6, 194, 17, 75, 57, 2, 83, 83, 28, 76, 7, - 65, 80, 89, 69, 79, 85, 78, 40, 5, 73, 89, 69, 79, 75, 215, 30, 72, 8, - 130, 15, 82, 178, 15, 80, 131, 4, 77, 19, 11, 45, 16, 166, 13, 75, 170, - 1, 82, 42, 83, 224, 13, 2, 67, 72, 146, 9, 78, 34, 80, 147, 2, 72, 27, - 11, 45, 24, 74, 80, 30, 83, 134, 13, 82, 242, 13, 67, 130, 9, 75, 42, 78, - 179, 2, 72, 6, 174, 33, 73, 131, 6, 65, 6, 40, 4, 83, 65, 78, 71, 183, - 194, 13, 73, 4, 238, 35, 78, 147, 3, 83, 21, 11, 45, 18, 174, 12, 82, - 242, 13, 67, 202, 6, 84, 186, 2, 75, 218, 2, 72, 62, 80, 39, 83, 36, 88, - 6, 65, 78, 83, 73, 79, 83, 48, 6, 72, 73, 69, 85, 80, 72, 53, 4, 73, 69, - 85, 80, 7, 11, 45, 4, 236, 7, 2, 75, 65, 195, 26, 80, 9, 11, 45, 6, 150, - 11, 84, 234, 22, 80, 243, 2, 83, 23, 11, 45, 20, 112, 5, 82, 73, 69, 85, - 76, 24, 4, 83, 73, 79, 83, 134, 3, 80, 246, 19, 67, 194, 5, 77, 170, 4, - 84, 243, 1, 72, 5, 153, 3, 2, 45, 80, 5, 221, 32, 2, 45, 84, 57, 11, 45, - 54, 102, 75, 92, 5, 77, 73, 69, 85, 77, 50, 80, 126, 83, 74, 84, 44, 2, - 89, 69, 154, 28, 78, 179, 2, 72, 10, 52, 5, 73, 89, 69, 79, 75, 190, 4, - 65, 131, 19, 72, 7, 11, 45, 4, 254, 32, 72, 99, 83, 9, 11, 45, 6, 130, - 30, 75, 218, 2, 72, 99, 83, 14, 48, 4, 73, 69, 85, 80, 174, 26, 72, 163, - 6, 65, 11, 11, 45, 8, 42, 80, 222, 29, 84, 242, 1, 72, 99, 83, 2, 243, - 25, 72, 6, 40, 4, 83, 65, 78, 71, 167, 187, 13, 73, 4, 182, 28, 75, 187, - 3, 83, 6, 100, 5, 73, 75, 69, 85, 84, 151, 25, 72, 6, 56, 9, 79, 82, 73, - 78, 72, 73, 69, 85, 72, 191, 3, 83, 5, 255, 29, 45, 52, 48, 3, 73, 79, - 83, 161, 1, 4, 83, 65, 78, 71, 25, 11, 45, 22, 82, 75, 162, 3, 82, 242, - 13, 67, 198, 2, 80, 254, 2, 77, 138, 1, 84, 147, 5, 72, 4, 22, 65, 135, - 26, 73, 2, 237, 18, 6, 80, 89, 69, 79, 85, 78, 28, 160, 1, 5, 82, 73, 69, - 85, 76, 36, 6, 84, 73, 75, 69, 85, 84, 16, 3, 89, 69, 83, 138, 19, 83, - 178, 1, 77, 154, 3, 67, 42, 75, 42, 78, 34, 80, 203, 172, 18, 73, 5, 17, - 2, 45, 75, 2, 159, 17, 72, 5, 255, 16, 45, 2, 135, 197, 18, 73, 20, 40, - 5, 73, 75, 69, 85, 84, 155, 21, 72, 19, 11, 45, 16, 58, 82, 42, 83, 42, - 84, 162, 13, 67, 130, 9, 75, 75, 80, 2, 17, 2, 73, 69, 2, 227, 171, 24, - 85, 4, 21, 3, 73, 79, 83, 5, 223, 1, 45, 2, 255, 19, 72, 18, 44, 6, 83, - 73, 69, 85, 78, 71, 243, 19, 79, 17, 11, 45, 14, 50, 75, 30, 83, 198, 17, - 77, 154, 6, 72, 63, 80, 4, 166, 14, 72, 135, 7, 73, 4, 26, 83, 215, 179, - 13, 73, 2, 21, 3, 65, 78, 71, 2, 207, 20, 75, 190, 1, 122, 65, 118, 69, - 134, 1, 73, 92, 7, 83, 83, 65, 78, 71, 65, 82, 106, 79, 138, 1, 85, 102, - 89, 174, 15, 87, 179, 149, 10, 70, 23, 48, 4, 82, 65, 69, 65, 98, 45, - 135, 179, 25, 69, 13, 11, 45, 10, 166, 234, 22, 69, 178, 201, 2, 65, 2, - 73, 3, 85, 25, 18, 79, 55, 85, 9, 11, 45, 6, 154, 142, 25, 69, 234, 36, - 79, 3, 85, 15, 11, 45, 12, 170, 9, 69, 166, 169, 25, 65, 2, 79, 3, 85, - 31, 11, 45, 28, 66, 65, 34, 89, 166, 1, 79, 166, 139, 25, 69, 234, 36, - 73, 3, 85, 5, 11, 82, 2, 195, 157, 18, 65, 14, 50, 65, 206, 231, 22, 69, - 178, 201, 2, 79, 3, 85, 7, 134, 146, 25, 45, 247, 30, 69, 23, 26, 45, - 195, 176, 25, 69, 18, 50, 79, 22, 89, 202, 230, 22, 69, 179, 201, 2, 85, - 5, 179, 156, 25, 45, 8, 198, 230, 22, 69, 147, 137, 2, 65, 17, 11, 45, - 14, 158, 19, 89, 206, 166, 5, 73, 128, 137, 13, 3, 69, 79, 45, 190, 172, - 6, 65, 163, 64, 85, 62, 42, 65, 70, 69, 66, 73, 22, 79, 107, 85, 11, 26, - 45, 171, 174, 25, 69, 6, 178, 143, 25, 89, 246, 30, 79, 3, 85, 11, 11, - 79, 9, 11, 45, 6, 174, 171, 25, 89, 186, 2, 79, 3, 85, 5, 215, 136, 25, - 45, 19, 11, 45, 16, 58, 89, 198, 236, 24, 65, 174, 33, 69, 246, 30, 73, - 3, 79, 6, 194, 236, 24, 65, 175, 33, 69, 21, 11, 45, 18, 142, 16, 89, - 250, 210, 22, 69, 146, 137, 2, 65, 162, 64, 73, 2, 79, 3, 85, 186, 1, - 226, 1, 65, 46, 67, 54, 69, 30, 73, 22, 75, 188, 1, 5, 77, 73, 69, 85, - 77, 64, 5, 78, 73, 69, 85, 78, 70, 80, 168, 1, 5, 82, 73, 69, 85, 76, - 254, 1, 84, 90, 83, 246, 2, 87, 50, 89, 150, 1, 72, 226, 221, 24, 79, - 163, 64, 85, 9, 156, 13, 3, 82, 65, 69, 231, 156, 25, 69, 4, 22, 72, 207, - 8, 73, 2, 137, 135, 25, 2, 73, 69, 7, 162, 169, 25, 79, 3, 85, 5, 203, - 181, 18, 69, 14, 56, 7, 65, 80, 89, 69, 79, 85, 78, 106, 72, 155, 3, 73, - 8, 30, 80, 30, 83, 231, 3, 77, 4, 190, 4, 72, 215, 3, 73, 2, 25, 4, 83, - 65, 78, 71, 2, 207, 7, 80, 2, 241, 60, 2, 73, 69, 9, 11, 45, 6, 22, 80, - 247, 9, 83, 4, 142, 7, 73, 207, 2, 65, 13, 11, 45, 10, 234, 5, 67, 146, - 1, 84, 242, 1, 72, 62, 80, 39, 83, 20, 48, 4, 73, 69, 85, 80, 170, 2, 72, - 163, 6, 65, 17, 11, 45, 14, 42, 83, 186, 2, 84, 146, 2, 67, 43, 75, 6, - 21, 3, 73, 79, 83, 7, 11, 45, 4, 202, 4, 75, 107, 84, 27, 11, 45, 24, 68, - 2, 75, 73, 34, 77, 34, 80, 106, 84, 54, 89, 222, 4, 72, 99, 83, 4, 149, - 1, 4, 89, 69, 79, 75, 2, 11, 73, 2, 231, 248, 23, 69, 8, 30, 72, 34, 73, - 131, 6, 65, 2, 221, 240, 18, 3, 73, 69, 85, 4, 21, 3, 69, 85, 80, 5, 243, - 5, 45, 4, 22, 72, 151, 3, 73, 2, 137, 254, 21, 2, 73, 69, 2, 17, 2, 69, - 79, 2, 167, 4, 82, 28, 44, 3, 73, 79, 83, 57, 4, 83, 65, 78, 71, 13, 11, - 45, 10, 122, 67, 42, 75, 42, 78, 34, 80, 35, 84, 16, 78, 67, 42, 75, 42, - 78, 34, 80, 34, 84, 242, 1, 72, 98, 83, 219, 169, 18, 73, 2, 11, 73, 2, - 225, 246, 23, 2, 69, 85, 2, 11, 73, 2, 233, 246, 24, 2, 89, 69, 2, 11, - 73, 2, 243, 159, 24, 69, 2, 11, 73, 2, 143, 170, 24, 69, 2, 11, 73, 2, - 11, 75, 2, 135, 166, 24, 69, 10, 146, 214, 22, 69, 146, 137, 2, 65, 163, - 64, 73, 34, 58, 69, 206, 1, 79, 62, 85, 178, 220, 24, 65, 163, 64, 73, - 13, 42, 79, 73, 6, 83, 73, 69, 85, 78, 71, 5, 11, 82, 2, 17, 2, 73, 78, - 2, 11, 72, 2, 233, 242, 9, 2, 73, 69, 7, 11, 45, 4, 18, 80, 39, 83, 2, - 11, 65, 2, 11, 78, 2, 11, 83, 2, 179, 155, 13, 73, 9, 11, 45, 6, 26, 89, - 231, 156, 25, 73, 4, 195, 220, 24, 65, 9, 11, 45, 6, 26, 89, 171, 156, - 25, 73, 4, 247, 210, 22, 69, 24, 162, 144, 11, 84, 230, 152, 12, 70, 30, - 83, 182, 87, 78, 14, 79, 227, 112, 69, 100, 156, 1, 7, 76, 69, 84, 84, - 69, 82, 32, 196, 2, 5, 77, 65, 82, 75, 32, 72, 5, 83, 73, 71, 78, 32, - 224, 159, 2, 6, 86, 79, 87, 69, 76, 32, 183, 131, 21, 68, 58, 202, 1, 68, - 34, 75, 142, 132, 21, 84, 178, 55, 82, 238, 223, 1, 78, 214, 181, 1, 83, - 138, 69, 66, 2, 67, 2, 70, 2, 71, 2, 72, 2, 74, 2, 76, 2, 77, 2, 80, 2, - 86, 2, 87, 2, 89, 2, 90, 187, 2, 65, 4, 162, 150, 25, 68, 187, 2, 65, 8, - 56, 5, 73, 78, 78, 65, 32, 202, 149, 25, 72, 187, 2, 65, 4, 198, 149, 25, - 87, 3, 89, 4, 160, 221, 21, 6, 78, 65, 32, 75, 72, 79, 237, 186, 2, 3, - 83, 65, 75, 8, 52, 2, 84, 65, 237, 134, 23, 5, 72, 65, 82, 66, 65, 6, 42, - 72, 198, 163, 20, 83, 191, 240, 4, 78, 2, 159, 244, 24, 65, 42, 62, 76, - 176, 251, 18, 6, 83, 73, 71, 78, 32, 80, 247, 1, 86, 36, 33, 6, 69, 84, - 84, 69, 82, 32, 36, 186, 159, 21, 78, 206, 243, 3, 66, 2, 68, 2, 71, 2, - 72, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, 2, 89, 186, - 2, 65, 2, 73, 3, 85, 2, 235, 131, 24, 69, 4, 234, 204, 23, 68, 163, 199, - 1, 80, 54, 52, 5, 67, 72, 73, 78, 71, 41, 4, 82, 65, 78, 32, 2, 17, 2, - 32, 67, 2, 139, 225, 23, 72, 52, 52, 7, 76, 69, 84, 84, 69, 82, 32, 171, - 186, 6, 78, 42, 218, 1, 65, 210, 181, 11, 90, 238, 46, 84, 146, 120, 76, - 50, 81, 60, 6, 68, 65, 76, 69, 84, 72, 214, 169, 4, 71, 122, 83, 66, 89, - 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, 134, 2, 87, - 218, 103, 80, 171, 4, 77, 4, 246, 134, 17, 76, 159, 186, 7, 89, 174, 9, - 210, 1, 65, 242, 32, 66, 130, 33, 76, 200, 1, 16, 78, 84, 65, 73, 71, 65, - 78, 65, 32, 76, 69, 84, 84, 69, 82, 32, 174, 12, 82, 120, 11, 88, 65, 71, - 82, 65, 77, 32, 70, 79, 82, 32, 189, 189, 24, 4, 68, 71, 69, 72, 214, 1, - 42, 68, 98, 82, 201, 1, 3, 86, 89, 32, 6, 44, 5, 83, 84, 79, 78, 69, 183, - 225, 23, 80, 5, 213, 226, 2, 7, 32, 71, 82, 65, 86, 69, 89, 12, 32, 2, - 84, 32, 147, 164, 17, 45, 10, 60, 5, 87, 73, 84, 72, 32, 222, 171, 12, - 68, 239, 158, 9, 72, 6, 76, 9, 84, 73, 80, 32, 79, 78, 32, 84, 72, 134, - 251, 12, 82, 243, 244, 10, 65, 2, 239, 217, 24, 69, 196, 1, 134, 2, 65, - 202, 1, 66, 230, 2, 67, 154, 3, 68, 162, 1, 69, 186, 3, 70, 94, 72, 62, - 76, 222, 1, 77, 110, 79, 162, 1, 82, 142, 2, 83, 228, 1, 3, 78, 79, 82, - 198, 1, 84, 128, 2, 2, 85, 80, 174, 1, 87, 186, 148, 14, 73, 222, 243, 3, - 80, 130, 142, 4, 86, 227, 78, 71, 12, 108, 17, 82, 82, 79, 87, 32, 83, - 72, 65, 70, 84, 32, 87, 73, 68, 84, 72, 32, 182, 171, 18, 77, 207, 198, - 4, 83, 8, 36, 3, 79, 78, 69, 135, 166, 23, 84, 7, 11, 32, 4, 226, 246, - 13, 84, 251, 139, 9, 72, 14, 48, 4, 65, 76, 76, 79, 21, 4, 76, 65, 67, - 75, 2, 139, 235, 5, 84, 12, 30, 32, 153, 1, 2, 45, 70, 6, 52, 7, 67, 85, - 82, 86, 69, 68, 32, 135, 128, 24, 72, 4, 40, 4, 68, 79, 87, 78, 1, 2, 85, - 80, 2, 225, 228, 23, 8, 87, 65, 82, 68, 83, 32, 65, 78, 6, 45, 9, 69, 65, - 84, 72, 69, 82, 69, 68, 32, 6, 158, 220, 13, 83, 174, 173, 3, 78, 215, - 218, 6, 82, 14, 116, 2, 72, 69, 52, 5, 73, 82, 67, 76, 69, 149, 233, 17, - 14, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 68, 4, 196, 221, - 20, 4, 86, 82, 79, 78, 255, 225, 2, 67, 9, 64, 6, 32, 87, 73, 84, 72, 32, - 185, 235, 22, 4, 68, 32, 83, 65, 4, 52, 7, 83, 84, 82, 79, 75, 69, 32, - 239, 128, 5, 67, 2, 29, 5, 65, 78, 68, 32, 84, 2, 11, 87, 2, 11, 79, 2, - 21, 3, 32, 68, 79, 2, 11, 84, 2, 223, 133, 24, 83, 14, 52, 7, 65, 83, 72, - 69, 68, 32, 84, 18, 73, 31, 79, 2, 175, 16, 82, 2, 161, 162, 19, 2, 86, - 73, 10, 192, 16, 3, 87, 78, 87, 246, 147, 14, 85, 191, 184, 4, 76, 16, - 120, 5, 73, 71, 72, 84, 32, 156, 2, 16, 88, 67, 76, 65, 77, 65, 84, 73, - 79, 78, 32, 77, 65, 82, 75, 32, 199, 217, 18, 81, 10, 40, 2, 80, 79, 126, - 84, 155, 231, 22, 83, 6, 33, 6, 73, 78, 84, 69, 68, 32, 6, 194, 199, 16, - 80, 128, 158, 6, 11, 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 82, 23, 66, - 2, 193, 231, 22, 24, 69, 65, 82, 68, 82, 79, 80, 45, 83, 80, 79, 75, 69, - 68, 32, 80, 82, 79, 80, 69, 76, 76, 69, 82, 4, 234, 232, 23, 83, 227, 81, - 79, 6, 44, 5, 79, 85, 82, 32, 66, 179, 128, 5, 73, 2, 181, 139, 11, 6, - 65, 76, 76, 79, 79, 78, 4, 238, 199, 17, 79, 161, 233, 5, 6, 69, 65, 82, - 84, 32, 69, 20, 74, 65, 44, 3, 69, 70, 84, 28, 2, 79, 87, 189, 251, 4, 3, - 73, 71, 65, 4, 232, 230, 21, 2, 82, 71, 211, 209, 1, 84, 8, 254, 3, 45, - 195, 6, 87, 6, 26, 32, 191, 151, 10, 69, 4, 202, 158, 14, 68, 25, 4, 83, - 73, 78, 71, 4, 56, 8, 85, 76, 84, 73, 80, 76, 73, 67, 167, 200, 21, 73, - 2, 25, 4, 65, 84, 73, 79, 2, 159, 221, 5, 78, 6, 148, 147, 6, 9, 80, 69, - 78, 32, 67, 69, 78, 84, 82, 248, 180, 10, 13, 86, 65, 76, 32, 87, 73, 84, - 72, 32, 79, 86, 65, 76, 213, 151, 6, 5, 85, 84, 76, 73, 78, 12, 76, 4, - 73, 71, 72, 84, 129, 214, 23, 9, 79, 85, 78, 68, 45, 84, 73, 80, 80, 10, - 62, 45, 109, 11, 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 4, 69, 15, - 80, 79, 73, 78, 84, 73, 78, 71, 32, 65, 78, 71, 76, 69, 32, 4, 214, 236, - 6, 66, 203, 174, 7, 81, 7, 139, 6, 32, 26, 106, 65, 78, 73, 44, 2, 79, - 85, 136, 163, 14, 7, 67, 82, 73, 80, 84, 32, 76, 193, 139, 1, 3, 80, 65, - 82, 4, 156, 154, 14, 10, 78, 83, 45, 83, 69, 82, 73, 70, 32, 73, 175, - 195, 8, 76, 8, 136, 152, 14, 2, 78, 71, 183, 194, 8, 88, 10, 21, 3, 84, - 72, 32, 10, 60, 5, 69, 65, 83, 84, 32, 29, 6, 87, 69, 83, 84, 32, 80, 6, - 26, 80, 215, 215, 23, 65, 4, 41, 8, 79, 73, 78, 84, 73, 78, 71, 32, 4, - 250, 250, 16, 86, 255, 202, 6, 66, 12, 88, 9, 69, 65, 82, 68, 82, 79, 80, - 45, 83, 130, 1, 82, 145, 233, 6, 4, 87, 69, 76, 86, 6, 64, 6, 80, 79, 75, - 69, 68, 32, 253, 207, 23, 4, 72, 65, 78, 75, 4, 216, 218, 22, 8, 80, 73, - 78, 87, 72, 69, 69, 76, 27, 65, 2, 193, 3, 5, 73, 65, 78, 71, 76, 6, 26, - 87, 171, 141, 10, 80, 4, 53, 11, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, - 32, 4, 29, 5, 87, 73, 84, 72, 32, 4, 152, 142, 20, 5, 76, 65, 82, 71, 69, - 179, 243, 1, 69, 12, 76, 5, 72, 73, 84, 69, 32, 164, 1, 2, 73, 68, 149, - 133, 23, 3, 69, 68, 71, 8, 64, 6, 83, 81, 85, 65, 82, 69, 182, 227, 17, - 68, 187, 183, 5, 67, 5, 169, 186, 23, 19, 32, 67, 79, 78, 84, 65, 73, 78, - 73, 78, 71, 32, 66, 76, 65, 67, 75, 32, 86, 2, 181, 255, 20, 2, 69, 45, - 142, 2, 40, 4, 82, 69, 87, 32, 219, 237, 24, 69, 140, 2, 112, 7, 65, 67, - 67, 69, 78, 84, 32, 142, 8, 76, 164, 14, 5, 77, 65, 82, 75, 32, 114, 80, - 225, 180, 21, 2, 89, 79, 60, 128, 2, 9, 65, 84, 78, 65, 72, 32, 72, 65, - 70, 22, 68, 36, 3, 71, 69, 82, 74, 77, 124, 2, 80, 65, 28, 4, 69, 84, 78, - 65, 20, 2, 81, 65, 58, 83, 58, 84, 156, 1, 2, 89, 69, 78, 90, 224, 172, - 8, 3, 82, 69, 86, 190, 146, 15, 79, 245, 148, 1, 3, 73, 76, 85, 2, 243, - 169, 18, 85, 4, 206, 146, 19, 69, 171, 149, 5, 65, 6, 32, 3, 69, 83, 72, - 179, 28, 83, 5, 241, 227, 6, 4, 32, 77, 85, 81, 8, 84, 5, 69, 82, 75, 72, - 65, 132, 251, 17, 2, 85, 78, 153, 45, 5, 65, 72, 65, 80, 65, 5, 221, 237, - 19, 4, 32, 75, 69, 70, 4, 26, 83, 219, 170, 24, 90, 2, 247, 195, 24, 72, - 4, 224, 163, 24, 6, 82, 78, 69, 89, 32, 80, 191, 35, 68, 4, 182, 24, 69, - 185, 237, 22, 6, 72, 65, 76, 83, 72, 69, 8, 38, 69, 241, 233, 22, 3, 73, - 80, 69, 6, 48, 6, 76, 73, 83, 72, 65, 32, 135, 232, 11, 86, 4, 252, 178, - 22, 3, 81, 69, 84, 205, 145, 2, 4, 71, 69, 68, 79, 4, 176, 212, 8, 10, - 82, 65, 72, 32, 66, 69, 78, 32, 89, 79, 231, 221, 2, 84, 8, 18, 65, 95, - 73, 6, 40, 4, 81, 69, 70, 32, 167, 134, 6, 82, 4, 246, 142, 11, 81, 149, - 193, 12, 3, 71, 65, 68, 2, 255, 171, 24, 78, 150, 1, 76, 6, 69, 84, 84, - 69, 82, 32, 201, 11, 8, 73, 71, 65, 84, 85, 82, 69, 32, 140, 1, 134, 3, - 65, 204, 1, 3, 66, 69, 84, 0, 3, 75, 65, 70, 0, 2, 80, 69, 68, 6, 70, 73, - 78, 65, 76, 32, 92, 2, 81, 79, 16, 2, 72, 69, 52, 2, 78, 85, 0, 4, 90, - 65, 89, 73, 18, 83, 48, 3, 82, 69, 83, 170, 1, 84, 52, 4, 68, 65, 76, 69, - 12, 5, 71, 73, 77, 69, 76, 0, 5, 76, 65, 77, 69, 68, 0, 3, 77, 69, 77, - 48, 3, 86, 65, 86, 80, 5, 87, 73, 68, 69, 32, 153, 1, 3, 89, 79, 68, 14, - 26, 76, 135, 225, 23, 89, 12, 64, 2, 69, 70, 73, 10, 84, 69, 82, 78, 65, - 84, 73, 86, 69, 32, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 130, 13, 77, - 130, 1, 80, 35, 81, 4, 198, 214, 16, 65, 131, 161, 1, 80, 7, 33, 6, 32, - 87, 73, 84, 72, 32, 4, 138, 15, 82, 195, 233, 13, 68, 14, 88, 2, 75, 65, - 236, 2, 2, 80, 69, 148, 154, 1, 2, 84, 83, 218, 192, 22, 78, 135, 110, - 77, 4, 235, 2, 70, 7, 244, 10, 5, 32, 87, 73, 84, 72, 131, 211, 24, 84, - 4, 167, 2, 78, 16, 44, 4, 65, 77, 69, 75, 17, 3, 72, 73, 78, 4, 231, 1, - 72, 13, 33, 6, 32, 87, 73, 84, 72, 32, 10, 40, 6, 68, 65, 71, 69, 83, 72, - 39, 83, 7, 33, 6, 32, 65, 78, 68, 32, 83, 4, 218, 133, 6, 72, 155, 193, - 2, 73, 12, 50, 69, 12, 2, 65, 86, 1, 4, 83, 65, 68, 73, 4, 11, 84, 5, - 225, 244, 13, 7, 32, 87, 73, 84, 72, 32, 68, 7, 33, 6, 32, 87, 73, 84, - 72, 32, 4, 208, 253, 1, 2, 72, 79, 191, 246, 11, 68, 16, 174, 2, 76, 254, - 210, 8, 65, 178, 196, 2, 84, 158, 218, 2, 82, 156, 132, 9, 2, 68, 65, - 218, 96, 75, 222, 106, 72, 169, 4, 7, 70, 73, 78, 65, 76, 32, 77, 7, 33, - 6, 32, 87, 73, 84, 72, 32, 4, 172, 7, 2, 72, 73, 251, 234, 13, 68, 10, - 72, 6, 65, 76, 69, 70, 32, 76, 29, 8, 89, 73, 68, 68, 73, 83, 72, 32, 2, - 209, 195, 19, 2, 65, 77, 8, 120, 7, 68, 79, 85, 66, 76, 69, 32, 232, 4, - 9, 89, 79, 68, 32, 89, 79, 68, 32, 80, 193, 151, 21, 5, 86, 65, 86, 32, - 89, 4, 146, 150, 11, 86, 151, 134, 10, 89, 6, 80, 3, 76, 79, 87, 0, 3, - 85, 80, 80, 173, 129, 23, 6, 77, 65, 83, 79, 82, 65, 2, 169, 194, 23, 2, - 69, 82, 50, 84, 5, 79, 73, 78, 84, 32, 225, 5, 11, 85, 78, 67, 84, 85, - 65, 84, 73, 79, 78, 32, 38, 228, 1, 9, 68, 65, 71, 69, 83, 72, 32, 79, - 82, 46, 72, 106, 80, 162, 1, 81, 86, 82, 22, 83, 224, 216, 9, 2, 84, 83, - 224, 157, 11, 17, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 72, 32, - 86, 65, 82, 189, 147, 3, 3, 77, 69, 84, 2, 17, 2, 32, 77, 2, 197, 1, 2, - 65, 80, 12, 60, 5, 65, 84, 65, 70, 32, 102, 73, 33, 4, 79, 76, 65, 77, 6, - 38, 80, 34, 81, 141, 2, 2, 83, 69, 2, 11, 65, 2, 223, 227, 17, 84, 2, - 129, 201, 23, 2, 65, 77, 2, 11, 82, 2, 139, 238, 13, 73, 5, 205, 144, 11, - 12, 32, 72, 65, 83, 69, 82, 32, 70, 79, 82, 32, 86, 6, 52, 5, 65, 77, 65, - 84, 83, 245, 198, 11, 2, 85, 66, 5, 241, 249, 10, 2, 32, 81, 2, 159, 232, - 6, 65, 8, 34, 69, 22, 72, 163, 186, 8, 73, 2, 179, 186, 23, 71, 4, 158, - 186, 8, 73, 223, 214, 7, 69, 12, 152, 1, 3, 71, 69, 82, 60, 3, 80, 65, - 83, 20, 7, 83, 79, 70, 32, 80, 65, 83, 240, 144, 22, 7, 78, 85, 78, 32, - 72, 65, 70, 253, 186, 1, 3, 77, 65, 81, 4, 26, 83, 203, 226, 22, 69, 2, - 253, 202, 23, 3, 72, 65, 89, 2, 151, 234, 13, 69, 2, 131, 234, 13, 85, 8, - 114, 77, 200, 157, 12, 15, 76, 83, 67, 72, 82, 69, 73, 66, 69, 82, 32, - 80, 65, 85, 83, 229, 227, 5, 3, 73, 67, 79, 4, 144, 229, 5, 12, 69, 84, - 32, 87, 73, 84, 72, 32, 87, 72, 73, 84, 203, 209, 17, 32, 188, 4, 164, 1, - 2, 65, 45, 50, 72, 70, 75, 230, 1, 77, 114, 78, 146, 2, 82, 66, 83, 154, - 1, 84, 226, 1, 87, 62, 89, 110, 69, 182, 248, 8, 85, 226, 174, 5, 79, - 139, 192, 3, 73, 8, 158, 171, 24, 87, 246, 30, 49, 2, 50, 3, 51, 72, 166, - 6, 79, 198, 198, 8, 65, 178, 228, 5, 85, 166, 116, 69, 3, 73, 74, 72, 2, - 65, 45, 104, 2, 79, 45, 178, 4, 73, 226, 3, 69, 187, 155, 15, 85, 24, - 146, 242, 11, 49, 238, 191, 12, 75, 214, 22, 50, 2, 51, 2, 52, 2, 53, 2, - 54, 2, 55, 2, 56, 3, 57, 8, 146, 180, 24, 75, 218, 19, 49, 2, 50, 3, 51, - 54, 68, 2, 69, 45, 154, 7, 79, 186, 155, 15, 65, 2, 73, 231, 203, 2, 85, - 6, 186, 196, 24, 77, 186, 2, 49, 3, 50, 68, 116, 2, 69, 45, 72, 2, 73, - 45, 246, 2, 65, 242, 250, 8, 79, 226, 174, 5, 85, 225, 146, 6, 6, 45, 77, - 85, 45, 77, 79, 14, 222, 166, 24, 75, 246, 30, 49, 2, 50, 2, 51, 2, 52, - 2, 53, 3, 54, 16, 182, 174, 24, 84, 214, 22, 49, 2, 50, 2, 51, 2, 52, 2, - 53, 2, 54, 3, 55, 54, 222, 4, 79, 2, 85, 186, 155, 15, 73, 230, 203, 2, - 65, 3, 69, 68, 62, 65, 2, 85, 226, 3, 73, 182, 248, 8, 69, 135, 163, 6, - 79, 16, 11, 45, 16, 174, 195, 24, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, - 2, 55, 3, 56, 64, 74, 69, 20, 2, 79, 45, 72, 2, 85, 45, 154, 157, 15, 73, - 231, 203, 2, 65, 18, 247, 129, 19, 45, 14, 202, 191, 24, 82, 186, 2, 49, - 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 10, 198, 162, 24, 84, 246, 30, 49, 2, - 50, 2, 51, 3, 52, 42, 218, 249, 8, 65, 2, 73, 134, 163, 6, 79, 231, 203, - 2, 69, 32, 40, 2, 65, 45, 66, 79, 159, 231, 17, 85, 12, 166, 161, 24, 89, - 246, 30, 49, 2, 50, 2, 51, 2, 52, 3, 53, 12, 11, 45, 12, 206, 191, 24, - 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 4, 188, 174, 8, 21, 77, 73, 84, - 73, 65, 78, 32, 67, 79, 78, 74, 85, 71, 65, 84, 69, 32, 77, 65, 84, 82, - 215, 144, 16, 66, 128, 1, 210, 2, 65, 110, 66, 144, 1, 2, 67, 79, 94, 68, - 198, 2, 70, 66, 71, 40, 4, 72, 79, 76, 68, 164, 1, 2, 73, 78, 116, 2, 77, - 79, 58, 79, 122, 80, 100, 2, 82, 69, 66, 83, 238, 1, 84, 210, 5, 87, 172, - 168, 15, 4, 76, 73, 77, 73, 140, 191, 5, 11, 89, 79, 85, 84, 72, 70, 85, - 76, 32, 70, 79, 137, 177, 3, 9, 69, 78, 84, 72, 85, 83, 73, 65, 83, 6, - 76, 3, 80, 80, 82, 124, 4, 70, 84, 69, 82, 209, 169, 19, 4, 66, 85, 78, - 68, 2, 201, 152, 24, 2, 79, 65, 6, 92, 5, 69, 70, 79, 82, 69, 232, 216, - 3, 6, 73, 84, 73, 78, 71, 32, 1, 4, 82, 69, 65, 75, 2, 165, 233, 23, 7, - 32, 67, 79, 77, 80, 76, 69, 6, 26, 78, 203, 160, 19, 77, 4, 204, 210, 20, - 4, 84, 69, 77, 80, 209, 213, 2, 3, 70, 76, 73, 14, 110, 69, 78, 73, 226, - 164, 19, 85, 241, 245, 2, 15, 65, 82, 75, 69, 78, 73, 78, 71, 32, 79, 70, - 32, 84, 72, 69, 6, 242, 160, 19, 67, 192, 6, 2, 76, 73, 149, 205, 4, 5, - 86, 69, 76, 79, 80, 4, 144, 151, 19, 21, 70, 70, 73, 67, 85, 76, 84, 89, - 32, 65, 84, 32, 84, 72, 69, 32, 66, 69, 71, 73, 78, 169, 253, 2, 4, 83, - 80, 69, 82, 4, 240, 155, 19, 2, 79, 76, 165, 197, 4, 5, 69, 76, 76, 79, - 87, 12, 36, 5, 65, 84, 72, 69, 82, 35, 82, 2, 189, 147, 15, 3, 73, 78, - 71, 10, 40, 4, 69, 65, 84, 32, 251, 247, 23, 65, 8, 22, 80, 215, 5, 84, - 6, 22, 79, 151, 5, 82, 4, 172, 2, 2, 83, 83, 171, 244, 23, 87, 8, 50, 78, - 226, 156, 19, 67, 217, 5, 3, 70, 76, 85, 4, 180, 162, 19, 2, 79, 67, 197, - 236, 1, 5, 69, 82, 32, 84, 82, 4, 196, 195, 22, 3, 68, 69, 83, 145, 62, - 3, 85, 84, 72, 6, 26, 66, 37, 2, 80, 80, 2, 245, 225, 23, 4, 83, 84, 82, - 85, 4, 26, 82, 207, 224, 23, 79, 2, 157, 143, 22, 2, 69, 83, 6, 160, 152, - 15, 9, 85, 83, 72, 73, 78, 71, 32, 85, 80, 192, 137, 2, 3, 82, 79, 71, - 143, 211, 6, 69, 6, 26, 84, 227, 140, 19, 86, 4, 146, 158, 19, 85, 171, - 137, 4, 82, 8, 132, 1, 5, 77, 65, 76, 76, 32, 248, 179, 21, 6, 84, 65, - 78, 68, 83, 84, 185, 244, 1, 11, 80, 76, 73, 84, 84, 73, 78, 71, 32, 65, - 80, 4, 24, 2, 80, 82, 43, 84, 2, 241, 158, 19, 5, 69, 80, 79, 78, 68, 2, - 11, 65, 2, 247, 221, 23, 77, 30, 36, 3, 72, 69, 32, 251, 231, 17, 82, 28, - 186, 2, 65, 130, 1, 67, 132, 1, 3, 70, 65, 77, 20, 9, 82, 69, 67, 69, 80, - 84, 73, 86, 69, 30, 87, 172, 22, 12, 77, 65, 82, 82, 89, 73, 78, 71, 32, - 77, 65, 73, 132, 154, 5, 6, 71, 69, 78, 84, 76, 69, 240, 227, 10, 13, 75, - 69, 69, 80, 73, 78, 71, 32, 83, 84, 73, 76, 76, 173, 238, 3, 7, 74, 79, - 89, 79, 85, 83, 32, 6, 58, 82, 185, 188, 11, 8, 66, 89, 83, 77, 65, 76, - 32, 87, 4, 220, 191, 20, 8, 79, 85, 83, 73, 78, 71, 32, 84, 163, 218, 3, - 77, 6, 188, 131, 1, 2, 65, 85, 252, 186, 19, 9, 82, 69, 65, 84, 73, 86, - 69, 32, 72, 161, 212, 1, 9, 76, 73, 78, 71, 73, 78, 71, 32, 70, 2, 207, - 134, 24, 73, 2, 129, 189, 20, 2, 32, 69, 4, 166, 159, 22, 69, 189, 204, - 1, 5, 65, 78, 68, 69, 82, 4, 190, 238, 6, 65, 153, 167, 6, 14, 79, 82, - 75, 32, 79, 78, 32, 84, 72, 69, 32, 68, 69, 67, 222, 1, 236, 1, 2, 71, - 72, 180, 2, 7, 82, 65, 71, 65, 78, 65, 32, 212, 4, 7, 83, 84, 79, 82, 73, - 67, 32, 236, 198, 15, 7, 78, 68, 85, 32, 84, 69, 77, 240, 33, 4, 75, 73, - 78, 71, 218, 249, 1, 66, 169, 180, 4, 8, 80, 80, 79, 80, 79, 84, 65, 77, - 12, 18, 32, 119, 45, 6, 164, 142, 5, 2, 66, 82, 132, 248, 16, 6, 86, 79, - 76, 84, 65, 71, 217, 49, 9, 79, 67, 84, 69, 84, 32, 80, 82, 69, 6, 92, - 11, 83, 80, 69, 69, 68, 32, 84, 82, 65, 73, 78, 249, 206, 5, 6, 72, 69, - 69, 76, 69, 68, 5, 181, 193, 11, 14, 32, 87, 73, 84, 72, 32, 66, 85, 76, - 76, 69, 84, 32, 78, 200, 1, 112, 9, 68, 73, 71, 82, 65, 80, 72, 32, 89, - 20, 7, 76, 69, 84, 84, 69, 82, 32, 154, 173, 1, 86, 215, 207, 20, 73, 2, - 207, 183, 17, 79, 194, 1, 194, 1, 65, 74, 83, 138, 164, 1, 66, 162, 3, - 78, 150, 2, 68, 2, 71, 2, 72, 2, 75, 2, 77, 2, 80, 2, 82, 2, 84, 2, 90, - 126, 87, 46, 89, 174, 209, 22, 86, 234, 36, 69, 2, 73, 2, 79, 3, 85, 7, - 37, 7, 82, 67, 72, 65, 73, 67, 32, 4, 174, 252, 23, 87, 151, 14, 89, 42, - 76, 5, 77, 65, 76, 76, 32, 170, 160, 24, 65, 2, 69, 2, 73, 2, 79, 3, 85, - 32, 230, 169, 1, 87, 46, 89, 226, 179, 5, 75, 206, 157, 17, 84, 234, 36, - 65, 2, 69, 2, 73, 2, 79, 3, 85, 2, 183, 186, 8, 83, 108, 166, 1, 76, 52, - 3, 78, 69, 89, 46, 82, 146, 7, 84, 138, 1, 85, 230, 200, 16, 83, 178, - 219, 2, 67, 220, 198, 3, 6, 77, 79, 84, 72, 69, 84, 134, 167, 1, 79, 155, - 3, 80, 6, 132, 153, 16, 4, 76, 79, 87, 32, 255, 132, 8, 69, 4, 174, 171, - 22, 66, 233, 161, 1, 2, 32, 80, 66, 60, 8, 73, 90, 79, 78, 84, 65, 76, - 32, 153, 6, 2, 83, 69, 60, 218, 1, 66, 110, 76, 152, 1, 17, 79, 78, 69, - 32, 69, 73, 71, 72, 84, 72, 32, 66, 76, 79, 67, 75, 45, 88, 10, 83, 67, - 65, 78, 32, 76, 73, 78, 69, 45, 46, 84, 170, 240, 21, 67, 42, 69, 230, 6, - 77, 150, 1, 82, 247, 2, 90, 6, 44, 5, 76, 65, 67, 75, 32, 255, 225, 23, - 65, 4, 38, 79, 241, 223, 22, 3, 72, 69, 88, 2, 227, 223, 22, 67, 10, 40, - 4, 73, 78, 69, 32, 143, 246, 21, 65, 8, 44, 5, 87, 73, 84, 72, 32, 179, - 246, 21, 69, 6, 26, 84, 219, 247, 21, 70, 4, 250, 247, 21, 72, 243, 91, - 73, 14, 208, 237, 16, 3, 49, 51, 53, 178, 171, 7, 50, 2, 51, 2, 52, 2, - 53, 2, 54, 3, 55, 8, 170, 152, 24, 49, 2, 51, 2, 55, 3, 57, 10, 32, 2, - 65, 66, 223, 250, 21, 82, 8, 26, 85, 223, 249, 21, 32, 6, 33, 6, 76, 65, - 84, 73, 79, 78, 7, 11, 32, 4, 152, 205, 9, 8, 87, 73, 84, 72, 32, 74, 85, - 83, 223, 148, 14, 83, 7, 11, 32, 4, 204, 198, 7, 2, 82, 65, 235, 146, 16, - 70, 10, 26, 32, 171, 138, 23, 69, 8, 86, 80, 128, 134, 19, 5, 66, 69, 86, - 69, 82, 144, 80, 3, 83, 80, 82, 179, 190, 4, 68, 2, 255, 242, 14, 69, 12, - 48, 6, 82, 71, 76, 65, 83, 83, 77, 2, 83, 69, 5, 129, 194, 20, 14, 32, - 87, 73, 84, 72, 32, 70, 76, 79, 87, 73, 78, 71, 32, 9, 11, 32, 6, 88, 8, - 87, 73, 84, 72, 32, 71, 65, 82, 205, 137, 22, 8, 66, 85, 73, 76, 68, 73, - 78, 71, 2, 159, 189, 22, 68, 7, 142, 147, 24, 74, 3, 83, 8, 106, 83, 184, - 252, 22, 11, 78, 68, 82, 69, 68, 32, 80, 79, 73, 78, 84, 176, 13, 2, 71, - 71, 163, 136, 1, 84, 2, 147, 255, 22, 72, 20, 80, 2, 71, 73, 22, 80, 224, - 1, 5, 83, 84, 69, 82, 69, 185, 137, 22, 2, 65, 67, 4, 151, 252, 21, 69, - 12, 60, 3, 72, 69, 78, 221, 160, 4, 6, 79, 68, 73, 65, 83, 84, 11, 34, - 32, 82, 65, 227, 132, 20, 45, 4, 26, 87, 239, 173, 22, 66, 2, 21, 3, 73, - 84, 72, 2, 145, 190, 3, 2, 32, 68, 2, 165, 228, 12, 6, 84, 73, 79, 78, - 32, 80, 2, 217, 249, 22, 2, 83, 73, 210, 5, 172, 1, 3, 67, 69, 32, 152, - 1, 2, 68, 69, 222, 24, 77, 222, 2, 78, 230, 35, 82, 132, 2, 7, 90, 65, - 75, 65, 89, 65, 32, 209, 250, 19, 9, 32, 76, 79, 86, 69, 32, 89, 79, 85, - 8, 114, 67, 132, 169, 11, 18, 72, 79, 67, 75, 69, 89, 32, 83, 84, 73, 67, - 75, 32, 65, 78, 68, 32, 80, 235, 190, 1, 83, 4, 162, 252, 15, 82, 223, - 231, 2, 85, 246, 1, 68, 3, 78, 84, 73, 201, 1, 9, 79, 71, 82, 65, 80, 72, - 73, 67, 32, 8, 64, 4, 67, 65, 76, 32, 105, 8, 70, 73, 67, 65, 84, 73, 79, - 78, 6, 32, 2, 84, 79, 155, 138, 23, 87, 5, 173, 255, 14, 12, 32, 65, 78, - 68, 32, 83, 76, 65, 78, 84, 69, 68, 2, 205, 241, 22, 2, 32, 67, 238, 1, - 208, 2, 11, 65, 78, 78, 79, 84, 65, 84, 73, 79, 78, 32, 242, 3, 67, 72, - 2, 68, 69, 248, 5, 5, 78, 85, 77, 66, 69, 22, 84, 172, 243, 5, 8, 72, 65, - 76, 70, 32, 70, 73, 76, 232, 186, 1, 5, 69, 78, 84, 69, 82, 0, 3, 82, 73, - 83, 24, 5, 76, 69, 86, 69, 76, 188, 143, 9, 5, 86, 65, 82, 73, 65, 250, - 233, 4, 70, 154, 47, 73, 243, 231, 1, 83, 32, 232, 1, 5, 66, 79, 84, 84, - 79, 22, 70, 82, 77, 62, 84, 140, 1, 4, 76, 73, 78, 75, 196, 143, 1, 4, - 83, 69, 67, 79, 182, 165, 6, 79, 172, 135, 6, 6, 82, 69, 86, 69, 82, 83, - 152, 222, 9, 5, 72, 69, 65, 86, 69, 169, 39, 3, 69, 65, 82, 2, 167, 196, - 23, 77, 6, 48, 3, 79, 85, 82, 221, 186, 23, 3, 73, 82, 83, 4, 210, 195, - 23, 84, 27, 32, 4, 36, 3, 73, 68, 68, 223, 155, 23, 65, 2, 195, 189, 13, - 76, 8, 34, 72, 46, 87, 227, 137, 8, 79, 4, 214, 149, 9, 82, 181, 162, 14, - 2, 73, 82, 2, 183, 194, 23, 79, 4, 36, 3, 76, 79, 83, 251, 173, 21, 79, - 2, 249, 193, 23, 3, 73, 78, 71, 36, 104, 20, 83, 67, 82, 73, 80, 84, 73, - 79, 78, 32, 67, 72, 65, 82, 65, 67, 84, 69, 82, 32, 159, 179, 7, 80, 34, - 144, 2, 9, 65, 66, 79, 86, 69, 32, 84, 79, 32, 84, 8, 76, 69, 70, 84, 32, - 84, 79, 32, 76, 5, 79, 86, 69, 82, 76, 20, 2, 83, 85, 246, 253, 14, 82, - 172, 200, 5, 8, 70, 85, 76, 76, 32, 83, 85, 82, 229, 231, 2, 15, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 32, 82, 69, 70, 76, 4, 60, 9, 77, 73, 68, - 68, 76, 69, 32, 65, 78, 247, 221, 21, 66, 2, 199, 206, 21, 68, 4, 168, - 172, 22, 10, 77, 73, 68, 68, 76, 69, 32, 65, 78, 68, 211, 168, 1, 82, 2, - 171, 233, 16, 65, 18, 72, 12, 82, 82, 79, 85, 78, 68, 32, 70, 82, 79, 77, - 32, 247, 189, 17, 66, 16, 82, 76, 232, 211, 11, 3, 85, 80, 80, 250, 135, - 10, 66, 130, 165, 1, 65, 159, 82, 82, 6, 218, 211, 11, 79, 147, 255, 11, - 69, 2, 251, 220, 8, 82, 148, 1, 92, 10, 65, 76, 76, 89, 32, 77, 65, 82, - 75, 32, 41, 9, 69, 76, 69, 71, 82, 65, 80, 72, 32, 10, 162, 137, 22, 70, - 70, 84, 155, 87, 79, 138, 1, 140, 1, 11, 83, 89, 77, 66, 79, 76, 32, 70, - 79, 82, 32, 245, 238, 12, 17, 76, 73, 78, 69, 32, 70, 69, 69, 68, 32, 83, - 69, 80, 65, 82, 65, 84, 136, 1, 182, 1, 65, 58, 68, 200, 2, 5, 72, 79, - 85, 82, 32, 214, 1, 74, 28, 4, 70, 69, 66, 82, 64, 2, 77, 65, 192, 204, - 15, 3, 78, 79, 86, 0, 4, 83, 69, 80, 84, 25, 4, 79, 67, 84, 79, 4, 192, - 139, 20, 3, 85, 71, 85, 165, 142, 2, 2, 80, 82, 64, 44, 3, 65, 89, 32, - 137, 209, 15, 2, 69, 67, 62, 66, 84, 218, 215, 5, 69, 66, 70, 70, 78, 26, - 83, 235, 131, 17, 79, 34, 34, 72, 90, 87, 179, 167, 23, 69, 8, 36, 3, 73, - 82, 84, 163, 133, 22, 82, 6, 26, 89, 163, 161, 22, 69, 5, 203, 202, 22, - 45, 24, 26, 69, 247, 246, 23, 79, 22, 36, 3, 78, 84, 89, 251, 249, 22, - 76, 21, 163, 171, 15, 45, 50, 78, 84, 182, 213, 5, 69, 66, 70, 70, 78, - 26, 83, 142, 173, 16, 90, 223, 86, 79, 20, 42, 87, 146, 215, 5, 72, 207, - 206, 17, 69, 14, 26, 69, 163, 245, 23, 79, 12, 36, 3, 78, 84, 89, 167, - 248, 22, 76, 11, 199, 166, 17, 45, 6, 24, 2, 65, 78, 35, 85, 2, 11, 85, - 2, 215, 174, 17, 65, 4, 210, 221, 23, 78, 143, 5, 76, 4, 222, 209, 23, - 82, 171, 34, 89, 68, 40, 6, 65, 71, 69, 32, 79, 70, 83, 80, 5, 241, 138, - 9, 15, 32, 79, 82, 32, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 65, - 65, 14, 69, 82, 73, 65, 76, 32, 65, 82, 65, 77, 65, 73, 67, 32, 62, 72, - 7, 78, 85, 77, 66, 69, 82, 32, 230, 18, 76, 205, 217, 19, 2, 83, 69, 16, - 26, 84, 211, 207, 15, 79, 10, 154, 191, 11, 87, 250, 147, 1, 69, 131, - 172, 9, 72, 136, 3, 202, 1, 67, 234, 1, 68, 214, 6, 70, 132, 2, 5, 72, - 73, 66, 73, 84, 156, 1, 15, 80, 85, 84, 32, 83, 89, 77, 66, 79, 76, 32, - 70, 79, 82, 32, 206, 1, 83, 236, 5, 2, 84, 69, 206, 8, 86, 171, 130, 10, - 66, 10, 32, 2, 79, 77, 69, 2, 82, 69, 4, 164, 215, 16, 3, 73, 78, 71, - 209, 230, 2, 5, 80, 76, 69, 84, 69, 6, 36, 3, 65, 83, 69, 135, 171, 23, - 77, 4, 34, 32, 181, 188, 10, 2, 83, 32, 2, 185, 191, 11, 8, 70, 79, 78, - 84, 32, 83, 73, 90, 145, 1, 24, 2, 69, 88, 103, 73, 5, 173, 210, 22, 20, - 32, 80, 79, 73, 78, 84, 73, 78, 71, 32, 65, 84, 32, 84, 72, 69, 32, 86, - 73, 69, 138, 1, 72, 8, 67, 32, 83, 73, 89, 65, 81, 32, 197, 144, 18, 4, - 65, 78, 32, 82, 136, 1, 196, 1, 11, 65, 76, 84, 69, 82, 78, 65, 84, 69, - 32, 76, 2, 76, 28, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 100, 7, 78, 85, - 77, 66, 69, 82, 32, 210, 250, 8, 82, 153, 125, 6, 80, 76, 65, 67, 69, 72, - 2, 225, 168, 23, 2, 65, 75, 6, 68, 4, 79, 78, 69, 32, 229, 229, 21, 7, - 84, 72, 82, 69, 69, 32, 81, 4, 186, 227, 21, 72, 47, 81, 122, 212, 1, 10, - 65, 76, 84, 69, 82, 78, 65, 84, 69, 32, 72, 5, 75, 65, 82, 79, 82, 0, 4, - 76, 65, 75, 72, 246, 145, 10, 69, 66, 70, 94, 78, 26, 83, 78, 84, 236, - 135, 5, 8, 80, 82, 69, 70, 73, 88, 69, 68, 199, 41, 79, 6, 26, 84, 147, - 204, 22, 79, 4, 208, 167, 6, 2, 69, 78, 251, 160, 17, 87, 5, 179, 151, - 23, 65, 16, 72, 5, 73, 78, 73, 84, 89, 85, 9, 79, 82, 77, 65, 84, 73, 79, - 78, 32, 5, 45, 9, 32, 78, 69, 71, 65, 84, 69, 68, 32, 2, 173, 175, 8, 4, - 87, 73, 84, 72, 12, 42, 83, 249, 224, 19, 4, 68, 69, 83, 75, 10, 192, - 156, 7, 5, 69, 80, 65, 82, 65, 191, 129, 10, 79, 4, 11, 32, 4, 220, 147, - 23, 15, 65, 82, 65, 66, 73, 67, 32, 70, 79, 82, 77, 32, 83, 72, 65, 1, - 14, 83, 89, 77, 77, 69, 84, 82, 73, 67, 32, 83, 87, 65, 80, 10, 80, 6, - 76, 65, 84, 73, 78, 32, 242, 252, 14, 83, 161, 213, 7, 4, 78, 85, 77, 66, - 6, 64, 6, 67, 65, 80, 73, 84, 65, 0, 4, 83, 77, 65, 76, 27, 76, 2, 21, 3, - 76, 32, 76, 2, 217, 222, 21, 2, 69, 84, 116, 84, 13, 67, 82, 73, 80, 84, - 73, 79, 78, 65, 76, 32, 80, 65, 141, 209, 15, 2, 69, 82, 114, 72, 6, 72, - 76, 65, 86, 73, 32, 225, 1, 7, 82, 84, 72, 73, 65, 78, 32, 54, 48, 7, 76, - 69, 84, 84, 69, 82, 32, 191, 3, 78, 38, 130, 180, 10, 84, 222, 119, 65, - 22, 68, 34, 76, 22, 77, 50, 87, 254, 169, 4, 71, 90, 90, 34, 83, 66, 89, - 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, 223, 105, 80, - 60, 22, 76, 251, 1, 78, 44, 11, 69, 44, 29, 5, 84, 84, 69, 82, 32, 44, - 146, 178, 10, 84, 242, 119, 68, 34, 76, 50, 81, 214, 205, 1, 82, 142, - 220, 2, 65, 50, 71, 90, 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, 75, - 174, 81, 66, 170, 225, 4, 78, 134, 2, 87, 218, 103, 80, 171, 4, 77, 16, - 33, 6, 85, 77, 66, 69, 82, 32, 16, 138, 170, 11, 84, 226, 144, 4, 79, - 167, 134, 3, 70, 50, 36, 4, 71, 82, 65, 76, 179, 3, 82, 23, 11, 32, 20, - 58, 65, 140, 1, 5, 87, 73, 84, 72, 32, 159, 183, 21, 69, 4, 96, 6, 86, - 69, 82, 65, 71, 69, 193, 180, 16, 12, 82, 79, 85, 78, 68, 32, 65, 32, 80, - 79, 73, 78, 2, 229, 181, 16, 5, 32, 87, 73, 84, 72, 14, 160, 1, 3, 84, - 73, 77, 20, 2, 85, 78, 248, 242, 6, 16, 76, 69, 70, 84, 87, 65, 82, 68, - 83, 32, 65, 82, 82, 79, 87, 32, 194, 178, 13, 73, 198, 1, 79, 251, 64, - 68, 2, 251, 166, 20, 69, 4, 134, 167, 20, 68, 131, 226, 2, 73, 28, 94, - 76, 232, 1, 7, 83, 69, 67, 84, 73, 79, 78, 146, 7, 82, 128, 130, 12, 2, - 67, 65, 43, 73, 8, 164, 1, 17, 73, 78, 69, 65, 82, 32, 65, 78, 78, 79, - 84, 65, 84, 73, 79, 78, 32, 169, 239, 4, 17, 79, 67, 75, 69, 68, 32, 70, - 69, 77, 65, 76, 69, 32, 65, 78, 68, 32, 6, 156, 171, 8, 3, 65, 78, 67, - 222, 158, 8, 84, 159, 219, 3, 83, 15, 11, 32, 12, 168, 1, 6, 65, 66, 79, - 86, 69, 32, 64, 5, 87, 73, 84, 72, 32, 193, 160, 20, 22, 66, 69, 83, 73, - 68, 69, 32, 65, 78, 68, 32, 74, 79, 73, 78, 69, 68, 32, 87, 73, 84, 72, - 4, 176, 161, 20, 9, 66, 65, 82, 32, 65, 66, 79, 86, 69, 23, 85, 6, 154, - 173, 4, 76, 254, 244, 15, 79, 195, 225, 2, 68, 40, 56, 2, 69, 82, 189, 5, - 7, 73, 83, 73, 66, 76, 69, 32, 34, 48, 3, 83, 69, 32, 225, 2, 4, 84, 69, - 68, 32, 16, 174, 1, 66, 80, 5, 67, 72, 69, 67, 75, 68, 24, 68, 79, 87, - 78, 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 87, 73, 84, 72, 32, - 84, 73, 80, 234, 186, 20, 87, 219, 26, 77, 6, 44, 5, 76, 65, 67, 75, 32, - 251, 238, 21, 85, 4, 146, 146, 22, 68, 227, 27, 83, 4, 252, 212, 20, 8, - 69, 82, 32, 66, 79, 65, 82, 68, 183, 186, 2, 32, 2, 221, 238, 20, 2, 32, - 76, 18, 144, 1, 6, 73, 78, 84, 69, 82, 82, 22, 76, 170, 250, 11, 80, 230, - 184, 4, 69, 244, 198, 1, 2, 79, 72, 204, 158, 2, 4, 85, 78, 68, 69, 183, - 97, 81, 2, 207, 217, 4, 79, 6, 60, 9, 79, 87, 32, 75, 65, 86, 89, 75, 65, - 163, 235, 6, 65, 5, 229, 162, 18, 11, 32, 87, 73, 84, 72, 32, 75, 65, 86, - 89, 75, 6, 38, 84, 178, 194, 19, 80, 223, 89, 83, 2, 159, 181, 16, 73, 4, - 246, 177, 22, 69, 215, 93, 73, 218, 1, 94, 65, 138, 21, 69, 62, 79, 42, - 85, 157, 195, 11, 10, 73, 71, 83, 65, 87, 32, 80, 85, 90, 90, 202, 1, - 120, 5, 67, 75, 45, 79, 45, 32, 7, 80, 65, 78, 69, 83, 69, 32, 184, 2, 7, - 86, 65, 78, 69, 83, 69, 32, 207, 200, 23, 82, 2, 169, 184, 18, 3, 76, 65, - 78, 16, 246, 1, 67, 18, 80, 152, 157, 1, 10, 73, 78, 68, 85, 83, 84, 82, - 73, 65, 76, 236, 229, 3, 3, 66, 65, 78, 134, 174, 3, 68, 220, 143, 11, - 15, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 66, 69, 71, 73, 180, 248, - 1, 3, 71, 79, 66, 169, 109, 2, 79, 71, 2, 207, 32, 65, 2, 165, 145, 13, - 7, 79, 83, 84, 32, 79, 70, 70, 182, 1, 172, 2, 15, 67, 79, 78, 83, 79, - 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 76, 2, 76, 69, 40, 4, 82, 73, 71, - 72, 224, 6, 2, 80, 65, 176, 3, 14, 84, 85, 82, 78, 69, 68, 32, 80, 65, - 68, 65, 32, 80, 73, 88, 5, 83, 73, 71, 78, 32, 144, 1, 11, 86, 79, 87, - 69, 76, 32, 83, 73, 71, 78, 32, 167, 197, 21, 68, 6, 52, 2, 75, 69, 188, - 201, 16, 2, 80, 69, 175, 5, 67, 2, 199, 144, 23, 82, 96, 38, 70, 65, 5, - 84, 84, 69, 82, 32, 2, 41, 8, 84, 32, 82, 69, 82, 69, 78, 71, 2, 219, - 248, 21, 71, 94, 230, 1, 68, 26, 73, 48, 2, 75, 65, 66, 78, 130, 1, 66, - 2, 67, 2, 71, 16, 2, 80, 65, 56, 2, 82, 65, 32, 2, 83, 65, 42, 84, 74, - 74, 218, 178, 21, 65, 142, 138, 2, 72, 2, 76, 2, 77, 2, 87, 2, 89, 186, - 2, 69, 2, 79, 3, 85, 8, 222, 3, 68, 15, 65, 7, 184, 205, 5, 3, 32, 75, - 65, 171, 245, 17, 73, 7, 11, 32, 4, 22, 83, 215, 2, 77, 2, 133, 137, 21, - 2, 65, 83, 14, 36, 2, 71, 65, 90, 89, 167, 1, 65, 7, 33, 6, 32, 76, 69, - 76, 69, 84, 5, 29, 5, 32, 82, 65, 83, 87, 2, 159, 230, 5, 65, 4, 163, 1, - 65, 7, 11, 32, 4, 154, 1, 77, 153, 188, 23, 3, 67, 69, 82, 5, 237, 204, - 16, 3, 32, 65, 71, 7, 17, 2, 32, 77, 4, 70, 85, 71, 65, 8, 18, 65, 55, - 84, 5, 17, 2, 32, 77, 2, 11, 85, 2, 171, 154, 23, 82, 4, 11, 65, 5, 11, - 32, 2, 11, 77, 2, 11, 65, 2, 11, 72, 2, 237, 185, 17, 2, 65, 80, 28, 40, - 3, 68, 65, 32, 165, 3, 2, 78, 71, 24, 174, 1, 65, 90, 76, 86, 80, 244, - 150, 7, 10, 84, 73, 82, 84, 65, 32, 84, 85, 77, 69, 158, 135, 12, 87, - 168, 199, 2, 7, 73, 83, 69, 78, 45, 73, 83, 169, 211, 1, 3, 77, 65, 68, - 6, 44, 3, 68, 69, 71, 177, 169, 22, 2, 78, 68, 5, 11, 32, 2, 193, 246, - 22, 2, 65, 68, 6, 38, 85, 165, 185, 23, 3, 73, 78, 71, 4, 240, 200, 18, - 2, 78, 71, 163, 250, 3, 72, 4, 38, 73, 205, 193, 18, 3, 65, 78, 71, 2, - 181, 197, 16, 3, 83, 69, 76, 4, 140, 153, 13, 5, 82, 65, 78, 71, 75, 251, - 209, 9, 75, 10, 108, 5, 67, 69, 67, 65, 75, 248, 205, 5, 3, 87, 73, 71, - 202, 246, 10, 76, 249, 228, 2, 5, 80, 65, 78, 89, 65, 5, 157, 176, 18, 3, - 32, 84, 69, 18, 116, 4, 83, 85, 75, 85, 42, 84, 64, 4, 87, 85, 76, 85, - 142, 195, 16, 80, 137, 224, 1, 7, 68, 73, 82, 71, 65, 32, 77, 5, 225, - 190, 22, 5, 32, 77, 69, 78, 68, 6, 26, 65, 203, 196, 16, 79, 4, 178, 196, - 16, 82, 187, 162, 6, 76, 5, 25, 4, 32, 77, 69, 76, 2, 151, 180, 23, 73, - 4, 36, 3, 76, 76, 89, 203, 239, 19, 65, 2, 167, 210, 19, 70, 4, 192, 132, - 22, 2, 89, 83, 191, 98, 73, 6, 196, 200, 14, 2, 71, 71, 194, 135, 5, 80, - 191, 199, 3, 78, 188, 25, 74, 65, 178, 78, 69, 218, 1, 72, 162, 50, 73, + 65, 73, 132, 145, 19, 3, 74, 69, 67, 244, 152, 2, 8, 86, 69, 82, 71, 82, + 69, 69, 78, 167, 199, 5, 80, 22, 38, 82, 218, 248, 26, 83, 135, 65, 71, + 19, 30, 32, 137, 1, 2, 84, 72, 6, 88, 3, 79, 70, 32, 181, 232, 4, 13, 87, + 73, 84, 72, 32, 72, 69, 65, 82, 73, 78, 71, 32, 4, 132, 196, 11, 2, 77, + 65, 195, 227, 6, 82, 11, 17, 2, 32, 71, 8, 44, 5, 76, 79, 66, 69, 32, + 239, 165, 25, 82, 6, 70, 65, 173, 242, 21, 11, 69, 85, 82, 79, 80, 69, + 45, 65, 70, 82, 73, 4, 244, 142, 10, 4, 77, 69, 82, 73, 193, 154, 2, 11, + 83, 73, 65, 45, 65, 85, 83, 84, 82, 65, 76, 2, 187, 178, 2, 79, 176, 17, + 112, 18, 89, 80, 84, 73, 65, 78, 32, 72, 73, 69, 82, 79, 71, 76, 89, 80, + 72, 32, 202, 212, 2, 69, 179, 135, 26, 71, 172, 17, 146, 3, 65, 178, 4, + 66, 52, 2, 67, 48, 224, 1, 2, 68, 48, 170, 4, 69, 178, 3, 70, 164, 4, 2, + 71, 48, 210, 3, 72, 214, 1, 73, 238, 2, 76, 122, 77, 222, 8, 78, 210, 5, + 79, 140, 5, 2, 80, 48, 120, 2, 82, 48, 232, 1, 2, 83, 48, 190, 3, 84, + 220, 2, 2, 85, 48, 250, 2, 86, 134, 5, 87, 236, 2, 3, 88, 48, 48, 88, 3, + 89, 48, 48, 84, 2, 90, 48, 188, 217, 3, 3, 75, 48, 48, 129, 151, 15, 3, + 81, 48, 48, 228, 1, 30, 48, 133, 3, 2, 65, 48, 160, 1, 86, 48, 98, 49, + 102, 52, 166, 55, 51, 150, 248, 20, 55, 198, 232, 1, 50, 2, 53, 3, 54, + 24, 170, 68, 54, 198, 129, 24, 53, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, + 2, 55, 2, 56, 3, 57, 24, 142, 197, 24, 52, 2, 55, 242, 145, 4, 48, 2, 49, + 2, 50, 2, 51, 2, 53, 2, 54, 2, 56, 3, 57, 28, 170, 196, 24, 48, 2, 50, 2, + 51, 2, 53, 242, 145, 4, 49, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 68, 46, + 48, 246, 54, 51, 246, 223, 22, 49, 3, 50, 22, 210, 65, 55, 182, 147, 28, + 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 26, 148, 9, 4, 69, + 71, 73, 78, 185, 25, 2, 48, 48, 56, 34, 48, 90, 49, 155, 245, 8, 50, 24, + 230, 39, 50, 242, 171, 28, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, + 3, 57, 22, 142, 193, 24, 48, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 2, 55, 2, 56, 3, 57, 184, 1, 70, 48, 94, 51, 102, 52, 102, 53, + 106, 54, 194, 29, 50, 231, 242, 22, 49, 20, 222, 191, 24, 56, 242, 145, + 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 24, 130, 191, 24, + 49, 2, 52, 242, 145, 4, 48, 2, 50, 2, 51, 2, 53, 2, 54, 2, 55, 2, 56, 3, + 57, 24, 158, 190, 24, 54, 2, 56, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 55, 3, 57, 42, 214, 60, 48, 230, 128, 24, 50, 2, 52, 242, + 145, 4, 49, 2, 51, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 32, 194, 60, 55, + 130, 146, 28, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 94, 30, 48, + 189, 2, 2, 78, 68, 88, 38, 48, 94, 50, 102, 51, 215, 7, 49, 22, 186, 187, + 24, 56, 2, 57, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, + 24, 222, 186, 24, 48, 2, 56, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 2, 55, 3, 57, 18, 250, 185, 24, 52, 242, 145, 4, 48, 2, 49, 2, 50, + 2, 51, 2, 54, 2, 55, 3, 56, 6, 11, 32, 6, 136, 183, 5, 6, 87, 65, 76, 76, + 69, 68, 210, 19, 69, 247, 225, 20, 83, 132, 1, 42, 48, 133, 9, 5, 85, 76, + 76, 32, 66, 130, 1, 54, 48, 94, 49, 102, 51, 102, 52, 102, 53, 215, 1, + 50, 20, 230, 183, 24, 49, 242, 145, 4, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, + 55, 2, 56, 3, 57, 22, 138, 183, 24, 51, 242, 145, 4, 48, 2, 49, 2, 50, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 26, 166, 182, 24, 49, 2, 55, 2, + 56, 242, 145, 4, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 57, 26, 194, + 181, 24, 53, 2, 54, 2, 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 52, + 2, 56, 3, 57, 14, 222, 26, 49, 242, 171, 28, 48, 2, 50, 3, 51, 128, 1, + 62, 48, 98, 49, 102, 51, 102, 52, 210, 27, 50, 255, 201, 8, 53, 24, 166, + 50, 55, 198, 129, 24, 54, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 56, 3, 57, 22, 138, 179, 24, 49, 242, 145, 4, 48, 2, 50, 2, 51, 2, 52, 2, + 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, 166, 178, 24, 54, 2, 55, 242, 145, 4, + 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 56, 3, 57, 24, 194, 177, 24, + 51, 2, 53, 242, 145, 4, 48, 2, 49, 2, 50, 2, 52, 2, 54, 2, 55, 2, 56, 3, + 57, 24, 80, 2, 48, 48, 84, 4, 65, 76, 70, 32, 161, 40, 7, 79, 82, 73, 90, + 79, 78, 84, 18, 138, 176, 24, 54, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, + 2, 53, 2, 55, 3, 56, 4, 22, 66, 255, 42, 76, 2, 191, 241, 16, 76, 52, 58, + 48, 181, 1, 9, 78, 83, 69, 82, 84, 32, 65, 84, 32, 38, 18, 48, 95, 49, + 22, 186, 174, 24, 53, 2, 57, 242, 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 54, + 2, 55, 3, 56, 16, 222, 173, 24, 48, 2, 49, 242, 145, 4, 50, 2, 51, 2, 52, + 3, 53, 14, 68, 6, 66, 79, 84, 84, 79, 77, 0, 3, 84, 79, 80, 199, 219, 19, + 77, 7, 11, 32, 4, 162, 174, 27, 69, 249, 8, 2, 83, 84, 22, 32, 2, 48, 48, + 167, 223, 15, 79, 20, 250, 171, 24, 50, 2, 54, 242, 145, 4, 49, 2, 51, 2, + 52, 2, 53, 2, 55, 3, 56, 164, 1, 118, 48, 128, 4, 15, 79, 68, 73, 70, 73, + 69, 82, 32, 68, 65, 77, 65, 71, 69, 68, 129, 246, 24, 5, 73, 82, 82, 79, + 82, 132, 1, 42, 48, 98, 49, 106, 50, 102, 51, 107, 52, 24, 182, 40, 49, + 198, 129, 24, 51, 242, 145, 4, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, + 57, 44, 138, 41, 50, 146, 128, 24, 48, 2, 53, 2, 54, 2, 55, 242, 145, 4, + 49, 2, 51, 2, 52, 2, 56, 3, 57, 26, 178, 168, 24, 50, 2, 52, 2, 56, 242, + 145, 4, 48, 2, 49, 2, 51, 2, 53, 2, 54, 2, 55, 3, 57, 26, 138, 38, 51, + 198, 129, 24, 49, 242, 145, 4, 48, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, + 56, 3, 57, 12, 230, 166, 24, 48, 242, 145, 4, 49, 2, 50, 2, 51, 3, 52, + 31, 25, 4, 32, 65, 84, 32, 28, 96, 6, 66, 79, 84, 84, 79, 77, 120, 5, 83, + 84, 65, 82, 84, 68, 3, 84, 79, 80, 207, 165, 27, 69, 11, 11, 32, 8, 56, + 5, 83, 84, 65, 82, 84, 186, 1, 65, 139, 165, 27, 69, 5, 129, 2, 8, 32, + 65, 78, 68, 32, 84, 79, 80, 7, 29, 5, 32, 65, 78, 68, 32, 4, 222, 198, + 24, 66, 147, 246, 2, 84, 11, 11, 32, 8, 54, 65, 20, 5, 83, 84, 65, 82, + 84, 247, 164, 27, 69, 2, 73, 2, 78, 68, 5, 53, 11, 32, 65, 78, 68, 32, + 66, 79, 84, 84, 79, 77, 2, 235, 216, 19, 32, 194, 1, 50, 48, 128, 2, 2, + 76, 48, 229, 1, 2, 85, 48, 98, 58, 49, 98, 51, 194, 14, 50, 150, 6, 52, + 247, 221, 22, 48, 24, 146, 32, 56, 182, 147, 28, 48, 2, 49, 2, 50, 2, 51, + 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 28, 246, 160, 24, 51, 2, 52, 2, 53, 2, + 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 54, 2, 56, 3, 57, 44, 34, 48, 94, + 49, 163, 138, 21, 50, 20, 238, 159, 24, 53, 242, 145, 4, 49, 2, 50, 2, + 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 22, 146, 159, 24, 55, 242, 145, 4, + 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 52, 34, 49, + 102, 50, 251, 238, 22, 48, 26, 138, 158, 24, 48, 2, 49, 2, 56, 242, 145, + 4, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 8, 166, 157, 24, 50, + 242, 145, 4, 48, 3, 49, 152, 1, 50, 48, 149, 254, 18, 6, 86, 69, 82, 76, + 65, 89, 150, 1, 66, 48, 154, 1, 49, 138, 1, 50, 102, 51, 106, 53, 227, + 235, 22, 52, 34, 90, 54, 162, 155, 24, 49, 2, 53, 242, 145, 4, 50, 2, 51, + 2, 52, 2, 55, 2, 56, 3, 57, 15, 142, 173, 28, 65, 2, 66, 2, 67, 2, 68, 2, + 69, 3, 70, 28, 98, 48, 130, 154, 24, 57, 242, 145, 4, 49, 2, 50, 2, 51, + 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 9, 238, 171, 28, 65, 2, 66, 3, 67, 28, + 218, 153, 24, 48, 2, 52, 2, 53, 2, 57, 242, 145, 4, 49, 2, 50, 2, 51, 2, + 54, 2, 55, 3, 56, 32, 134, 23, 54, 242, 129, 24, 48, 2, 51, 242, 145, 4, + 49, 2, 50, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 8, 202, 22, 48, 183, 147, + 28, 49, 26, 26, 48, 251, 194, 8, 49, 22, 210, 151, 24, 49, 2, 51, 242, + 145, 4, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 68, 34, 48, 98, 49, + 199, 233, 22, 50, 24, 142, 21, 51, 198, 129, 24, 50, 242, 145, 4, 49, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, 242, 149, 24, 48, 2, 54, 242, + 145, 4, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 108, 50, 48, + 94, 49, 106, 50, 98, 51, 175, 179, 19, 52, 22, 218, 148, 24, 50, 2, 54, + 242, 145, 4, 49, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 26, 186, 18, + 52, 198, 129, 24, 55, 242, 145, 4, 48, 2, 49, 2, 50, 2, 51, 2, 53, 2, 54, + 2, 56, 3, 57, 24, 210, 17, 54, 182, 147, 28, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 55, 2, 56, 3, 57, 22, 182, 146, 24, 53, 242, 145, 4, 48, 2, + 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 90, 34, 48, 249, 12, + 3, 65, 76, 76, 88, 42, 48, 94, 49, 102, 51, 151, 227, 22, 50, 26, 130, + 145, 24, 51, 2, 55, 2, 56, 2, 57, 242, 145, 4, 49, 2, 50, 2, 52, 2, 53, + 3, 54, 24, 166, 144, 24, 49, 2, 54, 242, 145, 4, 48, 2, 50, 2, 51, 2, 52, + 2, 53, 2, 55, 2, 56, 3, 57, 18, 194, 143, 24, 50, 2, 51, 242, 145, 4, 48, + 2, 49, 2, 52, 2, 53, 3, 54, 94, 50, 48, 90, 50, 102, 51, 102, 52, 247, + 223, 22, 49, 22, 254, 12, 54, 182, 147, 28, 49, 2, 50, 2, 51, 2, 52, 2, + 53, 2, 55, 2, 56, 3, 57, 24, 234, 141, 24, 51, 2, 57, 242, 145, 4, 48, 2, + 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 22, 134, 141, 24, 50, 242, + 145, 4, 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 6, + 146, 158, 28, 48, 2, 49, 3, 50, 158, 1, 42, 48, 185, 4, 5, 69, 82, 84, + 73, 67, 156, 1, 62, 48, 98, 49, 98, 50, 210, 1, 51, 253, 135, 24, 2, 52, + 48, 42, 198, 9, 55, 98, 49, 230, 128, 24, 50, 242, 145, 4, 51, 2, 52, 2, + 53, 2, 54, 2, 56, 3, 57, 32, 186, 8, 49, 46, 50, 182, 147, 28, 48, 2, 51, + 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 50, 98, 48, 234, 136, 24, 51, + 2, 56, 2, 57, 242, 145, 4, 49, 2, 50, 2, 52, 2, 53, 2, 54, 3, 55, 27, + 214, 154, 28, 65, 2, 66, 2, 67, 2, 68, 2, 69, 2, 70, 2, 71, 2, 72, 2, 73, + 2, 74, 2, 75, 3, 76, 28, 250, 135, 24, 48, 2, 49, 2, 51, 2, 55, 242, 145, + 4, 50, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 2, 137, 234, 23, 2, 65, 76, 66, + 34, 48, 161, 2, 3, 73, 68, 69, 64, 26, 48, 94, 49, 103, 50, 22, 186, 134, + 24, 51, 2, 57, 242, 145, 4, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, + 28, 222, 133, 24, 48, 2, 52, 2, 55, 2, 56, 242, 145, 4, 49, 2, 50, 2, 51, + 2, 53, 2, 54, 3, 57, 14, 250, 132, 24, 52, 242, 145, 4, 48, 2, 49, 2, 50, + 2, 51, 3, 53, 2, 17, 2, 32, 76, 2, 203, 183, 15, 79, 24, 202, 2, 52, 198, + 129, 24, 54, 2, 56, 242, 145, 4, 49, 2, 50, 2, 51, 2, 53, 3, 55, 18, 182, + 131, 24, 49, 242, 145, 4, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, + 82, 22, 48, 167, 1, 49, 34, 90, 50, 46, 51, 198, 129, 24, 52, 2, 53, 242, + 145, 4, 49, 2, 54, 2, 55, 2, 56, 3, 57, 11, 222, 147, 28, 65, 2, 66, 2, + 67, 3, 68, 7, 178, 147, 28, 65, 3, 66, 48, 66, 53, 86, 54, 130, 146, 28, + 48, 2, 49, 2, 50, 2, 51, 3, 52, 21, 210, 146, 28, 65, 2, 66, 2, 67, 2, + 68, 2, 69, 2, 70, 2, 71, 2, 72, 3, 73, 19, 254, 145, 28, 65, 2, 66, 2, + 67, 2, 68, 2, 69, 2, 70, 2, 71, 3, 72, 18, 26, 32, 211, 233, 15, 72, 16, + 70, 80, 124, 5, 82, 65, 89, 83, 32, 226, 152, 3, 84, 131, 223, 22, 83, 8, + 222, 152, 3, 79, 209, 190, 16, 22, 69, 84, 65, 76, 76, 69, 68, 32, 79, + 85, 84, 76, 73, 78, 69, 68, 32, 66, 76, 65, 67, 75, 4, 252, 245, 18, 2, + 73, 78, 1, 3, 79, 85, 84, 160, 1, 132, 1, 13, 66, 65, 83, 65, 78, 32, 76, + 69, 84, 84, 69, 82, 32, 166, 3, 69, 176, 4, 7, 89, 77, 65, 73, 67, 32, + 76, 199, 134, 28, 70, 80, 230, 1, 71, 78, 76, 34, 78, 50, 82, 210, 254, + 25, 69, 166, 140, 1, 67, 2, 68, 2, 75, 2, 83, 2, 84, 2, 90, 206, 105, 66, + 2, 70, 2, 72, 2, 74, 2, 77, 2, 80, 2, 81, 2, 86, 2, 88, 214, 22, 65, 2, + 73, 2, 79, 2, 85, 3, 89, 8, 38, 72, 182, 245, 27, 74, 215, 22, 69, 4, + 190, 182, 25, 65, 203, 213, 2, 69, 4, 142, 245, 27, 76, 215, 22, 69, 8, + 238, 244, 27, 68, 2, 74, 214, 22, 65, 3, 69, 4, 190, 244, 27, 82, 215, + 22, 69, 32, 96, 5, 67, 84, 82, 73, 67, 160, 1, 7, 77, 69, 78, 84, 32, 79, + 70, 238, 252, 26, 80, 135, 83, 86, 10, 26, 32, 131, 151, 24, 65, 8, 98, + 80, 232, 212, 17, 2, 84, 79, 176, 246, 8, 9, 76, 73, 71, 72, 84, 32, 66, + 85, 76, 187, 33, 65, 2, 11, 76, 2, 175, 136, 28, 85, 19, 11, 32, 16, 72, + 5, 87, 73, 84, 72, 32, 153, 214, 16, 7, 79, 80, 69, 78, 73, 78, 71, 12, + 130, 1, 76, 32, 12, 84, 87, 79, 32, 72, 79, 82, 73, 90, 79, 78, 84, 146, + 225, 19, 86, 226, 182, 4, 85, 142, 61, 79, 175, 177, 2, 68, 2, 245, 222, + 25, 3, 79, 78, 71, 2, 173, 219, 14, 7, 65, 76, 32, 83, 84, 82, 79, 46, + 238, 175, 4, 69, 165, 206, 15, 15, 73, 71, 65, 84, 85, 82, 69, 32, 90, + 65, 89, 73, 78, 45, 89, 53, 48, 4, 79, 74, 73, 32, 218, 2, 80, 163, 3, + 32, 18, 164, 1, 10, 67, 79, 77, 80, 79, 78, 69, 78, 84, 32, 109, 26, 77, + 79, 68, 73, 70, 73, 69, 82, 32, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, + 75, 32, 84, 89, 80, 69, 45, 8, 244, 132, 15, 2, 82, 69, 12, 5, 67, 85, + 82, 76, 89, 0, 5, 87, 72, 73, 84, 69, 185, 207, 2, 2, 66, 65, 10, 216, + 219, 20, 2, 49, 45, 194, 167, 7, 51, 2, 52, 2, 53, 3, 54, 26, 44, 3, 84, + 89, 32, 149, 251, 3, 2, 72, 65, 24, 82, 78, 60, 3, 80, 65, 71, 20, 3, 83, + 69, 84, 209, 189, 27, 4, 68, 79, 67, 85, 8, 36, 3, 79, 84, 69, 187, 147, + 24, 69, 7, 251, 162, 13, 32, 4, 191, 247, 25, 69, 11, 33, 6, 32, 87, 73, + 84, 72, 32, 8, 242, 135, 14, 82, 24, 3, 76, 69, 70, 224, 166, 1, 2, 83, + 77, 255, 159, 9, 79, 38, 86, 32, 64, 2, 68, 32, 214, 1, 81, 20, 6, 86, + 69, 76, 79, 80, 69, 199, 227, 15, 84, 6, 42, 81, 250, 147, 26, 68, 235, + 172, 1, 83, 2, 223, 184, 27, 85, 20, 32, 3, 79, 70, 32, 131, 1, 87, 18, + 88, 3, 80, 82, 79, 254, 232, 20, 71, 56, 2, 83, 69, 166, 71, 77, 30, 84, + 203, 177, 5, 76, 4, 190, 233, 20, 84, 151, 147, 6, 79, 2, 193, 250, 19, + 7, 73, 84, 72, 32, 76, 69, 70, 5, 247, 176, 21, 85, 7, 33, 6, 32, 87, 73, + 84, 72, 32, 4, 42, 76, 153, 254, 23, 4, 68, 79, 87, 78, 2, 161, 220, 22, + 4, 73, 71, 72, 84, 6, 154, 252, 27, 76, 2, 77, 3, 84, 46, 28, 2, 65, 76, + 231, 6, 73, 40, 30, 32, 133, 2, 2, 83, 32, 12, 56, 3, 84, 79, 32, 229, + 151, 13, 5, 65, 78, 68, 32, 80, 10, 68, 3, 79, 82, 32, 249, 168, 27, 8, + 66, 89, 32, 68, 69, 70, 73, 78, 8, 64, 3, 80, 82, 69, 28, 3, 83, 85, 67, + 226, 227, 25, 71, 39, 76, 2, 189, 162, 15, 2, 67, 69, 2, 157, 151, 26, 3, + 67, 69, 69, 28, 72, 4, 83, 73, 71, 78, 160, 225, 25, 4, 87, 73, 84, 72, + 199, 199, 1, 67, 25, 11, 32, 22, 42, 65, 201, 1, 5, 87, 73, 84, 72, 32, + 12, 112, 5, 66, 79, 86, 69, 32, 65, 19, 78, 68, 32, 83, 76, 65, 78, 84, + 69, 68, 32, 80, 65, 82, 65, 76, 76, 69, 76, 8, 182, 143, 21, 80, 210, 5, + 84, 146, 189, 2, 76, 171, 131, 3, 82, 5, 239, 243, 6, 32, 10, 160, 1, 4, + 66, 85, 77, 80, 20, 7, 73, 78, 70, 73, 78, 73, 84, 20, 18, 84, 87, 79, + 32, 68, 79, 84, 83, 32, 65, 66, 79, 86, 69, 32, 65, 78, 68, 211, 162, 15, + 68, 2, 191, 248, 26, 89, 4, 155, 211, 25, 89, 2, 17, 2, 32, 84, 2, 187, + 195, 25, 87, 6, 80, 7, 86, 65, 76, 69, 78, 84, 32, 137, 147, 21, 7, 65, + 78, 71, 85, 76, 65, 82, 4, 48, 6, 87, 73, 84, 72, 32, 70, 251, 212, 27, + 84, 2, 11, 79, 2, 237, 248, 2, 2, 85, 82, 20, 152, 1, 11, 82, 79, 82, 45, + 66, 65, 82, 82, 69, 68, 32, 236, 166, 5, 7, 73, 83, 32, 70, 79, 82, 77, + 161, 202, 7, 9, 65, 83, 69, 32, 84, 79, 32, 84, 72, 12, 140, 224, 5, 4, + 87, 72, 73, 84, 13, 5, 66, 76, 65, 67, 75, 10, 58, 67, 20, 6, 84, 73, 77, + 65, 84, 69, 155, 241, 27, 65, 5, 211, 167, 26, 65, 4, 210, 219, 26, 68, + 199, 149, 1, 83, 154, 8, 60, 7, 72, 73, 79, 80, 73, 67, 32, 178, 240, 27, + 66, 3, 88, 150, 8, 204, 1, 2, 67, 79, 232, 1, 7, 78, 85, 77, 66, 69, 82, + 32, 114, 80, 54, 83, 156, 24, 11, 84, 79, 78, 65, 76, 32, 77, 65, 82, 75, + 32, 230, 135, 19, 68, 158, 246, 5, 70, 82, 81, 173, 150, 2, 4, 87, 79, + 82, 68, 10, 26, 77, 215, 158, 27, 76, 8, 52, 7, 66, 73, 78, 73, 78, 71, + 32, 211, 235, 27, 77, 6, 60, 11, 71, 69, 77, 73, 78, 65, 84, 73, 79, 78, + 32, 51, 86, 4, 44, 5, 65, 78, 68, 32, 86, 239, 171, 27, 77, 2, 145, 140, + 24, 4, 79, 87, 69, 76, 22, 66, 84, 134, 144, 22, 72, 238, 234, 3, 69, 30, + 70, 42, 78, 39, 83, 8, 130, 206, 16, 69, 158, 174, 9, 72, 27, 87, 4, 202, + 119, 65, 145, 164, 26, 5, 82, 69, 70, 65, 67, 198, 7, 50, 69, 37, 8, 89, + 76, 76, 65, 66, 76, 69, 32, 4, 146, 156, 24, 77, 223, 229, 2, 67, 194, 7, + 210, 1, 66, 90, 67, 246, 1, 68, 186, 1, 70, 90, 71, 214, 2, 72, 162, 1, + 75, 102, 77, 90, 78, 90, 80, 138, 2, 81, 174, 1, 82, 86, 83, 210, 1, 84, + 122, 74, 2, 76, 138, 1, 87, 2, 89, 66, 88, 134, 1, 90, 95, 86, 38, 194, + 12, 87, 230, 8, 66, 134, 194, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, + 73, 3, 85, 78, 94, 67, 254, 15, 72, 250, 197, 23, 65, 2, 79, 210, 209, 3, + 69, 234, 61, 87, 186, 2, 73, 3, 85, 42, 70, 72, 174, 213, 23, 65, 210, + 209, 3, 69, 162, 64, 73, 2, 79, 3, 85, 28, 166, 19, 72, 134, 194, 23, 65, + 210, 209, 3, 69, 162, 64, 73, 2, 79, 3, 85, 60, 94, 68, 214, 14, 90, 174, + 197, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 30, + 210, 14, 72, 174, 197, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, + 2, 73, 3, 85, 24, 190, 8, 87, 234, 202, 23, 65, 210, 209, 3, 69, 234, 61, + 89, 186, 2, 73, 2, 79, 3, 85, 118, 142, 1, 85, 226, 7, 71, 232, 3, 7, 76, + 79, 84, 84, 65, 76, 32, 158, 2, 87, 218, 1, 89, 134, 194, 23, 65, 2, 79, + 210, 209, 3, 69, 163, 64, 73, 39, 29, 5, 82, 65, 71, 69, 32, 36, 74, 66, + 2, 70, 2, 77, 2, 80, 46, 71, 2, 75, 2, 81, 247, 140, 12, 72, 4, 11, 87, + 4, 226, 203, 27, 69, 215, 22, 73, 6, 11, 87, 6, 234, 161, 27, 69, 163, + 64, 73, 52, 70, 72, 182, 207, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, + 73, 3, 85, 36, 202, 4, 87, 230, 8, 89, 134, 194, 23, 65, 210, 209, 3, 69, + 162, 64, 73, 2, 79, 3, 85, 64, 250, 4, 88, 134, 6, 87, 218, 1, 89, 134, + 194, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, 85, 26, 142, 3, 87, + 234, 202, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 89, 186, 2, 73, 3, 85, + 36, 166, 7, 89, 250, 197, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, + 186, 2, 73, 3, 85, 56, 82, 72, 142, 1, 87, 234, 202, 23, 65, 2, 79, 210, + 209, 3, 69, 162, 64, 73, 3, 85, 32, 74, 65, 170, 203, 23, 79, 210, 209, + 3, 69, 234, 61, 87, 186, 2, 73, 3, 85, 19, 160, 9, 8, 82, 89, 78, 71, 69, + 65, 76, 32, 247, 211, 27, 65, 8, 182, 156, 27, 69, 162, 64, 65, 3, 73, + 64, 94, 72, 134, 6, 87, 218, 1, 89, 134, 194, 23, 65, 2, 79, 210, 209, 3, + 69, 162, 64, 73, 3, 85, 24, 130, 6, 87, 222, 195, 23, 65, 210, 209, 3, + 69, 162, 64, 73, 2, 79, 3, 85, 20, 146, 201, 23, 65, 2, 79, 210, 209, 3, + 69, 234, 61, 87, 2, 89, 186, 2, 73, 3, 85, 74, 102, 69, 226, 1, 72, 170, + 3, 90, 78, 83, 134, 194, 23, 65, 2, 79, 186, 143, 4, 87, 186, 2, 73, 3, + 85, 13, 56, 8, 66, 65, 84, 66, 69, 73, 84, 32, 143, 217, 27, 69, 8, 174, + 223, 22, 66, 2, 70, 2, 77, 3, 80, 80, 118, 72, 76, 2, 84, 72, 62, 90, + 162, 2, 83, 210, 194, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, 186, + 2, 73, 3, 85, 18, 246, 197, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, + 186, 2, 73, 3, 85, 12, 250, 150, 27, 69, 234, 61, 65, 186, 2, 73, 2, 79, + 3, 85, 16, 238, 196, 23, 65, 2, 79, 210, 209, 3, 69, 162, 64, 73, 3, 85, + 40, 82, 87, 218, 1, 89, 134, 194, 23, 65, 2, 79, 210, 209, 3, 69, 162, + 64, 73, 3, 85, 10, 218, 195, 23, 65, 210, 209, 3, 69, 163, 64, 73, 48, + 90, 72, 78, 90, 134, 194, 23, 65, 2, 79, 210, 209, 3, 69, 234, 61, 87, + 186, 2, 73, 3, 85, 16, 206, 194, 23, 65, 210, 209, 3, 69, 234, 61, 87, + 186, 2, 73, 2, 79, 3, 85, 14, 130, 194, 23, 65, 210, 209, 3, 69, 162, 64, + 73, 2, 79, 3, 85, 20, 130, 1, 68, 74, 72, 30, 75, 42, 82, 0, 7, 83, 72, + 79, 82, 84, 32, 82, 220, 147, 4, 3, 67, 72, 73, 177, 136, 23, 3, 89, 73, + 90, 6, 48, 4, 69, 82, 69, 84, 205, 200, 26, 2, 73, 70, 5, 17, 2, 45, 72, + 2, 205, 156, 27, 2, 73, 68, 4, 152, 200, 26, 2, 69, 78, 163, 2, 85, 2, + 137, 162, 4, 3, 73, 75, 82, 12, 96, 2, 82, 79, 244, 155, 11, 3, 78, 79, + 77, 181, 168, 15, 9, 76, 69, 82, 32, 67, 79, 78, 83, 84, 8, 92, 5, 80, + 69, 65, 78, 32, 248, 152, 24, 8, 45, 67, 85, 82, 82, 69, 78, 67, 215, + 175, 2, 32, 4, 202, 142, 4, 67, 19, 80, 50, 30, 67, 102, 80, 187, 1, 84, + 6, 60, 9, 76, 65, 77, 65, 84, 73, 79, 78, 32, 243, 181, 26, 69, 4, 222, + 249, 24, 81, 187, 147, 2, 77, 10, 96, 7, 76, 79, 83, 73, 79, 78, 32, 157, + 144, 27, 11, 82, 69, 83, 83, 73, 79, 78, 76, 69, 83, 83, 8, 136, 220, 11, + 4, 70, 82, 65, 77, 197, 161, 15, 8, 65, 84, 32, 72, 79, 82, 73, 90, 34, + 98, 82, 209, 189, 21, 18, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, + 45, 73, 78, 68, 73, 67, 14, 140, 1, 12, 69, 77, 69, 76, 89, 32, 72, 69, + 65, 86, 89, 32, 241, 244, 25, 16, 65, 84, 69, 82, 82, 69, 83, 84, 82, 73, + 65, 76, 32, 65, 76, 73, 12, 50, 83, 238, 176, 25, 70, 234, 2, 87, 203, + 11, 71, 4, 254, 177, 25, 65, 43, 73, 7, 226, 178, 19, 71, 195, 151, 8, + 83, 152, 4, 142, 1, 65, 130, 19, 69, 190, 1, 73, 134, 8, 76, 138, 6, 79, + 142, 7, 82, 130, 5, 85, 228, 193, 20, 2, 86, 83, 242, 203, 4, 83, 199, + 140, 2, 70, 92, 122, 67, 178, 15, 76, 176, 2, 2, 88, 32, 170, 148, 3, 77, + 176, 250, 5, 2, 82, 83, 140, 251, 1, 2, 84, 72, 203, 230, 9, 73, 70, 72, + 2, 69, 32, 156, 179, 16, 4, 83, 73, 77, 73, 165, 206, 4, 2, 84, 79, 66, + 226, 1, 83, 160, 1, 4, 87, 73, 84, 72, 172, 128, 13, 2, 80, 65, 252, 136, + 2, 2, 77, 65, 164, 162, 11, 13, 84, 72, 82, 79, 87, 73, 78, 71, 32, 65, + 32, 75, 73, 201, 1, 14, 72, 79, 76, 68, 73, 78, 71, 32, 66, 65, 67, 75, + 32, 84, 4, 192, 130, 17, 18, 65, 86, 79, 85, 82, 73, 78, 71, 32, 68, 69, + 76, 73, 67, 73, 79, 85, 83, 141, 138, 5, 13, 67, 82, 69, 65, 77, 73, 78, + 71, 32, 73, 78, 32, 70, 54, 38, 32, 245, 158, 24, 3, 79, 85, 84, 52, 196, + 4, 2, 67, 79, 44, 5, 72, 69, 65, 68, 45, 38, 77, 98, 79, 92, 7, 78, 79, + 32, 71, 79, 79, 68, 238, 1, 80, 164, 1, 16, 83, 84, 85, 67, 75, 45, 79, + 85, 84, 32, 84, 79, 78, 71, 85, 69, 110, 84, 204, 183, 1, 9, 66, 65, 71, + 83, 32, 85, 78, 68, 69, 188, 163, 17, 22, 70, 73, 78, 71, 69, 82, 32, 67, + 79, 86, 69, 82, 73, 78, 71, 32, 67, 76, 79, 83, 69, 68, 244, 67, 3, 82, + 79, 76, 180, 231, 1, 13, 76, 79, 79, 75, 32, 79, 70, 32, 84, 82, 73, 85, + 77, 244, 141, 3, 8, 68, 73, 65, 71, 79, 78, 65, 76, 1, 20, 85, 78, 69, + 86, 69, 78, 32, 69, 89, 69, 83, 32, 65, 78, 68, 32, 87, 65, 86, 89, 4, + 252, 4, 3, 87, 66, 79, 203, 159, 19, 76, 2, 225, 175, 22, 4, 66, 65, 78, + 68, 4, 60, 6, 69, 68, 73, 67, 65, 76, 161, 234, 25, 3, 79, 78, 79, 2, + 157, 247, 25, 3, 32, 77, 65, 12, 90, 75, 36, 4, 80, 69, 78, 32, 189, 172, + 20, 10, 78, 69, 32, 69, 89, 69, 66, 82, 79, 87, 2, 217, 158, 22, 4, 32, + 71, 69, 83, 8, 116, 5, 77, 79, 85, 84, 72, 133, 151, 24, 18, 69, 89, 69, + 83, 32, 65, 78, 68, 32, 72, 65, 78, 68, 32, 79, 86, 69, 82, 7, 11, 32, 4, + 236, 133, 10, 3, 86, 79, 77, 145, 155, 9, 5, 65, 78, 68, 32, 67, 6, 132, + 1, 18, 65, 82, 84, 89, 32, 72, 79, 82, 78, 32, 65, 78, 68, 32, 80, 65, + 82, 84, 100, 2, 69, 69, 173, 159, 19, 4, 76, 69, 65, 68, 2, 205, 200, 22, + 2, 89, 32, 7, 29, 5, 32, 65, 78, 68, 32, 4, 36, 3, 87, 73, 78, 207, 159, + 19, 84, 2, 169, 183, 1, 4, 75, 73, 78, 71, 4, 50, 69, 169, 204, 22, 6, + 72, 69, 82, 77, 79, 77, 2, 157, 167, 27, 8, 65, 82, 83, 32, 79, 70, 32, + 74, 10, 34, 76, 237, 162, 22, 2, 65, 70, 8, 84, 13, 73, 78, 71, 32, 68, + 73, 65, 71, 79, 78, 65, 76, 32, 233, 233, 23, 2, 69, 78, 6, 128, 1, 9, + 67, 82, 79, 83, 83, 73, 78, 71, 32, 177, 178, 19, 16, 73, 78, 32, 87, 72, + 73, 84, 69, 32, 67, 73, 82, 67, 76, 69, 32, 4, 140, 140, 16, 3, 82, 73, + 83, 227, 173, 3, 78, 4, 194, 250, 14, 73, 131, 143, 4, 77, 14, 50, 65, + 50, 77, 44, 2, 82, 82, 251, 227, 18, 78, 4, 156, 171, 8, 3, 82, 70, 85, + 199, 232, 9, 84, 4, 152, 243, 8, 2, 73, 78, 231, 173, 7, 65, 4, 144, 243, + 7, 2, 73, 83, 203, 193, 19, 89, 58, 138, 1, 71, 90, 76, 178, 1, 78, 98, + 82, 182, 2, 83, 164, 14, 4, 86, 69, 32, 68, 141, 252, 4, 10, 69, 76, 68, + 32, 72, 79, 67, 75, 69, 89, 6, 48, 4, 85, 82, 69, 32, 221, 132, 26, 2, + 72, 84, 4, 218, 199, 25, 68, 235, 172, 1, 83, 10, 32, 2, 69, 32, 65, 2, + 77, 32, 6, 218, 192, 13, 70, 140, 155, 2, 3, 67, 65, 66, 147, 165, 8, 83, + 4, 52, 4, 80, 82, 79, 74, 149, 153, 20, 3, 70, 82, 65, 2, 227, 209, 15, + 69, 4, 72, 4, 71, 69, 82, 80, 197, 166, 25, 8, 73, 84, 69, 32, 80, 65, + 82, 84, 2, 171, 133, 16, 82, 22, 34, 69, 189, 1, 3, 83, 84, 32, 13, 56, + 2, 32, 69, 68, 4, 87, 79, 82, 75, 227, 176, 15, 67, 4, 198, 184, 13, 78, + 193, 213, 4, 8, 88, 84, 73, 78, 71, 85, 73, 83, 4, 192, 193, 23, 6, 32, + 83, 80, 65, 82, 75, 215, 237, 3, 83, 10, 238, 173, 5, 81, 224, 179, 10, + 8, 83, 84, 82, 79, 78, 71, 32, 73, 223, 225, 6, 80, 10, 38, 72, 141, 221, + 23, 3, 84, 69, 68, 9, 128, 255, 3, 13, 73, 78, 71, 32, 80, 79, 76, 69, + 32, 65, 78, 68, 32, 226, 205, 5, 69, 137, 218, 16, 19, 32, 67, 65, 75, + 69, 32, 87, 73, 84, 72, 32, 83, 87, 73, 82, 76, 32, 68, 69, 46, 50, 65, + 170, 1, 69, 98, 79, 194, 1, 85, 39, 89, 12, 114, 84, 236, 163, 4, 5, 80, + 80, 73, 78, 71, 244, 155, 3, 6, 71, 32, 73, 78, 32, 72, 213, 219, 17, 3, + 77, 73, 78, 6, 242, 217, 8, 32, 174, 199, 11, 66, 135, 241, 5, 78, 4, + 172, 242, 23, 8, 88, 69, 68, 32, 66, 73, 67, 69, 153, 145, 1, 7, 85, 82, + 45, 68, 69, 45, 76, 12, 52, 2, 82, 65, 20, 3, 87, 69, 82, 243, 225, 25, + 80, 5, 251, 161, 26, 76, 7, 17, 2, 32, 80, 4, 58, 85, 185, 199, 24, 8, + 76, 65, 89, 73, 78, 71, 32, 67, 2, 157, 191, 26, 4, 78, 67, 84, 85, 4, + 190, 158, 3, 83, 159, 243, 23, 84, 15, 25, 4, 73, 78, 71, 32, 12, 64, 6, + 83, 65, 85, 67, 69, 82, 134, 140, 10, 68, 207, 131, 10, 69, 9, 11, 32, 6, + 40, 4, 87, 73, 84, 72, 203, 145, 26, 83, 4, 34, 32, 1, 4, 79, 85, 84, 32, + 2, 21, 3, 66, 69, 65, 2, 219, 232, 26, 77, 56, 102, 71, 20, 2, 76, 68, + 68, 2, 79, 84, 22, 82, 142, 2, 85, 232, 146, 23, 2, 78, 68, 191, 210, 3, + 88, 5, 243, 147, 27, 71, 4, 208, 201, 9, 8, 73, 78, 71, 32, 72, 65, 78, + 68, 251, 162, 17, 69, 5, 171, 153, 14, 80, 18, 78, 75, 132, 1, 3, 84, 85, + 78, 238, 215, 20, 77, 222, 192, 4, 32, 179, 116, 67, 8, 80, 10, 32, 65, + 78, 68, 32, 75, 78, 73, 70, 69, 218, 156, 15, 69, 223, 181, 11, 73, 5, + 177, 214, 15, 7, 32, 87, 73, 84, 72, 32, 80, 4, 200, 135, 27, 6, 69, 32, + 67, 79, 79, 75, 179, 27, 65, 22, 26, 82, 175, 182, 23, 78, 20, 38, 32, + 218, 2, 84, 199, 231, 18, 45, 16, 110, 67, 174, 1, 68, 182, 170, 2, 66, + 136, 152, 10, 7, 76, 69, 65, 70, 32, 67, 76, 242, 106, 84, 235, 215, 11, + 80, 4, 252, 174, 13, 3, 76, 85, 66, 181, 86, 32, 79, 82, 78, 69, 82, 32, + 65, 82, 82, 79, 87, 83, 32, 67, 73, 82, 67, 76, 73, 78, 71, 32, 65, 78, + 84, 73, 67, 76, 79, 67, 75, 87, 4, 21, 3, 79, 84, 32, 4, 222, 217, 23, + 80, 195, 132, 3, 77, 2, 231, 43, 72, 30, 78, 65, 250, 1, 69, 98, 79, 237, + 250, 16, 8, 73, 69, 68, 32, 83, 72, 82, 73, 12, 96, 6, 67, 84, 73, 79, + 78, 32, 68, 8, 77, 69, 32, 87, 73, 84, 72, 32, 245, 238, 10, 2, 71, 73, + 4, 142, 249, 19, 83, 177, 6, 9, 78, 85, 77, 69, 82, 65, 84, 79, 82, 6, + 50, 80, 218, 170, 2, 65, 253, 176, 21, 2, 84, 73, 2, 161, 254, 21, 2, 73, + 67, 6, 48, 6, 78, 67, 72, 32, 70, 82, 243, 133, 19, 69, 4, 150, 134, 26, + 73, 133, 15, 3, 65, 78, 67, 10, 52, 3, 78, 84, 45, 116, 2, 87, 78, 167, + 221, 26, 71, 4, 70, 84, 217, 143, 2, 11, 70, 65, 67, 73, 78, 71, 32, 66, + 65, 66, 89, 2, 237, 187, 12, 6, 73, 76, 84, 69, 68, 32, 5, 237, 143, 8, + 6, 73, 78, 71, 32, 70, 65, 226, 1, 80, 2, 76, 76, 134, 6, 78, 184, 242, + 16, 5, 69, 76, 32, 80, 85, 179, 138, 10, 83, 216, 1, 42, 32, 73, 6, 87, + 73, 68, 84, 72, 32, 10, 158, 137, 12, 77, 188, 166, 3, 2, 79, 85, 170, + 247, 8, 66, 151, 29, 83, 206, 1, 242, 1, 67, 42, 76, 78, 78, 30, 80, 66, + 82, 142, 1, 83, 38, 89, 182, 155, 10, 77, 226, 208, 10, 65, 158, 2, 68, + 58, 69, 98, 71, 118, 72, 202, 4, 81, 198, 153, 2, 87, 182, 29, 84, 162, + 146, 1, 70, 224, 177, 1, 6, 66, 82, 79, 75, 69, 78, 211, 7, 86, 10, 138, + 240, 20, 73, 62, 79, 131, 81, 69, 116, 42, 69, 190, 243, 20, 65, 231, + 183, 4, 79, 10, 162, 1, 70, 175, 245, 20, 83, 4, 142, 202, 21, 79, 35, + 85, 6, 42, 79, 174, 246, 20, 69, 211, 236, 2, 76, 2, 199, 169, 25, 85, + 10, 36, 3, 73, 71, 72, 183, 251, 24, 69, 8, 17, 2, 84, 32, 8, 244, 172, + 20, 5, 87, 72, 73, 84, 69, 246, 220, 2, 67, 210, 3, 80, 239, 7, 83, 4, + 226, 196, 23, 69, 139, 184, 1, 79, 2, 199, 151, 25, 69, 6, 180, 201, 11, + 8, 67, 84, 73, 79, 78, 32, 65, 80, 132, 248, 8, 5, 69, 82, 65, 76, 32, + 211, 188, 1, 78, 130, 21, 114, 65, 250, 6, 69, 222, 22, 73, 162, 1, 76, + 134, 15, 79, 198, 6, 82, 178, 92, 85, 242, 146, 22, 72, 131, 238, 3, 83, + 142, 1, 42, 82, 253, 245, 26, 4, 77, 69, 32, 68, 140, 1, 36, 3, 65, 89, + 32, 231, 230, 25, 76, 138, 1, 166, 1, 67, 210, 1, 83, 192, 2, 6, 86, 79, + 87, 69, 76, 32, 224, 174, 8, 6, 82, 69, 68, 85, 80, 76, 246, 203, 10, 72, + 238, 168, 1, 80, 214, 181, 3, 77, 171, 190, 1, 68, 52, 42, 79, 205, 1, 5, + 65, 80, 73, 84, 65, 8, 88, 10, 77, 66, 73, 78, 73, 78, 71, 32, 68, 79, + 37, 8, 78, 83, 79, 78, 65, 78, 84, 32, 4, 158, 145, 12, 85, 171, 128, 14, + 84, 4, 230, 145, 12, 78, 223, 156, 11, 71, 46, 36, 3, 77, 65, 76, 147, + 138, 22, 85, 44, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 44, 200, 1, + 4, 79, 76, 68, 32, 190, 147, 20, 78, 238, 245, 6, 66, 2, 67, 2, 68, 2, + 70, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, + 2, 87, 2, 88, 2, 89, 187, 2, 65, 4, 166, 137, 27, 75, 3, 78, 12, 44, 5, + 83, 73, 71, 78, 32, 155, 201, 26, 76, 10, 242, 202, 26, 69, 162, 64, 65, + 2, 73, 3, 79, 146, 3, 112, 2, 65, 82, 110, 77, 50, 79, 136, 210, 23, 9, + 82, 77, 65, 78, 32, 80, 69, 78, 78, 174, 177, 2, 84, 239, 105, 78, 7, 29, + 5, 32, 87, 73, 84, 72, 4, 200, 152, 14, 5, 79, 85, 84, 32, 72, 233, 175, + 9, 5, 32, 72, 65, 78, 68, 4, 26, 32, 143, 132, 22, 73, 2, 183, 147, 23, + 83, 130, 3, 46, 77, 245, 5, 6, 82, 71, 73, 65, 78, 32, 38, 92, 13, 65, + 78, 84, 73, 67, 32, 70, 73, 71, 85, 82, 69, 32, 205, 4, 5, 69, 84, 82, + 73, 67, 32, 158, 1, 65, 82, 67, 172, 1, 9, 70, 79, 82, 84, 85, 78, 65, + 32, 77, 44, 3, 76, 65, 69, 0, 4, 84, 82, 73, 83, 34, 80, 80, 3, 82, 85, + 66, 219, 206, 10, 86, 6, 216, 1, 6, 67, 81, 85, 73, 83, 73, 12, 4, 77, + 73, 83, 83, 211, 158, 23, 76, 8, 42, 65, 97, 6, 79, 78, 74, 85, 78, 67, + 6, 56, 3, 80, 85, 84, 0, 3, 85, 68, 65, 131, 180, 18, 82, 2, 165, 90, 5, + 32, 68, 82, 65, 67, 2, 11, 84, 2, 191, 229, 26, 73, 4, 206, 167, 2, 73, + 233, 163, 24, 2, 65, 74, 2, 197, 207, 10, 3, 84, 73, 84, 6, 44, 2, 85, + 69, 153, 248, 22, 3, 79, 80, 85, 4, 138, 225, 26, 76, 155, 34, 82, 2, + 159, 250, 24, 69, 6, 228, 255, 19, 4, 65, 76, 76, 89, 137, 228, 1, 5, 32, + 80, 82, 79, 80, 220, 2, 228, 1, 6, 67, 65, 80, 73, 84, 65, 0, 4, 83, 77, + 65, 76, 172, 3, 7, 76, 69, 84, 84, 69, 82, 32, 180, 2, 24, 77, 84, 65, + 86, 82, 85, 76, 73, 32, 67, 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, + 69, 82, 32, 165, 6, 2, 80, 65, 80, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, + 32, 80, 142, 2, 65, 34, 72, 166, 5, 67, 118, 71, 130, 1, 74, 34, 75, 82, + 80, 34, 83, 94, 90, 176, 178, 5, 2, 84, 65, 214, 144, 8, 76, 226, 180, 2, + 82, 218, 176, 9, 66, 2, 77, 2, 88, 226, 40, 78, 2, 81, 234, 35, 86, 234, + 47, 68, 14, 69, 2, 73, 2, 79, 2, 85, 2, 89, 143, 57, 87, 4, 154, 174, 26, + 69, 227, 79, 78, 10, 46, 65, 218, 230, 26, 73, 2, 79, 215, 22, 69, 4, + 170, 253, 26, 69, 3, 82, 94, 254, 1, 85, 178, 2, 65, 42, 67, 74, 69, 46, + 71, 34, 72, 98, 74, 34, 75, 34, 76, 50, 80, 34, 83, 34, 84, 62, 90, 230, + 247, 15, 82, 218, 176, 9, 66, 2, 77, 2, 88, 226, 40, 78, 2, 81, 234, 35, + 86, 234, 47, 68, 14, 73, 2, 79, 2, 89, 142, 57, 87, 255, 2, 70, 4, 240, + 130, 22, 4, 45, 66, 82, 74, 159, 248, 4, 78, 92, 250, 1, 65, 42, 67, 74, + 69, 46, 71, 34, 72, 98, 74, 34, 75, 34, 76, 50, 80, 34, 83, 34, 84, 62, + 90, 230, 247, 15, 82, 218, 176, 9, 66, 2, 77, 2, 88, 226, 40, 78, 2, 81, + 234, 35, 86, 234, 47, 68, 14, 73, 2, 79, 2, 85, 2, 89, 142, 57, 87, 255, + 2, 70, 6, 254, 168, 26, 69, 2, 73, 227, 79, 78, 8, 38, 72, 194, 236, 25, + 73, 243, 59, 65, 4, 174, 168, 26, 73, 135, 23, 65, 4, 208, 140, 9, 2, 76, + 73, 159, 235, 17, 78, 4, 166, 171, 25, 72, 191, 124, 65, 12, 46, 65, 162, + 224, 26, 73, 2, 79, 215, 22, 69, 6, 26, 82, 219, 246, 26, 69, 5, 215, + 239, 25, 68, 4, 166, 170, 25, 72, 207, 64, 73, 4, 230, 210, 25, 72, 223, + 83, 65, 4, 11, 65, 4, 174, 210, 15, 66, 203, 163, 11, 83, 4, 150, 210, + 25, 72, 227, 106, 65, 4, 222, 245, 25, 72, 247, 47, 65, 6, 176, 184, 3, + 6, 85, 82, 78, 69, 68, 32, 187, 250, 1, 65, 4, 154, 209, 25, 72, 223, 83, + 69, 2, 157, 171, 20, 7, 82, 65, 71, 82, 65, 80, 72, 10, 48, 2, 77, 69, + 20, 4, 78, 71, 69, 82, 31, 82, 2, 143, 222, 25, 76, 2, 237, 188, 18, 2, + 32, 82, 6, 38, 76, 253, 234, 13, 3, 65, 70, 70, 5, 183, 221, 25, 83, 202, + 1, 66, 65, 214, 13, 79, 161, 163, 26, 7, 69, 73, 67, 72, 32, 83, 84, 194, + 1, 84, 8, 71, 79, 76, 73, 84, 73, 67, 32, 229, 12, 8, 83, 83, 32, 79, 70, + 32, 77, 73, 192, 1, 56, 6, 67, 65, 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, + 96, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 96, 206, 1, 65, 22, 66, + 42, 67, 94, 68, 94, 70, 38, 71, 46, 73, 138, 2, 76, 58, 77, 66, 78, 34, + 79, 30, 80, 58, 82, 30, 83, 186, 1, 84, 110, 86, 22, 89, 90, 90, 210, + 137, 19, 72, 190, 133, 2, 85, 139, 183, 5, 75, 2, 155, 202, 26, 90, 4, + 214, 3, 73, 209, 217, 26, 2, 85, 75, 4, 48, 8, 65, 85, 68, 65, 84, 69, + 32, 67, 15, 72, 2, 11, 72, 2, 209, 255, 19, 2, 82, 73, 6, 42, 74, 30, 79, + 213, 202, 26, 2, 90, 69, 2, 137, 255, 19, 2, 69, 82, 2, 163, 251, 24, 66, + 4, 186, 148, 21, 82, 139, 180, 5, 73, 2, 21, 3, 76, 65, 71, 2, 243, 232, + 21, 79, 13, 38, 78, 54, 79, 141, 1, 2, 90, 72, 2, 137, 191, 26, 8, 73, + 84, 73, 65, 76, 32, 73, 90, 4, 33, 6, 84, 65, 84, 69, 68, 32, 4, 26, 66, + 25, 2, 83, 77, 2, 11, 73, 2, 35, 71, 2, 21, 3, 65, 76, 76, 2, 141, 226, + 24, 2, 32, 89, 4, 134, 232, 26, 73, 211, 2, 69, 4, 52, 9, 65, 84, 73, 78, + 65, 84, 69, 32, 77, 35, 74, 2, 193, 137, 11, 3, 89, 83, 76, 2, 213, 144, + 9, 3, 85, 68, 73, 2, 11, 65, 2, 187, 145, 21, 83, 4, 182, 196, 26, 78, 3, + 84, 4, 26, 79, 235, 232, 26, 69, 2, 221, 200, 22, 2, 75, 79, 2, 213, 245, + 21, 2, 73, 84, 14, 106, 72, 58, 76, 252, 239, 13, 6, 80, 73, 68, 69, 82, + 89, 173, 191, 10, 8, 77, 65, 76, 76, 32, 89, 85, 83, 6, 32, 2, 84, 65, + 163, 231, 26, 65, 5, 131, 189, 25, 80, 2, 231, 251, 19, 79, 6, 78, 86, + 172, 157, 22, 9, 82, 79, 75, 85, 84, 65, 83, 84, 73, 167, 181, 4, 83, 2, + 229, 166, 19, 2, 82, 73, 2, 151, 211, 24, 69, 12, 50, 69, 198, 249, 18, + 65, 130, 236, 7, 79, 3, 85, 6, 250, 140, 21, 83, 147, 152, 5, 82, 4, 248, + 148, 9, 3, 69, 77, 76, 145, 135, 16, 4, 72, 73, 86, 69, 2, 199, 225, 26, + 76, 6, 248, 242, 11, 13, 66, 69, 32, 87, 73, 84, 72, 32, 77, 69, 82, 73, + 68, 154, 196, 4, 87, 183, 151, 9, 86, 68, 162, 1, 65, 44, 12, 84, 72, 73, + 67, 32, 76, 69, 84, 84, 69, 82, 32, 198, 166, 18, 82, 222, 102, 71, 228, + 141, 5, 3, 78, 71, 71, 238, 187, 1, 79, 185, 77, 2, 76, 70, 4, 172, 183, + 15, 2, 76, 32, 147, 171, 11, 84, 54, 210, 2, 65, 50, 72, 46, 73, 46, 78, + 46, 80, 2, 81, 40, 2, 82, 65, 22, 84, 160, 141, 9, 2, 87, 73, 246, 147, + 12, 85, 244, 69, 3, 70, 65, 73, 204, 7, 4, 66, 65, 73, 82, 248, 21, 2, + 79, 84, 150, 30, 68, 166, 128, 1, 77, 198, 147, 1, 69, 164, 30, 3, 76, + 65, 71, 148, 41, 3, 83, 65, 85, 230, 161, 1, 74, 196, 16, 2, 71, 73, 141, + 12, 2, 75, 85, 4, 216, 214, 24, 3, 73, 72, 86, 163, 134, 2, 72, 4, 162, + 224, 13, 87, 157, 243, 11, 2, 65, 71, 4, 190, 142, 9, 85, 165, 241, 14, + 2, 71, 71, 6, 178, 206, 15, 73, 241, 140, 9, 2, 65, 85, 2, 201, 153, 26, + 5, 65, 73, 82, 84, 72, 2, 223, 184, 26, 73, 4, 224, 184, 23, 2, 72, 73, + 237, 69, 2, 69, 73, 234, 9, 46, 65, 198, 5, 69, 206, 82, 73, 151, 3, 79, + 152, 1, 96, 7, 68, 85, 65, 84, 73, 79, 78, 32, 5, 78, 84, 72, 65, 32, + 138, 184, 20, 86, 219, 141, 5, 80, 2, 11, 32, 2, 239, 200, 25, 67, 146, + 1, 120, 7, 76, 69, 84, 84, 69, 82, 32, 212, 2, 5, 83, 73, 71, 78, 32, + 130, 247, 22, 65, 248, 8, 2, 86, 79, 195, 199, 3, 79, 100, 214, 1, 86, + 154, 251, 22, 65, 38, 68, 114, 84, 230, 5, 85, 186, 202, 1, 73, 42, 76, + 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 206, + 40, 79, 162, 8, 69, 158, 20, 72, 2, 77, 2, 82, 3, 89, 14, 60, 5, 69, 68, + 73, 67, 32, 242, 129, 23, 79, 223, 214, 3, 65, 4, 164, 159, 24, 6, 68, + 79, 85, 66, 76, 69, 175, 244, 1, 65, 16, 66, 67, 206, 186, 22, 78, 190, + 66, 65, 182, 1, 80, 135, 150, 3, 86, 4, 162, 242, 7, 79, 215, 199, 14, + 65, 192, 8, 76, 10, 65, 84, 69, 82, 45, 84, 72, 65, 78, 32, 206, 7, 69, + 207, 199, 25, 89, 56, 134, 1, 65, 150, 3, 66, 62, 79, 216, 2, 11, 69, 81, + 85, 65, 76, 32, 84, 79, 32, 79, 82, 182, 204, 6, 67, 138, 4, 87, 131, + 248, 18, 83, 16, 44, 5, 66, 79, 86, 69, 32, 147, 209, 6, 78, 12, 150, 1, + 83, 180, 1, 19, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 69, 32, 69, 81, + 85, 65, 76, 32, 65, 184, 203, 6, 4, 76, 69, 83, 83, 159, 229, 18, 82, 6, + 148, 1, 7, 73, 77, 73, 76, 65, 82, 32, 185, 206, 6, 23, 76, 65, 78, 84, + 69, 68, 32, 69, 81, 85, 65, 76, 32, 65, 66, 79, 86, 69, 32, 76, 69, 83, + 83, 4, 26, 65, 143, 206, 6, 79, 2, 65, 3, 66, 79, 86, 6, 40, 4, 69, 83, + 73, 68, 247, 206, 6, 85, 2, 231, 2, 69, 20, 40, 2, 82, 32, 245, 1, 3, 86, + 69, 82, 16, 120, 16, 83, 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, + 32, 84, 79, 190, 208, 6, 65, 166, 253, 12, 69, 167, 237, 4, 76, 9, 49, + 10, 32, 87, 73, 84, 72, 32, 68, 79, 84, 32, 6, 44, 5, 65, 66, 79, 86, 69, + 255, 157, 18, 73, 5, 183, 157, 26, 32, 4, 52, 7, 76, 65, 80, 80, 73, 78, + 71, 215, 237, 19, 32, 2, 209, 185, 24, 2, 32, 76, 134, 8, 36, 2, 75, 32, + 185, 73, 2, 78, 32, 254, 7, 130, 3, 65, 216, 15, 8, 67, 65, 80, 73, 84, + 65, 76, 32, 182, 11, 68, 134, 1, 70, 68, 2, 73, 78, 222, 3, 75, 138, 1, + 76, 174, 3, 78, 66, 77, 84, 3, 88, 69, 83, 22, 79, 202, 1, 80, 90, 82, + 182, 1, 83, 130, 22, 84, 200, 2, 13, 85, 80, 83, 73, 76, 79, 78, 32, 87, + 73, 84, 72, 32, 150, 1, 86, 142, 2, 89, 230, 228, 7, 66, 212, 176, 3, 4, + 71, 82, 65, 77, 196, 23, 2, 90, 69, 175, 132, 12, 81, 112, 92, 10, 67, + 82, 79, 80, 72, 79, 78, 73, 67, 32, 172, 14, 6, 78, 79, 32, 84, 69, 76, + 23, 82, 106, 188, 2, 6, 65, 84, 84, 73, 67, 32, 222, 5, 67, 92, 3, 78, + 65, 88, 32, 12, 68, 69, 76, 80, 72, 73, 67, 32, 70, 73, 86, 69, 0, 14, + 83, 84, 82, 65, 84, 73, 65, 78, 32, 70, 73, 70, 84, 89, 40, 11, 69, 80, + 73, 68, 65, 85, 82, 69, 65, 78, 32, 112, 3, 72, 69, 82, 164, 1, 9, 77, + 69, 83, 83, 69, 78, 73, 65, 78, 35, 84, 48, 72, 2, 70, 73, 180, 2, 4, 79, + 78, 69, 32, 205, 1, 4, 84, 69, 78, 32, 26, 36, 3, 70, 84, 89, 105, 2, 86, + 69, 11, 11, 32, 8, 22, 84, 171, 4, 83, 6, 48, 7, 72, 79, 85, 83, 65, 78, + 68, 215, 3, 65, 5, 231, 3, 32, 17, 11, 32, 14, 56, 7, 72, 85, 78, 68, 82, + 69, 68, 18, 84, 143, 3, 83, 7, 131, 2, 32, 6, 48, 7, 72, 79, 85, 83, 65, + 78, 68, 187, 2, 65, 5, 213, 1, 2, 32, 84, 14, 98, 72, 48, 7, 84, 72, 79, + 85, 83, 65, 78, 186, 190, 24, 81, 217, 228, 1, 5, 68, 82, 65, 67, 72, 6, + 44, 5, 85, 78, 68, 82, 69, 155, 190, 24, 65, 4, 17, 2, 68, 32, 4, 22, 84, + 131, 1, 83, 2, 95, 65, 8, 30, 84, 86, 83, 175, 1, 77, 4, 50, 65, 21, 8, + 72, 79, 85, 83, 65, 78, 68, 32, 2, 163, 178, 16, 76, 2, 11, 83, 2, 157, + 191, 24, 2, 84, 65, 4, 88, 5, 65, 82, 89, 83, 84, 145, 1, 12, 89, 82, 69, + 78, 65, 73, 67, 32, 84, 87, 79, 32, 2, 101, 5, 73, 65, 78, 32, 70, 2, 17, + 2, 32, 77, 2, 243, 143, 13, 78, 6, 30, 70, 29, 3, 84, 87, 79, 2, 201, + 178, 15, 2, 73, 86, 5, 11, 32, 2, 237, 148, 10, 5, 68, 82, 65, 67, 72, 8, + 112, 8, 77, 73, 79, 78, 73, 65, 78, 32, 157, 152, 25, 14, 65, 69, 85, 77, + 32, 79, 78, 69, 32, 80, 76, 69, 84, 72, 6, 182, 185, 12, 70, 150, 176, + 12, 84, 215, 58, 79, 2, 11, 32, 2, 143, 233, 24, 84, 32, 92, 8, 72, 69, + 83, 80, 73, 65, 78, 32, 129, 1, 10, 82, 79, 69, 90, 69, 78, 73, 65, 78, + 32, 20, 40, 2, 70, 73, 38, 84, 227, 155, 18, 79, 6, 158, 225, 20, 86, + 247, 236, 3, 70, 8, 226, 174, 15, 72, 142, 191, 10, 69, 239, 48, 87, 12, + 36, 2, 70, 73, 209, 24, 2, 84, 69, 8, 250, 180, 18, 86, 213, 136, 7, 3, + 70, 84, 89, 2, 155, 136, 10, 69, 4, 144, 231, 22, 2, 79, 85, 153, 181, 1, + 3, 84, 65, 66, 154, 2, 66, 76, 174, 45, 82, 66, 68, 144, 230, 7, 2, 75, + 65, 135, 6, 84, 144, 2, 44, 6, 69, 84, 84, 69, 82, 32, 239, 45, 85, 142, + 2, 198, 2, 65, 190, 1, 69, 28, 4, 73, 79, 84, 65, 128, 1, 2, 79, 77, 156, + 3, 3, 82, 72, 79, 46, 83, 48, 7, 85, 80, 83, 73, 76, 79, 78, 146, 33, 80, + 170, 2, 84, 146, 182, 5, 68, 252, 180, 2, 2, 75, 65, 238, 192, 1, 71, + 190, 138, 11, 67, 230, 154, 2, 66, 2, 72, 2, 90, 166, 1, 76, 186, 235, 2, + 89, 210, 43, 77, 2, 78, 147, 17, 88, 48, 68, 4, 76, 80, 72, 65, 213, 28, + 8, 82, 67, 72, 65, 73, 67, 32, 83, 47, 33, 6, 32, 87, 73, 84, 72, 32, 44, + 242, 2, 68, 30, 80, 226, 29, 86, 226, 5, 79, 162, 234, 3, 84, 191, 174, + 5, 77, 62, 186, 1, 84, 131, 27, 80, 31, 33, 6, 32, 87, 73, 84, 72, 32, + 28, 186, 5, 68, 136, 25, 2, 80, 83, 158, 1, 86, 226, 5, 79, 162, 234, 3, + 84, 191, 174, 5, 77, 62, 28, 2, 69, 71, 235, 34, 73, 42, 11, 65, 43, 33, + 6, 32, 87, 73, 84, 72, 32, 40, 54, 68, 30, 80, 194, 35, 79, 22, 86, 143, + 234, 3, 84, 16, 65, 4, 65, 83, 73, 65, 18, 36, 4, 83, 73, 76, 73, 211, + 16, 82, 17, 29, 5, 32, 65, 78, 68, 32, 14, 44, 2, 79, 88, 0, 3, 86, 65, + 82, 23, 80, 4, 81, 2, 73, 65, 6, 60, 10, 69, 82, 73, 83, 80, 79, 77, 69, + 78, 73, 175, 15, 82, 5, 169, 15, 7, 32, 65, 78, 68, 32, 80, 82, 5, 161, + 35, 7, 32, 87, 73, 84, 72, 32, 68, 6, 146, 144, 8, 73, 162, 210, 17, 65, + 239, 48, 72, 23, 33, 6, 32, 87, 73, 84, 72, 32, 20, 66, 68, 166, 26, 86, + 226, 5, 79, 162, 234, 3, 84, 191, 174, 5, 77, 10, 130, 24, 65, 213, 191, + 22, 5, 73, 65, 76, 89, 84, 18, 76, 9, 73, 65, 76, 89, 84, 73, 75, 65, 32, + 32, 3, 82, 65, 67, 227, 22, 65, 8, 174, 24, 65, 243, 240, 3, 84, 2, 131, + 191, 11, 72, 4, 40, 3, 73, 86, 69, 1, 3, 79, 85, 82, 2, 205, 37, 2, 32, + 79, 76, 144, 1, 27, 83, 84, 82, 85, 77, 69, 78, 84, 65, 76, 32, 78, 79, + 84, 65, 84, 73, 79, 78, 32, 83, 89, 77, 66, 79, 76, 45, 193, 168, 22, 2, + 68, 73, 74, 70, 49, 70, 50, 62, 51, 62, 52, 170, 37, 53, 194, 134, 26, + 55, 3, 56, 17, 162, 173, 26, 49, 2, 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, + 57, 15, 222, 172, 26, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 12, 162, + 172, 26, 48, 2, 50, 2, 54, 2, 55, 2, 56, 3, 57, 17, 230, 171, 26, 48, 2, + 50, 2, 51, 2, 53, 2, 55, 2, 56, 3, 57, 8, 54, 65, 38, 79, 169, 32, 6, 89, + 65, 84, 72, 79, 83, 4, 186, 130, 8, 80, 239, 146, 17, 73, 2, 11, 82, 2, + 11, 79, 2, 167, 131, 24, 78, 32, 128, 1, 6, 69, 84, 84, 69, 82, 32, 168, + 2, 6, 79, 87, 69, 82, 32, 78, 32, 6, 85, 78, 65, 84, 69, 32, 177, 209, + 22, 2, 73, 84, 24, 94, 83, 140, 13, 9, 65, 82, 67, 72, 65, 73, 67, 32, + 75, 2, 75, 182, 11, 68, 195, 191, 25, 89, 16, 88, 13, 77, 65, 76, 76, 32, + 67, 65, 80, 73, 84, 65, 76, 32, 210, 12, 65, 171, 247, 7, 84, 12, 74, 80, + 222, 196, 9, 71, 166, 157, 9, 79, 154, 212, 2, 82, 139, 181, 1, 76, 4, + 182, 147, 26, 83, 219, 19, 73, 2, 213, 138, 10, 3, 85, 77, 69, 4, 222, + 25, 83, 139, 228, 7, 69, 4, 80, 4, 69, 84, 82, 69, 149, 208, 23, 10, 85, + 83, 73, 67, 65, 76, 32, 76, 69, 73, 2, 235, 212, 2, 84, 12, 88, 3, 78, + 69, 32, 194, 240, 9, 88, 176, 151, 5, 3, 85, 78, 75, 225, 208, 5, 2, 66, + 79, 6, 64, 8, 72, 65, 76, 70, 32, 83, 73, 71, 21, 4, 81, 85, 65, 82, 4, + 255, 164, 25, 78, 2, 251, 216, 20, 84, 16, 62, 82, 206, 11, 83, 114, 69, + 206, 239, 7, 72, 247, 145, 17, 73, 2, 217, 29, 2, 79, 83, 6, 100, 3, 72, + 79, 32, 217, 249, 7, 16, 69, 86, 69, 82, 83, 69, 68, 32, 76, 85, 78, 65, + 84, 69, 32, 69, 4, 240, 243, 13, 10, 87, 73, 84, 72, 32, 83, 84, 82, 79, + 75, 163, 153, 11, 83, 226, 2, 220, 1, 5, 77, 65, 76, 76, 32, 192, 19, 22, + 85, 66, 83, 67, 82, 73, 80, 84, 32, 83, 77, 65, 76, 76, 32, 76, 69, 84, + 84, 69, 82, 32, 72, 10, 89, 77, 66, 79, 76, 32, 84, 65, 85, 32, 201, 160, + 24, 6, 73, 78, 85, 83, 79, 73, 212, 2, 56, 7, 76, 69, 84, 84, 69, 82, 32, + 202, 17, 82, 67, 68, 206, 2, 178, 2, 65, 162, 2, 68, 38, 69, 52, 4, 73, + 79, 84, 65, 0, 7, 85, 80, 83, 73, 76, 79, 78, 254, 3, 75, 28, 2, 79, 77, + 182, 5, 80, 112, 3, 82, 72, 79, 94, 83, 94, 84, 168, 234, 7, 2, 70, 73, + 210, 193, 1, 71, 190, 138, 11, 67, 230, 154, 2, 66, 2, 72, 2, 90, 166, 1, + 76, 138, 151, 3, 77, 2, 78, 147, 17, 88, 58, 64, 4, 76, 80, 72, 65, 149, + 1, 7, 82, 67, 72, 65, 73, 67, 32, 55, 33, 6, 32, 87, 73, 84, 72, 32, 52, + 82, 86, 226, 6, 68, 30, 80, 114, 79, 142, 1, 89, 142, 236, 3, 84, 191, + 174, 5, 77, 6, 154, 5, 82, 155, 3, 65, 4, 18, 75, 23, 83, 2, 139, 248, 7, + 79, 2, 11, 65, 2, 147, 189, 13, 77, 4, 202, 226, 7, 73, 203, 251, 14, 69, + 70, 22, 80, 215, 4, 84, 20, 249, 7, 3, 83, 73, 76, 41, 33, 6, 32, 87, 73, + 84, 72, 32, 38, 78, 68, 166, 1, 80, 178, 1, 86, 226, 5, 79, 162, 234, 3, + 84, 191, 174, 5, 77, 18, 50, 65, 29, 8, 73, 65, 76, 89, 84, 73, 75, 65, + 8, 153, 1, 3, 83, 73, 65, 11, 29, 5, 32, 65, 78, 68, 32, 8, 170, 1, 80, + 154, 6, 79, 22, 86, 143, 234, 3, 84, 10, 18, 83, 115, 69, 8, 21, 3, 73, + 76, 73, 9, 17, 2, 32, 65, 6, 21, 3, 78, 68, 32, 6, 30, 80, 154, 6, 79, + 23, 86, 2, 11, 69, 2, 11, 82, 2, 181, 17, 4, 73, 83, 80, 79, 4, 22, 82, + 147, 15, 65, 2, 249, 244, 25, 2, 65, 67, 4, 130, 243, 7, 65, 3, 79, 70, + 28, 2, 69, 71, 151, 3, 73, 50, 11, 65, 51, 33, 6, 32, 87, 73, 84, 72, 32, + 48, 58, 68, 30, 80, 114, 79, 62, 86, 82, 89, 143, 236, 3, 84, 16, 61, 4, + 65, 83, 73, 65, 20, 32, 4, 83, 73, 76, 73, 91, 69, 17, 29, 5, 32, 65, 78, + 68, 32, 14, 42, 79, 12, 2, 80, 69, 50, 86, 83, 89, 4, 83, 88, 4, 89, 9, + 82, 73, 83, 80, 79, 77, 69, 78, 73, 4, 11, 65, 4, 11, 82, 4, 17, 2, 73, + 65, 5, 33, 6, 32, 65, 78, 68, 32, 89, 2, 243, 12, 80, 20, 17, 2, 67, 82, + 20, 17, 2, 79, 78, 21, 33, 6, 32, 87, 73, 84, 72, 32, 18, 88, 5, 68, 65, + 83, 73, 65, 0, 5, 80, 83, 73, 76, 73, 54, 79, 22, 86, 143, 234, 3, 84, 7, + 29, 5, 32, 65, 78, 68, 32, 4, 18, 79, 23, 86, 2, 203, 220, 9, 88, 2, 179, + 9, 65, 8, 88, 11, 65, 77, 80, 72, 89, 76, 73, 65, 78, 32, 68, 162, 252, + 25, 72, 2, 83, 219, 19, 73, 2, 203, 215, 7, 73, 7, 33, 6, 32, 87, 73, 84, + 72, 32, 4, 34, 68, 177, 139, 21, 2, 80, 83, 2, 203, 201, 8, 65, 10, 54, + 65, 238, 234, 7, 84, 230, 1, 73, 143, 131, 18, 72, 4, 214, 176, 13, 77, + 251, 221, 12, 78, 4, 150, 209, 22, 72, 175, 152, 3, 65, 4, 41, 8, 69, 86, + 69, 82, 83, 69, 68, 32, 4, 18, 68, 43, 76, 2, 37, 7, 79, 84, 84, 69, 68, + 32, 76, 2, 11, 85, 2, 33, 6, 78, 65, 84, 69, 32, 83, 2, 221, 235, 7, 3, + 73, 71, 77, 10, 154, 170, 9, 71, 190, 138, 11, 67, 2, 80, 130, 103, 82, + 231, 179, 1, 66, 2, 143, 155, 21, 82, 16, 106, 72, 104, 7, 82, 89, 66, + 76, 73, 79, 78, 44, 3, 87, 79, 32, 170, 227, 3, 79, 185, 209, 16, 2, 65, + 76, 6, 40, 4, 82, 69, 69, 32, 195, 233, 7, 69, 4, 146, 1, 79, 189, 215, + 22, 7, 81, 85, 65, 82, 84, 69, 82, 2, 21, 3, 32, 66, 65, 2, 255, 233, 23, + 83, 4, 42, 79, 165, 152, 12, 4, 84, 72, 73, 82, 2, 133, 229, 19, 2, 66, + 79, 6, 80, 5, 65, 67, 85, 84, 69, 0, 9, 68, 73, 65, 69, 82, 69, 83, 73, + 83, 39, 72, 2, 33, 6, 32, 65, 78, 68, 32, 72, 2, 133, 199, 7, 2, 79, 79, + 60, 102, 65, 21, 21, 79, 67, 65, 76, 32, 78, 79, 84, 65, 84, 73, 79, 78, + 32, 83, 89, 77, 66, 79, 76, 45, 2, 131, 211, 9, 82, 58, 90, 50, 2, 53, + 190, 194, 23, 49, 134, 196, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 13, + 190, 134, 26, 48, 2, 49, 2, 50, 2, 51, 3, 52, 4, 26, 80, 203, 187, 20, + 69, 2, 11, 79, 2, 33, 6, 71, 69, 71, 82, 65, 77, 2, 229, 128, 21, 2, 77, + 69, 8, 230, 237, 13, 65, 206, 193, 10, 66, 202, 78, 72, 253, 64, 3, 83, + 65, 76, 12, 60, 6, 78, 78, 73, 78, 71, 32, 253, 251, 24, 3, 77, 65, 67, + 10, 100, 4, 70, 65, 67, 69, 241, 232, 17, 15, 67, 65, 84, 32, 70, 65, 67, + 69, 32, 87, 73, 84, 72, 32, 83, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 108, + 23, 79, 78, 69, 32, 76, 65, 82, 71, 69, 32, 65, 78, 68, 32, 79, 78, 69, + 32, 83, 77, 65, 76, 76, 35, 83, 2, 11, 32, 2, 151, 161, 8, 69, 4, 32, 2, + 84, 65, 167, 231, 17, 77, 2, 223, 130, 23, 82, 6, 28, 3, 85, 80, 32, 39, + 87, 4, 246, 207, 22, 83, 135, 240, 2, 77, 2, 207, 149, 18, 73, 220, 4, + 136, 1, 2, 65, 82, 70, 73, 52, 7, 74, 65, 82, 65, 84, 73, 32, 184, 6, 12, + 78, 74, 65, 76, 65, 32, 71, 79, 78, 68, 73, 32, 143, 3, 82, 4, 34, 65, + 149, 129, 21, 2, 68, 83, 2, 11, 78, 2, 175, 248, 24, 73, 4, 222, 219, 24, + 84, 221, 162, 1, 4, 68, 69, 32, 68, 182, 1, 168, 1, 7, 76, 69, 84, 84, + 69, 82, 32, 220, 1, 5, 83, 73, 71, 78, 32, 160, 2, 6, 86, 79, 87, 69, 76, + 32, 234, 133, 20, 65, 154, 24, 82, 182, 231, 3, 68, 179, 227, 1, 79, 98, + 194, 159, 22, 65, 38, 68, 114, 84, 46, 86, 186, 5, 85, 186, 202, 1, 73, + 42, 76, 246, 14, 90, 238, 180, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, + 74, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, + 24, 98, 67, 28, 3, 77, 65, 68, 22, 84, 182, 199, 3, 83, 150, 150, 18, 78, + 190, 66, 65, 187, 151, 3, 86, 4, 118, 73, 175, 220, 21, 65, 2, 219, 140, + 19, 68, 4, 68, 5, 87, 79, 45, 67, 73, 29, 8, 72, 82, 69, 69, 45, 68, 79, + 84, 2, 25, 4, 82, 67, 76, 69, 2, 165, 206, 20, 5, 32, 78, 85, 75, 84, 34, + 44, 5, 83, 73, 71, 78, 32, 215, 191, 15, 67, 30, 210, 191, 15, 67, 154, + 226, 6, 65, 38, 85, 22, 86, 166, 202, 1, 73, 198, 140, 2, 69, 3, 79, 126, + 108, 7, 76, 69, 84, 84, 69, 82, 32, 216, 1, 5, 83, 73, 71, 78, 32, 38, + 86, 190, 129, 24, 68, 179, 227, 1, 79, 80, 186, 129, 22, 78, 146, 24, 65, + 38, 68, 114, 84, 230, 5, 85, 186, 202, 1, 73, 42, 76, 222, 196, 1, 66, 2, + 67, 2, 71, 2, 74, 2, 75, 2, 80, 206, 40, 79, 162, 8, 69, 158, 20, 72, 2, + 77, 2, 82, 2, 83, 2, 86, 3, 89, 4, 250, 187, 23, 86, 247, 244, 1, 65, 20, + 190, 7, 79, 235, 177, 23, 73, 160, 2, 84, 6, 77, 85, 75, 72, 73, 32, 189, + 7, 10, 85, 78, 71, 32, 75, 72, 69, 77, 65, 32, 172, 1, 194, 1, 65, 44, 7, + 76, 69, 84, 84, 69, 82, 32, 238, 1, 83, 228, 2, 2, 86, 79, 140, 144, 13, + 3, 84, 73, 80, 174, 242, 5, 73, 252, 175, 2, 5, 69, 75, 32, 79, 78, 202, + 199, 2, 68, 203, 175, 1, 85, 4, 198, 210, 21, 66, 177, 231, 1, 2, 68, 68, + 96, 174, 198, 8, 71, 2, 75, 178, 206, 13, 65, 38, 68, 82, 82, 34, 84, + 230, 5, 85, 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, 126, 66, 2, 67, 2, + 74, 2, 80, 2, 83, 206, 40, 79, 162, 8, 69, 158, 20, 70, 2, 72, 2, 77, 2, + 86, 2, 89, 3, 90, 26, 108, 19, 69, 81, 85, 69, 78, 67, 69, 32, 70, 79, + 82, 32, 76, 69, 84, 84, 69, 82, 32, 93, 4, 73, 71, 78, 32, 12, 70, 71, 2, + 75, 138, 242, 23, 83, 146, 219, 1, 76, 226, 31, 70, 3, 90, 2, 135, 242, + 23, 72, 14, 128, 1, 6, 65, 68, 65, 75, 32, 66, 2, 66, 220, 140, 15, 2, + 85, 68, 190, 196, 6, 78, 236, 177, 2, 3, 89, 65, 75, 139, 168, 1, 86, 2, + 239, 151, 8, 73, 18, 45, 9, 87, 69, 76, 32, 83, 73, 71, 78, 32, 18, 178, + 150, 22, 65, 38, 85, 186, 202, 1, 73, 210, 237, 1, 79, 163, 8, 69, 116, + 216, 1, 22, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, + 77, 69, 68, 73, 65, 76, 32, 44, 7, 76, 69, 84, 84, 69, 82, 32, 168, 1, 5, + 83, 73, 71, 78, 32, 56, 6, 86, 79, 87, 69, 76, 32, 159, 245, 23, 68, 8, + 246, 232, 25, 72, 2, 82, 2, 86, 3, 89, 60, 254, 244, 21, 78, 182, 24, 68, + 114, 84, 162, 149, 3, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, + 2, 76, 2, 77, 2, 82, 2, 83, 2, 86, 2, 89, 187, 2, 65, 4, 226, 164, 25, + 65, 233, 35, 6, 84, 72, 79, 76, 72, 79, 24, 150, 158, 20, 83, 147, 137, + 5, 76, 168, 23, 110, 65, 214, 95, 69, 150, 104, 73, 146, 9, 79, 158, 12, + 84, 30, 85, 130, 1, 89, 225, 236, 12, 4, 82, 89, 86, 78, 140, 11, 236, 1, + 2, 73, 82, 100, 8, 76, 70, 87, 73, 68, 84, 72, 32, 242, 10, 77, 210, 1, + 78, 236, 76, 21, 80, 80, 89, 32, 80, 69, 82, 83, 79, 78, 32, 82, 65, 73, + 83, 73, 78, 71, 32, 79, 78, 22, 82, 38, 84, 208, 247, 17, 2, 85, 77, 255, + 253, 5, 68, 8, 66, 32, 140, 199, 20, 6, 89, 32, 67, 82, 69, 65, 251, 164, + 4, 67, 4, 194, 179, 24, 80, 231, 115, 83, 244, 1, 140, 2, 7, 72, 65, 78, + 71, 85, 76, 32, 216, 4, 8, 75, 65, 84, 65, 75, 65, 78, 65, 204, 3, 3, 76, + 69, 70, 0, 4, 82, 73, 71, 72, 204, 188, 6, 11, 70, 79, 82, 77, 83, 32, + 76, 73, 71, 72, 84, 202, 134, 4, 85, 250, 213, 2, 73, 142, 190, 4, 66, + 166, 238, 4, 87, 215, 35, 68, 104, 52, 7, 76, 69, 84, 84, 69, 82, 32, + 163, 221, 10, 70, 102, 206, 1, 75, 28, 5, 78, 73, 69, 85, 78, 42, 80, 24, + 5, 82, 73, 69, 85, 76, 86, 83, 98, 89, 202, 61, 67, 54, 69, 30, 73, 242, + 4, 77, 138, 1, 84, 206, 3, 87, 198, 1, 72, 202, 213, 24, 65, 2, 79, 163, + 64, 85, 6, 222, 65, 72, 155, 3, 73, 7, 11, 45, 4, 134, 72, 67, 131, 3, + 72, 6, 146, 69, 72, 35, 73, 17, 11, 45, 14, 206, 49, 84, 226, 14, 80, + 130, 4, 77, 194, 3, 75, 218, 2, 72, 99, 83, 12, 40, 4, 83, 65, 78, 71, + 211, 221, 13, 73, 10, 210, 70, 67, 42, 75, 74, 80, 34, 84, 211, 2, 83, + 14, 214, 149, 23, 69, 146, 137, 2, 65, 162, 64, 73, 2, 79, 3, 85, 118, + 70, 32, 157, 241, 2, 11, 45, 72, 73, 82, 65, 71, 65, 78, 65, 32, 80, 116, + 76, 7, 76, 69, 84, 84, 69, 82, 32, 242, 240, 2, 83, 34, 86, 195, 216, 21, + 77, 110, 146, 1, 83, 230, 234, 2, 78, 150, 2, 72, 2, 75, 2, 77, 2, 82, 2, + 84, 170, 1, 89, 158, 38, 87, 226, 199, 22, 65, 2, 69, 2, 73, 2, 79, 3, + 85, 28, 76, 5, 77, 65, 76, 76, 32, 206, 219, 25, 65, 2, 69, 2, 73, 2, 79, + 3, 85, 18, 206, 237, 2, 89, 150, 201, 22, 84, 234, 36, 65, 2, 69, 2, 73, + 2, 79, 3, 85, 4, 11, 84, 4, 156, 157, 13, 2, 32, 67, 135, 156, 11, 87, + 14, 56, 3, 77, 69, 82, 106, 83, 249, 135, 22, 3, 66, 85, 82, 9, 29, 5, + 32, 65, 78, 68, 32, 6, 196, 169, 12, 3, 87, 82, 69, 212, 233, 3, 2, 83, + 73, 191, 148, 8, 80, 4, 252, 155, 25, 3, 84, 69, 82, 163, 61, 65, 194, 8, + 118, 68, 202, 2, 71, 128, 66, 13, 73, 70, 73, 32, 82, 79, 72, 73, 78, 71, + 89, 65, 32, 165, 5, 5, 85, 78, 79, 79, 32, 10, 100, 12, 32, 87, 73, 84, + 72, 32, 73, 78, 68, 69, 88, 32, 188, 1, 2, 66, 65, 173, 233, 21, 2, 83, + 72, 4, 156, 1, 18, 65, 78, 68, 32, 77, 73, 68, 68, 76, 69, 32, 70, 73, + 78, 71, 69, 82, 83, 1, 16, 70, 73, 78, 71, 69, 82, 32, 65, 78, 68, 32, + 84, 72, 85, 77, 66, 2, 201, 139, 16, 2, 32, 67, 4, 130, 202, 24, 76, 211, + 139, 1, 71, 170, 7, 84, 3, 85, 76, 32, 217, 64, 13, 90, 72, 79, 85, 32, + 78, 85, 77, 69, 82, 65, 76, 32, 146, 7, 164, 1, 9, 67, 72, 79, 83, 69, + 79, 78, 71, 32, 244, 15, 4, 68, 79, 85, 66, 0, 4, 83, 73, 78, 71, 46, 74, + 180, 31, 7, 76, 69, 84, 84, 69, 82, 32, 143, 158, 10, 70, 250, 1, 246, 1, + 67, 172, 2, 5, 73, 69, 85, 78, 71, 146, 1, 75, 132, 1, 5, 77, 73, 69, 85, + 77, 56, 5, 78, 73, 69, 85, 78, 74, 80, 172, 2, 5, 82, 73, 69, 85, 76, + 210, 1, 83, 166, 3, 84, 124, 2, 89, 69, 200, 40, 5, 72, 73, 69, 85, 72, + 195, 149, 10, 70, 30, 76, 2, 72, 73, 84, 7, 69, 79, 78, 71, 67, 72, 73, + 121, 4, 73, 69, 85, 67, 16, 40, 4, 69, 85, 67, 72, 41, 2, 84, 85, 7, 11, + 45, 4, 202, 31, 75, 243, 26, 72, 10, 21, 3, 69, 85, 77, 10, 22, 83, 155, + 46, 67, 6, 40, 4, 83, 65, 78, 71, 195, 205, 13, 73, 4, 194, 54, 67, 227, + 3, 83, 5, 215, 30, 45, 27, 11, 45, 24, 90, 80, 234, 30, 82, 242, 13, 67, + 194, 5, 77, 138, 1, 84, 186, 2, 75, 218, 2, 72, 99, 83, 6, 214, 50, 72, + 214, 3, 73, 207, 2, 65, 16, 80, 7, 65, 80, 89, 69, 79, 85, 78, 228, 20, + 5, 73, 89, 69, 79, 75, 131, 25, 72, 10, 234, 29, 82, 178, 15, 80, 30, 83, + 231, 3, 77, 11, 11, 45, 8, 158, 52, 75, 74, 80, 34, 84, 211, 2, 83, 15, + 11, 45, 12, 190, 51, 67, 42, 75, 74, 80, 34, 84, 242, 1, 72, 99, 83, 42, + 68, 6, 72, 73, 69, 85, 80, 72, 40, 4, 73, 69, 85, 80, 223, 53, 65, 7, 11, + 45, 4, 158, 51, 80, 147, 2, 72, 35, 11, 45, 32, 82, 83, 234, 20, 80, 214, + 7, 75, 162, 12, 67, 202, 6, 84, 226, 2, 78, 179, 2, 72, 14, 32, 3, 73, + 79, 83, 251, 3, 83, 13, 11, 45, 10, 242, 46, 84, 146, 2, 67, 42, 75, 75, + 80, 29, 11, 45, 26, 78, 75, 42, 83, 190, 44, 77, 154, 3, 67, 82, 78, 34, + 80, 34, 84, 243, 1, 72, 6, 170, 22, 65, 130, 19, 72, 135, 7, 73, 8, 40, + 4, 83, 65, 78, 71, 167, 198, 13, 73, 6, 206, 47, 75, 74, 80, 35, 84, 58, + 48, 3, 73, 79, 83, 217, 1, 4, 83, 65, 78, 71, 33, 11, 45, 30, 130, 1, 80, + 44, 2, 83, 83, 210, 22, 82, 210, 1, 75, 162, 12, 67, 194, 5, 77, 138, 1, + 84, 226, 2, 78, 178, 2, 72, 163, 162, 18, 73, 6, 184, 23, 4, 73, 69, 85, + 80, 179, 19, 72, 2, 233, 48, 3, 65, 78, 71, 26, 236, 17, 5, 67, 73, 69, + 85, 67, 172, 3, 4, 83, 73, 79, 83, 154, 1, 82, 186, 20, 84, 54, 89, 134, + 2, 75, 42, 78, 34, 80, 146, 2, 72, 163, 162, 18, 73, 16, 40, 5, 73, 75, + 69, 85, 84, 195, 41, 72, 15, 11, 45, 12, 226, 20, 82, 178, 19, 77, 154, + 3, 67, 42, 75, 74, 80, 243, 2, 83, 4, 150, 19, 83, 139, 22, 79, 2, 149, + 249, 8, 6, 76, 69, 32, 68, 79, 84, 216, 3, 92, 9, 79, 78, 71, 83, 69, 79, + 78, 71, 32, 165, 21, 9, 85, 78, 71, 83, 69, 79, 78, 71, 32, 154, 2, 226, + 1, 67, 80, 5, 72, 73, 69, 85, 72, 60, 5, 73, 69, 85, 78, 71, 46, 75, 220, + 1, 5, 77, 73, 69, 85, 77, 188, 1, 5, 78, 73, 69, 85, 78, 94, 80, 240, 2, + 5, 82, 73, 69, 85, 76, 190, 4, 83, 194, 3, 84, 213, 1, 2, 89, 69, 8, 36, + 4, 73, 69, 85, 67, 239, 30, 72, 7, 11, 45, 4, 162, 32, 83, 239, 7, 80, + 11, 11, 45, 8, 174, 16, 82, 178, 19, 77, 234, 3, 78, 35, 80, 9, 11, 45, + 6, 194, 17, 75, 57, 2, 83, 83, 28, 76, 7, 65, 80, 89, 69, 79, 85, 78, 40, + 5, 73, 89, 69, 79, 75, 215, 30, 72, 8, 130, 15, 82, 178, 15, 80, 131, 4, + 77, 19, 11, 45, 16, 166, 13, 75, 170, 1, 82, 42, 83, 224, 13, 2, 67, 72, + 146, 9, 78, 34, 80, 147, 2, 72, 27, 11, 45, 24, 74, 80, 30, 83, 134, 13, + 82, 242, 13, 67, 130, 9, 75, 42, 78, 179, 2, 72, 6, 174, 33, 73, 131, 6, + 65, 6, 40, 4, 83, 65, 78, 71, 159, 186, 13, 73, 4, 238, 35, 78, 147, 3, + 83, 21, 11, 45, 18, 174, 12, 82, 242, 13, 67, 202, 6, 84, 186, 2, 75, + 218, 2, 72, 62, 80, 39, 83, 36, 88, 6, 65, 78, 83, 73, 79, 83, 48, 6, 72, + 73, 69, 85, 80, 72, 53, 4, 73, 69, 85, 80, 7, 11, 45, 4, 236, 7, 2, 75, + 65, 195, 26, 80, 9, 11, 45, 6, 150, 11, 84, 234, 22, 80, 243, 2, 83, 23, + 11, 45, 20, 112, 5, 82, 73, 69, 85, 76, 24, 4, 83, 73, 79, 83, 134, 3, + 80, 246, 19, 67, 194, 5, 77, 170, 4, 84, 243, 1, 72, 5, 153, 3, 2, 45, + 80, 5, 221, 32, 2, 45, 84, 57, 11, 45, 54, 102, 75, 92, 5, 77, 73, 69, + 85, 77, 50, 80, 126, 83, 74, 84, 44, 2, 89, 69, 154, 28, 78, 179, 2, 72, + 10, 52, 5, 73, 89, 69, 79, 75, 190, 4, 65, 131, 19, 72, 7, 11, 45, 4, + 254, 32, 72, 99, 83, 9, 11, 45, 6, 130, 30, 75, 218, 2, 72, 99, 83, 14, + 48, 4, 73, 69, 85, 80, 174, 26, 72, 163, 6, 65, 11, 11, 45, 8, 42, 80, + 222, 29, 84, 242, 1, 72, 99, 83, 2, 243, 25, 72, 6, 40, 4, 83, 65, 78, + 71, 143, 179, 13, 73, 4, 182, 28, 75, 187, 3, 83, 6, 100, 5, 73, 75, 69, + 85, 84, 151, 25, 72, 6, 56, 9, 79, 82, 73, 78, 72, 73, 69, 85, 72, 191, + 3, 83, 5, 255, 29, 45, 52, 48, 3, 73, 79, 83, 161, 1, 4, 83, 65, 78, 71, + 25, 11, 45, 22, 82, 75, 162, 3, 82, 242, 13, 67, 198, 2, 80, 254, 2, 77, + 138, 1, 84, 147, 5, 72, 4, 22, 65, 135, 26, 73, 2, 237, 18, 6, 80, 89, + 69, 79, 85, 78, 28, 160, 1, 5, 82, 73, 69, 85, 76, 36, 6, 84, 73, 75, 69, + 85, 84, 16, 3, 89, 69, 83, 138, 19, 83, 178, 1, 77, 154, 3, 67, 42, 75, + 42, 78, 34, 80, 179, 164, 18, 73, 5, 17, 2, 45, 75, 2, 159, 17, 72, 5, + 255, 16, 45, 2, 239, 188, 18, 73, 20, 40, 5, 73, 75, 69, 85, 84, 155, 21, + 72, 19, 11, 45, 16, 58, 82, 42, 83, 42, 84, 162, 13, 67, 130, 9, 75, 75, + 80, 2, 17, 2, 73, 69, 2, 203, 163, 24, 85, 4, 21, 3, 73, 79, 83, 5, 223, + 1, 45, 2, 255, 19, 72, 18, 44, 6, 83, 73, 69, 85, 78, 71, 243, 19, 79, + 17, 11, 45, 14, 50, 75, 30, 83, 198, 17, 77, 154, 6, 72, 63, 80, 4, 166, + 14, 72, 135, 7, 73, 4, 26, 83, 191, 171, 13, 73, 2, 21, 3, 65, 78, 71, 2, + 207, 20, 75, 190, 1, 122, 65, 118, 69, 134, 1, 73, 92, 7, 83, 83, 65, 78, + 71, 65, 82, 106, 79, 138, 1, 85, 102, 89, 174, 15, 87, 231, 145, 10, 70, + 23, 48, 4, 82, 65, 69, 65, 98, 45, 239, 170, 25, 69, 13, 11, 45, 10, 142, + 226, 22, 69, 178, 201, 2, 65, 2, 73, 3, 85, 25, 18, 79, 55, 85, 9, 11, + 45, 6, 130, 134, 25, 69, 234, 36, 79, 3, 85, 15, 11, 45, 12, 170, 9, 69, + 142, 161, 25, 65, 2, 79, 3, 85, 31, 11, 45, 28, 66, 65, 34, 89, 166, 1, + 79, 142, 131, 25, 69, 234, 36, 73, 3, 85, 5, 11, 82, 2, 171, 149, 18, 65, + 14, 50, 65, 182, 223, 22, 69, 178, 201, 2, 79, 3, 85, 7, 238, 137, 25, + 45, 247, 30, 69, 23, 26, 45, 171, 168, 25, 69, 18, 50, 79, 22, 89, 178, + 222, 22, 69, 179, 201, 2, 85, 5, 155, 148, 25, 45, 8, 174, 222, 22, 69, + 147, 137, 2, 65, 17, 11, 45, 14, 158, 19, 89, 130, 163, 5, 73, 180, 132, + 13, 3, 69, 79, 45, 190, 172, 6, 65, 163, 64, 85, 62, 42, 65, 70, 69, 66, + 73, 22, 79, 107, 85, 11, 26, 45, 147, 166, 25, 69, 6, 154, 135, 25, 89, + 246, 30, 79, 3, 85, 11, 11, 79, 9, 11, 45, 6, 150, 163, 25, 89, 186, 2, + 79, 3, 85, 5, 191, 128, 25, 45, 19, 11, 45, 16, 58, 89, 174, 228, 24, 65, + 174, 33, 69, 246, 30, 73, 3, 79, 6, 170, 228, 24, 65, 175, 33, 69, 21, + 11, 45, 18, 142, 16, 89, 226, 202, 22, 69, 146, 137, 2, 65, 162, 64, 73, + 2, 79, 3, 85, 186, 1, 226, 1, 65, 46, 67, 54, 69, 30, 73, 22, 75, 188, 1, + 5, 77, 73, 69, 85, 77, 64, 5, 78, 73, 69, 85, 78, 70, 80, 168, 1, 5, 82, + 73, 69, 85, 76, 254, 1, 84, 90, 83, 246, 2, 87, 50, 89, 150, 1, 72, 202, + 213, 24, 79, 163, 64, 85, 9, 156, 13, 3, 82, 65, 69, 207, 148, 25, 69, 4, + 22, 72, 207, 8, 73, 2, 241, 254, 24, 2, 73, 69, 7, 138, 161, 25, 79, 3, + 85, 5, 179, 173, 18, 69, 14, 56, 7, 65, 80, 89, 69, 79, 85, 78, 106, 72, + 155, 3, 73, 8, 30, 80, 30, 83, 231, 3, 77, 4, 190, 4, 72, 215, 3, 73, 2, + 25, 4, 83, 65, 78, 71, 2, 207, 7, 80, 2, 241, 60, 2, 73, 69, 9, 11, 45, + 6, 22, 80, 247, 9, 83, 4, 142, 7, 73, 207, 2, 65, 13, 11, 45, 10, 234, 5, + 67, 146, 1, 84, 242, 1, 72, 62, 80, 39, 83, 20, 48, 4, 73, 69, 85, 80, + 170, 2, 72, 163, 6, 65, 17, 11, 45, 14, 42, 83, 186, 2, 84, 146, 2, 67, + 43, 75, 6, 21, 3, 73, 79, 83, 7, 11, 45, 4, 202, 4, 75, 107, 84, 27, 11, + 45, 24, 68, 2, 75, 73, 34, 77, 34, 80, 106, 84, 54, 89, 222, 4, 72, 99, + 83, 4, 149, 1, 4, 89, 69, 79, 75, 2, 11, 73, 2, 207, 240, 23, 69, 8, 30, + 72, 34, 73, 131, 6, 65, 2, 197, 232, 18, 3, 73, 69, 85, 4, 21, 3, 69, 85, + 80, 5, 243, 5, 45, 4, 22, 72, 151, 3, 73, 2, 241, 245, 21, 2, 73, 69, 2, + 17, 2, 69, 79, 2, 167, 4, 82, 28, 44, 3, 73, 79, 83, 57, 4, 83, 65, 78, + 71, 13, 11, 45, 10, 122, 67, 42, 75, 42, 78, 34, 80, 35, 84, 16, 78, 67, + 42, 75, 42, 78, 34, 80, 34, 84, 242, 1, 72, 98, 83, 195, 161, 18, 73, 2, + 11, 73, 2, 201, 238, 23, 2, 69, 85, 2, 11, 73, 2, 209, 238, 24, 2, 89, + 69, 2, 11, 73, 2, 219, 151, 24, 69, 2, 11, 73, 2, 247, 161, 24, 69, 2, + 11, 73, 2, 11, 75, 2, 239, 157, 24, 69, 10, 250, 205, 22, 69, 146, 137, + 2, 65, 163, 64, 73, 34, 58, 69, 206, 1, 79, 62, 85, 154, 212, 24, 65, + 163, 64, 73, 13, 42, 79, 73, 6, 83, 73, 69, 85, 78, 71, 5, 11, 82, 2, 17, + 2, 73, 78, 2, 11, 72, 2, 157, 239, 9, 2, 73, 69, 7, 11, 45, 4, 18, 80, + 39, 83, 2, 11, 65, 2, 11, 78, 2, 11, 83, 2, 155, 147, 13, 73, 9, 11, 45, + 6, 26, 89, 207, 148, 25, 73, 4, 171, 212, 24, 65, 9, 11, 45, 6, 26, 89, + 147, 148, 25, 73, 4, 223, 202, 22, 69, 24, 138, 136, 11, 84, 230, 152, + 12, 70, 30, 83, 182, 87, 78, 14, 79, 227, 112, 69, 100, 156, 1, 7, 76, + 69, 84, 84, 69, 82, 32, 196, 2, 5, 77, 65, 82, 75, 32, 72, 5, 83, 73, 71, + 78, 32, 224, 159, 2, 6, 86, 79, 87, 69, 76, 32, 159, 251, 20, 68, 58, + 202, 1, 68, 34, 75, 246, 251, 20, 84, 178, 55, 82, 238, 223, 1, 78, 214, + 181, 1, 83, 138, 69, 66, 2, 67, 2, 70, 2, 71, 2, 72, 2, 74, 2, 76, 2, 77, + 2, 80, 2, 86, 2, 87, 2, 89, 2, 90, 187, 2, 65, 4, 138, 142, 25, 68, 187, + 2, 65, 8, 56, 5, 73, 78, 78, 65, 32, 178, 141, 25, 72, 187, 2, 65, 4, + 174, 141, 25, 87, 3, 89, 4, 136, 213, 21, 6, 78, 65, 32, 75, 72, 79, 237, + 186, 2, 3, 83, 65, 75, 8, 52, 2, 84, 65, 213, 254, 22, 5, 72, 65, 82, 66, + 65, 6, 42, 72, 174, 155, 20, 83, 191, 240, 4, 78, 2, 135, 236, 24, 65, + 42, 62, 76, 152, 243, 18, 6, 83, 73, 71, 78, 32, 80, 247, 1, 86, 36, 33, + 6, 69, 84, 84, 69, 82, 32, 36, 162, 151, 21, 78, 206, 243, 3, 66, 2, 68, + 2, 71, 2, 72, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, 2, + 89, 186, 2, 65, 2, 73, 3, 85, 2, 211, 251, 23, 69, 4, 210, 196, 23, 68, + 163, 199, 1, 80, 54, 52, 5, 67, 72, 73, 78, 71, 41, 4, 82, 65, 78, 32, 2, + 17, 2, 32, 67, 2, 243, 216, 23, 72, 52, 52, 7, 76, 69, 84, 84, 69, 82, + 32, 223, 182, 6, 78, 42, 218, 1, 65, 186, 173, 11, 90, 238, 46, 84, 146, + 120, 76, 50, 81, 60, 6, 68, 65, 76, 69, 84, 72, 214, 169, 4, 71, 122, 83, + 66, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, 134, + 2, 87, 218, 103, 80, 171, 4, 77, 4, 222, 254, 16, 76, 159, 186, 7, 89, + 174, 9, 210, 1, 65, 242, 32, 66, 130, 33, 76, 200, 1, 16, 78, 84, 65, 73, + 71, 65, 78, 65, 32, 76, 69, 84, 84, 69, 82, 32, 174, 12, 82, 120, 11, 88, + 65, 71, 82, 65, 77, 32, 70, 79, 82, 32, 165, 181, 24, 4, 68, 71, 69, 72, + 214, 1, 42, 68, 98, 82, 201, 1, 3, 86, 89, 32, 6, 44, 5, 83, 84, 79, 78, + 69, 159, 217, 23, 80, 5, 137, 223, 2, 7, 32, 71, 82, 65, 86, 69, 89, 12, + 32, 2, 84, 32, 251, 155, 17, 45, 10, 60, 5, 87, 73, 84, 72, 32, 198, 163, + 12, 68, 239, 158, 9, 72, 6, 76, 9, 84, 73, 80, 32, 79, 78, 32, 84, 72, + 238, 242, 12, 82, 243, 244, 10, 65, 2, 215, 209, 24, 69, 196, 1, 134, 2, + 65, 202, 1, 66, 230, 2, 67, 154, 3, 68, 162, 1, 69, 186, 3, 70, 94, 72, + 62, 76, 222, 1, 77, 110, 79, 162, 1, 82, 142, 2, 83, 228, 1, 3, 78, 79, + 82, 198, 1, 84, 128, 2, 2, 85, 80, 174, 1, 87, 162, 140, 14, 73, 222, + 243, 3, 80, 130, 142, 4, 86, 227, 78, 71, 12, 108, 17, 82, 82, 79, 87, + 32, 83, 72, 65, 70, 84, 32, 87, 73, 68, 84, 72, 32, 158, 163, 18, 77, + 207, 198, 4, 83, 8, 36, 3, 79, 78, 69, 239, 157, 23, 84, 7, 11, 32, 4, + 202, 238, 13, 84, 251, 139, 9, 72, 14, 48, 4, 65, 76, 76, 79, 21, 4, 76, + 65, 67, 75, 2, 191, 231, 5, 84, 12, 30, 32, 153, 1, 2, 45, 70, 6, 52, 7, + 67, 85, 82, 86, 69, 68, 32, 239, 247, 23, 72, 4, 40, 4, 68, 79, 87, 78, + 1, 2, 85, 80, 2, 201, 220, 23, 8, 87, 65, 82, 68, 83, 32, 65, 78, 6, 45, + 9, 69, 65, 84, 72, 69, 82, 69, 68, 32, 6, 134, 212, 13, 83, 174, 173, 3, + 78, 215, 218, 6, 82, 14, 116, 2, 72, 69, 52, 5, 73, 82, 67, 76, 69, 253, + 224, 17, 14, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 68, 4, + 172, 213, 20, 4, 86, 82, 79, 78, 255, 225, 2, 67, 9, 64, 6, 32, 87, 73, + 84, 72, 32, 161, 227, 22, 4, 68, 32, 83, 65, 4, 52, 7, 83, 84, 82, 79, + 75, 69, 32, 163, 253, 4, 67, 2, 29, 5, 65, 78, 68, 32, 84, 2, 11, 87, 2, + 11, 79, 2, 21, 3, 32, 68, 79, 2, 11, 84, 2, 199, 253, 23, 83, 14, 52, 7, + 65, 83, 72, 69, 68, 32, 84, 18, 73, 31, 79, 2, 175, 16, 82, 2, 137, 154, + 19, 2, 86, 73, 10, 192, 16, 3, 87, 78, 87, 222, 139, 14, 85, 191, 184, 4, + 76, 16, 120, 5, 73, 71, 72, 84, 32, 156, 2, 16, 88, 67, 76, 65, 77, 65, + 84, 73, 79, 78, 32, 77, 65, 82, 75, 32, 175, 209, 18, 81, 10, 40, 2, 80, + 79, 126, 84, 131, 223, 22, 83, 6, 33, 6, 73, 78, 84, 69, 68, 32, 6, 170, + 191, 16, 80, 128, 158, 6, 11, 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 82, + 23, 66, 2, 169, 223, 22, 24, 69, 65, 82, 68, 82, 79, 80, 45, 83, 80, 79, + 75, 69, 68, 32, 80, 82, 79, 80, 69, 76, 76, 69, 82, 4, 210, 224, 23, 83, + 227, 81, 79, 6, 44, 5, 79, 85, 82, 32, 66, 231, 252, 4, 73, 2, 157, 131, + 11, 6, 65, 76, 76, 79, 79, 78, 4, 214, 191, 17, 79, 161, 233, 5, 6, 69, + 65, 82, 84, 32, 69, 20, 74, 65, 44, 3, 69, 70, 84, 28, 2, 79, 87, 241, + 247, 4, 3, 73, 71, 65, 4, 208, 222, 21, 2, 82, 71, 211, 209, 1, 84, 8, + 254, 3, 45, 195, 6, 87, 6, 26, 32, 239, 147, 10, 69, 4, 178, 150, 14, 68, + 25, 4, 83, 73, 78, 71, 4, 56, 8, 85, 76, 84, 73, 80, 76, 73, 67, 143, + 192, 21, 73, 2, 25, 4, 65, 84, 73, 79, 2, 211, 217, 5, 78, 6, 200, 143, + 6, 9, 80, 69, 78, 32, 67, 69, 78, 84, 82, 172, 176, 10, 13, 86, 65, 76, + 32, 87, 73, 84, 72, 32, 79, 86, 65, 76, 213, 151, 6, 5, 85, 84, 76, 73, + 78, 12, 76, 4, 73, 71, 72, 84, 233, 205, 23, 9, 79, 85, 78, 68, 45, 84, + 73, 80, 80, 10, 62, 45, 109, 11, 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, + 87, 4, 69, 15, 80, 79, 73, 78, 84, 73, 78, 71, 32, 65, 78, 71, 76, 69, + 32, 4, 138, 233, 6, 66, 255, 169, 7, 81, 7, 139, 6, 32, 26, 106, 65, 78, + 73, 44, 2, 79, 85, 240, 154, 14, 7, 67, 82, 73, 80, 84, 32, 76, 193, 139, + 1, 3, 80, 65, 82, 4, 132, 146, 14, 10, 78, 83, 45, 83, 69, 82, 73, 70, + 32, 73, 175, 195, 8, 76, 8, 240, 143, 14, 2, 78, 71, 183, 194, 8, 88, 10, + 21, 3, 84, 72, 32, 10, 60, 5, 69, 65, 83, 84, 32, 29, 6, 87, 69, 83, 84, + 32, 80, 6, 26, 80, 191, 207, 23, 65, 4, 41, 8, 79, 73, 78, 84, 73, 78, + 71, 32, 4, 226, 242, 16, 86, 255, 202, 6, 66, 12, 88, 9, 69, 65, 82, 68, + 82, 79, 80, 45, 83, 130, 1, 82, 197, 229, 6, 4, 87, 69, 76, 86, 6, 64, 6, + 80, 79, 75, 69, 68, 32, 229, 199, 23, 4, 72, 65, 78, 75, 4, 192, 210, 22, + 8, 80, 73, 78, 87, 72, 69, 69, 76, 27, 65, 2, 193, 3, 5, 73, 65, 78, 71, + 76, 6, 26, 87, 219, 137, 10, 80, 4, 53, 11, 65, 82, 68, 83, 32, 65, 82, + 82, 79, 87, 32, 4, 29, 5, 87, 73, 84, 72, 32, 4, 128, 134, 20, 5, 76, 65, + 82, 71, 69, 179, 243, 1, 69, 12, 76, 5, 72, 73, 84, 69, 32, 164, 1, 2, + 73, 68, 253, 252, 22, 3, 69, 68, 71, 8, 64, 6, 83, 81, 85, 65, 82, 69, + 158, 219, 17, 68, 187, 183, 5, 67, 5, 145, 178, 23, 19, 32, 67, 79, 78, + 84, 65, 73, 78, 73, 78, 71, 32, 66, 76, 65, 67, 75, 32, 86, 2, 157, 247, + 20, 2, 69, 45, 142, 2, 40, 4, 82, 69, 87, 32, 195, 229, 24, 69, 140, 2, + 112, 7, 65, 67, 67, 69, 78, 84, 32, 142, 8, 76, 164, 14, 5, 77, 65, 82, + 75, 32, 114, 80, 201, 172, 21, 2, 89, 79, 60, 128, 2, 9, 65, 84, 78, 65, + 72, 32, 72, 65, 70, 22, 68, 36, 3, 71, 69, 82, 74, 77, 124, 2, 80, 65, + 28, 4, 69, 84, 78, 65, 20, 2, 81, 65, 58, 83, 58, 84, 156, 1, 2, 89, 69, + 78, 90, 148, 169, 8, 3, 82, 69, 86, 242, 141, 15, 79, 245, 148, 1, 3, 73, + 76, 85, 2, 219, 161, 18, 85, 4, 182, 138, 19, 69, 171, 149, 5, 65, 6, 32, + 3, 69, 83, 72, 179, 28, 83, 5, 165, 224, 6, 4, 32, 77, 85, 81, 8, 84, 5, + 69, 82, 75, 72, 65, 236, 242, 17, 2, 85, 78, 153, 45, 5, 65, 72, 65, 80, + 65, 5, 197, 229, 19, 4, 32, 75, 69, 70, 4, 26, 83, 195, 162, 24, 90, 2, + 223, 187, 24, 72, 4, 200, 155, 24, 6, 82, 78, 69, 89, 32, 80, 191, 35, + 68, 4, 182, 24, 69, 161, 229, 22, 6, 72, 65, 76, 83, 72, 69, 8, 38, 69, + 217, 225, 22, 3, 73, 80, 69, 6, 48, 6, 76, 73, 83, 72, 65, 32, 239, 223, + 11, 86, 4, 228, 170, 22, 3, 81, 69, 84, 205, 145, 2, 4, 71, 69, 68, 79, + 4, 228, 208, 8, 10, 82, 65, 72, 32, 66, 69, 78, 32, 89, 79, 155, 217, 2, + 84, 8, 18, 65, 95, 73, 6, 40, 4, 81, 69, 70, 32, 219, 130, 6, 82, 4, 222, + 134, 11, 81, 149, 193, 12, 3, 71, 65, 68, 2, 231, 163, 24, 78, 150, 1, + 76, 6, 69, 84, 84, 69, 82, 32, 201, 11, 8, 73, 71, 65, 84, 85, 82, 69, + 32, 140, 1, 134, 3, 65, 204, 1, 3, 66, 69, 84, 0, 3, 75, 65, 70, 0, 2, + 80, 69, 68, 6, 70, 73, 78, 65, 76, 32, 92, 2, 81, 79, 16, 2, 72, 69, 52, + 2, 78, 85, 0, 4, 90, 65, 89, 73, 18, 83, 48, 3, 82, 69, 83, 170, 1, 84, + 52, 4, 68, 65, 76, 69, 12, 5, 71, 73, 77, 69, 76, 0, 5, 76, 65, 77, 69, + 68, 0, 3, 77, 69, 77, 48, 3, 86, 65, 86, 80, 5, 87, 73, 68, 69, 32, 153, + 1, 3, 89, 79, 68, 14, 26, 76, 239, 216, 23, 89, 12, 64, 2, 69, 70, 73, + 10, 84, 69, 82, 78, 65, 84, 73, 86, 69, 32, 9, 33, 6, 32, 87, 73, 84, 72, + 32, 6, 130, 13, 77, 130, 1, 80, 35, 81, 4, 174, 206, 16, 65, 131, 161, 1, + 80, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 138, 15, 82, 171, 225, 13, 68, + 14, 88, 2, 75, 65, 236, 2, 2, 80, 69, 148, 154, 1, 2, 84, 83, 194, 184, + 22, 78, 135, 110, 77, 4, 235, 2, 70, 7, 244, 10, 5, 32, 87, 73, 84, 72, + 235, 202, 24, 84, 4, 167, 2, 78, 16, 44, 4, 65, 77, 69, 75, 17, 3, 72, + 73, 78, 4, 231, 1, 72, 13, 33, 6, 32, 87, 73, 84, 72, 32, 10, 40, 6, 68, + 65, 71, 69, 83, 72, 39, 83, 7, 33, 6, 32, 65, 78, 68, 32, 83, 4, 142, + 130, 6, 72, 155, 193, 2, 73, 12, 50, 69, 12, 2, 65, 86, 1, 4, 83, 65, 68, + 73, 4, 11, 84, 5, 201, 236, 13, 7, 32, 87, 73, 84, 72, 32, 68, 7, 33, 6, + 32, 87, 73, 84, 72, 32, 4, 208, 253, 1, 2, 72, 79, 167, 238, 11, 68, 16, + 174, 2, 76, 178, 207, 8, 65, 230, 191, 2, 84, 158, 218, 2, 82, 156, 132, + 9, 2, 68, 65, 218, 96, 75, 222, 106, 72, 169, 4, 7, 70, 73, 78, 65, 76, + 32, 77, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 172, 7, 2, 72, 73, 227, 226, + 13, 68, 10, 72, 6, 65, 76, 69, 70, 32, 76, 29, 8, 89, 73, 68, 68, 73, 83, + 72, 32, 2, 185, 187, 19, 2, 65, 77, 8, 120, 7, 68, 79, 85, 66, 76, 69, + 32, 232, 4, 9, 89, 79, 68, 32, 89, 79, 68, 32, 80, 169, 143, 21, 5, 86, + 65, 86, 32, 89, 4, 250, 141, 11, 86, 151, 134, 10, 89, 6, 80, 3, 76, 79, + 87, 0, 3, 85, 80, 80, 149, 249, 22, 6, 77, 65, 83, 79, 82, 65, 2, 145, + 186, 23, 2, 69, 82, 50, 84, 5, 79, 73, 78, 84, 32, 225, 5, 11, 85, 78, + 67, 84, 85, 65, 84, 73, 79, 78, 32, 38, 228, 1, 9, 68, 65, 71, 69, 83, + 72, 32, 79, 82, 46, 72, 106, 80, 162, 1, 81, 86, 82, 22, 83, 148, 213, 9, + 2, 84, 83, 148, 153, 11, 17, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, + 83, 72, 32, 86, 65, 82, 189, 147, 3, 3, 77, 69, 84, 2, 17, 2, 32, 77, 2, + 197, 1, 2, 65, 80, 12, 60, 5, 65, 84, 65, 70, 32, 102, 73, 33, 4, 79, 76, + 65, 77, 6, 38, 80, 34, 81, 141, 2, 2, 83, 69, 2, 11, 65, 2, 199, 219, 17, + 84, 2, 233, 192, 23, 2, 65, 77, 2, 11, 82, 2, 243, 229, 13, 73, 5, 181, + 136, 11, 12, 32, 72, 65, 83, 69, 82, 32, 70, 79, 82, 32, 86, 6, 52, 5, + 65, 77, 65, 84, 83, 221, 190, 11, 2, 85, 66, 5, 217, 241, 10, 2, 32, 81, + 2, 211, 228, 6, 65, 8, 34, 69, 22, 72, 215, 182, 8, 73, 2, 155, 178, 23, + 71, 4, 210, 182, 8, 73, 147, 210, 7, 69, 12, 152, 1, 3, 71, 69, 82, 60, + 3, 80, 65, 83, 20, 7, 83, 79, 70, 32, 80, 65, 83, 216, 136, 22, 7, 78, + 85, 78, 32, 72, 65, 70, 253, 186, 1, 3, 77, 65, 81, 4, 26, 83, 179, 218, + 22, 69, 2, 229, 194, 23, 3, 72, 65, 89, 2, 255, 225, 13, 69, 2, 235, 225, + 13, 85, 8, 114, 77, 176, 149, 12, 15, 76, 83, 67, 72, 82, 69, 73, 66, 69, + 82, 32, 80, 65, 85, 83, 229, 227, 5, 3, 73, 67, 79, 4, 196, 225, 5, 12, + 69, 84, 32, 87, 73, 84, 72, 32, 87, 72, 73, 84, 255, 204, 17, 32, 188, 4, + 164, 1, 2, 65, 45, 50, 72, 70, 75, 230, 1, 77, 114, 78, 146, 2, 82, 66, + 83, 154, 1, 84, 226, 1, 87, 62, 89, 110, 69, 234, 244, 8, 85, 150, 170, + 5, 79, 139, 192, 3, 73, 8, 134, 163, 24, 87, 246, 30, 49, 2, 50, 3, 51, + 72, 166, 6, 79, 250, 194, 8, 65, 230, 223, 5, 85, 166, 116, 69, 3, 73, + 74, 72, 2, 65, 45, 104, 2, 79, 45, 178, 4, 73, 226, 3, 69, 163, 147, 15, + 85, 24, 250, 233, 11, 49, 238, 191, 12, 75, 214, 22, 50, 2, 51, 2, 52, 2, + 53, 2, 54, 2, 55, 2, 56, 3, 57, 8, 250, 171, 24, 75, 218, 19, 49, 2, 50, + 3, 51, 54, 68, 2, 69, 45, 154, 7, 79, 162, 147, 15, 65, 2, 73, 231, 203, + 2, 85, 6, 162, 188, 24, 77, 186, 2, 49, 3, 50, 68, 116, 2, 69, 45, 72, 2, + 73, 45, 246, 2, 65, 166, 247, 8, 79, 150, 170, 5, 85, 225, 146, 6, 6, 45, + 77, 85, 45, 77, 79, 14, 198, 158, 24, 75, 246, 30, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 3, 54, 16, 158, 166, 24, 84, 214, 22, 49, 2, 50, 2, 51, 2, 52, + 2, 53, 2, 54, 3, 55, 54, 222, 4, 79, 2, 85, 162, 147, 15, 73, 230, 203, + 2, 65, 3, 69, 68, 62, 65, 2, 85, 226, 3, 73, 234, 244, 8, 69, 187, 158, + 6, 79, 16, 11, 45, 16, 150, 187, 24, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 54, 2, 55, 3, 56, 64, 74, 69, 20, 2, 79, 45, 72, 2, 85, 45, 130, 149, 15, + 73, 231, 203, 2, 65, 18, 223, 249, 18, 45, 14, 178, 183, 24, 82, 186, 2, + 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 10, 174, 154, 24, 84, 246, 30, 49, + 2, 50, 2, 51, 3, 52, 42, 142, 246, 8, 65, 2, 73, 186, 158, 6, 79, 231, + 203, 2, 69, 32, 40, 2, 65, 45, 66, 79, 135, 223, 17, 85, 12, 142, 153, + 24, 89, 246, 30, 49, 2, 50, 2, 51, 2, 52, 3, 53, 12, 11, 45, 12, 182, + 183, 24, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 4, 240, 170, 8, 21, 77, + 73, 84, 73, 65, 78, 32, 67, 79, 78, 74, 85, 71, 65, 84, 69, 32, 77, 65, + 84, 82, 139, 140, 16, 66, 128, 1, 210, 2, 65, 110, 66, 144, 1, 2, 67, 79, + 94, 68, 198, 2, 70, 66, 71, 40, 4, 72, 79, 76, 68, 164, 1, 2, 73, 78, + 116, 2, 77, 79, 58, 79, 122, 80, 100, 2, 82, 69, 66, 83, 238, 1, 84, 210, + 5, 87, 148, 160, 15, 4, 76, 73, 77, 73, 140, 191, 5, 11, 89, 79, 85, 84, + 72, 70, 85, 76, 32, 70, 79, 137, 177, 3, 9, 69, 78, 84, 72, 85, 83, 73, + 65, 83, 6, 76, 3, 80, 80, 82, 124, 4, 70, 84, 69, 82, 185, 161, 19, 4, + 66, 85, 78, 68, 2, 177, 144, 24, 2, 79, 65, 6, 92, 5, 69, 70, 79, 82, 69, + 156, 213, 3, 6, 73, 84, 73, 78, 71, 32, 1, 4, 82, 69, 65, 75, 2, 141, + 225, 23, 7, 32, 67, 79, 77, 80, 76, 69, 6, 26, 78, 179, 152, 19, 77, 4, + 180, 202, 20, 4, 84, 69, 77, 80, 209, 213, 2, 3, 70, 76, 73, 14, 110, 69, + 78, 73, 202, 156, 19, 85, 241, 245, 2, 15, 65, 82, 75, 69, 78, 73, 78, + 71, 32, 79, 70, 32, 84, 72, 69, 6, 218, 152, 19, 67, 192, 6, 2, 76, 73, + 149, 205, 4, 5, 86, 69, 76, 79, 80, 4, 248, 142, 19, 21, 70, 70, 73, 67, + 85, 76, 84, 89, 32, 65, 84, 32, 84, 72, 69, 32, 66, 69, 71, 73, 78, 169, + 253, 2, 4, 83, 80, 69, 82, 4, 216, 147, 19, 2, 79, 76, 165, 197, 4, 5, + 69, 76, 76, 79, 87, 12, 36, 5, 65, 84, 72, 69, 82, 35, 82, 2, 165, 139, + 15, 3, 73, 78, 71, 10, 40, 4, 69, 65, 84, 32, 227, 239, 23, 65, 8, 22, + 80, 215, 5, 84, 6, 22, 79, 151, 5, 82, 4, 172, 2, 2, 83, 83, 147, 236, + 23, 87, 8, 50, 78, 202, 148, 19, 67, 217, 5, 3, 70, 76, 85, 4, 156, 154, + 19, 2, 79, 67, 197, 236, 1, 5, 69, 82, 32, 84, 82, 4, 172, 187, 22, 3, + 68, 69, 83, 145, 62, 3, 85, 84, 72, 6, 26, 66, 37, 2, 80, 80, 2, 221, + 217, 23, 4, 83, 84, 82, 85, 4, 26, 82, 183, 216, 23, 79, 2, 133, 135, 22, + 2, 69, 83, 6, 136, 144, 15, 9, 85, 83, 72, 73, 78, 71, 32, 85, 80, 192, + 137, 2, 3, 82, 79, 71, 143, 211, 6, 69, 6, 26, 84, 203, 132, 19, 86, 4, + 250, 149, 19, 85, 171, 137, 4, 82, 8, 132, 1, 5, 77, 65, 76, 76, 32, 224, + 171, 21, 6, 84, 65, 78, 68, 83, 84, 185, 244, 1, 11, 80, 76, 73, 84, 84, + 73, 78, 71, 32, 65, 80, 4, 24, 2, 80, 82, 43, 84, 2, 217, 150, 19, 5, 69, + 80, 79, 78, 68, 2, 11, 65, 2, 223, 213, 23, 77, 30, 36, 3, 72, 69, 32, + 227, 223, 17, 82, 28, 186, 2, 65, 130, 1, 67, 132, 1, 3, 70, 65, 77, 20, + 9, 82, 69, 67, 69, 80, 84, 73, 86, 69, 30, 87, 172, 22, 12, 77, 65, 82, + 82, 89, 73, 78, 71, 32, 77, 65, 73, 184, 150, 5, 6, 71, 69, 78, 84, 76, + 69, 164, 223, 10, 13, 75, 69, 69, 80, 73, 78, 71, 32, 83, 84, 73, 76, 76, + 173, 238, 3, 7, 74, 79, 89, 79, 85, 83, 32, 6, 58, 82, 161, 180, 11, 8, + 66, 89, 83, 77, 65, 76, 32, 87, 4, 196, 183, 20, 8, 79, 85, 83, 73, 78, + 71, 32, 84, 163, 218, 3, 77, 6, 188, 131, 1, 2, 65, 85, 228, 178, 19, 9, + 82, 69, 65, 84, 73, 86, 69, 32, 72, 161, 212, 1, 9, 76, 73, 78, 71, 73, + 78, 71, 32, 70, 2, 183, 254, 23, 73, 2, 233, 180, 20, 2, 32, 69, 4, 142, + 151, 22, 69, 189, 204, 1, 5, 65, 78, 68, 69, 82, 4, 242, 234, 6, 65, 205, + 162, 6, 14, 79, 82, 75, 32, 79, 78, 32, 84, 72, 69, 32, 68, 69, 67, 222, + 1, 236, 1, 2, 71, 72, 180, 2, 7, 82, 65, 71, 65, 78, 65, 32, 212, 4, 7, + 83, 84, 79, 82, 73, 67, 32, 212, 190, 15, 7, 78, 68, 85, 32, 84, 69, 77, + 240, 33, 4, 75, 73, 78, 71, 218, 249, 1, 66, 169, 180, 4, 8, 80, 80, 79, + 80, 79, 84, 65, 77, 12, 18, 32, 119, 45, 6, 216, 138, 5, 2, 66, 82, 184, + 243, 16, 6, 86, 79, 76, 84, 65, 71, 217, 49, 9, 79, 67, 84, 69, 84, 32, + 80, 82, 69, 6, 92, 11, 83, 80, 69, 69, 68, 32, 84, 82, 65, 73, 78, 173, + 203, 5, 6, 72, 69, 69, 76, 69, 68, 5, 157, 185, 11, 14, 32, 87, 73, 84, + 72, 32, 66, 85, 76, 76, 69, 84, 32, 78, 200, 1, 112, 9, 68, 73, 71, 82, + 65, 80, 72, 32, 89, 20, 7, 76, 69, 84, 84, 69, 82, 32, 154, 173, 1, 86, + 191, 199, 20, 73, 2, 183, 175, 17, 79, 194, 1, 194, 1, 65, 74, 83, 138, + 164, 1, 66, 162, 3, 78, 150, 2, 68, 2, 71, 2, 72, 2, 75, 2, 77, 2, 80, 2, + 82, 2, 84, 2, 90, 126, 87, 46, 89, 150, 201, 22, 86, 234, 36, 69, 2, 73, + 2, 79, 3, 85, 7, 37, 7, 82, 67, 72, 65, 73, 67, 32, 4, 150, 244, 23, 87, + 151, 14, 89, 42, 76, 5, 77, 65, 76, 76, 32, 146, 152, 24, 65, 2, 69, 2, + 73, 2, 79, 3, 85, 32, 230, 169, 1, 87, 46, 89, 150, 176, 5, 75, 130, 153, + 17, 84, 234, 36, 65, 2, 69, 2, 73, 2, 79, 3, 85, 2, 235, 182, 8, 83, 108, + 166, 1, 76, 52, 3, 78, 69, 89, 46, 82, 146, 7, 84, 138, 1, 85, 206, 192, + 16, 83, 178, 219, 2, 67, 220, 198, 3, 6, 77, 79, 84, 72, 69, 84, 134, + 167, 1, 79, 155, 3, 80, 6, 236, 144, 16, 4, 76, 79, 87, 32, 255, 132, 8, + 69, 4, 150, 163, 22, 66, 233, 161, 1, 2, 32, 80, 66, 60, 8, 73, 90, 79, + 78, 84, 65, 76, 32, 153, 6, 2, 83, 69, 60, 218, 1, 66, 110, 76, 152, 1, + 17, 79, 78, 69, 32, 69, 73, 71, 72, 84, 72, 32, 66, 76, 79, 67, 75, 45, + 88, 10, 83, 67, 65, 78, 32, 76, 73, 78, 69, 45, 46, 84, 146, 232, 21, 67, + 42, 69, 230, 6, 77, 150, 1, 82, 247, 2, 90, 6, 44, 5, 76, 65, 67, 75, 32, + 231, 217, 23, 65, 4, 38, 79, 217, 215, 22, 3, 72, 69, 88, 2, 203, 215, + 22, 67, 10, 40, 4, 73, 78, 69, 32, 247, 237, 21, 65, 8, 44, 5, 87, 73, + 84, 72, 32, 155, 238, 21, 69, 6, 26, 84, 195, 239, 21, 70, 4, 226, 239, + 21, 72, 243, 91, 73, 14, 184, 229, 16, 3, 49, 51, 53, 178, 171, 7, 50, 2, + 51, 2, 52, 2, 53, 2, 54, 3, 55, 8, 146, 144, 24, 49, 2, 51, 2, 55, 3, 57, + 10, 32, 2, 65, 66, 199, 242, 21, 82, 8, 26, 85, 199, 241, 21, 32, 6, 33, + 6, 76, 65, 84, 73, 79, 78, 7, 11, 32, 4, 128, 197, 9, 8, 87, 73, 84, 72, + 32, 74, 85, 83, 223, 148, 14, 83, 7, 11, 32, 4, 128, 195, 7, 2, 82, 65, + 159, 142, 16, 70, 10, 26, 32, 147, 130, 23, 69, 8, 86, 80, 232, 253, 18, + 5, 66, 69, 86, 69, 82, 144, 80, 3, 83, 80, 82, 179, 190, 4, 68, 2, 231, + 234, 14, 69, 12, 48, 6, 82, 71, 76, 65, 83, 83, 77, 2, 83, 69, 5, 233, + 185, 20, 14, 32, 87, 73, 84, 72, 32, 70, 76, 79, 87, 73, 78, 71, 32, 9, + 11, 32, 6, 88, 8, 87, 73, 84, 72, 32, 71, 65, 82, 181, 129, 22, 8, 66, + 85, 73, 76, 68, 73, 78, 71, 2, 135, 181, 22, 68, 7, 246, 138, 24, 74, 3, + 83, 8, 106, 83, 160, 244, 22, 11, 78, 68, 82, 69, 68, 32, 80, 79, 73, 78, + 84, 176, 13, 2, 71, 71, 163, 136, 1, 84, 2, 251, 246, 22, 72, 20, 80, 2, + 71, 73, 22, 80, 224, 1, 5, 83, 84, 69, 82, 69, 161, 129, 22, 2, 65, 67, + 4, 255, 243, 21, 69, 12, 60, 3, 72, 69, 78, 145, 157, 4, 6, 79, 68, 73, + 65, 83, 84, 11, 34, 32, 82, 65, 203, 252, 19, 45, 4, 26, 87, 215, 165, + 22, 66, 2, 21, 3, 73, 84, 72, 2, 197, 186, 3, 2, 32, 68, 2, 141, 220, 12, + 6, 84, 73, 79, 78, 32, 80, 2, 193, 241, 22, 2, 83, 73, 210, 5, 172, 1, 3, + 67, 69, 32, 152, 1, 2, 68, 69, 222, 24, 77, 222, 2, 78, 230, 35, 82, 132, + 2, 7, 90, 65, 75, 65, 89, 65, 32, 185, 242, 19, 9, 32, 76, 79, 86, 69, + 32, 89, 79, 85, 8, 114, 67, 236, 160, 11, 18, 72, 79, 67, 75, 69, 89, 32, + 83, 84, 73, 67, 75, 32, 65, 78, 68, 32, 80, 235, 190, 1, 83, 4, 138, 244, + 15, 82, 223, 231, 2, 85, 246, 1, 68, 3, 78, 84, 73, 201, 1, 9, 79, 71, + 82, 65, 80, 72, 73, 67, 32, 8, 64, 4, 67, 65, 76, 32, 105, 8, 70, 73, 67, + 65, 84, 73, 79, 78, 6, 32, 2, 84, 79, 131, 130, 23, 87, 5, 149, 247, 14, + 12, 32, 65, 78, 68, 32, 83, 76, 65, 78, 84, 69, 68, 2, 181, 233, 22, 2, + 32, 67, 238, 1, 208, 2, 11, 65, 78, 78, 79, 84, 65, 84, 73, 79, 78, 32, + 242, 3, 67, 72, 2, 68, 69, 248, 5, 5, 78, 85, 77, 66, 69, 22, 84, 224, + 239, 5, 8, 72, 65, 76, 70, 32, 70, 73, 76, 232, 186, 1, 5, 69, 78, 84, + 69, 82, 0, 3, 82, 73, 83, 24, 5, 76, 69, 86, 69, 76, 240, 138, 9, 5, 86, + 65, 82, 73, 65, 250, 233, 4, 70, 154, 47, 73, 243, 231, 1, 83, 32, 232, + 1, 5, 66, 79, 84, 84, 79, 22, 70, 82, 77, 62, 84, 140, 1, 4, 76, 73, 78, + 75, 196, 143, 1, 4, 83, 69, 67, 79, 234, 161, 6, 79, 224, 130, 6, 6, 82, + 69, 86, 69, 82, 83, 152, 222, 9, 5, 72, 69, 65, 86, 69, 169, 39, 3, 69, + 65, 82, 2, 143, 188, 23, 77, 6, 48, 3, 79, 85, 82, 197, 178, 23, 3, 73, + 82, 83, 4, 186, 187, 23, 84, 27, 32, 4, 36, 3, 73, 68, 68, 199, 147, 23, + 65, 2, 171, 181, 13, 76, 8, 34, 72, 46, 87, 151, 134, 8, 79, 4, 134, 146, + 9, 82, 237, 157, 14, 2, 73, 82, 2, 159, 186, 23, 79, 4, 36, 3, 76, 79, + 83, 227, 165, 21, 79, 2, 225, 185, 23, 3, 73, 78, 71, 36, 104, 20, 83, + 67, 82, 73, 80, 84, 73, 79, 78, 32, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 32, 211, 175, 7, 80, 34, 144, 2, 9, 65, 66, 79, 86, 69, 32, 84, 79, 32, + 84, 8, 76, 69, 70, 84, 32, 84, 79, 32, 76, 5, 79, 86, 69, 82, 76, 20, 2, + 83, 85, 222, 245, 14, 82, 172, 200, 5, 8, 70, 85, 76, 76, 32, 83, 85, 82, + 229, 231, 2, 15, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 82, 69, 70, + 76, 4, 60, 9, 77, 73, 68, 68, 76, 69, 32, 65, 78, 223, 213, 21, 66, 2, + 175, 198, 21, 68, 4, 144, 164, 22, 10, 77, 73, 68, 68, 76, 69, 32, 65, + 78, 68, 211, 168, 1, 82, 2, 147, 225, 16, 65, 18, 72, 12, 82, 82, 79, 85, + 78, 68, 32, 70, 82, 79, 77, 32, 223, 181, 17, 66, 16, 82, 76, 208, 203, + 11, 3, 85, 80, 80, 250, 135, 10, 66, 130, 165, 1, 65, 159, 82, 82, 6, + 194, 203, 11, 79, 147, 255, 11, 69, 2, 175, 217, 8, 82, 148, 1, 92, 10, + 65, 76, 76, 89, 32, 77, 65, 82, 75, 32, 41, 9, 69, 76, 69, 71, 82, 65, + 80, 72, 32, 10, 138, 129, 22, 70, 70, 84, 155, 87, 79, 138, 1, 140, 1, + 11, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 221, 230, 12, 17, 76, 73, + 78, 69, 32, 70, 69, 69, 68, 32, 83, 69, 80, 65, 82, 65, 84, 136, 1, 182, + 1, 65, 58, 68, 200, 2, 5, 72, 79, 85, 82, 32, 214, 1, 74, 28, 4, 70, 69, + 66, 82, 64, 2, 77, 65, 168, 196, 15, 3, 78, 79, 86, 0, 4, 83, 69, 80, 84, + 25, 4, 79, 67, 84, 79, 4, 168, 131, 20, 3, 85, 71, 85, 165, 142, 2, 2, + 80, 82, 64, 44, 3, 65, 89, 32, 241, 200, 15, 2, 69, 67, 62, 66, 84, 142, + 212, 5, 69, 66, 70, 70, 78, 26, 83, 159, 255, 16, 79, 34, 34, 72, 90, 87, + 155, 159, 23, 69, 8, 36, 3, 73, 82, 84, 139, 253, 21, 82, 6, 26, 89, 139, + 153, 22, 69, 5, 179, 194, 22, 45, 24, 26, 69, 223, 238, 23, 79, 22, 36, + 3, 78, 84, 89, 227, 241, 22, 76, 21, 139, 163, 15, 45, 50, 78, 84, 234, + 209, 5, 69, 66, 70, 70, 78, 26, 83, 194, 168, 16, 90, 223, 86, 79, 20, + 42, 87, 198, 211, 5, 72, 131, 202, 17, 69, 14, 26, 69, 139, 237, 23, 79, + 12, 36, 3, 78, 84, 89, 143, 240, 22, 76, 11, 175, 158, 17, 45, 6, 24, 2, + 65, 78, 35, 85, 2, 11, 85, 2, 191, 166, 17, 65, 4, 186, 213, 23, 78, 143, + 5, 76, 4, 198, 201, 23, 82, 171, 34, 89, 68, 40, 6, 65, 71, 69, 32, 79, + 70, 83, 80, 5, 161, 135, 9, 15, 32, 79, 82, 32, 65, 80, 80, 82, 79, 88, + 73, 77, 65, 84, 69, 65, 65, 14, 69, 82, 73, 65, 76, 32, 65, 82, 65, 77, + 65, 73, 67, 32, 62, 72, 7, 78, 85, 77, 66, 69, 82, 32, 230, 18, 76, 181, + 209, 19, 2, 83, 69, 16, 26, 84, 187, 199, 15, 79, 10, 130, 183, 11, 87, + 250, 147, 1, 69, 131, 172, 9, 72, 136, 3, 202, 1, 67, 234, 1, 68, 214, 6, + 70, 132, 2, 5, 72, 73, 66, 73, 84, 156, 1, 15, 80, 85, 84, 32, 83, 89, + 77, 66, 79, 76, 32, 70, 79, 82, 32, 206, 1, 83, 236, 5, 2, 84, 69, 206, + 8, 86, 147, 250, 9, 66, 10, 32, 2, 79, 77, 69, 2, 82, 69, 4, 140, 207, + 16, 3, 73, 78, 71, 209, 230, 2, 5, 80, 76, 69, 84, 69, 6, 36, 3, 65, 83, + 69, 239, 162, 23, 77, 4, 34, 32, 157, 180, 10, 2, 83, 32, 2, 161, 183, + 11, 8, 70, 79, 78, 84, 32, 83, 73, 90, 145, 1, 24, 2, 69, 88, 103, 73, 5, + 149, 202, 22, 20, 32, 80, 79, 73, 78, 84, 73, 78, 71, 32, 65, 84, 32, 84, + 72, 69, 32, 86, 73, 69, 138, 1, 72, 8, 67, 32, 83, 73, 89, 65, 81, 32, + 173, 136, 18, 4, 65, 78, 32, 82, 136, 1, 196, 1, 11, 65, 76, 84, 69, 82, + 78, 65, 84, 69, 32, 76, 2, 76, 28, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, + 100, 7, 78, 85, 77, 66, 69, 82, 32, 130, 247, 8, 82, 209, 120, 6, 80, 76, + 65, 67, 69, 72, 2, 201, 160, 23, 2, 65, 75, 6, 68, 4, 79, 78, 69, 32, + 205, 221, 21, 7, 84, 72, 82, 69, 69, 32, 81, 4, 162, 219, 21, 72, 47, 81, + 122, 212, 1, 10, 65, 76, 84, 69, 82, 78, 65, 84, 69, 32, 72, 5, 75, 65, + 82, 79, 82, 0, 4, 76, 65, 75, 72, 222, 137, 10, 69, 66, 70, 94, 78, 26, + 83, 78, 84, 236, 135, 5, 8, 80, 82, 69, 70, 73, 88, 69, 68, 199, 41, 79, + 6, 26, 84, 251, 195, 22, 79, 4, 132, 164, 6, 2, 69, 78, 175, 156, 17, 87, + 5, 155, 143, 23, 65, 16, 72, 5, 73, 78, 73, 84, 89, 85, 9, 79, 82, 77, + 65, 84, 73, 79, 78, 32, 5, 45, 9, 32, 78, 69, 71, 65, 84, 69, 68, 32, 2, + 225, 171, 8, 4, 87, 73, 84, 72, 12, 42, 83, 225, 216, 19, 4, 68, 69, 83, + 75, 10, 244, 152, 7, 5, 69, 80, 65, 82, 65, 243, 252, 9, 79, 4, 11, 32, + 4, 196, 139, 23, 15, 65, 82, 65, 66, 73, 67, 32, 70, 79, 82, 77, 32, 83, + 72, 65, 1, 14, 83, 89, 77, 77, 69, 84, 82, 73, 67, 32, 83, 87, 65, 80, + 10, 80, 6, 76, 65, 84, 73, 78, 32, 218, 244, 14, 83, 161, 213, 7, 4, 78, + 85, 77, 66, 6, 64, 6, 67, 65, 80, 73, 84, 65, 0, 4, 83, 77, 65, 76, 27, + 76, 2, 21, 3, 76, 32, 76, 2, 193, 214, 21, 2, 69, 84, 116, 84, 13, 67, + 82, 73, 80, 84, 73, 79, 78, 65, 76, 32, 80, 65, 245, 200, 15, 2, 69, 82, + 114, 72, 6, 72, 76, 65, 86, 73, 32, 225, 1, 7, 82, 84, 72, 73, 65, 78, + 32, 54, 48, 7, 76, 69, 84, 84, 69, 82, 32, 191, 3, 78, 38, 234, 171, 10, + 84, 222, 119, 65, 22, 68, 34, 76, 22, 77, 50, 87, 254, 169, 4, 71, 90, + 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, + 4, 78, 223, 105, 80, 60, 22, 76, 251, 1, 78, 44, 11, 69, 44, 29, 5, 84, + 84, 69, 82, 32, 44, 250, 169, 10, 84, 242, 119, 68, 34, 76, 50, 81, 214, + 205, 1, 82, 142, 220, 2, 65, 50, 71, 90, 90, 34, 83, 66, 89, 198, 207, 1, + 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, 134, 2, 87, 218, 103, 80, + 171, 4, 77, 16, 33, 6, 85, 77, 66, 69, 82, 32, 16, 242, 161, 11, 84, 226, + 144, 4, 79, 167, 134, 3, 70, 50, 36, 4, 71, 82, 65, 76, 179, 3, 82, 23, + 11, 32, 20, 58, 65, 140, 1, 5, 87, 73, 84, 72, 32, 135, 175, 21, 69, 4, + 96, 6, 86, 69, 82, 65, 71, 69, 169, 172, 16, 12, 82, 79, 85, 78, 68, 32, + 65, 32, 80, 79, 73, 78, 2, 205, 173, 16, 5, 32, 87, 73, 84, 72, 14, 160, + 1, 3, 84, 73, 77, 20, 2, 85, 78, 172, 239, 6, 16, 76, 69, 70, 84, 87, 65, + 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 246, 173, 13, 73, 198, 1, 79, + 251, 64, 68, 2, 227, 158, 20, 69, 4, 238, 158, 20, 68, 131, 226, 2, 73, + 28, 94, 76, 232, 1, 7, 83, 69, 67, 84, 73, 79, 78, 146, 7, 82, 232, 249, + 11, 2, 67, 65, 43, 73, 8, 164, 1, 17, 73, 78, 69, 65, 82, 32, 65, 78, 78, + 79, 84, 65, 84, 73, 79, 78, 32, 221, 235, 4, 17, 79, 67, 75, 69, 68, 32, + 70, 69, 77, 65, 76, 69, 32, 65, 78, 68, 32, 6, 208, 167, 8, 3, 65, 78, + 67, 146, 154, 8, 84, 159, 219, 3, 83, 15, 11, 32, 12, 168, 1, 6, 65, 66, + 79, 86, 69, 32, 64, 5, 87, 73, 84, 72, 32, 169, 152, 20, 22, 66, 69, 83, + 73, 68, 69, 32, 65, 78, 68, 32, 74, 79, 73, 78, 69, 68, 32, 87, 73, 84, + 72, 4, 152, 153, 20, 9, 66, 65, 82, 32, 65, 66, 79, 86, 69, 23, 85, 6, + 206, 169, 4, 76, 178, 240, 15, 79, 195, 225, 2, 68, 40, 56, 2, 69, 82, + 189, 5, 7, 73, 83, 73, 66, 76, 69, 32, 34, 48, 3, 83, 69, 32, 225, 2, 4, + 84, 69, 68, 32, 16, 174, 1, 66, 80, 5, 67, 72, 69, 67, 75, 68, 24, 68, + 79, 87, 78, 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 87, 73, 84, + 72, 32, 84, 73, 80, 210, 178, 20, 87, 219, 26, 77, 6, 44, 5, 76, 65, 67, + 75, 32, 227, 230, 21, 85, 4, 250, 137, 22, 68, 227, 27, 83, 4, 228, 204, + 20, 8, 69, 82, 32, 66, 79, 65, 82, 68, 183, 186, 2, 32, 2, 197, 230, 20, + 2, 32, 76, 18, 144, 1, 6, 73, 78, 84, 69, 82, 82, 22, 76, 146, 242, 11, + 80, 230, 184, 4, 69, 244, 198, 1, 2, 79, 72, 204, 158, 2, 4, 85, 78, 68, + 69, 183, 97, 81, 2, 131, 214, 4, 79, 6, 60, 9, 79, 87, 32, 75, 65, 86, + 89, 75, 65, 215, 231, 6, 65, 5, 205, 154, 18, 11, 32, 87, 73, 84, 72, 32, + 75, 65, 86, 89, 75, 6, 38, 84, 154, 186, 19, 80, 223, 89, 83, 2, 135, + 173, 16, 73, 4, 222, 169, 22, 69, 215, 93, 73, 218, 1, 94, 65, 138, 21, + 69, 62, 79, 42, 85, 133, 187, 11, 10, 73, 71, 83, 65, 87, 32, 80, 85, 90, + 90, 202, 1, 120, 5, 67, 75, 45, 79, 45, 32, 7, 80, 65, 78, 69, 83, 69, + 32, 184, 2, 7, 86, 65, 78, 69, 83, 69, 32, 183, 192, 23, 82, 2, 145, 176, + 18, 3, 76, 65, 78, 16, 246, 1, 67, 18, 80, 204, 153, 1, 10, 73, 78, 68, + 85, 83, 84, 82, 73, 65, 76, 236, 229, 3, 3, 66, 65, 78, 134, 174, 3, 68, + 144, 139, 11, 15, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 66, 69, 71, + 73, 180, 248, 1, 3, 71, 79, 66, 169, 109, 2, 79, 71, 2, 207, 32, 65, 2, + 141, 137, 13, 7, 79, 83, 84, 32, 79, 70, 70, 182, 1, 172, 2, 15, 67, 79, + 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 76, 2, 76, 69, 40, 4, + 82, 73, 71, 72, 224, 6, 2, 80, 65, 176, 3, 14, 84, 85, 82, 78, 69, 68, + 32, 80, 65, 68, 65, 32, 80, 73, 88, 5, 83, 73, 71, 78, 32, 144, 1, 11, + 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 143, 189, 21, 68, 6, 52, 2, + 75, 69, 164, 193, 16, 2, 80, 69, 175, 5, 67, 2, 175, 136, 23, 82, 96, 38, + 70, 65, 5, 84, 84, 69, 82, 32, 2, 41, 8, 84, 32, 82, 69, 82, 69, 78, 71, + 2, 195, 240, 21, 71, 94, 230, 1, 68, 26, 73, 48, 2, 75, 65, 66, 78, 130, + 1, 66, 2, 67, 2, 71, 16, 2, 80, 65, 56, 2, 82, 65, 32, 2, 83, 65, 42, 84, + 74, 74, 194, 170, 21, 65, 142, 138, 2, 72, 2, 76, 2, 77, 2, 87, 2, 89, + 186, 2, 69, 2, 79, 3, 85, 8, 222, 3, 68, 15, 65, 7, 236, 201, 5, 3, 32, + 75, 65, 223, 240, 17, 73, 7, 11, 32, 4, 22, 83, 215, 2, 77, 2, 237, 128, + 21, 2, 65, 83, 14, 36, 2, 71, 65, 90, 89, 167, 1, 65, 7, 33, 6, 32, 76, + 69, 76, 69, 84, 5, 29, 5, 32, 82, 65, 83, 87, 2, 211, 226, 5, 65, 4, 163, + 1, 65, 7, 11, 32, 4, 154, 1, 77, 129, 180, 23, 3, 67, 69, 82, 5, 213, + 196, 16, 3, 32, 65, 71, 7, 17, 2, 32, 77, 4, 70, 85, 71, 65, 8, 18, 65, + 55, 84, 5, 17, 2, 32, 77, 2, 11, 85, 2, 147, 146, 23, 82, 4, 11, 65, 5, + 11, 32, 2, 11, 77, 2, 11, 65, 2, 11, 72, 2, 213, 177, 17, 2, 65, 80, 28, + 40, 3, 68, 65, 32, 165, 3, 2, 78, 71, 24, 174, 1, 65, 90, 76, 86, 80, + 168, 147, 7, 10, 84, 73, 82, 84, 65, 32, 84, 85, 77, 69, 210, 130, 12, + 87, 168, 199, 2, 7, 73, 83, 69, 78, 45, 73, 83, 169, 211, 1, 3, 77, 65, + 68, 6, 44, 3, 68, 69, 71, 153, 161, 22, 2, 78, 68, 5, 11, 32, 2, 169, + 238, 22, 2, 65, 68, 6, 38, 85, 141, 177, 23, 3, 73, 78, 71, 4, 216, 192, + 18, 2, 78, 71, 163, 250, 3, 72, 4, 38, 73, 181, 185, 18, 3, 65, 78, 71, + 2, 157, 189, 16, 3, 83, 69, 76, 4, 244, 144, 13, 5, 82, 65, 78, 71, 75, + 251, 209, 9, 75, 10, 108, 5, 67, 69, 67, 65, 75, 172, 202, 5, 3, 87, 73, + 71, 254, 241, 10, 76, 249, 228, 2, 5, 80, 65, 78, 89, 65, 5, 133, 168, + 18, 3, 32, 84, 69, 18, 116, 4, 83, 85, 75, 85, 42, 84, 64, 4, 87, 85, 76, + 85, 246, 186, 16, 80, 137, 224, 1, 7, 68, 73, 82, 71, 65, 32, 77, 5, 201, + 182, 22, 5, 32, 77, 69, 78, 68, 6, 26, 65, 179, 188, 16, 79, 4, 154, 188, + 16, 82, 187, 162, 6, 76, 5, 25, 4, 32, 77, 69, 76, 2, 255, 171, 23, 73, + 4, 36, 3, 76, 76, 89, 179, 231, 19, 65, 2, 143, 202, 19, 70, 4, 168, 252, + 21, 2, 89, 83, 191, 98, 73, 6, 172, 192, 14, 2, 71, 71, 194, 135, 5, 80, + 191, 199, 3, 78, 142, 18, 74, 65, 178, 78, 69, 218, 1, 72, 214, 46, 73, 198, 6, 78, 50, 79, 111, 82, 202, 10, 200, 1, 5, 73, 84, 72, 73, 32, 234, 4, 78, 188, 45, 6, 84, 65, 75, 65, 78, 65, 208, 13, 3, 87, 73, 32, 220, - 8, 7, 89, 65, 72, 32, 76, 73, 32, 224, 201, 4, 6, 75, 84, 79, 86, 73, 75, - 135, 244, 17, 65, 136, 1, 204, 1, 7, 76, 69, 84, 84, 69, 82, 32, 178, 2, - 83, 150, 116, 68, 228, 243, 3, 2, 86, 79, 236, 137, 3, 11, 78, 85, 77, - 66, 69, 82, 32, 83, 73, 71, 78, 162, 202, 9, 65, 189, 211, 1, 6, 69, 78, - 85, 77, 69, 82, 90, 214, 1, 68, 190, 210, 19, 65, 150, 1, 84, 230, 5, 85, + 8, 7, 89, 65, 72, 32, 76, 73, 32, 148, 198, 4, 6, 75, 84, 79, 86, 73, 75, + 187, 239, 17, 65, 136, 1, 204, 1, 7, 76, 69, 84, 84, 69, 82, 32, 178, 2, + 83, 202, 112, 68, 228, 243, 3, 2, 86, 79, 236, 137, 3, 11, 78, 85, 77, + 66, 69, 82, 32, 83, 73, 71, 78, 214, 197, 9, 65, 189, 211, 1, 6, 69, 78, + 85, 77, 69, 82, 90, 214, 1, 68, 166, 202, 19, 65, 150, 1, 84, 230, 5, 85, 186, 202, 1, 73, 138, 196, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 2, 82, 138, 69, 72, 2, 76, 2, 77, 2, 86, 2, 89, 186, 2, 69, 3, - 79, 10, 38, 68, 210, 173, 23, 72, 187, 2, 65, 6, 222, 178, 21, 68, 242, - 250, 1, 72, 187, 2, 65, 12, 40, 4, 73, 71, 78, 32, 179, 156, 11, 69, 10, - 202, 145, 19, 67, 98, 78, 138, 216, 3, 65, 239, 1, 86, 232, 4, 42, 71, + 79, 10, 38, 68, 186, 165, 23, 72, 187, 2, 65, 6, 198, 170, 21, 68, 242, + 250, 1, 72, 187, 2, 65, 12, 40, 4, 73, 71, 78, 32, 155, 148, 11, 69, 10, + 178, 137, 19, 67, 98, 78, 138, 216, 3, 65, 239, 1, 86, 232, 4, 42, 71, 241, 39, 5, 78, 65, 68, 65, 32, 174, 3, 76, 11, 88, 73, 32, 82, 65, 68, - 73, 67, 65, 76, 32, 249, 226, 20, 2, 65, 82, 172, 3, 130, 2, 65, 94, 66, + 73, 67, 65, 76, 32, 225, 218, 20, 2, 65, 82, 172, 3, 130, 2, 65, 94, 66, 230, 2, 67, 150, 2, 68, 158, 3, 69, 198, 1, 70, 138, 2, 71, 146, 1, 72, 210, 2, 73, 76, 2, 74, 65, 34, 75, 30, 76, 230, 1, 77, 254, 1, 78, 62, 79, 102, 80, 110, 82, 166, 1, 83, 230, 6, 84, 226, 2, 86, 50, 87, 210, 2, - 89, 207, 251, 21, 85, 10, 56, 2, 82, 82, 198, 252, 21, 71, 202, 104, 78, - 207, 47, 88, 4, 138, 173, 22, 79, 207, 1, 73, 34, 58, 65, 38, 73, 46, 76, - 54, 79, 102, 82, 207, 220, 21, 69, 4, 242, 202, 5, 77, 183, 142, 14, 68, - 6, 158, 240, 21, 84, 238, 115, 82, 163, 70, 71, 6, 210, 239, 19, 79, 170, - 136, 2, 65, 179, 155, 1, 85, 10, 62, 76, 226, 140, 23, 65, 218, 5, 78, - 142, 5, 68, 203, 17, 87, 2, 253, 219, 3, 4, 84, 32, 79, 70, 6, 42, 73, - 158, 248, 9, 65, 155, 197, 11, 85, 2, 219, 255, 13, 83, 28, 58, 65, 70, - 76, 74, 79, 206, 181, 10, 72, 183, 129, 11, 73, 6, 38, 85, 154, 139, 23, - 82, 219, 5, 86, 2, 141, 128, 22, 2, 76, 68, 8, 42, 65, 190, 190, 7, 73, - 167, 210, 14, 79, 4, 250, 166, 23, 78, 3, 87, 10, 130, 130, 22, 82, 148, + 89, 183, 243, 21, 85, 10, 56, 2, 82, 82, 174, 244, 21, 71, 202, 104, 78, + 207, 47, 88, 4, 242, 164, 22, 79, 207, 1, 73, 34, 58, 65, 38, 73, 46, 76, + 54, 79, 102, 82, 183, 212, 21, 69, 4, 166, 199, 5, 77, 235, 137, 14, 68, + 6, 134, 232, 21, 84, 238, 115, 82, 163, 70, 71, 6, 186, 231, 19, 79, 170, + 136, 2, 65, 179, 155, 1, 85, 10, 62, 76, 202, 132, 23, 65, 218, 5, 78, + 142, 5, 68, 203, 17, 87, 2, 177, 216, 3, 4, 84, 32, 79, 70, 6, 42, 73, + 134, 240, 9, 65, 155, 197, 11, 85, 2, 195, 247, 13, 83, 28, 58, 65, 70, + 76, 74, 79, 182, 173, 10, 72, 183, 129, 11, 73, 6, 38, 85, 130, 131, 23, + 82, 219, 5, 86, 2, 245, 247, 21, 2, 76, 68, 8, 42, 65, 242, 186, 7, 73, + 219, 205, 14, 79, 4, 226, 158, 23, 78, 3, 87, 10, 234, 249, 21, 82, 148, 2, 2, 77, 80, 222, 100, 86, 134, 5, 76, 235, 56, 87, 34, 38, 69, 38, 73, - 98, 79, 195, 1, 82, 4, 242, 160, 21, 65, 159, 204, 1, 69, 8, 38, 83, 226, - 128, 14, 86, 175, 2, 80, 4, 208, 192, 19, 5, 84, 73, 78, 71, 85, 207, - 228, 3, 72, 16, 94, 84, 76, 3, 85, 66, 76, 138, 130, 13, 87, 252, 208, 9, - 2, 32, 78, 222, 23, 79, 223, 56, 71, 7, 25, 4, 84, 69, 68, 32, 4, 168, - 187, 7, 3, 67, 76, 73, 155, 165, 15, 84, 2, 175, 134, 4, 69, 6, 242, 232, + 98, 79, 195, 1, 82, 4, 218, 152, 21, 65, 159, 204, 1, 69, 8, 38, 83, 202, + 248, 13, 86, 175, 2, 80, 4, 184, 184, 19, 5, 84, 73, 78, 71, 85, 207, + 228, 3, 72, 16, 94, 84, 76, 3, 85, 66, 76, 242, 249, 12, 87, 252, 208, 9, + 2, 32, 78, 222, 23, 79, 223, 56, 71, 7, 25, 4, 84, 69, 68, 32, 4, 220, + 183, 7, 3, 67, 76, 73, 207, 160, 15, 84, 2, 227, 130, 4, 69, 6, 218, 224, 21, 65, 222, 169, 1, 85, 219, 16, 89, 20, 106, 65, 38, 78, 32, 3, 86, 69, - 78, 140, 131, 9, 6, 77, 66, 82, 79, 73, 68, 250, 243, 13, 73, 243, 19, - 89, 6, 170, 233, 16, 82, 227, 184, 6, 84, 4, 178, 25, 67, 203, 202, 22, - 84, 5, 207, 208, 22, 73, 28, 74, 65, 50, 73, 62, 76, 38, 82, 170, 20, 69, - 250, 186, 22, 79, 223, 23, 85, 6, 146, 255, 13, 84, 130, 139, 9, 67, 131, - 22, 78, 8, 234, 240, 12, 69, 150, 133, 10, 71, 230, 19, 82, 199, 21, 83, - 4, 230, 214, 21, 85, 151, 201, 1, 89, 4, 180, 239, 21, 2, 65, 71, 207, - 175, 1, 79, 14, 58, 79, 52, 2, 82, 65, 190, 176, 19, 72, 239, 164, 2, 65, - 7, 206, 216, 22, 76, 241, 34, 5, 32, 83, 76, 79, 87, 4, 218, 206, 22, 73, + 78, 244, 250, 8, 6, 77, 66, 82, 79, 73, 68, 250, 243, 13, 73, 243, 19, + 89, 6, 146, 225, 16, 82, 227, 184, 6, 84, 4, 178, 25, 67, 179, 194, 22, + 84, 5, 183, 200, 22, 73, 28, 74, 65, 50, 73, 62, 76, 38, 82, 170, 20, 69, + 226, 178, 22, 79, 223, 23, 85, 6, 250, 246, 13, 84, 130, 139, 9, 67, 131, + 22, 78, 8, 210, 232, 12, 69, 150, 133, 10, 71, 230, 19, 82, 199, 21, 83, + 4, 206, 206, 21, 85, 151, 201, 1, 89, 4, 156, 231, 21, 2, 65, 71, 207, + 175, 1, 79, 14, 58, 79, 52, 2, 82, 65, 166, 168, 19, 72, 239, 164, 2, 65, + 7, 182, 208, 22, 76, 241, 34, 5, 32, 83, 76, 79, 87, 4, 194, 198, 22, 73, 135, 18, 83, 22, 58, 65, 142, 1, 69, 60, 5, 73, 68, 73, 78, 71, 19, 79, - 8, 38, 76, 154, 215, 22, 78, 199, 13, 73, 4, 34, 70, 165, 132, 22, 2, 66, - 69, 2, 41, 8, 32, 84, 82, 69, 69, 32, 84, 82, 2, 135, 184, 19, 85, 6, 26, - 65, 175, 156, 23, 77, 4, 138, 128, 23, 82, 175, 28, 68, 2, 195, 19, 32, - 6, 26, 82, 215, 152, 23, 79, 4, 150, 133, 23, 83, 215, 22, 78, 6, 26, 78, - 223, 132, 23, 67, 4, 26, 83, 135, 154, 23, 67, 2, 135, 138, 22, 69, 4, - 170, 132, 23, 68, 215, 22, 82, 2, 133, 179, 5, 2, 78, 73, 22, 46, 65, 34, - 69, 78, 73, 41, 3, 79, 78, 71, 4, 190, 131, 23, 77, 191, 19, 67, 8, 38, - 65, 242, 219, 22, 71, 199, 58, 69, 4, 246, 247, 13, 84, 215, 161, 9, 70, - 6, 210, 130, 23, 70, 2, 78, 215, 22, 68, 5, 153, 204, 11, 3, 32, 83, 84, - 22, 42, 69, 34, 73, 46, 79, 139, 200, 22, 65, 4, 198, 200, 22, 76, 195, - 51, 65, 4, 128, 243, 11, 2, 78, 73, 139, 195, 9, 76, 12, 34, 82, 34, 85, - 199, 199, 22, 79, 4, 134, 244, 21, 84, 187, 82, 78, 6, 26, 78, 251, 149, - 23, 84, 4, 158, 232, 21, 84, 235, 174, 1, 68, 6, 26, 79, 159, 250, 22, - 69, 4, 242, 255, 22, 83, 215, 22, 84, 10, 40, 2, 78, 69, 22, 80, 203, - 207, 22, 76, 5, 199, 157, 6, 83, 4, 190, 178, 10, 80, 247, 193, 2, 69, - 10, 54, 82, 230, 248, 21, 76, 166, 1, 79, 179, 154, 1, 73, 4, 148, 207, - 12, 2, 73, 86, 181, 141, 7, 2, 79, 70, 18, 62, 65, 42, 73, 234, 173, 10, - 79, 170, 150, 12, 85, 195, 9, 69, 6, 182, 196, 22, 73, 226, 79, 80, 3, - 84, 6, 156, 242, 12, 3, 71, 72, 84, 230, 227, 9, 86, 155, 39, 67, 74, + 8, 38, 76, 130, 207, 22, 78, 199, 13, 73, 4, 34, 70, 141, 252, 21, 2, 66, + 69, 2, 41, 8, 32, 84, 82, 69, 69, 32, 84, 82, 2, 239, 175, 19, 85, 6, 26, + 65, 151, 148, 23, 77, 4, 242, 247, 22, 82, 175, 28, 68, 2, 195, 19, 32, + 6, 26, 82, 191, 144, 23, 79, 4, 254, 252, 22, 83, 215, 22, 78, 6, 26, 78, + 199, 252, 22, 67, 4, 26, 83, 239, 145, 23, 67, 2, 239, 129, 22, 69, 4, + 146, 252, 22, 68, 215, 22, 82, 2, 185, 175, 5, 2, 78, 73, 22, 46, 65, 34, + 69, 78, 73, 41, 3, 79, 78, 71, 4, 166, 251, 22, 77, 191, 19, 67, 8, 38, + 65, 218, 211, 22, 71, 199, 58, 69, 4, 222, 239, 13, 84, 215, 161, 9, 70, + 6, 186, 250, 22, 70, 2, 78, 215, 22, 68, 5, 129, 196, 11, 3, 32, 83, 84, + 22, 42, 69, 34, 73, 46, 79, 243, 191, 22, 65, 4, 174, 192, 22, 76, 195, + 51, 65, 4, 232, 234, 11, 2, 78, 73, 139, 195, 9, 76, 12, 34, 82, 34, 85, + 175, 191, 22, 79, 4, 238, 235, 21, 84, 187, 82, 78, 6, 26, 78, 227, 141, + 23, 84, 4, 134, 224, 21, 84, 235, 174, 1, 68, 6, 26, 79, 135, 242, 22, + 69, 4, 218, 247, 22, 83, 215, 22, 84, 10, 40, 2, 78, 69, 22, 80, 179, + 199, 22, 76, 5, 251, 153, 6, 83, 4, 166, 170, 10, 80, 247, 193, 2, 69, + 10, 54, 82, 206, 240, 21, 76, 166, 1, 79, 179, 154, 1, 73, 4, 252, 198, + 12, 2, 73, 86, 181, 141, 7, 2, 79, 70, 18, 62, 65, 42, 73, 210, 165, 10, + 79, 170, 150, 12, 85, 195, 9, 69, 6, 158, 188, 22, 73, 226, 79, 80, 3, + 84, 6, 132, 234, 12, 3, 71, 72, 84, 230, 227, 9, 86, 155, 39, 67, 74, 170, 1, 65, 86, 67, 54, 69, 62, 72, 178, 1, 73, 46, 76, 62, 80, 106, 84, - 142, 245, 17, 87, 158, 159, 1, 78, 234, 64, 79, 130, 174, 1, 77, 226, - 103, 81, 130, 35, 75, 247, 47, 85, 6, 144, 195, 3, 9, 67, 82, 73, 70, 73, - 67, 73, 65, 76, 202, 178, 19, 76, 175, 28, 89, 4, 224, 246, 10, 2, 82, - 73, 249, 218, 5, 2, 72, 79, 8, 170, 210, 21, 67, 134, 51, 65, 174, 10, - 76, 167, 129, 1, 69, 10, 18, 69, 39, 79, 4, 222, 132, 22, 76, 199, 139, - 1, 69, 6, 40, 4, 82, 84, 32, 84, 183, 243, 22, 79, 4, 44, 5, 65, 73, 76, - 69, 68, 207, 133, 16, 72, 2, 201, 138, 21, 2, 32, 66, 4, 184, 247, 17, 2, - 67, 75, 195, 148, 5, 76, 6, 26, 65, 211, 209, 22, 73, 4, 246, 247, 22, - 86, 199, 21, 83, 10, 50, 69, 34, 73, 190, 148, 19, 82, 179, 169, 3, 79, - 4, 154, 213, 22, 65, 183, 22, 69, 2, 159, 241, 22, 82, 12, 34, 69, 34, - 79, 239, 252, 21, 65, 4, 198, 252, 22, 65, 219, 16, 80, 6, 26, 80, 147, - 246, 22, 78, 5, 223, 187, 22, 80, 30, 82, 65, 98, 73, 34, 79, 38, 82, 52, - 2, 85, 82, 32, 2, 87, 79, 167, 186, 22, 69, 6, 38, 78, 154, 229, 21, 66, - 239, 26, 76, 2, 33, 6, 78, 69, 68, 32, 76, 69, 2, 207, 233, 13, 65, 4, - 174, 205, 22, 71, 155, 39, 76, 4, 146, 251, 18, 78, 243, 138, 2, 79, 6, - 190, 240, 16, 73, 150, 232, 4, 65, 179, 155, 1, 69, 4, 134, 190, 21, 66, - 227, 37, 84, 5, 187, 199, 19, 32, 4, 254, 220, 12, 65, 209, 157, 5, 3, + 246, 236, 17, 87, 158, 159, 1, 78, 234, 64, 79, 130, 174, 1, 77, 226, + 103, 81, 130, 35, 75, 247, 47, 85, 6, 196, 191, 3, 9, 67, 82, 73, 70, 73, + 67, 73, 65, 76, 254, 173, 19, 76, 175, 28, 89, 4, 200, 238, 10, 2, 82, + 73, 249, 218, 5, 2, 72, 79, 8, 146, 202, 21, 67, 134, 51, 65, 174, 10, + 76, 167, 129, 1, 69, 10, 18, 69, 39, 79, 4, 198, 252, 21, 76, 199, 139, + 1, 69, 6, 40, 4, 82, 84, 32, 84, 159, 235, 22, 79, 4, 44, 5, 65, 73, 76, + 69, 68, 183, 253, 15, 72, 2, 177, 130, 21, 2, 32, 66, 4, 160, 239, 17, 2, + 67, 75, 195, 148, 5, 76, 6, 26, 65, 187, 201, 22, 73, 4, 222, 239, 22, + 86, 199, 21, 83, 10, 50, 69, 34, 73, 166, 140, 19, 82, 179, 169, 3, 79, + 4, 130, 205, 22, 65, 183, 22, 69, 2, 135, 233, 22, 82, 12, 34, 69, 34, + 79, 215, 244, 21, 65, 4, 174, 244, 22, 65, 219, 16, 80, 6, 26, 80, 251, + 237, 22, 78, 5, 199, 179, 22, 80, 30, 82, 65, 98, 73, 34, 79, 38, 82, 52, + 2, 85, 82, 32, 2, 87, 79, 143, 178, 22, 69, 6, 38, 78, 130, 221, 21, 66, + 239, 26, 76, 2, 33, 6, 78, 69, 68, 32, 76, 69, 2, 183, 225, 13, 65, 4, + 150, 197, 22, 71, 155, 39, 76, 4, 250, 242, 18, 78, 243, 138, 2, 79, 6, + 166, 232, 16, 73, 150, 232, 4, 65, 179, 155, 1, 69, 4, 238, 181, 21, 66, + 227, 37, 84, 5, 163, 191, 19, 32, 4, 230, 212, 12, 65, 209, 157, 5, 3, 73, 76, 76, 26, 58, 65, 110, 69, 42, 72, 32, 2, 73, 78, 30, 79, 39, 82, - 6, 32, 2, 76, 75, 247, 202, 22, 84, 5, 11, 32, 2, 11, 69, 2, 17, 2, 78, - 67, 2, 237, 243, 17, 2, 76, 79, 4, 168, 184, 22, 2, 65, 80, 195, 51, 83, - 4, 218, 190, 21, 73, 231, 63, 69, 4, 206, 135, 23, 68, 3, 69, 4, 150, - 187, 21, 77, 135, 201, 1, 82, 4, 150, 182, 22, 79, 239, 80, 65, 2, 141, - 229, 20, 2, 69, 76, 186, 1, 92, 2, 76, 69, 148, 2, 5, 83, 73, 71, 78, 32, - 170, 207, 17, 65, 186, 9, 86, 247, 182, 3, 68, 110, 44, 5, 84, 84, 69, - 82, 32, 219, 195, 22, 78, 108, 190, 214, 17, 78, 142, 209, 1, 65, 38, 68, + 6, 32, 2, 76, 75, 223, 194, 22, 84, 5, 11, 32, 2, 11, 69, 2, 17, 2, 78, + 67, 2, 213, 235, 17, 2, 76, 79, 4, 144, 176, 22, 2, 65, 80, 195, 51, 83, + 4, 194, 182, 21, 73, 231, 63, 69, 4, 182, 255, 22, 68, 3, 69, 4, 254, + 178, 21, 77, 135, 201, 1, 82, 4, 254, 173, 22, 79, 239, 80, 65, 2, 245, + 220, 20, 2, 69, 76, 186, 1, 92, 2, 76, 69, 148, 2, 5, 83, 73, 71, 78, 32, + 146, 199, 17, 65, 186, 9, 86, 247, 182, 3, 68, 110, 44, 5, 84, 84, 69, + 82, 32, 195, 187, 22, 78, 108, 166, 206, 17, 78, 142, 209, 1, 65, 38, 68, 46, 76, 38, 82, 34, 84, 46, 86, 186, 5, 85, 206, 141, 1, 79, 238, 60, 73, 182, 196, 1, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 162, 7, 69, - 234, 61, 70, 2, 72, 2, 77, 3, 89, 22, 94, 67, 138, 1, 83, 246, 228, 18, + 234, 61, 70, 2, 72, 2, 77, 3, 89, 22, 94, 67, 138, 1, 83, 222, 220, 18, 78, 190, 66, 65, 190, 158, 1, 74, 150, 3, 85, 235, 245, 1, 86, 4, 100, 19, 79, 77, 66, 73, 78, 73, 78, 71, 32, 65, 78, 85, 83, 86, 65, 82, 65, - 32, 65, 195, 228, 18, 65, 2, 173, 253, 19, 3, 66, 79, 86, 4, 216, 198, + 32, 65, 171, 220, 18, 65, 2, 149, 245, 19, 3, 66, 79, 86, 4, 192, 190, 12, 6, 80, 65, 67, 73, 78, 71, 255, 143, 5, 73, 162, 2, 62, 32, 173, 11, 10, 45, 72, 73, 82, 65, 71, 65, 78, 65, 32, 154, 2, 140, 1, 7, 76, 69, - 84, 84, 69, 82, 32, 242, 9, 86, 232, 130, 19, 10, 68, 73, 71, 82, 65, 80, + 84, 84, 69, 82, 32, 242, 9, 86, 208, 250, 18, 10, 68, 73, 71, 82, 65, 80, 72, 32, 75, 79, 238, 204, 1, 73, 191, 146, 1, 77, 146, 2, 186, 1, 65, 178, 1, 66, 106, 77, 186, 2, 78, 54, 83, 226, 1, 68, 2, 71, 2, 72, 2, 75, - 2, 80, 2, 82, 2, 84, 2, 86, 2, 90, 126, 87, 46, 89, 150, 246, 22, 69, 2, + 2, 80, 2, 82, 2, 84, 2, 86, 2, 90, 126, 87, 46, 89, 254, 237, 22, 69, 2, 73, 2, 79, 3, 85, 19, 60, 4, 73, 78, 85, 32, 45, 7, 82, 67, 72, 65, 73, - 67, 32, 8, 130, 7, 84, 138, 224, 22, 67, 215, 22, 80, 8, 38, 89, 166, - 216, 22, 87, 235, 36, 69, 4, 138, 253, 22, 69, 3, 73, 20, 50, 73, 190, - 252, 22, 65, 2, 69, 2, 79, 3, 85, 13, 253, 4, 9, 68, 65, 75, 85, 79, 78, - 32, 78, 71, 36, 50, 73, 214, 251, 22, 65, 2, 69, 2, 79, 3, 85, 29, 29, 5, + 67, 32, 8, 130, 7, 84, 242, 215, 22, 67, 215, 22, 80, 8, 38, 89, 142, + 208, 22, 87, 235, 36, 69, 4, 242, 244, 22, 69, 3, 73, 20, 50, 73, 166, + 244, 22, 65, 2, 69, 2, 79, 3, 85, 13, 253, 4, 9, 68, 65, 75, 85, 79, 78, + 32, 78, 71, 36, 50, 73, 190, 243, 22, 65, 2, 69, 2, 79, 3, 85, 29, 29, 5, 78, 78, 65, 78, 32, 26, 96, 15, 78, 65, 83, 65, 76, 73, 90, 69, 68, 32, - 84, 79, 78, 69, 45, 69, 5, 84, 79, 78, 69, 45, 14, 206, 250, 22, 49, 2, - 50, 2, 51, 2, 52, 2, 53, 2, 55, 3, 56, 12, 138, 250, 22, 50, 2, 51, 2, - 52, 2, 53, 2, 55, 3, 56, 13, 206, 249, 22, 65, 2, 69, 2, 73, 2, 79, 3, - 85, 76, 76, 5, 77, 65, 76, 76, 32, 206, 248, 22, 65, 2, 69, 2, 73, 2, 79, - 3, 85, 66, 142, 1, 72, 2, 82, 54, 75, 46, 84, 30, 87, 46, 89, 154, 159, + 84, 79, 78, 69, 45, 69, 5, 84, 79, 78, 69, 45, 14, 182, 242, 22, 49, 2, + 50, 2, 51, 2, 52, 2, 53, 2, 55, 3, 56, 12, 242, 241, 22, 50, 2, 51, 2, + 52, 2, 53, 2, 55, 3, 56, 13, 182, 241, 22, 65, 2, 69, 2, 73, 2, 79, 3, + 85, 76, 76, 5, 77, 65, 76, 76, 32, 182, 240, 22, 65, 2, 69, 2, 73, 2, 79, + 3, 85, 66, 142, 1, 72, 2, 82, 54, 75, 46, 84, 30, 87, 46, 89, 130, 151, 19, 78, 198, 150, 3, 83, 210, 27, 77, 234, 36, 65, 2, 69, 2, 73, 2, 79, - 3, 85, 10, 186, 247, 22, 65, 2, 69, 2, 73, 2, 79, 3, 85, 8, 134, 247, 22, - 65, 2, 69, 2, 79, 3, 85, 4, 218, 246, 22, 79, 3, 85, 8, 190, 246, 22, 65, - 2, 69, 2, 73, 3, 79, 6, 146, 246, 22, 65, 2, 79, 3, 85, 2, 189, 207, 20, + 3, 85, 10, 162, 239, 22, 65, 2, 69, 2, 73, 2, 79, 3, 85, 8, 238, 238, 22, + 65, 2, 69, 2, 79, 3, 85, 4, 194, 238, 22, 79, 3, 85, 8, 166, 238, 22, 65, + 2, 69, 2, 73, 3, 79, 6, 250, 237, 22, 65, 2, 79, 3, 85, 2, 165, 199, 20, 5, 79, 73, 67, 69, 68, 8, 52, 5, 68, 79, 85, 66, 76, 22, 80, 38, 83, 35, - 86, 2, 251, 128, 8, 69, 2, 89, 6, 82, 79, 76, 79, 78, 71, 2, 29, 5, 69, + 86, 2, 175, 253, 7, 69, 2, 89, 6, 82, 79, 76, 79, 78, 71, 2, 29, 5, 69, 77, 73, 45, 86, 2, 21, 3, 79, 73, 67, 2, 33, 6, 69, 68, 32, 83, 79, 85, - 2, 223, 167, 22, 78, 174, 1, 216, 1, 7, 76, 69, 84, 84, 69, 82, 32, 128, + 2, 199, 159, 22, 78, 174, 1, 216, 1, 7, 76, 69, 84, 84, 69, 82, 32, 128, 2, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 148, 3, 5, 83, 73, - 71, 78, 32, 88, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 162, 171, - 12, 68, 151, 224, 6, 67, 94, 226, 1, 65, 198, 166, 4, 74, 146, 236, 14, + 71, 78, 32, 88, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 138, 163, + 12, 68, 151, 224, 6, 67, 94, 226, 1, 65, 250, 162, 4, 74, 198, 231, 14, 68, 114, 84, 230, 5, 85, 22, 86, 166, 202, 1, 73, 138, 196, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 82, - 2, 87, 2, 89, 186, 2, 69, 3, 79, 7, 162, 240, 22, 65, 3, 73, 22, 122, 67, + 2, 87, 2, 89, 186, 2, 69, 3, 79, 7, 138, 232, 22, 65, 3, 73, 22, 122, 67, 90, 68, 58, 70, 54, 83, 20, 12, 65, 76, 84, 69, 82, 78, 65, 84, 69, 32, - 83, 69, 237, 217, 21, 4, 84, 82, 73, 80, 4, 56, 8, 76, 79, 83, 73, 78, - 71, 32, 83, 199, 154, 21, 73, 2, 229, 226, 21, 2, 80, 73, 4, 11, 79, 4, - 220, 218, 21, 2, 85, 66, 203, 147, 1, 84, 4, 200, 153, 21, 5, 73, 76, 76, - 69, 68, 163, 57, 76, 6, 18, 69, 23, 80, 2, 187, 245, 10, 67, 4, 140, 151, - 4, 2, 65, 67, 171, 202, 17, 73, 12, 222, 226, 7, 75, 182, 236, 10, 67, - 98, 78, 238, 64, 82, 170, 162, 1, 86, 247, 244, 1, 65, 20, 66, 65, 246, - 164, 4, 86, 234, 239, 14, 69, 2, 85, 187, 202, 1, 73, 6, 240, 233, 16, 8, + 83, 69, 213, 209, 21, 4, 84, 82, 73, 80, 4, 56, 8, 76, 79, 83, 73, 78, + 71, 32, 83, 175, 146, 21, 73, 2, 205, 218, 21, 2, 80, 73, 4, 11, 79, 4, + 196, 210, 21, 2, 85, 66, 203, 147, 1, 84, 4, 176, 145, 21, 5, 73, 76, 76, + 69, 68, 163, 57, 76, 6, 18, 69, 23, 80, 2, 163, 237, 10, 67, 4, 192, 147, + 4, 2, 65, 67, 223, 197, 17, 73, 12, 146, 223, 7, 75, 234, 231, 10, 67, + 98, 78, 238, 64, 82, 170, 162, 1, 86, 247, 244, 1, 65, 20, 66, 65, 170, + 161, 4, 86, 158, 235, 14, 69, 2, 85, 187, 202, 1, 73, 6, 216, 225, 16, 8, 76, 84, 69, 82, 78, 65, 84, 69, 230, 129, 6, 65, 3, 73, 96, 148, 1, 7, 76, 69, 84, 84, 69, 82, 32, 200, 1, 5, 83, 73, 71, 78, 32, 44, 5, 84, 79, - 78, 69, 32, 92, 6, 86, 79, 87, 69, 76, 32, 159, 243, 20, 68, 56, 138, - 206, 18, 79, 186, 7, 72, 158, 151, 2, 78, 214, 181, 1, 75, 2, 80, 2, 83, + 78, 69, 32, 92, 6, 86, 79, 87, 69, 76, 32, 135, 235, 20, 68, 56, 242, + 197, 18, 79, 186, 7, 72, 158, 151, 2, 78, 214, 181, 1, 75, 2, 80, 2, 83, 2, 84, 138, 69, 66, 2, 67, 2, 68, 2, 71, 2, 76, 2, 77, 2, 82, 2, 86, 2, - 87, 2, 89, 2, 90, 186, 2, 65, 3, 73, 4, 130, 243, 4, 67, 205, 242, 17, 2, - 83, 72, 6, 36, 5, 67, 65, 76, 89, 65, 23, 80, 5, 17, 2, 32, 80, 2, 249, - 240, 17, 3, 76, 79, 80, 10, 130, 167, 22, 69, 2, 85, 163, 64, 79, 36, 24, - 2, 76, 86, 23, 89, 2, 215, 234, 20, 73, 35, 68, 5, 66, 79, 65, 82, 68, - 36, 4, 67, 65, 80, 32, 243, 245, 2, 72, 5, 193, 157, 19, 4, 32, 65, 78, - 68, 26, 166, 154, 17, 78, 138, 180, 3, 65, 170, 35, 68, 135, 30, 84, 188, - 13, 202, 1, 65, 224, 9, 18, 73, 84, 65, 78, 32, 83, 77, 65, 76, 76, 32, - 83, 67, 82, 73, 80, 84, 32, 204, 3, 4, 77, 69, 82, 32, 204, 25, 5, 79, - 74, 75, 73, 32, 141, 6, 8, 85, 68, 65, 87, 65, 68, 73, 32, 138, 1, 56, 8, - 82, 79, 83, 72, 84, 72, 73, 32, 147, 190, 22, 78, 136, 1, 220, 1, 4, 68, + 87, 2, 89, 2, 90, 186, 2, 65, 3, 73, 4, 182, 239, 4, 67, 129, 238, 17, 2, + 83, 72, 6, 36, 5, 67, 65, 76, 89, 65, 23, 80, 5, 17, 2, 32, 80, 2, 225, + 232, 17, 3, 76, 79, 80, 10, 234, 158, 22, 69, 2, 85, 163, 64, 79, 36, 24, + 2, 76, 86, 23, 89, 2, 191, 226, 20, 73, 35, 68, 5, 66, 79, 65, 82, 68, + 36, 4, 67, 65, 80, 32, 167, 242, 2, 72, 5, 169, 149, 19, 4, 32, 65, 78, + 68, 26, 142, 146, 17, 78, 138, 180, 3, 65, 170, 35, 68, 135, 30, 84, 142, + 6, 202, 1, 65, 224, 9, 4, 77, 69, 82, 32, 204, 25, 5, 79, 74, 75, 73, 32, + 140, 6, 8, 85, 68, 65, 87, 65, 68, 73, 32, 169, 172, 7, 17, 73, 84, 65, + 78, 32, 83, 77, 65, 76, 76, 32, 83, 67, 82, 73, 80, 84, 138, 1, 56, 8, + 82, 79, 83, 72, 84, 72, 73, 32, 251, 181, 22, 78, 136, 1, 220, 1, 4, 68, 73, 71, 73, 20, 7, 76, 69, 84, 84, 69, 82, 32, 144, 2, 7, 78, 85, 77, 66, 69, 82, 32, 36, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 136, - 2, 5, 83, 73, 71, 78, 32, 210, 1, 86, 159, 201, 8, 70, 8, 243, 146, 16, - 84, 74, 182, 1, 75, 42, 84, 218, 140, 7, 78, 150, 245, 11, 68, 194, 149, + 2, 5, 83, 73, 71, 78, 32, 210, 1, 86, 135, 193, 8, 70, 8, 219, 138, 16, + 84, 74, 182, 1, 75, 42, 84, 142, 137, 7, 78, 202, 240, 11, 68, 194, 149, 3, 83, 82, 66, 2, 67, 2, 71, 2, 80, 2, 86, 138, 69, 72, 2, 74, 2, 76, 2, - 77, 2, 82, 2, 89, 2, 90, 187, 2, 65, 6, 170, 221, 22, 72, 2, 75, 187, 2, - 65, 12, 218, 130, 19, 84, 170, 218, 3, 72, 187, 2, 65, 8, 186, 215, 14, + 77, 2, 82, 2, 89, 2, 90, 187, 2, 65, 6, 146, 213, 22, 72, 2, 75, 187, 2, + 65, 12, 194, 250, 18, 84, 170, 218, 3, 72, 187, 2, 65, 8, 162, 207, 14, 84, 243, 170, 2, 79, 18, 70, 67, 74, 68, 66, 76, 36, 5, 77, 65, 78, 71, - 65, 163, 136, 21, 83, 4, 26, 82, 251, 137, 21, 73, 2, 173, 186, 21, 6, - 69, 83, 67, 69, 78, 84, 6, 26, 79, 199, 253, 18, 65, 4, 142, 253, 18, 85, - 175, 224, 3, 84, 4, 214, 227, 6, 79, 247, 195, 7, 73, 2, 227, 159, 21, - 76, 12, 72, 2, 66, 65, 22, 67, 20, 2, 68, 79, 130, 162, 20, 86, 247, 244, - 1, 65, 2, 143, 223, 21, 82, 2, 167, 154, 6, 65, 4, 44, 5, 85, 66, 76, 69, - 32, 167, 170, 20, 84, 2, 21, 3, 82, 73, 78, 2, 139, 170, 20, 71, 14, 44, - 5, 79, 87, 69, 76, 32, 199, 158, 20, 73, 12, 44, 5, 83, 73, 71, 78, 32, - 183, 152, 22, 76, 10, 202, 147, 4, 86, 230, 198, 18, 69, 2, 73, 2, 79, 3, - 85, 176, 7, 72, 12, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 147, - 207, 7, 70, 174, 7, 22, 66, 147, 1, 67, 128, 4, 142, 254, 7, 48, 2, 49, - 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, - 67, 2, 68, 2, 69, 3, 70, 174, 3, 142, 1, 68, 242, 251, 7, 48, 2, 49, 2, - 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, - 211, 217, 13, 70, 12, 226, 214, 22, 48, 2, 49, 2, 50, 2, 51, 2, 52, 3, - 53, 246, 2, 202, 1, 67, 240, 2, 18, 73, 78, 68, 69, 80, 69, 78, 68, 69, + 65, 139, 128, 21, 83, 4, 26, 82, 227, 129, 21, 73, 2, 149, 178, 21, 6, + 69, 83, 67, 69, 78, 84, 6, 26, 79, 175, 245, 18, 65, 4, 246, 244, 18, 85, + 175, 224, 3, 84, 4, 138, 224, 6, 79, 171, 191, 7, 73, 2, 203, 151, 21, + 76, 12, 72, 2, 66, 65, 22, 67, 20, 2, 68, 79, 234, 153, 20, 86, 247, 244, + 1, 65, 2, 247, 214, 21, 82, 2, 219, 150, 6, 65, 4, 44, 5, 85, 66, 76, 69, + 32, 143, 162, 20, 84, 2, 21, 3, 82, 73, 78, 2, 243, 161, 20, 71, 14, 44, + 5, 79, 87, 69, 76, 32, 175, 150, 20, 73, 12, 44, 5, 83, 73, 71, 78, 32, + 159, 144, 22, 76, 10, 254, 143, 4, 86, 154, 194, 18, 69, 2, 73, 2, 79, 3, + 85, 246, 2, 202, 1, 67, 240, 2, 18, 73, 78, 68, 69, 80, 69, 78, 68, 69, 78, 84, 32, 86, 79, 87, 69, 76, 32, 220, 2, 7, 76, 69, 84, 84, 69, 82, - 32, 254, 2, 83, 208, 12, 6, 86, 79, 87, 69, 76, 32, 187, 203, 20, 68, 70, + 32, 254, 2, 83, 208, 12, 6, 86, 79, 87, 69, 76, 32, 239, 198, 20, 68, 70, 176, 1, 20, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 67, - 79, 69, 78, 71, 32, 245, 189, 17, 17, 85, 82, 82, 69, 78, 67, 89, 32, 83, + 79, 69, 78, 71, 32, 169, 185, 17, 17, 85, 82, 82, 69, 78, 67, 89, 32, 83, 89, 77, 66, 79, 76, 32, 82, 73, 68, 138, 1, 78, 154, 4, 67, 2, 75, 90, - 80, 74, 84, 54, 68, 2, 76, 158, 132, 22, 83, 158, 41, 77, 2, 82, 2, 86, - 2, 89, 190, 28, 66, 3, 72, 8, 162, 179, 22, 71, 2, 89, 246, 30, 65, 3, + 80, 74, 84, 54, 68, 2, 76, 210, 255, 21, 83, 158, 41, 77, 2, 82, 2, 86, + 2, 89, 190, 28, 66, 3, 72, 8, 214, 174, 22, 71, 2, 89, 246, 30, 65, 3, 79, 42, 82, 81, 196, 1, 11, 83, 73, 71, 78, 32, 67, 79, 69, 78, 71, 32, - 50, 76, 3, 82, 26, 82, 65, 44, 6, 79, 79, 32, 84, 89, 80, 34, 85, 178, - 195, 20, 73, 199, 140, 2, 69, 8, 190, 208, 22, 65, 2, 73, 2, 81, 3, 85, - 4, 11, 69, 4, 199, 149, 10, 32, 9, 166, 192, 7, 85, 207, 143, 15, 75, 8, - 18, 81, 31, 82, 4, 186, 207, 22, 69, 3, 85, 4, 131, 190, 18, 89, 70, 138, - 1, 67, 2, 75, 42, 78, 50, 80, 30, 83, 46, 84, 54, 68, 2, 76, 186, 173, + 50, 76, 3, 82, 26, 82, 65, 44, 6, 79, 79, 32, 84, 89, 80, 34, 85, 230, + 190, 20, 73, 199, 140, 2, 69, 8, 242, 203, 22, 65, 2, 73, 2, 81, 3, 85, + 4, 11, 69, 4, 251, 144, 10, 32, 9, 166, 192, 7, 85, 131, 139, 15, 75, 8, + 18, 81, 31, 82, 4, 238, 202, 22, 69, 3, 85, 4, 183, 185, 18, 89, 70, 138, + 1, 67, 2, 75, 42, 78, 50, 80, 30, 83, 46, 84, 54, 68, 2, 76, 238, 168, 22, 77, 2, 82, 2, 86, 2, 89, 190, 28, 66, 2, 72, 3, 81, 8, 210, 1, 72, - 174, 204, 22, 65, 3, 79, 8, 226, 174, 22, 71, 2, 78, 2, 89, 247, 30, 79, - 6, 122, 72, 175, 204, 22, 79, 6, 150, 174, 22, 83, 190, 28, 72, 187, 2, - 65, 12, 50, 72, 0, 2, 84, 72, 174, 204, 22, 65, 3, 79, 4, 170, 204, 22, + 226, 199, 22, 65, 3, 79, 8, 150, 170, 22, 71, 2, 78, 2, 89, 247, 30, 79, + 6, 122, 72, 227, 199, 22, 79, 6, 202, 169, 22, 83, 190, 28, 72, 187, 2, + 65, 12, 50, 72, 0, 2, 84, 72, 226, 199, 22, 65, 3, 79, 4, 222, 199, 22, 65, 3, 79, 130, 1, 60, 4, 73, 71, 78, 32, 221, 6, 6, 89, 77, 66, 79, 76, 32, 46, 202, 2, 65, 104, 10, 83, 65, 77, 89, 79, 75, 32, 83, 65, 78, 22, 66, 118, 67, 86, 75, 74, 82, 54, 84, 188, 229, 4, 3, 76, 69, 75, 168, 11, - 6, 80, 72, 78, 65, 69, 75, 224, 232, 10, 10, 89, 85, 85, 75, 65, 76, 69, + 6, 80, 72, 78, 65, 69, 75, 148, 228, 10, 10, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 244, 243, 1, 3, 78, 73, 75, 236, 171, 3, 9, 77, 85, 85, 83, 73, 75, 65, 84, 79, 141, 15, 4, 86, 73, 82, 73, 6, 100, 9, 86, 65, 75, - 82, 65, 72, 65, 83, 65, 232, 145, 18, 4, 84, 84, 72, 65, 173, 145, 4, 2, - 72, 83, 2, 187, 197, 22, 78, 8, 38, 65, 129, 188, 21, 3, 69, 89, 89, 6, - 174, 6, 84, 216, 1, 2, 78, 84, 185, 243, 20, 6, 82, 73, 89, 79, 79, 83, - 4, 248, 155, 7, 12, 65, 77, 78, 85, 67, 32, 80, 73, 73, 32, 75, 85, 183, - 228, 12, 79, 6, 188, 221, 11, 2, 65, 75, 226, 156, 9, 72, 205, 82, 4, 79, - 79, 77, 85, 4, 130, 221, 11, 79, 137, 235, 5, 4, 69, 65, 72, 77, 4, 180, - 178, 21, 4, 82, 73, 73, 83, 217, 9, 8, 79, 65, 78, 68, 65, 75, 72, 73, + 82, 65, 72, 65, 83, 65, 156, 141, 18, 4, 84, 84, 72, 65, 173, 145, 4, 2, + 72, 83, 2, 239, 192, 22, 78, 8, 38, 65, 181, 183, 21, 3, 69, 89, 89, 6, + 174, 6, 84, 216, 1, 2, 78, 84, 237, 238, 20, 6, 82, 73, 89, 79, 79, 83, + 4, 248, 155, 7, 12, 65, 77, 78, 85, 67, 32, 80, 73, 73, 32, 75, 85, 235, + 223, 12, 79, 6, 240, 216, 11, 2, 65, 75, 226, 156, 9, 72, 205, 82, 4, 79, + 79, 77, 85, 4, 182, 216, 11, 79, 137, 235, 5, 4, 69, 65, 72, 77, 4, 232, + 173, 21, 4, 82, 73, 73, 83, 217, 9, 8, 79, 65, 78, 68, 65, 75, 72, 73, 84, 128, 1, 3, 68, 65, 80, 92, 10, 76, 69, 75, 32, 65, 84, 84, 65, 75, 32, 182, 1, 80, 72, 5, 84, 85, 84, 69, 89, 78, 66, 47, 77, 24, 22, 45, 223, 3, 32, 20, 30, 80, 238, 2, 66, 47, 77, 8, 138, 3, 73, 37, 3, 82, 65, - 77, 20, 50, 80, 98, 66, 186, 150, 11, 77, 219, 219, 10, 83, 12, 36, 3, - 82, 65, 77, 223, 174, 22, 73, 11, 11, 45, 8, 42, 66, 186, 150, 11, 77, - 251, 228, 8, 80, 4, 142, 242, 21, 85, 151, 60, 69, 26, 44, 2, 65, 84, 44, - 3, 82, 65, 77, 91, 73, 2, 21, 3, 72, 65, 77, 2, 175, 190, 16, 65, 20, 18, + 77, 20, 50, 80, 98, 66, 238, 145, 11, 77, 219, 219, 10, 83, 12, 36, 3, + 82, 65, 77, 147, 170, 22, 73, 11, 11, 45, 8, 42, 66, 238, 145, 11, 77, + 251, 228, 8, 80, 4, 194, 237, 21, 85, 151, 60, 69, 26, 44, 2, 65, 84, 44, + 3, 82, 65, 77, 91, 73, 2, 21, 3, 72, 65, 77, 2, 227, 185, 16, 65, 20, 18, 45, 119, 32, 16, 34, 66, 32, 2, 80, 73, 15, 77, 8, 30, 69, 37, 3, 85, 79, - 78, 4, 35, 73, 4, 21, 3, 85, 79, 89, 4, 11, 32, 4, 34, 82, 189, 138, 22, - 2, 75, 79, 2, 195, 149, 21, 79, 42, 76, 10, 73, 78, 72, 69, 82, 69, 78, - 84, 32, 65, 29, 5, 83, 73, 71, 78, 32, 4, 238, 190, 22, 65, 3, 81, 38, - 102, 65, 54, 73, 30, 79, 38, 89, 216, 254, 2, 5, 67, 79, 69, 78, 71, 182, - 172, 7, 85, 239, 145, 12, 69, 10, 194, 180, 3, 65, 170, 137, 19, 69, 2, - 73, 3, 85, 7, 182, 189, 22, 69, 3, 73, 6, 154, 189, 22, 69, 2, 77, 3, 79, - 7, 246, 188, 22, 65, 3, 89, 130, 1, 146, 1, 68, 88, 7, 76, 69, 84, 84, + 78, 4, 35, 73, 4, 21, 3, 85, 79, 89, 4, 11, 32, 4, 34, 82, 241, 133, 22, + 2, 75, 79, 2, 247, 144, 21, 79, 42, 76, 10, 73, 78, 72, 69, 82, 69, 78, + 84, 32, 65, 29, 5, 83, 73, 71, 78, 32, 4, 162, 186, 22, 65, 3, 81, 38, + 102, 65, 54, 73, 30, 79, 38, 89, 216, 254, 2, 5, 67, 79, 69, 78, 71, 234, + 167, 7, 85, 239, 145, 12, 69, 10, 194, 180, 3, 65, 222, 132, 19, 69, 2, + 73, 3, 85, 7, 234, 184, 22, 69, 3, 73, 6, 206, 184, 22, 69, 2, 77, 3, 79, + 7, 170, 184, 22, 65, 3, 89, 130, 1, 146, 1, 68, 88, 7, 76, 69, 84, 84, 69, 82, 32, 170, 2, 83, 160, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, - 78, 32, 238, 237, 15, 87, 231, 85, 65, 6, 48, 6, 79, 85, 66, 76, 69, 32, - 155, 219, 18, 65, 4, 134, 168, 10, 83, 135, 179, 8, 68, 90, 234, 1, 83, - 254, 4, 66, 42, 71, 146, 141, 6, 68, 166, 145, 12, 74, 182, 55, 65, 150, + 78, 32, 162, 233, 15, 87, 231, 85, 65, 6, 48, 6, 79, 85, 66, 76, 69, 32, + 207, 214, 18, 65, 4, 186, 163, 10, 83, 135, 179, 8, 68, 90, 234, 1, 83, + 254, 4, 66, 42, 71, 146, 141, 6, 68, 218, 140, 12, 74, 182, 55, 65, 150, 1, 84, 198, 208, 1, 76, 226, 195, 1, 78, 126, 67, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 81, 2, 82, 2, 86, 2, 89, 186, 2, 69, 2, 73, 2, 79, 3, 85, - 4, 26, 72, 231, 184, 22, 65, 2, 209, 248, 21, 3, 79, 82, 84, 12, 40, 4, - 73, 71, 78, 32, 159, 165, 10, 69, 10, 54, 83, 226, 154, 18, 78, 154, 67, - 86, 243, 148, 3, 65, 4, 26, 72, 251, 179, 17, 85, 2, 11, 65, 2, 179, 146, - 22, 68, 18, 190, 240, 3, 86, 198, 239, 14, 65, 222, 202, 1, 73, 198, 140, + 4, 26, 72, 155, 180, 22, 65, 2, 133, 244, 21, 3, 79, 82, 84, 12, 40, 4, + 73, 71, 78, 32, 211, 160, 10, 69, 10, 54, 83, 150, 150, 18, 78, 154, 67, + 86, 243, 148, 3, 65, 4, 26, 72, 175, 175, 17, 85, 2, 11, 65, 2, 231, 141, + 22, 68, 18, 190, 240, 3, 86, 250, 234, 14, 65, 222, 202, 1, 73, 198, 140, 2, 69, 2, 79, 3, 85, 138, 1, 100, 7, 76, 69, 84, 84, 69, 82, 32, 176, 2, - 5, 83, 73, 71, 78, 32, 230, 194, 16, 86, 203, 252, 3, 68, 94, 222, 1, 66, - 42, 71, 146, 141, 6, 68, 254, 143, 12, 74, 222, 56, 65, 118, 82, 34, 84, + 5, 83, 73, 71, 78, 32, 154, 190, 16, 86, 203, 252, 3, 68, 94, 222, 1, 66, + 42, 71, 146, 141, 6, 68, 178, 139, 12, 74, 222, 56, 65, 118, 82, 34, 84, 230, 5, 85, 186, 202, 1, 73, 138, 196, 1, 78, 126, 67, 2, 75, 2, 80, 2, - 83, 138, 69, 72, 2, 76, 2, 77, 2, 86, 2, 89, 186, 2, 69, 3, 79, 6, 202, - 177, 22, 66, 2, 72, 187, 2, 65, 6, 162, 177, 22, 71, 2, 72, 187, 2, 65, - 6, 178, 150, 18, 78, 154, 67, 86, 243, 148, 3, 65, 136, 1, 140, 1, 8, 82, - 65, 84, 32, 82, 65, 73, 32, 216, 3, 2, 83, 83, 208, 247, 20, 4, 87, 73, + 83, 138, 69, 72, 2, 76, 2, 77, 2, 86, 2, 89, 186, 2, 69, 3, 79, 6, 254, + 172, 22, 66, 2, 72, 187, 2, 65, 6, 214, 172, 22, 71, 2, 72, 187, 2, 65, + 6, 230, 145, 18, 78, 154, 67, 86, 243, 148, 3, 65, 136, 1, 140, 1, 8, 82, + 65, 84, 32, 82, 65, 73, 32, 216, 3, 2, 83, 83, 132, 243, 20, 4, 87, 73, 70, 82, 202, 47, 80, 240, 93, 2, 77, 79, 191, 18, 84, 116, 140, 1, 7, 76, 69, 84, 84, 69, 82, 32, 172, 1, 5, 83, 73, 71, 78, 32, 92, 11, 86, 79, - 87, 69, 76, 32, 83, 73, 71, 78, 32, 223, 237, 11, 68, 64, 142, 211, 18, + 87, 69, 76, 32, 83, 73, 71, 78, 32, 147, 233, 11, 68, 64, 194, 206, 18, 68, 114, 84, 206, 223, 1, 78, 214, 181, 1, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 2, 83, 138, 69, 72, 2, 76, 2, 77, 2, 82, 2, 86, 2, 89, 187, 2, - 65, 12, 184, 209, 9, 3, 84, 79, 78, 0, 2, 89, 85, 190, 252, 1, 83, 198, - 156, 10, 65, 239, 1, 86, 16, 182, 215, 18, 65, 130, 151, 3, 85, 162, 64, - 69, 2, 73, 3, 79, 13, 40, 4, 73, 78, 71, 32, 183, 236, 21, 32, 8, 96, 4, - 70, 65, 67, 69, 177, 147, 14, 14, 67, 65, 84, 32, 70, 65, 67, 69, 32, 87, - 73, 84, 72, 32, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 158, 146, 14, 83, - 159, 155, 5, 67, 4, 232, 167, 18, 3, 69, 69, 76, 171, 232, 3, 79, 4, 40, - 4, 82, 69, 65, 78, 207, 137, 22, 65, 2, 33, 6, 32, 83, 84, 65, 78, 68, 2, - 193, 250, 18, 2, 65, 82, 2, 11, 79, 2, 171, 169, 10, 78, 200, 43, 154, 1, - 65, 178, 233, 1, 69, 198, 62, 73, 226, 83, 79, 206, 33, 85, 94, 89, 138, - 226, 7, 82, 232, 195, 9, 5, 32, 66, 32, 66, 65, 142, 163, 1, 76, 239, 66, + 65, 12, 236, 204, 9, 3, 84, 79, 78, 0, 2, 89, 85, 190, 252, 1, 83, 198, + 156, 10, 65, 239, 1, 86, 16, 234, 210, 18, 65, 130, 151, 3, 85, 162, 64, + 69, 2, 73, 3, 79, 13, 40, 4, 73, 78, 71, 32, 235, 231, 21, 32, 8, 96, 4, + 70, 65, 67, 69, 229, 142, 14, 14, 67, 65, 84, 32, 70, 65, 67, 69, 32, 87, + 73, 84, 72, 32, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 210, 141, 14, 83, + 159, 155, 5, 67, 4, 156, 163, 18, 3, 69, 69, 76, 171, 232, 3, 79, 4, 40, + 4, 82, 69, 65, 78, 131, 133, 22, 65, 2, 33, 6, 32, 83, 84, 65, 78, 68, 2, + 245, 245, 18, 2, 65, 82, 2, 11, 79, 2, 223, 164, 10, 78, 200, 43, 154, 1, + 65, 178, 233, 1, 69, 198, 62, 73, 226, 83, 79, 206, 33, 85, 94, 89, 190, + 221, 7, 82, 232, 195, 9, 5, 32, 66, 32, 66, 65, 142, 163, 1, 76, 239, 66, 70, 134, 23, 142, 1, 66, 44, 6, 67, 82, 79, 83, 83, 69, 46, 68, 58, 78, 64, 2, 79, 32, 222, 11, 82, 236, 21, 4, 83, 84, 32, 81, 77, 4, 84, 73, - 78, 32, 4, 228, 194, 14, 2, 32, 67, 155, 218, 6, 69, 2, 137, 255, 16, 6, - 32, 83, 84, 73, 67, 75, 4, 148, 255, 12, 5, 89, 32, 66, 69, 69, 247, 234, - 8, 68, 4, 178, 202, 9, 68, 161, 241, 10, 7, 71, 85, 65, 71, 69, 32, 84, + 78, 32, 4, 152, 190, 14, 2, 32, 67, 155, 218, 6, 69, 2, 189, 250, 16, 6, + 32, 83, 84, 73, 67, 75, 4, 200, 250, 12, 5, 89, 32, 66, 69, 69, 247, 234, + 8, 68, 4, 230, 197, 9, 68, 161, 241, 10, 7, 71, 85, 65, 71, 69, 32, 84, 174, 1, 200, 2, 3, 72, 79, 32, 28, 7, 76, 69, 84, 84, 69, 82, 32, 214, 5, 83, 148, 1, 9, 84, 79, 78, 69, 32, 77, 65, 73, 32, 84, 11, 86, 79, 87, - 69, 76, 32, 83, 73, 71, 78, 32, 228, 170, 4, 2, 75, 79, 224, 130, 13, 2, + 69, 76, 32, 83, 73, 71, 78, 32, 228, 170, 4, 2, 75, 79, 148, 254, 12, 2, 89, 65, 230, 199, 2, 69, 170, 51, 68, 212, 138, 1, 7, 67, 65, 78, 67, 69, - 76, 76, 221, 68, 6, 78, 73, 71, 71, 65, 72, 4, 186, 133, 22, 77, 3, 78, + 76, 76, 221, 68, 6, 78, 73, 71, 71, 65, 72, 4, 238, 128, 22, 77, 3, 78, 94, 176, 1, 3, 70, 79, 32, 78, 75, 96, 2, 76, 79, 50, 80, 154, 1, 83, 86, - 84, 30, 72, 162, 161, 16, 78, 234, 222, 5, 66, 2, 67, 2, 68, 2, 77, 2, - 82, 2, 87, 2, 89, 247, 30, 79, 8, 42, 70, 250, 174, 15, 83, 175, 182, 5, - 84, 4, 210, 210, 21, 79, 155, 62, 65, 10, 26, 72, 251, 161, 22, 79, 8, - 32, 3, 77, 85, 32, 231, 2, 79, 4, 142, 201, 21, 78, 211, 57, 71, 7, 17, - 2, 32, 76, 4, 166, 208, 21, 73, 67, 79, 30, 52, 4, 65, 76, 73, 32, 210, - 1, 72, 255, 158, 22, 79, 24, 230, 200, 6, 68, 34, 84, 206, 6, 78, 210, - 211, 13, 66, 2, 67, 2, 71, 2, 74, 147, 219, 1, 76, 8, 52, 9, 65, 78, 83, - 75, 82, 73, 84, 32, 83, 71, 79, 4, 250, 156, 22, 72, 3, 83, 6, 26, 72, - 255, 158, 22, 79, 4, 11, 79, 4, 11, 32, 4, 166, 171, 15, 83, 175, 182, 5, + 84, 30, 72, 214, 156, 16, 78, 234, 222, 5, 66, 2, 67, 2, 68, 2, 77, 2, + 82, 2, 87, 2, 89, 247, 30, 79, 8, 42, 70, 174, 170, 15, 83, 175, 182, 5, + 84, 4, 134, 206, 21, 79, 155, 62, 65, 10, 26, 72, 175, 157, 22, 79, 8, + 32, 3, 77, 85, 32, 231, 2, 79, 4, 194, 196, 21, 78, 211, 57, 71, 7, 17, + 2, 32, 76, 4, 218, 203, 21, 73, 67, 79, 30, 52, 4, 65, 76, 73, 32, 210, + 1, 72, 179, 154, 22, 79, 24, 230, 200, 6, 68, 34, 84, 206, 6, 78, 134, + 207, 13, 66, 2, 67, 2, 71, 2, 74, 147, 219, 1, 76, 8, 52, 9, 65, 78, 83, + 75, 82, 73, 84, 32, 83, 71, 79, 4, 174, 152, 22, 72, 3, 83, 6, 26, 72, + 179, 154, 22, 79, 4, 11, 79, 4, 11, 32, 4, 218, 166, 15, 83, 175, 182, 5, 84, 6, 112, 14, 69, 77, 73, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, - 209, 195, 18, 8, 73, 71, 78, 32, 80, 65, 76, 73, 4, 134, 197, 21, 78, - 211, 57, 76, 8, 50, 84, 132, 163, 17, 2, 67, 65, 223, 246, 4, 69, 4, 130, - 254, 21, 72, 247, 30, 73, 32, 106, 65, 44, 5, 77, 65, 73, 32, 75, 166, - 138, 18, 89, 162, 58, 85, 186, 202, 1, 69, 2, 73, 199, 140, 2, 79, 11, - 234, 155, 22, 65, 2, 73, 2, 77, 3, 89, 4, 222, 203, 21, 65, 3, 79, 166, - 1, 32, 2, 71, 69, 255, 147, 21, 73, 164, 1, 26, 32, 171, 251, 13, 82, - 160, 1, 254, 1, 66, 44, 4, 71, 82, 69, 69, 22, 79, 250, 1, 84, 190, 242, + 133, 191, 18, 8, 73, 71, 78, 32, 80, 65, 76, 73, 4, 186, 192, 21, 78, + 211, 57, 76, 8, 50, 84, 184, 158, 17, 2, 67, 65, 223, 246, 4, 69, 4, 182, + 249, 21, 72, 247, 30, 73, 32, 106, 65, 44, 5, 77, 65, 73, 32, 75, 218, + 133, 18, 89, 162, 58, 85, 186, 202, 1, 69, 2, 73, 199, 140, 2, 79, 11, + 158, 151, 22, 65, 2, 73, 2, 77, 3, 89, 4, 146, 199, 21, 65, 3, 79, 166, + 1, 32, 2, 71, 69, 179, 143, 21, 73, 164, 1, 26, 32, 223, 246, 13, 82, + 160, 1, 254, 1, 66, 44, 4, 71, 82, 69, 69, 22, 79, 250, 1, 84, 242, 237, 11, 68, 36, 2, 85, 80, 164, 193, 3, 12, 76, 69, 70, 84, 32, 84, 82, 73, 65, 78, 71, 76, 200, 203, 4, 5, 80, 85, 82, 80, 76, 12, 3, 82, 69, 68, 0, 6, 89, 69, 76, 76, 79, 87, 179, 66, 67, 10, 40, 3, 82, 79, 87, 201, 1, 2, - 76, 85, 4, 227, 129, 20, 78, 10, 48, 3, 78, 69, 32, 129, 1, 4, 82, 65, - 78, 71, 4, 240, 161, 8, 5, 68, 79, 84, 32, 79, 133, 234, 2, 18, 82, 73, + 76, 85, 4, 151, 253, 19, 78, 10, 48, 3, 78, 69, 32, 129, 1, 4, 82, 65, + 78, 71, 4, 164, 157, 8, 5, 68, 79, 84, 32, 79, 133, 234, 2, 18, 82, 73, 78, 71, 32, 79, 86, 69, 82, 32, 84, 87, 79, 32, 82, 73, 78, 71, 6, 11, - 69, 6, 11, 32, 6, 178, 194, 20, 67, 162, 21, 68, 155, 28, 83, 116, 156, - 1, 3, 87, 79, 32, 108, 10, 89, 80, 69, 32, 80, 73, 69, 67, 69, 32, 197, - 208, 18, 17, 82, 73, 80, 76, 69, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, - 66, 65, 4, 242, 241, 17, 68, 141, 93, 19, 82, 73, 78, 71, 83, 32, 79, 86, + 69, 6, 11, 32, 6, 230, 189, 20, 67, 162, 21, 68, 155, 28, 83, 116, 156, + 1, 3, 87, 79, 32, 108, 10, 89, 80, 69, 32, 80, 73, 69, 67, 69, 32, 249, + 203, 18, 17, 82, 73, 80, 76, 69, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, + 66, 65, 4, 166, 237, 17, 68, 141, 93, 19, 82, 73, 78, 71, 83, 32, 79, 86, 69, 82, 32, 79, 78, 69, 32, 82, 73, 78, 71, 110, 182, 1, 67, 136, 2, 9, 68, 73, 65, 71, 79, 78, 65, 76, 32, 218, 1, 76, 186, 2, 82, 158, 1, 83, 204, 3, 6, 85, 80, 80, 69, 82, 32, 145, 2, 9, 86, 69, 82, 84, 69, 88, 32, 79, 70, 14, 80, 9, 69, 78, 84, 82, 69, 32, 79, 70, 32, 73, 7, 82, 79, 83, - 83, 66, 65, 82, 8, 252, 8, 6, 90, 32, 87, 73, 84, 72, 138, 137, 22, 75, + 83, 66, 65, 82, 8, 252, 8, 6, 90, 32, 87, 73, 84, 72, 190, 132, 22, 75, 2, 88, 3, 89, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 40, 3, 76, 79, 87, 1, - 3, 85, 80, 80, 2, 137, 205, 10, 2, 69, 82, 12, 48, 6, 85, 80, 80, 69, 82, - 32, 167, 230, 9, 76, 8, 56, 4, 76, 69, 70, 84, 225, 230, 9, 4, 82, 73, + 3, 85, 80, 80, 2, 189, 200, 10, 2, 69, 82, 12, 48, 6, 85, 80, 80, 69, 82, + 32, 219, 225, 9, 76, 8, 56, 4, 76, 69, 70, 84, 149, 226, 9, 4, 82, 73, 71, 72, 5, 11, 32, 2, 21, 3, 65, 78, 68, 2, 17, 2, 32, 76, 2, 17, 2, 79, - 87, 2, 209, 220, 21, 2, 69, 82, 26, 48, 5, 79, 87, 69, 82, 32, 129, 3, 2, + 87, 2, 133, 216, 21, 2, 69, 82, 26, 48, 5, 79, 87, 69, 82, 32, 129, 3, 2, 69, 70, 24, 84, 5, 76, 69, 70, 84, 32, 56, 6, 82, 73, 71, 72, 84, 32, - 158, 6, 72, 179, 1, 84, 8, 22, 65, 207, 7, 67, 4, 194, 1, 78, 135, 226, + 158, 6, 72, 179, 1, 84, 8, 22, 65, 207, 7, 67, 4, 194, 1, 78, 187, 221, 20, 82, 10, 22, 65, 151, 7, 67, 6, 192, 1, 13, 78, 68, 32, 85, 80, 80, - 69, 82, 32, 82, 73, 71, 72, 249, 211, 19, 2, 82, 67, 4, 44, 4, 65, 73, + 69, 82, 32, 82, 73, 71, 72, 173, 207, 19, 2, 82, 67, 4, 44, 4, 65, 73, 83, 69, 77, 3, 73, 71, 72, 2, 53, 11, 68, 32, 85, 80, 80, 69, 82, 32, 76, - 69, 70, 2, 231, 139, 19, 84, 2, 137, 141, 21, 3, 84, 32, 65, 34, 48, 5, + 69, 70, 2, 155, 135, 19, 84, 2, 189, 136, 21, 3, 84, 32, 65, 34, 48, 5, 72, 79, 82, 84, 32, 77, 3, 84, 69, 77, 4, 40, 3, 76, 79, 87, 1, 3, 85, 80, 80, 2, 217, 4, 4, 69, 82, 32, 84, 31, 44, 6, 32, 87, 73, 84, 72, 32, - 171, 1, 45, 8, 44, 5, 76, 69, 70, 84, 32, 30, 82, 59, 67, 4, 82, 67, 199, - 221, 10, 74, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 17, 2, 32, 67, 2, 169, - 229, 20, 4, 82, 79, 83, 83, 20, 48, 2, 49, 50, 22, 50, 26, 52, 203, 189, - 11, 51, 5, 183, 223, 14, 51, 9, 11, 51, 7, 11, 52, 5, 239, 135, 22, 53, + 171, 1, 45, 8, 44, 5, 76, 69, 70, 84, 32, 30, 82, 59, 67, 4, 82, 67, 251, + 216, 10, 74, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 17, 2, 32, 67, 2, 221, + 224, 20, 4, 82, 79, 83, 83, 20, 48, 2, 49, 50, 22, 50, 26, 52, 255, 184, + 11, 51, 5, 235, 218, 14, 51, 9, 11, 51, 7, 11, 52, 5, 163, 131, 22, 53, 18, 62, 72, 96, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 83, 84, 4, 65, 14, - 65, 76, 70, 32, 86, 69, 82, 84, 69, 88, 32, 79, 70, 32, 4, 214, 134, 22, - 77, 3, 87, 6, 17, 2, 84, 32, 6, 26, 67, 175, 134, 19, 65, 4, 202, 92, 82, - 235, 168, 17, 79, 2, 157, 250, 8, 3, 69, 82, 77, 2, 187, 231, 14, 32, 6, + 65, 76, 70, 32, 86, 69, 82, 84, 69, 88, 32, 79, 70, 32, 4, 138, 130, 22, + 77, 3, 87, 6, 17, 2, 84, 32, 6, 26, 67, 227, 129, 19, 65, 4, 202, 92, 82, + 159, 164, 17, 79, 2, 209, 245, 8, 3, 69, 82, 77, 2, 239, 226, 14, 32, 6, 53, 11, 85, 65, 82, 84, 69, 82, 32, 77, 79, 79, 78, 7, 223, 240, 6, 32, 158, 20, 150, 1, 67, 224, 46, 18, 69, 80, 73, 71, 82, 65, 80, 72, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 252, 1, 7, 76, 69, 84, 84, 69, 82, 32, - 247, 12, 83, 206, 7, 56, 8, 65, 80, 73, 84, 65, 76, 32, 76, 243, 191, 20, + 247, 12, 83, 206, 7, 56, 8, 65, 80, 73, 84, 65, 76, 32, 76, 167, 187, 20, 82, 204, 7, 76, 6, 69, 84, 84, 69, 82, 32, 169, 45, 8, 73, 71, 65, 84, 85, 82, 69, 32, 200, 7, 154, 2, 65, 158, 3, 66, 154, 1, 67, 254, 1, 68, 186, 2, 69, 174, 2, 70, 82, 71, 194, 1, 72, 146, 1, 73, 154, 2, 74, 118, 75, 126, 76, 234, 2, 77, 114, 78, 134, 2, 79, 198, 2, 80, 114, 81, 62, 82, 190, 2, 83, 130, 3, 84, 142, 3, 85, 234, 1, 86, 146, 1, 87, 118, 88, 50, 89, 167, 1, 90, 93, 172, 1, 6, 32, 87, 73, 84, 72, 32, 166, 1, 69, - 246, 65, 78, 176, 158, 14, 6, 70, 82, 73, 67, 65, 78, 158, 193, 3, 76, + 246, 65, 78, 228, 153, 14, 6, 70, 82, 73, 67, 65, 78, 158, 193, 3, 76, 210, 183, 2, 86, 186, 164, 1, 65, 2, 79, 2, 85, 3, 89, 66, 246, 64, 66, 34, 68, 108, 3, 82, 73, 78, 242, 33, 77, 250, 21, 67, 150, 50, 72, 158, - 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, 142, 175, 13, 84, 219, + 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, 194, 170, 13, 84, 219, 183, 3, 83, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 206, 184, 1, 65, 239, - 199, 3, 77, 21, 60, 6, 32, 87, 73, 84, 72, 32, 190, 68, 82, 187, 147, 21, - 69, 14, 154, 67, 84, 138, 60, 70, 210, 57, 76, 182, 159, 16, 68, 170, + 199, 3, 77, 21, 60, 6, 32, 87, 73, 84, 72, 32, 190, 68, 82, 239, 142, 21, + 69, 14, 154, 67, 84, 138, 60, 70, 210, 57, 76, 234, 154, 16, 68, 170, 206, 2, 72, 247, 165, 1, 83, 33, 108, 6, 32, 87, 73, 84, 72, 32, 204, 70, - 7, 76, 79, 83, 69, 68, 32, 73, 54, 85, 154, 228, 20, 79, 139, 60, 72, 20, - 94, 67, 198, 181, 1, 65, 154, 233, 3, 80, 206, 133, 15, 72, 182, 50, 66, - 242, 34, 68, 211, 80, 83, 8, 198, 68, 69, 190, 113, 73, 227, 156, 19, 65, + 7, 76, 79, 83, 69, 68, 32, 73, 54, 85, 206, 223, 20, 79, 139, 60, 72, 20, + 94, 67, 198, 181, 1, 65, 154, 233, 3, 80, 130, 129, 15, 72, 182, 50, 66, + 242, 34, 68, 211, 80, 83, 8, 198, 68, 69, 190, 113, 73, 151, 152, 19, 65, 35, 76, 6, 32, 87, 73, 84, 72, 32, 178, 1, 90, 25, 6, 79, 85, 66, 76, 69, - 32, 24, 78, 83, 226, 15, 67, 202, 47, 84, 218, 117, 76, 182, 159, 16, 68, + 32, 24, 78, 83, 226, 15, 67, 202, 47, 84, 218, 117, 76, 234, 154, 16, 68, 171, 206, 2, 72, 8, 92, 13, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, - 32, 90, 150, 138, 1, 72, 235, 189, 20, 84, 5, 209, 72, 2, 32, 87, 4, 254, - 71, 87, 187, 185, 10, 84, 91, 104, 6, 32, 87, 73, 84, 72, 32, 152, 1, 2, - 90, 72, 134, 76, 71, 206, 152, 17, 84, 210, 143, 4, 83, 63, 78, 70, 254, + 32, 90, 150, 138, 1, 72, 159, 185, 20, 84, 5, 209, 72, 2, 32, 87, 4, 254, + 71, 87, 239, 180, 10, 84, 91, 104, 6, 32, 87, 73, 84, 72, 32, 152, 1, 2, + 90, 72, 134, 76, 71, 130, 148, 17, 84, 210, 143, 4, 83, 63, 78, 70, 254, 73, 67, 158, 2, 68, 194, 16, 84, 158, 23, 77, 250, 1, 86, 238, 45, 72, - 158, 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, 62, 66, 171, 230, + 158, 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, 62, 66, 223, 225, 16, 83, 7, 11, 32, 4, 138, 70, 87, 211, 8, 82, 9, 33, 6, 32, 87, 73, 84, - 72, 32, 6, 242, 158, 20, 72, 166, 85, 68, 211, 80, 83, 35, 76, 6, 32, 87, - 73, 84, 72, 32, 190, 81, 76, 230, 204, 18, 65, 147, 211, 2, 72, 20, 154, - 84, 67, 250, 90, 65, 178, 174, 3, 66, 190, 25, 77, 226, 140, 4, 79, 154, + 72, 32, 6, 166, 154, 20, 72, 166, 85, 68, 211, 80, 83, 35, 76, 6, 32, 87, + 73, 84, 72, 32, 190, 81, 76, 154, 200, 18, 65, 147, 211, 2, 72, 20, 154, + 84, 67, 250, 90, 65, 178, 174, 3, 66, 190, 25, 77, 150, 136, 4, 79, 154, 154, 11, 72, 166, 85, 68, 211, 80, 83, 29, 76, 6, 32, 87, 73, 84, 72, 32, - 250, 126, 65, 198, 244, 7, 87, 247, 173, 12, 69, 20, 186, 82, 66, 34, 67, - 46, 68, 178, 201, 19, 72, 247, 165, 1, 83, 59, 80, 6, 32, 87, 73, 84, 72, - 32, 132, 88, 2, 78, 83, 198, 244, 20, 79, 207, 36, 83, 40, 138, 1, 68, + 250, 126, 65, 250, 239, 7, 87, 247, 173, 12, 69, 20, 186, 82, 66, 34, 67, + 46, 68, 230, 196, 19, 72, 247, 165, 1, 83, 59, 80, 6, 32, 87, 73, 84, 72, + 32, 132, 88, 2, 78, 83, 250, 239, 20, 79, 207, 36, 83, 40, 138, 1, 68, 162, 83, 67, 242, 1, 77, 142, 1, 84, 130, 71, 72, 158, 1, 79, 198, 10, - 71, 186, 2, 65, 246, 173, 3, 73, 62, 66, 171, 230, 16, 83, 10, 22, 79, - 191, 83, 73, 6, 218, 121, 85, 131, 212, 18, 84, 11, 33, 6, 32, 87, 73, - 84, 72, 32, 8, 42, 67, 174, 135, 18, 84, 219, 183, 3, 83, 4, 234, 170, 1, + 71, 186, 2, 65, 246, 173, 3, 73, 62, 66, 223, 225, 16, 83, 10, 22, 79, + 191, 83, 73, 6, 218, 121, 85, 183, 207, 18, 84, 11, 33, 6, 32, 87, 73, + 84, 72, 32, 8, 42, 67, 226, 130, 18, 84, 219, 183, 3, 83, 4, 234, 170, 1, 73, 131, 223, 3, 82, 25, 33, 6, 32, 87, 73, 84, 72, 32, 22, 182, 89, 67, - 34, 68, 50, 83, 222, 79, 65, 138, 1, 76, 198, 211, 7, 79, 155, 154, 11, - 72, 41, 60, 6, 32, 87, 73, 84, 72, 32, 190, 94, 65, 231, 142, 21, 74, 32, + 34, 68, 50, 83, 222, 79, 65, 138, 1, 76, 250, 206, 7, 79, 155, 154, 11, + 72, 41, 60, 6, 32, 87, 73, 84, 72, 32, 190, 94, 65, 155, 138, 21, 74, 32, 138, 1, 66, 36, 2, 68, 79, 52, 7, 77, 73, 68, 68, 76, 69, 32, 38, 83, - 174, 2, 67, 182, 91, 72, 230, 72, 65, 138, 1, 76, 251, 219, 16, 84, 4, - 170, 198, 12, 69, 143, 237, 8, 65, 6, 22, 85, 231, 91, 84, 2, 249, 241, - 4, 2, 66, 76, 4, 230, 131, 18, 84, 159, 151, 3, 68, 4, 214, 2, 77, 211, - 184, 21, 84, 19, 44, 6, 32, 87, 73, 84, 72, 32, 207, 94, 73, 10, 242, - 165, 1, 65, 190, 160, 16, 68, 198, 60, 84, 231, 145, 2, 72, 33, 48, 6, - 32, 87, 73, 84, 72, 32, 215, 233, 21, 74, 28, 102, 67, 44, 2, 83, 77, - 178, 96, 76, 134, 65, 71, 186, 2, 65, 102, 68, 234, 211, 7, 79, 183, 136, - 9, 84, 6, 190, 132, 1, 69, 22, 73, 231, 188, 19, 65, 2, 157, 233, 10, 10, + 174, 2, 67, 182, 91, 72, 230, 72, 65, 138, 1, 76, 175, 215, 16, 84, 4, + 222, 193, 12, 69, 143, 237, 8, 65, 6, 22, 85, 231, 91, 84, 2, 249, 241, + 4, 2, 66, 76, 4, 154, 255, 17, 84, 159, 151, 3, 68, 4, 214, 2, 77, 135, + 180, 21, 84, 19, 44, 6, 32, 87, 73, 84, 72, 32, 207, 94, 73, 10, 242, + 165, 1, 65, 242, 155, 16, 68, 198, 60, 84, 231, 145, 2, 72, 33, 48, 6, + 32, 87, 73, 84, 72, 32, 139, 229, 21, 74, 28, 102, 67, 44, 2, 83, 77, + 178, 96, 76, 134, 65, 71, 186, 2, 65, 102, 68, 158, 207, 7, 79, 183, 136, + 9, 84, 6, 190, 132, 1, 69, 22, 73, 155, 184, 19, 65, 2, 209, 228, 10, 10, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 101, 108, 6, 32, 87, 73, 84, 72, - 32, 178, 103, 76, 138, 159, 4, 80, 218, 155, 9, 77, 134, 197, 7, 73, 2, + 32, 178, 103, 76, 138, 159, 4, 80, 142, 151, 9, 77, 134, 197, 7, 73, 2, 79, 3, 85, 84, 144, 1, 2, 76, 79, 34, 77, 226, 96, 67, 70, 68, 154, 2, 79, 38, 83, 66, 84, 106, 86, 222, 44, 72, 242, 12, 71, 186, 2, 65, 246, - 173, 3, 73, 63, 66, 4, 158, 99, 78, 215, 130, 21, 79, 8, 154, 99, 65, + 173, 3, 73, 63, 66, 4, 158, 99, 78, 139, 254, 20, 79, 8, 154, 99, 65, 235, 159, 4, 73, 19, 44, 6, 32, 87, 73, 84, 72, 32, 155, 23, 72, 14, 242, - 103, 70, 34, 83, 170, 56, 65, 230, 238, 18, 72, 167, 85, 68, 7, 33, 6, + 103, 70, 34, 83, 170, 56, 65, 154, 234, 18, 72, 167, 85, 68, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 190, 105, 68, 39, 83, 43, 94, 32, 156, 1, 8, 69, 86, 69, 82, 83, 69, 68, 32, 216, 111, 3, 85, 77, 32, 167, 147, 4, 65, 28, 40, 5, 87, 73, 84, 72, 32, 215, 112, 82, 26, 134, 78, 67, 218, 29, - 68, 170, 2, 84, 174, 48, 65, 138, 1, 76, 238, 172, 3, 73, 218, 166, 4, - 79, 143, 192, 12, 83, 8, 218, 110, 72, 154, 156, 4, 79, 186, 199, 13, 67, + 68, 170, 2, 84, 174, 48, 65, 138, 1, 76, 238, 172, 3, 73, 142, 162, 4, + 79, 143, 192, 12, 83, 8, 218, 110, 72, 154, 156, 4, 79, 238, 194, 13, 67, 239, 143, 3, 69, 49, 136, 1, 6, 32, 87, 73, 84, 72, 32, 136, 1, 5, 77, 65, 76, 76, 32, 240, 115, 2, 65, 76, 234, 1, 72, 152, 2, 2, 73, 71, 167, 138, 4, 67, 32, 86, 67, 138, 112, 65, 118, 68, 138, 1, 83, 174, 1, 86, - 190, 252, 7, 79, 155, 154, 11, 72, 10, 226, 112, 65, 230, 10, 69, 82, 79, - 203, 31, 73, 4, 132, 168, 19, 11, 81, 32, 87, 73, 84, 72, 32, 72, 79, 79, + 242, 247, 7, 79, 155, 154, 11, 72, 10, 226, 112, 65, 230, 10, 69, 82, 79, + 203, 31, 73, 4, 184, 163, 19, 11, 81, 32, 87, 73, 84, 72, 32, 72, 79, 79, 75, 173, 247, 1, 7, 67, 65, 80, 73, 84, 65, 76, 59, 136, 1, 6, 32, 87, 73, 84, 72, 32, 168, 1, 6, 85, 82, 78, 69, 68, 32, 188, 123, 2, 72, 79, - 176, 1, 2, 79, 78, 74, 82, 243, 222, 20, 90, 22, 82, 67, 50, 68, 254, - 152, 1, 76, 234, 237, 3, 82, 246, 255, 14, 72, 247, 165, 1, 83, 8, 202, - 120, 69, 22, 73, 62, 79, 171, 188, 19, 65, 6, 190, 142, 1, 73, 255, 169, - 16, 79, 18, 246, 39, 73, 242, 138, 3, 65, 190, 169, 18, 72, 2, 75, 2, 76, + 176, 1, 2, 79, 78, 74, 82, 167, 218, 20, 90, 22, 82, 67, 50, 68, 254, + 152, 1, 76, 234, 237, 3, 82, 170, 251, 14, 72, 247, 165, 1, 83, 8, 202, + 120, 69, 22, 73, 62, 79, 223, 183, 19, 65, 6, 190, 142, 1, 73, 179, 165, + 16, 79, 18, 246, 39, 73, 242, 138, 3, 65, 242, 164, 18, 72, 2, 75, 2, 76, 2, 77, 2, 84, 3, 86, 79, 26, 32, 183, 135, 5, 80, 74, 44, 5, 87, 73, 84, - 72, 32, 199, 183, 20, 66, 72, 166, 132, 1, 67, 74, 68, 150, 2, 72, 170, + 72, 32, 251, 178, 20, 66, 72, 166, 132, 1, 67, 74, 68, 150, 2, 72, 170, 1, 77, 134, 1, 79, 142, 1, 84, 186, 9, 71, 186, 2, 65, 246, 173, 3, 73, - 62, 66, 234, 225, 14, 82, 195, 132, 2, 83, 23, 88, 6, 32, 87, 73, 84, 72, - 32, 178, 139, 1, 73, 66, 79, 134, 189, 19, 69, 151, 144, 1, 89, 8, 226, - 138, 1, 68, 210, 230, 16, 84, 231, 145, 2, 72, 19, 48, 6, 32, 87, 73, 84, - 72, 32, 243, 151, 7, 89, 14, 190, 144, 1, 67, 18, 68, 70, 71, 186, 2, 65, - 231, 238, 18, 72, 7, 201, 140, 1, 7, 32, 87, 73, 84, 72, 32, 68, 29, 48, - 6, 32, 87, 73, 84, 72, 32, 219, 169, 17, 79, 24, 154, 143, 1, 67, 18, 68, - 70, 71, 22, 72, 42, 76, 254, 1, 65, 238, 199, 3, 77, 150, 149, 13, 84, + 62, 66, 158, 221, 14, 82, 195, 132, 2, 83, 23, 88, 6, 32, 87, 73, 84, 72, + 32, 178, 139, 1, 73, 66, 79, 186, 184, 19, 69, 151, 144, 1, 89, 8, 226, + 138, 1, 68, 134, 226, 16, 84, 231, 145, 2, 72, 19, 48, 6, 32, 87, 73, 84, + 72, 32, 167, 147, 7, 89, 14, 190, 144, 1, 67, 18, 68, 70, 71, 186, 2, 65, + 155, 234, 18, 72, 7, 201, 140, 1, 7, 32, 87, 73, 84, 72, 32, 68, 29, 48, + 6, 32, 87, 73, 84, 72, 32, 143, 165, 17, 79, 24, 154, 143, 1, 67, 18, 68, + 70, 71, 22, 72, 42, 76, 254, 1, 65, 238, 199, 3, 77, 202, 144, 13, 84, 219, 183, 3, 83, 25, 33, 6, 32, 87, 73, 84, 72, 32, 22, 254, 56, 67, 150, - 88, 65, 102, 68, 38, 76, 34, 83, 242, 231, 3, 80, 207, 133, 15, 72, 4, - 254, 213, 10, 73, 195, 232, 10, 79, 12, 128, 1, 5, 65, 82, 67, 72, 65, - 30, 73, 64, 9, 82, 69, 86, 69, 82, 83, 69, 68, 32, 201, 211, 10, 7, 83, - 73, 68, 69, 87, 65, 89, 2, 217, 246, 13, 2, 73, 67, 4, 220, 107, 5, 78, - 86, 69, 82, 84, 149, 216, 14, 3, 32, 76, 79, 4, 142, 211, 21, 70, 3, 80, + 88, 65, 102, 68, 38, 76, 34, 83, 242, 231, 3, 80, 131, 129, 15, 72, 4, + 178, 209, 10, 73, 195, 232, 10, 79, 12, 128, 1, 5, 65, 82, 67, 72, 65, + 30, 73, 64, 9, 82, 69, 86, 69, 82, 83, 69, 68, 32, 253, 206, 10, 7, 83, + 73, 68, 69, 87, 65, 89, 2, 141, 242, 13, 2, 73, 67, 4, 220, 107, 5, 78, + 86, 69, 82, 84, 201, 211, 14, 3, 32, 76, 79, 4, 194, 206, 21, 70, 3, 80, 138, 1, 242, 2, 65, 36, 2, 66, 73, 152, 1, 21, 73, 78, 86, 69, 82, 84, 69, 68, 32, 71, 76, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 72, 2, 80, 72, 16, 2, 82, 69, 222, 1, 83, 132, 8, 3, 84, 87, 79, 182, 20, 87, 128, - 170, 4, 2, 68, 69, 148, 5, 2, 76, 65, 206, 11, 71, 212, 196, 15, 20, 86, + 170, 4, 2, 68, 69, 148, 5, 2, 76, 65, 206, 11, 71, 136, 192, 15, 20, 86, 79, 73, 67, 69, 68, 32, 76, 65, 82, 89, 78, 71, 69, 65, 76, 32, 83, 80, - 73, 199, 119, 89, 4, 230, 187, 4, 76, 183, 196, 16, 73, 6, 76, 7, 76, 65, + 73, 199, 119, 89, 4, 230, 187, 4, 76, 235, 191, 16, 73, 6, 76, 7, 76, 65, 66, 73, 65, 76, 32, 29, 8, 68, 69, 78, 84, 65, 76, 32, 80, 4, 26, 80, - 239, 206, 4, 67, 2, 153, 146, 16, 6, 69, 82, 67, 85, 83, 83, 7, 33, 6, - 32, 87, 73, 84, 72, 32, 4, 234, 243, 4, 67, 183, 170, 16, 83, 2, 207, 81, + 239, 206, 4, 67, 2, 205, 141, 16, 6, 69, 82, 67, 85, 83, 83, 7, 33, 6, + 32, 87, 73, 84, 72, 32, 4, 234, 243, 4, 67, 235, 165, 16, 83, 2, 207, 81, 65, 8, 104, 7, 86, 69, 82, 83, 69, 68, 32, 233, 243, 4, 13, 84, 82, 79, 70, 76, 69, 88, 32, 67, 76, 73, 67, 75, 4, 80, 3, 69, 83, 72, 161, 8, 12, 71, 76, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 2, 213, 133, 1, 2, 32, 76, 96, 172, 1, 13, 77, 65, 76, 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, - 244, 112, 10, 84, 82, 69, 84, 67, 72, 69, 68, 32, 67, 185, 198, 19, 10, + 244, 112, 10, 84, 82, 69, 84, 67, 72, 69, 68, 32, 67, 237, 193, 19, 10, 73, 78, 79, 76, 79, 71, 73, 67, 65, 76, 90, 230, 1, 69, 30, 73, 22, 76, - 74, 79, 42, 82, 126, 84, 254, 182, 4, 66, 214, 41, 71, 234, 165, 16, 65, + 74, 79, 42, 82, 126, 84, 254, 182, 4, 66, 214, 41, 71, 158, 161, 16, 65, 162, 64, 67, 2, 68, 2, 70, 2, 72, 2, 74, 2, 75, 2, 77, 2, 78, 2, 80, 2, - 81, 2, 83, 2, 85, 2, 86, 2, 87, 2, 89, 3, 90, 7, 226, 199, 21, 84, 3, 90, - 5, 147, 220, 4, 78, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 238, 225, 8, 66, - 183, 182, 12, 83, 9, 238, 95, 80, 142, 232, 20, 69, 3, 85, 11, 92, 8, 69, - 86, 69, 82, 83, 69, 68, 32, 236, 128, 1, 5, 32, 87, 73, 84, 72, 179, 181, - 20, 85, 4, 242, 198, 21, 78, 3, 82, 13, 33, 6, 85, 82, 78, 69, 68, 32, - 10, 178, 198, 21, 69, 2, 71, 2, 75, 2, 77, 3, 82, 186, 11, 136, 1, 5, 77, + 81, 2, 83, 2, 85, 2, 86, 2, 87, 2, 89, 3, 90, 7, 150, 195, 21, 84, 3, 90, + 5, 147, 220, 4, 78, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 162, 221, 8, 66, + 183, 182, 12, 83, 9, 238, 95, 80, 194, 227, 20, 69, 3, 85, 11, 92, 8, 69, + 86, 69, 82, 83, 69, 68, 32, 236, 128, 1, 5, 32, 87, 73, 84, 72, 231, 176, + 20, 85, 4, 166, 194, 21, 78, 3, 82, 13, 33, 6, 85, 82, 78, 69, 68, 32, + 10, 230, 193, 21, 69, 2, 71, 2, 75, 2, 77, 3, 82, 186, 11, 136, 1, 5, 77, 65, 76, 76, 32, 145, 131, 1, 22, 85, 66, 83, 67, 82, 73, 80, 84, 32, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 150, 11, 76, 15, 67, 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, 43, 76, 4, 18, 73, 3, @@ -4516,2677 +4495,2670 @@ static const unsigned char packed_name_dawg[] = { 230, 2, 73, 166, 7, 74, 182, 1, 75, 178, 2, 76, 206, 6, 77, 178, 2, 78, 218, 3, 79, 242, 8, 80, 218, 2, 81, 174, 1, 82, 142, 8, 83, 250, 10, 84, 246, 13, 85, 218, 9, 86, 130, 3, 87, 110, 88, 226, 2, 89, 171, 3, 90, - 101, 118, 32, 198, 3, 69, 82, 78, 192, 226, 4, 4, 76, 80, 72, 65, 222, - 180, 15, 86, 186, 164, 1, 65, 2, 79, 2, 85, 3, 89, 72, 88, 5, 87, 73, 84, + 101, 118, 32, 198, 3, 69, 82, 78, 192, 226, 4, 4, 76, 80, 72, 65, 146, + 176, 15, 86, 186, 164, 1, 65, 2, 79, 2, 85, 3, 89, 72, 88, 5, 87, 73, 84, 72, 32, 157, 229, 5, 11, 82, 69, 86, 69, 82, 83, 69, 68, 45, 83, 67, 70, 150, 1, 66, 34, 68, 54, 82, 170, 34, 77, 250, 21, 67, 150, 50, 72, 158, - 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, 142, 175, 13, 84, 219, + 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, 194, 170, 13, 84, 219, 183, 3, 83, 12, 161, 106, 4, 82, 69, 86, 69, 12, 22, 79, 151, 57, 73, 8, 214, 57, 84, 211, 13, 85, 10, 26, 73, 175, 231, 4, 69, 8, 26, 78, 179, - 174, 4, 71, 6, 17, 2, 71, 32, 6, 236, 58, 4, 65, 66, 79, 86, 251, 223, + 174, 4, 71, 6, 17, 2, 71, 32, 6, 236, 58, 4, 65, 66, 79, 86, 175, 219, 18, 66, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 242, 116, 71, 186, 2, 65, - 239, 199, 3, 77, 2, 181, 198, 10, 7, 71, 76, 73, 67, 65, 78, 65, 41, 140, + 239, 199, 3, 77, 2, 233, 193, 10, 7, 71, 76, 73, 67, 65, 78, 65, 41, 140, 1, 6, 32, 87, 73, 84, 72, 32, 130, 1, 65, 108, 11, 76, 65, 67, 75, 76, - 69, 84, 84, 69, 82, 32, 38, 82, 174, 201, 4, 79, 143, 202, 16, 69, 18, - 110, 84, 138, 60, 70, 210, 57, 76, 230, 224, 3, 77, 174, 7, 80, 166, 183, + 69, 84, 84, 69, 82, 32, 38, 82, 174, 201, 4, 79, 195, 197, 16, 69, 18, + 110, 84, 138, 60, 70, 210, 57, 76, 230, 224, 3, 77, 174, 7, 80, 218, 178, 12, 68, 170, 206, 2, 72, 247, 165, 1, 83, 2, 255, 7, 79, 8, 64, 5, 82, - 82, 69, 68, 32, 161, 81, 6, 83, 69, 76, 73, 78, 69, 6, 182, 32, 65, 154, - 152, 21, 69, 3, 79, 6, 242, 195, 4, 79, 183, 244, 16, 69, 2, 181, 186, + 82, 69, 68, 32, 161, 81, 6, 83, 69, 76, 73, 78, 69, 6, 182, 32, 65, 206, + 147, 21, 69, 3, 79, 6, 242, 195, 4, 79, 235, 239, 16, 69, 2, 233, 181, 10, 4, 79, 75, 69, 78, 47, 108, 6, 32, 87, 73, 84, 72, 32, 196, 1, 2, 72, - 73, 92, 6, 76, 79, 83, 69, 68, 32, 90, 85, 155, 228, 20, 79, 24, 102, 67, - 182, 113, 65, 154, 233, 3, 80, 218, 5, 82, 246, 255, 14, 72, 182, 50, 66, - 242, 34, 68, 211, 80, 83, 10, 54, 69, 190, 113, 73, 150, 251, 6, 85, 207, + 73, 92, 6, 76, 79, 83, 69, 68, 32, 90, 85, 207, 223, 20, 79, 24, 102, 67, + 182, 113, 65, 154, 233, 3, 80, 218, 5, 82, 170, 251, 14, 72, 182, 50, 66, + 242, 34, 68, 211, 80, 83, 10, 54, 69, 190, 113, 73, 202, 246, 6, 85, 207, 161, 12, 65, 4, 245, 51, 5, 68, 73, 76, 76, 65, 7, 49, 10, 32, 87, 73, 84, 72, 32, 76, 79, 87, 32, 4, 162, 107, 82, 45, 4, 76, 69, 70, 84, 8, - 34, 73, 18, 79, 159, 200, 4, 82, 2, 163, 88, 78, 4, 130, 221, 4, 80, 151, - 146, 9, 77, 4, 37, 7, 65, 84, 82, 73, 76, 76, 79, 5, 209, 142, 13, 5, 32, + 34, 73, 18, 79, 159, 200, 4, 82, 2, 163, 88, 78, 4, 130, 221, 4, 80, 203, + 141, 9, 77, 4, 37, 7, 65, 84, 82, 73, 76, 76, 79, 5, 133, 138, 13, 5, 32, 87, 73, 84, 72, 73, 96, 6, 32, 87, 73, 84, 72, 32, 182, 1, 69, 34, 79, - 178, 1, 90, 178, 213, 4, 66, 187, 201, 16, 85, 32, 98, 83, 34, 84, 238, - 32, 67, 226, 45, 77, 170, 31, 76, 138, 217, 3, 72, 138, 15, 80, 167, 183, - 12, 68, 4, 134, 68, 72, 235, 189, 20, 84, 4, 26, 79, 215, 209, 19, 65, 2, - 219, 141, 20, 80, 8, 246, 78, 90, 207, 189, 20, 76, 16, 60, 6, 84, 76, - 69, 83, 83, 32, 49, 5, 85, 66, 76, 69, 32, 8, 26, 74, 151, 176, 21, 73, - 7, 167, 198, 4, 32, 8, 42, 87, 142, 202, 4, 82, 175, 239, 5, 84, 2, 163, - 239, 6, 89, 11, 11, 32, 8, 26, 87, 151, 198, 4, 68, 2, 169, 90, 5, 73, + 178, 1, 90, 178, 213, 4, 66, 239, 196, 16, 85, 32, 98, 83, 34, 84, 238, + 32, 67, 226, 45, 77, 170, 31, 76, 138, 217, 3, 72, 138, 15, 80, 219, 178, + 12, 68, 4, 134, 68, 72, 159, 185, 20, 84, 4, 26, 79, 139, 205, 19, 65, 2, + 143, 137, 20, 80, 8, 246, 78, 90, 131, 185, 20, 76, 16, 60, 6, 84, 76, + 69, 83, 83, 32, 49, 5, 85, 66, 76, 69, 32, 8, 26, 74, 203, 171, 21, 73, + 7, 167, 198, 4, 32, 8, 42, 87, 142, 202, 4, 82, 227, 234, 5, 84, 2, 215, + 234, 6, 89, 11, 11, 32, 8, 26, 87, 151, 198, 4, 68, 2, 169, 90, 5, 73, 84, 72, 32, 67, 119, 112, 6, 32, 87, 73, 84, 72, 32, 214, 4, 71, 72, 2, - 78, 71, 68, 2, 83, 72, 164, 1, 2, 90, 72, 159, 150, 17, 84, 76, 182, 1, + 78, 71, 68, 2, 83, 72, 164, 1, 2, 90, 72, 211, 145, 17, 84, 76, 182, 1, 67, 158, 2, 68, 110, 78, 214, 15, 84, 158, 23, 77, 250, 1, 86, 190, 3, 70, 178, 42, 72, 158, 1, 79, 198, 10, 71, 186, 2, 65, 246, 173, 3, 73, - 62, 66, 194, 64, 82, 235, 165, 16, 83, 24, 92, 6, 69, 68, 73, 76, 76, 65, - 32, 9, 73, 82, 67, 85, 77, 70, 76, 69, 88, 151, 132, 20, 65, 5, 169, 149, - 4, 3, 32, 65, 78, 19, 11, 32, 16, 40, 4, 65, 78, 68, 32, 167, 137, 19, + 62, 66, 194, 64, 82, 159, 161, 16, 83, 24, 92, 6, 69, 68, 73, 76, 76, 65, + 32, 9, 73, 82, 67, 85, 77, 70, 76, 69, 88, 203, 255, 19, 65, 5, 169, 149, + 4, 3, 32, 65, 78, 19, 11, 32, 16, 40, 4, 65, 78, 68, 32, 219, 132, 19, 66, 14, 162, 86, 67, 130, 2, 72, 226, 11, 71, 186, 2, 65, 238, 199, 3, - 77, 158, 170, 4, 68, 251, 234, 8, 84, 12, 22, 79, 227, 98, 73, 10, 28, 2, - 84, 32, 227, 51, 85, 8, 192, 88, 5, 65, 66, 79, 86, 69, 199, 175, 18, 66, - 2, 131, 154, 14, 79, 4, 157, 134, 7, 13, 89, 80, 84, 79, 76, 79, 71, 73, + 77, 210, 165, 4, 68, 251, 234, 8, 84, 12, 22, 79, 227, 98, 73, 10, 28, 2, + 84, 32, 227, 51, 85, 8, 192, 88, 5, 65, 66, 79, 86, 69, 251, 170, 18, 66, + 2, 183, 149, 14, 79, 4, 209, 129, 7, 13, 89, 80, 84, 79, 76, 79, 71, 73, 67, 65, 76, 32, 65, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 158, 195, 4, 67, 231, 9, 80, 13, 33, 6, 32, 87, 73, 84, 72, 32, 10, 88, 10, 68, 79, 85, 66, 76, 69, 32, 66, 65, 82, 230, 203, 4, 80, 142, 1, 67, 207, 4, 82, 5, 217, 204, 4, 4, 32, 65, 78, 68, 15, 11, 32, 12, 38, 82, 37, 5, 87, 73, - 84, 72, 32, 2, 157, 150, 14, 4, 69, 86, 69, 82, 10, 54, 67, 178, 202, 4, - 80, 218, 5, 82, 195, 158, 14, 84, 4, 234, 220, 7, 85, 207, 161, 12, 65, + 84, 72, 32, 2, 209, 145, 14, 4, 69, 86, 69, 82, 10, 54, 67, 178, 202, 4, + 80, 218, 5, 82, 247, 153, 14, 84, 4, 158, 216, 7, 85, 207, 161, 12, 65, 17, 84, 6, 32, 87, 73, 84, 72, 32, 73, 11, 69, 78, 71, 32, 68, 73, 71, - 82, 65, 80, 72, 10, 134, 194, 4, 77, 174, 7, 80, 206, 133, 15, 72, 166, - 85, 68, 211, 80, 83, 5, 209, 168, 18, 8, 32, 87, 73, 84, 72, 32, 84, 82, - 37, 72, 6, 32, 87, 73, 84, 72, 32, 126, 76, 230, 204, 18, 65, 147, 211, + 82, 65, 80, 72, 10, 134, 194, 4, 77, 174, 7, 80, 130, 129, 15, 72, 166, + 85, 68, 211, 80, 83, 5, 133, 164, 18, 8, 32, 87, 73, 84, 72, 32, 84, 82, + 37, 72, 6, 32, 87, 73, 84, 72, 32, 126, 76, 154, 200, 18, 65, 147, 211, 2, 72, 22, 218, 3, 67, 250, 90, 65, 178, 174, 3, 66, 190, 25, 77, 174, - 33, 80, 182, 235, 3, 79, 154, 154, 11, 72, 166, 85, 68, 211, 80, 83, 8, - 33, 6, 79, 84, 84, 65, 76, 32, 8, 142, 205, 18, 83, 250, 212, 2, 65, 2, + 33, 80, 234, 230, 3, 79, 154, 154, 11, 72, 166, 85, 68, 211, 80, 83, 8, + 33, 6, 79, 84, 84, 65, 76, 32, 8, 194, 200, 18, 83, 250, 212, 2, 65, 2, 73, 3, 85, 39, 140, 1, 6, 32, 87, 73, 84, 72, 32, 150, 45, 65, 232, 25, - 12, 79, 79, 75, 69, 68, 32, 83, 67, 72, 87, 65, 32, 174, 243, 3, 69, 159, - 230, 16, 86, 24, 86, 66, 34, 67, 46, 68, 214, 91, 76, 146, 232, 3, 80, - 206, 133, 15, 72, 247, 165, 1, 83, 2, 205, 147, 13, 3, 82, 69, 86, 6, - 158, 59, 69, 154, 32, 73, 227, 156, 19, 65, 8, 234, 87, 73, 226, 190, 3, - 69, 203, 228, 12, 79, 75, 80, 6, 32, 87, 73, 84, 72, 32, 222, 4, 78, 188, - 1, 2, 79, 84, 135, 152, 21, 83, 48, 178, 1, 67, 34, 68, 210, 1, 77, 64, + 12, 79, 79, 75, 69, 68, 32, 83, 67, 72, 87, 65, 32, 174, 243, 3, 69, 211, + 225, 16, 86, 24, 86, 66, 34, 67, 46, 68, 214, 91, 76, 146, 232, 3, 80, + 130, 129, 15, 72, 247, 165, 1, 83, 2, 129, 143, 13, 3, 82, 69, 86, 6, + 158, 59, 69, 154, 32, 73, 151, 152, 19, 65, 8, 234, 87, 73, 226, 190, 3, + 69, 255, 223, 12, 79, 75, 80, 6, 32, 87, 73, 84, 72, 32, 222, 4, 78, 188, + 1, 2, 79, 84, 187, 147, 21, 83, 48, 178, 1, 67, 34, 68, 210, 1, 77, 64, 6, 79, 71, 79, 78, 69, 75, 78, 84, 130, 71, 72, 226, 11, 71, 186, 2, 65, 246, 173, 3, 73, 62, 66, 144, 64, 6, 83, 84, 82, 79, 75, 69, 51, 82, 4, - 210, 88, 73, 227, 156, 19, 65, 14, 18, 73, 47, 79, 4, 217, 26, 7, 65, 69, + 210, 88, 73, 151, 152, 19, 65, 14, 18, 73, 47, 79, 4, 217, 26, 7, 65, 69, 82, 69, 83, 73, 83, 10, 28, 2, 84, 32, 215, 37, 85, 8, 64, 10, 65, 66, - 79, 86, 69, 32, 65, 78, 68, 32, 187, 249, 18, 66, 6, 150, 84, 71, 186, 2, - 65, 131, 221, 16, 84, 4, 29, 5, 65, 67, 82, 79, 78, 5, 217, 36, 4, 32, + 79, 86, 69, 32, 65, 78, 68, 32, 239, 244, 18, 66, 6, 150, 84, 71, 186, 2, + 65, 183, 216, 16, 84, 4, 29, 5, 65, 67, 82, 79, 78, 5, 217, 36, 4, 32, 65, 78, 68, 7, 145, 73, 15, 32, 65, 78, 68, 32, 68, 79, 84, 32, 65, 66, 79, 86, 69, 32, 4, 21, 3, 73, 76, 68, 4, 151, 142, 5, 69, 16, 46, 83, 93, - 7, 86, 69, 82, 84, 69, 68, 32, 12, 29, 5, 85, 76, 65, 82, 32, 12, 238, - 152, 21, 68, 2, 70, 2, 71, 2, 82, 2, 83, 3, 84, 4, 26, 65, 199, 129, 21, - 79, 2, 143, 188, 17, 76, 6, 206, 163, 4, 65, 129, 188, 6, 5, 73, 70, 73, + 7, 86, 69, 82, 84, 69, 68, 32, 12, 29, 5, 85, 76, 65, 82, 32, 12, 162, + 148, 21, 68, 2, 70, 2, 71, 2, 82, 2, 83, 3, 84, 4, 26, 65, 251, 252, 20, + 79, 2, 195, 183, 17, 76, 6, 206, 163, 4, 65, 181, 183, 6, 5, 73, 70, 73, 69, 68, 13, 33, 6, 32, 87, 73, 84, 72, 32, 10, 94, 67, 148, 180, 4, 13, - 68, 79, 84, 32, 65, 66, 79, 86, 69, 32, 65, 78, 68, 187, 178, 16, 83, 6, - 178, 82, 73, 130, 223, 3, 82, 227, 189, 15, 65, 29, 48, 6, 32, 87, 73, - 84, 72, 32, 175, 147, 21, 82, 24, 98, 67, 34, 68, 50, 83, 222, 79, 65, - 138, 1, 76, 146, 232, 3, 80, 182, 235, 3, 79, 155, 154, 11, 72, 4, 210, - 48, 69, 251, 188, 19, 65, 6, 214, 70, 73, 182, 197, 3, 69, 151, 182, 4, + 68, 79, 84, 32, 65, 66, 79, 86, 69, 32, 65, 78, 68, 239, 173, 16, 83, 6, + 178, 82, 73, 130, 223, 3, 82, 151, 185, 15, 65, 29, 48, 6, 32, 87, 73, + 84, 72, 32, 227, 142, 21, 82, 24, 98, 67, 34, 68, 50, 83, 222, 79, 65, + 138, 1, 76, 146, 232, 3, 80, 234, 230, 3, 79, 155, 154, 11, 72, 4, 210, + 48, 69, 175, 184, 19, 65, 6, 214, 70, 73, 182, 197, 3, 69, 203, 177, 4, 79, 4, 29, 5, 84, 82, 79, 75, 69, 5, 161, 25, 6, 32, 65, 78, 68, 32, 68, 79, 136, 1, 6, 32, 87, 73, 84, 72, 32, 250, 3, 65, 38, 69, 48, 5, 79, 78, - 71, 32, 83, 130, 180, 4, 83, 2, 90, 186, 201, 16, 85, 219, 16, 74, 50, + 71, 32, 83, 130, 180, 4, 83, 2, 90, 238, 196, 16, 85, 219, 16, 74, 50, 178, 1, 66, 86, 67, 56, 2, 68, 79, 100, 3, 77, 73, 68, 130, 2, 72, 230, 72, 65, 138, 1, 76, 150, 224, 3, 73, 162, 1, 82, 222, 2, 70, 130, 4, 80, - 234, 243, 12, 84, 219, 183, 3, 83, 6, 36, 3, 69, 76, 84, 167, 216, 20, + 158, 239, 12, 84, 219, 183, 3, 83, 6, 36, 3, 69, 76, 84, 219, 211, 20, 65, 5, 193, 181, 4, 6, 32, 65, 78, 68, 32, 80, 8, 166, 44, 69, 22, 73, - 154, 155, 7, 85, 207, 161, 12, 65, 8, 38, 84, 25, 5, 85, 66, 76, 69, 32, - 4, 141, 25, 2, 32, 66, 4, 242, 172, 4, 77, 175, 191, 15, 66, 8, 36, 4, - 68, 76, 69, 32, 207, 44, 45, 6, 186, 167, 17, 84, 210, 150, 3, 82, 79, - 68, 4, 173, 154, 4, 4, 77, 66, 68, 65, 6, 158, 181, 4, 90, 189, 138, 13, + 206, 150, 7, 85, 207, 161, 12, 65, 8, 38, 84, 25, 5, 85, 66, 76, 69, 32, + 4, 141, 25, 2, 32, 66, 4, 242, 172, 4, 77, 227, 186, 15, 66, 8, 36, 4, + 68, 76, 69, 32, 207, 44, 45, 6, 238, 162, 17, 84, 210, 150, 3, 82, 79, + 68, 4, 173, 154, 4, 4, 77, 66, 68, 65, 6, 158, 181, 4, 90, 241, 133, 13, 3, 78, 73, 83, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 18, 68, 35, 72, 4, - 206, 63, 73, 203, 205, 19, 79, 2, 197, 172, 4, 2, 73, 71, 27, 56, 6, 32, - 87, 73, 84, 72, 32, 102, 73, 167, 251, 20, 85, 16, 138, 72, 65, 182, 223, - 3, 67, 186, 2, 77, 174, 7, 80, 166, 183, 12, 68, 198, 60, 84, 231, 145, + 206, 63, 73, 255, 200, 19, 79, 2, 197, 172, 4, 2, 73, 71, 27, 56, 6, 32, + 87, 73, 84, 72, 32, 102, 73, 219, 246, 20, 85, 16, 138, 72, 65, 182, 223, + 3, 67, 186, 2, 77, 174, 7, 80, 218, 178, 12, 68, 198, 60, 84, 231, 145, 2, 72, 6, 25, 4, 68, 68, 76, 69, 6, 76, 7, 45, 87, 69, 76, 83, 72, 32, - 173, 145, 17, 6, 32, 83, 67, 79, 84, 83, 4, 190, 255, 19, 76, 211, 139, - 1, 86, 49, 58, 32, 216, 2, 2, 71, 32, 130, 247, 20, 85, 219, 16, 74, 40, + 225, 140, 17, 6, 32, 83, 67, 79, 84, 83, 4, 242, 250, 19, 76, 211, 139, + 1, 86, 49, 58, 32, 216, 2, 2, 71, 32, 182, 242, 20, 85, 219, 16, 74, 40, 88, 5, 87, 73, 84, 72, 32, 209, 142, 6, 11, 80, 82, 69, 67, 69, 68, 69, 68, 32, 66, 89, 38, 122, 67, 74, 76, 158, 37, 77, 234, 27, 71, 186, 2, - 65, 102, 68, 182, 232, 3, 80, 218, 5, 82, 222, 229, 3, 79, 183, 136, 9, - 84, 10, 170, 36, 69, 22, 73, 134, 255, 3, 82, 150, 156, 3, 85, 207, 161, + 65, 102, 68, 182, 232, 3, 80, 218, 5, 82, 146, 225, 3, 79, 183, 136, 9, + 84, 10, 170, 36, 69, 22, 73, 134, 255, 3, 82, 202, 151, 3, 85, 207, 161, 12, 65, 6, 132, 66, 3, 79, 78, 71, 202, 2, 73, 183, 239, 3, 69, 2, 25, 4, - 87, 73, 84, 72, 2, 177, 224, 17, 5, 32, 84, 73, 76, 68, 115, 116, 6, 32, - 87, 73, 84, 72, 32, 186, 6, 76, 52, 4, 80, 69, 78, 32, 174, 186, 13, 77, + 87, 73, 84, 72, 2, 229, 219, 17, 5, 32, 84, 73, 76, 68, 115, 116, 6, 32, + 87, 73, 84, 72, 32, 186, 6, 76, 52, 4, 80, 69, 78, 32, 226, 181, 13, 77, 134, 197, 7, 73, 2, 79, 3, 85, 86, 154, 1, 67, 70, 68, 152, 1, 2, 76, 79, 86, 77, 46, 79, 38, 83, 66, 84, 106, 86, 222, 44, 72, 242, 12, 71, 186, 2, 65, 246, 173, 3, 73, 62, 66, 195, 64, 82, 14, 172, 49, 9, 73, 82, 67, - 85, 77, 70, 76, 69, 88, 159, 172, 19, 65, 14, 18, 73, 47, 79, 4, 221, 13, + 85, 77, 70, 76, 69, 88, 211, 167, 19, 65, 14, 18, 73, 47, 79, 4, 221, 13, 7, 65, 69, 82, 69, 83, 73, 83, 10, 22, 84, 171, 47, 85, 6, 11, 32, 6, - 140, 13, 5, 65, 66, 79, 86, 69, 223, 212, 18, 66, 6, 66, 78, 216, 208, + 140, 13, 5, 65, 66, 79, 86, 69, 147, 208, 18, 66, 6, 66, 78, 140, 204, 12, 6, 87, 32, 82, 73, 78, 71, 255, 177, 8, 79, 2, 159, 21, 71, 6, 11, 65, 6, 189, 2, 4, 67, 82, 79, 78, 4, 217, 11, 5, 71, 79, 78, 69, 75, 4, 25, 4, 84, 82, 79, 75, 4, 11, 69, 5, 213, 49, 2, 32, 65, 8, 25, 4, 73, 76, 68, 69, 9, 29, 5, 32, 65, 78, 68, 32, 6, 162, 47, 68, 142, 13, 65, 239, 199, 3, 77, 6, 81, 18, 69, 82, 84, 73, 67, 65, 76, 32, 76, 73, 78, - 69, 32, 66, 69, 76, 79, 87, 7, 221, 43, 4, 32, 65, 78, 68, 2, 153, 136, + 69, 32, 66, 69, 76, 79, 87, 7, 221, 43, 4, 32, 65, 78, 68, 2, 205, 131, 10, 8, 68, 32, 80, 79, 76, 73, 83, 72, 16, 26, 79, 131, 166, 4, 69, 13, - 48, 6, 32, 87, 73, 84, 72, 32, 227, 254, 20, 69, 8, 210, 55, 71, 186, 2, - 65, 242, 238, 3, 82, 235, 165, 16, 83, 25, 44, 6, 32, 87, 73, 84, 72, 32, + 48, 6, 32, 87, 73, 84, 72, 32, 151, 250, 20, 69, 8, 210, 55, 71, 186, 2, + 65, 242, 238, 3, 82, 159, 161, 16, 83, 25, 44, 6, 32, 87, 73, 84, 72, 32, 179, 1, 72, 18, 86, 70, 34, 83, 170, 56, 65, 238, 225, 3, 77, 174, 7, 80, - 206, 133, 15, 72, 167, 85, 68, 2, 153, 196, 14, 3, 76, 79, 85, 6, 210, - 28, 84, 209, 175, 12, 6, 81, 85, 73, 82, 82, 69, 4, 26, 65, 171, 252, 20, + 130, 129, 15, 72, 167, 85, 68, 2, 205, 191, 14, 3, 76, 79, 85, 6, 210, + 28, 84, 133, 171, 12, 6, 81, 85, 73, 82, 82, 69, 4, 26, 65, 223, 247, 20, 73, 2, 193, 183, 5, 18, 82, 89, 78, 71, 69, 65, 76, 32, 86, 79, 73, 67, 69, 68, 32, 70, 82, 73, 13, 48, 6, 32, 87, 73, 84, 72, 32, 139, 161, 4, - 80, 8, 42, 68, 16, 4, 72, 79, 79, 75, 23, 83, 2, 227, 44, 73, 5, 171, - 195, 18, 32, 2, 197, 26, 6, 84, 82, 79, 75, 69, 32, 77, 90, 32, 228, 4, + 80, 8, 42, 68, 16, 4, 72, 79, 79, 75, 23, 83, 2, 227, 44, 73, 5, 223, + 190, 18, 32, 2, 197, 26, 6, 84, 82, 79, 75, 69, 32, 77, 90, 32, 228, 4, 8, 69, 86, 69, 82, 83, 69, 68, 32, 148, 2, 2, 85, 77, 179, 147, 4, 65, - 46, 36, 4, 87, 73, 84, 72, 235, 6, 82, 44, 26, 32, 195, 190, 15, 79, 42, + 46, 36, 4, 87, 73, 84, 72, 235, 6, 82, 44, 26, 32, 247, 185, 15, 79, 42, 166, 1, 67, 50, 68, 200, 1, 8, 70, 73, 83, 72, 72, 79, 79, 75, 66, 76, - 34, 84, 142, 18, 77, 162, 30, 65, 246, 173, 3, 73, 166, 59, 80, 182, 235, - 3, 79, 143, 192, 12, 83, 6, 170, 19, 69, 154, 255, 3, 82, 227, 189, 15, - 65, 8, 11, 79, 8, 24, 2, 84, 32, 111, 85, 6, 26, 66, 251, 249, 19, 65, 4, + 34, 84, 142, 18, 77, 162, 30, 65, 246, 173, 3, 73, 166, 59, 80, 234, 230, + 3, 79, 143, 192, 12, 83, 6, 170, 19, 69, 154, 255, 3, 82, 151, 185, 15, + 65, 8, 11, 79, 8, 24, 2, 84, 32, 111, 85, 6, 26, 66, 175, 245, 19, 65, 4, 25, 4, 69, 76, 79, 87, 5, 29, 5, 32, 65, 78, 68, 32, 2, 191, 249, 3, 77, 2, 21, 3, 66, 76, 69, 2, 11, 32, 2, 227, 46, 71, 7, 29, 5, 32, 65, 78, 68, 32, 4, 214, 146, 4, 77, 175, 7, 80, 4, 222, 49, 73, 131, 236, 3, 79, - 4, 238, 215, 18, 73, 195, 61, 65, 22, 162, 1, 72, 40, 6, 79, 80, 69, 78, + 4, 162, 211, 18, 73, 195, 61, 65, 22, 162, 1, 72, 40, 6, 79, 80, 69, 78, 32, 69, 216, 147, 4, 8, 82, 32, 87, 73, 84, 72, 32, 70, 168, 2, 3, 83, - 67, 82, 190, 223, 14, 69, 190, 87, 67, 159, 166, 1, 75, 2, 11, 65, 2, - 253, 250, 9, 2, 76, 70, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 138, 157, 4, - 82, 247, 255, 14, 72, 5, 11, 32, 2, 11, 82, 2, 185, 146, 17, 3, 79, 84, + 67, 82, 242, 218, 14, 69, 190, 87, 67, 159, 166, 1, 75, 2, 11, 65, 2, + 177, 246, 9, 2, 76, 70, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 138, 157, 4, + 82, 171, 251, 14, 72, 5, 11, 32, 2, 11, 82, 2, 237, 141, 17, 3, 79, 84, 85, 85, 180, 1, 6, 32, 87, 73, 84, 72, 32, 218, 4, 65, 66, 67, 218, 1, 72, 34, 73, 156, 2, 13, 81, 85, 65, 84, 32, 82, 69, 86, 69, 82, 83, 69, - 68, 221, 235, 9, 6, 84, 73, 82, 82, 85, 80, 40, 110, 65, 34, 67, 86, 68, - 138, 1, 83, 174, 1, 86, 210, 9, 77, 186, 135, 4, 80, 182, 235, 3, 79, + 68, 145, 231, 9, 6, 84, 73, 82, 82, 85, 80, 40, 110, 65, 34, 67, 86, 68, + 138, 1, 83, 174, 1, 86, 210, 9, 77, 186, 135, 4, 80, 234, 230, 3, 79, 155, 154, 11, 72, 4, 205, 1, 4, 67, 85, 84, 69, 12, 58, 65, 230, 10, 69, - 82, 79, 202, 31, 73, 151, 251, 6, 85, 4, 113, 3, 82, 79, 78, 8, 32, 3, - 79, 84, 32, 207, 32, 73, 6, 26, 66, 207, 241, 19, 65, 4, 25, 4, 69, 76, - 79, 87, 5, 11, 32, 2, 173, 237, 19, 3, 65, 78, 68, 4, 22, 72, 203, 42, + 82, 79, 202, 31, 73, 203, 246, 6, 85, 4, 113, 3, 82, 79, 78, 8, 32, 3, + 79, 84, 32, 207, 32, 73, 6, 26, 66, 131, 237, 19, 65, 4, 25, 4, 69, 76, + 79, 87, 5, 11, 32, 2, 225, 232, 19, 3, 65, 78, 68, 4, 22, 72, 203, 42, 87, 2, 21, 3, 79, 82, 84, 2, 17, 2, 32, 83, 2, 11, 84, 2, 21, 3, 82, 79, - 75, 2, 11, 69, 2, 17, 2, 32, 79, 2, 197, 222, 19, 4, 86, 69, 82, 76, 2, - 37, 7, 69, 82, 84, 73, 67, 65, 76, 2, 205, 40, 2, 32, 76, 4, 46, 76, 165, - 226, 19, 5, 75, 72, 65, 32, 89, 2, 247, 12, 84, 18, 48, 3, 72, 87, 65, + 75, 2, 11, 69, 2, 17, 2, 32, 79, 2, 249, 217, 19, 4, 86, 69, 82, 76, 2, + 37, 7, 69, 82, 84, 73, 67, 65, 76, 2, 205, 40, 2, 32, 76, 4, 46, 76, 217, + 221, 19, 5, 75, 72, 65, 32, 89, 2, 247, 12, 84, 18, 48, 3, 72, 87, 65, 97, 5, 82, 73, 80, 84, 32, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 222, 35, - 71, 186, 2, 65, 242, 238, 3, 82, 247, 255, 14, 72, 8, 26, 82, 207, 132, - 4, 71, 5, 241, 186, 11, 5, 32, 87, 73, 84, 72, 2, 133, 240, 16, 3, 65, + 71, 186, 2, 65, 242, 238, 3, 82, 171, 251, 14, 72, 8, 26, 82, 207, 132, + 4, 71, 5, 165, 182, 11, 5, 32, 87, 73, 84, 72, 2, 185, 235, 16, 3, 65, 82, 80, 14, 48, 7, 68, 69, 87, 65, 89, 83, 32, 199, 1, 71, 12, 110, 79, - 56, 4, 84, 85, 82, 78, 156, 205, 10, 11, 68, 73, 65, 69, 82, 69, 83, 73, - 90, 69, 68, 215, 154, 10, 85, 7, 26, 80, 135, 135, 4, 32, 2, 193, 240, 9, - 2, 69, 78, 2, 221, 138, 13, 2, 69, 68, 2, 237, 237, 16, 4, 77, 79, 73, - 68, 2, 139, 129, 10, 32, 147, 1, 188, 1, 6, 32, 87, 73, 84, 72, 32, 192, + 56, 4, 84, 85, 82, 78, 208, 200, 10, 11, 68, 73, 65, 69, 82, 69, 83, 73, + 90, 69, 68, 215, 154, 10, 85, 7, 26, 80, 135, 135, 4, 32, 2, 245, 235, 9, + 2, 69, 78, 2, 145, 134, 13, 2, 69, 68, 2, 161, 233, 16, 4, 77, 79, 73, + 68, 2, 191, 252, 9, 32, 147, 1, 188, 1, 6, 32, 87, 73, 84, 72, 32, 192, 3, 2, 69, 83, 70, 72, 130, 2, 79, 102, 82, 54, 85, 174, 131, 4, 67, 202, - 1, 83, 208, 129, 11, 9, 65, 73, 76, 76, 69, 83, 83, 32, 80, 251, 215, 5, + 1, 83, 132, 253, 10, 9, 65, 73, 76, 76, 69, 83, 83, 32, 80, 251, 215, 5, 90, 34, 110, 67, 182, 1, 68, 66, 77, 170, 31, 76, 146, 232, 3, 80, 168, - 5, 4, 72, 79, 79, 75, 50, 82, 235, 165, 16, 83, 10, 58, 69, 22, 73, 62, - 79, 222, 154, 7, 85, 207, 161, 12, 65, 2, 219, 168, 12, 68, 2, 37, 7, 82, - 67, 85, 77, 70, 76, 69, 2, 215, 178, 18, 88, 2, 17, 2, 77, 77, 2, 175, - 178, 18, 65, 8, 32, 2, 73, 65, 135, 191, 16, 79, 4, 154, 21, 71, 215, 6, + 5, 4, 72, 79, 79, 75, 50, 82, 159, 161, 16, 83, 10, 58, 69, 22, 73, 62, + 79, 146, 150, 7, 85, 207, 161, 12, 65, 2, 143, 164, 12, 68, 2, 37, 7, 82, + 67, 85, 77, 70, 76, 69, 2, 139, 174, 18, 88, 2, 17, 2, 77, 77, 2, 227, + 173, 18, 65, 8, 32, 2, 73, 65, 187, 186, 16, 79, 4, 154, 21, 71, 215, 6, 69, 4, 17, 2, 73, 68, 4, 26, 45, 255, 255, 3, 68, 2, 149, 142, 4, 6, 72, 69, 73, 71, 72, 84, 6, 45, 9, 72, 32, 68, 73, 71, 82, 65, 80, 72, 7, 243, 133, 4, 32, 8, 64, 12, 32, 87, 73, 84, 72, 32, 83, 84, 82, 73, 75, 69, - 43, 79, 2, 233, 179, 16, 5, 84, 72, 82, 79, 85, 6, 17, 2, 82, 78, 7, 41, + 43, 79, 2, 157, 175, 16, 5, 84, 72, 82, 79, 85, 6, 17, 2, 82, 78, 7, 41, 8, 32, 87, 73, 84, 72, 32, 83, 84, 4, 25, 4, 82, 79, 75, 69, 5, 11, 32, 2, 133, 215, 3, 6, 84, 72, 82, 79, 85, 71, 8, 26, 78, 203, 133, 4, 80, 6, - 17, 2, 69, 32, 6, 206, 206, 4, 83, 134, 212, 10, 70, 155, 168, 3, 84, 2, - 17, 2, 69, 83, 2, 11, 73, 2, 255, 187, 20, 76, 76, 44, 5, 82, 78, 69, 68, - 32, 143, 222, 20, 77, 74, 162, 1, 68, 22, 72, 66, 73, 54, 79, 142, 1, 82, - 110, 84, 22, 86, 198, 129, 4, 65, 38, 77, 198, 2, 89, 210, 193, 16, 85, - 218, 19, 69, 2, 71, 2, 75, 2, 76, 3, 87, 2, 131, 160, 17, 69, 7, 141, + 17, 2, 69, 32, 6, 206, 206, 4, 83, 186, 207, 10, 70, 155, 168, 3, 84, 2, + 17, 2, 69, 83, 2, 11, 73, 2, 179, 183, 20, 76, 76, 44, 5, 82, 78, 69, 68, + 32, 195, 217, 20, 77, 74, 162, 1, 68, 22, 72, 66, 73, 54, 79, 142, 1, 82, + 110, 84, 22, 86, 198, 129, 4, 65, 38, 77, 198, 2, 89, 134, 189, 16, 85, + 218, 19, 69, 2, 71, 2, 75, 2, 76, 3, 87, 2, 183, 155, 17, 69, 7, 141, 242, 3, 11, 32, 87, 73, 84, 72, 32, 70, 73, 83, 72, 72, 5, 11, 78, 2, - 197, 218, 9, 5, 83, 85, 76, 65, 82, 12, 66, 69, 232, 230, 3, 7, 32, 79, + 249, 213, 9, 5, 83, 85, 76, 65, 82, 12, 66, 69, 232, 230, 3, 7, 32, 79, 80, 69, 78, 45, 79, 159, 29, 80, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, - 238, 178, 18, 72, 143, 248, 1, 83, 15, 33, 6, 32, 87, 73, 84, 72, 32, 12, - 198, 247, 3, 77, 174, 7, 80, 130, 5, 76, 154, 159, 14, 84, 183, 97, 72, + 162, 174, 18, 72, 143, 248, 1, 83, 15, 33, 6, 32, 87, 73, 84, 72, 32, 12, + 198, 247, 3, 77, 174, 7, 80, 130, 5, 76, 206, 154, 14, 84, 183, 97, 72, 5, 135, 255, 3, 32, 7, 11, 32, 4, 161, 5, 4, 87, 73, 84, 72, 97, 90, 32, - 152, 228, 3, 6, 80, 83, 73, 76, 79, 78, 182, 244, 16, 69, 2, 73, 2, 77, + 152, 228, 3, 6, 80, 83, 73, 76, 79, 78, 234, 239, 16, 69, 2, 73, 2, 77, 3, 79, 82, 48, 3, 66, 65, 82, 49, 5, 87, 73, 84, 72, 32, 5, 245, 17, 8, 32, 87, 73, 84, 72, 32, 83, 72, 78, 142, 1, 67, 74, 68, 150, 2, 72, 170, 1, 77, 134, 1, 79, 106, 82, 38, 84, 186, 9, 71, 82, 83, 234, 1, 65, 246, 173, 3, 73, 62, 66, 143, 66, 76, 6, 152, 203, 4, 9, 73, 82, 67, 85, 77, - 70, 76, 69, 88, 139, 228, 14, 65, 18, 52, 8, 73, 65, 69, 82, 69, 83, 73, - 83, 131, 1, 79, 13, 11, 32, 10, 40, 4, 65, 78, 68, 32, 183, 179, 18, 66, - 8, 50, 67, 226, 13, 71, 186, 2, 65, 239, 199, 3, 77, 2, 183, 173, 19, 65, - 6, 26, 85, 167, 163, 18, 84, 4, 21, 3, 66, 76, 69, 4, 11, 32, 4, 138, 13, + 70, 76, 69, 88, 191, 223, 14, 65, 18, 52, 8, 73, 65, 69, 82, 69, 83, 73, + 83, 131, 1, 79, 13, 11, 32, 10, 40, 4, 65, 78, 68, 32, 235, 174, 18, 66, + 8, 50, 67, 226, 13, 71, 186, 2, 65, 239, 199, 3, 77, 2, 235, 168, 19, 65, + 6, 26, 85, 219, 158, 18, 84, 4, 21, 3, 66, 76, 69, 4, 11, 32, 4, 138, 13, 71, 187, 2, 65, 14, 11, 79, 14, 28, 2, 82, 78, 207, 81, 79, 13, 29, 5, - 32, 65, 78, 68, 32, 10, 66, 72, 226, 11, 71, 186, 2, 65, 138, 242, 7, 68, + 32, 65, 78, 68, 32, 10, 66, 72, 226, 11, 71, 186, 2, 65, 190, 237, 7, 68, 251, 234, 8, 84, 2, 229, 80, 2, 79, 79, 10, 29, 5, 65, 67, 82, 79, 78, - 11, 29, 5, 32, 65, 78, 68, 32, 8, 50, 68, 214, 10, 71, 186, 2, 65, 131, - 221, 16, 84, 2, 171, 10, 73, 6, 29, 5, 71, 79, 78, 69, 75, 7, 11, 32, 4, - 25, 4, 65, 78, 68, 32, 4, 178, 12, 65, 131, 221, 16, 84, 4, 142, 251, 3, - 69, 171, 161, 14, 73, 6, 25, 4, 73, 76, 68, 69, 7, 11, 32, 4, 26, 65, - 151, 174, 18, 66, 2, 17, 2, 78, 68, 2, 11, 32, 2, 139, 11, 65, 29, 84, 6, - 32, 87, 73, 84, 72, 32, 162, 1, 73, 66, 79, 134, 189, 19, 69, 151, 144, - 1, 89, 14, 82, 68, 234, 242, 3, 80, 142, 1, 67, 146, 7, 82, 206, 235, 12, - 84, 231, 145, 2, 72, 4, 26, 73, 203, 251, 7, 79, 2, 17, 2, 65, 71, 2, - 201, 157, 20, 2, 79, 78, 2, 41, 8, 83, 73, 71, 79, 84, 72, 73, 67, 2, - 131, 239, 18, 32, 6, 33, 6, 76, 65, 80, 85, 75, 32, 6, 158, 182, 20, 65, + 11, 29, 5, 32, 65, 78, 68, 32, 8, 50, 68, 214, 10, 71, 186, 2, 65, 183, + 216, 16, 84, 2, 171, 10, 73, 6, 29, 5, 71, 79, 78, 69, 75, 7, 11, 32, 4, + 25, 4, 65, 78, 68, 32, 4, 178, 12, 65, 183, 216, 16, 84, 4, 142, 251, 3, + 69, 223, 156, 14, 73, 6, 25, 4, 73, 76, 68, 69, 7, 11, 32, 4, 26, 65, + 203, 169, 18, 66, 2, 17, 2, 78, 68, 2, 11, 32, 2, 139, 11, 65, 29, 84, 6, + 32, 87, 73, 84, 72, 32, 162, 1, 73, 66, 79, 186, 184, 19, 69, 151, 144, + 1, 89, 14, 82, 68, 234, 242, 3, 80, 142, 1, 67, 146, 7, 82, 130, 231, 12, + 84, 231, 145, 2, 72, 4, 26, 73, 255, 246, 7, 79, 2, 17, 2, 65, 71, 2, + 253, 152, 20, 2, 79, 78, 2, 41, 8, 83, 73, 71, 79, 84, 72, 73, 67, 2, + 183, 234, 18, 32, 6, 33, 6, 76, 65, 80, 85, 75, 32, 6, 210, 177, 20, 65, 2, 79, 3, 85, 19, 33, 6, 32, 87, 73, 84, 72, 32, 16, 202, 4, 67, 18, 68, - 70, 71, 186, 2, 65, 154, 144, 18, 82, 207, 94, 72, 17, 33, 6, 32, 87, 73, + 70, 71, 186, 2, 65, 206, 139, 18, 82, 207, 94, 72, 17, 33, 6, 32, 87, 73, 84, 72, 32, 14, 42, 68, 32, 2, 76, 79, 187, 239, 3, 80, 4, 222, 3, 73, - 247, 198, 19, 79, 8, 60, 11, 78, 71, 32, 76, 69, 70, 84, 32, 76, 69, 71, + 171, 194, 19, 79, 8, 60, 11, 78, 71, 32, 76, 69, 70, 84, 32, 76, 69, 71, 79, 87, 7, 11, 32, 4, 60, 7, 65, 78, 68, 32, 76, 79, 87, 65, 4, 87, 73, - 84, 72, 2, 17, 2, 32, 82, 2, 21, 3, 73, 71, 72, 2, 155, 154, 11, 84, 2, - 185, 199, 19, 4, 32, 83, 69, 82, 33, 48, 6, 32, 87, 73, 84, 72, 32, 175, - 155, 16, 79, 28, 110, 67, 18, 68, 70, 71, 22, 72, 42, 76, 22, 83, 234, 1, - 65, 238, 199, 3, 77, 150, 149, 13, 84, 155, 179, 1, 82, 2, 203, 3, 73, 6, - 26, 73, 171, 163, 16, 79, 2, 17, 2, 65, 69, 2, 187, 192, 16, 82, 2, 239, - 216, 18, 82, 4, 17, 2, 79, 79, 4, 239, 136, 5, 75, 2, 187, 205, 19, 79, - 4, 26, 72, 179, 150, 20, 84, 2, 21, 3, 79, 82, 84, 2, 197, 252, 7, 6, 32, + 84, 72, 2, 17, 2, 32, 82, 2, 21, 3, 73, 71, 72, 2, 207, 149, 11, 84, 2, + 237, 194, 19, 4, 32, 83, 69, 82, 33, 48, 6, 32, 87, 73, 84, 72, 32, 227, + 150, 16, 79, 28, 110, 67, 18, 68, 70, 71, 22, 72, 42, 76, 22, 83, 234, 1, + 65, 238, 199, 3, 77, 202, 144, 13, 84, 155, 179, 1, 82, 2, 203, 3, 73, 6, + 26, 73, 223, 158, 16, 79, 2, 17, 2, 65, 69, 2, 239, 187, 16, 82, 2, 163, + 212, 18, 82, 4, 17, 2, 79, 79, 4, 239, 136, 5, 75, 2, 239, 200, 19, 79, + 4, 26, 72, 231, 145, 20, 84, 2, 21, 3, 79, 82, 84, 2, 249, 247, 7, 6, 32, 82, 73, 71, 72, 84, 31, 33, 6, 32, 87, 73, 84, 72, 32, 28, 98, 65, 22, - 67, 82, 68, 38, 76, 34, 83, 198, 224, 3, 77, 174, 7, 80, 218, 5, 82, 247, - 255, 14, 72, 2, 223, 190, 13, 67, 6, 42, 73, 150, 251, 6, 85, 207, 161, - 12, 65, 2, 229, 203, 11, 4, 82, 67, 85, 77, 6, 154, 187, 3, 69, 203, 228, - 12, 79, 2, 11, 73, 2, 163, 183, 12, 78, 4, 26, 87, 163, 147, 20, 84, 2, - 215, 154, 17, 65, 18, 90, 70, 142, 195, 9, 73, 172, 9, 6, 76, 79, 78, 71, - 32, 83, 190, 217, 10, 83, 219, 5, 79, 10, 34, 70, 254, 193, 20, 73, 3, - 76, 7, 250, 193, 20, 73, 3, 76, 36, 150, 1, 83, 202, 192, 20, 65, 2, 69, + 67, 82, 68, 38, 76, 34, 83, 198, 224, 3, 77, 174, 7, 80, 218, 5, 82, 171, + 251, 14, 72, 2, 147, 186, 13, 67, 6, 42, 73, 202, 246, 6, 85, 207, 161, + 12, 65, 2, 153, 199, 11, 4, 82, 67, 85, 77, 6, 154, 187, 3, 69, 255, 223, + 12, 79, 2, 11, 73, 2, 215, 178, 12, 78, 4, 26, 87, 215, 142, 20, 84, 2, + 139, 150, 17, 65, 18, 90, 70, 194, 190, 9, 73, 172, 9, 6, 76, 79, 78, 71, + 32, 83, 190, 217, 10, 83, 219, 5, 79, 10, 34, 70, 178, 189, 20, 73, 3, + 76, 7, 174, 189, 20, 73, 3, 76, 36, 150, 1, 83, 254, 187, 20, 65, 2, 69, 2, 72, 2, 73, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, 79, 2, 80, 2, 82, 2, 84, 2, 85, 2, 86, 3, 88, 5, 215, 230, 4, 67, 226, 5, 240, 1, 2, 65, 70, 144, 1, 2, 70, 84, 190, 38, 79, 20, 5, 80, 67, 72, 65, 32, 164, 8, 8, 83, - 83, 45, 84, 72, 65, 78, 32, 184, 250, 12, 5, 85, 75, 79, 84, 72, 218, + 83, 45, 84, 72, 65, 78, 32, 236, 245, 12, 5, 85, 75, 79, 84, 72, 218, 194, 3, 68, 228, 23, 6, 86, 69, 76, 32, 83, 76, 218, 233, 2, 77, 239, 79, 71, 6, 120, 3, 76, 69, 83, 160, 196, 1, 14, 32, 70, 76, 85, 84, 84, 69, - 82, 73, 78, 71, 32, 73, 78, 189, 218, 11, 3, 89, 32, 71, 2, 227, 243, 14, + 82, 73, 78, 71, 32, 73, 78, 241, 213, 11, 3, 89, 32, 71, 2, 151, 239, 14, 83, 134, 4, 58, 32, 250, 20, 45, 217, 2, 6, 87, 65, 82, 68, 83, 32, 246, 1, 166, 2, 65, 234, 4, 66, 202, 1, 67, 96, 2, 68, 79, 112, 2, 72, 65, - 166, 3, 76, 46, 77, 38, 79, 102, 82, 146, 3, 83, 82, 84, 222, 1, 87, 158, - 183, 8, 70, 236, 5, 14, 74, 85, 83, 84, 73, 70, 73, 69, 68, 32, 82, 73, + 166, 3, 76, 46, 77, 38, 79, 102, 82, 146, 3, 83, 82, 84, 222, 1, 87, 210, + 178, 8, 70, 236, 5, 14, 74, 85, 83, 84, 73, 70, 73, 69, 68, 32, 82, 73, 71, 72, 86, 78, 202, 1, 80, 153, 13, 10, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 28, 22, 78, 143, 4, 82, 22, 28, 2, 68, 32, 191, 3, 71, 16, 96, 6, 76, 79, 87, 69, 82, 32, 32, 6, 82, 73, 71, 72, 84, 32, 89, 6, 85, 80, 80, - 69, 82, 32, 4, 202, 1, 65, 239, 196, 17, 79, 6, 50, 84, 209, 143, 18, 6, - 68, 79, 85, 66, 76, 69, 4, 250, 157, 17, 82, 211, 232, 1, 65, 6, 82, 65, + 69, 82, 32, 4, 202, 1, 65, 163, 192, 17, 79, 6, 50, 84, 133, 139, 18, 6, + 68, 79, 85, 66, 76, 69, 4, 174, 153, 17, 82, 211, 232, 1, 65, 6, 82, 65, 53, 16, 79, 78, 69, 32, 69, 73, 71, 72, 84, 72, 32, 66, 76, 79, 67, 75, - 2, 237, 155, 17, 8, 78, 68, 32, 82, 73, 71, 72, 84, 5, 245, 147, 19, 17, + 2, 161, 151, 17, 8, 78, 68, 32, 82, 73, 71, 72, 84, 5, 169, 143, 19, 17, 32, 67, 79, 78, 84, 65, 73, 78, 73, 78, 71, 32, 66, 76, 65, 67, 75, 6, - 198, 188, 8, 69, 185, 1, 4, 76, 69, 32, 66, 6, 26, 67, 163, 192, 8, 82, - 2, 253, 191, 8, 5, 32, 76, 69, 83, 83, 12, 40, 4, 65, 82, 66, 32, 187, - 192, 8, 76, 8, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 4, 57, 12, 32, 82, - 73, 71, 72, 84, 32, 66, 65, 82, 66, 32, 4, 240, 137, 17, 4, 68, 79, 87, - 78, 1, 2, 85, 80, 14, 254, 191, 8, 85, 166, 26, 79, 242, 235, 2, 69, 141, + 250, 183, 8, 69, 185, 1, 4, 76, 69, 32, 66, 6, 26, 67, 215, 187, 8, 82, + 2, 177, 187, 8, 5, 32, 76, 69, 83, 83, 12, 40, 4, 65, 82, 66, 32, 239, + 187, 8, 76, 8, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 4, 57, 12, 32, 82, + 73, 71, 72, 84, 32, 66, 65, 82, 66, 32, 4, 164, 133, 17, 4, 68, 79, 87, + 78, 1, 2, 85, 80, 14, 178, 187, 8, 85, 166, 26, 79, 242, 235, 2, 69, 141, 168, 2, 8, 76, 79, 83, 69, 68, 32, 69, 78, 10, 44, 5, 85, 66, 76, 69, 32, - 171, 192, 8, 84, 8, 222, 193, 8, 87, 190, 30, 65, 154, 132, 3, 81, 199, - 199, 4, 80, 38, 36, 3, 76, 70, 32, 163, 198, 8, 78, 36, 132, 2, 6, 67, - 73, 82, 67, 76, 69, 162, 193, 8, 66, 90, 70, 82, 72, 50, 82, 58, 84, 70, + 223, 187, 8, 84, 8, 146, 189, 8, 87, 190, 30, 65, 154, 132, 3, 81, 199, + 199, 4, 80, 38, 36, 3, 76, 70, 32, 215, 193, 8, 78, 36, 132, 2, 6, 67, + 73, 82, 67, 76, 69, 214, 188, 8, 66, 90, 70, 82, 72, 50, 82, 58, 84, 70, 87, 246, 13, 76, 22, 85, 176, 200, 8, 30, 73, 78, 86, 69, 82, 83, 69, 32, 77, 69, 68, 73, 85, 77, 32, 83, 72, 65, 68, 69, 32, 65, 78, 68, 32, 82, 73, 71, 72, 84, 255, 26, 77, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 42, - 84, 206, 136, 18, 70, 191, 214, 1, 68, 4, 150, 203, 5, 72, 199, 145, 13, - 87, 4, 232, 162, 1, 2, 85, 71, 163, 161, 7, 79, 2, 217, 155, 19, 4, 85, - 76, 84, 73, 8, 36, 3, 78, 69, 32, 243, 196, 8, 85, 6, 194, 183, 17, 81, + 84, 130, 132, 18, 70, 191, 214, 1, 68, 4, 146, 203, 5, 72, 255, 140, 13, + 87, 4, 232, 162, 1, 2, 85, 71, 215, 156, 7, 79, 2, 141, 151, 19, 4, 85, + 76, 84, 73, 8, 36, 3, 78, 69, 32, 167, 192, 8, 85, 6, 246, 178, 17, 81, 146, 4, 69, 45, 5, 84, 72, 73, 82, 68, 30, 44, 5, 73, 71, 72, 84, 32, - 199, 197, 8, 65, 28, 152, 1, 5, 65, 82, 82, 79, 87, 132, 1, 12, 68, 79, - 85, 66, 76, 69, 32, 65, 82, 82, 79, 87, 30, 87, 214, 242, 8, 79, 162, + 251, 192, 8, 65, 28, 152, 1, 5, 65, 82, 82, 79, 87, 132, 1, 12, 68, 79, + 85, 66, 76, 69, 32, 65, 82, 82, 79, 87, 30, 87, 138, 238, 8, 79, 162, 143, 8, 66, 54, 83, 211, 68, 84, 11, 11, 32, 8, 72, 5, 87, 73, 84, 72, - 32, 221, 214, 18, 7, 84, 72, 82, 79, 85, 71, 72, 6, 146, 195, 16, 68, - 234, 183, 3, 86, 79, 83, 7, 245, 234, 8, 2, 32, 87, 4, 202, 253, 8, 65, - 227, 191, 8, 72, 34, 218, 195, 8, 45, 70, 69, 78, 73, 168, 1, 3, 80, 69, - 69, 26, 81, 227, 2, 85, 26, 106, 82, 178, 200, 8, 72, 130, 226, 7, 79, + 32, 145, 210, 18, 7, 84, 72, 82, 79, 85, 71, 72, 6, 198, 190, 16, 68, + 234, 183, 3, 86, 79, 83, 7, 169, 230, 8, 2, 32, 87, 4, 254, 248, 8, 65, + 227, 191, 8, 72, 34, 142, 191, 8, 45, 70, 69, 78, 73, 168, 1, 3, 80, 69, + 69, 26, 81, 227, 2, 85, 26, 106, 82, 230, 195, 8, 72, 130, 226, 7, 79, 212, 134, 1, 8, 87, 79, 32, 84, 72, 73, 82, 68, 151, 198, 1, 65, 6, 40, - 4, 73, 65, 78, 71, 171, 203, 8, 65, 4, 140, 242, 4, 8, 76, 69, 32, 66, - 69, 83, 73, 68, 179, 191, 12, 85, 16, 206, 205, 8, 72, 202, 1, 73, 181, + 4, 73, 65, 78, 71, 223, 198, 8, 65, 4, 140, 242, 4, 8, 76, 69, 32, 66, + 69, 83, 73, 68, 231, 186, 12, 85, 16, 130, 201, 8, 72, 202, 1, 73, 181, 200, 10, 2, 82, 73, 62, 128, 1, 9, 80, 79, 73, 78, 84, 73, 78, 71, 32, - 138, 1, 83, 250, 205, 8, 70, 226, 2, 72, 153, 7, 7, 84, 79, 45, 82, 73, - 71, 72, 30, 86, 65, 130, 211, 8, 67, 94, 68, 58, 77, 58, 82, 182, 1, 83, - 74, 84, 211, 172, 8, 69, 6, 190, 211, 8, 78, 158, 175, 8, 84, 159, 2, 73, - 4, 44, 5, 73, 68, 69, 32, 65, 175, 214, 8, 72, 2, 205, 147, 1, 2, 82, 67, + 138, 1, 83, 174, 201, 8, 70, 226, 2, 72, 153, 7, 7, 84, 79, 45, 82, 73, + 71, 72, 30, 86, 65, 182, 206, 8, 67, 94, 68, 58, 77, 58, 82, 182, 1, 83, + 74, 84, 211, 172, 8, 69, 6, 242, 206, 8, 78, 158, 175, 8, 84, 159, 2, 73, + 4, 44, 5, 73, 68, 69, 32, 65, 227, 209, 8, 72, 2, 205, 147, 1, 2, 82, 67, 210, 1, 172, 1, 5, 65, 82, 82, 79, 87, 174, 5, 66, 70, 72, 242, 3, 84, - 178, 2, 87, 162, 214, 8, 68, 210, 1, 70, 170, 7, 76, 26, 79, 34, 80, 50, - 82, 70, 83, 242, 206, 8, 67, 47, 81, 73, 26, 32, 159, 236, 17, 45, 68, - 102, 65, 138, 1, 84, 132, 2, 5, 87, 73, 84, 72, 32, 242, 215, 8, 70, 217, - 165, 10, 4, 79, 86, 69, 82, 12, 44, 5, 66, 79, 86, 69, 32, 223, 217, 8, - 78, 10, 64, 4, 83, 72, 79, 82, 214, 216, 8, 82, 182, 230, 4, 65, 55, 84, - 2, 223, 255, 18, 84, 12, 56, 7, 72, 82, 79, 85, 71, 72, 32, 53, 3, 79, - 32, 66, 6, 226, 188, 13, 83, 238, 206, 4, 76, 211, 149, 2, 88, 6, 32, 2, - 65, 82, 231, 218, 8, 76, 5, 245, 168, 12, 23, 32, 79, 86, 69, 82, 32, 82, + 178, 2, 87, 214, 209, 8, 68, 210, 1, 70, 170, 7, 76, 26, 79, 34, 80, 50, + 82, 70, 83, 242, 206, 8, 67, 47, 81, 73, 26, 32, 211, 231, 17, 45, 68, + 102, 65, 138, 1, 84, 132, 2, 5, 87, 73, 84, 72, 32, 166, 211, 8, 70, 217, + 165, 10, 4, 79, 86, 69, 82, 12, 44, 5, 66, 79, 86, 69, 32, 147, 213, 8, + 78, 10, 64, 4, 83, 72, 79, 82, 138, 212, 8, 82, 182, 230, 4, 65, 55, 84, + 2, 147, 251, 18, 84, 12, 56, 7, 72, 82, 79, 85, 71, 72, 32, 53, 3, 79, + 32, 66, 6, 150, 184, 13, 83, 238, 206, 4, 76, 211, 149, 2, 88, 6, 32, 2, + 65, 82, 155, 214, 8, 76, 5, 169, 164, 12, 23, 32, 79, 86, 69, 82, 32, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 36, 118, - 76, 198, 218, 8, 68, 182, 1, 80, 30, 83, 38, 84, 138, 210, 8, 77, 38, 78, - 122, 69, 150, 153, 1, 72, 171, 165, 1, 86, 4, 162, 174, 17, 65, 171, 247, - 1, 79, 8, 234, 220, 8, 65, 172, 10, 5, 79, 84, 84, 79, 77, 219, 200, 8, - 76, 30, 26, 65, 131, 181, 17, 69, 26, 48, 6, 82, 80, 79, 79, 78, 32, 139, - 215, 19, 78, 24, 80, 10, 87, 73, 84, 72, 32, 66, 65, 82, 66, 32, 249, - 245, 9, 4, 79, 86, 69, 82, 22, 40, 4, 68, 79, 87, 78, 117, 2, 85, 80, 10, - 26, 32, 243, 186, 17, 87, 8, 234, 223, 8, 66, 188, 2, 7, 65, 66, 79, 86, - 69, 32, 82, 234, 208, 8, 70, 179, 5, 84, 12, 26, 32, 255, 185, 17, 87, - 10, 60, 6, 65, 66, 79, 86, 69, 32, 222, 177, 17, 70, 179, 5, 84, 6, 42, - 76, 213, 223, 8, 4, 82, 73, 71, 72, 4, 250, 221, 8, 69, 147, 223, 4, 79, - 54, 44, 2, 82, 73, 202, 227, 8, 79, 159, 5, 87, 34, 44, 5, 65, 78, 71, - 76, 69, 255, 231, 8, 80, 30, 56, 8, 45, 72, 69, 65, 68, 69, 68, 32, 251, - 191, 17, 32, 28, 52, 5, 65, 82, 82, 79, 87, 202, 184, 17, 68, 39, 80, 25, - 11, 32, 22, 192, 228, 8, 9, 79, 86, 69, 82, 32, 82, 73, 71, 72, 22, 87, - 135, 208, 8, 84, 6, 26, 72, 143, 234, 8, 65, 4, 45, 9, 73, 84, 69, 32, - 65, 82, 82, 79, 87, 5, 173, 189, 17, 2, 32, 87, 5, 243, 253, 18, 80, 148, + 76, 250, 213, 8, 68, 182, 1, 80, 30, 83, 38, 84, 138, 210, 8, 77, 38, 78, + 122, 69, 150, 153, 1, 72, 171, 165, 1, 86, 4, 214, 169, 17, 65, 171, 247, + 1, 79, 8, 158, 216, 8, 65, 172, 10, 5, 79, 84, 84, 79, 77, 219, 200, 8, + 76, 30, 26, 65, 183, 176, 17, 69, 26, 48, 6, 82, 80, 79, 79, 78, 32, 191, + 210, 19, 78, 24, 80, 10, 87, 73, 84, 72, 32, 66, 65, 82, 66, 32, 173, + 241, 9, 4, 79, 86, 69, 82, 22, 40, 4, 68, 79, 87, 78, 117, 2, 85, 80, 10, + 26, 32, 167, 182, 17, 87, 8, 158, 219, 8, 66, 188, 2, 7, 65, 66, 79, 86, + 69, 32, 82, 234, 208, 8, 70, 179, 5, 84, 12, 26, 32, 179, 181, 17, 87, + 10, 60, 6, 65, 66, 79, 86, 69, 32, 146, 173, 17, 70, 179, 5, 84, 6, 42, + 76, 137, 219, 8, 4, 82, 73, 71, 72, 4, 174, 217, 8, 69, 147, 223, 4, 79, + 54, 44, 2, 82, 73, 254, 222, 8, 79, 159, 5, 87, 34, 44, 5, 65, 78, 71, + 76, 69, 179, 227, 8, 80, 30, 56, 8, 45, 72, 69, 65, 68, 69, 68, 32, 175, + 187, 17, 32, 28, 52, 5, 65, 82, 82, 79, 87, 254, 179, 17, 68, 39, 80, 25, + 11, 32, 22, 244, 223, 8, 9, 79, 86, 69, 82, 32, 82, 73, 71, 72, 22, 87, + 135, 208, 8, 84, 6, 26, 72, 195, 229, 8, 65, 4, 45, 9, 73, 84, 69, 32, + 65, 82, 82, 79, 87, 5, 225, 184, 17, 2, 32, 87, 5, 167, 249, 18, 80, 148, 1, 252, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 124, 7, 76, 69, 84, 84, 69, 82, 32, 236, 1, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 198, 1, 83, 172, 1, 11, 86, 79, 87, 69, 76, - 32, 83, 73, 71, 78, 32, 251, 154, 18, 68, 18, 66, 75, 22, 78, 130, 148, - 20, 76, 2, 77, 2, 80, 2, 82, 3, 84, 5, 155, 195, 19, 65, 5, 189, 212, 12, - 4, 89, 73, 78, 45, 78, 194, 1, 75, 2, 80, 254, 153, 7, 68, 130, 236, 10, + 32, 83, 73, 71, 78, 32, 175, 150, 18, 68, 18, 66, 75, 22, 78, 182, 143, + 20, 76, 2, 77, 2, 80, 2, 82, 3, 84, 5, 207, 190, 19, 65, 5, 241, 207, 12, + 4, 89, 73, 78, 45, 78, 194, 1, 75, 2, 80, 178, 149, 7, 68, 130, 236, 10, 66, 2, 70, 2, 71, 2, 72, 2, 77, 138, 15, 78, 170, 181, 1, 84, 46, 67, 2, - 83, 138, 69, 74, 2, 76, 2, 82, 2, 86, 2, 87, 2, 89, 187, 2, 65, 6, 222, - 143, 20, 72, 2, 76, 187, 2, 65, 10, 82, 84, 40, 14, 78, 89, 69, 84, 32, + 83, 138, 69, 74, 2, 76, 2, 82, 2, 86, 2, 87, 2, 89, 187, 2, 65, 6, 146, + 139, 20, 72, 2, 76, 187, 2, 65, 10, 82, 84, 40, 14, 78, 89, 69, 84, 32, 84, 72, 89, 79, 79, 77, 32, 84, 65, 43, 67, 6, 38, 65, 21, 5, 83, 72, 79, - 79, 75, 2, 247, 253, 6, 45, 5, 17, 2, 32, 67, 2, 237, 150, 15, 3, 69, 82, + 79, 75, 2, 171, 249, 6, 45, 5, 17, 2, 32, 67, 2, 161, 146, 15, 3, 69, 82, 45, 8, 92, 4, 73, 71, 78, 32, 37, 15, 85, 66, 74, 79, 73, 78, 69, 68, 32, - 76, 69, 84, 84, 69, 82, 4, 202, 242, 15, 78, 231, 208, 2, 82, 4, 11, 32, - 4, 226, 140, 20, 82, 3, 89, 14, 130, 184, 16, 85, 206, 141, 1, 79, 250, + 76, 69, 84, 84, 69, 82, 4, 254, 237, 15, 78, 231, 208, 2, 82, 4, 11, 32, + 4, 150, 136, 20, 82, 3, 89, 14, 182, 179, 16, 85, 206, 141, 1, 79, 250, 198, 2, 65, 186, 2, 69, 3, 73, 52, 138, 1, 65, 128, 4, 11, 69, 81, 85, 65, 76, 32, 84, 79, 32, 79, 82, 200, 1, 2, 66, 85, 42, 67, 186, 1, 79, - 210, 2, 87, 207, 252, 18, 83, 16, 40, 5, 66, 79, 86, 69, 32, 171, 4, 78, + 210, 2, 87, 131, 248, 18, 83, 16, 40, 5, 66, 79, 86, 69, 32, 171, 4, 78, 12, 152, 1, 7, 71, 82, 69, 65, 84, 69, 82, 110, 83, 176, 1, 19, 68, 79, - 85, 66, 76, 69, 45, 76, 73, 78, 69, 32, 69, 81, 85, 65, 76, 32, 65, 167, - 228, 15, 76, 2, 181, 5, 23, 45, 84, 72, 65, 78, 32, 65, 66, 79, 86, 69, + 85, 66, 76, 69, 45, 76, 73, 78, 69, 32, 69, 81, 85, 65, 76, 32, 65, 219, + 223, 15, 76, 2, 181, 5, 23, 45, 84, 72, 65, 78, 32, 65, 66, 79, 86, 69, 32, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 69, 6, 152, 1, 7, 73, 77, 73, 76, 65, 82, 32, 93, 26, 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, 32, 65, 66, 79, 86, 69, 32, 71, 82, 69, 65, 84, 69, 82, 4, 18, 65, 59, - 79, 2, 25, 4, 66, 79, 86, 69, 2, 181, 243, 17, 2, 32, 71, 2, 227, 2, 82, + 79, 2, 25, 4, 66, 79, 86, 69, 2, 233, 238, 17, 2, 32, 71, 2, 227, 2, 82, 2, 145, 2, 6, 45, 84, 72, 65, 78, 32, 4, 17, 2, 68, 32, 4, 220, 3, 5, 78, - 79, 84, 32, 65, 221, 162, 13, 11, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, - 69, 4, 217, 132, 13, 5, 84, 32, 78, 79, 84, 4, 65, 14, 76, 79, 83, 69, + 79, 84, 32, 65, 145, 158, 13, 11, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, + 69, 4, 141, 128, 13, 5, 84, 32, 78, 79, 84, 4, 65, 14, 76, 79, 83, 69, 68, 32, 66, 89, 32, 67, 85, 82, 86, 69, 5, 11, 32, 2, 61, 13, 65, 66, 79, - 86, 69, 32, 83, 76, 65, 78, 84, 69, 68, 2, 17, 2, 32, 69, 2, 151, 245, - 14, 81, 18, 40, 2, 82, 32, 221, 230, 11, 2, 86, 69, 16, 114, 65, 48, 16, - 83, 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, 32, 84, 79, 194, 129, - 13, 69, 131, 237, 4, 71, 2, 237, 190, 9, 7, 80, 80, 82, 79, 88, 73, 77, - 9, 49, 10, 32, 87, 73, 84, 72, 32, 68, 79, 84, 32, 6, 26, 65, 243, 209, - 11, 73, 4, 25, 4, 66, 79, 86, 69, 5, 179, 176, 18, 32, 6, 25, 4, 73, 84, - 72, 32, 6, 66, 67, 40, 8, 81, 85, 69, 83, 84, 73, 79, 78, 247, 177, 19, - 68, 2, 201, 208, 11, 5, 73, 82, 67, 76, 69, 2, 17, 2, 32, 77, 2, 17, 2, - 65, 82, 2, 255, 132, 19, 75, 136, 11, 190, 1, 71, 186, 5, 77, 166, 7, 78, - 156, 65, 2, 80, 83, 20, 3, 83, 85, 32, 142, 221, 15, 82, 136, 35, 11, 86, + 86, 69, 32, 83, 76, 65, 78, 84, 69, 68, 2, 17, 2, 32, 69, 2, 203, 240, + 14, 81, 18, 40, 2, 82, 32, 145, 226, 11, 2, 86, 69, 16, 114, 65, 48, 16, + 83, 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, 32, 84, 79, 246, 252, + 12, 69, 131, 237, 4, 71, 2, 161, 186, 9, 7, 80, 80, 82, 79, 88, 73, 77, + 9, 49, 10, 32, 87, 73, 84, 72, 32, 68, 79, 84, 32, 6, 26, 65, 167, 205, + 11, 73, 4, 25, 4, 66, 79, 86, 69, 5, 231, 171, 18, 32, 6, 25, 4, 73, 84, + 72, 32, 6, 66, 67, 40, 8, 81, 85, 69, 83, 84, 73, 79, 78, 171, 173, 19, + 68, 2, 253, 203, 11, 5, 73, 82, 67, 76, 69, 2, 17, 2, 32, 77, 2, 17, 2, + 65, 82, 2, 179, 128, 19, 75, 136, 11, 190, 1, 71, 186, 5, 77, 166, 7, 78, + 156, 65, 2, 80, 83, 20, 3, 83, 85, 32, 194, 216, 15, 82, 136, 35, 11, 86, 82, 69, 32, 84, 79, 85, 82, 78, 79, 73, 214, 59, 79, 190, 221, 1, 90, - 191, 84, 66, 44, 26, 65, 57, 2, 72, 84, 2, 181, 174, 9, 9, 84, 85, 82, + 191, 84, 66, 44, 26, 65, 57, 2, 72, 84, 2, 233, 169, 9, 9, 84, 85, 82, 69, 32, 79, 80, 69, 78, 42, 38, 32, 137, 4, 4, 78, 73, 78, 71, 36, 146, - 1, 69, 38, 70, 126, 82, 40, 3, 76, 69, 70, 86, 83, 42, 84, 236, 204, 7, + 1, 69, 38, 70, 126, 82, 40, 3, 76, 69, 70, 86, 83, 42, 84, 160, 200, 7, 3, 66, 76, 85, 238, 170, 9, 87, 254, 41, 86, 226, 78, 71, 219, 69, 67, 2, - 141, 230, 17, 4, 73, 71, 72, 84, 8, 94, 73, 153, 180, 18, 17, 79, 85, 82, - 32, 80, 79, 73, 78, 84, 69, 68, 32, 66, 76, 65, 67, 75, 4, 161, 226, 17, - 2, 86, 69, 4, 36, 3, 73, 71, 72, 135, 157, 18, 65, 2, 245, 241, 1, 16, - 84, 32, 84, 79, 82, 84, 79, 73, 83, 69, 32, 83, 72, 69, 76, 76, 6, 194, - 129, 17, 72, 254, 97, 65, 43, 73, 4, 220, 174, 16, 2, 87, 69, 21, 3, 72, - 82, 69, 7, 29, 5, 32, 77, 79, 79, 68, 5, 219, 155, 8, 32, 138, 1, 80, 3, - 66, 85, 32, 201, 163, 8, 11, 73, 84, 69, 68, 32, 76, 73, 65, 66, 73, 76, + 193, 225, 17, 4, 73, 71, 72, 84, 8, 94, 73, 205, 175, 18, 17, 79, 85, 82, + 32, 80, 79, 73, 78, 84, 69, 68, 32, 66, 76, 65, 67, 75, 4, 213, 221, 17, + 2, 86, 69, 4, 36, 3, 73, 71, 72, 187, 152, 18, 65, 2, 245, 241, 1, 16, + 84, 32, 84, 79, 82, 84, 79, 73, 83, 69, 32, 83, 72, 69, 76, 76, 6, 246, + 252, 16, 72, 254, 97, 65, 43, 73, 4, 144, 170, 16, 2, 87, 69, 21, 3, 72, + 82, 69, 7, 29, 5, 32, 77, 79, 79, 68, 5, 143, 151, 8, 32, 138, 1, 80, 3, + 66, 85, 32, 253, 158, 8, 11, 73, 84, 69, 68, 32, 76, 73, 65, 66, 73, 76, 136, 1, 128, 1, 7, 76, 69, 84, 84, 69, 82, 32, 222, 1, 83, 200, 2, 5, 86, - 79, 87, 69, 76, 154, 217, 12, 69, 246, 198, 4, 81, 223, 96, 68, 60, 170, - 1, 71, 198, 145, 6, 84, 234, 231, 8, 89, 186, 136, 1, 78, 246, 173, 3, + 79, 87, 69, 76, 206, 212, 12, 69, 246, 198, 4, 81, 223, 96, 68, 60, 170, + 1, 71, 250, 140, 6, 84, 234, 231, 8, 89, 186, 136, 1, 78, 246, 173, 3, 83, 82, 66, 2, 67, 2, 68, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, - 2, 82, 3, 87, 6, 202, 171, 18, 89, 230, 201, 1, 72, 187, 2, 65, 32, 108, + 2, 82, 3, 87, 6, 254, 166, 18, 89, 230, 201, 1, 72, 187, 2, 65, 32, 108, 4, 73, 71, 78, 32, 128, 1, 12, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, - 82, 32, 245, 255, 6, 2, 85, 66, 8, 72, 3, 75, 69, 77, 0, 3, 77, 85, 75, - 32, 2, 83, 65, 231, 170, 17, 76, 2, 153, 175, 17, 3, 80, 72, 82, 2, 131, - 226, 19, 45, 18, 194, 255, 15, 78, 142, 177, 3, 65, 194, 66, 75, 2, 76, + 82, 32, 169, 251, 6, 2, 85, 66, 8, 72, 3, 75, 69, 77, 0, 3, 77, 85, 75, + 32, 2, 83, 65, 155, 166, 17, 76, 2, 205, 170, 17, 3, 80, 72, 82, 2, 183, + 221, 19, 45, 18, 246, 250, 15, 78, 142, 177, 3, 65, 194, 66, 75, 2, 76, 2, 77, 2, 80, 2, 82, 3, 84, 20, 84, 6, 32, 83, 73, 71, 78, 32, 149, 90, - 10, 45, 67, 65, 82, 82, 73, 69, 82, 32, 76, 18, 230, 216, 5, 65, 130, + 10, 45, 67, 65, 82, 82, 73, 69, 82, 32, 76, 18, 154, 212, 5, 65, 130, 210, 11, 79, 146, 137, 2, 69, 162, 64, 73, 3, 85, 226, 8, 22, 69, 187, 64, 75, 222, 8, 34, 32, 177, 3, 3, 65, 82, 32, 14, 120, 12, 73, 78, 84, - 69, 71, 82, 65, 84, 73, 79, 78, 32, 150, 167, 13, 70, 206, 153, 3, 83, + 69, 71, 82, 65, 84, 73, 79, 78, 32, 202, 162, 13, 70, 206, 153, 3, 83, 237, 147, 1, 4, 84, 65, 66, 85, 6, 108, 5, 87, 73, 84, 72, 32, 157, 1, 17, 78, 79, 84, 32, 73, 78, 67, 76, 85, 68, 73, 78, 71, 32, 84, 72, 69, 4, 76, 7, 82, 69, 67, 84, 65, 78, 71, 1, 8, 83, 69, 77, 73, 67, 73, 82, 67, 2, 73, 16, 85, 76, 65, 82, 32, 80, 65, 84, 72, 32, 65, 82, 79, 85, - 78, 68, 2, 17, 2, 32, 80, 2, 179, 201, 18, 79, 208, 8, 60, 8, 65, 32, 83, + 78, 68, 2, 17, 2, 32, 80, 2, 231, 196, 18, 79, 208, 8, 60, 8, 65, 32, 83, 73, 71, 78, 32, 65, 205, 24, 2, 66, 32, 170, 5, 122, 49, 86, 51, 202, 2, - 52, 214, 1, 53, 158, 4, 54, 142, 3, 55, 132, 4, 2, 56, 48, 78, 66, 185, - 159, 18, 3, 48, 50, 56, 6, 212, 198, 12, 5, 48, 48, 45, 49, 48, 200, 233, + 52, 214, 1, 53, 158, 4, 54, 142, 3, 55, 132, 4, 2, 56, 48, 78, 66, 237, + 154, 18, 3, 48, 50, 56, 6, 136, 194, 12, 5, 48, 48, 45, 49, 48, 200, 233, 5, 2, 50, 48, 233, 19, 2, 51, 49, 150, 1, 78, 48, 90, 49, 130, 1, 55, - 250, 172, 14, 50, 2, 51, 2, 52, 2, 53, 3, 54, 22, 178, 1, 57, 190, 235, - 19, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 24, 90, 51, 190, - 235, 19, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 6, - 186, 235, 19, 65, 2, 66, 3, 67, 4, 150, 235, 19, 48, 3, 49, 38, 18, 48, + 174, 168, 14, 50, 2, 51, 2, 52, 2, 53, 3, 54, 22, 178, 1, 57, 242, 230, + 19, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 24, 90, 51, 242, + 230, 19, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 6, + 238, 230, 19, 65, 2, 66, 3, 67, 4, 202, 230, 19, 48, 3, 49, 38, 18, 48, 91, 49, 20, 162, 1, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 74, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, - 55, 3, 56, 2, 237, 183, 6, 2, 45, 86, 160, 1, 102, 48, 78, 49, 62, 51, - 86, 52, 70, 53, 86, 54, 190, 11, 50, 194, 171, 2, 57, 174, 240, 11, 55, - 3, 56, 16, 186, 232, 19, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, - 57, 12, 238, 231, 19, 48, 2, 49, 2, 50, 2, 51, 2, 53, 3, 54, 18, 178, - 231, 19, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 14, - 222, 230, 19, 48, 2, 49, 2, 50, 2, 53, 2, 55, 2, 56, 3, 57, 18, 154, 230, - 19, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 12, 198, - 229, 19, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 104, 70, 48, 78, 50, 86, - 51, 38, 52, 78, 54, 150, 162, 14, 53, 131, 2, 49, 16, 194, 228, 19, 48, - 2, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 56, 3, 57, 18, 246, 227, 19, 48, 2, - 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 6, 162, 227, 19, 52, - 2, 55, 3, 56, 16, 254, 226, 19, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, - 56, 3, 57, 10, 178, 226, 19, 48, 2, 49, 2, 50, 2, 51, 3, 52, 44, 86, 48, - 134, 2, 49, 196, 129, 2, 2, 51, 50, 153, 204, 17, 6, 50, 54, 32, 69, 89, - 89, 26, 110, 57, 154, 225, 8, 55, 182, 6, 50, 62, 54, 254, 63, 52, 146, - 155, 3, 51, 114, 56, 186, 211, 2, 49, 155, 122, 53, 10, 26, 45, 207, 212, - 18, 32, 8, 96, 2, 50, 32, 156, 180, 12, 3, 54, 32, 76, 184, 2, 3, 52, 32, - 76, 137, 174, 3, 3, 51, 32, 76, 2, 247, 183, 12, 76, 14, 114, 51, 32, 3, - 52, 32, 65, 0, 2, 53, 32, 134, 65, 49, 174, 223, 3, 50, 198, 200, 4, 48, - 249, 249, 6, 2, 55, 32, 2, 11, 32, 2, 147, 153, 12, 79, 2, 151, 160, 18, - 66, 16, 250, 221, 19, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, + 55, 3, 56, 2, 161, 179, 6, 2, 45, 86, 160, 1, 102, 48, 78, 49, 62, 51, + 86, 52, 70, 53, 86, 54, 190, 11, 50, 194, 171, 2, 57, 226, 235, 11, 55, + 3, 56, 16, 238, 227, 19, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, + 57, 12, 162, 227, 19, 48, 2, 49, 2, 50, 2, 51, 2, 53, 3, 54, 18, 230, + 226, 19, 48, 2, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 14, + 146, 226, 19, 48, 2, 49, 2, 50, 2, 53, 2, 55, 2, 56, 3, 57, 18, 206, 225, + 19, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 12, 250, + 224, 19, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 104, 70, 48, 78, 50, 86, + 51, 38, 52, 78, 54, 202, 157, 14, 53, 131, 2, 49, 16, 246, 223, 19, 48, + 2, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 56, 3, 57, 18, 170, 223, 19, 48, 2, + 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 6, 214, 222, 19, 52, + 2, 55, 3, 56, 16, 178, 222, 19, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, + 56, 3, 57, 10, 230, 221, 19, 48, 2, 49, 2, 50, 2, 51, 3, 52, 44, 86, 48, + 134, 2, 49, 196, 129, 2, 2, 51, 50, 205, 199, 17, 6, 50, 54, 32, 69, 89, + 89, 26, 110, 57, 206, 220, 8, 55, 182, 6, 50, 62, 54, 254, 63, 52, 146, + 155, 3, 51, 114, 56, 186, 211, 2, 49, 155, 122, 53, 10, 26, 45, 131, 208, + 18, 32, 8, 96, 2, 50, 32, 208, 175, 12, 3, 54, 32, 76, 184, 2, 3, 52, 32, + 76, 137, 174, 3, 3, 51, 32, 76, 2, 171, 179, 12, 76, 14, 114, 51, 32, 3, + 52, 32, 65, 0, 2, 53, 32, 134, 65, 49, 174, 223, 3, 50, 250, 195, 4, 48, + 249, 249, 6, 2, 55, 32, 2, 11, 32, 2, 199, 148, 12, 79, 2, 203, 155, 18, + 66, 16, 174, 217, 19, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 162, 1, 22, 48, 155, 5, 49, 140, 1, 82, 49, 54, 50, 118, 51, 62, 52, - 78, 53, 86, 54, 62, 55, 70, 56, 155, 152, 14, 48, 10, 186, 220, 19, 48, - 2, 49, 2, 51, 2, 54, 3, 55, 28, 86, 49, 2, 50, 138, 82, 51, 170, 137, 19, - 48, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 7, 174, 219, 19, 70, 3, 77, 12, - 146, 219, 19, 48, 2, 49, 2, 52, 2, 55, 2, 56, 3, 57, 16, 214, 218, 19, - 48, 2, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 138, 218, 19, - 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 12, 182, 217, - 19, 48, 2, 49, 2, 53, 2, 54, 2, 55, 3, 57, 14, 250, 216, 19, 48, 2, 51, - 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 12, 182, 216, 19, 48, 2, 49, 2, 50, 2, - 53, 2, 54, 3, 55, 22, 82, 50, 36, 2, 51, 49, 30, 56, 186, 171, 12, 49, - 206, 2, 54, 146, 1, 55, 3, 57, 6, 166, 215, 19, 48, 2, 50, 3, 51, 4, 130, - 215, 19, 65, 3, 66, 4, 230, 214, 19, 48, 3, 56, 166, 3, 116, 9, 73, 68, + 78, 53, 86, 54, 62, 55, 70, 56, 207, 147, 14, 48, 10, 238, 215, 19, 48, + 2, 49, 2, 51, 2, 54, 3, 55, 28, 86, 49, 2, 50, 138, 82, 51, 222, 132, 19, + 48, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 7, 226, 214, 19, 70, 3, 77, 12, + 198, 214, 19, 48, 2, 49, 2, 52, 2, 55, 2, 56, 3, 57, 16, 138, 214, 19, + 48, 2, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 190, 213, 19, + 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 12, 234, 212, + 19, 48, 2, 49, 2, 53, 2, 54, 2, 55, 3, 57, 14, 174, 212, 19, 48, 2, 51, + 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 12, 234, 211, 19, 48, 2, 49, 2, 50, 2, + 53, 2, 54, 3, 55, 22, 82, 50, 36, 2, 51, 49, 30, 56, 238, 166, 12, 49, + 206, 2, 54, 146, 1, 55, 3, 57, 6, 218, 210, 19, 48, 2, 50, 3, 51, 4, 182, + 210, 19, 65, 3, 66, 4, 154, 210, 19, 48, 3, 56, 166, 3, 116, 9, 73, 68, 69, 79, 71, 82, 65, 77, 32, 220, 17, 10, 77, 79, 78, 79, 71, 82, 65, 77, 32, 66, 249, 1, 2, 83, 89, 234, 1, 54, 66, 253, 15, 8, 86, 69, 83, 83, 69, 76, 32, 66, 176, 1, 22, 49, 131, 11, 50, 126, 86, 48, 210, 3, 50, 166, 1, 51, 86, 52, 122, 53, 114, 54, 146, 1, 55, 118, 56, 71, 57, 28, - 114, 53, 98, 54, 58, 55, 78, 56, 62, 57, 156, 139, 7, 3, 50, 32, 87, 254, - 88, 48, 137, 175, 11, 4, 52, 32, 68, 69, 6, 132, 138, 7, 2, 32, 69, 220, + 114, 53, 98, 54, 58, 55, 78, 56, 62, 57, 208, 134, 7, 3, 50, 32, 87, 254, + 88, 48, 137, 175, 11, 4, 52, 32, 68, 69, 6, 184, 133, 7, 2, 32, 69, 220, 166, 11, 3, 70, 32, 77, 133, 82, 7, 77, 32, 83, 84, 65, 76, 76, 4, 168, - 245, 1, 3, 70, 32, 69, 133, 160, 16, 2, 77, 32, 4, 36, 3, 70, 32, 83, 1, - 2, 77, 32, 2, 129, 236, 11, 4, 72, 69, 45, 71, 4, 240, 159, 9, 3, 77, 32, - 66, 173, 149, 9, 3, 70, 32, 83, 4, 224, 198, 17, 4, 77, 32, 66, 85, 129, - 110, 3, 70, 32, 67, 10, 248, 152, 9, 4, 51, 32, 83, 80, 240, 10, 5, 49, + 245, 1, 3, 70, 32, 69, 185, 155, 16, 2, 77, 32, 4, 36, 3, 70, 32, 83, 1, + 2, 77, 32, 2, 181, 231, 11, 4, 72, 69, 45, 71, 4, 164, 155, 9, 3, 77, 32, + 66, 173, 149, 9, 3, 70, 32, 83, 4, 148, 194, 17, 4, 77, 32, 66, 85, 129, + 110, 3, 70, 32, 67, 10, 172, 148, 9, 4, 51, 32, 83, 80, 240, 10, 5, 49, 32, 66, 65, 82, 148, 240, 4, 4, 50, 32, 79, 76, 20, 6, 53, 32, 67, 89, - 80, 69, 129, 179, 4, 4, 48, 32, 87, 72, 6, 54, 49, 164, 239, 17, 3, 48, - 32, 79, 211, 223, 1, 50, 2, 181, 179, 18, 2, 32, 87, 10, 224, 5, 3, 53, - 32, 87, 252, 150, 9, 6, 48, 32, 66, 82, 79, 78, 172, 2, 4, 49, 32, 71, - 79, 206, 175, 10, 50, 3, 54, 16, 82, 57, 134, 238, 2, 49, 138, 223, 16, + 80, 69, 129, 179, 4, 4, 48, 32, 87, 72, 6, 54, 49, 216, 234, 17, 3, 48, + 32, 79, 211, 223, 1, 50, 2, 233, 174, 18, 2, 32, 87, 10, 224, 5, 3, 53, + 32, 87, 176, 146, 9, 6, 48, 32, 66, 82, 79, 78, 172, 2, 4, 49, 32, 71, + 79, 206, 175, 10, 50, 3, 54, 16, 82, 57, 134, 238, 2, 49, 190, 218, 16, 48, 2, 50, 2, 51, 2, 52, 2, 55, 3, 56, 2, 157, 102, 3, 32, 67, 76, 20, - 160, 177, 14, 5, 51, 32, 65, 82, 77, 152, 216, 4, 5, 50, 32, 71, 65, 82, - 182, 67, 48, 2, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 130, - 130, 14, 54, 216, 196, 3, 4, 51, 32, 77, 79, 134, 133, 2, 48, 2, 49, 2, - 50, 2, 52, 2, 55, 2, 56, 3, 57, 14, 234, 202, 19, 48, 2, 49, 2, 50, 2, - 51, 2, 52, 2, 53, 3, 57, 4, 204, 169, 2, 3, 49, 32, 72, 219, 160, 17, 48, + 212, 172, 14, 5, 51, 32, 65, 82, 77, 152, 216, 4, 5, 50, 32, 71, 65, 82, + 182, 67, 48, 2, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 182, + 253, 13, 54, 216, 196, 3, 4, 51, 32, 77, 79, 134, 133, 2, 48, 2, 49, 2, + 50, 2, 52, 2, 55, 2, 56, 3, 57, 14, 158, 198, 19, 48, 2, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 3, 57, 4, 204, 169, 2, 3, 49, 32, 72, 143, 156, 17, 48, 50, 42, 50, 110, 51, 130, 1, 52, 227, 1, 53, 4, 84, 8, 48, 32, 70, 79, - 79, 84, 83, 84, 245, 215, 6, 7, 53, 32, 66, 65, 84, 72, 84, 2, 231, 179, - 18, 79, 12, 104, 4, 51, 32, 83, 87, 132, 143, 14, 4, 48, 32, 83, 80, 154, - 156, 4, 49, 218, 156, 1, 50, 2, 52, 3, 54, 2, 131, 175, 18, 79, 16, 168, - 1, 9, 48, 32, 87, 72, 69, 69, 76, 69, 68, 2, 49, 34, 51, 180, 180, 17, + 79, 84, 83, 84, 169, 211, 6, 7, 53, 32, 66, 65, 84, 72, 84, 2, 155, 175, + 18, 79, 12, 104, 4, 51, 32, 83, 87, 184, 138, 14, 4, 48, 32, 83, 80, 154, + 156, 4, 49, 218, 156, 1, 50, 2, 52, 3, 54, 2, 183, 170, 18, 79, 16, 168, + 1, 9, 48, 32, 87, 72, 69, 69, 76, 69, 68, 2, 49, 34, 51, 232, 175, 17, 12, 50, 32, 67, 72, 65, 82, 73, 79, 84, 32, 70, 82, 226, 145, 2, 53, 2, - 54, 2, 56, 3, 57, 2, 145, 186, 18, 3, 32, 67, 72, 2, 195, 196, 6, 32, 18, - 224, 190, 18, 3, 52, 32, 68, 158, 135, 1, 49, 2, 50, 2, 51, 2, 53, 2, 54, - 2, 55, 2, 56, 3, 57, 58, 50, 50, 160, 155, 12, 2, 49, 53, 1, 2, 51, 48, - 54, 50, 50, 206, 157, 12, 53, 198, 232, 1, 48, 3, 49, 12, 174, 196, 19, + 54, 2, 56, 3, 57, 2, 197, 181, 18, 3, 32, 67, 72, 2, 247, 191, 6, 32, 18, + 148, 186, 18, 3, 52, 32, 68, 158, 135, 1, 49, 2, 50, 2, 51, 2, 53, 2, 54, + 2, 55, 2, 56, 3, 57, 58, 50, 50, 212, 150, 12, 2, 49, 53, 1, 2, 51, 48, + 54, 50, 50, 130, 153, 12, 53, 198, 232, 1, 48, 3, 49, 12, 226, 191, 19, 49, 2, 50, 2, 54, 2, 55, 2, 56, 3, 57, 12, 46, 49, 153, 12, 6, 50, 52, 55, 32, 68, 73, 10, 50, 50, 70, 51, 181, 11, 5, 53, 54, 32, 84, 85, 4, - 148, 180, 3, 3, 55, 32, 75, 237, 239, 15, 5, 56, 32, 75, 65, 78, 4, 56, - 3, 53, 32, 77, 233, 132, 16, 5, 51, 32, 65, 82, 69, 2, 195, 214, 12, 69, + 148, 180, 3, 3, 55, 32, 75, 161, 235, 15, 5, 56, 32, 75, 65, 78, 4, 56, + 3, 53, 32, 77, 157, 128, 16, 5, 51, 32, 65, 82, 69, 2, 247, 209, 12, 69, 176, 1, 84, 9, 76, 76, 65, 66, 76, 69, 32, 66, 48, 229, 12, 7, 77, 66, 79, 76, 32, 66, 48, 148, 1, 114, 48, 142, 1, 49, 162, 1, 50, 230, 1, 51, 174, 1, 52, 162, 1, 53, 154, 1, 54, 186, 1, 55, 198, 1, 56, 87, 57, 18, - 118, 54, 182, 203, 1, 55, 130, 8, 52, 190, 14, 57, 170, 252, 10, 53, 158, - 152, 2, 56, 198, 10, 49, 254, 2, 50, 207, 8, 51, 2, 151, 129, 18, 32, 16, + 118, 54, 182, 203, 1, 55, 130, 8, 52, 190, 14, 57, 222, 247, 10, 53, 158, + 152, 2, 56, 198, 10, 49, 254, 2, 50, 207, 8, 51, 2, 203, 252, 17, 32, 16, 122, 54, 18, 55, 202, 212, 1, 49, 134, 2, 50, 166, 26, 52, 176, 187, 1, - 2, 53, 32, 158, 247, 5, 48, 229, 128, 9, 2, 51, 32, 2, 171, 95, 32, 2, - 235, 143, 11, 32, 18, 166, 1, 51, 22, 54, 20, 3, 57, 32, 80, 224, 6, 2, - 53, 32, 168, 180, 3, 2, 48, 32, 232, 222, 14, 2, 55, 32, 140, 7, 2, 52, - 32, 162, 91, 56, 185, 44, 3, 49, 32, 81, 2, 247, 180, 14, 32, 2, 195, - 250, 14, 32, 2, 235, 148, 12, 85, 16, 134, 1, 48, 20, 2, 51, 32, 186, - 200, 1, 55, 234, 34, 54, 218, 241, 4, 57, 210, 165, 2, 56, 246, 171, 4, - 49, 205, 237, 5, 3, 50, 32, 81, 2, 183, 182, 14, 32, 2, 135, 1, 82, 16, + 2, 53, 32, 210, 242, 5, 48, 229, 128, 9, 2, 51, 32, 2, 171, 95, 32, 2, + 159, 139, 11, 32, 18, 166, 1, 51, 22, 54, 20, 3, 57, 32, 80, 224, 6, 2, + 53, 32, 168, 180, 3, 2, 48, 32, 156, 218, 14, 2, 55, 32, 140, 7, 2, 52, + 32, 162, 91, 56, 185, 44, 3, 49, 32, 81, 2, 171, 176, 14, 32, 2, 247, + 245, 14, 32, 2, 159, 144, 12, 85, 16, 134, 1, 48, 20, 2, 51, 32, 186, + 200, 1, 55, 234, 34, 54, 142, 237, 4, 57, 210, 165, 2, 56, 246, 171, 4, + 49, 205, 237, 5, 3, 50, 32, 81, 2, 235, 177, 14, 32, 2, 135, 1, 82, 16, 116, 2, 51, 32, 22, 53, 174, 196, 1, 48, 222, 1, 49, 242, 5, 50, 218, 10, - 52, 178, 5, 54, 133, 228, 12, 3, 56, 32, 78, 2, 151, 191, 15, 65, 2, 235, - 166, 17, 32, 18, 130, 1, 51, 222, 196, 1, 49, 150, 1, 56, 42, 57, 102, - 55, 194, 5, 48, 250, 141, 2, 52, 132, 181, 15, 2, 50, 32, 157, 4, 2, 53, - 32, 2, 251, 204, 12, 32, 16, 132, 1, 2, 50, 32, 20, 2, 56, 32, 204, 1, 3, - 54, 32, 84, 210, 191, 1, 55, 226, 3, 57, 146, 2, 53, 198, 248, 6, 49, - 243, 172, 10, 48, 2, 151, 238, 17, 80, 2, 213, 143, 12, 2, 82, 79, 18, + 52, 178, 5, 54, 185, 223, 12, 3, 56, 32, 78, 2, 203, 186, 15, 65, 2, 159, + 162, 17, 32, 18, 130, 1, 51, 222, 196, 1, 49, 150, 1, 56, 42, 57, 102, + 55, 194, 5, 48, 250, 141, 2, 52, 184, 176, 15, 2, 50, 32, 157, 4, 2, 53, + 32, 2, 175, 200, 12, 32, 16, 132, 1, 2, 50, 32, 20, 2, 56, 32, 204, 1, 3, + 54, 32, 84, 210, 191, 1, 55, 226, 3, 57, 146, 2, 53, 250, 243, 6, 49, + 243, 172, 10, 48, 2, 203, 233, 17, 80, 2, 137, 139, 12, 2, 82, 79, 18, 172, 1, 3, 54, 32, 82, 242, 191, 1, 55, 138, 8, 48, 170, 16, 53, 12, 3, - 49, 32, 68, 168, 171, 7, 2, 52, 32, 222, 252, 3, 50, 200, 158, 6, 3, 56, - 32, 81, 241, 2, 2, 51, 32, 2, 139, 142, 12, 65, 8, 238, 191, 1, 49, 168, - 24, 3, 55, 32, 84, 196, 250, 6, 2, 53, 32, 191, 156, 6, 48, 4, 150, 160, - 17, 49, 21, 3, 48, 32, 68, 28, 90, 52, 30, 54, 30, 56, 142, 136, 12, 53, - 158, 2, 49, 30, 51, 166, 1, 50, 171, 173, 3, 55, 4, 222, 179, 19, 55, 3, - 57, 4, 194, 179, 19, 51, 3, 52, 8, 166, 179, 19, 50, 2, 51, 2, 54, 3, 57, - 4, 228, 212, 10, 9, 69, 68, 32, 80, 65, 80, 69, 82, 67, 223, 200, 7, 32, - 5, 163, 128, 18, 84, 98, 96, 7, 76, 69, 84, 84, 69, 82, 32, 129, 240, 6, + 49, 32, 68, 220, 166, 7, 2, 52, 32, 222, 252, 3, 50, 200, 158, 6, 3, 56, + 32, 81, 241, 2, 2, 51, 32, 2, 191, 137, 12, 65, 8, 238, 191, 1, 49, 168, + 24, 3, 55, 32, 84, 248, 245, 6, 2, 53, 32, 191, 156, 6, 48, 4, 202, 155, + 17, 49, 21, 3, 48, 32, 68, 28, 90, 52, 30, 54, 30, 56, 194, 131, 12, 53, + 158, 2, 49, 30, 51, 166, 1, 50, 171, 173, 3, 55, 4, 146, 175, 19, 55, 3, + 57, 4, 246, 174, 19, 51, 3, 52, 8, 218, 174, 19, 50, 2, 51, 2, 54, 3, 57, + 4, 152, 208, 10, 9, 69, 68, 32, 80, 65, 80, 69, 82, 67, 223, 200, 7, 32, + 5, 215, 251, 17, 84, 98, 96, 7, 76, 69, 84, 84, 69, 82, 32, 181, 235, 6, 11, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 94, 238, 1, 84, 150, 246, - 2, 68, 182, 164, 10, 85, 130, 159, 2, 78, 138, 31, 69, 190, 143, 3, 67, + 2, 68, 234, 159, 10, 85, 130, 159, 2, 78, 138, 31, 69, 190, 143, 3, 67, 2, 71, 2, 72, 2, 75, 2, 80, 2, 83, 2, 89, 2, 90, 162, 7, 65, 2, 79, 234, 61, 66, 2, 70, 2, 74, 2, 76, 2, 77, 2, 87, 2, 88, 187, 2, 73, 20, 64, 4, - 79, 78, 69, 32, 202, 231, 18, 83, 138, 69, 72, 187, 2, 65, 12, 48, 4, 77, - 89, 65, 32, 141, 197, 1, 2, 78, 65, 10, 246, 193, 12, 74, 234, 205, 6, + 79, 78, 69, 32, 254, 226, 18, 83, 138, 69, 72, 187, 2, 65, 12, 48, 4, 77, + 89, 65, 32, 141, 197, 1, 2, 78, 65, 10, 170, 189, 12, 74, 234, 205, 6, 66, 158, 11, 84, 254, 16, 67, 39, 78, 210, 2, 232, 1, 2, 67, 75, 132, 1, 3, 71, 73, 67, 176, 6, 3, 78, 71, 32, 206, 9, 84, 116, 3, 86, 69, 32, 70, - 87, 172, 12, 5, 90, 69, 78, 71, 69, 174, 232, 7, 66, 240, 156, 10, 8, 85, + 87, 172, 12, 5, 90, 69, 78, 71, 69, 226, 227, 7, 66, 240, 156, 10, 8, 85, 68, 76, 89, 32, 67, 82, 89, 141, 15, 4, 76, 76, 73, 80, 9, 96, 10, 73, 78, 71, 45, 83, 72, 73, 70, 84, 32, 137, 25, 9, 32, 87, 73, 84, 72, 32, - 73, 78, 75, 4, 174, 185, 17, 90, 223, 86, 79, 40, 56, 6, 32, 71, 65, 84, + 73, 78, 75, 4, 226, 180, 17, 90, 223, 86, 79, 40, 56, 6, 32, 71, 65, 84, 69, 32, 137, 2, 3, 65, 76, 32, 12, 104, 6, 66, 85, 70, 70, 69, 82, 84, 9, - 73, 78, 86, 69, 82, 84, 69, 68, 32, 142, 153, 18, 65, 187, 87, 79, 5, + 73, 78, 86, 69, 82, 84, 69, 68, 32, 194, 148, 18, 65, 187, 87, 79, 5, 133, 1, 17, 32, 87, 73, 84, 72, 32, 73, 78, 86, 69, 82, 84, 69, 68, 32, - 73, 78, 4, 48, 3, 79, 85, 84, 205, 159, 6, 3, 73, 78, 80, 2, 155, 175, + 73, 78, 4, 48, 3, 79, 85, 84, 129, 155, 6, 3, 73, 78, 80, 2, 207, 170, 18, 80, 28, 36, 3, 65, 78, 68, 85, 2, 79, 82, 15, 33, 6, 32, 87, 73, 84, - 72, 32, 12, 226, 1, 68, 94, 72, 58, 77, 147, 182, 15, 85, 15, 11, 32, 12, + 72, 32, 12, 226, 1, 68, 94, 72, 58, 77, 199, 177, 15, 85, 15, 11, 32, 12, 88, 13, 79, 86, 69, 82, 76, 65, 80, 80, 73, 78, 71, 32, 76, 49, 5, 87, - 73, 84, 72, 32, 2, 209, 150, 18, 7, 79, 71, 73, 67, 65, 76, 32, 10, 26, - 68, 94, 72, 59, 77, 6, 11, 79, 6, 44, 5, 85, 66, 76, 69, 32, 235, 168, - 18, 84, 4, 230, 182, 15, 85, 143, 61, 79, 2, 209, 228, 15, 9, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 2, 173, 225, 7, 5, 73, 68, 68, 76, 69, 48, 70, + 73, 84, 72, 32, 2, 133, 146, 18, 7, 79, 71, 73, 67, 65, 76, 32, 10, 26, + 68, 94, 72, 59, 77, 6, 11, 79, 6, 44, 5, 85, 66, 76, 69, 32, 159, 164, + 18, 84, 4, 154, 178, 15, 85, 143, 61, 79, 2, 133, 224, 15, 9, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 2, 225, 220, 7, 5, 73, 68, 68, 76, 69, 48, 70, 68, 228, 1, 4, 76, 69, 70, 84, 241, 2, 5, 82, 73, 71, 72, 84, 6, 164, 1, 30, 65, 83, 72, 32, 70, 82, 79, 77, 32, 76, 69, 70, 84, 32, 77, 69, 77, - 66, 69, 82, 32, 79, 70, 32, 68, 79, 85, 66, 76, 69, 198, 165, 16, 73, - 151, 210, 1, 82, 2, 17, 2, 32, 86, 2, 137, 151, 18, 5, 69, 82, 84, 73, + 66, 69, 82, 32, 79, 70, 32, 68, 79, 85, 66, 76, 69, 250, 160, 16, 73, + 151, 210, 1, 82, 2, 17, 2, 32, 86, 2, 189, 146, 18, 5, 69, 82, 84, 73, 67, 20, 46, 32, 193, 1, 6, 87, 65, 82, 68, 83, 32, 8, 48, 6, 82, 73, 71, - 72, 84, 32, 139, 131, 16, 84, 6, 44, 5, 65, 82, 82, 79, 87, 203, 248, 15, - 68, 5, 193, 248, 13, 18, 32, 87, 73, 84, 72, 32, 68, 69, 80, 69, 78, 68, - 69, 78, 84, 32, 76, 79, 12, 214, 3, 68, 42, 65, 146, 1, 83, 229, 244, 8, + 72, 84, 32, 191, 254, 15, 84, 6, 44, 5, 65, 82, 82, 79, 87, 255, 243, 15, + 68, 5, 245, 243, 13, 18, 32, 87, 73, 84, 72, 32, 68, 69, 80, 69, 78, 68, + 69, 78, 84, 32, 76, 79, 12, 214, 3, 68, 42, 65, 146, 1, 83, 153, 240, 8, 19, 72, 65, 82, 80, 79, 79, 78, 32, 65, 66, 79, 86, 69, 32, 83, 72, 79, - 82, 84, 22, 48, 6, 87, 65, 82, 68, 83, 32, 235, 251, 8, 32, 20, 88, 5, + 82, 84, 22, 48, 6, 87, 65, 82, 68, 83, 32, 159, 247, 8, 32, 20, 88, 5, 65, 82, 82, 79, 87, 202, 1, 68, 96, 8, 72, 65, 82, 80, 79, 79, 78, 32, 91, 83, 11, 11, 32, 8, 164, 1, 7, 84, 72, 82, 79, 85, 71, 72, 132, 143, - 3, 10, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, 196, 232, 5, 9, 79, 86, - 69, 82, 32, 76, 79, 78, 71, 203, 188, 7, 70, 2, 203, 142, 18, 32, 4, 37, - 7, 79, 85, 66, 76, 69, 32, 65, 4, 25, 4, 82, 82, 79, 87, 5, 181, 179, 16, - 2, 32, 70, 4, 236, 246, 8, 4, 79, 86, 69, 82, 33, 11, 65, 66, 79, 86, 69, - 32, 83, 72, 79, 82, 84, 2, 233, 228, 7, 3, 81, 85, 73, 6, 92, 5, 73, 79, - 78, 32, 66, 144, 255, 17, 9, 32, 79, 70, 32, 70, 79, 82, 84, 85, 215, 93, - 85, 2, 211, 241, 9, 79, 4, 38, 76, 213, 132, 14, 3, 72, 79, 84, 2, 245, - 223, 17, 2, 69, 84, 222, 1, 34, 32, 229, 1, 3, 69, 82, 32, 14, 138, 1, - 66, 176, 201, 10, 11, 68, 79, 85, 66, 76, 69, 32, 80, 82, 73, 77, 214, + 3, 10, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, 248, 227, 5, 9, 79, 86, + 69, 82, 32, 76, 79, 78, 71, 203, 188, 7, 70, 2, 255, 137, 18, 32, 4, 37, + 7, 79, 85, 66, 76, 69, 32, 65, 4, 25, 4, 82, 82, 79, 87, 5, 233, 174, 16, + 2, 32, 70, 4, 160, 242, 8, 4, 79, 86, 69, 82, 33, 11, 65, 66, 79, 86, 69, + 32, 83, 72, 79, 82, 84, 2, 157, 224, 7, 3, 81, 85, 73, 6, 92, 5, 73, 79, + 78, 32, 66, 196, 250, 17, 9, 32, 79, 70, 32, 70, 79, 82, 84, 85, 215, 93, + 85, 2, 135, 237, 9, 79, 4, 38, 76, 137, 128, 14, 3, 72, 79, 84, 2, 169, + 219, 17, 2, 69, 84, 222, 1, 34, 32, 229, 1, 3, 69, 82, 32, 14, 138, 1, + 66, 228, 196, 10, 11, 68, 79, 85, 66, 76, 69, 32, 80, 82, 73, 77, 214, 183, 6, 65, 148, 113, 6, 75, 65, 86, 89, 75, 65, 227, 10, 76, 4, 38, 82, - 209, 249, 4, 3, 65, 84, 84, 2, 185, 130, 18, 7, 73, 71, 72, 84, 78, 69, + 133, 245, 4, 3, 65, 84, 84, 2, 237, 253, 17, 7, 73, 71, 72, 84, 78, 69, 83, 208, 1, 158, 1, 72, 140, 2, 5, 76, 69, 70, 84, 32, 236, 2, 6, 82, 73, - 71, 72, 84, 32, 154, 247, 15, 66, 74, 67, 74, 70, 234, 10, 77, 150, 2, - 79, 170, 18, 83, 67, 84, 20, 84, 4, 65, 76, 70, 32, 205, 186, 7, 11, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 32, 82, 18, 176, 166, 7, 9, 65, 78, 68, + 71, 72, 84, 32, 206, 242, 15, 66, 74, 67, 74, 70, 234, 10, 77, 150, 2, + 79, 170, 18, 83, 67, 84, 20, 84, 4, 65, 76, 70, 32, 129, 182, 7, 11, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 32, 82, 18, 228, 161, 7, 9, 65, 78, 68, 32, 85, 80, 80, 69, 82, 32, 7, 73, 78, 86, 69, 82, 83, 69, 150, 216, 8, 72, 230, 1, 86, 174, 26, 77, 130, 3, 76, 22, 82, 202, 5, 66, 247, 157, 1, 67, 72, 186, 1, 66, 60, 8, 70, 79, 85, 78, 84, 65, 73, 78, 22, 80, 56, 12, 83, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 82, 154, 1, 81, 246, 2, - 84, 232, 197, 11, 3, 67, 82, 65, 203, 187, 4, 79, 24, 56, 8, 65, 76, 76, - 80, 79, 73, 78, 84, 175, 135, 16, 76, 2, 179, 246, 9, 32, 4, 132, 131, - 15, 5, 65, 73, 78, 84, 66, 163, 141, 1, 69, 2, 185, 195, 7, 5, 32, 65, - 78, 84, 73, 74, 110, 81, 166, 2, 83, 82, 84, 202, 178, 7, 82, 158, 199, + 84, 156, 193, 11, 3, 67, 82, 65, 203, 187, 4, 79, 24, 56, 8, 65, 76, 76, + 80, 79, 73, 78, 84, 227, 130, 16, 76, 2, 231, 241, 9, 32, 4, 184, 254, + 14, 5, 65, 73, 78, 84, 66, 163, 141, 1, 69, 2, 237, 190, 7, 5, 32, 65, + 78, 84, 73, 74, 110, 81, 166, 2, 83, 82, 84, 254, 173, 7, 82, 158, 199, 8, 66, 238, 3, 67, 226, 3, 79, 222, 7, 68, 207, 2, 80, 30, 17, 2, 85, 65, - 30, 48, 6, 68, 82, 65, 78, 84, 32, 239, 146, 16, 82, 28, 74, 70, 60, 2, - 78, 69, 50, 83, 150, 142, 16, 67, 226, 1, 77, 143, 1, 84, 4, 26, 65, 231, - 198, 17, 82, 2, 149, 185, 7, 3, 67, 69, 32, 2, 25, 4, 85, 84, 82, 65, 2, - 195, 209, 18, 76, 4, 234, 224, 10, 77, 215, 175, 5, 84, 6, 240, 191, 7, - 11, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 82, 191, 209, 8, 72, 6, 150, - 146, 16, 82, 155, 1, 87, 5, 253, 230, 17, 25, 32, 68, 73, 86, 73, 68, 69, + 30, 48, 6, 68, 82, 65, 78, 84, 32, 163, 142, 16, 82, 28, 74, 70, 60, 2, + 78, 69, 50, 83, 202, 137, 16, 67, 226, 1, 77, 143, 1, 84, 4, 26, 65, 155, + 194, 17, 82, 2, 201, 180, 7, 3, 67, 69, 32, 2, 25, 4, 85, 84, 82, 65, 2, + 247, 204, 18, 76, 4, 158, 220, 10, 77, 215, 175, 5, 84, 6, 164, 187, 7, + 11, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 82, 191, 209, 8, 72, 6, 202, + 141, 16, 82, 155, 1, 87, 5, 177, 226, 17, 25, 32, 68, 73, 86, 73, 68, 69, 68, 32, 66, 89, 32, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 82, 85, - 6, 18, 71, 23, 78, 2, 143, 253, 13, 71, 4, 168, 231, 17, 5, 65, 82, 32, + 6, 18, 71, 23, 78, 2, 195, 248, 13, 71, 4, 220, 226, 17, 5, 65, 82, 32, 69, 67, 151, 103, 71, 114, 104, 12, 67, 73, 65, 78, 32, 76, 69, 84, 84, - 69, 82, 32, 232, 1, 5, 68, 73, 65, 78, 32, 131, 129, 18, 73, 58, 210, 1, - 77, 150, 138, 5, 75, 154, 214, 9, 84, 158, 24, 66, 246, 146, 2, 65, 2, + 69, 82, 32, 232, 1, 5, 68, 73, 65, 78, 32, 183, 252, 17, 73, 58, 210, 1, + 77, 202, 133, 5, 75, 154, 214, 9, 84, 158, 24, 66, 246, 146, 2, 65, 2, 69, 2, 78, 238, 253, 1, 68, 2, 71, 2, 72, 2, 73, 2, 74, 2, 76, 2, 80, 2, - 81, 2, 82, 2, 83, 2, 85, 2, 87, 2, 88, 3, 90, 5, 167, 137, 19, 77, 54, - 88, 7, 76, 69, 84, 84, 69, 82, 32, 153, 224, 14, 9, 84, 82, 73, 65, 78, - 71, 85, 76, 65, 52, 222, 159, 13, 84, 190, 215, 1, 76, 198, 135, 2, 83, + 81, 2, 82, 2, 83, 2, 85, 2, 87, 2, 88, 3, 90, 5, 219, 132, 19, 77, 54, + 88, 7, 76, 69, 84, 84, 69, 82, 32, 205, 219, 14, 9, 84, 82, 73, 65, 78, + 71, 85, 76, 65, 52, 146, 155, 13, 84, 190, 215, 1, 76, 198, 135, 2, 83, 238, 11, 65, 2, 69, 2, 78, 238, 253, 1, 66, 2, 67, 2, 68, 2, 70, 2, 71, 2, 73, 2, 75, 2, 77, 2, 79, 2, 81, 2, 82, 2, 85, 2, 86, 3, 89, 128, 54, 162, 1, 65, 194, 103, 69, 182, 103, 73, 154, 25, 79, 164, 112, 3, 82, 79, - 32, 234, 3, 85, 204, 70, 7, 89, 65, 78, 77, 65, 82, 32, 138, 165, 15, 86, + 32, 234, 3, 85, 204, 70, 7, 89, 65, 78, 77, 65, 82, 32, 190, 160, 15, 86, 198, 61, 77, 27, 87, 204, 23, 186, 1, 71, 62, 72, 254, 10, 75, 234, 3, 76, 252, 13, 2, 77, 77, 22, 78, 154, 17, 80, 118, 82, 174, 7, 83, 190, 7, - 84, 184, 36, 3, 89, 65, 78, 204, 129, 1, 3, 88, 73, 77, 175, 248, 15, 67, - 6, 228, 243, 17, 4, 73, 67, 32, 87, 138, 91, 78, 155, 53, 69, 166, 1, 84, + 84, 184, 36, 3, 89, 65, 78, 204, 129, 1, 3, 88, 73, 77, 227, 243, 15, 67, + 6, 152, 239, 17, 4, 73, 67, 32, 87, 138, 91, 78, 155, 53, 69, 166, 1, 84, 6, 65, 74, 65, 78, 73, 32, 129, 3, 10, 74, 79, 78, 71, 32, 84, 73, 76, - 69, 32, 78, 38, 76, 162, 2, 83, 215, 140, 13, 65, 72, 88, 6, 69, 84, 84, - 69, 82, 32, 161, 150, 12, 10, 73, 71, 65, 84, 85, 82, 69, 32, 83, 72, 70, - 134, 175, 3, 78, 150, 245, 11, 68, 82, 82, 34, 84, 162, 149, 3, 66, 2, + 69, 32, 78, 38, 76, 162, 2, 83, 139, 136, 13, 65, 72, 88, 6, 69, 84, 84, + 69, 82, 32, 213, 145, 12, 10, 73, 71, 65, 84, 85, 82, 69, 32, 83, 72, 70, + 134, 175, 3, 78, 202, 240, 11, 68, 82, 82, 34, 84, 162, 149, 3, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 83, 2, 86, - 186, 2, 65, 2, 69, 2, 73, 2, 79, 3, 85, 4, 170, 237, 6, 69, 253, 245, 7, + 186, 2, 65, 2, 69, 2, 73, 2, 79, 3, 85, 4, 222, 232, 6, 69, 253, 245, 7, 5, 73, 71, 78, 32, 78, 88, 236, 1, 2, 66, 65, 38, 69, 46, 70, 46, 78, 42, 79, 46, 80, 22, 83, 118, 84, 194, 1, 87, 112, 5, 71, 82, 69, 69, 78, 0, - 3, 82, 69, 68, 168, 136, 6, 3, 65, 85, 84, 222, 21, 74, 209, 175, 11, 11, - 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 4, 162, 158, 1, 77, 199, 220, + 3, 82, 69, 68, 220, 131, 6, 3, 65, 85, 84, 222, 21, 74, 209, 175, 11, 11, + 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 4, 162, 158, 1, 77, 251, 215, 17, 67, 8, 228, 2, 4, 73, 71, 72, 84, 195, 1, 65, 12, 172, 2, 2, 73, 86, 13, 3, 79, 85, 82, 8, 192, 1, 2, 79, 82, 65, 2, 73, 78, 8, 218, 1, 78, - 173, 229, 11, 3, 82, 67, 72, 2, 139, 209, 17, 76, 18, 88, 2, 79, 85, 76, - 4, 69, 86, 69, 78, 0, 2, 73, 88, 182, 157, 12, 85, 255, 199, 1, 80, 2, + 225, 224, 11, 3, 82, 67, 72, 2, 191, 204, 17, 76, 18, 88, 2, 79, 85, 76, + 4, 69, 86, 69, 78, 0, 2, 73, 88, 234, 152, 12, 85, 255, 199, 1, 80, 2, 157, 2, 2, 84, 72, 12, 36, 3, 72, 82, 69, 13, 2, 87, 79, 6, 11, 69, 6, - 25, 4, 32, 79, 70, 32, 6, 46, 67, 189, 248, 6, 5, 66, 65, 77, 66, 79, 4, - 184, 140, 6, 2, 73, 82, 153, 234, 10, 5, 72, 65, 82, 65, 67, 6, 50, 69, - 60, 4, 72, 73, 84, 69, 227, 190, 17, 73, 2, 17, 2, 83, 84, 2, 17, 2, 32, - 87, 2, 247, 232, 17, 73, 2, 17, 2, 32, 68, 2, 163, 190, 17, 82, 52, 52, - 5, 65, 83, 65, 82, 32, 241, 139, 15, 2, 69, 77, 50, 162, 1, 69, 40, 7, + 25, 4, 32, 79, 70, 32, 6, 46, 67, 241, 243, 6, 5, 66, 65, 77, 66, 79, 4, + 236, 135, 6, 2, 73, 82, 153, 234, 10, 5, 72, 65, 82, 65, 67, 6, 50, 69, + 60, 4, 72, 73, 84, 69, 151, 186, 17, 73, 2, 17, 2, 83, 84, 2, 17, 2, 32, + 87, 2, 171, 228, 17, 73, 2, 17, 2, 32, 68, 2, 215, 185, 17, 82, 52, 52, + 5, 65, 83, 65, 82, 32, 165, 135, 15, 2, 69, 77, 50, 162, 1, 69, 40, 7, 76, 69, 84, 84, 69, 82, 32, 152, 1, 5, 80, 65, 83, 83, 73, 32, 11, 86, - 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 173, 236, 18, 3, 65, 78, 71, 2, - 205, 244, 15, 5, 78, 68, 32, 79, 70, 36, 182, 249, 16, 78, 222, 250, 1, + 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 225, 231, 18, 3, 65, 78, 71, 2, + 129, 240, 15, 5, 78, 68, 32, 79, 70, 36, 234, 244, 16, 78, 222, 250, 1, 66, 2, 67, 2, 68, 2, 71, 2, 74, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, - 2, 84, 2, 86, 2, 89, 187, 2, 65, 2, 11, 77, 2, 211, 156, 18, 66, 8, 146, - 245, 18, 69, 2, 73, 2, 79, 3, 85, 246, 1, 80, 7, 65, 89, 65, 76, 65, 77, + 2, 84, 2, 86, 2, 89, 187, 2, 65, 2, 11, 77, 2, 135, 152, 18, 66, 8, 198, + 240, 18, 69, 2, 73, 2, 79, 3, 85, 246, 1, 80, 7, 65, 89, 65, 76, 65, 77, 32, 176, 11, 2, 69, 32, 225, 1, 3, 84, 69, 83, 236, 1, 198, 1, 68, 44, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 240, 1, 7, 76, 69, 84, 84, 69, 82, 32, 164, 5, 7, 78, 85, 77, 66, 69, 82, 32, 36, 5, 83, 73, 71, 78, 32, - 230, 191, 13, 86, 239, 201, 1, 65, 22, 164, 171, 8, 2, 65, 84, 163, 211, + 154, 187, 13, 86, 239, 201, 1, 65, 22, 216, 166, 8, 2, 65, 84, 163, 211, 8, 73, 26, 56, 4, 79, 78, 69, 32, 121, 6, 84, 72, 82, 69, 69, 32, 18, 82, - 84, 254, 135, 5, 83, 130, 132, 8, 70, 62, 79, 146, 222, 3, 69, 46, 72, - 47, 81, 4, 134, 143, 13, 87, 255, 220, 3, 69, 8, 150, 136, 5, 83, 198, + 84, 178, 131, 5, 83, 130, 132, 8, 70, 62, 79, 146, 222, 3, 69, 46, 72, + 47, 81, 4, 186, 138, 13, 87, 255, 220, 3, 69, 8, 202, 131, 5, 83, 198, 135, 8, 69, 110, 84, 179, 220, 3, 81, 132, 1, 226, 1, 65, 82, 67, 158, 1, - 68, 78, 84, 82, 86, 226, 141, 13, 78, 182, 128, 2, 76, 38, 82, 134, 6, + 68, 78, 84, 82, 86, 150, 137, 13, 78, 182, 128, 2, 76, 38, 82, 134, 6, 85, 206, 141, 1, 79, 238, 60, 73, 182, 196, 1, 83, 82, 66, 2, 71, 2, 74, - 2, 75, 2, 80, 162, 7, 69, 234, 61, 72, 2, 77, 3, 89, 11, 240, 167, 16, 7, + 2, 75, 2, 80, 162, 7, 69, 234, 61, 72, 2, 77, 3, 89, 11, 164, 163, 16, 7, 82, 67, 72, 65, 73, 67, 32, 206, 198, 2, 65, 2, 73, 3, 85, 22, 26, 72, - 215, 237, 18, 65, 20, 44, 5, 73, 76, 76, 85, 32, 167, 237, 18, 65, 18, - 138, 132, 13, 76, 174, 235, 3, 78, 146, 197, 1, 82, 222, 56, 75, 2, 77, - 3, 89, 10, 212, 226, 10, 4, 79, 84, 32, 82, 190, 194, 7, 68, 138, 69, 72, - 187, 2, 65, 10, 38, 84, 170, 233, 18, 72, 187, 2, 65, 6, 166, 233, 18, - 72, 2, 84, 187, 2, 65, 12, 242, 227, 3, 69, 234, 176, 11, 79, 223, 214, - 3, 65, 6, 162, 142, 13, 79, 223, 134, 4, 84, 18, 50, 67, 114, 86, 250, - 142, 15, 65, 251, 149, 3, 80, 6, 54, 79, 120, 5, 73, 82, 67, 85, 76, 171, - 203, 14, 65, 2, 145, 190, 13, 9, 77, 66, 73, 78, 73, 78, 71, 32, 65, 6, - 60, 9, 69, 82, 84, 73, 67, 65, 76, 32, 66, 255, 165, 18, 73, 2, 253, 142, + 139, 233, 18, 65, 20, 44, 5, 73, 76, 76, 85, 32, 219, 232, 18, 65, 18, + 190, 255, 12, 76, 174, 235, 3, 78, 146, 197, 1, 82, 222, 56, 75, 2, 77, + 3, 89, 10, 136, 222, 10, 4, 79, 84, 32, 82, 190, 194, 7, 68, 138, 69, 72, + 187, 2, 65, 10, 38, 84, 222, 228, 18, 72, 187, 2, 65, 6, 218, 228, 18, + 72, 2, 84, 187, 2, 65, 12, 242, 227, 3, 69, 158, 172, 11, 79, 223, 214, + 3, 65, 6, 214, 137, 13, 79, 223, 134, 4, 84, 18, 50, 67, 114, 86, 174, + 138, 15, 65, 251, 149, 3, 80, 6, 54, 79, 120, 5, 73, 82, 67, 85, 76, 223, + 198, 14, 65, 2, 197, 185, 13, 9, 77, 66, 73, 78, 73, 78, 71, 32, 65, 6, + 60, 9, 69, 82, 84, 73, 67, 65, 76, 32, 66, 179, 161, 18, 73, 2, 177, 138, 15, 2, 65, 82, 8, 80, 12, 87, 73, 84, 72, 32, 83, 84, 82, 79, 75, 69, 32, - 70, 65, 227, 224, 17, 83, 4, 64, 10, 65, 78, 68, 32, 77, 65, 76, 69, 32, - 65, 227, 224, 17, 83, 2, 25, 4, 78, 68, 32, 70, 2, 11, 69, 2, 11, 77, 2, - 139, 211, 7, 65, 2, 191, 163, 17, 69, 2, 243, 225, 16, 79, 185, 1, 210, + 70, 65, 151, 220, 17, 83, 4, 64, 10, 65, 78, 68, 32, 77, 65, 76, 69, 32, + 65, 151, 220, 17, 83, 2, 25, 4, 78, 68, 32, 70, 2, 11, 69, 2, 11, 77, 2, + 191, 206, 7, 65, 2, 243, 158, 17, 69, 2, 167, 221, 16, 79, 185, 1, 210, 1, 32, 220, 2, 5, 68, 65, 73, 67, 32, 224, 3, 8, 73, 67, 72, 65, 69, 65, - 78, 32, 222, 8, 83, 156, 166, 2, 3, 85, 65, 76, 130, 228, 10, 65, 240, + 78, 32, 222, 8, 83, 156, 166, 2, 3, 85, 65, 76, 182, 223, 10, 65, 240, 167, 1, 8, 84, 69, 76, 80, 73, 69, 67, 69, 235, 132, 4, 71, 12, 132, 1, 3, 73, 78, 32, 128, 1, 5, 87, 73, 84, 72, 32, 136, 147, 2, 3, 68, 65, 78, - 237, 140, 13, 8, 65, 78, 68, 32, 87, 79, 77, 65, 4, 248, 140, 10, 19, 66, + 161, 136, 13, 8, 65, 78, 68, 32, 87, 79, 77, 65, 4, 172, 136, 10, 19, 66, 85, 83, 73, 78, 69, 83, 83, 32, 83, 85, 73, 84, 32, 76, 69, 86, 73, 84, - 189, 151, 1, 4, 84, 85, 88, 69, 4, 140, 243, 13, 8, 71, 85, 65, 32, 80, + 189, 151, 1, 4, 84, 85, 88, 69, 4, 192, 238, 13, 8, 71, 85, 65, 32, 80, 73, 32, 77, 205, 163, 3, 4, 84, 85, 82, 66, 58, 112, 4, 65, 70, 70, 82, - 28, 7, 76, 69, 84, 84, 69, 82, 32, 208, 184, 14, 3, 86, 79, 67, 226, 72, - 71, 251, 25, 80, 2, 249, 247, 17, 2, 73, 67, 50, 82, 65, 176, 1, 2, 68, - 85, 2, 85, 28, 3, 72, 65, 76, 22, 73, 183, 152, 18, 75, 38, 154, 1, 75, - 206, 246, 12, 84, 250, 191, 1, 83, 130, 217, 3, 73, 226, 79, 66, 2, 68, - 2, 71, 2, 72, 2, 76, 2, 77, 2, 78, 2, 80, 2, 81, 2, 82, 3, 90, 5, 235, - 220, 18, 83, 2, 185, 132, 8, 2, 83, 72, 2, 187, 220, 18, 81, 4, 222, 222, + 28, 7, 76, 69, 84, 84, 69, 82, 32, 132, 180, 14, 3, 86, 79, 67, 226, 72, + 71, 251, 25, 80, 2, 173, 243, 17, 2, 73, 67, 50, 82, 65, 176, 1, 2, 68, + 85, 2, 85, 28, 3, 72, 65, 76, 22, 73, 235, 147, 18, 75, 38, 154, 1, 75, + 130, 242, 12, 84, 250, 191, 1, 83, 130, 217, 3, 73, 226, 79, 66, 2, 68, + 2, 71, 2, 72, 2, 76, 2, 77, 2, 78, 2, 80, 2, 81, 2, 82, 3, 90, 5, 159, + 216, 18, 83, 2, 237, 255, 7, 2, 83, 72, 2, 239, 215, 18, 81, 4, 146, 218, 18, 78, 3, 84, 102, 216, 1, 7, 76, 69, 84, 84, 69, 82, 32, 194, 4, 78, 80, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 220, 1, 4, 83, - 73, 71, 78, 249, 200, 10, 16, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, + 73, 71, 78, 173, 196, 10, 16, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 78, 32, 77, 65, 82, 72, 218, 1, 65, 46, 66, 38, 68, 30, 71, 30, 74, 2, - 90, 30, 75, 30, 81, 38, 83, 50, 84, 54, 88, 158, 164, 6, 76, 134, 206, 1, + 90, 30, 75, 30, 81, 38, 83, 50, 84, 54, 88, 210, 159, 6, 76, 134, 206, 1, 82, 246, 221, 2, 89, 198, 207, 1, 72, 190, 184, 5, 78, 134, 2, 87, 218, - 103, 70, 2, 80, 171, 4, 77, 6, 142, 209, 10, 76, 122, 65, 179, 137, 7, - 89, 4, 134, 249, 12, 72, 227, 220, 3, 69, 4, 254, 165, 6, 65, 23, 72, 4, - 182, 208, 10, 72, 15, 73, 4, 242, 208, 10, 72, 15, 65, 4, 226, 166, 12, - 72, 15, 65, 4, 210, 165, 6, 72, 131, 129, 6, 79, 8, 186, 205, 10, 83, - 154, 3, 65, 131, 137, 7, 72, 6, 206, 164, 6, 72, 178, 175, 10, 69, 219, - 134, 1, 65, 4, 202, 165, 12, 65, 3, 79, 10, 33, 6, 85, 77, 66, 69, 82, - 32, 10, 250, 207, 10, 79, 58, 84, 131, 203, 2, 70, 14, 80, 2, 68, 79, - 116, 3, 76, 73, 78, 190, 167, 5, 70, 230, 219, 11, 84, 167, 10, 83, 6, + 103, 70, 2, 80, 171, 4, 77, 6, 194, 204, 10, 76, 122, 65, 179, 137, 7, + 89, 4, 186, 244, 12, 72, 227, 220, 3, 69, 4, 178, 161, 6, 65, 23, 72, 4, + 234, 203, 10, 72, 15, 73, 4, 166, 204, 10, 72, 15, 65, 4, 150, 162, 12, + 72, 15, 65, 4, 134, 161, 6, 72, 131, 129, 6, 79, 8, 238, 200, 10, 83, + 154, 3, 65, 131, 137, 7, 72, 6, 130, 160, 6, 72, 178, 175, 10, 69, 219, + 134, 1, 65, 4, 254, 160, 12, 65, 3, 79, 10, 33, 6, 85, 77, 66, 69, 82, + 32, 10, 174, 203, 10, 79, 58, 84, 131, 203, 2, 70, 14, 80, 2, 68, 79, + 116, 3, 76, 73, 78, 242, 162, 5, 70, 230, 219, 11, 84, 167, 10, 83, 6, 54, 84, 13, 9, 85, 66, 76, 69, 32, 68, 79, 84, 32, 5, 11, 32, 2, 25, 4, - 87, 73, 84, 72, 2, 151, 193, 2, 73, 2, 231, 203, 3, 69, 2, 139, 168, 17, - 32, 2, 11, 32, 2, 249, 190, 18, 2, 83, 72, 4, 92, 17, 32, 83, 89, 77, 66, - 79, 76, 32, 70, 79, 82, 32, 76, 73, 71, 72, 84, 139, 220, 10, 76, 2, 179, - 140, 15, 72, 142, 1, 142, 1, 65, 20, 5, 67, 72, 69, 78, 32, 216, 164, 6, + 87, 73, 84, 72, 2, 151, 193, 2, 73, 2, 231, 203, 3, 69, 2, 191, 163, 17, + 32, 2, 11, 32, 2, 173, 186, 18, 2, 83, 72, 4, 92, 17, 32, 83, 89, 77, 66, + 79, 76, 32, 70, 79, 82, 32, 76, 73, 71, 72, 84, 191, 215, 10, 76, 2, 231, + 135, 15, 72, 142, 1, 142, 1, 65, 20, 5, 67, 72, 69, 78, 32, 140, 160, 6, 4, 82, 73, 65, 71, 249, 175, 11, 13, 84, 73, 65, 76, 32, 65, 82, 84, 83, - 32, 85, 78, 73, 2, 227, 161, 5, 67, 136, 1, 152, 1, 7, 76, 69, 84, 84, + 32, 85, 78, 73, 2, 151, 157, 5, 67, 136, 1, 152, 1, 7, 76, 69, 84, 84, 69, 82, 32, 194, 1, 83, 236, 2, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, - 78, 32, 170, 129, 18, 72, 225, 5, 4, 77, 65, 82, 75, 60, 254, 3, 84, 206, - 148, 2, 68, 166, 188, 14, 78, 214, 181, 1, 67, 2, 75, 2, 80, 2, 83, 2, + 78, 32, 222, 252, 17, 72, 225, 5, 4, 77, 65, 82, 75, 60, 254, 3, 84, 206, + 148, 2, 68, 218, 183, 14, 78, 214, 181, 1, 67, 2, 75, 2, 80, 2, 83, 2, 90, 138, 69, 45, 2, 66, 2, 71, 2, 72, 2, 74, 2, 76, 2, 77, 2, 82, 2, 87, 2, 89, 187, 2, 65, 62, 96, 4, 73, 71, 78, 32, 37, 16, 85, 66, 74, 79, 73, - 78, 69, 68, 32, 76, 69, 84, 84, 69, 82, 32, 4, 254, 177, 14, 67, 235, - 216, 3, 65, 58, 182, 1, 84, 206, 148, 2, 68, 166, 188, 14, 78, 214, 181, + 78, 69, 68, 32, 76, 69, 84, 84, 69, 82, 32, 4, 178, 173, 14, 67, 235, + 216, 3, 65, 58, 182, 1, 84, 206, 148, 2, 68, 218, 183, 14, 78, 214, 181, 1, 67, 2, 75, 2, 80, 2, 83, 2, 90, 138, 69, 66, 2, 71, 2, 72, 2, 74, 2, - 76, 2, 77, 2, 82, 2, 87, 2, 89, 187, 2, 65, 8, 194, 134, 18, 83, 138, 69, - 72, 187, 2, 65, 10, 158, 203, 18, 65, 186, 2, 69, 2, 73, 2, 79, 3, 85, + 76, 2, 77, 2, 82, 2, 87, 2, 89, 187, 2, 65, 8, 246, 129, 18, 83, 138, 69, + 72, 187, 2, 65, 10, 210, 198, 18, 65, 186, 2, 69, 2, 73, 2, 79, 3, 85, 156, 1, 120, 11, 65, 82, 65, 77, 32, 71, 79, 78, 68, 73, 32, 232, 5, 3, - 67, 85, 76, 64, 5, 75, 32, 87, 79, 82, 183, 132, 18, 85, 150, 1, 100, 7, + 67, 85, 76, 64, 5, 75, 32, 87, 79, 82, 235, 255, 17, 85, 150, 1, 100, 7, 76, 69, 84, 84, 69, 82, 32, 178, 2, 82, 56, 5, 83, 73, 71, 78, 32, 82, - 86, 247, 211, 16, 68, 94, 210, 1, 74, 42, 84, 198, 235, 14, 65, 38, 68, + 86, 171, 207, 16, 68, 94, 210, 1, 74, 42, 84, 250, 230, 14, 65, 38, 68, 214, 6, 85, 186, 202, 1, 73, 42, 76, 190, 195, 1, 75, 38, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 80, 138, 69, 72, 2, 77, 2, 82, 2, 86, 2, 89, 186, 2, - 69, 3, 79, 6, 130, 199, 18, 78, 38, 72, 187, 2, 65, 10, 246, 129, 18, 84, - 138, 69, 72, 2, 82, 187, 2, 65, 4, 32, 2, 65, 45, 219, 236, 14, 69, 2, - 147, 132, 18, 75, 10, 230, 176, 1, 67, 182, 207, 12, 72, 178, 43, 78, - 150, 227, 1, 86, 247, 244, 1, 65, 22, 26, 79, 199, 139, 16, 73, 20, 45, - 9, 87, 69, 76, 32, 83, 73, 71, 78, 32, 20, 74, 86, 198, 239, 14, 65, 38, - 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 2, 141, 203, 7, 6, 79, 67, - 65, 76, 73, 67, 2, 145, 141, 18, 11, 73, 78, 69, 32, 79, 82, 68, 73, 78, - 65, 76, 2, 179, 176, 17, 75, 226, 15, 76, 10, 72, 69, 77, 65, 84, 73, 67, - 65, 76, 32, 153, 224, 14, 3, 69, 32, 68, 224, 15, 252, 1, 5, 66, 79, 76, + 69, 3, 79, 6, 182, 194, 18, 78, 38, 72, 187, 2, 65, 10, 170, 253, 17, 84, + 138, 69, 72, 2, 82, 187, 2, 65, 4, 32, 2, 65, 45, 143, 232, 14, 69, 2, + 199, 255, 17, 75, 10, 230, 176, 1, 67, 234, 202, 12, 72, 178, 43, 78, + 150, 227, 1, 86, 247, 244, 1, 65, 22, 26, 79, 251, 134, 16, 73, 20, 45, + 9, 87, 69, 76, 32, 83, 73, 71, 78, 32, 20, 74, 86, 250, 234, 14, 65, 38, + 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 2, 193, 198, 7, 6, 79, 67, + 65, 76, 73, 67, 2, 197, 136, 18, 11, 73, 78, 69, 32, 79, 82, 68, 73, 78, + 65, 76, 2, 231, 171, 17, 75, 226, 15, 76, 10, 72, 69, 77, 65, 84, 73, 67, + 65, 76, 32, 205, 219, 14, 3, 69, 32, 68, 224, 15, 252, 1, 5, 66, 79, 76, 68, 32, 168, 6, 14, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 75, 32, 238, 1, 70, 164, 2, 7, 73, 84, 65, 76, 73, 67, 32, 180, 3, 10, 77, 79, 78, 79, 83, 80, 65, 67, 69, 32, 40, 2, 82, 73, 36, 3, 76, 69, 70, 167, 1, 83, 160, 5, 176, 1, 8, 67, 65, 80, 73, 84, 65, 76, 32, 130, 2, 83, 210, 14, 73, 210, 3, 69, 38, 75, 38, 78, 30, 80, 98, 82, 242, 5, 84, - 56, 7, 70, 82, 65, 75, 84, 85, 82, 195, 177, 16, 68, 104, 190, 4, 68, + 56, 7, 70, 82, 65, 75, 84, 85, 82, 247, 172, 16, 68, 104, 190, 4, 68, 174, 15, 84, 174, 4, 65, 22, 66, 2, 90, 42, 69, 98, 71, 22, 73, 22, 75, - 34, 76, 22, 79, 50, 80, 42, 82, 22, 83, 70, 85, 214, 197, 1, 67, 198, - 137, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 70, 2, 72, 2, 74, 2, + 34, 76, 22, 79, 50, 80, 42, 82, 22, 83, 70, 85, 214, 197, 1, 67, 250, + 132, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 70, 2, 72, 2, 74, 2, 81, 2, 86, 2, 87, 3, 89, 208, 1, 60, 5, 77, 65, 76, 76, 32, 201, 25, 5, 67, 82, 73, 80, 84, 104, 250, 1, 68, 218, 19, 65, 22, 66, 2, 90, 42, 69, 38, 70, 62, 71, 22, 73, 22, 75, 34, 76, 22, 79, 50, 80, 42, 82, 22, 83, - 34, 84, 38, 85, 214, 197, 1, 67, 198, 137, 13, 77, 2, 78, 186, 202, 1, - 88, 198, 140, 2, 72, 2, 74, 2, 81, 2, 86, 2, 87, 3, 89, 7, 26, 73, 151, - 128, 15, 69, 2, 247, 213, 1, 71, 110, 68, 8, 67, 65, 80, 73, 84, 65, 76, - 32, 150, 23, 83, 131, 177, 16, 68, 38, 154, 188, 18, 65, 2, 66, 2, 68, 2, + 34, 84, 38, 85, 214, 197, 1, 67, 250, 132, 13, 77, 2, 78, 186, 202, 1, + 88, 198, 140, 2, 72, 2, 74, 2, 81, 2, 86, 2, 87, 3, 89, 7, 26, 73, 203, + 251, 14, 69, 2, 247, 213, 1, 71, 110, 68, 8, 67, 65, 80, 73, 84, 65, 76, + 32, 150, 23, 83, 183, 172, 16, 68, 38, 206, 183, 18, 65, 2, 66, 2, 68, 2, 69, 2, 70, 2, 71, 2, 73, 2, 74, 2, 75, 2, 76, 2, 77, 2, 79, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 3, 89, 96, 52, 7, 82, 65, 75, 84, 85, 82, 32, - 255, 143, 7, 65, 94, 52, 8, 67, 65, 80, 73, 84, 65, 76, 32, 131, 21, 83, - 42, 134, 186, 18, 65, 2, 66, 2, 68, 2, 69, 2, 70, 2, 71, 2, 74, 2, 75, 2, + 179, 139, 7, 65, 94, 52, 8, 67, 65, 80, 73, 84, 65, 76, 32, 131, 21, 83, + 42, 186, 181, 18, 65, 2, 66, 2, 68, 2, 69, 2, 70, 2, 71, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, 79, 2, 80, 2, 81, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 3, 89, 222, 1, 100, 6, 83, 77, 65, 76, 76, 32, 222, 7, 67, 218, 2, 69, 38, 75, 38, 78, 30, 80, 98, 82, 243, 5, 84, 104, 242, 1, 68, 186, 12, 65, 22, 66, 2, 90, 42, 69, 38, 70, 62, 71, 22, 73, 22, 75, 34, 76, 22, - 79, 50, 80, 42, 82, 22, 83, 34, 84, 38, 85, 214, 197, 1, 67, 198, 137, + 79, 50, 80, 42, 82, 22, 83, 34, 84, 38, 85, 214, 197, 1, 67, 250, 132, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 74, 2, 81, 2, 86, 2, 87, 3, - 89, 9, 52, 7, 79, 84, 76, 69, 83, 83, 32, 219, 248, 14, 69, 4, 186, 181, - 18, 73, 3, 74, 124, 246, 15, 67, 34, 83, 131, 177, 16, 68, 12, 32, 2, 71, - 72, 167, 138, 7, 83, 10, 17, 2, 84, 32, 10, 112, 6, 87, 72, 73, 84, 69, - 32, 142, 245, 5, 68, 222, 107, 65, 153, 235, 4, 9, 70, 76, 65, 84, 84, - 69, 78, 69, 68, 4, 174, 180, 14, 83, 39, 84, 130, 6, 84, 10, 65, 78, 83, + 89, 9, 52, 7, 79, 84, 76, 69, 83, 83, 32, 143, 244, 14, 69, 4, 238, 176, + 18, 73, 3, 74, 124, 246, 15, 67, 34, 83, 183, 172, 16, 68, 12, 32, 2, 71, + 72, 219, 133, 7, 83, 10, 17, 2, 84, 32, 10, 112, 6, 87, 72, 73, 84, 69, + 32, 194, 240, 5, 68, 222, 107, 65, 153, 235, 4, 9, 70, 76, 65, 84, 84, + 69, 78, 69, 68, 4, 226, 175, 14, 83, 39, 84, 130, 6, 84, 10, 65, 78, 83, 45, 83, 69, 82, 73, 70, 32, 249, 13, 6, 67, 82, 73, 80, 84, 32, 176, 5, 96, 5, 66, 79, 76, 68, 32, 164, 12, 6, 73, 84, 65, 76, 73, 67, 34, 67, - 34, 83, 131, 177, 16, 68, 204, 3, 98, 73, 122, 67, 218, 2, 69, 38, 75, - 38, 78, 30, 80, 98, 82, 30, 83, 214, 5, 84, 251, 177, 16, 68, 220, 1, 33, + 34, 83, 183, 172, 16, 68, 204, 3, 98, 73, 122, 67, 218, 2, 69, 38, 75, + 38, 78, 30, 80, 98, 82, 30, 83, 214, 5, 84, 175, 173, 16, 68, 220, 1, 33, 6, 84, 65, 76, 73, 67, 32, 220, 1, 74, 67, 218, 2, 69, 38, 75, 38, 78, 30, 80, 98, 82, 30, 83, 215, 5, 84, 102, 37, 7, 65, 80, 73, 84, 65, 76, 32, 102, 250, 1, 84, 174, 4, 65, 22, 66, 2, 90, 22, 68, 22, 69, 98, 71, 22, 73, 22, 75, 34, 76, 22, 79, 50, 80, 42, 82, 22, 83, 70, 85, 214, 197, - 1, 67, 198, 137, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 70, 2, 72, - 2, 74, 2, 81, 2, 86, 2, 87, 3, 89, 9, 232, 159, 11, 4, 72, 69, 84, 65, - 151, 233, 6, 65, 2, 249, 178, 16, 4, 80, 83, 73, 76, 2, 17, 2, 65, 80, 2, - 159, 7, 80, 2, 209, 138, 18, 2, 65, 66, 6, 74, 72, 148, 150, 5, 8, 65, - 82, 84, 73, 65, 76, 32, 68, 175, 128, 12, 73, 2, 191, 150, 17, 73, 2, - 169, 150, 17, 2, 72, 79, 102, 29, 5, 77, 65, 76, 76, 32, 102, 246, 1, 65, + 1, 67, 250, 132, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 70, 2, 72, + 2, 74, 2, 81, 2, 86, 2, 87, 3, 89, 9, 156, 155, 11, 4, 72, 69, 84, 65, + 151, 233, 6, 65, 2, 173, 174, 16, 4, 80, 83, 73, 76, 2, 17, 2, 65, 80, 2, + 159, 7, 80, 2, 133, 134, 18, 2, 65, 66, 6, 74, 72, 200, 145, 5, 8, 65, + 82, 84, 73, 65, 76, 32, 68, 175, 128, 12, 73, 2, 243, 145, 17, 73, 2, + 221, 145, 17, 2, 72, 79, 102, 29, 5, 77, 65, 76, 76, 32, 102, 246, 1, 65, 22, 66, 2, 90, 22, 68, 22, 69, 38, 70, 62, 71, 22, 73, 22, 75, 34, 76, - 22, 79, 50, 80, 42, 82, 22, 83, 34, 84, 38, 85, 214, 197, 1, 67, 198, - 137, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 72, 2, 74, 2, 81, 2, - 86, 2, 87, 3, 89, 5, 179, 205, 14, 76, 5, 219, 132, 18, 69, 5, 175, 236, - 14, 69, 7, 130, 213, 1, 80, 199, 209, 16, 84, 5, 11, 73, 2, 29, 5, 78, - 65, 76, 32, 83, 2, 227, 1, 73, 5, 215, 210, 15, 65, 5, 191, 131, 18, 79, - 5, 11, 65, 2, 195, 234, 14, 80, 5, 243, 235, 14, 65, 7, 11, 77, 4, 190, - 171, 1, 73, 183, 185, 16, 69, 9, 186, 147, 18, 72, 2, 83, 219, 19, 73, 5, - 247, 135, 18, 72, 5, 11, 73, 2, 187, 133, 18, 71, 7, 162, 233, 14, 72, + 22, 79, 50, 80, 42, 82, 22, 83, 34, 84, 38, 85, 214, 197, 1, 67, 250, + 132, 13, 77, 2, 78, 186, 202, 1, 88, 198, 140, 2, 72, 2, 74, 2, 81, 2, + 86, 2, 87, 3, 89, 5, 231, 200, 14, 76, 5, 143, 128, 18, 69, 5, 227, 231, + 14, 69, 7, 130, 213, 1, 80, 251, 204, 16, 84, 5, 11, 73, 2, 29, 5, 78, + 65, 76, 32, 83, 2, 227, 1, 73, 5, 139, 206, 15, 65, 5, 243, 254, 17, 79, + 5, 11, 65, 2, 247, 229, 14, 80, 5, 167, 231, 14, 65, 7, 11, 77, 4, 190, + 171, 1, 73, 235, 180, 16, 69, 9, 238, 142, 18, 72, 2, 83, 219, 19, 73, 5, + 171, 131, 18, 72, 5, 11, 73, 2, 239, 128, 18, 71, 7, 214, 228, 14, 72, 175, 152, 3, 65, 5, 151, 210, 1, 80, 2, 11, 72, 2, 11, 69, 2, 11, 84, 2, - 151, 144, 17, 65, 104, 11, 32, 104, 18, 67, 35, 83, 52, 53, 5, 65, 80, - 73, 84, 65, 52, 21, 3, 77, 65, 76, 52, 195, 131, 12, 76, 82, 76, 8, 67, - 65, 80, 73, 84, 65, 76, 32, 157, 1, 6, 83, 77, 65, 76, 76, 32, 36, 138, - 164, 18, 65, 2, 67, 2, 68, 2, 71, 2, 74, 2, 75, 2, 78, 2, 79, 2, 80, 2, - 81, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 2, 89, 3, 90, 46, 238, 162, + 203, 139, 17, 65, 104, 11, 32, 104, 18, 67, 35, 83, 52, 53, 5, 65, 80, + 73, 84, 65, 52, 21, 3, 77, 65, 76, 52, 247, 254, 11, 76, 82, 76, 8, 67, + 65, 80, 73, 84, 65, 76, 32, 157, 1, 6, 83, 77, 65, 76, 76, 32, 36, 190, + 159, 18, 65, 2, 67, 2, 68, 2, 71, 2, 74, 2, 75, 2, 78, 2, 79, 2, 80, 2, + 81, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 2, 89, 3, 90, 46, 162, 158, 18, 65, 2, 66, 2, 67, 2, 68, 2, 70, 2, 72, 2, 73, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, 80, 2, 81, 2, 82, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 2, 89, 3, 90, 40, 45, 9, 32, 78, 85, 77, 69, 82, 65, 76, 32, 40, 70, 69, - 66, 70, 70, 78, 26, 83, 66, 84, 206, 172, 16, 90, 223, 86, 79, 6, 40, 4, - 73, 71, 72, 84, 203, 253, 9, 76, 5, 131, 202, 16, 69, 8, 30, 73, 105, 3, - 79, 85, 82, 4, 146, 135, 5, 70, 239, 129, 13, 86, 4, 65, 3, 73, 78, 69, - 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 5, 219, 200, 16, 84, 10, 42, 72, - 150, 253, 9, 87, 187, 209, 7, 69, 4, 222, 133, 5, 73, 175, 166, 11, 82, + 66, 70, 70, 78, 26, 83, 66, 84, 130, 168, 16, 90, 223, 86, 79, 6, 40, 4, + 73, 71, 72, 84, 255, 248, 9, 76, 5, 183, 197, 16, 69, 8, 30, 73, 105, 3, + 79, 85, 82, 4, 198, 130, 5, 70, 239, 129, 13, 86, 4, 65, 3, 73, 78, 69, + 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 5, 143, 196, 16, 84, 10, 42, 72, + 202, 248, 9, 87, 187, 209, 7, 69, 4, 146, 129, 5, 73, 175, 166, 11, 82, 130, 9, 226, 1, 65, 188, 4, 9, 67, 72, 65, 78, 73, 67, 65, 76, 32, 34, 68, 204, 15, 11, 69, 84, 69, 73, 32, 77, 65, 89, 69, 75, 32, 178, 11, 76, 62, 78, 134, 50, 82, 176, 15, 8, 83, 83, 65, 71, 69, 32, 87, 65, 22, 84, - 211, 155, 17, 77, 26, 68, 6, 83, 85, 82, 69, 68, 32, 137, 182, 14, 5, 84, - 32, 79, 78, 32, 24, 96, 5, 65, 78, 71, 76, 69, 164, 148, 10, 9, 82, 73, + 135, 151, 17, 77, 26, 68, 6, 83, 85, 82, 69, 68, 32, 189, 177, 14, 5, 84, + 32, 79, 78, 32, 24, 96, 5, 65, 78, 71, 76, 69, 216, 143, 10, 9, 82, 73, 71, 72, 84, 32, 65, 78, 71, 139, 245, 7, 66, 21, 11, 32, 18, 212, 1, 39, 87, 73, 84, 72, 32, 79, 80, 69, 78, 32, 65, 82, 77, 32, 69, 78, 68, 73, 78, 71, 32, 73, 78, 32, 65, 82, 82, 79, 87, 32, 80, 79, 73, 78, 84, 73, - 78, 71, 32, 205, 230, 17, 7, 79, 80, 69, 78, 73, 78, 71, 16, 62, 68, 24, + 78, 71, 32, 129, 226, 17, 7, 79, 80, 69, 78, 73, 78, 71, 16, 62, 68, 24, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 43, 85, 4, 73, 3, 79, 87, 78, 4, - 157, 150, 8, 5, 84, 32, 65, 78, 68, 4, 11, 80, 4, 153, 233, 11, 3, 32, - 65, 78, 4, 166, 153, 17, 65, 215, 56, 76, 252, 1, 56, 9, 69, 70, 65, 73, + 209, 145, 8, 5, 84, 32, 65, 78, 68, 4, 11, 80, 4, 205, 228, 11, 3, 32, + 65, 78, 4, 218, 148, 17, 65, 215, 56, 76, 252, 1, 56, 9, 69, 70, 65, 73, 68, 82, 73, 78, 32, 159, 7, 73, 190, 1, 174, 1, 67, 52, 6, 68, 73, 71, - 73, 84, 32, 152, 1, 7, 78, 85, 77, 66, 69, 82, 32, 114, 83, 224, 147, 7, + 73, 84, 32, 152, 1, 7, 78, 85, 77, 66, 69, 82, 32, 114, 83, 148, 143, 7, 12, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 32, 131, 170, 8, 70, 70, - 128, 3, 5, 65, 80, 73, 84, 65, 135, 189, 15, 79, 26, 82, 84, 48, 2, 79, - 78, 142, 161, 16, 70, 30, 83, 102, 90, 210, 86, 78, 239, 112, 69, 8, 44, - 3, 72, 82, 69, 241, 148, 17, 2, 87, 79, 4, 239, 148, 17, 69, 20, 50, 84, - 182, 249, 4, 69, 46, 70, 42, 78, 31, 83, 6, 246, 250, 4, 72, 220, 247, 4, - 2, 87, 69, 159, 209, 7, 69, 70, 68, 3, 77, 65, 76, 157, 212, 9, 8, 89, + 128, 3, 5, 65, 80, 73, 84, 65, 187, 184, 15, 79, 26, 82, 84, 48, 2, 79, + 78, 194, 156, 16, 70, 30, 83, 102, 90, 210, 86, 78, 239, 112, 69, 8, 44, + 3, 72, 82, 69, 165, 144, 17, 2, 87, 79, 4, 163, 144, 17, 69, 20, 50, 84, + 234, 244, 4, 69, 46, 70, 42, 78, 31, 83, 6, 170, 246, 4, 72, 220, 247, 4, + 2, 87, 69, 159, 209, 7, 69, 70, 68, 3, 77, 65, 76, 209, 207, 9, 8, 89, 77, 66, 79, 76, 32, 65, 73, 68, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, - 32, 68, 242, 1, 65, 38, 78, 218, 227, 3, 72, 2, 75, 178, 213, 10, 89, + 32, 68, 242, 1, 65, 38, 78, 142, 223, 3, 72, 2, 75, 178, 213, 10, 89, 222, 150, 3, 79, 162, 64, 66, 2, 67, 2, 68, 2, 69, 2, 70, 2, 71, 2, 73, 2, 74, 2, 76, 2, 77, 2, 80, 2, 81, 2, 82, 2, 83, 2, 84, 2, 85, 2, 86, 2, - 87, 2, 88, 3, 90, 7, 254, 243, 3, 84, 171, 156, 14, 73, 7, 130, 144, 18, - 71, 3, 89, 62, 48, 5, 69, 86, 65, 76, 32, 45, 3, 85, 77, 32, 6, 218, 243, + 87, 2, 88, 3, 90, 7, 178, 239, 3, 84, 171, 156, 14, 73, 7, 182, 139, 18, + 71, 3, 89, 62, 48, 5, 69, 86, 65, 76, 32, 45, 3, 85, 77, 32, 6, 142, 239, 10, 69, 134, 198, 4, 67, 115, 81, 56, 210, 1, 66, 50, 70, 164, 1, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 248, 1, 11, 77, 65, 84, 72, 69, 77, 65, 84, - 73, 67, 65, 22, 83, 124, 4, 84, 72, 82, 69, 214, 174, 15, 86, 246, 62, - 69, 166, 4, 87, 203, 11, 71, 4, 164, 158, 6, 3, 79, 76, 68, 211, 239, 7, + 73, 67, 65, 22, 83, 124, 4, 84, 72, 82, 69, 138, 170, 15, 86, 246, 62, + 69, 166, 4, 87, 203, 11, 71, 4, 216, 153, 6, 3, 79, 76, 68, 211, 239, 7, 76, 10, 84, 9, 76, 65, 84, 84, 69, 78, 69, 68, 32, 224, 3, 3, 79, 85, 82, - 135, 239, 15, 73, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 213, 1, + 187, 234, 15, 73, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 213, 1, 3, 84, 32, 80, 6, 11, 84, 6, 78, 32, 41, 15, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 65, 78, 71, 76, 69, 4, 36, 5, 67, 85, 82, 76, 89, 59, 80, 2, - 17, 2, 32, 66, 2, 249, 184, 7, 4, 82, 65, 67, 75, 2, 193, 198, 17, 10, - 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 2, 163, 203, 17, 76, 12, 150, - 143, 15, 72, 200, 95, 2, 73, 88, 182, 2, 65, 245, 115, 15, 77, 65, 76, + 17, 2, 32, 66, 2, 173, 180, 7, 4, 82, 65, 67, 75, 2, 245, 193, 17, 10, + 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 2, 215, 198, 17, 76, 12, 202, + 138, 15, 72, 200, 95, 2, 73, 88, 182, 2, 65, 245, 115, 15, 77, 65, 76, 76, 32, 87, 72, 73, 84, 69, 32, 67, 73, 82, 67, 4, 11, 69, 4, 45, 9, 32, - 80, 79, 73, 78, 84, 69, 68, 32, 4, 250, 207, 9, 80, 151, 158, 6, 66, 158, + 80, 79, 73, 78, 84, 69, 68, 32, 4, 174, 203, 9, 80, 151, 158, 6, 66, 158, 1, 146, 1, 65, 104, 6, 67, 72, 69, 73, 75, 72, 34, 76, 144, 6, 8, 83, 89, - 76, 76, 65, 66, 76, 69, 0, 4, 87, 79, 82, 68, 50, 86, 147, 139, 16, 68, - 6, 80, 8, 72, 65, 78, 71, 32, 75, 72, 85, 164, 6, 3, 80, 85, 78, 227, - 223, 13, 78, 2, 251, 200, 16, 68, 4, 150, 182, 17, 65, 139, 60, 69, 94, + 76, 76, 65, 66, 76, 69, 0, 4, 87, 79, 82, 68, 50, 86, 199, 134, 16, 68, + 6, 80, 8, 72, 65, 78, 71, 32, 75, 72, 85, 164, 6, 3, 80, 85, 78, 151, + 219, 13, 78, 2, 175, 196, 16, 68, 4, 202, 177, 17, 65, 139, 60, 69, 94, 52, 6, 69, 84, 84, 69, 82, 32, 185, 5, 2, 85, 77, 92, 250, 1, 66, 36, 2, 67, 72, 38, 68, 50, 71, 38, 74, 34, 75, 42, 78, 62, 80, 30, 83, 42, 84, - 54, 73, 0, 3, 76, 65, 73, 0, 3, 77, 73, 84, 166, 130, 13, 72, 166, 10, + 54, 73, 0, 3, 76, 65, 73, 0, 3, 77, 73, 84, 218, 253, 12, 72, 166, 10, 82, 2, 87, 248, 186, 2, 2, 65, 84, 250, 223, 1, 89, 246, 8, 85, 226, 79, - 69, 3, 79, 4, 146, 198, 16, 72, 147, 189, 1, 65, 4, 174, 247, 16, 73, - 211, 139, 1, 65, 8, 214, 171, 10, 72, 182, 203, 6, 73, 147, 68, 68, 4, - 166, 171, 10, 72, 239, 211, 7, 79, 4, 246, 196, 16, 72, 195, 49, 73, 6, - 216, 1, 2, 79, 75, 139, 169, 10, 72, 12, 178, 1, 65, 0, 3, 71, 79, 85, - 214, 253, 17, 78, 3, 89, 6, 118, 65, 255, 194, 16, 72, 6, 142, 240, 17, - 65, 162, 14, 72, 3, 83, 10, 48, 2, 73, 76, 138, 169, 10, 72, 199, 143, 7, - 84, 5, 225, 177, 1, 4, 32, 76, 79, 78, 2, 193, 252, 17, 3, 32, 73, 89, 2, - 157, 150, 17, 7, 32, 82, 69, 80, 69, 84, 73, 30, 64, 10, 79, 87, 69, 76, - 32, 83, 73, 71, 78, 32, 187, 194, 15, 73, 28, 130, 1, 65, 44, 4, 67, 72, - 69, 73, 2, 79, 0, 3, 83, 79, 85, 0, 2, 89, 69, 22, 73, 38, 85, 178, 137, - 11, 78, 211, 185, 4, 86, 8, 198, 234, 16, 78, 210, 82, 65, 187, 64, 85, - 2, 155, 234, 16, 78, 4, 134, 234, 16, 78, 139, 147, 1, 73, 4, 226, 233, - 16, 78, 139, 147, 1, 85, 6, 148, 225, 16, 4, 80, 79, 77, 69, 146, 19, 84, + 69, 3, 79, 4, 198, 193, 16, 72, 147, 189, 1, 65, 4, 226, 242, 16, 73, + 211, 139, 1, 65, 8, 138, 167, 10, 72, 182, 203, 6, 73, 147, 68, 68, 4, + 218, 166, 10, 72, 239, 211, 7, 79, 4, 170, 192, 16, 72, 195, 49, 73, 6, + 216, 1, 2, 79, 75, 191, 164, 10, 72, 12, 178, 1, 65, 0, 3, 71, 79, 85, + 138, 249, 17, 78, 3, 89, 6, 118, 65, 179, 190, 16, 72, 6, 194, 235, 17, + 65, 162, 14, 72, 3, 83, 10, 48, 2, 73, 76, 190, 164, 10, 72, 199, 143, 7, + 84, 5, 225, 177, 1, 4, 32, 76, 79, 78, 2, 245, 247, 17, 3, 32, 73, 89, 2, + 209, 145, 17, 7, 32, 82, 69, 80, 69, 84, 73, 30, 64, 10, 79, 87, 69, 76, + 32, 83, 73, 71, 78, 32, 239, 189, 15, 73, 28, 130, 1, 65, 44, 4, 67, 72, + 69, 73, 2, 79, 0, 3, 83, 79, 85, 0, 2, 89, 69, 22, 73, 38, 85, 230, 132, + 11, 78, 211, 185, 4, 86, 8, 250, 229, 16, 78, 210, 82, 65, 187, 64, 85, + 2, 207, 229, 16, 78, 4, 186, 229, 16, 78, 139, 147, 1, 73, 4, 150, 229, + 16, 78, 139, 147, 1, 85, 6, 200, 220, 16, 4, 80, 79, 77, 69, 146, 19, 84, 195, 56, 79, 178, 3, 160, 1, 11, 68, 69, 32, 75, 73, 75, 65, 75, 85, 73, - 32, 212, 228, 16, 20, 79, 82, 65, 72, 32, 87, 73, 84, 72, 32, 78, 73, 78, + 32, 136, 224, 16, 20, 79, 82, 65, 72, 32, 87, 73, 84, 72, 32, 78, 73, 78, 69, 32, 66, 82, 65, 78, 67, 79, 83, 174, 3, 148, 1, 17, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 78, 85, 77, 66, 69, 82, 32, 164, 1, 10, 83, 89, - 76, 76, 65, 66, 76, 69, 32, 77, 215, 172, 9, 68, 14, 62, 84, 56, 7, 72, - 85, 78, 68, 82, 69, 68, 147, 186, 4, 77, 8, 26, 69, 219, 186, 4, 72, 6, - 26, 78, 167, 177, 14, 69, 4, 172, 186, 4, 2, 32, 84, 163, 190, 13, 83, + 76, 76, 65, 66, 76, 69, 32, 77, 139, 168, 9, 68, 14, 62, 84, 56, 7, 72, + 85, 78, 68, 82, 69, 68, 199, 181, 4, 77, 8, 26, 69, 143, 182, 4, 72, 6, + 26, 78, 219, 172, 14, 69, 4, 224, 181, 4, 2, 32, 84, 163, 190, 13, 83, 142, 3, 22, 48, 143, 21, 49, 198, 1, 118, 48, 250, 1, 49, 210, 1, 50, 138, 2, 51, 254, 1, 52, 130, 2, 53, 158, 2, 54, 242, 1, 55, 134, 2, 56, - 187, 2, 57, 18, 142, 1, 49, 34, 50, 22, 51, 22, 52, 162, 151, 2, 53, 162, - 241, 3, 56, 196, 236, 10, 3, 57, 32, 77, 92, 3, 55, 32, 77, 237, 90, 3, - 54, 32, 87, 2, 11, 32, 2, 151, 226, 17, 75, 2, 243, 236, 17, 32, 2, 179, - 159, 12, 32, 2, 11, 32, 2, 207, 225, 17, 87, 20, 130, 1, 49, 22, 54, 18, - 56, 22, 57, 228, 28, 2, 48, 32, 162, 188, 7, 53, 218, 209, 5, 52, 198, - 10, 55, 222, 9, 50, 207, 244, 3, 51, 2, 231, 198, 17, 32, 2, 147, 25, 32, - 2, 215, 214, 13, 32, 2, 227, 128, 13, 32, 20, 106, 49, 22, 50, 22, 51, - 22, 52, 22, 53, 22, 54, 22, 55, 22, 57, 142, 229, 11, 48, 185, 236, 1, 2, - 56, 32, 2, 147, 175, 10, 32, 2, 195, 134, 10, 32, 2, 227, 205, 17, 32, 2, - 211, 153, 12, 32, 2, 167, 238, 12, 32, 2, 219, 207, 17, 32, 2, 179, 232, + 187, 2, 57, 18, 142, 1, 49, 34, 50, 22, 51, 22, 52, 162, 151, 2, 53, 214, + 236, 3, 56, 196, 236, 10, 3, 57, 32, 77, 92, 3, 55, 32, 77, 237, 90, 3, + 54, 32, 87, 2, 11, 32, 2, 203, 221, 17, 75, 2, 167, 232, 17, 32, 2, 231, + 154, 12, 32, 2, 11, 32, 2, 131, 221, 17, 87, 20, 130, 1, 49, 22, 54, 18, + 56, 22, 57, 228, 28, 2, 48, 32, 214, 183, 7, 53, 218, 209, 5, 52, 198, + 10, 55, 222, 9, 50, 207, 244, 3, 51, 2, 155, 194, 17, 32, 2, 147, 25, 32, + 2, 139, 210, 13, 32, 2, 151, 252, 12, 32, 20, 106, 49, 22, 50, 22, 51, + 22, 52, 22, 53, 22, 54, 22, 55, 22, 57, 194, 224, 11, 48, 185, 236, 1, 2, + 56, 32, 2, 199, 170, 10, 32, 2, 247, 129, 10, 32, 2, 151, 201, 17, 32, 2, + 135, 149, 12, 32, 2, 219, 233, 12, 32, 2, 143, 203, 17, 32, 2, 231, 227, 12, 32, 2, 219, 28, 32, 20, 174, 1, 48, 16, 2, 49, 32, 20, 2, 52, 32, 20, - 2, 56, 32, 130, 195, 4, 57, 214, 51, 50, 22, 53, 220, 240, 7, 2, 54, 32, + 2, 56, 32, 182, 190, 4, 57, 214, 51, 50, 22, 53, 220, 240, 7, 2, 54, 32, 188, 136, 4, 3, 55, 32, 78, 237, 90, 3, 51, 32, 89, 2, 159, 37, 32, 2, - 163, 220, 17, 89, 2, 143, 220, 17, 70, 2, 183, 163, 16, 78, 20, 192, 1, + 215, 215, 17, 89, 2, 195, 215, 17, 70, 2, 235, 158, 16, 78, 20, 192, 1, 2, 48, 32, 22, 53, 22, 56, 160, 8, 3, 52, 32, 75, 128, 22, 3, 54, 32, 72, - 222, 2, 55, 202, 213, 4, 49, 224, 184, 4, 3, 57, 32, 87, 156, 174, 4, 2, - 51, 32, 157, 197, 1, 3, 50, 32, 72, 2, 219, 251, 15, 72, 2, 175, 217, 15, - 32, 2, 211, 206, 17, 32, 20, 178, 1, 48, 18, 53, 20, 2, 54, 32, 20, 2, - 56, 32, 22, 57, 232, 218, 9, 2, 50, 32, 236, 4, 2, 51, 32, 210, 214, 1, + 222, 2, 55, 254, 208, 4, 49, 224, 184, 4, 3, 57, 32, 87, 156, 174, 4, 2, + 51, 32, 157, 197, 1, 3, 50, 32, 72, 2, 143, 247, 15, 72, 2, 227, 212, 15, + 32, 2, 135, 202, 17, 32, 20, 178, 1, 48, 18, 53, 20, 2, 54, 32, 20, 2, + 56, 32, 22, 57, 156, 214, 9, 2, 50, 32, 236, 4, 2, 51, 32, 210, 214, 1, 49, 164, 234, 3, 3, 52, 32, 76, 197, 144, 1, 3, 55, 32, 78, 2, 159, 4, - 32, 2, 231, 162, 16, 32, 2, 191, 190, 17, 71, 2, 131, 156, 13, 78, 2, - 185, 149, 16, 2, 32, 77, 20, 196, 1, 2, 50, 32, 22, 54, 238, 25, 51, 168, - 2, 3, 55, 32, 78, 200, 216, 1, 2, 52, 32, 234, 150, 3, 56, 144, 150, 5, + 32, 2, 155, 158, 16, 32, 2, 243, 185, 17, 71, 2, 183, 151, 13, 78, 2, + 237, 144, 16, 2, 32, 77, 20, 196, 1, 2, 50, 32, 22, 54, 238, 25, 51, 168, + 2, 3, 55, 32, 78, 200, 216, 1, 2, 52, 32, 158, 146, 3, 56, 144, 150, 5, 3, 48, 32, 78, 192, 89, 3, 49, 32, 87, 158, 13, 57, 249, 238, 4, 3, 53, - 32, 75, 2, 179, 188, 17, 77, 2, 207, 157, 10, 32, 20, 196, 1, 3, 52, 32, + 32, 75, 2, 231, 183, 17, 77, 2, 131, 153, 10, 32, 20, 196, 1, 3, 52, 32, 75, 20, 2, 53, 32, 22, 57, 232, 7, 3, 49, 32, 71, 234, 1, 51, 236, 6, 3, - 48, 32, 71, 146, 5, 50, 212, 230, 10, 2, 55, 32, 172, 160, 4, 3, 54, 32, - 75, 217, 88, 3, 56, 32, 70, 2, 131, 195, 17, 80, 2, 131, 209, 17, 70, 2, - 163, 249, 10, 32, 20, 228, 1, 2, 48, 32, 20, 2, 49, 32, 20, 2, 52, 32, - 22, 53, 172, 14, 6, 54, 32, 76, 79, 78, 71, 224, 11, 2, 57, 32, 228, 173, + 48, 32, 71, 146, 5, 50, 136, 226, 10, 2, 55, 32, 172, 160, 4, 3, 54, 32, + 75, 217, 88, 3, 56, 32, 70, 2, 183, 190, 17, 80, 2, 183, 204, 17, 70, 2, + 215, 244, 10, 32, 20, 228, 1, 2, 48, 32, 20, 2, 49, 32, 20, 2, 52, 32, + 22, 53, 172, 14, 6, 54, 32, 76, 79, 78, 71, 224, 11, 2, 57, 32, 152, 169, 3, 3, 51, 32, 72, 128, 165, 9, 4, 50, 32, 78, 71, 236, 247, 3, 3, 55, 32, - 72, 189, 97, 3, 56, 32, 70, 2, 243, 206, 17, 89, 2, 147, 243, 15, 80, 2, - 255, 242, 15, 76, 2, 183, 232, 16, 32, 20, 230, 1, 53, 216, 14, 4, 48, - 32, 78, 71, 244, 7, 3, 51, 32, 71, 220, 163, 12, 2, 55, 32, 250, 117, 57, + 72, 189, 97, 3, 56, 32, 70, 2, 167, 202, 17, 89, 2, 199, 238, 15, 80, 2, + 179, 238, 15, 76, 2, 235, 227, 16, 32, 20, 230, 1, 53, 216, 14, 4, 48, + 32, 78, 71, 244, 7, 3, 51, 32, 71, 144, 159, 12, 2, 55, 32, 250, 117, 57, 200, 117, 3, 50, 32, 75, 136, 203, 1, 3, 49, 32, 84, 156, 28, 4, 56, 32, - 78, 89, 152, 134, 1, 3, 52, 32, 77, 225, 34, 2, 54, 32, 2, 183, 179, 17, + 78, 89, 152, 134, 1, 3, 52, 32, 77, 225, 34, 2, 54, 32, 2, 235, 174, 17, 32, 200, 1, 118, 48, 186, 2, 49, 210, 2, 50, 166, 2, 51, 222, 1, 52, 186, 2, 53, 214, 2, 54, 166, 2, 55, 190, 2, 56, 223, 2, 57, 20, 222, 1, 49, 30, 52, 28, 7, 53, 32, 76, 79, 78, 71, 32, 12, 2, 51, 32, 184, 11, 6, 54, - 32, 76, 79, 78, 71, 202, 241, 4, 50, 170, 170, 2, 48, 204, 143, 5, 3, 55, - 32, 71, 200, 182, 3, 3, 57, 32, 89, 201, 40, 3, 56, 32, 75, 2, 129, 148, - 16, 2, 32, 70, 2, 137, 149, 15, 2, 32, 84, 2, 11, 77, 2, 227, 148, 15, + 32, 76, 79, 78, 71, 254, 236, 4, 50, 170, 170, 2, 48, 204, 143, 5, 3, 55, + 32, 71, 200, 182, 3, 3, 57, 32, 89, 201, 40, 3, 56, 32, 75, 2, 181, 143, + 16, 2, 32, 70, 2, 189, 144, 15, 2, 32, 84, 2, 11, 77, 2, 151, 144, 15, 66, 20, 208, 1, 6, 48, 32, 76, 79, 78, 71, 22, 51, 34, 54, 22, 56, 32, 2, - 57, 32, 248, 17, 4, 53, 32, 78, 71, 128, 209, 2, 2, 55, 32, 196, 151, 2, + 57, 32, 248, 17, 4, 53, 32, 78, 71, 128, 209, 2, 2, 55, 32, 248, 146, 2, 3, 50, 32, 75, 216, 151, 10, 3, 52, 32, 87, 181, 136, 2, 2, 49, 32, 2, - 183, 183, 16, 32, 2, 11, 32, 2, 255, 198, 17, 74, 2, 155, 210, 16, 32, 2, - 11, 32, 2, 203, 198, 17, 87, 2, 151, 202, 15, 78, 20, 226, 1, 50, 32, 2, - 51, 32, 128, 4, 3, 52, 32, 71, 254, 9, 48, 244, 245, 9, 4, 56, 32, 72, + 235, 178, 16, 32, 2, 11, 32, 2, 179, 194, 17, 74, 2, 207, 205, 16, 32, 2, + 11, 32, 2, 255, 193, 17, 87, 2, 203, 197, 15, 78, 20, 226, 1, 50, 32, 2, + 51, 32, 128, 4, 3, 52, 32, 71, 254, 9, 48, 168, 241, 9, 4, 56, 32, 72, 79, 208, 225, 2, 5, 55, 32, 78, 71, 71, 148, 88, 2, 53, 32, 168, 61, 2, 57, 32, 216, 237, 1, 3, 54, 32, 87, 221, 153, 1, 2, 49, 32, 2, 11, 32, 2, - 183, 166, 13, 77, 2, 11, 78, 2, 143, 199, 17, 68, 20, 200, 3, 2, 56, 32, - 252, 4, 3, 52, 32, 78, 148, 244, 4, 3, 50, 32, 75, 250, 215, 2, 49, 2, + 235, 161, 13, 77, 2, 11, 78, 2, 195, 194, 17, 68, 20, 200, 3, 2, 56, 32, + 252, 4, 3, 52, 32, 78, 200, 239, 4, 3, 50, 32, 75, 250, 215, 2, 49, 2, 53, 232, 174, 2, 2, 55, 32, 160, 140, 5, 3, 51, 32, 70, 0, 3, 54, 32, 83, 224, 53, 2, 48, 32, 197, 152, 1, 3, 57, 32, 87, 20, 236, 1, 8, 50, 32, 76, 79, 78, 71, 32, 77, 20, 3, 53, 32, 77, 22, 54, 224, 2, 3, 57, 32, 78, - 186, 220, 6, 55, 176, 160, 3, 3, 51, 32, 87, 160, 230, 2, 2, 48, 32, 168, - 60, 3, 56, 32, 71, 216, 233, 1, 3, 49, 32, 89, 1, 3, 52, 32, 86, 2, 147, - 184, 17, 66, 2, 155, 195, 17, 66, 2, 169, 159, 16, 3, 32, 78, 71, 20, + 238, 215, 6, 55, 176, 160, 3, 3, 51, 32, 87, 160, 230, 2, 2, 48, 32, 168, + 60, 3, 56, 32, 71, 216, 233, 1, 3, 49, 32, 89, 1, 3, 52, 32, 86, 2, 199, + 179, 17, 66, 2, 207, 190, 17, 66, 2, 221, 154, 16, 3, 32, 78, 71, 20, 192, 1, 2, 50, 32, 34, 52, 26, 53, 34, 54, 36, 2, 55, 32, 188, 7, 2, 48, - 32, 204, 128, 10, 3, 56, 32, 75, 188, 198, 2, 2, 49, 32, 136, 144, 3, 5, - 57, 32, 78, 71, 71, 229, 210, 1, 2, 51, 32, 2, 11, 78, 2, 183, 210, 17, - 74, 2, 165, 5, 2, 32, 77, 2, 11, 32, 2, 223, 192, 17, 71, 2, 169, 137, - 15, 4, 32, 78, 71, 71, 2, 223, 225, 15, 74, 20, 220, 1, 2, 48, 32, 20, 6, - 49, 32, 76, 79, 78, 71, 30, 56, 156, 2, 2, 55, 32, 188, 198, 9, 3, 52, + 32, 128, 252, 9, 3, 56, 32, 75, 188, 198, 2, 2, 49, 32, 136, 144, 3, 5, + 57, 32, 78, 71, 71, 229, 210, 1, 2, 51, 32, 2, 11, 78, 2, 235, 205, 17, + 74, 2, 165, 5, 2, 32, 77, 2, 11, 32, 2, 147, 188, 17, 71, 2, 221, 132, + 15, 4, 32, 78, 71, 71, 2, 147, 221, 15, 74, 20, 220, 1, 2, 48, 32, 20, 6, + 49, 32, 76, 79, 78, 71, 30, 56, 156, 2, 2, 55, 32, 240, 193, 9, 3, 52, 32, 78, 236, 49, 4, 54, 32, 71, 85, 160, 140, 5, 2, 53, 32, 216, 88, 3, - 50, 32, 83, 0, 2, 51, 32, 241, 101, 2, 57, 32, 2, 147, 135, 15, 74, 2, - 141, 169, 12, 2, 32, 77, 2, 191, 217, 12, 32, 24, 198, 1, 50, 2, 52, 36, - 6, 53, 32, 76, 79, 78, 71, 28, 3, 55, 32, 78, 34, 56, 168, 247, 11, 2, + 50, 32, 83, 0, 2, 51, 32, 241, 101, 2, 57, 32, 2, 199, 130, 15, 74, 2, + 193, 164, 12, 2, 32, 77, 2, 243, 212, 12, 32, 24, 198, 1, 50, 2, 52, 36, + 6, 53, 32, 76, 79, 78, 71, 28, 3, 55, 32, 78, 34, 56, 220, 242, 11, 2, 54, 32, 196, 98, 3, 57, 32, 75, 148, 131, 3, 3, 51, 32, 86, 240, 113, 4, - 48, 32, 78, 89, 219, 53, 49, 4, 205, 134, 15, 4, 32, 77, 66, 79, 2, 229, - 176, 17, 2, 32, 74, 2, 11, 71, 2, 151, 131, 16, 85, 2, 155, 249, 15, 32, + 48, 32, 78, 89, 219, 53, 49, 4, 129, 130, 15, 4, 32, 77, 66, 79, 2, 153, + 172, 17, 2, 32, 74, 2, 11, 71, 2, 203, 254, 15, 85, 2, 207, 244, 15, 32, 20, 212, 1, 2, 48, 32, 22, 49, 22, 50, 20, 6, 51, 32, 76, 79, 78, 71, 34, - 56, 168, 142, 9, 2, 53, 32, 128, 129, 1, 3, 52, 32, 78, 232, 198, 2, 2, + 56, 220, 137, 9, 2, 53, 32, 128, 129, 1, 3, 52, 32, 78, 232, 198, 2, 2, 54, 32, 216, 129, 3, 4, 55, 32, 77, 66, 237, 30, 4, 57, 32, 77, 85, 2, - 187, 130, 15, 68, 2, 223, 141, 10, 32, 2, 215, 222, 10, 32, 2, 165, 189, - 15, 3, 32, 78, 71, 2, 17, 2, 32, 77, 2, 163, 218, 15, 66, 16, 142, 1, 48, + 239, 253, 14, 68, 2, 147, 137, 10, 32, 2, 139, 218, 10, 32, 2, 217, 184, + 15, 3, 32, 78, 71, 2, 17, 2, 32, 77, 2, 215, 213, 15, 66, 16, 142, 1, 48, 32, 3, 49, 32, 78, 20, 3, 50, 32, 78, 20, 2, 51, 32, 20, 3, 52, 32, 87, - 22, 53, 20, 2, 54, 32, 233, 212, 12, 3, 55, 32, 70, 2, 11, 32, 2, 243, - 216, 15, 71, 2, 223, 216, 15, 68, 2, 131, 166, 17, 74, 2, 235, 250, 16, - 72, 2, 235, 182, 17, 85, 2, 147, 254, 15, 32, 2, 163, 145, 1, 83, 248, 1, - 72, 6, 79, 73, 84, 73, 67, 32, 212, 131, 11, 2, 67, 85, 191, 193, 2, 80, + 22, 53, 20, 2, 54, 32, 157, 208, 12, 3, 55, 32, 70, 2, 11, 32, 2, 167, + 212, 15, 71, 2, 147, 212, 15, 68, 2, 183, 161, 17, 74, 2, 159, 246, 16, + 72, 2, 159, 178, 17, 85, 2, 199, 249, 15, 32, 2, 163, 145, 1, 83, 248, 1, + 72, 6, 79, 73, 84, 73, 67, 32, 136, 255, 10, 2, 67, 85, 191, 193, 2, 80, 244, 1, 104, 8, 67, 85, 82, 83, 73, 86, 69, 32, 221, 10, 13, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, 67, 32, 180, 1, 96, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 250, 2, 76, 133, 3, 7, 78, 85, 77, 66, 69, 82, 32, 24, 78, 69, 50, 70, 44, 4, 79, 78, 69, 32, 46, 83, 50, 84, 61, 3, 78, 73, 78, 4, 160, 1, 2, 76, 69, 93, 4, 73, 71, 72, 84, 4, 192, 1, 2, 73, 86, - 13, 3, 79, 85, 82, 4, 140, 192, 15, 4, 84, 87, 69, 76, 19, 72, 4, 26, 69, + 13, 3, 79, 85, 82, 4, 192, 187, 15, 4, 84, 87, 69, 76, 19, 72, 4, 26, 69, 93, 2, 73, 88, 2, 65, 2, 86, 69, 6, 46, 69, 12, 3, 72, 82, 69, 13, 2, 87, - 79, 2, 23, 78, 2, 11, 69, 2, 237, 193, 15, 5, 32, 84, 87, 69, 76, 52, 76, + 79, 2, 23, 78, 2, 11, 69, 2, 161, 189, 15, 5, 32, 84, 87, 69, 76, 52, 76, 6, 69, 84, 84, 69, 82, 32, 137, 2, 8, 79, 71, 79, 71, 82, 65, 77, 32, 48, - 182, 1, 65, 46, 84, 238, 235, 1, 78, 2, 83, 162, 217, 13, 72, 234, 181, + 182, 1, 65, 46, 84, 238, 235, 1, 78, 2, 83, 214, 212, 13, 72, 234, 181, 1, 75, 138, 69, 66, 2, 68, 2, 76, 2, 77, 2, 80, 2, 81, 2, 82, 2, 87, 2, - 89, 186, 2, 69, 2, 73, 3, 79, 5, 157, 182, 11, 6, 82, 67, 72, 65, 73, 67, - 6, 178, 194, 17, 65, 2, 69, 3, 79, 4, 202, 209, 4, 73, 153, 212, 12, 2, + 89, 186, 2, 69, 2, 73, 3, 79, 5, 209, 177, 11, 6, 82, 67, 72, 65, 73, 67, + 6, 230, 189, 17, 65, 2, 69, 3, 79, 4, 254, 204, 4, 73, 153, 212, 12, 2, 82, 77, 104, 92, 5, 69, 73, 71, 72, 84, 30, 70, 92, 4, 78, 73, 78, 69, 54, 83, 78, 84, 73, 2, 79, 78, 11, 150, 1, 89, 223, 1, 32, 24, 18, 73, - 35, 79, 12, 142, 2, 86, 163, 236, 3, 70, 12, 148, 2, 2, 85, 82, 251, 235, - 3, 82, 11, 28, 2, 84, 89, 223, 1, 32, 2, 215, 161, 6, 32, 24, 40, 4, 69, - 86, 69, 78, 1, 2, 73, 88, 13, 154, 1, 32, 251, 235, 3, 84, 28, 34, 72, - 50, 87, 143, 160, 6, 69, 12, 32, 2, 82, 69, 239, 235, 3, 73, 8, 39, 69, - 12, 26, 79, 239, 235, 3, 69, 9, 11, 32, 6, 178, 158, 6, 72, 207, 195, 5, - 84, 64, 96, 7, 76, 69, 84, 84, 69, 82, 32, 201, 167, 3, 11, 83, 89, 77, + 35, 79, 12, 142, 2, 86, 215, 231, 3, 70, 12, 148, 2, 2, 85, 82, 175, 231, + 3, 82, 11, 28, 2, 84, 89, 223, 1, 32, 2, 139, 157, 6, 32, 24, 40, 4, 69, + 86, 69, 78, 1, 2, 73, 88, 13, 154, 1, 32, 175, 231, 3, 84, 28, 34, 72, + 50, 87, 195, 155, 6, 69, 12, 32, 2, 82, 69, 163, 231, 3, 73, 8, 39, 69, + 12, 26, 79, 163, 231, 3, 69, 9, 11, 32, 6, 230, 153, 6, 72, 207, 195, 5, + 84, 64, 96, 7, 76, 69, 84, 84, 69, 82, 32, 253, 162, 3, 11, 83, 89, 77, 66, 79, 76, 32, 86, 73, 68, 74, 60, 174, 1, 66, 2, 82, 22, 78, 30, 83, - 38, 84, 222, 189, 15, 72, 234, 181, 1, 75, 138, 69, 68, 2, 76, 2, 77, 2, - 80, 2, 81, 2, 87, 2, 89, 186, 2, 65, 2, 69, 2, 73, 3, 79, 4, 151, 166, 3, - 65, 8, 130, 166, 3, 65, 3, 69, 6, 230, 165, 3, 65, 195, 149, 14, 69, 10, - 194, 165, 3, 65, 2, 69, 195, 149, 14, 79, 2, 243, 171, 12, 73, 22, 26, - 82, 207, 252, 16, 73, 20, 44, 5, 73, 67, 65, 76, 32, 251, 185, 17, 79, + 38, 84, 146, 185, 15, 72, 234, 181, 1, 75, 138, 69, 68, 2, 76, 2, 77, 2, + 80, 2, 81, 2, 87, 2, 89, 186, 2, 65, 2, 69, 2, 73, 3, 79, 4, 203, 161, 3, + 65, 8, 182, 161, 3, 65, 3, 69, 6, 154, 161, 3, 65, 195, 149, 14, 69, 10, + 246, 160, 3, 65, 2, 69, 195, 149, 14, 79, 2, 167, 167, 12, 73, 22, 26, + 82, 131, 248, 16, 73, 20, 44, 5, 73, 67, 65, 76, 32, 175, 181, 17, 79, 18, 116, 10, 76, 79, 78, 71, 32, 79, 86, 69, 82, 32, 74, 80, 26, 84, 168, - 1, 7, 83, 72, 79, 82, 84, 32, 79, 215, 32, 66, 4, 180, 246, 2, 2, 83, 72, + 1, 7, 83, 72, 79, 82, 84, 32, 79, 215, 32, 66, 4, 232, 241, 2, 2, 83, 72, 169, 253, 10, 7, 84, 87, 79, 32, 83, 72, 79, 2, 109, 3, 69, 78, 84, 8, 66, 69, 34, 82, 41, 10, 87, 79, 32, 83, 72, 79, 82, 84, 83, 32, 2, 17, 2, - 84, 82, 2, 23, 65, 2, 11, 73, 2, 189, 157, 16, 2, 83, 69, 4, 26, 79, 235, - 131, 8, 74, 2, 205, 195, 10, 4, 86, 69, 82, 32, 230, 2, 104, 3, 65, 79, + 84, 82, 2, 23, 65, 2, 11, 73, 2, 241, 152, 16, 2, 83, 69, 4, 26, 79, 159, + 255, 7, 74, 2, 129, 191, 10, 4, 86, 69, 82, 32, 230, 2, 104, 3, 65, 79, 32, 136, 18, 2, 67, 82, 142, 1, 68, 142, 1, 76, 130, 1, 78, 245, 2, 4, 82, 82, 79, 82, 170, 2, 156, 1, 7, 76, 69, 84, 84, 69, 82, 32, 180, 10, 5, 83, 73, 71, 78, 32, 212, 1, 5, 84, 79, 78, 69, 32, 69, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 178, 1, 214, 1, 65, 110, 66, 34, 68, 106, 71, 34, 76, 50, 78, 106, 82, 170, 1, 83, 54, 84, 218, 1, 86, 32, 3, 89, - 73, 32, 118, 90, 238, 180, 13, 81, 234, 233, 1, 80, 222, 196, 1, 72, 2, + 73, 32, 118, 90, 162, 176, 13, 81, 234, 233, 1, 80, 222, 196, 1, 72, 2, 77, 138, 69, 70, 2, 75, 2, 87, 3, 88, 10, 52, 7, 82, 67, 72, 65, 73, 67, - 32, 175, 178, 17, 72, 8, 134, 132, 9, 90, 162, 184, 4, 78, 207, 243, 3, - 77, 4, 158, 158, 17, 82, 219, 19, 65, 16, 50, 90, 154, 4, 76, 214, 170, - 17, 68, 187, 2, 65, 8, 202, 157, 17, 89, 162, 17, 72, 2, 90, 187, 2, 65, - 6, 174, 233, 16, 72, 195, 71, 65, 8, 170, 184, 10, 72, 238, 245, 6, 89, - 187, 2, 65, 18, 54, 65, 170, 232, 16, 71, 2, 78, 2, 89, 139, 69, 72, 5, - 11, 83, 2, 141, 234, 13, 4, 65, 76, 73, 90, 16, 60, 9, 69, 70, 79, 82, - 77, 69, 68, 32, 84, 167, 152, 17, 84, 14, 40, 4, 79, 78, 69, 45, 167, - 177, 15, 83, 12, 202, 174, 17, 49, 2, 50, 2, 52, 2, 53, 2, 54, 3, 56, 8, - 182, 154, 17, 89, 162, 17, 72, 2, 83, 187, 2, 65, 32, 78, 76, 20, 4, 79, - 78, 69, 45, 70, 83, 254, 169, 17, 84, 186, 2, 65, 3, 69, 4, 231, 180, 10, - 72, 14, 246, 172, 17, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 8, - 250, 169, 17, 72, 2, 83, 186, 2, 65, 3, 69, 4, 202, 169, 17, 70, 187, 2, - 65, 16, 70, 84, 244, 173, 15, 2, 68, 90, 146, 63, 78, 226, 187, 1, 75, 3, - 80, 8, 218, 227, 16, 83, 138, 69, 84, 187, 2, 65, 16, 50, 90, 254, 226, - 16, 83, 138, 69, 72, 187, 2, 65, 8, 150, 178, 10, 83, 238, 245, 6, 89, + 32, 227, 173, 17, 72, 8, 186, 255, 8, 90, 162, 184, 4, 78, 207, 243, 3, + 77, 4, 210, 153, 17, 82, 219, 19, 65, 16, 50, 90, 154, 4, 76, 138, 166, + 17, 68, 187, 2, 65, 8, 254, 152, 17, 89, 162, 17, 72, 2, 90, 187, 2, 65, + 6, 226, 228, 16, 72, 195, 71, 65, 8, 222, 179, 10, 72, 238, 245, 6, 89, + 187, 2, 65, 18, 54, 65, 222, 227, 16, 71, 2, 78, 2, 89, 139, 69, 72, 5, + 11, 83, 2, 193, 229, 13, 4, 65, 76, 73, 90, 16, 60, 9, 69, 70, 79, 82, + 77, 69, 68, 32, 84, 219, 147, 17, 84, 14, 40, 4, 79, 78, 69, 45, 219, + 172, 15, 83, 12, 254, 169, 17, 49, 2, 50, 2, 52, 2, 53, 2, 54, 3, 56, 8, + 234, 149, 17, 89, 162, 17, 72, 2, 83, 187, 2, 65, 32, 78, 76, 20, 4, 79, + 78, 69, 45, 70, 83, 178, 165, 17, 84, 186, 2, 65, 3, 69, 4, 155, 176, 10, + 72, 14, 170, 168, 17, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 8, + 174, 165, 17, 72, 2, 83, 186, 2, 65, 3, 69, 4, 254, 164, 17, 70, 187, 2, + 65, 16, 70, 84, 168, 169, 15, 2, 68, 90, 146, 63, 78, 226, 187, 1, 75, 3, + 80, 8, 142, 223, 16, 83, 138, 69, 84, 187, 2, 65, 16, 50, 90, 178, 222, + 16, 83, 138, 69, 72, 187, 2, 65, 8, 202, 173, 10, 83, 238, 245, 6, 89, 187, 2, 65, 8, 144, 1, 9, 82, 69, 70, 79, 82, 77, 69, 68, 32, 34, 65, - 133, 133, 16, 18, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 77, 79, 68, 73, - 70, 73, 69, 82, 4, 30, 65, 221, 88, 2, 86, 79, 2, 133, 150, 12, 3, 83, - 80, 73, 8, 202, 134, 15, 66, 204, 78, 3, 84, 79, 80, 182, 86, 65, 159, - 82, 82, 104, 146, 1, 65, 78, 69, 62, 73, 78, 79, 74, 85, 74, 89, 224, - 149, 7, 9, 82, 79, 85, 78, 68, 69, 68, 32, 69, 238, 196, 7, 87, 178, 75, - 78, 227, 127, 86, 19, 222, 168, 15, 78, 226, 189, 1, 69, 146, 63, 72, - 146, 1, 65, 2, 73, 3, 85, 15, 246, 207, 13, 82, 158, 216, 1, 78, 130, - 254, 1, 65, 3, 73, 23, 202, 167, 15, 65, 54, 79, 134, 253, 1, 78, 86, 69, - 2, 71, 2, 73, 3, 85, 13, 42, 69, 226, 164, 17, 71, 2, 79, 3, 85, 4, 222, - 164, 17, 82, 3, 89, 19, 182, 166, 15, 65, 182, 234, 1, 69, 134, 19, 78, - 2, 79, 86, 73, 3, 85, 7, 162, 144, 17, 85, 219, 19, 73, 12, 18, 32, 63, - 79, 4, 244, 141, 16, 4, 79, 78, 32, 85, 13, 4, 68, 65, 83, 72, 8, 142, - 237, 11, 83, 154, 137, 4, 80, 242, 37, 32, 163, 112, 66, 12, 64, 4, 68, - 76, 69, 32, 237, 223, 4, 6, 76, 73, 78, 69, 32, 72, 10, 220, 193, 5, 3, + 185, 128, 16, 18, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 77, 79, 68, 73, + 70, 73, 69, 82, 4, 30, 65, 221, 88, 2, 86, 79, 2, 185, 145, 12, 3, 83, + 80, 73, 8, 254, 129, 15, 66, 204, 78, 3, 84, 79, 80, 182, 86, 65, 159, + 82, 82, 104, 146, 1, 65, 78, 69, 62, 73, 78, 79, 74, 85, 74, 89, 148, + 145, 7, 9, 82, 79, 85, 78, 68, 69, 68, 32, 69, 238, 196, 7, 87, 178, 75, + 78, 227, 127, 86, 19, 146, 164, 15, 78, 226, 189, 1, 69, 146, 63, 72, + 146, 1, 65, 2, 73, 3, 85, 15, 170, 203, 13, 82, 158, 216, 1, 78, 130, + 254, 1, 65, 3, 73, 23, 254, 162, 15, 65, 54, 79, 134, 253, 1, 78, 86, 69, + 2, 71, 2, 73, 3, 85, 13, 42, 69, 150, 160, 17, 71, 2, 79, 3, 85, 4, 146, + 160, 17, 82, 3, 89, 19, 234, 161, 15, 65, 182, 234, 1, 69, 134, 19, 78, + 2, 79, 86, 73, 3, 85, 7, 214, 139, 17, 85, 219, 19, 73, 12, 18, 32, 63, + 79, 4, 168, 137, 16, 4, 79, 78, 32, 85, 13, 4, 68, 65, 83, 72, 8, 194, + 232, 11, 83, 154, 137, 4, 80, 242, 37, 32, 163, 112, 66, 12, 64, 4, 68, + 76, 69, 32, 161, 219, 4, 6, 76, 73, 78, 69, 32, 72, 10, 144, 189, 5, 3, 84, 72, 73, 198, 232, 8, 76, 22, 82, 159, 167, 2, 68, 8, 76, 6, 73, 84, - 65, 82, 89, 32, 164, 194, 10, 3, 75, 89, 32, 211, 215, 5, 76, 4, 26, 72, - 219, 181, 12, 77, 2, 135, 178, 4, 69, 24, 42, 73, 76, 2, 85, 83, 207, - 159, 17, 89, 6, 34, 68, 22, 77, 255, 150, 15, 66, 2, 203, 157, 6, 73, 2, - 231, 237, 6, 73, 16, 46, 32, 153, 183, 10, 5, 45, 79, 82, 45, 80, 14, 40, - 4, 83, 73, 71, 78, 159, 183, 13, 84, 13, 11, 32, 10, 44, 5, 87, 73, 84, - 72, 32, 247, 173, 6, 73, 8, 66, 67, 166, 203, 4, 68, 230, 173, 8, 82, 21, - 4, 70, 65, 76, 76, 2, 177, 242, 11, 3, 79, 77, 77, 5, 143, 147, 15, 32, + 65, 82, 89, 32, 216, 189, 10, 3, 75, 89, 32, 211, 215, 5, 76, 4, 26, 72, + 143, 177, 12, 77, 2, 187, 173, 4, 69, 24, 42, 73, 76, 2, 85, 83, 131, + 155, 17, 89, 6, 34, 68, 22, 77, 179, 146, 15, 66, 2, 255, 152, 6, 73, 2, + 155, 233, 6, 73, 16, 46, 32, 205, 178, 10, 5, 45, 79, 82, 45, 80, 14, 40, + 4, 83, 73, 71, 78, 211, 178, 13, 84, 13, 11, 32, 10, 44, 5, 87, 73, 84, + 72, 32, 171, 169, 6, 73, 8, 66, 67, 218, 198, 4, 68, 230, 173, 8, 82, 21, + 4, 70, 65, 76, 76, 2, 229, 237, 11, 3, 79, 77, 77, 5, 195, 142, 15, 32, 186, 9, 184, 1, 10, 66, 73, 76, 69, 32, 80, 72, 79, 78, 69, 166, 1, 68, - 198, 76, 78, 178, 27, 79, 172, 1, 3, 83, 81, 85, 38, 84, 250, 1, 85, 218, - 187, 11, 89, 189, 225, 2, 5, 86, 73, 69, 32, 67, 7, 11, 32, 4, 108, 21, + 198, 76, 78, 178, 27, 79, 172, 1, 3, 83, 81, 85, 38, 84, 250, 1, 85, 142, + 183, 11, 89, 189, 225, 2, 5, 86, 73, 69, 32, 67, 7, 11, 32, 4, 108, 21, 87, 73, 84, 72, 32, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 32, 65, 82, - 82, 79, 87, 195, 178, 1, 79, 2, 11, 32, 2, 173, 232, 16, 2, 65, 84, 156, - 6, 58, 69, 74, 73, 157, 75, 7, 85, 76, 79, 32, 84, 87, 79, 4, 156, 202, + 82, 79, 87, 195, 178, 1, 79, 2, 11, 32, 2, 225, 227, 16, 2, 65, 84, 156, + 6, 58, 69, 74, 73, 157, 75, 7, 85, 76, 79, 32, 84, 87, 79, 4, 208, 197, 16, 10, 82, 78, 32, 80, 69, 78, 84, 65, 84, 72, 159, 18, 76, 150, 6, 42, 32, 221, 1, 5, 70, 73, 69, 82, 32, 158, 1, 88, 5, 83, 73, 71, 78, 32, - 158, 180, 3, 86, 170, 163, 3, 68, 186, 1, 76, 243, 203, 4, 65, 10, 42, - 65, 218, 217, 8, 72, 179, 251, 7, 86, 4, 44, 5, 82, 68, 72, 65, 67, 251, - 210, 16, 78, 2, 161, 211, 16, 3, 65, 78, 68, 248, 4, 92, 12, 66, 82, 69, + 210, 175, 3, 86, 170, 163, 3, 68, 186, 1, 76, 243, 203, 4, 65, 10, 42, + 65, 142, 213, 8, 72, 179, 251, 7, 86, 4, 44, 5, 82, 68, 72, 65, 67, 175, + 206, 16, 78, 2, 213, 206, 16, 3, 65, 78, 68, 248, 4, 92, 12, 66, 82, 69, 86, 69, 32, 87, 73, 84, 72, 32, 73, 89, 7, 76, 69, 84, 84, 69, 82, 32, 2, - 33, 6, 78, 86, 69, 82, 84, 69, 2, 21, 3, 68, 32, 66, 2, 205, 153, 16, 2, + 33, 6, 78, 86, 69, 82, 84, 69, 2, 21, 3, 68, 32, 66, 2, 129, 149, 16, 2, 82, 69, 246, 4, 198, 1, 65, 82, 66, 66, 67, 198, 13, 68, 202, 1, 69, 182, 2, 71, 82, 72, 46, 76, 230, 4, 77, 216, 3, 7, 79, 80, 69, 78, 32, 83, 72, 22, 80, 38, 82, 182, 4, 83, 206, 33, 84, 114, 85, 118, 86, 63, 89, 6, 38, - 76, 166, 27, 67, 227, 209, 10, 80, 2, 253, 19, 6, 86, 69, 79, 76, 65, 82, + 76, 166, 27, 67, 151, 205, 10, 80, 2, 253, 19, 6, 86, 69, 79, 76, 65, 82, 6, 192, 19, 5, 73, 76, 65, 66, 73, 193, 45, 4, 69, 71, 73, 78, 162, 1, 240, 1, 7, 65, 80, 73, 84, 65, 76, 32, 200, 2, 7, 69, 78, 84, 82, 69, 68, 32, 100, 13, 72, 73, 78, 69, 83, 69, 32, 84, 79, 78, 69, 32, 89, 108, 8, - 89, 82, 73, 76, 76, 73, 67, 32, 218, 230, 10, 73, 244, 2, 4, 82, 79, 83, - 83, 219, 211, 5, 79, 58, 214, 1, 66, 42, 82, 130, 27, 72, 186, 157, 13, + 89, 82, 73, 76, 76, 73, 67, 32, 142, 226, 10, 73, 244, 2, 4, 82, 79, 83, + 83, 219, 211, 5, 79, 58, 214, 1, 66, 42, 82, 130, 27, 72, 238, 152, 13, 79, 222, 150, 3, 65, 162, 64, 67, 2, 68, 2, 69, 2, 70, 2, 71, 2, 73, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, 80, 2, 81, 2, 83, 2, 84, 2, 85, 2, 86, - 3, 87, 5, 237, 150, 6, 5, 65, 82, 82, 69, 68, 7, 41, 8, 69, 86, 69, 82, - 83, 69, 68, 32, 4, 134, 143, 17, 69, 3, 78, 4, 30, 76, 21, 3, 82, 73, 71, + 3, 87, 5, 161, 146, 6, 5, 65, 82, 82, 69, 68, 7, 41, 8, 69, 86, 69, 82, + 83, 69, 68, 32, 4, 186, 138, 17, 69, 3, 78, 4, 30, 76, 21, 3, 82, 73, 71, 2, 29, 2, 69, 70, 2, 11, 72, 2, 11, 84, 2, 181, 26, 2, 32, 72, 16, 36, 3, - 65, 78, 71, 1, 2, 73, 78, 8, 11, 32, 8, 166, 145, 12, 83, 170, 171, 4, - 80, 158, 44, 81, 3, 82, 78, 34, 72, 30, 83, 255, 188, 16, 69, 2, 181, - 161, 15, 2, 65, 82, 74, 40, 5, 77, 65, 76, 76, 32, 183, 6, 79, 72, 186, - 1, 66, 138, 1, 68, 38, 69, 150, 1, 80, 58, 83, 94, 84, 34, 89, 226, 134, + 65, 78, 71, 1, 2, 73, 78, 8, 11, 32, 8, 218, 140, 12, 83, 170, 171, 4, + 80, 158, 44, 81, 3, 82, 78, 34, 72, 30, 83, 179, 184, 16, 69, 2, 233, + 156, 15, 2, 65, 82, 74, 40, 5, 77, 65, 76, 76, 32, 183, 6, 79, 72, 186, + 1, 66, 138, 1, 68, 38, 69, 150, 1, 80, 58, 83, 94, 84, 34, 89, 150, 130, 16, 90, 130, 64, 73, 150, 19, 67, 2, 71, 186, 22, 74, 2, 86, 158, 20, 72, - 2, 75, 186, 2, 65, 2, 79, 3, 85, 6, 38, 89, 198, 27, 65, 139, 239, 16, + 2, 75, 186, 2, 65, 2, 79, 3, 85, 6, 38, 89, 198, 27, 65, 191, 234, 16, 69, 2, 237, 202, 1, 19, 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, - 75, 82, 65, 73, 78, 73, 65, 4, 242, 215, 6, 90, 251, 177, 10, 69, 15, 50, - 83, 150, 137, 17, 70, 2, 76, 2, 77, 3, 82, 5, 25, 4, 32, 87, 73, 84, 2, - 21, 3, 72, 32, 68, 2, 11, 69, 2, 253, 156, 13, 3, 83, 67, 69, 4, 26, 65, - 155, 136, 17, 69, 2, 205, 219, 16, 2, 76, 79, 8, 42, 84, 226, 173, 1, 67, - 187, 215, 15, 72, 4, 153, 19, 8, 82, 65, 73, 71, 72, 84, 32, 85, 4, 202, - 240, 16, 83, 215, 22, 69, 6, 36, 3, 69, 82, 85, 219, 134, 17, 85, 5, 37, - 7, 32, 87, 73, 84, 72, 32, 66, 2, 21, 3, 65, 67, 75, 2, 169, 200, 16, 2, - 32, 89, 2, 175, 186, 11, 70, 16, 18, 69, 27, 79, 2, 169, 5, 2, 78, 84, - 14, 64, 2, 84, 32, 52, 5, 85, 66, 76, 69, 32, 129, 52, 2, 87, 78, 6, 162, - 224, 9, 83, 210, 202, 4, 86, 247, 181, 1, 72, 4, 210, 137, 2, 65, 231, - 248, 2, 80, 24, 40, 5, 88, 84, 82, 65, 45, 131, 49, 78, 20, 52, 5, 72, + 75, 82, 65, 73, 78, 73, 65, 4, 166, 211, 6, 90, 251, 177, 10, 69, 15, 50, + 83, 202, 132, 17, 70, 2, 76, 2, 77, 3, 82, 5, 25, 4, 32, 87, 73, 84, 2, + 21, 3, 72, 32, 68, 2, 11, 69, 2, 177, 152, 13, 3, 83, 67, 69, 4, 26, 65, + 207, 131, 17, 69, 2, 129, 215, 16, 2, 76, 79, 8, 42, 84, 226, 173, 1, 67, + 239, 210, 15, 72, 4, 153, 19, 8, 82, 65, 73, 71, 72, 84, 32, 85, 4, 254, + 235, 16, 83, 215, 22, 69, 6, 36, 3, 69, 82, 85, 143, 130, 17, 85, 5, 37, + 7, 32, 87, 73, 84, 72, 32, 66, 2, 21, 3, 65, 67, 75, 2, 221, 195, 16, 2, + 32, 89, 2, 227, 181, 11, 70, 16, 18, 69, 27, 79, 2, 169, 5, 2, 78, 84, + 14, 64, 2, 84, 32, 52, 5, 85, 66, 76, 69, 32, 129, 52, 2, 87, 78, 6, 214, + 219, 9, 83, 210, 202, 4, 86, 247, 181, 1, 72, 4, 210, 137, 2, 65, 155, + 244, 2, 80, 24, 40, 5, 88, 84, 82, 65, 45, 131, 49, 78, 20, 52, 5, 72, 73, 71, 72, 32, 81, 4, 76, 79, 87, 32, 10, 156, 1, 9, 69, 88, 84, 82, 65, 45, 76, 79, 87, 154, 7, 68, 70, 76, 79, 84, 10, 76, 10, 69, 88, 84, 82, 65, 45, 72, 73, 71, 72, 154, 7, 68, 70, 76, 79, 84, 2, 145, 8, 8, 32, 67, - 79, 78, 84, 79, 85, 82, 8, 162, 9, 82, 226, 3, 76, 173, 209, 15, 9, 69, + 79, 78, 84, 79, 85, 82, 8, 162, 9, 82, 226, 3, 76, 225, 204, 15, 9, 69, 79, 82, 71, 73, 65, 78, 32, 78, 10, 248, 5, 4, 73, 71, 72, 32, 255, 40, 65, 44, 46, 65, 84, 2, 79, 87, 201, 11, 2, 69, 70, 2, 21, 3, 84, 69, 82, - 2, 17, 2, 65, 76, 2, 17, 2, 32, 67, 2, 239, 205, 15, 76, 36, 86, 32, 133, - 151, 12, 15, 69, 82, 32, 82, 73, 71, 72, 84, 32, 67, 79, 82, 78, 69, 82, + 2, 17, 2, 65, 76, 2, 17, 2, 32, 67, 2, 163, 201, 15, 76, 36, 86, 32, 185, + 146, 12, 15, 69, 82, 32, 82, 73, 71, 72, 84, 32, 67, 79, 82, 78, 69, 82, 34, 158, 1, 67, 20, 2, 68, 79, 40, 4, 76, 69, 70, 84, 82, 77, 12, 2, 82, - 73, 50, 84, 178, 3, 65, 42, 71, 170, 2, 73, 172, 157, 14, 2, 85, 80, 255, - 188, 1, 86, 2, 175, 215, 10, 73, 6, 238, 2, 84, 241, 161, 14, 2, 87, 78, - 6, 28, 2, 32, 65, 247, 2, 45, 4, 25, 4, 82, 82, 79, 87, 5, 187, 164, 14, - 72, 2, 111, 65, 4, 216, 163, 14, 3, 71, 72, 84, 175, 216, 2, 78, 4, 194, - 2, 79, 219, 220, 14, 73, 18, 18, 65, 23, 73, 2, 195, 212, 15, 67, 16, 26, - 68, 179, 201, 13, 78, 14, 38, 32, 217, 1, 4, 68, 76, 69, 32, 8, 26, 68, + 73, 50, 84, 178, 3, 65, 42, 71, 170, 2, 73, 224, 152, 14, 2, 85, 80, 255, + 188, 1, 86, 2, 227, 210, 10, 73, 6, 238, 2, 84, 165, 157, 14, 2, 87, 78, + 6, 28, 2, 32, 65, 247, 2, 45, 4, 25, 4, 82, 82, 79, 87, 5, 239, 159, 14, + 72, 2, 111, 65, 4, 140, 159, 14, 3, 71, 72, 84, 175, 216, 2, 78, 4, 194, + 2, 79, 143, 216, 14, 73, 18, 18, 65, 23, 73, 2, 247, 207, 15, 67, 16, 26, + 68, 231, 196, 13, 78, 14, 38, 32, 217, 1, 4, 68, 76, 69, 32, 8, 26, 68, 70, 76, 79, 84, 4, 17, 2, 79, 84, 4, 25, 4, 84, 69, 68, 32, 4, 18, 76, 79, 84, 2, 25, 4, 69, 70, 84, 45, 2, 25, 4, 83, 84, 69, 77, 2, 17, 2, 32, - 84, 2, 11, 79, 2, 11, 78, 2, 135, 214, 15, 69, 6, 40, 6, 68, 79, 85, 66, - 76, 69, 75, 71, 4, 11, 32, 4, 18, 65, 43, 71, 2, 11, 67, 2, 145, 213, 10, - 2, 85, 84, 2, 11, 82, 2, 223, 212, 10, 65, 2, 171, 242, 14, 69, 4, 134, - 198, 13, 76, 159, 152, 2, 82, 26, 104, 6, 65, 73, 83, 69, 68, 32, 150, 1, - 69, 216, 1, 3, 73, 71, 72, 193, 250, 8, 5, 72, 79, 84, 73, 67, 10, 70, - 68, 30, 73, 214, 218, 9, 69, 128, 255, 5, 2, 85, 80, 215, 76, 67, 2, 197, - 163, 15, 2, 79, 87, 2, 189, 218, 9, 7, 78, 86, 69, 82, 84, 69, 68, 8, + 84, 2, 11, 79, 2, 11, 78, 2, 187, 209, 15, 69, 6, 40, 6, 68, 79, 85, 66, + 76, 69, 75, 71, 4, 11, 32, 4, 18, 65, 43, 71, 2, 11, 67, 2, 197, 208, 10, + 2, 85, 84, 2, 11, 82, 2, 147, 208, 10, 65, 2, 223, 237, 14, 69, 4, 186, + 193, 13, 76, 159, 152, 2, 82, 26, 104, 6, 65, 73, 83, 69, 68, 32, 150, 1, + 69, 216, 1, 3, 73, 71, 72, 245, 245, 8, 5, 72, 79, 84, 73, 67, 10, 70, + 68, 30, 73, 138, 214, 9, 69, 128, 255, 5, 2, 85, 80, 215, 76, 67, 2, 249, + 158, 15, 2, 79, 87, 2, 241, 213, 9, 7, 78, 86, 69, 82, 84, 69, 68, 8, 104, 7, 86, 69, 82, 83, 69, 68, 32, 137, 28, 14, 84, 82, 79, 70, 76, 69, - 88, 32, 67, 76, 73, 67, 75, 32, 6, 26, 71, 163, 159, 14, 67, 4, 11, 76, + 88, 32, 67, 76, 73, 67, 75, 32, 6, 26, 71, 215, 154, 14, 67, 4, 11, 76, 4, 49, 10, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 5, 171, 19, 32, 6, 17, - 2, 84, 32, 6, 38, 72, 150, 213, 13, 84, 239, 69, 65, 2, 197, 196, 7, 3, + 2, 84, 32, 6, 38, 72, 202, 208, 13, 84, 239, 69, 65, 2, 249, 191, 7, 3, 65, 76, 70, 156, 2, 138, 1, 72, 48, 5, 77, 65, 76, 76, 32, 148, 31, 8, 84, 82, 69, 83, 83, 32, 65, 78, 53, 11, 85, 80, 69, 82, 83, 67, 82, 73, - 80, 84, 32, 4, 180, 158, 8, 3, 79, 82, 84, 251, 205, 6, 69, 144, 2, 154, + 80, 84, 32, 4, 232, 153, 8, 3, 79, 82, 84, 251, 205, 6, 69, 144, 2, 154, 2, 65, 50, 66, 130, 1, 67, 238, 2, 68, 238, 2, 90, 66, 69, 46, 70, 30, 71, 110, 72, 102, 77, 34, 73, 34, 74, 98, 76, 176, 3, 7, 78, 32, 87, 73, 84, 72, 32, 30, 79, 94, 80, 22, 82, 146, 2, 83, 190, 1, 84, 246, 7, 85, - 142, 1, 86, 226, 211, 16, 75, 2, 81, 2, 87, 2, 88, 3, 89, 9, 222, 147, + 142, 1, 86, 150, 207, 16, 75, 2, 81, 2, 87, 2, 88, 3, 89, 9, 146, 143, 13, 76, 170, 140, 3, 73, 227, 79, 69, 11, 46, 65, 50, 79, 222, 8, 32, - 179, 193, 16, 69, 2, 17, 2, 82, 82, 2, 169, 247, 5, 2, 69, 68, 2, 229, + 231, 188, 16, 69, 2, 17, 2, 82, 82, 2, 221, 242, 5, 2, 69, 68, 2, 229, 20, 4, 84, 84, 79, 77, 41, 100, 7, 65, 80, 73, 84, 65, 76, 32, 180, 1, 6, - 76, 79, 83, 69, 68, 32, 190, 17, 32, 139, 199, 16, 72, 30, 114, 73, 214, - 6, 71, 226, 16, 76, 214, 190, 16, 79, 158, 20, 65, 186, 2, 66, 2, 72, 2, - 78, 2, 82, 2, 85, 3, 89, 7, 22, 78, 191, 11, 32, 2, 225, 240, 5, 5, 86, - 69, 82, 84, 69, 4, 26, 82, 243, 166, 9, 79, 2, 217, 20, 9, 69, 86, 69, + 76, 79, 83, 69, 68, 32, 190, 17, 32, 191, 194, 16, 72, 30, 114, 73, 214, + 6, 71, 226, 16, 76, 138, 186, 16, 79, 158, 20, 65, 186, 2, 66, 2, 72, 2, + 78, 2, 82, 2, 85, 3, 89, 7, 22, 78, 191, 11, 32, 2, 149, 236, 5, 5, 86, + 69, 82, 84, 69, 4, 26, 82, 167, 162, 9, 79, 2, 217, 20, 9, 69, 86, 69, 82, 83, 69, 68, 32, 79, 23, 104, 6, 32, 87, 73, 84, 72, 32, 86, 69, 32, 9, 79, 84, 76, 69, 83, 83, 32, 74, 32, 105, 3, 90, 32, 68, 6, 26, 72, - 163, 179, 14, 84, 4, 21, 3, 79, 79, 75, 5, 213, 250, 13, 3, 32, 65, 78, - 4, 238, 15, 90, 211, 181, 16, 76, 4, 33, 6, 87, 73, 84, 72, 32, 83, 4, - 29, 5, 84, 82, 79, 75, 69, 5, 193, 239, 8, 4, 32, 65, 78, 68, 6, 33, 6, + 215, 174, 14, 84, 4, 21, 3, 79, 79, 75, 5, 137, 246, 13, 3, 32, 65, 78, + 4, 238, 15, 90, 135, 177, 16, 76, 4, 33, 6, 87, 73, 84, 72, 32, 83, 4, + 29, 5, 84, 82, 79, 75, 69, 5, 245, 234, 8, 4, 32, 65, 78, 68, 6, 33, 6, 73, 71, 82, 65, 80, 72, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 138, 14, 67, - 207, 4, 82, 11, 142, 231, 16, 83, 2, 84, 2, 90, 63, 78, 5, 225, 13, 3, - 69, 78, 71, 11, 56, 5, 82, 69, 69, 75, 32, 162, 1, 32, 183, 144, 14, 65, - 4, 26, 71, 139, 143, 11, 80, 2, 183, 145, 14, 65, 11, 40, 6, 32, 87, 73, - 84, 72, 32, 39, 69, 4, 206, 144, 15, 72, 247, 165, 1, 83, 4, 17, 2, 78, - 71, 5, 11, 32, 2, 255, 235, 8, 87, 4, 222, 4, 32, 191, 188, 16, 79, 5, - 37, 7, 32, 87, 73, 84, 72, 32, 67, 2, 11, 82, 2, 225, 173, 14, 6, 79, 83, + 207, 4, 82, 11, 194, 226, 16, 83, 2, 84, 2, 90, 63, 78, 5, 225, 13, 3, + 69, 78, 71, 11, 56, 5, 82, 69, 69, 75, 32, 162, 1, 32, 235, 139, 14, 65, + 4, 26, 71, 191, 138, 11, 80, 2, 235, 140, 14, 65, 11, 40, 6, 32, 87, 73, + 84, 72, 32, 39, 69, 4, 130, 140, 15, 72, 247, 165, 1, 83, 4, 17, 2, 78, + 71, 5, 11, 32, 2, 179, 231, 8, 87, 4, 222, 4, 32, 243, 183, 16, 79, 5, + 37, 7, 32, 87, 73, 84, 72, 32, 67, 2, 11, 82, 2, 149, 169, 14, 6, 79, 83, 83, 69, 68, 45, 25, 116, 6, 32, 87, 73, 84, 72, 32, 226, 9, 83, 2, 90, - 112, 2, 69, 90, 193, 194, 16, 8, 73, 71, 65, 84, 85, 82, 69, 32, 12, 54, - 73, 82, 77, 82, 82, 222, 6, 80, 143, 245, 3, 66, 2, 49, 10, 78, 86, 69, - 82, 84, 69, 68, 32, 76, 65, 2, 157, 233, 12, 2, 90, 89, 2, 11, 73, 2, 17, - 2, 68, 68, 2, 17, 2, 76, 69, 2, 221, 250, 12, 2, 32, 84, 4, 61, 13, 69, + 112, 2, 69, 90, 245, 189, 16, 8, 73, 71, 65, 84, 85, 82, 69, 32, 12, 54, + 73, 82, 77, 82, 82, 222, 6, 80, 195, 240, 3, 66, 2, 49, 10, 78, 86, 69, + 82, 84, 69, 68, 32, 76, 65, 2, 209, 228, 12, 2, 90, 89, 2, 11, 73, 2, 17, + 2, 68, 68, 2, 17, 2, 76, 69, 2, 145, 246, 12, 2, 32, 84, 4, 61, 13, 69, 84, 82, 79, 70, 76, 69, 88, 32, 72, 79, 79, 75, 5, 205, 12, 4, 32, 65, 78, 68, 4, 210, 11, 82, 207, 1, 76, 9, 18, 32, 47, 80, 2, 21, 3, 87, 73, - 84, 2, 219, 176, 16, 72, 4, 229, 196, 12, 2, 69, 78, 5, 231, 204, 16, 72, + 84, 2, 143, 172, 16, 72, 4, 153, 192, 12, 2, 69, 78, 5, 155, 200, 16, 72, 15, 80, 6, 32, 87, 73, 84, 72, 32, 62, 65, 41, 8, 69, 86, 69, 82, 83, 69, - 68, 32, 4, 26, 70, 155, 168, 14, 84, 2, 225, 229, 8, 3, 73, 83, 72, 2, - 17, 2, 77, 83, 2, 235, 232, 5, 32, 6, 38, 71, 170, 7, 79, 167, 215, 16, - 69, 2, 11, 76, 2, 161, 137, 14, 4, 79, 84, 84, 65, 13, 72, 6, 32, 87, 73, - 84, 72, 32, 34, 67, 61, 6, 73, 68, 69, 87, 65, 89, 4, 158, 3, 67, 195, - 132, 15, 72, 4, 26, 82, 187, 227, 11, 72, 2, 209, 219, 5, 3, 73, 80, 84, - 2, 159, 194, 6, 83, 51, 106, 32, 102, 67, 116, 2, 69, 83, 44, 2, 79, 80, - 42, 83, 96, 6, 85, 82, 78, 69, 68, 32, 215, 155, 13, 72, 4, 29, 5, 87, - 73, 84, 72, 32, 4, 22, 80, 219, 5, 82, 2, 213, 225, 8, 6, 65, 76, 65, 84, + 68, 32, 4, 26, 70, 207, 163, 14, 84, 2, 149, 225, 8, 3, 73, 83, 72, 2, + 17, 2, 77, 83, 2, 159, 228, 5, 32, 6, 38, 71, 170, 7, 79, 219, 210, 16, + 69, 2, 11, 76, 2, 213, 132, 14, 4, 79, 84, 84, 65, 13, 72, 6, 32, 87, 73, + 84, 72, 32, 34, 67, 61, 6, 73, 68, 69, 87, 65, 89, 4, 158, 3, 67, 247, + 255, 14, 72, 4, 26, 82, 239, 222, 11, 72, 2, 133, 215, 5, 3, 73, 80, 84, + 2, 211, 189, 6, 83, 51, 106, 32, 102, 67, 116, 2, 69, 83, 44, 2, 79, 80, + 42, 83, 96, 6, 85, 82, 78, 69, 68, 32, 139, 151, 13, 72, 4, 29, 5, 87, + 73, 84, 72, 32, 4, 22, 80, 219, 5, 82, 2, 137, 221, 8, 6, 65, 76, 65, 84, 65, 76, 2, 45, 9, 32, 68, 73, 71, 82, 65, 80, 72, 32, 2, 25, 4, 87, 73, - 84, 72, 2, 17, 2, 32, 67, 2, 175, 145, 3, 85, 2, 11, 72, 2, 189, 155, 10, - 3, 32, 68, 73, 2, 165, 226, 5, 5, 32, 72, 65, 76, 70, 4, 37, 7, 32, 68, + 84, 72, 2, 17, 2, 32, 67, 2, 227, 140, 3, 85, 2, 11, 72, 2, 241, 150, 10, + 3, 32, 68, 73, 2, 217, 221, 5, 5, 32, 72, 65, 76, 70, 4, 37, 7, 32, 68, 73, 71, 82, 65, 80, 4, 11, 72, 5, 11, 32, 2, 141, 3, 4, 87, 73, 84, 72, - 32, 86, 65, 38, 77, 74, 79, 42, 82, 214, 1, 89, 170, 213, 16, 72, 2, 73, - 2, 86, 3, 87, 7, 134, 252, 12, 76, 139, 220, 3, 69, 5, 41, 8, 32, 87, 73, - 84, 72, 32, 76, 79, 2, 253, 141, 4, 2, 78, 71, 2, 11, 80, 2, 225, 158, 6, - 2, 69, 78, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 26, 76, 207, 128, 15, 72, + 32, 86, 65, 38, 77, 74, 79, 42, 82, 214, 1, 89, 222, 208, 16, 72, 2, 73, + 2, 86, 3, 87, 7, 186, 247, 12, 76, 139, 220, 3, 69, 5, 41, 8, 32, 87, 73, + 84, 72, 32, 76, 79, 2, 177, 137, 4, 2, 78, 71, 2, 11, 80, 2, 149, 154, 6, + 2, 69, 78, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 26, 76, 131, 252, 14, 72, 4, 37, 7, 79, 78, 71, 32, 76, 69, 71, 5, 25, 4, 32, 65, 78, 68, 2, 17, 2, - 32, 82, 2, 11, 69, 2, 241, 219, 8, 7, 84, 82, 79, 70, 76, 69, 88, 5, 29, - 5, 32, 87, 73, 84, 72, 2, 213, 238, 3, 2, 32, 66, 9, 18, 32, 95, 80, 4, - 40, 4, 87, 73, 84, 72, 243, 176, 15, 66, 2, 17, 2, 32, 76, 2, 11, 69, 2, - 131, 1, 70, 2, 129, 132, 16, 2, 83, 73, 7, 33, 6, 32, 87, 73, 84, 72, 32, - 4, 26, 82, 179, 253, 14, 72, 2, 21, 3, 73, 71, 72, 2, 163, 217, 8, 84, 4, + 32, 82, 2, 11, 69, 2, 165, 215, 8, 7, 84, 82, 79, 70, 76, 69, 88, 5, 29, + 5, 32, 87, 73, 84, 72, 2, 137, 234, 3, 2, 32, 66, 9, 18, 32, 95, 80, 4, + 40, 4, 87, 73, 84, 72, 167, 172, 15, 66, 2, 17, 2, 32, 76, 2, 11, 69, 2, + 131, 1, 70, 2, 181, 255, 15, 2, 83, 73, 7, 33, 6, 32, 87, 73, 84, 72, 32, + 4, 26, 82, 231, 248, 14, 72, 2, 21, 3, 73, 71, 72, 2, 215, 212, 8, 84, 4, 11, 68, 4, 11, 32, 4, 146, 210, 1, 72, 35, 76, 4, 24, 2, 72, 65, 31, 84, 2, 25, 4, 76, 70, 32, 84, 2, 43, 82, 4, 30, 82, 53, 3, 85, 82, 78, 2, - 189, 129, 16, 8, 73, 65, 78, 71, 85, 76, 65, 82, 2, 169, 172, 8, 2, 69, - 68, 8, 70, 80, 184, 159, 10, 7, 78, 65, 83, 80, 73, 82, 65, 143, 177, 6, - 83, 4, 11, 32, 4, 226, 177, 13, 84, 239, 69, 65, 4, 26, 79, 135, 180, 15, - 69, 2, 11, 73, 2, 235, 254, 15, 67, 4, 36, 3, 65, 78, 71, 1, 2, 73, 78, + 241, 252, 15, 8, 73, 65, 78, 71, 85, 76, 65, 82, 2, 221, 167, 8, 2, 69, + 68, 8, 70, 80, 236, 154, 10, 7, 78, 65, 83, 80, 73, 82, 65, 143, 177, 6, + 83, 4, 11, 32, 4, 150, 173, 13, 84, 239, 69, 65, 4, 26, 79, 187, 175, 15, + 69, 2, 11, 73, 2, 159, 250, 15, 67, 4, 36, 3, 65, 78, 71, 1, 2, 73, 78, 2, 25, 4, 32, 68, 69, 80, 2, 21, 3, 65, 82, 84, 2, 21, 3, 73, 78, 71, 2, - 17, 2, 32, 84, 2, 11, 79, 2, 171, 135, 6, 78, 2, 11, 32, 2, 131, 163, 15, + 17, 2, 32, 84, 2, 11, 79, 2, 223, 130, 6, 78, 2, 11, 32, 2, 183, 158, 15, 83, 234, 2, 92, 2, 69, 89, 88, 7, 71, 79, 76, 73, 65, 78, 32, 206, 24, - 79, 209, 140, 12, 3, 75, 69, 89, 6, 26, 32, 203, 143, 16, 45, 4, 128, - 142, 12, 6, 87, 73, 84, 72, 32, 87, 167, 211, 2, 66, 214, 2, 194, 2, 68, + 79, 133, 136, 12, 3, 75, 69, 89, 6, 26, 32, 255, 138, 16, 45, 4, 180, + 137, 12, 6, 87, 73, 84, 72, 32, 87, 167, 211, 2, 66, 214, 2, 194, 2, 68, 46, 70, 148, 1, 14, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 73, 82, 71, 65, 16, 7, 76, 69, 84, 84, 69, 82, 32, 138, 16, 83, 132, 1, 7, 82, 79, - 84, 65, 84, 69, 68, 22, 66, 98, 84, 160, 2, 4, 86, 79, 87, 69, 194, 241, + 84, 65, 84, 69, 68, 22, 66, 98, 84, 160, 2, 4, 86, 79, 87, 69, 246, 236, 3, 67, 164, 1, 6, 77, 65, 78, 67, 72, 85, 160, 201, 7, 4, 78, 73, 82, 85, - 239, 208, 2, 69, 22, 232, 20, 3, 79, 85, 66, 171, 193, 14, 73, 12, 112, + 239, 208, 2, 69, 22, 232, 20, 3, 79, 85, 66, 223, 188, 14, 73, 12, 112, 19, 82, 69, 69, 32, 86, 65, 82, 73, 65, 84, 73, 79, 78, 32, 83, 69, 76, - 69, 67, 202, 243, 13, 85, 195, 46, 79, 8, 177, 250, 9, 3, 84, 79, 82, 5, + 69, 67, 254, 238, 13, 85, 195, 46, 79, 8, 229, 245, 9, 3, 84, 79, 82, 5, 227, 19, 32, 136, 2, 130, 2, 65, 244, 4, 2, 67, 72, 88, 2, 77, 65, 174, - 2, 83, 246, 1, 84, 234, 3, 90, 178, 195, 14, 72, 246, 173, 1, 75, 2, 76, + 2, 83, 246, 1, 84, 234, 3, 90, 230, 190, 14, 72, 246, 173, 1, 75, 2, 76, 162, 7, 69, 2, 79, 2, 85, 234, 61, 66, 2, 68, 2, 70, 2, 71, 2, 74, 2, 78, 2, 80, 2, 81, 2, 82, 2, 87, 2, 89, 187, 2, 73, 59, 56, 8, 76, 73, 32, 71, - 65, 76, 73, 32, 171, 197, 16, 78, 54, 174, 1, 65, 52, 6, 86, 73, 83, 65, + 65, 76, 73, 32, 223, 192, 16, 78, 54, 174, 1, 65, 52, 6, 86, 73, 83, 65, 82, 71, 22, 68, 76, 5, 72, 65, 76, 70, 32, 34, 73, 50, 85, 34, 78, 30, - 84, 66, 66, 174, 250, 15, 80, 2, 90, 254, 68, 83, 14, 67, 3, 75, 7, 48, - 6, 78, 85, 83, 86, 65, 82, 155, 196, 16, 72, 2, 243, 165, 9, 65, 8, 26, - 65, 179, 193, 16, 68, 7, 166, 253, 8, 77, 253, 131, 7, 3, 71, 65, 76, 4, - 254, 192, 16, 89, 187, 2, 85, 5, 45, 9, 78, 86, 69, 82, 84, 69, 68, 32, - 85, 2, 249, 255, 15, 3, 66, 65, 68, 4, 142, 192, 16, 71, 3, 78, 8, 60, 6, - 72, 82, 69, 69, 32, 66, 174, 250, 15, 84, 195, 71, 65, 2, 17, 2, 65, 76, - 2, 211, 156, 16, 85, 6, 26, 65, 171, 193, 16, 73, 5, 29, 5, 32, 87, 73, - 84, 72, 2, 149, 238, 14, 2, 32, 84, 41, 29, 5, 78, 67, 72, 85, 32, 38, - 104, 9, 65, 76, 73, 32, 71, 65, 76, 73, 32, 186, 194, 14, 90, 242, 250, - 1, 70, 2, 75, 2, 82, 187, 2, 73, 28, 122, 68, 194, 198, 9, 67, 246, 227, + 84, 66, 66, 226, 245, 15, 80, 2, 90, 254, 68, 83, 14, 67, 3, 75, 7, 48, + 6, 78, 85, 83, 86, 65, 82, 207, 191, 16, 72, 2, 167, 161, 9, 65, 8, 26, + 65, 231, 188, 16, 68, 7, 218, 248, 8, 77, 253, 131, 7, 3, 71, 65, 76, 4, + 178, 188, 16, 89, 187, 2, 85, 5, 45, 9, 78, 86, 69, 82, 84, 69, 68, 32, + 85, 2, 173, 251, 15, 3, 66, 65, 68, 4, 194, 187, 16, 71, 3, 78, 8, 60, 6, + 72, 82, 69, 69, 32, 66, 226, 245, 15, 84, 195, 71, 65, 2, 17, 2, 65, 76, + 2, 135, 152, 16, 85, 6, 26, 65, 223, 188, 16, 73, 5, 29, 5, 32, 87, 73, + 84, 72, 2, 201, 233, 14, 2, 32, 84, 41, 29, 5, 78, 67, 72, 85, 32, 38, + 104, 9, 65, 76, 73, 32, 71, 65, 76, 73, 32, 238, 189, 14, 90, 242, 250, + 1, 70, 2, 75, 2, 82, 187, 2, 73, 28, 122, 68, 246, 193, 9, 67, 246, 227, 2, 84, 138, 151, 2, 66, 2, 71, 2, 74, 2, 76, 234, 181, 1, 90, 254, 4, 78, - 131, 64, 83, 4, 186, 193, 14, 68, 243, 250, 1, 72, 48, 52, 4, 73, 66, 69, - 32, 210, 187, 16, 72, 187, 2, 65, 44, 214, 222, 5, 71, 2, 72, 170, 202, + 131, 64, 83, 4, 238, 188, 14, 68, 243, 250, 1, 72, 48, 52, 4, 73, 66, 69, + 32, 134, 183, 16, 72, 187, 2, 65, 44, 138, 218, 5, 71, 2, 72, 170, 202, 6, 84, 238, 3, 73, 246, 147, 2, 67, 2, 83, 246, 7, 82, 190, 164, 1, 65, 186, 9, 90, 162, 7, 85, 234, 61, 68, 2, 70, 2, 74, 2, 75, 2, 80, 187, 2, - 69, 60, 52, 4, 79, 68, 79, 32, 222, 185, 16, 83, 187, 2, 65, 56, 250, 1, + 69, 60, 52, 4, 79, 68, 79, 32, 146, 181, 16, 83, 187, 2, 65, 56, 250, 1, 65, 98, 68, 34, 74, 34, 78, 252, 164, 1, 8, 76, 79, 78, 71, 32, 86, 79, - 87, 206, 180, 4, 71, 170, 202, 6, 84, 226, 151, 2, 67, 246, 7, 72, 150, + 87, 130, 176, 4, 71, 170, 202, 6, 84, 226, 151, 2, 67, 246, 7, 72, 150, 181, 1, 79, 2, 85, 234, 61, 66, 2, 75, 2, 77, 2, 80, 2, 81, 2, 87, 2, 89, - 186, 2, 69, 3, 73, 6, 56, 8, 76, 73, 32, 71, 65, 76, 73, 32, 139, 185, - 16, 78, 4, 178, 188, 14, 90, 243, 250, 1, 84, 4, 254, 182, 16, 90, 187, - 2, 65, 4, 222, 182, 16, 73, 187, 2, 65, 2, 191, 182, 16, 73, 6, 138, 165, - 16, 72, 162, 17, 82, 187, 2, 65, 8, 128, 1, 4, 87, 73, 82, 76, 217, 191, + 186, 2, 69, 3, 73, 6, 56, 8, 76, 73, 32, 71, 65, 76, 73, 32, 191, 180, + 16, 78, 4, 230, 183, 14, 90, 243, 250, 1, 84, 4, 178, 178, 16, 90, 187, + 2, 65, 4, 146, 178, 16, 73, 187, 2, 65, 2, 243, 177, 16, 73, 6, 190, 160, + 16, 72, 162, 17, 82, 187, 2, 65, 8, 128, 1, 4, 87, 73, 82, 76, 141, 187, 4, 21, 73, 66, 69, 32, 83, 89, 76, 76, 65, 66, 76, 69, 32, 66, 79, 85, 78, 68, 65, 82, 89, 6, 17, 2, 32, 66, 6, 25, 4, 73, 82, 71, 65, 7, 33, 6, - 32, 87, 73, 84, 72, 32, 4, 150, 2, 68, 255, 240, 15, 79, 6, 152, 1, 3, + 32, 87, 73, 84, 72, 32, 4, 150, 2, 68, 179, 236, 15, 79, 6, 152, 1, 3, 82, 73, 80, 56, 18, 85, 82, 78, 69, 68, 32, 83, 87, 73, 82, 76, 32, 66, 73, 82, 71, 65, 32, 217, 192, 1, 8, 79, 68, 79, 32, 83, 79, 70, 84, 2, - 165, 241, 15, 9, 76, 69, 32, 66, 73, 82, 71, 65, 32, 2, 33, 6, 87, 73, - 84, 72, 32, 68, 2, 229, 240, 15, 5, 79, 85, 66, 76, 69, 2, 135, 235, 9, + 217, 236, 15, 9, 76, 69, 32, 66, 73, 82, 71, 65, 32, 2, 33, 6, 87, 73, + 84, 72, 32, 68, 2, 153, 236, 15, 5, 79, 85, 66, 76, 69, 2, 187, 230, 9, 76, 10, 84, 9, 71, 82, 65, 77, 32, 70, 79, 82, 32, 60, 4, 83, 84, 65, 66, - 215, 251, 13, 82, 6, 26, 89, 179, 198, 12, 69, 4, 158, 226, 15, 65, 155, - 1, 73, 2, 171, 132, 4, 76, 10, 48, 2, 78, 32, 250, 210, 4, 68, 231, 200, - 11, 83, 6, 88, 12, 86, 73, 69, 87, 73, 78, 71, 32, 67, 69, 82, 69, 174, - 197, 12, 67, 85, 2, 76, 65, 2, 249, 145, 16, 2, 77, 79, 4, 174, 190, 12, + 139, 247, 13, 82, 6, 26, 89, 231, 193, 12, 69, 4, 210, 221, 15, 65, 155, + 1, 73, 2, 223, 255, 3, 76, 10, 48, 2, 78, 32, 174, 206, 4, 68, 231, 200, + 11, 83, 6, 88, 12, 86, 73, 69, 87, 73, 78, 71, 32, 67, 69, 82, 69, 226, + 192, 12, 67, 85, 2, 76, 65, 2, 173, 141, 16, 2, 77, 79, 4, 226, 185, 12, 73, 139, 243, 3, 69, 10, 26, 72, 69, 2, 79, 82, 2, 45, 9, 69, 82, 32, 67, - 72, 82, 73, 83, 84, 2, 243, 254, 2, 77, 8, 50, 32, 52, 4, 73, 90, 69, 68, - 175, 161, 15, 87, 4, 150, 202, 8, 66, 221, 171, 6, 4, 83, 67, 79, 79, 2, - 209, 176, 3, 7, 32, 87, 72, 69, 69, 76, 67, 18, 52, 2, 78, 84, 152, 1, 2, - 83, 69, 191, 172, 16, 84, 10, 48, 3, 65, 73, 78, 169, 142, 12, 3, 32, 70, - 85, 9, 11, 32, 6, 186, 207, 9, 82, 24, 5, 67, 65, 66, 76, 69, 177, 241, - 1, 6, 66, 73, 67, 89, 67, 76, 7, 11, 32, 4, 180, 154, 15, 2, 84, 82, 131, - 86, 70, 86, 52, 7, 76, 69, 84, 84, 69, 82, 32, 231, 235, 5, 68, 62, 198, - 1, 75, 62, 77, 34, 78, 34, 79, 30, 80, 34, 84, 242, 105, 68, 212, 133, 8, + 72, 82, 73, 83, 84, 2, 167, 250, 2, 77, 8, 50, 32, 52, 4, 73, 90, 69, 68, + 227, 156, 15, 87, 4, 202, 197, 8, 66, 221, 171, 6, 4, 83, 67, 79, 79, 2, + 133, 172, 3, 7, 32, 87, 72, 69, 69, 76, 67, 18, 52, 2, 78, 84, 152, 1, 2, + 83, 69, 243, 167, 16, 84, 10, 48, 3, 65, 73, 78, 221, 137, 12, 3, 32, 70, + 85, 9, 11, 32, 6, 238, 202, 9, 82, 24, 5, 67, 65, 66, 76, 69, 177, 241, + 1, 6, 66, 73, 67, 89, 67, 76, 7, 11, 32, 4, 232, 149, 15, 2, 84, 82, 131, + 86, 70, 86, 52, 7, 76, 69, 84, 84, 69, 82, 32, 155, 231, 5, 68, 62, 198, + 1, 75, 62, 77, 34, 78, 34, 79, 30, 80, 34, 84, 242, 105, 68, 136, 129, 8, 2, 72, 65, 2, 82, 166, 226, 1, 83, 190, 89, 76, 246, 7, 67, 218, 100, 69, - 254, 242, 3, 89, 190, 28, 66, 2, 87, 187, 2, 65, 6, 160, 174, 5, 2, 69, - 65, 178, 137, 6, 72, 199, 243, 4, 79, 4, 174, 152, 16, 65, 215, 1, 73, 4, - 218, 218, 15, 73, 139, 60, 71, 7, 154, 170, 16, 76, 3, 79, 4, 166, 150, - 16, 72, 219, 19, 65, 6, 222, 149, 9, 72, 234, 144, 7, 69, 155, 3, 65, - 206, 4, 44, 2, 76, 84, 234, 6, 83, 247, 139, 14, 67, 102, 36, 4, 65, 78, - 73, 32, 219, 2, 73, 76, 52, 7, 76, 69, 84, 84, 69, 82, 32, 151, 149, 4, - 83, 74, 206, 1, 68, 234, 83, 78, 194, 236, 1, 82, 254, 208, 9, 74, 202, + 254, 242, 3, 89, 190, 28, 66, 2, 87, 187, 2, 65, 6, 212, 169, 5, 2, 69, + 65, 178, 137, 6, 72, 199, 243, 4, 79, 4, 226, 147, 16, 65, 215, 1, 73, 4, + 142, 214, 15, 73, 139, 60, 71, 7, 206, 165, 16, 76, 3, 79, 4, 218, 145, + 16, 72, 219, 19, 65, 6, 146, 145, 9, 72, 234, 144, 7, 69, 155, 3, 65, + 206, 4, 44, 2, 76, 84, 234, 6, 83, 171, 135, 14, 67, 102, 36, 4, 65, 78, + 73, 32, 219, 2, 73, 76, 52, 7, 76, 69, 84, 84, 69, 82, 32, 203, 144, 4, + 83, 74, 206, 1, 68, 234, 83, 78, 246, 231, 1, 82, 254, 208, 9, 74, 202, 56, 84, 162, 149, 3, 66, 2, 67, 2, 71, 2, 75, 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 83, 2, 86, 2, 89, 186, 2, 65, 2, 69, 2, 73, 3, 85, 10, 38, 68, - 238, 163, 16, 72, 187, 2, 65, 6, 234, 163, 16, 68, 2, 72, 187, 2, 65, 26, - 56, 2, 80, 76, 236, 2, 3, 83, 69, 84, 207, 143, 15, 77, 18, 50, 69, 89, + 162, 159, 16, 72, 187, 2, 65, 6, 158, 159, 16, 68, 2, 72, 187, 2, 65, 26, + 56, 2, 80, 76, 236, 2, 3, 83, 69, 84, 131, 139, 15, 77, 18, 50, 69, 89, 8, 73, 67, 65, 84, 73, 79, 78, 32, 2, 41, 8, 32, 77, 85, 83, 73, 67, 65, - 76, 2, 21, 3, 32, 78, 79, 2, 195, 142, 15, 84, 16, 40, 4, 83, 73, 71, 78, - 139, 164, 16, 88, 15, 11, 32, 12, 48, 3, 73, 78, 32, 81, 5, 87, 73, 84, - 72, 32, 8, 254, 206, 3, 76, 22, 82, 140, 191, 9, 5, 68, 79, 85, 66, 76, - 183, 238, 1, 84, 4, 242, 179, 12, 85, 187, 238, 2, 68, 7, 11, 32, 4, 244, - 83, 5, 77, 85, 76, 84, 73, 203, 155, 12, 85, 228, 3, 44, 5, 72, 82, 79, - 79, 77, 21, 2, 73, 67, 5, 215, 243, 14, 32, 224, 3, 30, 32, 109, 3, 65, + 76, 2, 21, 3, 32, 78, 79, 2, 247, 137, 15, 84, 16, 40, 4, 83, 73, 71, 78, + 191, 159, 16, 88, 15, 11, 32, 12, 48, 3, 73, 78, 32, 81, 5, 87, 73, 84, + 72, 32, 8, 178, 202, 3, 76, 22, 82, 140, 191, 9, 5, 68, 79, 85, 66, 76, + 183, 238, 1, 84, 4, 166, 175, 12, 85, 187, 238, 2, 68, 7, 11, 32, 4, 244, + 83, 5, 77, 85, 76, 84, 73, 255, 150, 12, 85, 228, 3, 44, 5, 72, 82, 79, + 79, 77, 21, 2, 73, 67, 5, 139, 239, 14, 32, 224, 3, 30, 32, 109, 3, 65, 76, 32, 6, 64, 4, 78, 65, 84, 85, 20, 3, 83, 72, 65, 209, 43, 2, 70, 76, - 2, 187, 212, 10, 82, 2, 227, 191, 11, 82, 218, 3, 64, 8, 75, 69, 89, 66, - 79, 65, 82, 68, 66, 83, 131, 248, 3, 78, 5, 41, 8, 32, 87, 73, 84, 72, - 32, 74, 65, 2, 231, 254, 13, 67, 212, 3, 48, 6, 89, 77, 66, 79, 76, 32, - 239, 177, 11, 67, 210, 3, 230, 2, 66, 238, 1, 67, 230, 9, 68, 250, 2, 69, + 2, 239, 207, 10, 82, 2, 151, 187, 11, 82, 218, 3, 64, 8, 75, 69, 89, 66, + 79, 65, 82, 68, 66, 83, 183, 243, 3, 78, 5, 41, 8, 32, 87, 73, 84, 72, + 32, 74, 65, 2, 155, 250, 13, 67, 212, 3, 48, 6, 89, 77, 66, 79, 76, 32, + 163, 173, 11, 67, 210, 3, 230, 2, 66, 238, 1, 67, 230, 9, 68, 250, 2, 69, 162, 1, 70, 166, 2, 71, 112, 9, 65, 82, 80, 69, 71, 71, 73, 65, 84, 168, 1, 2, 72, 65, 126, 75, 198, 3, 76, 138, 1, 77, 186, 2, 78, 162, 1, 79, 218, 2, 80, 200, 2, 2, 81, 85, 146, 2, 82, 198, 2, 83, 226, 5, 84, 182, - 10, 86, 42, 88, 42, 87, 232, 145, 9, 9, 73, 78, 86, 69, 82, 84, 69, 68, + 10, 86, 42, 88, 42, 87, 156, 141, 9, 9, 73, 78, 86, 69, 82, 84, 69, 68, 32, 143, 210, 6, 90, 20, 36, 5, 69, 71, 73, 78, 32, 59, 82, 8, 142, 15, - 80, 30, 83, 250, 251, 7, 66, 151, 245, 7, 84, 12, 24, 2, 65, 67, 35, 69, - 4, 250, 229, 15, 75, 155, 53, 69, 8, 26, 86, 255, 216, 15, 65, 6, 32, 2, - 73, 83, 183, 154, 16, 69, 5, 179, 26, 32, 84, 120, 2, 65, 69, 34, 76, 94, - 79, 194, 7, 82, 242, 11, 32, 224, 32, 7, 73, 82, 67, 76, 69, 32, 88, 233, - 227, 5, 2, 85, 84, 2, 11, 83, 2, 219, 212, 15, 85, 8, 42, 73, 249, 23, 5, - 85, 83, 84, 69, 82, 4, 26, 77, 187, 241, 13, 86, 2, 199, 219, 9, 65, 64, - 26, 77, 219, 149, 16, 68, 62, 64, 7, 66, 73, 78, 73, 78, 71, 32, 153, - 151, 6, 3, 77, 79, 78, 60, 202, 1, 65, 80, 7, 77, 65, 82, 67, 65, 84, 79, + 80, 30, 83, 174, 247, 7, 66, 151, 245, 7, 84, 12, 24, 2, 65, 67, 35, 69, + 4, 174, 225, 15, 75, 155, 53, 69, 8, 26, 86, 179, 212, 15, 65, 6, 32, 2, + 73, 83, 235, 149, 16, 69, 5, 179, 26, 32, 84, 120, 2, 65, 69, 34, 76, 94, + 79, 194, 7, 82, 242, 11, 32, 224, 32, 7, 73, 82, 67, 76, 69, 32, 88, 157, + 223, 5, 2, 85, 84, 2, 11, 83, 2, 143, 208, 15, 85, 8, 42, 73, 249, 23, 5, + 85, 83, 84, 69, 82, 4, 26, 77, 239, 236, 13, 86, 2, 251, 214, 9, 65, 64, + 26, 77, 143, 145, 16, 68, 62, 64, 7, 66, 73, 78, 73, 78, 71, 32, 205, + 146, 6, 3, 77, 79, 78, 60, 202, 1, 65, 80, 7, 77, 65, 82, 67, 65, 84, 79, 56, 2, 68, 79, 56, 2, 85, 80, 28, 2, 70, 76, 40, 5, 72, 65, 82, 77, 79, - 22, 83, 142, 2, 84, 250, 181, 7, 66, 172, 199, 3, 2, 76, 79, 143, 147, 5, + 22, 83, 142, 2, 84, 174, 177, 7, 66, 172, 199, 3, 2, 76, 79, 143, 147, 5, 82, 6, 76, 5, 67, 67, 69, 78, 84, 37, 10, 85, 71, 77, 69, 78, 84, 65, 84, - 73, 79, 5, 205, 2, 5, 45, 83, 84, 65, 67, 2, 219, 129, 15, 78, 6, 52, 2, - 87, 78, 168, 3, 2, 85, 66, 239, 244, 15, 73, 2, 149, 248, 14, 2, 32, 66, - 12, 248, 76, 2, 65, 71, 159, 199, 15, 73, 2, 223, 233, 14, 78, 12, 132, - 1, 9, 78, 65, 80, 32, 80, 73, 90, 90, 73, 22, 84, 232, 206, 4, 11, 80, - 82, 69, 67, 72, 71, 69, 83, 65, 78, 71, 247, 138, 6, 77, 2, 231, 130, 12, - 67, 6, 44, 5, 65, 67, 67, 65, 84, 199, 129, 16, 69, 4, 40, 4, 73, 83, 83, - 73, 243, 145, 16, 79, 2, 251, 242, 15, 77, 10, 34, 82, 165, 158, 12, 2, - 69, 78, 8, 28, 2, 73, 80, 199, 6, 69, 2, 173, 129, 12, 6, 76, 69, 32, 84, - 79, 78, 4, 22, 79, 179, 2, 69, 2, 147, 130, 15, 73, 24, 98, 65, 142, 1, - 69, 92, 6, 79, 85, 66, 76, 69, 32, 145, 169, 10, 7, 82, 85, 77, 32, 67, + 73, 79, 5, 205, 2, 5, 45, 83, 84, 65, 67, 2, 143, 253, 14, 78, 6, 52, 2, + 87, 78, 168, 3, 2, 85, 66, 163, 240, 15, 73, 2, 201, 243, 14, 2, 32, 66, + 12, 248, 76, 2, 65, 71, 211, 194, 15, 73, 2, 147, 229, 14, 78, 12, 132, + 1, 9, 78, 65, 80, 32, 80, 73, 90, 90, 73, 22, 84, 156, 202, 4, 11, 80, + 82, 69, 67, 72, 71, 69, 83, 65, 78, 71, 247, 138, 6, 77, 2, 155, 254, 11, + 67, 6, 44, 5, 65, 67, 67, 65, 84, 251, 252, 15, 69, 4, 40, 4, 73, 83, 83, + 73, 167, 141, 16, 79, 2, 175, 238, 15, 77, 10, 34, 82, 217, 153, 12, 2, + 69, 78, 8, 28, 2, 73, 80, 199, 6, 69, 2, 225, 252, 11, 6, 76, 69, 32, 84, + 79, 78, 4, 22, 79, 179, 2, 69, 2, 199, 253, 14, 73, 24, 98, 65, 142, 1, + 69, 92, 6, 79, 85, 66, 76, 69, 32, 197, 164, 10, 7, 82, 85, 77, 32, 67, 76, 69, 10, 96, 2, 32, 67, 20, 2, 77, 80, 204, 29, 4, 83, 72, 69, 68, - 137, 200, 15, 5, 76, 32, 83, 69, 71, 2, 255, 194, 8, 65, 5, 175, 132, 14, + 189, 195, 15, 5, 76, 32, 83, 69, 71, 2, 179, 190, 8, 65, 5, 227, 255, 13, 32, 4, 40, 3, 67, 82, 69, 29, 3, 71, 82, 69, 2, 181, 25, 3, 83, 67, 69, - 2, 155, 233, 8, 69, 6, 242, 21, 83, 254, 6, 66, 191, 135, 5, 70, 14, 32, + 2, 207, 228, 8, 69, 6, 242, 21, 83, 254, 6, 66, 243, 130, 5, 70, 14, 32, 3, 78, 68, 32, 151, 16, 73, 10, 74, 80, 30, 83, 204, 13, 3, 79, 70, 32, - 174, 238, 7, 66, 151, 245, 7, 84, 2, 185, 227, 12, 2, 72, 82, 2, 231, - 147, 15, 76, 34, 104, 6, 69, 82, 77, 65, 84, 65, 22, 73, 122, 79, 102, - 32, 144, 36, 3, 85, 83, 65, 213, 230, 3, 2, 76, 65, 5, 175, 218, 13, 32, + 226, 233, 7, 66, 151, 245, 7, 84, 2, 237, 222, 12, 2, 72, 82, 2, 155, + 143, 15, 76, 34, 104, 6, 69, 82, 77, 65, 84, 65, 22, 73, 122, 79, 102, + 32, 144, 36, 3, 85, 83, 65, 137, 226, 3, 2, 76, 65, 5, 227, 213, 13, 32, 10, 22, 78, 135, 34, 86, 8, 56, 9, 71, 69, 82, 69, 68, 32, 84, 82, 69, - 239, 20, 65, 6, 137, 242, 5, 4, 77, 79, 76, 79, 6, 208, 25, 3, 85, 82, - 45, 203, 167, 14, 82, 18, 54, 32, 56, 7, 76, 73, 83, 83, 65, 78, 68, 23, - 82, 6, 25, 4, 67, 76, 69, 70, 7, 157, 13, 3, 32, 79, 84, 4, 251, 134, 6, + 239, 20, 65, 6, 189, 237, 5, 4, 77, 79, 76, 79, 6, 208, 25, 3, 85, 82, + 45, 255, 162, 14, 82, 18, 54, 32, 56, 7, 76, 73, 83, 83, 65, 78, 68, 23, + 82, 6, 25, 4, 67, 76, 69, 70, 7, 157, 13, 3, 32, 79, 84, 4, 175, 130, 6, 79, 8, 84, 9, 65, 67, 69, 32, 78, 79, 84, 69, 32, 37, 8, 69, 71, 79, 82, - 73, 65, 78, 32, 4, 184, 227, 8, 2, 78, 79, 27, 83, 4, 250, 2, 67, 3, 70, - 8, 44, 3, 76, 70, 32, 205, 8, 3, 85, 80, 84, 6, 52, 3, 80, 69, 68, 210, - 223, 3, 78, 151, 181, 8, 82, 2, 139, 199, 5, 65, 24, 48, 6, 73, 69, 86, - 65, 78, 32, 139, 223, 14, 79, 22, 178, 1, 67, 46, 69, 68, 7, 81, 85, 65, - 82, 84, 69, 82, 62, 70, 148, 220, 3, 4, 72, 65, 76, 70, 0, 5, 87, 72, 79, + 73, 65, 78, 32, 4, 236, 222, 8, 2, 78, 79, 27, 83, 4, 250, 2, 67, 3, 70, + 8, 44, 3, 76, 70, 32, 205, 8, 3, 85, 80, 84, 6, 52, 3, 80, 69, 68, 134, + 219, 3, 78, 151, 181, 8, 82, 2, 191, 194, 5, 65, 24, 48, 6, 73, 69, 86, + 65, 78, 32, 191, 218, 14, 79, 22, 178, 1, 67, 46, 69, 68, 7, 81, 85, 65, + 82, 84, 69, 82, 62, 70, 200, 215, 3, 4, 72, 65, 76, 70, 0, 5, 87, 72, 79, 76, 69, 173, 224, 1, 9, 82, 69, 67, 73, 84, 65, 84, 73, 86, 2, 11, 32, 2, - 11, 67, 2, 235, 163, 5, 76, 6, 64, 5, 73, 71, 72, 84, 72, 221, 203, 14, - 5, 78, 68, 32, 79, 70, 4, 253, 129, 6, 10, 32, 78, 79, 84, 69, 32, 83, - 84, 69, 77, 4, 218, 14, 76, 185, 205, 3, 4, 73, 78, 65, 76, 8, 44, 4, 79, + 11, 67, 2, 159, 159, 5, 76, 6, 64, 5, 73, 71, 72, 84, 72, 145, 199, 14, + 5, 78, 68, 32, 79, 70, 4, 177, 253, 5, 10, 32, 78, 79, 84, 69, 32, 83, + 84, 69, 77, 4, 218, 14, 76, 237, 200, 3, 4, 73, 78, 65, 76, 8, 44, 4, 79, 78, 71, 65, 217, 13, 2, 69, 70, 7, 11, 32, 4, 28, 3, 73, 77, 80, 3, 80, 2, 193, 2, 7, 69, 82, 70, 69, 67, 84, 65, 18, 104, 2, 65, 88, 20, 2, 69, 90, 20, 5, 73, 78, 73, 77, 65, 44, 3, 79, 79, 78, 25, 4, 85, 76, 84, 73, - 2, 167, 224, 15, 73, 2, 175, 226, 15, 90, 7, 11, 32, 4, 226, 142, 12, 82, + 2, 219, 219, 15, 73, 2, 227, 221, 15, 90, 7, 11, 32, 4, 150, 138, 12, 82, 195, 83, 66, 4, 189, 17, 2, 32, 78, 4, 60, 11, 80, 76, 69, 32, 77, 69, - 65, 83, 85, 82, 69, 15, 32, 2, 11, 32, 2, 223, 141, 12, 82, 10, 120, 4, - 69, 66, 69, 78, 212, 26, 3, 85, 76, 76, 236, 225, 5, 3, 65, 84, 85, 189, - 227, 6, 7, 79, 84, 69, 72, 69, 65, 68, 2, 253, 228, 14, 4, 83, 84, 73, + 65, 83, 85, 82, 69, 15, 32, 2, 11, 32, 2, 147, 137, 12, 82, 10, 120, 4, + 69, 66, 69, 78, 212, 26, 3, 85, 76, 76, 160, 221, 5, 3, 65, 84, 85, 189, + 227, 6, 7, 79, 84, 69, 72, 69, 65, 68, 2, 177, 224, 14, 4, 83, 84, 73, 77, 32, 88, 2, 78, 69, 120, 14, 82, 78, 65, 77, 69, 78, 84, 32, 83, 84, 82, 79, 75, 69, 107, 84, 6, 92, 18, 32, 72, 85, 78, 68, 82, 69, 68, 32, 84, 87, 69, 78, 84, 89, 45, 69, 73, 159, 20, 45, 4, 181, 13, 2, 71, 72, - 22, 11, 45, 22, 170, 166, 3, 49, 194, 214, 12, 50, 2, 51, 2, 52, 2, 53, + 22, 11, 45, 22, 222, 161, 3, 49, 194, 214, 12, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 4, 173, 4, 3, 84, 65, 86, 18, 96, 9, 65, 82, - 69, 78, 84, 72, 69, 83, 73, 0, 2, 76, 85, 18, 69, 142, 1, 79, 163, 239, + 69, 78, 84, 72, 69, 83, 73, 0, 2, 76, 85, 18, 69, 142, 1, 79, 215, 234, 13, 73, 2, 243, 22, 83, 6, 68, 4, 68, 65, 76, 32, 49, 9, 83, 32, 83, 85, - 66, 80, 85, 78, 67, 4, 26, 85, 243, 184, 15, 77, 2, 215, 184, 15, 80, 2, - 255, 210, 13, 84, 6, 48, 2, 68, 65, 245, 5, 5, 82, 82, 69, 67, 84, 2, - 219, 240, 13, 84, 12, 76, 6, 65, 82, 84, 69, 82, 32, 125, 9, 73, 78, 68, - 73, 67, 69, 83, 73, 77, 8, 60, 5, 84, 79, 78, 69, 32, 234, 208, 3, 78, - 151, 181, 8, 82, 4, 26, 83, 187, 142, 5, 70, 2, 241, 247, 15, 3, 72, 65, - 82, 4, 17, 2, 65, 32, 4, 230, 186, 12, 65, 161, 186, 3, 3, 66, 65, 83, + 66, 80, 85, 78, 67, 4, 26, 85, 167, 180, 15, 77, 2, 139, 180, 15, 80, 2, + 179, 206, 13, 84, 6, 48, 2, 68, 65, 245, 5, 5, 82, 82, 69, 67, 84, 2, + 143, 236, 13, 84, 12, 76, 6, 65, 82, 84, 69, 82, 32, 125, 9, 73, 78, 68, + 73, 67, 69, 83, 73, 77, 8, 60, 5, 84, 79, 78, 69, 32, 158, 204, 3, 78, + 151, 181, 8, 82, 4, 26, 83, 239, 137, 5, 70, 2, 165, 243, 15, 3, 72, 65, + 82, 4, 17, 2, 65, 32, 4, 154, 182, 12, 65, 161, 186, 3, 3, 66, 65, 83, 14, 22, 69, 175, 1, 73, 10, 72, 4, 80, 69, 65, 84, 81, 10, 86, 69, 82, 83, 69, 32, 70, 73, 78, 65, 8, 56, 8, 69, 68, 32, 70, 73, 71, 85, 82, - 179, 163, 14, 32, 6, 179, 221, 5, 69, 2, 207, 4, 76, 4, 48, 2, 71, 72, - 57, 6, 78, 70, 79, 82, 90, 65, 2, 33, 6, 84, 32, 82, 69, 80, 69, 2, 179, - 169, 10, 65, 2, 171, 181, 8, 78, 48, 136, 1, 6, 67, 65, 78, 68, 73, 67, - 62, 69, 162, 1, 72, 54, 73, 252, 1, 6, 81, 85, 65, 82, 69, 32, 252, 158, - 8, 2, 85, 66, 251, 100, 79, 4, 17, 2, 85, 83, 5, 209, 234, 13, 5, 32, 70, - 76, 69, 88, 14, 32, 2, 77, 73, 223, 201, 15, 71, 12, 64, 6, 66, 82, 69, - 86, 73, 83, 1, 6, 77, 73, 78, 73, 77, 65, 6, 11, 32, 6, 134, 13, 87, 246, - 242, 11, 82, 195, 83, 66, 6, 84, 3, 79, 82, 84, 129, 239, 5, 3, 65, 82, - 80, 14, 32, 4, 78, 71, 76, 69, 43, 88, 2, 17, 2, 32, 66, 2, 207, 134, 14, - 65, 12, 18, 45, 79, 84, 4, 242, 7, 76, 217, 207, 14, 11, 83, 84, 82, 73, + 231, 158, 14, 32, 6, 231, 216, 5, 69, 2, 207, 4, 76, 4, 48, 2, 71, 72, + 57, 6, 78, 70, 79, 82, 90, 65, 2, 33, 6, 84, 32, 82, 69, 80, 69, 2, 231, + 164, 10, 65, 2, 223, 176, 8, 78, 48, 136, 1, 6, 67, 65, 78, 68, 73, 67, + 62, 69, 162, 1, 72, 54, 73, 252, 1, 6, 81, 85, 65, 82, 69, 32, 176, 154, + 8, 2, 85, 66, 251, 100, 79, 4, 17, 2, 85, 83, 5, 133, 230, 13, 5, 32, 70, + 76, 69, 88, 14, 32, 2, 77, 73, 147, 197, 15, 71, 12, 64, 6, 66, 82, 69, + 86, 73, 83, 1, 6, 77, 73, 78, 73, 77, 65, 6, 11, 32, 6, 134, 13, 87, 170, + 238, 11, 82, 195, 83, 66, 6, 84, 3, 79, 82, 84, 181, 234, 5, 3, 65, 82, + 80, 14, 32, 4, 78, 71, 76, 69, 43, 88, 2, 17, 2, 32, 66, 2, 131, 130, 14, + 65, 12, 18, 45, 79, 84, 4, 242, 7, 76, 141, 203, 14, 11, 83, 84, 82, 73, 78, 71, 32, 70, 82, 69, 84, 8, 52, 3, 69, 69, 78, 1, 6, 89, 45, 70, 79, - 85, 82, 4, 193, 12, 2, 84, 72, 6, 26, 78, 167, 239, 15, 66, 4, 229, 9, 7, + 85, 82, 4, 193, 12, 2, 84, 72, 6, 26, 78, 219, 234, 15, 66, 4, 229, 9, 7, 79, 84, 69, 72, 69, 65, 68, 60, 132, 1, 6, 69, 77, 80, 85, 83, 32, 154, 4, 72, 88, 2, 87, 79, 84, 7, 79, 82, 67, 85, 76, 85, 83, 46, 82, 141, 3, 3, 85, 82, 78, 16, 232, 1, 27, 73, 77, 80, 69, 82, 70, 69, 67, 84, 85, 77, 32, 67, 85, 77, 32, 80, 82, 79, 76, 65, 84, 73, 79, 78, 69, 32, 129, 1, 25, 80, 69, 82, 70, 69, 67, 84, 85, 77, 32, 67, 85, 77, 32, 80, 82, 79, 76, 65, 84, 73, 79, 78, 69, 32, 10, 60, 10, 73, 77, 80, 69, 82, 70, - 69, 67, 84, 65, 131, 1, 80, 9, 249, 210, 5, 11, 32, 68, 73, 77, 73, 78, + 69, 67, 84, 65, 131, 1, 80, 9, 173, 206, 5, 11, 32, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 6, 60, 3, 73, 77, 80, 41, 8, 80, 69, 82, 70, 69, 67, - 84, 65, 2, 245, 197, 15, 5, 69, 82, 70, 69, 67, 5, 197, 194, 8, 12, 32, + 84, 65, 2, 169, 193, 15, 5, 69, 82, 70, 69, 67, 5, 249, 189, 8, 12, 32, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 6, 72, 2, 82, 69, 249, 5, 11, 73, 82, 84, 89, 45, 83, 69, 67, 79, 78, 68, 2, 11, 69, 2, 11, 45, 2, 11, - 76, 2, 37, 7, 73, 78, 69, 32, 83, 84, 65, 2, 155, 231, 14, 70, 5, 189, - 221, 11, 6, 32, 82, 69, 83, 85, 80, 27, 33, 6, 73, 65, 78, 71, 76, 69, + 76, 2, 37, 7, 73, 78, 69, 32, 83, 84, 65, 2, 207, 226, 14, 70, 5, 241, + 216, 11, 6, 32, 82, 69, 83, 85, 80, 27, 33, 6, 73, 65, 78, 71, 76, 69, 24, 128, 1, 10, 32, 78, 79, 84, 69, 72, 69, 65, 68, 32, 61, 17, 45, 82, 79, 85, 78, 68, 32, 78, 79, 84, 69, 72, 69, 65, 68, 32, 68, 20, 58, 68, 24, 3, 85, 80, 32, 38, 82, 25, 3, 76, 69, 70, 4, 93, 3, 79, 87, 78, 8, - 34, 82, 78, 87, 183, 198, 12, 66, 4, 21, 3, 73, 71, 72, 4, 11, 84, 4, 11, - 32, 4, 26, 87, 183, 198, 12, 66, 2, 11, 72, 2, 243, 155, 14, 73, 7, 11, - 32, 4, 146, 192, 8, 83, 203, 164, 7, 85, 4, 36, 3, 79, 73, 68, 207, 161, - 15, 73, 2, 205, 139, 13, 5, 32, 78, 79, 84, 69, 6, 92, 4, 72, 79, 76, 69, - 253, 204, 8, 13, 73, 84, 72, 32, 70, 73, 78, 71, 69, 82, 78, 65, 73, 4, - 11, 32, 4, 210, 187, 3, 78, 151, 181, 8, 82, 232, 3, 224, 2, 15, 67, 79, + 34, 82, 78, 87, 235, 193, 12, 66, 4, 21, 3, 73, 71, 72, 4, 11, 84, 4, 11, + 32, 4, 26, 87, 235, 193, 12, 66, 2, 11, 72, 2, 167, 151, 14, 73, 7, 11, + 32, 4, 198, 187, 8, 83, 203, 164, 7, 85, 4, 36, 3, 79, 73, 68, 131, 157, + 15, 73, 2, 129, 135, 13, 5, 32, 78, 79, 84, 69, 6, 92, 4, 72, 79, 76, 69, + 177, 200, 8, 13, 73, 84, 72, 32, 70, 73, 78, 71, 69, 82, 78, 65, 73, 4, + 11, 32, 4, 134, 183, 3, 78, 151, 181, 8, 82, 232, 3, 224, 2, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 254, 1, 76, 212, 14, 16, 77, 79, 68, 73, 70, 73, 69, 82, 32, 76, 69, 84, 84, 69, 82, 32, 122, 83, 80, 16, 69, 65, 83, 84, 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 218, 9, 84, 204, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, - 140, 180, 9, 3, 80, 65, 79, 175, 154, 4, 68, 16, 66, 77, 165, 1, 11, 83, + 192, 175, 9, 3, 80, 65, 79, 175, 154, 4, 68, 16, 66, 77, 165, 1, 11, 83, 72, 65, 78, 32, 77, 69, 68, 73, 65, 76, 14, 80, 6, 69, 68, 73, 65, 76, - 32, 45, 10, 79, 78, 32, 77, 69, 68, 73, 65, 76, 32, 8, 170, 220, 15, 72, - 2, 82, 2, 87, 3, 89, 6, 254, 219, 15, 76, 2, 77, 3, 78, 2, 183, 228, 10, + 32, 45, 10, 79, 78, 32, 77, 69, 68, 73, 65, 76, 32, 8, 222, 215, 15, 72, + 2, 82, 2, 87, 3, 89, 6, 178, 215, 15, 76, 2, 77, 3, 78, 2, 235, 223, 10, 32, 238, 1, 104, 6, 69, 84, 84, 69, 82, 32, 185, 13, 15, 79, 71, 79, 71, 82, 65, 77, 32, 75, 72, 65, 77, 84, 73, 32, 232, 1, 238, 1, 65, 50, 69, 146, 1, 71, 50, 75, 254, 1, 77, 134, 1, 78, 58, 82, 86, 83, 130, 3, 84, - 198, 1, 87, 142, 243, 11, 68, 214, 6, 85, 22, 86, 166, 202, 1, 73, 42, + 198, 1, 87, 194, 238, 11, 68, 214, 6, 85, 22, 86, 166, 202, 1, 73, 42, 76, 222, 196, 1, 66, 2, 67, 2, 74, 2, 80, 138, 69, 72, 2, 89, 187, 2, 79, - 7, 192, 144, 15, 4, 73, 84, 79, 78, 219, 74, 85, 9, 77, 17, 65, 83, 84, - 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 6, 42, 71, 150, - 224, 10, 89, 199, 187, 3, 78, 2, 147, 224, 10, 72, 6, 130, 205, 9, 82, - 162, 138, 6, 72, 187, 2, 65, 44, 32, 2, 72, 65, 139, 217, 15, 65, 43, 25, - 4, 77, 84, 73, 32, 40, 134, 1, 68, 34, 84, 162, 223, 8, 78, 230, 176, 6, + 7, 244, 139, 15, 4, 73, 84, 79, 78, 219, 74, 85, 9, 77, 17, 65, 83, 84, + 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 6, 42, 71, 202, + 219, 10, 89, 199, 187, 3, 78, 2, 199, 219, 10, 72, 6, 182, 200, 9, 82, + 162, 138, 6, 72, 187, 2, 65, 44, 32, 2, 72, 65, 191, 212, 15, 65, 43, 25, + 4, 77, 84, 73, 32, 40, 134, 1, 68, 34, 84, 214, 218, 8, 78, 230, 176, 6, 67, 2, 72, 2, 74, 170, 37, 76, 226, 31, 70, 2, 71, 2, 82, 2, 83, 2, 88, - 3, 90, 6, 162, 144, 15, 68, 139, 69, 72, 4, 131, 144, 15, 84, 12, 36, 3, - 79, 78, 32, 139, 215, 15, 65, 10, 60, 2, 66, 66, 162, 217, 13, 74, 230, - 186, 1, 78, 199, 66, 69, 4, 198, 214, 15, 65, 3, 69, 10, 134, 222, 8, 78, - 238, 245, 6, 71, 2, 89, 187, 2, 65, 4, 132, 221, 2, 12, 85, 77, 65, 73, - 32, 80, 65, 76, 65, 85, 78, 71, 239, 248, 12, 65, 50, 90, 72, 200, 221, + 3, 90, 6, 214, 139, 15, 68, 139, 69, 72, 4, 183, 139, 15, 84, 12, 36, 3, + 79, 78, 32, 191, 210, 15, 65, 10, 60, 2, 66, 66, 214, 212, 13, 74, 230, + 186, 1, 78, 199, 66, 69, 4, 250, 209, 15, 65, 3, 69, 10, 186, 217, 8, 78, + 238, 245, 6, 71, 2, 89, 187, 2, 65, 4, 184, 216, 2, 12, 85, 77, 65, 73, + 32, 80, 65, 76, 65, 85, 78, 71, 239, 248, 12, 65, 50, 90, 72, 252, 216, 2, 9, 71, 65, 87, 32, 75, 65, 82, 69, 78, 198, 244, 12, 83, 187, 2, 65, 44, 66, 65, 197, 1, 11, 87, 69, 32, 80, 65, 76, 65, 85, 78, 71, 32, 41, - 17, 2, 78, 32, 38, 134, 1, 78, 190, 213, 13, 74, 2, 80, 2, 84, 234, 181, + 17, 2, 78, 32, 38, 134, 1, 78, 242, 208, 13, 74, 2, 80, 2, 84, 234, 181, 1, 66, 2, 67, 2, 71, 2, 75, 138, 69, 68, 2, 70, 2, 72, 2, 90, 187, 2, 65, - 6, 170, 208, 15, 78, 2, 89, 187, 2, 65, 4, 146, 213, 13, 67, 3, 83, 36, - 38, 65, 186, 138, 15, 84, 139, 69, 72, 31, 41, 8, 73, 32, 76, 65, 73, 78, - 71, 32, 28, 82, 78, 170, 243, 11, 68, 146, 150, 3, 66, 2, 71, 2, 74, 170, - 37, 76, 227, 31, 70, 4, 190, 206, 15, 78, 3, 89, 6, 92, 17, 69, 83, 84, - 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 255, 207, 15, 65, - 4, 158, 214, 10, 80, 183, 252, 2, 84, 6, 182, 193, 14, 79, 194, 62, 81, + 6, 222, 203, 15, 78, 2, 89, 187, 2, 65, 4, 198, 208, 13, 67, 3, 83, 36, + 38, 65, 238, 133, 15, 84, 139, 69, 72, 31, 41, 8, 73, 32, 76, 65, 73, 78, + 71, 32, 28, 82, 78, 222, 238, 11, 68, 146, 150, 3, 66, 2, 71, 2, 74, 170, + 37, 76, 227, 31, 70, 4, 242, 201, 15, 78, 3, 89, 6, 92, 17, 69, 83, 84, + 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 179, 203, 15, 65, + 4, 210, 209, 10, 80, 183, 252, 2, 84, 6, 234, 188, 14, 79, 194, 62, 81, 139, 63, 72, 4, 56, 6, 75, 72, 65, 77, 84, 73, 1, 4, 83, 72, 65, 78, 2, - 29, 5, 32, 82, 69, 68, 85, 2, 241, 132, 1, 2, 80, 76, 90, 76, 2, 72, 65, - 20, 4, 73, 71, 78, 32, 233, 6, 6, 89, 77, 66, 79, 76, 32, 20, 175, 191, + 29, 5, 32, 82, 69, 68, 85, 2, 165, 128, 1, 2, 80, 76, 90, 76, 2, 72, 65, + 20, 4, 73, 71, 78, 32, 233, 6, 6, 89, 77, 66, 79, 76, 32, 20, 227, 186, 9, 78, 52, 202, 3, 65, 32, 12, 75, 72, 65, 77, 84, 73, 32, 84, 79, 78, 69, 45, 30, 83, 132, 2, 15, 84, 65, 73, 32, 76, 65, 73, 78, 71, 32, 84, 79, 78, 69, 45, 28, 22, 87, 69, 83, 84, 69, 82, 78, 32, 80, 87, 79, 32, - 75, 65, 82, 69, 78, 32, 84, 79, 78, 69, 222, 244, 2, 68, 136, 169, 5, 19, + 75, 65, 82, 69, 78, 32, 84, 79, 78, 69, 146, 240, 2, 68, 136, 169, 5, 19, 82, 85, 77, 65, 73, 32, 80, 65, 76, 65, 85, 78, 71, 32, 84, 79, 78, 69, 45, 140, 180, 3, 9, 80, 65, 79, 32, 75, 65, 82, 69, 78, 148, 115, 6, 76, - 73, 84, 84, 76, 69, 155, 191, 2, 86, 4, 210, 192, 14, 83, 199, 68, 78, 4, - 226, 201, 15, 49, 3, 51, 18, 40, 4, 72, 65, 78, 32, 195, 248, 14, 69, 16, - 84, 8, 67, 79, 85, 78, 67, 73, 76, 32, 84, 5, 84, 79, 78, 69, 45, 199, - 201, 14, 83, 6, 136, 211, 11, 8, 69, 77, 80, 72, 65, 84, 73, 67, 185, - 244, 3, 4, 84, 79, 78, 69, 8, 238, 199, 15, 50, 2, 51, 2, 53, 3, 54, 4, - 194, 199, 15, 50, 3, 53, 10, 11, 45, 10, 154, 199, 15, 49, 2, 50, 2, 51, + 73, 84, 84, 76, 69, 155, 191, 2, 86, 4, 134, 188, 14, 83, 199, 68, 78, 4, + 150, 197, 15, 49, 3, 51, 18, 40, 4, 72, 65, 78, 32, 247, 243, 14, 69, 16, + 84, 8, 67, 79, 85, 78, 67, 73, 76, 32, 84, 5, 84, 79, 78, 69, 45, 251, + 196, 14, 83, 6, 188, 206, 11, 8, 69, 77, 80, 72, 65, 84, 73, 67, 185, + 244, 3, 4, 84, 79, 78, 69, 8, 162, 195, 15, 50, 2, 51, 2, 53, 3, 54, 4, + 246, 194, 15, 50, 3, 53, 10, 11, 45, 10, 206, 194, 15, 49, 2, 50, 2, 51, 2, 52, 3, 53, 18, 130, 1, 65, 128, 1, 2, 76, 79, 28, 5, 83, 72, 65, 78, - 32, 228, 178, 8, 4, 71, 69, 78, 73, 217, 96, 6, 67, 79, 77, 80, 76, 69, - 8, 84, 5, 73, 84, 79, 78, 32, 185, 179, 6, 10, 70, 79, 82, 69, 77, 69, - 78, 84, 73, 79, 6, 94, 69, 246, 175, 13, 84, 139, 121, 79, 2, 253, 178, - 8, 2, 67, 65, 4, 26, 69, 255, 168, 14, 79, 2, 201, 12, 4, 88, 67, 76, 65, + 32, 152, 174, 8, 4, 71, 69, 78, 73, 217, 96, 6, 67, 79, 77, 80, 76, 69, + 8, 84, 5, 73, 84, 79, 78, 32, 237, 174, 6, 10, 70, 79, 82, 69, 77, 69, + 78, 84, 73, 79, 6, 94, 69, 170, 171, 13, 84, 139, 121, 79, 2, 177, 174, + 8, 2, 67, 65, 4, 26, 69, 179, 164, 14, 79, 2, 201, 12, 4, 88, 67, 76, 65, 24, 140, 1, 20, 79, 78, 69, 32, 77, 65, 82, 75, 32, 83, 71, 65, 87, 32, - 75, 65, 82, 69, 78, 32, 201, 180, 9, 8, 65, 73, 32, 76, 65, 73, 78, 71, - 4, 38, 72, 181, 211, 8, 3, 75, 69, 32, 2, 191, 213, 8, 65, 56, 150, 2, + 75, 65, 82, 69, 78, 32, 253, 175, 9, 8, 65, 73, 32, 76, 65, 73, 78, 71, + 4, 38, 72, 233, 206, 8, 3, 75, 69, 32, 2, 243, 208, 8, 65, 56, 150, 2, 65, 76, 9, 71, 69, 66, 65, 32, 75, 65, 82, 69, 20, 6, 75, 65, 89, 65, 72, 32, 40, 4, 77, 79, 78, 32, 34, 83, 142, 1, 69, 40, 18, 87, 69, 83, 84, - 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 212, 187, 9, 2, - 84, 65, 254, 170, 2, 85, 22, 86, 167, 202, 1, 73, 8, 26, 73, 143, 192, - 15, 65, 7, 25, 4, 84, 79, 78, 32, 4, 171, 179, 13, 65, 2, 203, 255, 14, - 78, 6, 242, 168, 15, 69, 2, 79, 215, 22, 85, 4, 198, 171, 15, 73, 219, - 19, 79, 10, 80, 4, 72, 65, 78, 32, 209, 209, 8, 10, 71, 65, 87, 32, 75, - 65, 82, 69, 78, 32, 8, 54, 69, 20, 5, 70, 73, 78, 65, 76, 171, 187, 15, - 65, 5, 251, 192, 14, 32, 2, 151, 172, 15, 32, 4, 226, 152, 15, 69, 151, - 14, 85, 232, 17, 152, 2, 5, 45, 65, 82, 89, 32, 214, 4, 65, 222, 16, 66, - 30, 69, 146, 32, 73, 136, 1, 3, 75, 79, 32, 170, 10, 79, 166, 24, 85, - 224, 8, 22, 89, 73, 65, 75, 69, 78, 71, 32, 80, 85, 65, 67, 72, 85, 69, + 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 136, 183, 9, 2, + 84, 65, 254, 170, 2, 85, 22, 86, 167, 202, 1, 73, 8, 26, 73, 195, 187, + 15, 65, 7, 25, 4, 84, 79, 78, 32, 4, 223, 174, 13, 65, 2, 255, 250, 14, + 78, 6, 166, 164, 15, 69, 2, 79, 215, 22, 85, 4, 250, 166, 15, 73, 219, + 19, 79, 10, 80, 4, 72, 65, 78, 32, 133, 205, 8, 10, 71, 65, 87, 32, 75, + 65, 82, 69, 78, 32, 8, 54, 69, 20, 5, 70, 73, 78, 65, 76, 223, 182, 15, + 65, 5, 175, 188, 14, 32, 2, 203, 167, 15, 32, 4, 150, 148, 15, 69, 151, + 14, 85, 208, 11, 152, 2, 5, 45, 65, 82, 89, 32, 214, 4, 65, 222, 16, 66, + 30, 69, 146, 32, 73, 136, 1, 3, 75, 79, 32, 170, 10, 79, 162, 24, 85, + 152, 4, 22, 89, 73, 65, 75, 69, 78, 71, 32, 80, 85, 65, 67, 72, 85, 69, 32, 72, 77, 79, 78, 71, 32, 232, 135, 2, 2, 80, 78, 252, 208, 12, 2, 78, 66, 27, 76, 32, 130, 1, 67, 114, 84, 46, 83, 160, 1, 5, 85, 78, 73, 79, - 78, 108, 4, 87, 72, 73, 84, 214, 241, 11, 76, 210, 17, 73, 151, 162, 2, - 80, 8, 52, 7, 73, 82, 67, 76, 69, 68, 32, 159, 168, 14, 79, 6, 40, 2, 80, - 76, 14, 84, 251, 146, 8, 68, 2, 35, 85, 2, 21, 3, 73, 77, 69, 2, 187, - 245, 11, 83, 6, 40, 6, 81, 85, 65, 82, 69, 32, 87, 85, 4, 60, 9, 73, 78, - 84, 69, 82, 83, 69, 67, 84, 1, 2, 85, 78, 2, 147, 207, 11, 73, 2, 11, 77, - 2, 147, 242, 11, 77, 7, 69, 15, 32, 79, 80, 69, 82, 65, 84, 79, 82, 32, - 87, 73, 84, 72, 32, 4, 246, 171, 11, 80, 215, 186, 3, 68, 2, 11, 69, 2, - 205, 220, 12, 2, 32, 86, 188, 2, 170, 2, 66, 252, 4, 10, 71, 32, 77, 85, + 78, 108, 4, 87, 72, 73, 84, 138, 237, 11, 76, 210, 17, 73, 151, 162, 2, + 80, 8, 52, 7, 73, 82, 67, 76, 69, 68, 32, 211, 163, 14, 79, 6, 40, 2, 80, + 76, 14, 84, 175, 142, 8, 68, 2, 35, 85, 2, 21, 3, 73, 77, 69, 2, 239, + 240, 11, 83, 6, 40, 6, 81, 85, 65, 82, 69, 32, 87, 85, 4, 60, 9, 73, 78, + 84, 69, 82, 83, 69, 67, 84, 1, 2, 85, 78, 2, 199, 202, 11, 73, 2, 11, 77, + 2, 199, 237, 11, 77, 7, 69, 15, 32, 79, 80, 69, 82, 65, 84, 79, 82, 32, + 87, 73, 84, 72, 32, 4, 170, 167, 11, 80, 215, 186, 3, 68, 2, 11, 69, 2, + 129, 216, 12, 2, 32, 86, 188, 2, 170, 2, 66, 252, 4, 10, 71, 32, 77, 85, 78, 68, 65, 82, 73, 32, 142, 4, 73, 52, 2, 78, 68, 208, 4, 7, 84, 73, 79, - 78, 65, 76, 32, 132, 214, 1, 2, 85, 83, 148, 147, 8, 5, 77, 69, 32, 66, + 78, 65, 76, 32, 184, 209, 1, 2, 85, 83, 148, 147, 8, 5, 77, 69, 32, 66, 65, 220, 218, 3, 7, 90, 65, 82, 32, 65, 77, 85, 164, 163, 1, 8, 82, 82, 79, 87, 32, 78, 79, 45, 231, 62, 75, 82, 52, 7, 65, 84, 65, 69, 65, 78, - 32, 155, 177, 15, 76, 80, 160, 1, 7, 76, 69, 84, 84, 69, 82, 32, 236, 2, - 7, 78, 85, 77, 66, 69, 82, 32, 237, 253, 9, 16, 67, 82, 85, 67, 73, 70, + 32, 207, 172, 15, 76, 80, 160, 1, 7, 76, 69, 84, 84, 69, 82, 32, 236, 2, + 7, 78, 85, 77, 66, 69, 82, 32, 161, 249, 9, 16, 67, 82, 85, 67, 73, 70, 79, 82, 77, 32, 78, 85, 77, 66, 69, 82, 62, 236, 1, 6, 70, 73, 78, 65, - 76, 32, 134, 132, 2, 84, 242, 119, 68, 34, 76, 50, 81, 214, 205, 1, 82, + 76, 32, 186, 255, 1, 84, 242, 119, 68, 34, 76, 50, 81, 214, 205, 1, 82, 142, 220, 2, 65, 50, 71, 90, 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, 134, 2, 87, 218, 103, 80, 171, 4, 77, - 18, 222, 251, 2, 65, 54, 76, 190, 168, 4, 83, 190, 3, 89, 174, 213, 1, - 75, 174, 81, 66, 170, 225, 4, 78, 222, 105, 72, 171, 4, 77, 16, 238, 252, + 18, 146, 247, 2, 65, 54, 76, 190, 168, 4, 83, 190, 3, 89, 174, 213, 1, + 75, 174, 81, 66, 170, 225, 4, 78, 222, 105, 72, 171, 4, 77, 16, 162, 248, 2, 84, 202, 170, 4, 79, 255, 148, 6, 70, 84, 84, 7, 76, 69, 84, 84, 69, - 82, 32, 164, 2, 5, 83, 73, 71, 78, 32, 139, 184, 13, 68, 54, 42, 65, 50, - 69, 66, 73, 50, 79, 47, 85, 11, 190, 156, 15, 78, 202, 17, 66, 2, 72, 3, - 74, 15, 234, 175, 13, 78, 158, 114, 76, 166, 111, 84, 174, 28, 71, 3, 77, - 11, 246, 230, 14, 68, 162, 70, 72, 2, 83, 3, 84, 11, 146, 172, 15, 78, - 86, 76, 2, 80, 3, 89, 11, 186, 172, 15, 67, 2, 68, 2, 75, 3, 82, 10, 100, - 2, 77, 85, 20, 3, 83, 85, 84, 178, 118, 73, 184, 250, 10, 2, 79, 74, 197, - 129, 3, 3, 84, 79, 89, 2, 191, 242, 14, 72, 2, 131, 170, 15, 85, 4, 176, - 198, 11, 5, 76, 32, 80, 79, 76, 187, 15, 82, 133, 1, 41, 8, 73, 78, 65, + 82, 32, 164, 2, 5, 83, 73, 71, 78, 32, 191, 179, 13, 68, 54, 42, 65, 50, + 69, 66, 73, 50, 79, 47, 85, 11, 242, 151, 15, 78, 202, 17, 66, 2, 72, 3, + 74, 15, 158, 171, 13, 78, 158, 114, 76, 166, 111, 84, 174, 28, 71, 3, 77, + 11, 170, 226, 14, 68, 162, 70, 72, 2, 83, 3, 84, 11, 198, 167, 15, 78, + 86, 76, 2, 80, 3, 89, 11, 238, 167, 15, 67, 2, 68, 2, 75, 3, 82, 10, 100, + 2, 77, 85, 20, 3, 83, 85, 84, 230, 113, 73, 184, 250, 10, 2, 79, 74, 197, + 129, 3, 3, 84, 79, 89, 2, 243, 237, 14, 72, 2, 183, 165, 15, 85, 4, 228, + 193, 11, 5, 76, 32, 80, 79, 76, 187, 15, 82, 133, 1, 41, 8, 73, 78, 65, 71, 65, 82, 73, 32, 130, 1, 140, 1, 7, 76, 69, 84, 84, 69, 82, 32, 248, 1, 5, 83, 73, 71, 78, 32, 52, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, - 32, 251, 230, 4, 72, 94, 210, 1, 86, 194, 201, 11, 65, 38, 68, 82, 82, + 32, 175, 226, 4, 72, 94, 210, 1, 86, 246, 196, 11, 65, 38, 68, 82, 82, 34, 84, 230, 5, 85, 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 89, 186, 2, - 69, 3, 79, 6, 242, 152, 5, 79, 195, 142, 10, 65, 10, 230, 251, 9, 83, - 230, 208, 1, 65, 187, 151, 3, 86, 24, 234, 237, 4, 80, 166, 42, 86, 174, + 69, 3, 79, 6, 166, 148, 5, 79, 195, 142, 10, 65, 10, 154, 247, 9, 83, + 230, 208, 1, 65, 187, 151, 3, 86, 24, 158, 233, 4, 80, 166, 42, 86, 174, 183, 6, 65, 38, 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 4, 162, 48, - 68, 175, 180, 14, 80, 4, 206, 165, 15, 83, 15, 72, 254, 4, 216, 1, 3, 71, + 68, 227, 175, 14, 80, 4, 130, 161, 15, 83, 15, 72, 254, 4, 216, 1, 3, 71, 65, 84, 192, 7, 6, 73, 84, 72, 69, 82, 32, 194, 3, 83, 136, 1, 2, 85, 84, - 242, 1, 87, 148, 16, 3, 88, 84, 32, 180, 191, 8, 4, 80, 84, 85, 78, 148, + 242, 1, 87, 148, 16, 3, 88, 84, 32, 232, 186, 8, 4, 80, 84, 85, 78, 148, 144, 3, 2, 67, 75, 166, 163, 2, 82, 235, 146, 1, 76, 162, 1, 152, 1, 4, - 73, 86, 69, 32, 129, 249, 12, 27, 69, 68, 32, 68, 79, 85, 66, 76, 69, 32, + 73, 86, 69, 32, 181, 244, 12, 27, 69, 68, 32, 68, 79, 85, 66, 76, 69, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, 82, 32, 68, 79, 85, 66, 160, 1, 152, 1, 8, 67, 73, 82, 67, 76, 69, 68, 32, 224, 1, 9, 68, 73, 65, 71, - 79, 78, 65, 76, 32, 184, 1, 8, 83, 81, 85, 65, 82, 69, 68, 32, 143, 212, + 79, 78, 65, 76, 32, 184, 1, 8, 83, 81, 85, 65, 82, 69, 68, 32, 195, 207, 8, 65, 78, 112, 5, 68, 73, 71, 73, 84, 28, 7, 78, 85, 77, 66, 69, 82, 32, - 180, 3, 2, 76, 65, 234, 245, 13, 84, 151, 4, 83, 2, 157, 174, 13, 2, 32, - 90, 20, 50, 84, 194, 133, 2, 69, 46, 70, 42, 78, 31, 83, 6, 130, 135, 2, - 72, 47, 87, 6, 38, 77, 238, 219, 13, 67, 183, 4, 68, 2, 49, 10, 73, 68, + 180, 3, 2, 76, 65, 158, 241, 13, 84, 151, 4, 83, 2, 209, 169, 13, 2, 32, + 90, 20, 50, 84, 246, 128, 2, 69, 46, 70, 42, 78, 31, 83, 6, 182, 130, 2, + 72, 47, 87, 6, 38, 77, 162, 215, 13, 67, 183, 4, 68, 2, 49, 10, 73, 68, 68, 76, 69, 32, 82, 73, 71, 72, 2, 17, 2, 84, 32, 2, 41, 8, 84, 79, 32, - 76, 79, 87, 69, 82, 2, 249, 152, 12, 2, 32, 67, 74, 142, 1, 76, 70, 85, - 202, 170, 12, 68, 138, 29, 81, 140, 131, 1, 2, 67, 82, 226, 19, 65, 234, - 19, 73, 2, 87, 150, 8, 82, 198, 159, 1, 80, 3, 83, 54, 26, 65, 199, 247, - 10, 69, 52, 217, 250, 8, 5, 84, 73, 78, 32, 67, 2, 219, 250, 13, 80, 18, + 76, 79, 87, 69, 82, 2, 173, 148, 12, 2, 32, 67, 74, 142, 1, 76, 70, 85, + 254, 165, 12, 68, 138, 29, 81, 140, 131, 1, 2, 67, 82, 226, 19, 65, 234, + 19, 73, 2, 87, 150, 8, 82, 198, 159, 1, 80, 3, 83, 54, 26, 65, 251, 242, + 10, 69, 52, 141, 246, 8, 5, 84, 73, 78, 32, 67, 2, 143, 246, 13, 80, 18, 158, 1, 65, 216, 1, 17, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 78, 32, 78, 79, 82, 32, 37, 14, 76, 69, 83, 83, 45, 84, 72, 65, 78, 32, 78, 79, 82, 32, 6, 92, 3, 32, 83, 85, 85, 16, 80, 80, 82, 79, 88, 73, 77, 65, - 84, 69, 76, 89, 32, 78, 79, 82, 4, 30, 66, 1, 3, 80, 69, 82, 2, 245, 250, - 6, 8, 83, 69, 84, 32, 79, 70, 32, 78, 2, 237, 48, 5, 32, 65, 67, 84, 85, - 6, 178, 150, 8, 69, 167, 237, 4, 76, 6, 142, 150, 8, 69, 131, 237, 4, 71, - 6, 26, 84, 227, 143, 13, 83, 4, 76, 5, 73, 78, 71, 32, 68, 145, 221, 10, - 8, 32, 87, 73, 84, 72, 32, 69, 71, 2, 217, 129, 8, 2, 79, 76, 64, 40, 4, - 82, 65, 76, 32, 211, 222, 14, 69, 62, 48, 6, 67, 72, 69, 83, 83, 32, 243, - 217, 14, 70, 60, 74, 75, 238, 182, 13, 66, 38, 69, 150, 5, 80, 22, 81, - 38, 82, 131, 2, 84, 20, 44, 5, 78, 73, 71, 72, 84, 147, 184, 13, 73, 15, - 191, 184, 13, 32, 246, 2, 70, 32, 184, 8, 2, 65, 32, 252, 6, 3, 76, 73, - 78, 155, 224, 3, 83, 174, 1, 90, 77, 64, 4, 83, 72, 69, 81, 20, 8, 84, - 65, 73, 32, 76, 85, 69, 32, 175, 248, 13, 76, 4, 25, 4, 79, 79, 78, 32, - 4, 190, 148, 8, 87, 183, 234, 5, 83, 2, 223, 199, 9, 69, 166, 1, 160, 1, + 84, 69, 76, 89, 32, 78, 79, 82, 4, 30, 66, 1, 3, 80, 69, 82, 2, 169, 246, + 6, 8, 83, 69, 84, 32, 79, 70, 32, 78, 2, 233, 48, 5, 32, 65, 67, 84, 85, + 6, 230, 145, 8, 69, 167, 237, 4, 76, 6, 194, 145, 8, 69, 131, 237, 4, 71, + 6, 26, 84, 151, 139, 13, 83, 4, 76, 5, 73, 78, 71, 32, 68, 197, 216, 10, + 8, 32, 87, 73, 84, 72, 32, 69, 71, 2, 141, 253, 7, 2, 79, 76, 64, 40, 4, + 82, 65, 76, 32, 135, 218, 14, 69, 62, 48, 6, 67, 72, 69, 83, 83, 32, 167, + 213, 14, 70, 60, 74, 75, 162, 178, 13, 66, 38, 69, 150, 5, 80, 22, 81, + 38, 82, 131, 2, 84, 20, 44, 5, 78, 73, 71, 72, 84, 199, 179, 13, 73, 15, + 243, 179, 13, 32, 246, 2, 70, 32, 184, 8, 2, 65, 32, 252, 6, 3, 76, 73, + 78, 207, 219, 3, 83, 174, 1, 90, 77, 64, 4, 83, 72, 69, 81, 20, 8, 84, + 65, 73, 32, 76, 85, 69, 32, 227, 243, 13, 76, 4, 25, 4, 79, 79, 78, 32, + 4, 242, 143, 8, 87, 183, 234, 5, 83, 2, 147, 195, 9, 69, 166, 1, 160, 1, 7, 76, 69, 84, 84, 69, 82, 32, 244, 2, 8, 83, 73, 71, 78, 32, 76, 65, 69, - 22, 84, 76, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 231, 154, 13, + 22, 84, 76, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 155, 150, 13, 68, 102, 76, 6, 70, 73, 78, 65, 76, 32, 68, 4, 72, 73, 71, 72, 1, 3, 76, - 79, 87, 14, 238, 147, 13, 78, 130, 254, 1, 66, 2, 68, 2, 75, 2, 77, 3, - 86, 44, 11, 32, 44, 146, 1, 75, 2, 88, 34, 83, 234, 153, 11, 78, 246, + 79, 87, 14, 162, 143, 13, 78, 130, 254, 1, 66, 2, 68, 2, 75, 2, 77, 3, + 86, 44, 11, 32, 44, 146, 1, 75, 2, 88, 34, 83, 158, 149, 11, 78, 246, 173, 3, 84, 82, 80, 138, 69, 66, 2, 68, 2, 70, 2, 72, 2, 76, 2, 77, 2, - 81, 2, 86, 3, 89, 4, 210, 141, 15, 86, 187, 2, 65, 4, 178, 141, 15, 85, - 187, 2, 65, 5, 203, 143, 15, 86, 6, 168, 160, 7, 3, 79, 78, 69, 221, 80, + 81, 2, 86, 3, 89, 4, 134, 137, 15, 86, 187, 2, 65, 4, 230, 136, 15, 85, + 187, 2, 65, 5, 255, 138, 15, 86, 6, 220, 155, 7, 3, 79, 78, 69, 221, 80, 8, 72, 65, 77, 32, 68, 73, 71, 73, 34, 110, 65, 46, 73, 30, 79, 38, 85, - 188, 191, 12, 11, 86, 79, 87, 69, 76, 32, 83, 72, 79, 82, 84, 215, 205, - 2, 69, 8, 222, 252, 10, 65, 158, 145, 4, 69, 3, 89, 4, 206, 141, 15, 73, - 3, 89, 9, 150, 252, 10, 65, 159, 145, 4, 89, 11, 242, 251, 10, 69, 158, + 240, 186, 12, 11, 86, 79, 87, 69, 76, 32, 83, 72, 79, 82, 84, 215, 205, + 2, 69, 8, 146, 248, 10, 65, 158, 145, 4, 69, 3, 89, 4, 130, 137, 15, 73, + 3, 89, 9, 202, 247, 10, 65, 159, 145, 4, 89, 11, 166, 247, 10, 69, 158, 145, 4, 85, 3, 89, 194, 1, 182, 1, 68, 106, 71, 72, 7, 76, 69, 84, 84, - 69, 82, 32, 214, 2, 83, 198, 23, 80, 190, 139, 1, 86, 210, 240, 7, 65, + 69, 82, 32, 214, 2, 83, 194, 23, 80, 246, 134, 1, 86, 210, 240, 7, 65, 180, 238, 1, 5, 73, 78, 83, 69, 82, 206, 175, 1, 67, 255, 196, 2, 79, 26, - 64, 6, 79, 85, 66, 76, 69, 32, 238, 170, 11, 65, 255, 235, 1, 73, 4, 222, - 170, 11, 68, 179, 138, 1, 67, 2, 11, 65, 2, 11, 80, 2, 17, 2, 32, 70, 2, - 189, 156, 11, 2, 73, 76, 108, 218, 1, 78, 62, 86, 238, 169, 11, 65, 38, + 64, 6, 79, 85, 66, 76, 69, 32, 162, 166, 11, 65, 255, 235, 1, 73, 4, 146, + 166, 11, 68, 179, 138, 1, 67, 2, 11, 65, 2, 11, 80, 2, 17, 2, 32, 70, 2, + 241, 151, 11, 2, 73, 76, 108, 218, 1, 78, 62, 86, 162, 165, 11, 65, 38, 68, 114, 84, 230, 5, 85, 186, 202, 1, 73, 182, 196, 1, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 138, 69, 72, 2, 87, 2, - 89, 186, 2, 69, 3, 79, 14, 218, 192, 14, 71, 2, 89, 138, 69, 72, 2, 78, - 187, 2, 65, 10, 26, 69, 235, 176, 11, 79, 2, 157, 206, 12, 3, 68, 73, 67, - 22, 26, 73, 131, 202, 4, 65, 20, 44, 3, 71, 78, 32, 225, 174, 9, 2, 68, - 68, 18, 246, 232, 10, 67, 98, 78, 190, 66, 65, 190, 158, 1, 74, 228, 2, - 5, 70, 73, 78, 65, 76, 50, 85, 235, 245, 1, 86, 4, 219, 218, 14, 69, 4, - 178, 246, 9, 80, 231, 243, 3, 76, 6, 70, 78, 233, 237, 13, 11, 71, 72, - 84, 32, 87, 73, 84, 72, 32, 83, 84, 4, 252, 246, 7, 7, 69, 32, 80, 79, + 89, 186, 2, 69, 3, 79, 14, 142, 188, 14, 71, 2, 89, 138, 69, 72, 2, 78, + 187, 2, 65, 10, 26, 69, 159, 172, 11, 79, 2, 209, 201, 12, 3, 68, 73, 67, + 22, 26, 73, 183, 197, 4, 65, 20, 44, 3, 71, 78, 32, 149, 170, 9, 2, 68, + 68, 18, 170, 228, 10, 67, 98, 78, 190, 66, 65, 190, 158, 1, 74, 228, 2, + 5, 70, 73, 78, 65, 76, 50, 85, 235, 245, 1, 86, 4, 143, 214, 14, 69, 4, + 230, 241, 9, 80, 231, 243, 3, 76, 6, 70, 78, 157, 233, 13, 11, 71, 72, + 84, 32, 87, 73, 84, 72, 32, 83, 84, 4, 176, 242, 7, 7, 69, 32, 80, 79, 73, 78, 84, 179, 139, 7, 74, 124, 152, 1, 3, 67, 79, 77, 130, 3, 68, 78, - 76, 156, 4, 4, 72, 73, 71, 72, 72, 7, 83, 89, 77, 66, 79, 76, 32, 134, - 223, 7, 69, 229, 193, 1, 3, 84, 65, 77, 20, 52, 7, 66, 73, 78, 73, 78, - 71, 32, 159, 128, 15, 77, 18, 88, 3, 68, 79, 85, 32, 5, 76, 79, 78, 71, - 32, 78, 78, 33, 6, 83, 72, 79, 82, 84, 32, 2, 149, 129, 14, 3, 66, 76, - 69, 8, 142, 1, 72, 34, 76, 198, 138, 11, 82, 21, 7, 68, 69, 83, 67, 69, - 78, 68, 2, 11, 65, 2, 187, 216, 10, 83, 6, 34, 72, 34, 76, 199, 138, 11, - 82, 2, 141, 139, 11, 3, 73, 71, 72, 2, 237, 138, 11, 2, 79, 87, 24, 152, - 1, 4, 65, 78, 84, 65, 232, 222, 12, 4, 79, 82, 79, 77, 143, 44, 73, 70, + 76, 156, 4, 4, 72, 73, 71, 72, 72, 7, 83, 89, 77, 66, 79, 76, 32, 186, + 218, 7, 69, 229, 193, 1, 3, 84, 65, 77, 20, 52, 7, 66, 73, 78, 73, 78, + 71, 32, 211, 251, 14, 77, 18, 88, 3, 68, 79, 85, 32, 5, 76, 79, 78, 71, + 32, 78, 78, 33, 6, 83, 72, 79, 82, 84, 32, 2, 201, 252, 13, 3, 66, 76, + 69, 8, 142, 1, 72, 34, 76, 250, 133, 11, 82, 21, 7, 68, 69, 83, 67, 69, + 78, 68, 2, 11, 65, 2, 239, 211, 10, 83, 6, 34, 72, 34, 76, 251, 133, 11, + 82, 2, 193, 134, 11, 3, 73, 71, 72, 2, 161, 134, 11, 2, 79, 87, 24, 152, + 1, 4, 65, 78, 84, 65, 156, 218, 12, 4, 79, 82, 79, 77, 143, 44, 73, 70, 76, 4, 65, 74, 65, 78, 32, 6, 69, 84, 84, 69, 82, 32, 173, 3, 2, 79, 87, - 2, 209, 178, 13, 3, 89, 65, 76, 66, 228, 1, 2, 68, 65, 42, 74, 90, 78, - 234, 158, 11, 82, 210, 147, 1, 79, 138, 76, 67, 138, 189, 1, 69, 250, 18, + 2, 133, 174, 13, 3, 89, 65, 76, 66, 228, 1, 2, 68, 65, 42, 74, 90, 78, + 158, 154, 11, 82, 210, 147, 1, 79, 138, 76, 67, 138, 189, 1, 69, 250, 18, 71, 242, 42, 66, 2, 70, 2, 72, 2, 75, 2, 76, 2, 77, 2, 80, 2, 83, 2, 84, - 2, 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 5, 165, 194, 11, 5, 71, 66, 65, - 83, 73, 8, 40, 4, 79, 78, 65, 32, 151, 252, 14, 65, 6, 234, 254, 12, 67, - 242, 250, 1, 74, 3, 82, 11, 26, 65, 1, 2, 89, 65, 5, 169, 141, 8, 5, 32, - 87, 79, 76, 79, 2, 29, 5, 32, 84, 79, 78, 69, 2, 17, 2, 32, 65, 2, 223, - 211, 8, 80, 4, 68, 7, 71, 66, 65, 75, 85, 82, 85, 1, 6, 79, 79, 32, 68, - 69, 78, 2, 143, 164, 13, 78, 186, 1, 94, 32, 156, 3, 2, 77, 73, 118, 78, - 150, 1, 82, 238, 7, 84, 206, 213, 6, 83, 223, 215, 7, 45, 18, 202, 1, 66, - 96, 5, 69, 78, 84, 82, 89, 22, 80, 224, 186, 2, 15, 79, 78, 69, 32, 85, + 2, 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 5, 217, 189, 11, 5, 71, 66, 65, + 83, 73, 8, 40, 4, 79, 78, 65, 32, 203, 247, 14, 65, 6, 158, 250, 12, 67, + 242, 250, 1, 74, 3, 82, 11, 26, 65, 1, 2, 89, 65, 5, 221, 136, 8, 5, 32, + 87, 79, 76, 79, 2, 29, 5, 32, 84, 79, 78, 69, 2, 17, 2, 32, 65, 2, 147, + 207, 8, 80, 4, 68, 7, 71, 66, 65, 75, 85, 82, 85, 1, 6, 79, 79, 32, 68, + 69, 78, 2, 195, 159, 13, 78, 186, 1, 94, 32, 156, 3, 2, 77, 73, 118, 78, + 150, 1, 82, 234, 7, 84, 134, 209, 6, 83, 223, 215, 7, 45, 18, 202, 1, 66, + 96, 5, 69, 78, 84, 82, 89, 22, 80, 148, 182, 2, 15, 79, 78, 69, 32, 85, 78, 68, 69, 82, 32, 69, 73, 71, 72, 84, 164, 134, 4, 9, 77, 79, 66, 73, 76, 69, 32, 80, 72, 189, 30, 3, 83, 77, 79, 4, 52, 4, 82, 69, 65, 75, - 173, 137, 2, 3, 73, 67, 89, 2, 17, 2, 32, 72, 2, 199, 212, 13, 69, 5, - 251, 239, 13, 32, 4, 60, 6, 69, 68, 69, 83, 84, 82, 193, 212, 9, 3, 73, - 82, 65, 2, 237, 174, 11, 2, 73, 65, 4, 36, 5, 78, 65, 76, 32, 68, 59, 83, - 2, 209, 223, 13, 9, 73, 71, 73, 84, 32, 83, 72, 65, 80, 2, 139, 160, 11, - 77, 6, 38, 45, 221, 228, 9, 3, 70, 79, 82, 4, 76, 8, 66, 82, 69, 65, 75, - 73, 78, 71, 181, 169, 2, 5, 80, 79, 84, 65, 66, 2, 161, 227, 6, 2, 32, - 72, 97, 56, 2, 84, 72, 146, 11, 77, 181, 244, 10, 3, 68, 73, 67, 88, 42, - 32, 225, 210, 6, 4, 69, 65, 83, 84, 86, 96, 5, 69, 65, 83, 84, 32, 148, - 2, 6, 73, 78, 68, 73, 67, 32, 221, 1, 5, 87, 69, 83, 84, 32, 32, 82, 65, - 150, 248, 6, 80, 130, 1, 84, 190, 207, 4, 66, 38, 68, 18, 83, 251, 58, - 87, 14, 40, 4, 82, 82, 79, 87, 255, 243, 6, 78, 13, 11, 32, 10, 96, 9, - 67, 82, 79, 83, 83, 73, 78, 71, 32, 248, 2, 2, 65, 78, 202, 243, 6, 87, - 131, 145, 5, 70, 4, 190, 198, 3, 83, 187, 175, 3, 78, 20, 54, 80, 60, 3, - 81, 85, 65, 66, 82, 199, 132, 1, 70, 2, 37, 7, 76, 65, 67, 69, 72, 79, - 76, 2, 251, 180, 4, 68, 4, 228, 180, 4, 2, 82, 84, 249, 248, 9, 5, 78, - 84, 73, 84, 89, 2, 17, 2, 85, 80, 2, 179, 167, 4, 69, 34, 82, 65, 166, - 244, 6, 80, 130, 1, 84, 190, 207, 4, 66, 38, 68, 18, 83, 251, 58, 87, 16, - 34, 78, 33, 4, 82, 82, 79, 87, 2, 197, 195, 3, 3, 68, 32, 83, 15, 11, 32, - 12, 84, 3, 84, 79, 32, 182, 239, 6, 67, 40, 3, 65, 78, 68, 234, 2, 87, - 131, 145, 5, 70, 4, 190, 240, 6, 67, 173, 216, 6, 4, 76, 79, 78, 71, 56, - 54, 32, 236, 5, 5, 67, 72, 69, 68, 32, 207, 2, 69, 38, 162, 1, 65, 132, - 2, 4, 78, 79, 82, 77, 78, 80, 46, 83, 170, 1, 84, 154, 227, 7, 69, 196, - 33, 7, 73, 68, 69, 78, 84, 73, 67, 190, 203, 4, 71, 38, 76, 135, 80, 67, - 10, 88, 3, 32, 83, 85, 52, 7, 78, 32, 69, 76, 69, 77, 69, 28, 2, 83, 89, - 171, 134, 8, 76, 4, 30, 66, 1, 3, 80, 69, 82, 2, 29, 2, 83, 69, 2, 11, - 78, 2, 211, 125, 84, 2, 37, 7, 77, 80, 84, 79, 84, 73, 67, 2, 17, 2, 65, - 76, 2, 233, 134, 8, 2, 76, 89, 4, 149, 201, 6, 14, 65, 76, 32, 83, 85, - 66, 71, 82, 79, 85, 80, 32, 79, 70, 2, 185, 134, 8, 6, 65, 82, 65, 76, - 76, 69, 6, 48, 6, 81, 85, 65, 82, 69, 32, 167, 224, 13, 73, 4, 68, 5, 73, - 77, 65, 71, 69, 1, 8, 79, 82, 73, 71, 73, 78, 65, 76, 2, 21, 3, 32, 79, - 70, 2, 151, 199, 6, 32, 4, 174, 214, 10, 82, 207, 242, 1, 73, 8, 58, 76, - 40, 4, 82, 73, 71, 72, 133, 1, 3, 85, 80, 80, 4, 36, 2, 69, 70, 133, 1, - 2, 79, 87, 2, 89, 20, 84, 32, 83, 69, 77, 73, 67, 73, 82, 67, 76, 69, 32, - 87, 73, 84, 72, 32, 84, 72, 2, 17, 2, 82, 69, 2, 187, 145, 13, 69, 2, 11, - 69, 2, 41, 8, 82, 32, 82, 73, 71, 72, 84, 45, 2, 205, 148, 3, 6, 83, 72, - 65, 68, 79, 87, 11, 34, 32, 53, 4, 66, 79, 79, 75, 4, 17, 2, 80, 65, 4, - 142, 204, 14, 71, 215, 22, 68, 5, 81, 18, 32, 87, 73, 84, 72, 32, 68, 69, - 67, 79, 82, 65, 84, 73, 86, 69, 32, 67, 2, 179, 142, 4, 79, 186, 6, 102, - 77, 176, 3, 4, 83, 72, 85, 32, 216, 183, 5, 8, 84, 32, 65, 78, 68, 32, - 66, 79, 191, 169, 8, 76, 26, 36, 4, 66, 69, 82, 32, 247, 2, 69, 24, 58, - 69, 50, 70, 42, 83, 66, 84, 57, 4, 78, 73, 78, 69, 4, 204, 1, 3, 73, 71, - 72, 21, 3, 76, 69, 86, 4, 144, 1, 2, 79, 85, 13, 2, 73, 70, 6, 34, 73, - 85, 4, 69, 86, 69, 78, 4, 82, 88, 223, 142, 14, 71, 8, 40, 2, 72, 73, 46, - 69, 21, 2, 87, 69, 2, 11, 82, 2, 17, 2, 84, 69, 2, 11, 69, 2, 203, 204, - 7, 78, 4, 180, 204, 7, 3, 76, 86, 69, 1, 3, 78, 84, 89, 2, 255, 247, 6, - 82, 154, 6, 72, 12, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 215, - 182, 12, 73, 152, 6, 18, 49, 87, 50, 160, 2, 222, 1, 55, 2, 56, 2, 57, 2, - 65, 2, 66, 2, 67, 2, 68, 2, 69, 3, 70, 248, 3, 138, 1, 48, 2, 49, 2, 50, - 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, - 68, 2, 69, 143, 1, 70, 32, 242, 218, 14, 48, 2, 49, 2, 50, 2, 51, 2, 52, - 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, 68, 2, 69, 3, - 70, 24, 230, 217, 14, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, - 55, 2, 56, 2, 57, 2, 65, 3, 66, 142, 1, 118, 76, 226, 3, 83, 164, 2, 5, - 84, 79, 78, 69, 45, 196, 230, 7, 8, 67, 73, 82, 67, 76, 69, 68, 32, 179, - 247, 4, 68, 92, 88, 6, 69, 84, 84, 69, 82, 32, 173, 163, 1, 10, 79, 71, - 79, 71, 82, 65, 77, 32, 78, 89, 90, 130, 2, 78, 90, 84, 166, 220, 7, 88, - 182, 230, 2, 65, 144, 1, 2, 72, 65, 226, 51, 82, 210, 147, 1, 79, 150, - 61, 68, 2, 77, 2, 80, 254, 203, 1, 69, 234, 61, 67, 2, 70, 2, 71, 2, 75, - 2, 76, 2, 81, 2, 83, 2, 86, 2, 89, 2, 90, 186, 2, 73, 2, 85, 3, 87, 22, - 86, 84, 174, 200, 12, 80, 230, 137, 2, 67, 2, 75, 2, 81, 2, 82, 2, 89, - 187, 2, 65, 6, 142, 210, 14, 83, 2, 88, 187, 2, 65, 14, 64, 4, 73, 71, - 78, 32, 189, 1, 7, 89, 76, 76, 65, 66, 76, 69, 12, 56, 4, 70, 79, 82, 32, - 129, 213, 13, 4, 88, 87, 32, 88, 10, 204, 9, 2, 76, 79, 230, 164, 3, 84, - 156, 94, 8, 73, 78, 86, 69, 82, 84, 69, 66, 232, 144, 4, 3, 65, 78, 73, - 195, 177, 2, 80, 2, 177, 132, 12, 4, 32, 76, 69, 78, 14, 250, 209, 14, - 66, 2, 68, 2, 71, 2, 74, 2, 77, 2, 83, 3, 86, 254, 14, 226, 2, 66, 226, - 1, 67, 226, 5, 71, 244, 6, 4, 73, 76, 32, 68, 22, 76, 198, 69, 78, 150, - 5, 80, 234, 7, 82, 242, 10, 83, 188, 8, 2, 84, 84, 154, 8, 85, 248, 1, 3, - 86, 69, 82, 254, 170, 2, 89, 148, 151, 4, 14, 70, 70, 73, 67, 69, 32, 66, - 85, 73, 76, 68, 73, 78, 71, 154, 185, 1, 72, 146, 132, 2, 75, 210, 250, - 1, 68, 194, 64, 77, 246, 9, 87, 211, 139, 1, 88, 10, 132, 1, 6, 76, 73, - 81, 85, 69, 32, 252, 158, 2, 9, 83, 69, 82, 86, 69, 82, 32, 69, 89, 189, - 29, 8, 74, 69, 67, 84, 32, 82, 69, 80, 6, 172, 203, 4, 13, 65, 78, 71, - 76, 69, 32, 79, 80, 69, 78, 73, 78, 71, 171, 241, 1, 72, 28, 56, 2, 82, - 32, 234, 4, 84, 225, 198, 5, 3, 67, 85, 76, 22, 156, 1, 11, 65, 77, 79, - 85, 78, 84, 32, 79, 70, 32, 67, 22, 66, 198, 1, 67, 118, 68, 106, 70, 0, - 10, 73, 78, 86, 69, 82, 84, 69, 68, 32, 70, 243, 241, 12, 72, 2, 203, - 184, 5, 72, 6, 136, 1, 15, 82, 65, 78, 67, 72, 32, 66, 65, 78, 75, 32, - 73, 68, 69, 78, 156, 131, 5, 5, 69, 76, 84, 32, 66, 205, 144, 6, 3, 79, - 87, 32, 2, 21, 3, 84, 73, 70, 2, 11, 73, 2, 131, 132, 11, 67, 4, 92, 17, - 85, 83, 84, 79, 77, 69, 82, 32, 65, 67, 67, 79, 85, 78, 84, 32, 78, 243, - 201, 1, 72, 2, 159, 161, 6, 85, 4, 44, 5, 79, 85, 66, 76, 69, 147, 221, - 12, 65, 2, 11, 32, 2, 11, 66, 2, 157, 163, 7, 3, 65, 67, 75, 2, 191, 134, - 14, 79, 4, 160, 251, 8, 4, 65, 71, 79, 78, 197, 195, 3, 2, 79, 80, 60, - 48, 4, 72, 65, 77, 32, 185, 195, 14, 2, 79, 78, 58, 122, 70, 0, 10, 82, - 69, 86, 69, 82, 83, 69, 68, 32, 70, 36, 7, 76, 69, 84, 84, 69, 82, 32, - 149, 254, 3, 3, 83, 80, 65, 2, 161, 139, 4, 4, 69, 65, 84, 72, 52, 196, - 1, 2, 65, 73, 22, 66, 2, 80, 34, 67, 36, 2, 69, 65, 64, 2, 70, 69, 22, - 71, 22, 73, 58, 76, 2, 82, 22, 78, 46, 79, 34, 83, 46, 85, 222, 184, 1, - 77, 170, 9, 68, 189, 227, 11, 3, 84, 73, 78, 2, 155, 179, 14, 76, 2, 11, - 69, 2, 219, 190, 12, 73, 4, 226, 151, 8, 69, 183, 161, 4, 79, 6, 138, 1, - 66, 2, 68, 153, 143, 4, 6, 77, 72, 65, 78, 67, 72, 2, 247, 175, 9, 65, 2, - 183, 187, 13, 79, 4, 32, 2, 79, 68, 191, 194, 13, 70, 2, 195, 137, 8, 72, - 2, 243, 154, 12, 85, 4, 132, 172, 13, 3, 71, 69, 65, 247, 69, 73, 4, 218, - 241, 13, 78, 227, 79, 82, 4, 202, 225, 12, 65, 229, 93, 3, 84, 82, 65, 6, - 60, 5, 73, 76, 76, 69, 65, 186, 187, 12, 65, 251, 132, 2, 82, 2, 207, - 240, 13, 78, 2, 247, 148, 13, 82, 182, 8, 38, 32, 142, 11, 68, 255, 183, - 13, 73, 184, 1, 64, 6, 67, 72, 73, 75, 73, 32, 205, 6, 5, 79, 78, 65, 76, - 32, 96, 132, 1, 7, 76, 69, 84, 84, 69, 82, 32, 148, 3, 2, 77, 85, 62, 71, - 74, 80, 164, 216, 3, 2, 82, 69, 202, 237, 8, 68, 211, 173, 1, 65, 60, 50, - 65, 98, 69, 54, 73, 50, 76, 62, 79, 51, 85, 16, 50, 65, 210, 188, 14, 78, - 86, 71, 2, 76, 3, 84, 8, 162, 189, 14, 74, 2, 75, 2, 77, 3, 87, 8, 214, - 246, 13, 68, 198, 13, 82, 222, 56, 78, 3, 80, 8, 250, 170, 14, 78, 202, - 17, 72, 2, 82, 3, 83, 12, 162, 170, 10, 65, 242, 145, 4, 69, 2, 73, 2, - 79, 3, 85, 8, 170, 159, 14, 84, 174, 28, 66, 2, 72, 3, 86, 8, 198, 235, - 13, 78, 226, 79, 67, 2, 68, 3, 89, 4, 56, 2, 45, 71, 209, 206, 12, 6, 32, - 84, 84, 85, 68, 68, 2, 205, 206, 12, 13, 65, 65, 72, 76, 65, 65, 32, 84, - 84, 85, 68, 68, 65, 6, 84, 11, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, - 32, 177, 224, 6, 4, 72, 65, 65, 82, 4, 48, 8, 68, 79, 85, 66, 76, 69, 32, - 77, 3, 77, 2, 185, 242, 13, 3, 85, 67, 65, 88, 100, 7, 76, 69, 84, 84, - 69, 82, 32, 192, 2, 5, 83, 73, 71, 78, 32, 206, 193, 8, 65, 207, 255, 3, - 68, 60, 42, 65, 54, 69, 58, 73, 54, 79, 59, 85, 13, 178, 183, 14, 66, 2, - 68, 2, 72, 2, 76, 3, 87, 13, 158, 231, 13, 78, 226, 79, 67, 2, 71, 2, 72, - 3, 83, 13, 238, 205, 8, 84, 218, 232, 5, 68, 2, 78, 3, 80, 13, 182, 253, - 13, 82, 138, 56, 78, 86, 77, 2, 79, 3, 89, 13, 186, 239, 13, 68, 218, 52, - 78, 202, 17, 74, 2, 75, 3, 82, 6, 58, 73, 144, 246, 12, 4, 72, 79, 68, - 68, 239, 153, 1, 77, 2, 131, 182, 1, 75, 252, 6, 34, 32, 165, 57, 3, 69, - 82, 32, 246, 6, 240, 2, 8, 67, 72, 73, 78, 69, 83, 69, 32, 44, 10, 72, - 85, 78, 71, 65, 82, 73, 65, 78, 32, 128, 7, 7, 73, 84, 65, 76, 73, 67, - 32, 212, 4, 14, 78, 79, 82, 84, 72, 32, 65, 82, 65, 66, 73, 65, 78, 32, - 196, 4, 3, 80, 69, 82, 216, 13, 2, 83, 79, 144, 13, 14, 84, 85, 82, 75, - 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 132, 7, 7, 85, 89, 71, 72, 85, - 82, 32, 171, 225, 11, 75, 4, 146, 139, 12, 73, 241, 96, 3, 72, 79, 79, - 216, 1, 96, 6, 67, 65, 80, 73, 84, 65, 0, 4, 83, 77, 65, 76, 233, 5, 7, - 78, 85, 77, 66, 69, 82, 32, 102, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, - 32, 102, 214, 1, 65, 54, 69, 168, 2, 10, 78, 73, 75, 79, 76, 83, 66, 85, - 82, 71, 0, 9, 82, 85, 68, 73, 77, 69, 78, 84, 65, 42, 79, 32, 5, 83, 72, - 79, 82, 84, 22, 85, 168, 242, 3, 5, 67, 76, 79, 83, 69, 243, 171, 8, 73, - 11, 154, 240, 12, 77, 218, 119, 78, 162, 70, 65, 3, 75, 63, 178, 1, 77, - 22, 78, 78, 83, 182, 130, 10, 67, 254, 23, 71, 2, 76, 2, 84, 198, 135, 2, - 90, 218, 137, 2, 66, 2, 68, 2, 69, 2, 70, 2, 72, 2, 74, 2, 75, 2, 80, 2, - 82, 3, 86, 5, 171, 172, 14, 80, 11, 34, 84, 246, 171, 14, 67, 3, 89, 5, - 197, 149, 2, 5, 45, 83, 72, 65, 80, 5, 203, 171, 14, 90, 4, 11, 32, 4, - 214, 148, 14, 79, 3, 85, 7, 186, 148, 14, 69, 215, 22, 79, 2, 131, 237, - 13, 32, 9, 194, 167, 14, 78, 154, 3, 83, 3, 85, 12, 210, 4, 70, 242, 131, - 6, 79, 239, 203, 6, 84, 78, 80, 7, 76, 69, 84, 84, 69, 82, 32, 169, 3, 8, - 78, 85, 77, 69, 82, 65, 76, 32, 70, 190, 1, 69, 90, 75, 50, 83, 36, 3, - 78, 79, 82, 202, 207, 10, 85, 186, 202, 1, 73, 166, 140, 1, 80, 2, 84, - 150, 83, 67, 186, 22, 66, 2, 68, 2, 72, 2, 86, 2, 89, 2, 90, 214, 22, 65, - 3, 79, 23, 214, 254, 9, 83, 194, 159, 2, 82, 254, 203, 1, 75, 222, 61, - 70, 2, 76, 2, 77, 3, 78, 8, 194, 144, 14, 72, 214, 22, 65, 2, 69, 3, 85, - 4, 32, 2, 79, 85, 243, 143, 14, 72, 2, 29, 5, 84, 72, 69, 82, 78, 2, 253, - 154, 13, 2, 32, 84, 8, 38, 70, 222, 207, 12, 84, 215, 58, 79, 4, 11, 73, - 4, 242, 181, 12, 70, 143, 217, 1, 86, 64, 76, 7, 76, 69, 84, 84, 69, 82, - 32, 209, 3, 7, 78, 85, 77, 66, 69, 82, 32, 58, 210, 1, 65, 38, 71, 38, - 72, 30, 75, 38, 84, 74, 90, 234, 106, 77, 140, 158, 3, 2, 69, 83, 238, - 162, 3, 66, 2, 70, 2, 82, 2, 89, 182, 203, 3, 78, 154, 237, 1, 76, 210, - 58, 68, 146, 1, 81, 134, 3, 87, 131, 56, 83, 4, 134, 194, 3, 76, 167, - 145, 10, 73, 4, 254, 243, 12, 72, 191, 156, 1, 69, 4, 178, 161, 14, 65, - 3, 69, 4, 166, 180, 7, 72, 223, 236, 5, 65, 8, 34, 72, 210, 160, 14, 65, - 3, 69, 4, 142, 150, 13, 65, 195, 138, 1, 69, 4, 11, 65, 4, 206, 209, 13, - 73, 227, 79, 72, 6, 190, 153, 6, 84, 163, 236, 6, 79, 180, 1, 64, 11, 77, - 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 183, 5, 83, 76, 228, 1, 2, 67, - 72, 22, 68, 66, 69, 22, 73, 30, 77, 2, 78, 30, 80, 22, 83, 70, 84, 50, - 86, 38, 89, 94, 90, 254, 195, 6, 76, 2, 82, 214, 227, 2, 71, 150, 170, 2, - 79, 222, 208, 1, 66, 246, 40, 65, 254, 31, 75, 174, 45, 72, 187, 2, 85, - 2, 215, 216, 7, 69, 6, 26, 90, 183, 138, 14, 79, 4, 134, 167, 9, 72, 187, - 210, 4, 73, 5, 231, 157, 14, 70, 7, 210, 157, 14, 65, 3, 69, 2, 213, 134, - 14, 2, 69, 78, 2, 131, 198, 6, 69, 6, 26, 72, 151, 137, 14, 73, 4, 228, - 165, 9, 3, 67, 72, 79, 3, 79, 4, 26, 83, 211, 136, 14, 65, 2, 191, 247, - 13, 73, 4, 142, 165, 9, 79, 171, 190, 4, 69, 14, 60, 2, 69, 82, 218, 178, - 8, 65, 146, 215, 5, 82, 203, 17, 85, 7, 174, 155, 14, 73, 3, 85, 4, 142, - 164, 9, 72, 187, 210, 4, 65, 104, 88, 4, 73, 65, 78, 32, 241, 5, 13, 79, - 78, 65, 76, 32, 67, 79, 77, 80, 85, 84, 69, 82, 100, 80, 7, 78, 85, 77, - 66, 69, 82, 32, 80, 5, 83, 73, 71, 78, 32, 251, 222, 10, 87, 10, 42, 84, - 234, 188, 8, 72, 255, 192, 4, 79, 6, 238, 230, 1, 87, 199, 226, 11, 69, - 88, 210, 1, 65, 86, 66, 62, 68, 98, 74, 2, 86, 30, 84, 42, 88, 182, 111, - 71, 2, 75, 2, 78, 2, 82, 150, 206, 9, 77, 146, 143, 3, 83, 218, 69, 67, - 2, 70, 2, 72, 2, 76, 2, 80, 2, 89, 2, 90, 186, 2, 73, 3, 85, 9, 45, 9, - 85, 82, 65, 77, 65, 90, 68, 65, 65, 7, 170, 239, 6, 45, 139, 165, 7, 72, - 6, 38, 65, 213, 177, 10, 3, 85, 85, 77, 5, 231, 147, 14, 71, 10, 34, 65, - 234, 149, 14, 73, 3, 85, 7, 37, 7, 72, 89, 65, 65, 85, 83, 72, 5, 255, - 237, 6, 45, 4, 170, 149, 14, 65, 3, 73, 6, 214, 146, 14, 72, 186, 2, 65, - 3, 85, 4, 152, 220, 11, 8, 83, 72, 65, 65, 89, 65, 84, 72, 207, 184, 2, - 65, 5, 181, 147, 5, 31, 32, 87, 73, 84, 72, 32, 77, 79, 78, 73, 84, 79, - 82, 32, 73, 78, 32, 80, 79, 82, 84, 82, 65, 73, 84, 32, 79, 82, 73, 69, - 78, 144, 1, 92, 6, 71, 68, 73, 65, 78, 32, 141, 7, 12, 85, 84, 72, 32, - 65, 82, 65, 66, 73, 65, 78, 32, 80, 58, 70, 74, 76, 145, 5, 7, 78, 85, - 77, 66, 69, 82, 32, 2, 11, 82, 2, 201, 237, 11, 10, 65, 67, 84, 73, 79, - 78, 32, 79, 78, 69, 60, 76, 6, 69, 84, 84, 69, 82, 32, 149, 4, 8, 73, 71, - 65, 84, 85, 82, 69, 32, 58, 234, 1, 65, 96, 6, 70, 73, 78, 65, 76, 32, - 200, 1, 5, 82, 69, 83, 72, 45, 162, 216, 1, 76, 194, 170, 4, 71, 90, 90, - 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, - 78, 134, 2, 84, 2, 87, 218, 103, 80, 171, 4, 77, 6, 26, 76, 131, 143, 13, - 89, 4, 192, 133, 6, 8, 84, 69, 82, 78, 65, 84, 69, 32, 155, 214, 1, 69, - 18, 116, 3, 78, 85, 78, 0, 5, 83, 65, 68, 72, 69, 0, 3, 84, 65, 87, 190, - 216, 1, 65, 134, 211, 6, 66, 135, 203, 5, 72, 5, 41, 8, 32, 87, 73, 84, - 72, 32, 86, 69, 2, 133, 220, 5, 4, 82, 84, 73, 67, 2, 253, 215, 1, 6, 65, - 89, 73, 78, 45, 68, 18, 42, 84, 234, 131, 6, 79, 255, 148, 6, 70, 10, 42, - 72, 162, 217, 1, 87, 199, 226, 11, 69, 4, 162, 153, 12, 82, 159, 2, 73, - 64, 60, 7, 76, 69, 84, 84, 69, 82, 32, 245, 3, 3, 78, 85, 77, 58, 202, 1, - 65, 38, 68, 74, 71, 34, 75, 34, 83, 78, 84, 254, 43, 90, 254, 166, 1, 76, - 50, 81, 214, 205, 1, 82, 246, 221, 2, 89, 198, 207, 1, 72, 150, 87, 66, - 170, 225, 4, 78, 134, 2, 87, 218, 103, 70, 171, 4, 77, 4, 146, 168, 3, - 76, 167, 145, 10, 89, 6, 32, 2, 72, 65, 151, 212, 1, 65, 4, 246, 166, 8, - 76, 207, 180, 5, 68, 4, 134, 45, 72, 203, 209, 5, 73, 4, 146, 213, 7, 65, - 163, 81, 72, 8, 26, 65, 255, 135, 13, 72, 6, 218, 198, 7, 77, 234, 147, - 6, 68, 143, 45, 84, 8, 230, 90, 72, 194, 167, 11, 69, 219, 134, 1, 65, 6, - 56, 4, 66, 69, 82, 32, 145, 205, 13, 4, 69, 82, 73, 67, 4, 26, 70, 235, - 234, 12, 79, 2, 139, 149, 12, 73, 146, 1, 80, 7, 79, 82, 75, 72, 79, 78, - 32, 197, 3, 8, 89, 69, 78, 73, 83, 69, 73, 32, 84, 54, 65, 202, 1, 69, - 122, 73, 30, 79, 135, 151, 12, 66, 45, 106, 69, 170, 243, 9, 83, 226, - 144, 4, 66, 2, 68, 2, 71, 2, 76, 2, 78, 2, 81, 2, 82, 2, 84, 3, 89, 20, - 134, 132, 14, 66, 2, 68, 2, 71, 2, 75, 2, 76, 2, 78, 2, 82, 2, 83, 2, 84, - 3, 89, 20, 74, 78, 182, 230, 13, 76, 158, 27, 83, 146, 1, 67, 2, 77, 2, - 80, 3, 90, 8, 222, 130, 14, 67, 2, 71, 2, 84, 3, 89, 7, 178, 130, 14, 67, - 3, 81, 13, 130, 3, 69, 150, 255, 13, 80, 2, 81, 3, 84, 62, 38, 65, 170, - 1, 69, 86, 73, 23, 79, 39, 98, 69, 206, 255, 13, 83, 62, 78, 86, 66, 2, - 68, 2, 71, 2, 76, 2, 81, 2, 82, 2, 84, 3, 89, 17, 218, 130, 12, 78, 130, - 254, 1, 66, 2, 71, 2, 75, 2, 84, 3, 89, 15, 46, 78, 218, 254, 13, 83, - 146, 1, 67, 3, 90, 6, 230, 255, 13, 67, 2, 84, 3, 89, 5, 195, 255, 13, - 81, 6, 26, 69, 151, 255, 13, 81, 5, 147, 255, 13, 75, 52, 148, 1, 10, 67, - 79, 77, 66, 73, 78, 73, 78, 71, 32, 36, 7, 76, 69, 84, 84, 69, 82, 32, - 233, 1, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 8, 222, 241, - 5, 84, 243, 231, 3, 68, 36, 230, 200, 1, 65, 186, 206, 1, 82, 222, 220, - 2, 76, 58, 90, 34, 83, 66, 89, 168, 210, 1, 6, 70, 73, 78, 65, 76, 32, 0, - 6, 71, 73, 77, 69, 76, 45, 134, 3, 75, 174, 81, 66, 170, 225, 4, 78, 134, - 2, 84, 2, 87, 218, 103, 80, 171, 4, 77, 8, 56, 4, 84, 87, 79, 32, 174, - 212, 11, 70, 187, 131, 1, 66, 4, 158, 228, 12, 66, 75, 68, 6, 146, 181, - 1, 87, 136, 160, 3, 3, 65, 68, 85, 207, 217, 7, 77, 22, 212, 1, 34, 32, - 87, 73, 84, 72, 32, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 32, 77, - 65, 82, 75, 32, 87, 73, 84, 72, 32, 76, 69, 70, 84, 32, 82, 44, 7, 67, - 79, 77, 73, 78, 71, 32, 194, 1, 69, 151, 167, 13, 73, 2, 21, 3, 73, 71, - 72, 2, 203, 250, 9, 84, 10, 148, 1, 6, 65, 85, 84, 79, 77, 79, 20, 7, 70, - 73, 82, 69, 32, 69, 78, 144, 225, 2, 2, 84, 65, 148, 247, 8, 6, 80, 79, - 76, 73, 67, 69, 143, 22, 66, 2, 223, 206, 11, 66, 2, 215, 219, 12, 71, 8, - 70, 32, 229, 191, 12, 11, 45, 80, 73, 69, 67, 69, 32, 83, 87, 73, 77, 6, - 40, 4, 68, 79, 84, 32, 175, 173, 10, 66, 4, 26, 79, 135, 175, 10, 76, 2, - 129, 234, 2, 11, 86, 69, 82, 32, 84, 87, 79, 32, 68, 79, 84, 46, 82, 69, - 188, 6, 2, 84, 73, 188, 229, 11, 5, 72, 73, 85, 67, 72, 147, 183, 1, 80, - 36, 70, 78, 201, 5, 12, 82, 65, 84, 73, 78, 71, 32, 83, 89, 83, 84, 69, - 34, 22, 32, 139, 4, 45, 28, 108, 2, 66, 79, 32, 7, 67, 69, 78, 84, 82, - 69, 32, 114, 70, 70, 72, 42, 77, 142, 139, 7, 83, 135, 244, 3, 76, 4, - 242, 239, 13, 79, 155, 3, 88, 8, 50, 84, 174, 216, 11, 66, 222, 2, 65, - 135, 84, 67, 2, 37, 7, 69, 65, 82, 68, 82, 79, 80, 2, 143, 218, 11, 45, - 4, 44, 5, 73, 76, 69, 32, 70, 243, 131, 2, 79, 2, 239, 131, 2, 79, 2, 17, - 2, 65, 78, 2, 151, 191, 10, 68, 4, 57, 12, 65, 73, 76, 66, 79, 88, 32, - 87, 73, 84, 72, 32, 4, 44, 3, 76, 79, 87, 21, 4, 82, 65, 73, 83, 2, 17, - 2, 69, 82, 2, 129, 132, 12, 2, 69, 68, 6, 108, 15, 67, 73, 82, 67, 85, - 73, 84, 45, 79, 85, 84, 80, 85, 84, 32, 221, 204, 12, 6, 79, 85, 84, 76, - 73, 78, 4, 18, 72, 3, 76, 2, 161, 192, 1, 4, 45, 84, 89, 80, 2, 169, 222, - 12, 6, 77, 32, 67, 79, 77, 77, 6, 64, 2, 79, 78, 253, 177, 1, 8, 67, 65, - 76, 32, 68, 73, 83, 67, 2, 247, 207, 11, 32, 208, 1, 104, 3, 65, 78, 71, - 66, 67, 34, 73, 212, 8, 5, 78, 65, 84, 69, 32, 32, 3, 84, 72, 79, 199, - 176, 5, 32, 6, 28, 2, 69, 32, 167, 22, 85, 4, 198, 150, 12, 66, 203, 78, - 72, 4, 186, 174, 13, 85, 223, 61, 65, 188, 1, 48, 5, 71, 73, 78, 65, 76, - 21, 3, 89, 65, 32, 2, 183, 133, 1, 32, 186, 1, 106, 65, 30, 70, 250, 1, - 73, 32, 7, 76, 69, 84, 84, 69, 82, 32, 142, 2, 83, 218, 1, 86, 159, 240, - 11, 68, 4, 182, 137, 10, 73, 3, 85, 12, 41, 8, 82, 65, 67, 84, 73, 79, - 78, 32, 12, 56, 4, 79, 78, 69, 32, 81, 6, 84, 72, 82, 69, 69, 32, 8, 42, - 83, 206, 226, 11, 69, 46, 72, 47, 81, 2, 217, 227, 11, 4, 73, 88, 84, 69, - 4, 26, 83, 227, 228, 11, 81, 2, 145, 136, 8, 4, 73, 88, 84, 69, 2, 233, - 196, 12, 3, 83, 83, 72, 104, 226, 1, 82, 130, 238, 6, 89, 178, 154, 3, - 65, 38, 68, 114, 84, 46, 86, 186, 5, 85, 186, 202, 1, 73, 42, 76, 226, - 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, - 72, 2, 77, 2, 87, 186, 2, 69, 3, 79, 6, 234, 227, 13, 72, 2, 82, 187, 2, - 65, 18, 112, 20, 69, 81, 85, 69, 78, 67, 69, 32, 70, 79, 82, 32, 76, 69, - 84, 84, 69, 82, 32, 82, 29, 4, 73, 71, 78, 32, 4, 206, 226, 13, 72, 3, - 82, 14, 138, 199, 9, 67, 98, 78, 190, 66, 65, 250, 239, 1, 79, 195, 167, - 1, 86, 26, 49, 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 26, 206, 140, - 10, 65, 38, 85, 22, 86, 166, 202, 1, 73, 198, 140, 2, 69, 3, 79, 4, 194, - 220, 6, 76, 243, 30, 82, 4, 240, 245, 3, 2, 68, 79, 139, 183, 2, 71, 226, - 1, 76, 4, 65, 71, 69, 32, 140, 4, 6, 77, 65, 78, 89, 65, 32, 251, 221, - 13, 67, 144, 1, 56, 6, 67, 65, 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 72, - 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 72, 194, 1, 65, 38, 69, 90, - 75, 42, 79, 22, 84, 246, 229, 6, 72, 254, 250, 4, 67, 2, 68, 2, 71, 234, - 181, 1, 83, 2, 90, 130, 3, 66, 138, 66, 76, 2, 77, 2, 78, 2, 80, 2, 87, - 186, 2, 73, 3, 85, 9, 226, 225, 11, 73, 239, 253, 1, 72, 15, 26, 72, 179, - 143, 13, 73, 10, 134, 202, 9, 84, 226, 151, 2, 67, 242, 250, 1, 75, 3, - 80, 6, 154, 220, 13, 72, 2, 89, 187, 2, 65, 5, 203, 142, 13, 73, 6, 214, - 150, 13, 83, 195, 71, 65, 80, 52, 7, 76, 69, 84, 84, 69, 82, 32, 187, - 233, 11, 68, 60, 246, 1, 65, 38, 67, 22, 68, 38, 75, 34, 83, 30, 77, 162, - 241, 2, 81, 226, 159, 8, 79, 148, 125, 2, 76, 65, 236, 75, 2, 78, 85, - 134, 2, 87, 142, 62, 69, 234, 61, 66, 2, 70, 2, 71, 2, 72, 2, 74, 2, 82, - 2, 84, 2, 88, 2, 89, 186, 2, 73, 3, 85, 7, 194, 250, 2, 76, 135, 225, 10, - 65, 2, 183, 221, 12, 65, 4, 222, 197, 8, 69, 251, 146, 5, 72, 4, 186, - 217, 12, 65, 251, 126, 72, 4, 26, 72, 179, 218, 13, 65, 2, 219, 218, 12, - 73, 124, 68, 11, 79, 77, 65, 78, 32, 83, 73, 89, 65, 81, 32, 251, 160, - 13, 69, 122, 172, 1, 17, 65, 76, 84, 69, 82, 78, 65, 84, 69, 32, 78, 85, - 77, 66, 69, 82, 32, 200, 1, 13, 70, 82, 65, 67, 84, 73, 79, 78, 32, 79, - 78, 69, 32, 48, 3, 77, 65, 82, 47, 78, 26, 54, 70, 50, 83, 46, 84, 214, - 187, 12, 78, 239, 112, 69, 6, 248, 207, 5, 3, 79, 85, 82, 159, 139, 7, - 73, 6, 200, 207, 5, 2, 73, 88, 155, 149, 6, 69, 10, 226, 184, 2, 69, 12, - 2, 87, 79, 247, 171, 9, 72, 4, 26, 83, 175, 208, 11, 72, 2, 155, 209, 11, - 73, 2, 11, 82, 2, 11, 65, 2, 247, 137, 12, 84, 90, 33, 6, 85, 77, 66, 69, - 82, 32, 90, 58, 69, 66, 70, 94, 78, 26, 83, 78, 84, 179, 177, 5, 79, 10, - 25, 4, 73, 71, 72, 84, 11, 226, 182, 2, 89, 227, 193, 5, 32, 20, 18, 73, - 35, 79, 10, 166, 2, 70, 195, 176, 5, 86, 10, 134, 2, 82, 205, 176, 5, 2, - 85, 82, 10, 65, 3, 73, 78, 69, 20, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, - 11, 166, 1, 84, 219, 245, 7, 32, 24, 34, 72, 50, 87, 163, 180, 2, 69, 10, - 34, 73, 245, 176, 5, 2, 82, 69, 4, 51, 82, 10, 26, 69, 219, 176, 5, 79, - 4, 11, 78, 4, 11, 84, 4, 247, 179, 2, 89, 84, 34, 84, 217, 177, 11, 2, - 78, 67, 82, 42, 66, 37, 6, 76, 73, 78, 69, 68, 32, 2, 133, 195, 12, 4, - 79, 88, 32, 84, 80, 92, 7, 76, 65, 84, 73, 78, 32, 67, 242, 194, 6, 87, - 182, 243, 4, 66, 234, 14, 71, 159, 23, 68, 54, 186, 174, 7, 65, 215, 222, - 4, 82, 12, 18, 72, 43, 76, 2, 17, 2, 69, 65, 2, 239, 188, 12, 84, 10, 32, - 2, 65, 80, 255, 179, 12, 73, 9, 29, 5, 80, 73, 78, 71, 32, 6, 40, 6, 87, - 72, 73, 84, 69, 32, 51, 66, 4, 44, 5, 65, 78, 68, 32, 66, 151, 138, 10, - 83, 2, 253, 137, 10, 4, 76, 65, 67, 75, 152, 13, 150, 1, 65, 206, 65, 68, - 30, 69, 134, 13, 72, 138, 25, 73, 202, 4, 76, 160, 15, 2, 78, 80, 54, 79, - 238, 8, 82, 210, 15, 83, 186, 6, 85, 239, 177, 12, 77, 158, 6, 134, 2, - 68, 38, 71, 212, 1, 11, 72, 65, 87, 72, 32, 72, 77, 79, 78, 71, 32, 134, - 23, 76, 130, 6, 78, 58, 82, 196, 22, 2, 83, 83, 132, 2, 10, 85, 32, 67, - 73, 78, 32, 72, 65, 85, 32, 176, 7, 3, 87, 32, 80, 152, 252, 7, 2, 67, - 75, 233, 141, 5, 4, 80, 69, 82, 67, 5, 253, 185, 1, 4, 68, 73, 78, 71, - 14, 26, 69, 163, 165, 13, 79, 13, 34, 32, 130, 202, 13, 82, 3, 83, 6, 72, - 6, 87, 73, 84, 72, 32, 67, 181, 159, 4, 6, 70, 65, 67, 73, 78, 71, 4, 50, - 85, 145, 237, 7, 6, 73, 82, 67, 76, 69, 68, 2, 175, 189, 12, 82, 254, 1, - 190, 1, 67, 160, 6, 9, 77, 65, 82, 75, 32, 67, 73, 77, 32, 160, 1, 7, 78, - 85, 77, 66, 69, 82, 32, 244, 1, 5, 83, 73, 71, 78, 32, 144, 10, 7, 86, - 79, 87, 69, 76, 32, 75, 223, 191, 11, 68, 78, 92, 9, 76, 65, 78, 32, 83, - 73, 71, 78, 32, 137, 3, 9, 79, 78, 83, 79, 78, 65, 78, 84, 32, 38, 132, - 1, 2, 72, 65, 38, 75, 46, 76, 34, 84, 82, 86, 30, 89, 148, 9, 2, 88, 89, - 172, 5, 2, 80, 72, 174, 1, 70, 165, 2, 2, 77, 85, 4, 170, 198, 2, 87, - 151, 255, 10, 77, 6, 246, 15, 72, 178, 150, 13, 79, 159, 14, 87, 4, 210, - 12, 65, 195, 250, 12, 73, 8, 22, 83, 247, 9, 72, 6, 160, 197, 2, 3, 72, - 69, 69, 158, 193, 9, 65, 3, 87, 4, 234, 196, 2, 65, 3, 87, 4, 206, 196, - 2, 65, 175, 185, 10, 69, 40, 122, 67, 38, 72, 46, 78, 60, 2, 80, 76, 2, - 81, 222, 222, 2, 76, 2, 77, 2, 82, 2, 86, 2, 88, 2, 89, 247, 189, 10, 65, - 4, 230, 223, 2, 72, 247, 189, 10, 65, 6, 194, 223, 2, 76, 2, 78, 247, - 189, 10, 65, 12, 58, 67, 22, 84, 202, 222, 2, 75, 2, 76, 247, 189, 10, - 65, 2, 219, 222, 2, 72, 4, 198, 222, 2, 72, 3, 83, 14, 42, 75, 50, 83, - 38, 84, 167, 175, 13, 72, 4, 26, 72, 231, 130, 13, 69, 2, 175, 162, 6, - 65, 4, 154, 131, 12, 85, 147, 189, 1, 79, 4, 142, 130, 12, 85, 215, 18, - 65, 14, 52, 7, 72, 85, 78, 68, 82, 69, 68, 38, 84, 79, 77, 4, 108, 2, 32, - 77, 195, 190, 13, 83, 8, 24, 2, 69, 78, 51, 82, 6, 26, 32, 215, 190, 13, - 83, 4, 18, 66, 35, 84, 2, 253, 213, 4, 3, 73, 76, 76, 2, 11, 72, 2, 213, - 251, 9, 3, 79, 85, 83, 72, 188, 1, 4, 67, 73, 77, 32, 246, 2, 72, 32, 3, - 73, 66, 32, 22, 77, 86, 78, 50, 84, 124, 4, 86, 79, 83, 32, 198, 1, 88, - 208, 1, 6, 90, 87, 74, 32, 84, 72, 142, 178, 1, 76, 223, 227, 4, 65, 16, - 174, 1, 67, 84, 5, 78, 82, 69, 83, 32, 22, 84, 164, 252, 11, 7, 80, 85, - 66, 32, 68, 65, 87, 153, 189, 1, 16, 72, 65, 73, 83, 32, 76, 85, 83, 32, - 78, 84, 79, 71, 32, 78, 84, 4, 48, 7, 85, 65, 77, 32, 84, 83, 72, 255, 3, - 72, 2, 11, 79, 2, 175, 187, 2, 79, 2, 195, 184, 1, 84, 6, 52, 3, 88, 87, - 86, 161, 151, 10, 4, 83, 79, 86, 32, 5, 209, 155, 6, 4, 32, 67, 72, 87, - 4, 190, 72, 78, 171, 221, 12, 76, 2, 143, 252, 11, 89, 6, 40, 4, 69, 69, - 74, 32, 135, 251, 12, 85, 4, 128, 3, 2, 84, 83, 57, 2, 83, 85, 4, 26, 84, - 187, 252, 8, 81, 2, 135, 185, 2, 85, 6, 196, 1, 7, 88, 72, 69, 69, 74, - 32, 67, 224, 178, 8, 12, 72, 73, 82, 68, 45, 83, 84, 65, 71, 69, 32, 72, - 251, 222, 4, 65, 14, 54, 70, 22, 83, 30, 84, 166, 69, 76, 195, 251, 7, - 78, 2, 167, 164, 13, 69, 2, 173, 152, 6, 2, 69, 69, 6, 42, 72, 29, 6, 83, - 72, 65, 66, 32, 67, 4, 82, 73, 207, 164, 13, 79, 2, 175, 209, 5, 69, 14, - 34, 73, 22, 89, 175, 172, 11, 65, 2, 171, 247, 11, 65, 10, 40, 4, 69, 69, - 77, 32, 243, 149, 13, 79, 8, 84, 3, 78, 84, 88, 252, 149, 6, 2, 84, 79, - 154, 173, 2, 82, 245, 178, 3, 2, 70, 65, 2, 251, 149, 6, 73, 2, 227, 180, - 2, 65, 56, 50, 65, 66, 69, 38, 73, 2, 85, 38, 79, 39, 87, 20, 170, 1, 65, - 2, 73, 2, 85, 2, 87, 134, 178, 13, 66, 3, 86, 8, 106, 69, 134, 178, 13, - 66, 3, 86, 8, 70, 65, 134, 178, 13, 66, 3, 86, 8, 34, 79, 134, 178, 13, - 66, 3, 86, 4, 130, 178, 13, 66, 3, 86, 76, 18, 76, 23, 77, 2, 247, 243, - 12, 65, 74, 74, 32, 104, 6, 89, 82, 69, 78, 69, 32, 141, 142, 4, 4, 83, - 32, 85, 80, 8, 80, 3, 66, 82, 65, 246, 189, 11, 84, 248, 97, 4, 68, 79, - 87, 78, 1, 2, 85, 80, 2, 247, 141, 13, 78, 64, 80, 2, 76, 69, 40, 4, 82, - 73, 71, 72, 253, 2, 7, 78, 85, 77, 66, 69, 82, 32, 48, 38, 70, 89, 5, 84, - 84, 69, 82, 32, 2, 57, 12, 84, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, - 70, 2, 229, 231, 5, 2, 76, 69, 46, 224, 1, 5, 70, 73, 78, 65, 76, 30, 84, - 242, 119, 68, 34, 76, 50, 81, 214, 205, 1, 82, 142, 220, 2, 65, 50, 71, - 90, 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, - 225, 4, 78, 134, 2, 87, 218, 103, 80, 171, 4, 77, 2, 161, 172, 12, 2, 32, - 78, 4, 190, 167, 11, 69, 219, 134, 1, 65, 14, 194, 121, 84, 198, 191, 10, - 70, 223, 87, 79, 4, 32, 2, 67, 65, 147, 236, 12, 68, 2, 191, 149, 12, 75, - 188, 2, 94, 65, 220, 1, 11, 69, 78, 84, 72, 69, 83, 73, 90, 69, 68, 32, - 242, 16, 84, 203, 199, 12, 82, 14, 80, 5, 71, 82, 65, 80, 72, 52, 5, 76, - 76, 69, 76, 32, 209, 163, 6, 2, 67, 72, 6, 186, 248, 9, 32, 250, 223, 1, - 85, 235, 147, 1, 79, 6, 44, 5, 87, 73, 84, 72, 32, 163, 138, 13, 84, 4, - 222, 198, 6, 84, 175, 186, 4, 72, 150, 2, 252, 1, 7, 72, 65, 78, 71, 85, - 76, 32, 188, 4, 10, 73, 68, 69, 79, 71, 82, 65, 80, 72, 32, 188, 7, 18, - 75, 79, 82, 69, 65, 78, 32, 67, 72, 65, 82, 65, 67, 84, 69, 82, 32, 79, - 44, 7, 78, 85, 77, 66, 69, 82, 32, 250, 206, 4, 68, 145, 169, 2, 2, 76, - 65, 58, 102, 67, 110, 72, 30, 75, 66, 77, 34, 78, 34, 80, 62, 82, 30, 83, - 26, 84, 73, 5, 73, 69, 85, 78, 71, 10, 34, 72, 33, 4, 73, 69, 85, 67, 4, - 141, 3, 4, 73, 69, 85, 67, 7, 11, 32, 4, 178, 165, 13, 65, 3, 85, 4, 197, - 2, 3, 73, 69, 85, 8, 168, 2, 5, 72, 73, 69, 85, 75, 13, 5, 73, 89, 69, - 79, 75, 4, 245, 1, 4, 73, 69, 85, 77, 4, 213, 1, 4, 73, 69, 85, 78, 8, - 168, 1, 5, 72, 73, 69, 85, 80, 13, 4, 73, 69, 85, 80, 4, 121, 4, 73, 69, - 85, 76, 4, 93, 3, 73, 79, 83, 8, 56, 5, 72, 73, 69, 85, 84, 13, 5, 73, - 75, 69, 85, 84, 4, 11, 72, 5, 139, 160, 13, 32, 72, 148, 1, 2, 65, 76, - 30, 67, 74, 69, 82, 70, 112, 2, 76, 65, 22, 77, 38, 78, 32, 2, 82, 69, - 78, 83, 138, 2, 84, 50, 87, 254, 172, 11, 72, 239, 82, 79, 2, 237, 144, - 8, 2, 76, 73, 4, 32, 2, 79, 78, 179, 150, 11, 65, 2, 181, 251, 7, 4, 71, - 82, 65, 84, 6, 42, 78, 174, 179, 9, 65, 155, 194, 3, 73, 2, 169, 4, 5, - 84, 69, 82, 80, 82, 10, 58, 73, 204, 147, 12, 5, 69, 83, 84, 73, 86, 139, - 19, 79, 6, 208, 2, 3, 78, 65, 78, 130, 134, 13, 82, 3, 86, 2, 139, 230, - 12, 66, 4, 226, 198, 10, 69, 147, 136, 2, 79, 4, 138, 131, 12, 73, 195, - 1, 65, 8, 38, 83, 218, 139, 12, 80, 247, 111, 65, 4, 190, 214, 6, 79, - 183, 199, 6, 84, 18, 58, 69, 34, 79, 22, 80, 34, 84, 50, 85, 211, 141, - 12, 73, 4, 142, 199, 11, 86, 227, 84, 76, 2, 239, 251, 7, 67, 2, 11, 69, - 2, 227, 181, 4, 67, 4, 26, 85, 163, 234, 11, 79, 2, 219, 138, 13, 68, 4, - 26, 80, 247, 155, 13, 78, 2, 21, 3, 69, 82, 86, 2, 183, 144, 12, 73, 6, - 154, 169, 11, 72, 206, 162, 1, 69, 239, 48, 87, 4, 234, 224, 9, 79, 163, - 128, 2, 65, 4, 170, 164, 8, 32, 221, 166, 4, 2, 74, 69, 22, 42, 69, 46, - 70, 42, 78, 30, 83, 51, 84, 4, 216, 1, 3, 73, 71, 72, 131, 246, 4, 76, 4, - 160, 1, 2, 79, 85, 13, 2, 73, 70, 2, 133, 1, 3, 73, 78, 69, 4, 34, 73, - 73, 4, 69, 86, 69, 78, 2, 71, 88, 8, 34, 72, 46, 87, 207, 200, 12, 69, 2, - 11, 73, 2, 11, 82, 2, 175, 194, 11, 84, 4, 11, 69, 4, 190, 168, 11, 78, - 143, 115, 76, 22, 164, 1, 3, 73, 65, 76, 216, 1, 3, 89, 32, 80, 224, 206, - 6, 5, 72, 69, 78, 79, 80, 180, 229, 1, 6, 78, 69, 82, 83, 72, 73, 225, - 219, 3, 6, 32, 65, 76, 84, 69, 82, 12, 62, 32, 173, 124, 10, 76, 89, 45, - 82, 69, 67, 89, 67, 76, 69, 10, 38, 68, 41, 5, 76, 73, 78, 69, 32, 2, - 229, 174, 4, 5, 73, 70, 70, 69, 82, 8, 254, 205, 3, 68, 226, 45, 70, 20, - 4, 66, 65, 67, 75, 203, 153, 9, 85, 2, 223, 242, 3, 79, 10, 98, 69, 52, - 9, 73, 86, 69, 45, 80, 85, 76, 76, 45, 89, 9, 80, 79, 82, 84, 32, 67, 79, - 78, 84, 4, 176, 242, 9, 4, 78, 71, 69, 82, 147, 140, 2, 68, 4, 40, 4, 68, - 79, 87, 78, 1, 2, 85, 80, 2, 213, 176, 5, 6, 45, 79, 85, 84, 80, 85, 2, - 239, 253, 11, 82, 114, 192, 1, 12, 71, 76, 79, 84, 84, 65, 76, 32, 83, - 84, 79, 80, 62, 76, 156, 3, 3, 82, 73, 83, 36, 14, 77, 73, 68, 45, 76, - 69, 86, 69, 76, 32, 84, 79, 78, 69, 57, 7, 83, 65, 78, 68, 72, 73, 32, 7, - 11, 32, 4, 202, 5, 70, 213, 255, 11, 4, 86, 65, 82, 73, 82, 72, 6, 69, - 84, 84, 69, 82, 32, 209, 2, 7, 79, 87, 45, 70, 65, 76, 76, 74, 202, 1, - 70, 226, 252, 8, 73, 2, 85, 238, 27, 78, 198, 174, 3, 67, 2, 75, 2, 80, - 2, 84, 138, 69, 66, 2, 68, 2, 71, 2, 72, 2, 76, 2, 77, 2, 82, 2, 83, 2, - 86, 2, 90, 186, 2, 65, 2, 69, 3, 79, 20, 44, 5, 73, 78, 65, 76, 32, 163, - 142, 13, 65, 18, 158, 144, 11, 78, 130, 254, 1, 75, 2, 76, 2, 77, 2, 80, - 2, 84, 2, 87, 3, 89, 8, 157, 1, 5, 73, 78, 71, 32, 84, 7, 11, 32, 4, 192, - 1, 5, 76, 79, 78, 71, 32, 15, 70, 12, 66, 84, 73, 12, 71, 76, 79, 84, 84, - 65, 76, 32, 83, 84, 79, 80, 8, 21, 3, 79, 78, 69, 9, 11, 32, 6, 32, 4, - 76, 79, 78, 71, 27, 70, 5, 11, 32, 2, 11, 70, 2, 131, 201, 3, 73, 2, 171, - 181, 4, 82, 4, 162, 139, 13, 70, 3, 73, 80, 130, 1, 65, 122, 78, 162, 1, - 82, 162, 9, 83, 44, 3, 84, 82, 73, 130, 17, 68, 157, 156, 12, 9, 79, 80, - 76, 69, 32, 72, 85, 71, 71, 12, 50, 67, 50, 78, 138, 239, 6, 32, 155, - 154, 6, 82, 6, 202, 215, 11, 79, 194, 28, 69, 199, 149, 1, 72, 2, 227, - 128, 12, 85, 10, 118, 71, 20, 3, 83, 73, 86, 222, 179, 1, 84, 156, 188, - 4, 10, 32, 79, 86, 69, 82, 32, 83, 84, 65, 77, 187, 184, 5, 67, 2, 191, - 136, 12, 85, 2, 223, 202, 12, 69, 48, 186, 1, 32, 116, 10, 80, 69, 78, - 68, 73, 67, 85, 76, 65, 82, 42, 83, 130, 176, 7, 67, 252, 9, 10, 77, 65, - 78, 69, 78, 84, 32, 80, 65, 80, 237, 133, 2, 8, 70, 79, 82, 77, 73, 78, - 71, 32, 6, 34, 77, 30, 84, 139, 255, 11, 83, 2, 129, 242, 1, 2, 73, 76, - 2, 149, 154, 11, 8, 69, 78, 32, 84, 72, 79, 85, 83, 5, 213, 139, 9, 5, - 32, 87, 73, 84, 72, 32, 60, 2, 79, 78, 154, 75, 80, 157, 177, 11, 4, 69, - 86, 69, 82, 28, 38, 32, 237, 133, 10, 3, 65, 76, 32, 26, 216, 2, 10, 68, - 79, 73, 78, 71, 32, 67, 65, 82, 84, 32, 3, 73, 78, 32, 92, 5, 87, 73, 84, - 72, 32, 184, 224, 7, 4, 70, 82, 79, 87, 204, 13, 27, 82, 65, 73, 83, 73, - 78, 71, 32, 66, 79, 84, 72, 32, 72, 65, 78, 68, 83, 32, 73, 78, 32, 67, - 69, 76, 69, 66, 204, 193, 4, 5, 67, 76, 73, 77, 66, 213, 45, 11, 66, 79, - 87, 73, 78, 71, 32, 68, 69, 69, 80, 2, 11, 87, 2, 159, 189, 3, 72, 4, - 204, 175, 12, 6, 76, 79, 84, 85, 83, 32, 253, 64, 9, 83, 84, 69, 65, 77, - 89, 32, 82, 79, 12, 154, 1, 66, 180, 146, 2, 3, 80, 79, 85, 188, 165, 1, - 2, 67, 82, 244, 132, 6, 6, 70, 79, 76, 68, 69, 68, 177, 193, 2, 8, 72, - 69, 65, 68, 83, 67, 65, 82, 4, 36, 3, 76, 79, 78, 235, 244, 10, 65, 2, - 11, 68, 2, 11, 32, 2, 11, 72, 2, 11, 65, 2, 131, 198, 12, 73, 4, 180, - 169, 9, 2, 69, 84, 151, 206, 2, 79, 2, 209, 153, 9, 2, 32, 68, 140, 2, - 66, 65, 184, 19, 9, 73, 76, 73, 80, 80, 73, 78, 69, 32, 47, 79, 204, 1, - 108, 6, 71, 83, 45, 80, 65, 32, 189, 7, 16, 73, 83, 84, 79, 83, 32, 68, - 73, 83, 67, 32, 83, 73, 71, 78, 32, 112, 100, 7, 76, 69, 84, 84, 69, 82, - 32, 248, 4, 5, 77, 65, 82, 75, 32, 30, 83, 33, 4, 68, 79, 85, 66, 96, - 138, 2, 65, 138, 1, 67, 50, 68, 42, 83, 64, 5, 86, 79, 73, 67, 69, 178, - 129, 9, 71, 202, 173, 3, 78, 82, 84, 46, 75, 2, 80, 2, 90, 162, 7, 69, - 234, 61, 66, 2, 70, 2, 72, 2, 74, 2, 76, 2, 77, 2, 81, 2, 82, 2, 87, 2, - 88, 2, 89, 186, 2, 73, 2, 79, 3, 85, 7, 80, 8, 76, 84, 69, 82, 78, 65, - 84, 69, 21, 8, 83, 80, 73, 82, 65, 84, 69, 68, 2, 163, 246, 12, 32, 2, - 11, 32, 2, 167, 246, 12, 70, 6, 26, 65, 251, 245, 12, 72, 5, 231, 218, 8, - 78, 6, 226, 245, 12, 68, 2, 90, 187, 2, 65, 6, 244, 174, 8, 4, 77, 65, - 76, 76, 198, 198, 4, 72, 187, 2, 65, 4, 34, 68, 21, 4, 76, 69, 83, 83, 2, - 231, 249, 10, 32, 2, 171, 187, 9, 32, 4, 246, 175, 12, 68, 59, 83, 10, - 28, 3, 73, 78, 71, 31, 85, 2, 229, 169, 12, 2, 76, 69, 8, 58, 66, 213, - 170, 12, 8, 80, 69, 82, 70, 73, 88, 69, 68, 6, 209, 189, 8, 13, 74, 79, - 73, 78, 69, 68, 32, 76, 69, 84, 84, 69, 82, 92, 238, 1, 66, 146, 1, 67, - 172, 2, 2, 68, 79, 38, 71, 66, 72, 64, 2, 76, 73, 32, 2, 77, 65, 70, 80, - 162, 1, 82, 38, 83, 150, 1, 84, 70, 87, 200, 228, 5, 2, 70, 76, 176, 238, - 1, 2, 79, 88, 252, 240, 3, 2, 69, 65, 138, 10, 65, 135, 1, 86, 10, 52, 2, - 69, 69, 22, 79, 145, 41, 4, 85, 76, 76, 83, 5, 147, 182, 7, 72, 4, 32, 2, - 79, 77, 175, 242, 12, 87, 2, 11, 69, 2, 203, 153, 12, 82, 16, 34, 65, 86, - 72, 22, 76, 23, 79, 6, 130, 224, 5, 80, 208, 240, 3, 8, 82, 80, 69, 78, - 84, 82, 89, 32, 151, 161, 3, 84, 2, 199, 193, 2, 73, 2, 135, 179, 11, 85, - 6, 26, 76, 33, 2, 77, 66, 2, 11, 85, 2, 227, 160, 12, 77, 5, 37, 7, 73, - 78, 73, 78, 71, 32, 79, 2, 169, 255, 9, 5, 66, 76, 73, 81, 85, 4, 174, - 196, 11, 76, 223, 148, 1, 86, 4, 42, 82, 137, 141, 11, 4, 65, 85, 78, 84, - 2, 131, 181, 11, 65, 6, 42, 69, 238, 219, 7, 79, 243, 255, 2, 73, 2, 171, - 185, 12, 76, 4, 242, 220, 12, 76, 203, 17, 68, 4, 34, 78, 249, 251, 9, 2, - 84, 84, 2, 11, 65, 2, 211, 172, 9, 67, 8, 52, 2, 69, 68, 50, 76, 181, - 176, 7, 3, 65, 80, 89, 2, 25, 4, 69, 83, 84, 82, 2, 231, 160, 11, 73, 4, - 192, 187, 4, 2, 85, 77, 209, 231, 2, 3, 65, 78, 69, 4, 230, 218, 10, 79, - 251, 128, 2, 65, 12, 108, 2, 72, 73, 134, 237, 11, 65, 158, 45, 76, 128, - 19, 3, 84, 82, 65, 177, 39, 7, 77, 65, 76, 76, 32, 65, 88, 4, 214, 187, - 2, 69, 207, 175, 10, 80, 6, 208, 185, 4, 5, 65, 84, 84, 79, 79, 226, 236, - 7, 73, 207, 36, 85, 4, 146, 236, 7, 79, 137, 238, 3, 5, 65, 86, 89, 32, - 66, 4, 250, 244, 1, 83, 25, 4, 68, 79, 85, 66, 60, 56, 8, 69, 78, 73, 67, - 73, 65, 78, 32, 187, 224, 10, 76, 58, 92, 7, 76, 69, 84, 84, 69, 82, 32, - 160, 3, 7, 78, 85, 77, 66, 69, 82, 32, 231, 155, 6, 87, 44, 234, 1, 65, - 34, 68, 22, 72, 22, 81, 22, 83, 58, 84, 226, 130, 2, 87, 154, 239, 5, 90, - 154, 185, 1, 89, 164, 207, 1, 2, 82, 79, 184, 95, 3, 71, 65, 77, 162, 10, - 75, 130, 1, 78, 144, 58, 3, 76, 65, 77, 138, 17, 66, 198, 30, 80, 171, 4, - 77, 4, 170, 229, 11, 76, 199, 49, 73, 2, 199, 192, 3, 69, 4, 195, 253, 6, - 69, 2, 227, 228, 11, 79, 6, 254, 210, 10, 65, 162, 147, 1, 72, 189, 124, - 2, 69, 77, 4, 210, 192, 12, 65, 191, 8, 69, 12, 202, 50, 84, 203, 170, 4, - 79, 40, 104, 2, 67, 75, 66, 71, 62, 76, 90, 78, 178, 1, 83, 28, 7, 84, - 67, 72, 70, 79, 82, 75, 243, 224, 12, 69, 5, 17, 2, 85, 80, 2, 21, 3, 32, - 84, 82, 2, 223, 177, 11, 85, 7, 11, 32, 4, 26, 78, 163, 166, 12, 70, 2, - 131, 216, 11, 79, 6, 52, 4, 69, 32, 79, 70, 246, 92, 67, 235, 133, 12, - 76, 2, 11, 32, 2, 215, 151, 10, 80, 14, 68, 2, 67, 72, 46, 69, 194, 169, - 4, 87, 206, 176, 7, 75, 243, 98, 65, 4, 196, 160, 3, 2, 69, 68, 231, 176, - 8, 73, 4, 28, 2, 32, 68, 239, 73, 65, 2, 253, 134, 5, 2, 69, 67, 4, 134, - 203, 11, 67, 123, 84, 5, 245, 139, 10, 10, 32, 87, 73, 84, 72, 32, 84, - 69, 69, 32, 218, 1, 38, 65, 230, 9, 85, 167, 214, 12, 68, 176, 1, 78, 67, - 128, 1, 12, 78, 67, 75, 32, 67, 79, 78, 83, 84, 65, 78, 84, 83, 89, 6, - 44, 5, 69, 32, 79, 70, 32, 151, 198, 11, 65, 4, 56, 6, 73, 78, 84, 69, - 82, 69, 173, 137, 12, 2, 87, 79, 2, 251, 146, 7, 83, 5, 45, 9, 32, 79, - 86, 69, 82, 32, 84, 87, 79, 2, 11, 32, 2, 159, 202, 12, 80, 166, 1, 80, - 7, 71, 82, 79, 85, 78, 68, 32, 29, 9, 73, 78, 71, 32, 67, 65, 82, 68, 32, - 2, 173, 171, 4, 2, 83, 76, 164, 1, 182, 1, 66, 44, 3, 82, 69, 68, 0, 5, - 87, 72, 73, 84, 69, 42, 70, 74, 75, 38, 69, 34, 83, 36, 3, 81, 85, 69, - 14, 84, 92, 2, 65, 67, 0, 3, 78, 73, 78, 13, 4, 74, 65, 67, 75, 4, 40, 4, - 76, 65, 67, 75, 135, 169, 11, 65, 2, 17, 2, 32, 74, 2, 219, 237, 1, 79, - 18, 30, 79, 249, 1, 2, 73, 86, 10, 128, 2, 2, 85, 82, 239, 204, 11, 79, - 16, 34, 78, 185, 1, 3, 73, 78, 71, 8, 181, 1, 4, 73, 71, 72, 84, 16, 32, - 2, 69, 86, 117, 2, 73, 88, 8, 91, 69, 66, 78, 69, 12, 3, 72, 82, 69, 12, - 2, 87, 79, 161, 1, 5, 82, 85, 77, 80, 45, 8, 23, 78, 8, 11, 69, 8, 25, 4, - 32, 79, 70, 32, 8, 88, 3, 67, 76, 85, 20, 3, 83, 80, 65, 250, 145, 9, 72, - 137, 3, 5, 68, 73, 65, 77, 79, 2, 231, 153, 12, 66, 2, 171, 193, 11, 68, - 42, 90, 50, 190, 146, 10, 49, 134, 196, 2, 51, 2, 52, 2, 53, 2, 54, 2, - 55, 2, 56, 3, 57, 7, 190, 214, 12, 48, 3, 49, 41, 46, 83, 160, 4, 2, 84, - 79, 175, 128, 9, 78, 26, 52, 5, 32, 83, 73, 71, 78, 141, 163, 9, 2, 45, - 77, 25, 11, 32, 22, 64, 3, 73, 78, 32, 124, 5, 87, 73, 84, 72, 32, 215, - 255, 3, 65, 6, 34, 76, 22, 82, 195, 173, 11, 84, 2, 41, 2, 69, 70, 2, 21, - 3, 73, 71, 72, 2, 233, 255, 10, 6, 84, 32, 72, 65, 76, 70, 14, 162, 1, - 68, 34, 83, 140, 176, 10, 4, 84, 73, 76, 68, 152, 123, 5, 66, 76, 65, 67, - 75, 201, 38, 16, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 32, 65, 67, 67, - 69, 78, 2, 11, 79, 2, 167, 161, 10, 84, 4, 54, 77, 173, 181, 5, 7, 85, - 66, 83, 67, 82, 73, 80, 2, 197, 170, 9, 3, 65, 76, 76, 11, 33, 6, 32, 70, - 79, 82, 77, 32, 8, 162, 222, 10, 70, 71, 84, 2, 157, 152, 12, 8, 32, 84, - 82, 65, 78, 83, 73, 83, 58, 232, 1, 5, 76, 73, 67, 69, 32, 122, 80, 140, - 1, 11, 82, 84, 65, 66, 76, 69, 32, 83, 84, 69, 82, 22, 83, 158, 1, 84, - 146, 1, 85, 196, 1, 4, 87, 69, 82, 32, 210, 142, 7, 79, 157, 129, 5, 11, - 67, 75, 69, 84, 32, 67, 65, 76, 67, 85, 76, 6, 52, 3, 67, 65, 82, 217, - 253, 3, 4, 79, 70, 70, 73, 5, 217, 177, 10, 11, 83, 32, 82, 69, 86, 79, - 76, 86, 73, 78, 71, 6, 76, 13, 32, 68, 73, 82, 69, 67, 84, 73, 79, 78, - 65, 76, 32, 159, 215, 1, 67, 4, 158, 128, 1, 73, 169, 190, 6, 6, 70, 79, - 82, 77, 65, 84, 2, 251, 173, 12, 69, 12, 40, 2, 69, 73, 22, 84, 243, 140, - 5, 73, 2, 195, 252, 11, 68, 8, 36, 3, 65, 76, 32, 171, 189, 11, 66, 6, - 226, 213, 1, 72, 213, 206, 6, 4, 77, 65, 82, 75, 8, 66, 65, 238, 135, 2, - 32, 153, 183, 9, 6, 84, 69, 68, 32, 80, 76, 4, 26, 66, 239, 171, 12, 84, - 2, 29, 5, 76, 69, 32, 87, 65, 2, 243, 48, 84, 12, 108, 4, 76, 84, 82, 89, - 28, 7, 82, 73, 78, 71, 32, 76, 73, 28, 2, 84, 73, 202, 221, 10, 78, 179, - 234, 1, 67, 2, 213, 131, 12, 2, 32, 76, 2, 205, 179, 5, 2, 81, 85, 4, - 149, 223, 10, 2, 78, 71, 8, 24, 2, 79, 78, 47, 83, 4, 136, 179, 11, 4, - 45, 79, 70, 70, 15, 32, 4, 156, 152, 9, 3, 76, 69, 69, 231, 154, 2, 89, - 140, 1, 74, 69, 162, 10, 73, 230, 2, 79, 237, 221, 9, 6, 65, 89, 69, 82, - 32, 66, 102, 132, 1, 6, 71, 78, 65, 78, 84, 32, 66, 83, 252, 191, 5, 4, - 67, 69, 68, 69, 192, 207, 1, 5, 86, 73, 79, 85, 83, 241, 32, 2, 84, 90, - 6, 42, 87, 202, 193, 8, 80, 143, 184, 2, 77, 2, 199, 199, 7, 79, 70, 176, - 1, 27, 69, 78, 84, 65, 84, 73, 79, 78, 32, 70, 79, 82, 77, 32, 70, 79, - 82, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, 129, 216, 8, 10, 67, 82, 73, - 80, 84, 73, 79, 78, 32, 84, 68, 198, 1, 67, 22, 69, 46, 72, 50, 73, 94, - 76, 188, 1, 6, 82, 73, 71, 72, 84, 32, 192, 2, 6, 87, 65, 86, 89, 32, 76, - 178, 156, 4, 83, 252, 217, 4, 9, 84, 87, 79, 32, 68, 79, 84, 32, 76, 139, - 114, 81, 4, 191, 190, 2, 79, 6, 158, 158, 6, 88, 182, 227, 2, 77, 3, 78, - 2, 173, 154, 9, 7, 79, 82, 73, 90, 79, 78, 84, 4, 49, 10, 68, 69, 79, 71, - 82, 65, 80, 72, 73, 67, 4, 11, 32, 4, 218, 235, 9, 67, 35, 70, 22, 40, 4, - 69, 70, 84, 32, 143, 214, 10, 79, 20, 112, 6, 87, 72, 73, 84, 69, 32, - 142, 1, 66, 42, 68, 186, 100, 67, 166, 7, 65, 222, 203, 7, 80, 238, 7, - 83, 39, 84, 4, 162, 2, 67, 255, 99, 76, 22, 110, 66, 42, 68, 36, 6, 87, - 72, 73, 84, 69, 32, 150, 100, 67, 166, 7, 65, 222, 203, 7, 80, 238, 7, - 83, 39, 84, 2, 145, 101, 6, 76, 65, 67, 75, 32, 76, 2, 197, 107, 5, 79, - 85, 66, 76, 69, 6, 74, 67, 17, 14, 76, 69, 78, 84, 73, 67, 85, 76, 65, - 82, 32, 66, 82, 65, 2, 227, 99, 79, 4, 246, 234, 11, 67, 177, 29, 2, 75, - 67, 2, 187, 210, 10, 79, 22, 46, 78, 156, 1, 2, 86, 65, 231, 164, 12, 77, - 10, 34, 84, 133, 211, 6, 2, 67, 69, 6, 26, 32, 53, 2, 69, 82, 2, 21, 3, - 83, 67, 82, 2, 205, 193, 10, 2, 69, 69, 5, 17, 2, 32, 73, 2, 223, 235, - 11, 67, 10, 60, 5, 67, 89, 32, 77, 69, 29, 6, 84, 69, 32, 85, 83, 69, 2, - 213, 171, 7, 2, 83, 83, 8, 26, 32, 231, 180, 8, 45, 4, 134, 166, 10, 84, - 139, 121, 79, 14, 98, 74, 30, 80, 90, 83, 156, 34, 5, 72, 73, 66, 73, 84, - 173, 245, 8, 6, 66, 73, 78, 71, 32, 67, 2, 213, 167, 5, 2, 69, 67, 6, 64, - 6, 79, 82, 84, 73, 79, 78, 137, 157, 11, 4, 69, 82, 84, 89, 5, 183, 215, - 5, 65, 2, 173, 250, 10, 4, 69, 82, 80, 73, 60, 76, 14, 65, 76, 84, 69, - 82, 32, 80, 65, 72, 76, 65, 86, 73, 32, 215, 5, 89, 58, 172, 1, 15, 70, - 79, 85, 82, 32, 68, 79, 84, 83, 32, 87, 73, 84, 72, 32, 32, 7, 76, 69, - 84, 84, 69, 82, 32, 230, 2, 78, 154, 32, 83, 1, 8, 84, 85, 82, 78, 69, - 68, 32, 83, 4, 246, 242, 10, 67, 247, 114, 68, 36, 166, 1, 65, 22, 68, - 34, 76, 22, 77, 50, 87, 254, 169, 4, 71, 90, 90, 34, 83, 66, 89, 198, - 207, 1, 72, 234, 5, 75, 174, 81, 66, 170, 225, 4, 78, 134, 2, 84, 219, - 103, 80, 2, 223, 170, 4, 76, 2, 11, 65, 2, 227, 210, 6, 76, 2, 251, 170, - 4, 65, 2, 25, 4, 69, 77, 45, 81, 2, 255, 128, 6, 79, 2, 37, 7, 65, 87, - 45, 65, 89, 73, 78, 2, 149, 205, 1, 2, 45, 82, 14, 33, 6, 85, 77, 66, 69, - 82, 32, 14, 42, 84, 202, 170, 4, 79, 191, 236, 2, 70, 8, 42, 87, 250, - 191, 10, 72, 207, 162, 1, 69, 4, 182, 194, 10, 69, 239, 239, 1, 79, 2, - 243, 132, 12, 67, 18, 252, 1, 4, 78, 67, 84, 85, 94, 82, 56, 19, 84, 32, - 76, 73, 84, 84, 69, 82, 32, 73, 78, 32, 73, 84, 83, 32, 80, 76, 65, 178, - 151, 1, 83, 132, 42, 20, 66, 76, 73, 67, 32, 65, 68, 68, 82, 69, 83, 83, - 32, 76, 79, 85, 68, 83, 80, 69, 166, 237, 10, 49, 3, 50, 4, 164, 222, 10, - 9, 83, 32, 69, 76, 69, 86, 65, 84, 85, 129, 147, 1, 5, 65, 84, 73, 79, - 78, 4, 32, 2, 80, 76, 155, 152, 12, 83, 2, 175, 167, 11, 69, 2, 11, 67, - 2, 135, 153, 11, 69, 40, 98, 65, 180, 6, 6, 69, 83, 84, 73, 79, 78, 254, - 136, 6, 79, 229, 143, 5, 5, 73, 78, 67, 85, 78, 30, 104, 2, 68, 82, 240, - 4, 9, 84, 69, 82, 78, 73, 79, 78, 32, 73, 48, 4, 82, 84, 69, 82, 143, - 132, 11, 79, 24, 56, 4, 65, 78, 84, 32, 157, 4, 5, 85, 80, 76, 69, 32, - 20, 44, 6, 85, 80, 80, 69, 82, 32, 131, 2, 76, 16, 56, 4, 76, 69, 70, 84, - 249, 1, 5, 82, 73, 71, 72, 84, 11, 29, 5, 32, 65, 78, 68, 32, 8, 108, 6, - 76, 79, 87, 69, 82, 32, 53, 17, 85, 80, 80, 69, 82, 32, 82, 73, 71, 72, - 84, 32, 65, 78, 68, 32, 76, 4, 192, 1, 5, 76, 69, 70, 84, 32, 159, 254, - 11, 82, 4, 11, 79, 4, 11, 87, 4, 213, 254, 11, 2, 69, 82, 7, 65, 14, 32, - 65, 78, 68, 32, 76, 79, 87, 69, 82, 32, 76, 69, 70, 4, 11, 84, 5, 11, 32, - 2, 21, 3, 65, 78, 68, 2, 17, 2, 32, 76, 2, 17, 2, 79, 87, 2, 137, 213, - 10, 2, 69, 82, 4, 22, 73, 239, 37, 80, 2, 177, 228, 8, 7, 78, 84, 69, 71, - 82, 65, 76, 2, 17, 2, 32, 78, 2, 159, 222, 10, 79, 6, 34, 32, 161, 197, - 5, 2, 69, 68, 4, 162, 139, 5, 69, 175, 218, 6, 77, 220, 9, 114, 65, 142, - 8, 69, 220, 27, 6, 72, 73, 78, 79, 67, 69, 34, 73, 250, 87, 76, 46, 79, - 198, 19, 85, 243, 149, 11, 83, 62, 110, 67, 104, 2, 68, 73, 130, 1, 73, - 162, 5, 84, 172, 246, 7, 4, 66, 66, 73, 84, 214, 238, 3, 90, 235, 56, 77, - 6, 40, 4, 73, 78, 71, 32, 159, 250, 8, 67, 4, 192, 208, 10, 7, 77, 79, - 84, 79, 82, 67, 89, 199, 48, 67, 8, 66, 79, 141, 180, 8, 10, 67, 65, 76, - 32, 83, 89, 77, 66, 79, 76, 7, 168, 184, 6, 4, 65, 67, 84, 73, 229, 181, - 4, 2, 32, 66, 36, 60, 5, 76, 87, 65, 89, 32, 46, 78, 21, 4, 83, 69, 68, - 32, 4, 240, 131, 9, 2, 84, 82, 155, 251, 1, 67, 5, 243, 133, 11, 66, 28, - 152, 1, 3, 68, 79, 84, 34, 73, 48, 4, 72, 65, 78, 68, 182, 1, 77, 38, 83, - 166, 177, 7, 70, 206, 151, 2, 67, 161, 197, 1, 7, 66, 65, 67, 75, 32, 79, - 70, 5, 29, 5, 84, 69, 68, 32, 73, 2, 209, 40, 8, 78, 84, 69, 82, 80, 79, - 76, 65, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 214, 27, 70, 245, 194, 2, - 28, 80, 65, 82, 84, 32, 66, 69, 84, 87, 69, 69, 78, 32, 77, 73, 68, 68, - 76, 69, 32, 65, 78, 68, 32, 82, 73, 78, 71, 6, 230, 151, 11, 67, 2, 68, - 3, 82, 4, 60, 9, 77, 65, 76, 76, 32, 76, 69, 70, 84, 179, 251, 10, 81, 2, - 229, 158, 8, 2, 32, 83, 5, 243, 254, 11, 73, 250, 1, 226, 1, 67, 132, 4, - 2, 68, 32, 64, 2, 71, 73, 144, 1, 5, 74, 65, 78, 71, 32, 202, 4, 76, 32, - 8, 77, 73, 78, 68, 69, 82, 32, 82, 34, 80, 106, 83, 136, 1, 5, 84, 85, - 82, 78, 32, 42, 86, 209, 199, 1, 5, 70, 69, 82, 69, 78, 26, 114, 69, 60, - 3, 89, 67, 76, 146, 209, 5, 79, 205, 155, 4, 13, 82, 69, 65, 84, 73, 79, - 78, 65, 76, 32, 86, 69, 72, 4, 38, 73, 209, 198, 10, 3, 80, 84, 65, 2, - 163, 254, 11, 80, 18, 78, 69, 53, 15, 73, 78, 71, 32, 83, 89, 77, 66, 79, - 76, 32, 70, 79, 82, 32, 2, 29, 5, 68, 32, 80, 65, 80, 2, 211, 179, 10, - 69, 16, 100, 5, 84, 89, 80, 69, 45, 173, 130, 5, 14, 71, 69, 78, 69, 82, - 73, 67, 32, 77, 65, 84, 69, 82, 73, 14, 58, 49, 2, 50, 2, 51, 2, 52, 2, - 53, 2, 54, 3, 55, 2, 133, 210, 5, 6, 32, 80, 76, 65, 83, 84, 4, 42, 65, - 205, 255, 4, 4, 71, 73, 70, 84, 2, 231, 190, 3, 80, 54, 120, 4, 83, 84, - 69, 82, 213, 244, 5, 20, 79, 78, 65, 76, 32, 73, 78, 68, 73, 67, 65, 84, - 79, 82, 32, 83, 89, 77, 66, 79, 2, 235, 170, 10, 69, 74, 128, 1, 15, 67, - 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 44, 7, 76, 69, - 84, 84, 69, 82, 32, 226, 1, 83, 35, 86, 8, 146, 151, 10, 78, 130, 254, 1, - 72, 3, 82, 46, 162, 1, 78, 186, 253, 7, 77, 214, 147, 4, 66, 2, 67, 2, - 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, - 2, 89, 187, 2, 65, 12, 154, 254, 7, 89, 166, 31, 71, 206, 243, 3, 68, - 187, 2, 65, 2, 11, 69, 2, 211, 169, 11, 67, 18, 64, 10, 79, 87, 69, 76, - 32, 83, 73, 71, 78, 32, 139, 214, 9, 73, 16, 54, 69, 182, 209, 11, 65, - 186, 64, 73, 2, 79, 3, 85, 7, 234, 145, 12, 65, 3, 85, 2, 217, 254, 10, - 3, 73, 69, 86, 2, 193, 193, 11, 3, 73, 66, 66, 2, 41, 8, 76, 65, 67, 69, - 77, 69, 78, 84, 2, 17, 2, 32, 67, 2, 193, 214, 10, 5, 72, 65, 82, 65, 67, - 8, 32, 2, 84, 82, 231, 254, 6, 80, 6, 152, 138, 8, 16, 73, 67, 84, 69, - 68, 32, 76, 69, 70, 84, 32, 69, 78, 84, 82, 89, 135, 245, 3, 79, 6, 242, - 249, 10, 83, 194, 106, 76, 31, 82, 70, 64, 4, 69, 82, 83, 69, 197, 246, - 3, 6, 79, 76, 86, 73, 78, 71, 68, 30, 32, 169, 3, 2, 68, 32, 20, 184, 1, - 6, 67, 72, 69, 67, 75, 69, 28, 2, 76, 73, 108, 7, 83, 79, 76, 73, 68, 85, - 83, 232, 229, 7, 16, 84, 73, 76, 68, 69, 32, 79, 80, 69, 82, 65, 84, 79, - 82, 32, 65, 195, 253, 2, 73, 2, 197, 243, 10, 2, 82, 32, 4, 152, 212, 3, - 18, 71, 72, 84, 32, 70, 79, 85, 82, 32, 80, 79, 73, 78, 84, 69, 68, 32, - 80, 135, 237, 1, 78, 9, 11, 32, 6, 240, 166, 5, 9, 80, 82, 69, 67, 69, - 68, 73, 78, 71, 166, 161, 3, 79, 251, 154, 1, 87, 48, 248, 2, 5, 65, 78, - 71, 76, 69, 20, 7, 68, 79, 85, 66, 76, 69, 32, 118, 78, 20, 5, 70, 79, - 82, 75, 69, 70, 80, 82, 82, 214, 1, 83, 106, 84, 236, 238, 6, 30, 72, 65, - 78, 68, 32, 87, 73, 84, 72, 32, 77, 73, 68, 68, 76, 69, 32, 70, 73, 78, - 71, 69, 82, 32, 69, 88, 84, 69, 78, 68, 198, 190, 2, 67, 114, 81, 180, - 102, 6, 69, 77, 80, 84, 89, 32, 253, 93, 7, 86, 73, 67, 84, 79, 82, 89, - 5, 247, 231, 3, 32, 6, 40, 3, 80, 82, 73, 41, 3, 83, 84, 82, 4, 17, 2, - 77, 69, 5, 195, 184, 3, 32, 2, 29, 5, 79, 75, 69, 32, 78, 2, 155, 187, 6, - 79, 2, 49, 10, 68, 32, 80, 65, 82, 65, 71, 82, 65, 80, 2, 179, 4, 72, 4, - 36, 3, 73, 76, 67, 239, 235, 10, 82, 2, 11, 82, 2, 217, 254, 10, 2, 79, - 87, 6, 156, 1, 17, 65, 73, 83, 69, 68, 32, 72, 65, 78, 68, 32, 87, 73, - 84, 72, 32, 70, 148, 107, 8, 79, 84, 65, 84, 69, 68, 32, 70, 253, 176, 6, - 4, 73, 71, 72, 84, 2, 209, 112, 9, 73, 78, 71, 69, 82, 83, 32, 83, 80, 4, - 156, 134, 1, 17, 65, 78, 83, 45, 83, 69, 82, 73, 70, 32, 67, 65, 80, 73, - 84, 65, 76, 191, 174, 7, 69, 10, 88, 4, 73, 76, 68, 69, 28, 7, 82, 73, - 80, 76, 69, 32, 80, 225, 160, 7, 3, 72, 85, 77, 5, 237, 235, 4, 2, 32, - 69, 2, 143, 232, 10, 82, 2, 11, 82, 2, 143, 196, 11, 79, 147, 4, 228, 1, - 4, 66, 66, 79, 78, 152, 1, 3, 67, 69, 32, 60, 3, 71, 72, 84, 188, 81, 2, - 78, 71, 252, 1, 23, 83, 73, 78, 71, 32, 68, 73, 65, 71, 79, 78, 65, 76, - 32, 67, 82, 79, 83, 83, 73, 78, 71, 32, 198, 222, 5, 65, 227, 165, 4, 70, - 19, 37, 7, 32, 65, 82, 82, 79, 87, 32, 16, 88, 3, 76, 69, 70, 0, 4, 82, - 73, 71, 72, 178, 197, 4, 85, 161, 142, 7, 3, 68, 79, 87, 4, 207, 252, 1, - 84, 4, 26, 67, 135, 244, 9, 66, 2, 157, 145, 1, 3, 82, 65, 67, 224, 3, - 110, 32, 190, 36, 45, 152, 12, 11, 72, 65, 78, 68, 32, 73, 78, 84, 69, - 82, 73, 29, 6, 87, 65, 82, 68, 83, 32, 202, 1, 166, 2, 65, 132, 6, 2, 66, - 76, 62, 67, 184, 1, 2, 68, 79, 242, 1, 70, 60, 2, 72, 65, 176, 5, 13, 74, - 85, 83, 84, 73, 70, 73, 69, 68, 32, 76, 69, 70, 20, 2, 76, 79, 66, 78, - 82, 79, 122, 80, 148, 1, 2, 82, 65, 58, 83, 154, 6, 84, 160, 5, 9, 86, - 69, 82, 84, 73, 67, 65, 76, 32, 147, 1, 87, 28, 22, 78, 163, 4, 82, 22, - 24, 2, 68, 32, 39, 71, 4, 170, 50, 76, 21, 3, 85, 80, 80, 18, 26, 69, 17, - 2, 76, 69, 2, 203, 26, 82, 17, 11, 32, 14, 154, 1, 66, 44, 8, 68, 79, 84, - 84, 69, 68, 32, 83, 2, 83, 112, 5, 87, 73, 84, 72, 32, 189, 212, 10, 12, - 86, 65, 82, 73, 65, 78, 84, 32, 87, 73, 84, 72, 4, 173, 210, 10, 6, 82, - 65, 67, 75, 69, 84, 2, 37, 7, 85, 66, 83, 84, 73, 84, 85, 2, 25, 4, 84, - 73, 79, 78, 2, 21, 3, 32, 77, 65, 2, 171, 138, 1, 82, 4, 68, 11, 68, 79, - 87, 78, 87, 65, 82, 68, 83, 32, 90, 139, 247, 8, 65, 2, 141, 218, 10, 5, - 73, 71, 90, 65, 71, 6, 18, 67, 79, 82, 2, 41, 8, 32, 71, 82, 69, 65, 84, - 69, 82, 2, 249, 24, 4, 45, 84, 72, 65, 4, 41, 8, 79, 87, 32, 87, 73, 84, - 72, 32, 4, 144, 234, 7, 7, 67, 73, 82, 67, 76, 69, 68, 207, 182, 2, 83, - 4, 25, 4, 65, 67, 75, 32, 4, 130, 27, 76, 223, 218, 7, 84, 12, 38, 85, - 166, 26, 79, 243, 235, 2, 69, 8, 53, 11, 82, 76, 89, 32, 66, 82, 65, 67, - 75, 69, 84, 9, 11, 32, 6, 44, 4, 77, 73, 68, 68, 250, 10, 76, 27, 85, 2, - 221, 186, 10, 2, 76, 69, 12, 38, 84, 41, 5, 85, 66, 76, 69, 32, 2, 137, - 17, 6, 84, 69, 68, 32, 83, 85, 10, 50, 65, 94, 87, 214, 162, 3, 81, 199, - 199, 4, 80, 4, 162, 31, 78, 173, 161, 3, 15, 82, 82, 79, 87, 32, 87, 73, - 84, 72, 32, 82, 79, 85, 78, 68, 2, 139, 24, 73, 6, 26, 73, 155, 131, 3, - 76, 4, 238, 215, 8, 86, 191, 97, 83, 28, 32, 3, 76, 70, 32, 187, 4, 78, - 26, 128, 1, 8, 65, 78, 68, 32, 76, 69, 70, 84, 62, 66, 90, 70, 82, 72, - 50, 82, 58, 84, 70, 87, 246, 13, 76, 22, 85, 175, 227, 8, 77, 2, 29, 5, - 32, 72, 65, 76, 70, 2, 201, 217, 8, 2, 32, 87, 6, 11, 76, 6, 40, 4, 65, - 67, 75, 32, 183, 188, 10, 79, 4, 158, 154, 10, 67, 207, 11, 83, 4, 58, - 79, 237, 156, 3, 8, 76, 89, 73, 78, 71, 32, 83, 65, 2, 131, 202, 9, 76, - 2, 209, 216, 8, 7, 79, 82, 73, 90, 79, 78, 84, 2, 33, 6, 85, 78, 78, 73, - 78, 71, 2, 203, 238, 6, 32, 2, 153, 173, 5, 12, 82, 73, 80, 76, 69, 32, - 68, 65, 83, 72, 32, 72, 2, 209, 167, 10, 4, 72, 73, 84, 69, 2, 173, 152, - 1, 16, 68, 32, 84, 69, 76, 69, 80, 72, 79, 78, 69, 32, 82, 69, 67, 69, 4, - 187, 231, 7, 84, 2, 145, 152, 11, 11, 87, 32, 80, 65, 82, 65, 80, 72, 82, - 65, 83, 2, 177, 4, 16, 79, 82, 77, 65, 76, 32, 70, 65, 67, 84, 79, 82, - 32, 83, 69, 77, 8, 74, 85, 166, 221, 8, 78, 225, 189, 1, 8, 80, 69, 78, - 32, 83, 81, 85, 65, 2, 221, 233, 10, 6, 84, 69, 82, 32, 74, 79, 8, 49, - 10, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 9, 11, 32, 6, 34, 76, 26, 85, - 255, 196, 9, 69, 2, 157, 37, 2, 79, 87, 2, 133, 37, 2, 80, 80, 2, 217, - 10, 10, 73, 83, 69, 68, 32, 79, 77, 73, 83, 83, 40, 62, 45, 70, 69, 78, - 73, 68, 2, 80, 69, 126, 81, 227, 2, 85, 2, 173, 128, 8, 12, 83, 72, 65, - 80, 69, 68, 32, 66, 65, 71, 32, 68, 4, 26, 77, 191, 236, 8, 86, 2, 217, - 212, 10, 7, 73, 68, 73, 82, 69, 67, 84, 4, 210, 150, 3, 78, 169, 252, 7, - 8, 68, 69, 87, 65, 89, 83, 32, 85, 8, 32, 4, 65, 75, 69, 82, 67, 69, 7, - 33, 6, 32, 87, 73, 84, 72, 32, 4, 246, 252, 3, 79, 55, 84, 2, 137, 5, 2, - 67, 72, 20, 57, 12, 85, 65, 82, 69, 32, 66, 82, 65, 67, 75, 69, 84, 21, - 11, 32, 18, 84, 3, 76, 79, 87, 0, 3, 85, 80, 80, 28, 5, 87, 73, 84, 72, - 32, 227, 191, 9, 69, 2, 245, 230, 3, 2, 69, 82, 12, 96, 8, 84, 73, 67, - 75, 32, 73, 78, 32, 230, 6, 81, 166, 236, 7, 85, 134, 126, 68, 135, 193, - 2, 83, 4, 244, 229, 3, 6, 66, 79, 84, 84, 79, 77, 1, 3, 84, 79, 80, 2, - 165, 4, 6, 66, 83, 84, 73, 84, 85, 26, 54, 72, 130, 3, 82, 130, 223, 7, - 79, 235, 204, 2, 65, 14, 62, 73, 116, 5, 79, 85, 71, 72, 84, 45, 4, 82, - 69, 69, 32, 4, 21, 3, 82, 68, 32, 4, 68, 4, 73, 78, 68, 85, 221, 211, 1, - 7, 87, 72, 73, 84, 69, 32, 82, 2, 215, 166, 11, 67, 2, 11, 32, 2, 213, - 136, 3, 3, 66, 85, 66, 8, 60, 9, 81, 85, 65, 82, 84, 69, 82, 83, 32, 151, - 230, 8, 69, 6, 34, 76, 22, 85, 139, 236, 8, 66, 2, 37, 2, 79, 87, 2, 17, - 2, 80, 80, 2, 227, 230, 8, 69, 8, 34, 65, 89, 4, 73, 65, 78, 71, 2, 33, - 6, 78, 83, 80, 79, 83, 73, 2, 11, 84, 2, 17, 2, 73, 79, 2, 147, 138, 11, - 78, 6, 32, 2, 76, 69, 159, 229, 8, 85, 5, 41, 8, 32, 65, 66, 79, 86, 69, - 32, 76, 2, 181, 178, 9, 2, 69, 70, 6, 18, 66, 95, 82, 4, 68, 9, 65, 82, - 32, 87, 73, 84, 72, 32, 81, 213, 191, 10, 2, 79, 88, 2, 211, 223, 8, 85, - 2, 189, 188, 9, 3, 85, 76, 69, 14, 22, 72, 203, 1, 73, 12, 25, 4, 73, 84, - 69, 32, 12, 54, 67, 54, 76, 206, 210, 7, 80, 238, 7, 83, 39, 84, 4, 26, - 79, 163, 207, 7, 85, 2, 65, 3, 82, 78, 69, 2, 41, 8, 69, 78, 84, 73, 67, - 85, 76, 65, 2, 183, 134, 11, 82, 2, 225, 199, 6, 6, 71, 71, 76, 89, 32, - 70, 62, 118, 70, 226, 2, 72, 128, 1, 9, 80, 79, 73, 78, 84, 73, 78, 71, - 32, 214, 4, 83, 197, 1, 6, 84, 79, 45, 76, 69, 70, 18, 33, 6, 65, 67, 73, - 78, 71, 32, 18, 116, 14, 65, 82, 77, 69, 78, 73, 65, 78, 32, 69, 84, 69, - 82, 78, 20, 4, 66, 65, 83, 83, 16, 3, 70, 73, 83, 87, 83, 2, 255, 159, 8, - 73, 2, 175, 43, 73, 6, 26, 72, 151, 214, 11, 84, 5, 11, 32, 2, 233, 176, - 8, 6, 87, 73, 84, 72, 32, 79, 8, 140, 208, 3, 10, 86, 65, 83, 84, 73, 32, - 83, 73, 71, 78, 195, 223, 4, 78, 2, 81, 18, 65, 78, 68, 69, 68, 32, 73, - 78, 84, 69, 82, 76, 65, 67, 69, 68, 32, 80, 2, 21, 3, 69, 78, 84, 2, 251, - 150, 10, 65, 30, 90, 65, 30, 67, 94, 68, 58, 77, 58, 82, 182, 1, 83, 74, - 84, 210, 172, 8, 69, 179, 124, 71, 4, 90, 78, 159, 175, 8, 84, 2, 29, 5, - 85, 82, 86, 69, 68, 2, 17, 2, 32, 65, 2, 11, 78, 2, 217, 255, 10, 2, 71, - 76, 4, 136, 131, 3, 5, 79, 85, 66, 76, 69, 179, 188, 6, 73, 2, 165, 184, - 10, 9, 65, 71, 78, 73, 70, 89, 73, 78, 71, 10, 38, 79, 154, 178, 9, 65, - 235, 29, 73, 6, 92, 5, 67, 75, 69, 84, 32, 213, 177, 9, 12, 76, 76, 69, - 82, 32, 67, 79, 65, 83, 84, 69, 82, 4, 176, 43, 3, 66, 79, 79, 143, 208, - 10, 83, 2, 11, 84, 2, 21, 3, 73, 67, 75, 2, 185, 187, 6, 4, 32, 70, 73, - 71, 2, 239, 234, 7, 65, 4, 46, 72, 85, 7, 73, 68, 69, 32, 65, 82, 67, 2, - 17, 2, 65, 68, 2, 17, 2, 69, 68, 2, 209, 172, 10, 6, 32, 87, 72, 73, 84, - 69, 2, 11, 32, 2, 201, 239, 8, 8, 67, 76, 79, 67, 75, 87, 73, 83, 8, 17, - 2, 84, 32, 8, 86, 73, 40, 4, 79, 86, 69, 82, 176, 134, 5, 5, 69, 77, 66, - 69, 68, 139, 133, 6, 77, 2, 17, 2, 83, 79, 2, 131, 135, 1, 76, 2, 135, - 155, 3, 82, 2, 141, 187, 10, 2, 79, 82, 214, 1, 160, 1, 5, 65, 82, 82, - 79, 87, 130, 9, 66, 86, 68, 210, 1, 70, 122, 72, 178, 6, 76, 26, 79, 34, - 80, 50, 82, 70, 83, 94, 84, 206, 8, 87, 202, 197, 8, 67, 47, 81, 75, 26, - 32, 195, 147, 9, 45, 70, 94, 65, 170, 2, 70, 110, 84, 184, 1, 5, 87, 73, - 84, 72, 32, 129, 160, 1, 4, 79, 86, 69, 82, 12, 40, 5, 66, 79, 86, 69, - 32, 143, 1, 78, 10, 70, 82, 216, 163, 1, 5, 83, 72, 79, 82, 84, 222, 194, - 3, 65, 55, 84, 4, 37, 7, 69, 86, 69, 82, 83, 69, 32, 4, 138, 230, 4, 65, - 55, 84, 2, 61, 13, 68, 32, 85, 80, 80, 69, 82, 32, 65, 78, 68, 32, 76, 2, - 17, 2, 79, 87, 2, 129, 213, 8, 2, 69, 82, 6, 25, 4, 82, 79, 77, 32, 6, - 36, 3, 66, 65, 82, 187, 213, 8, 68, 5, 189, 1, 6, 32, 84, 79, 32, 66, 76, - 10, 56, 7, 72, 82, 79, 85, 71, 72, 32, 65, 3, 79, 32, 66, 6, 224, 224, 4, - 3, 83, 85, 80, 234, 207, 4, 71, 247, 149, 2, 88, 4, 26, 76, 139, 141, 11, - 65, 2, 153, 247, 9, 3, 65, 67, 75, 40, 140, 1, 6, 67, 79, 82, 78, 69, 82, - 26, 68, 98, 76, 86, 80, 30, 83, 38, 84, 138, 210, 8, 77, 38, 78, 122, 69, - 150, 153, 1, 72, 171, 165, 1, 86, 2, 209, 18, 2, 32, 68, 4, 11, 79, 4, - 40, 4, 84, 84, 69, 68, 203, 219, 7, 85, 2, 17, 2, 32, 83, 2, 163, 177, - 11, 84, 6, 26, 79, 231, 210, 8, 65, 4, 26, 87, 251, 194, 11, 79, 2, 157, - 201, 3, 2, 69, 82, 2, 193, 145, 9, 2, 76, 85, 6, 146, 211, 8, 77, 203, - 191, 2, 84, 10, 154, 16, 73, 171, 3, 65, 8, 58, 65, 204, 11, 5, 79, 84, - 84, 79, 77, 187, 199, 8, 76, 2, 145, 2, 2, 67, 75, 14, 48, 6, 79, 85, 66, - 76, 69, 32, 167, 225, 8, 65, 12, 40, 5, 65, 82, 82, 79, 87, 211, 18, 68, - 11, 26, 32, 143, 137, 9, 45, 6, 26, 87, 167, 215, 8, 70, 4, 25, 4, 73, - 84, 72, 32, 4, 186, 143, 11, 86, 79, 83, 4, 40, 4, 82, 79, 78, 84, 195, - 210, 8, 73, 2, 193, 209, 8, 14, 45, 84, 73, 76, 84, 69, 68, 32, 83, 72, - 65, 68, 79, 87, 30, 26, 65, 251, 213, 8, 69, 26, 48, 6, 82, 80, 79, 79, - 78, 32, 131, 248, 10, 78, 24, 80, 10, 87, 73, 84, 72, 32, 66, 65, 82, 66, - 32, 197, 152, 1, 4, 79, 86, 69, 82, 22, 44, 4, 68, 79, 87, 78, 173, 1, 2, - 85, 80, 10, 26, 32, 231, 219, 8, 87, 8, 76, 8, 65, 66, 79, 86, 69, 32, - 76, 69, 18, 66, 166, 211, 8, 70, 179, 5, 84, 2, 227, 2, 70, 2, 253, 222, - 4, 7, 69, 76, 79, 87, 32, 76, 79, 12, 26, 32, 187, 218, 8, 87, 10, 60, 6, - 65, 66, 79, 86, 69, 32, 154, 210, 8, 70, 179, 5, 84, 6, 22, 76, 155, 1, - 82, 4, 32, 2, 69, 70, 187, 221, 4, 79, 2, 213, 144, 2, 24, 84, 87, 65, - 82, 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, 72, 32, 66, - 65, 82, 66, 2, 21, 3, 73, 71, 72, 2, 105, 24, 84, 87, 65, 82, 68, 83, 32, - 72, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, 72, 32, 66, 65, 82, 66, 2, - 11, 32, 2, 139, 241, 1, 68, 2, 141, 1, 2, 69, 70, 2, 201, 212, 8, 3, 80, - 69, 78, 4, 202, 216, 8, 65, 233, 206, 1, 3, 85, 83, 72, 4, 36, 3, 73, 71, - 72, 223, 228, 10, 79, 2, 11, 84, 2, 171, 1, 45, 6, 32, 2, 81, 85, 215, - 207, 8, 65, 4, 26, 73, 239, 207, 8, 65, 2, 229, 215, 8, 2, 71, 71, 54, - 38, 79, 60, 2, 82, 73, 227, 4, 87, 2, 11, 80, 2, 11, 32, 2, 253, 199, 8, - 4, 83, 72, 65, 68, 34, 40, 5, 65, 78, 71, 76, 69, 255, 3, 80, 30, 56, 8, - 45, 72, 69, 65, 68, 69, 68, 32, 251, 219, 8, 32, 28, 52, 5, 65, 82, 82, - 79, 87, 202, 212, 8, 68, 39, 80, 25, 11, 32, 22, 64, 8, 79, 86, 69, 82, - 32, 76, 69, 70, 22, 87, 135, 208, 8, 84, 2, 183, 207, 8, 84, 18, 25, 4, - 73, 84, 72, 32, 18, 128, 1, 7, 68, 79, 85, 66, 76, 69, 32, 36, 7, 76, 79, - 78, 71, 32, 84, 73, 230, 207, 8, 66, 158, 1, 77, 34, 78, 34, 86, 35, 72, - 4, 166, 138, 9, 72, 195, 247, 1, 86, 4, 11, 80, 4, 11, 32, 4, 18, 68, 35, - 85, 2, 181, 208, 8, 3, 79, 87, 78, 2, 151, 208, 8, 80, 4, 21, 3, 76, 69, - 32, 4, 138, 3, 68, 203, 145, 10, 65, 18, 11, 79, 18, 56, 8, 45, 72, 69, - 65, 68, 69, 68, 32, 175, 210, 8, 32, 16, 76, 6, 65, 82, 82, 79, 87, 32, - 213, 1, 8, 84, 82, 73, 80, 76, 69, 32, 68, 14, 44, 5, 87, 73, 84, 72, 32, - 179, 198, 8, 70, 12, 42, 84, 210, 198, 7, 68, 235, 183, 3, 86, 8, 26, 65, - 243, 209, 8, 82, 6, 17, 2, 73, 76, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, - 250, 197, 7, 68, 235, 183, 3, 86, 2, 249, 132, 1, 2, 65, 83, 8, 58, 65, - 21, 10, 72, 73, 84, 69, 32, 65, 82, 82, 79, 87, 2, 207, 206, 8, 86, 7, - 11, 32, 4, 216, 193, 2, 4, 70, 82, 79, 77, 219, 145, 6, 87, 19, 66, 32, - 136, 1, 6, 69, 68, 32, 80, 76, 65, 21, 3, 73, 78, 71, 12, 82, 66, 22, 80, - 212, 201, 4, 2, 73, 78, 26, 69, 154, 158, 3, 79, 195, 198, 2, 65, 2, 239, - 153, 11, 85, 2, 11, 79, 2, 135, 232, 10, 73, 2, 247, 245, 10, 78, 2, 209, - 199, 3, 2, 32, 66, 4, 24, 2, 70, 65, 75, 83, 2, 17, 2, 76, 76, 2, 21, 3, - 73, 78, 71, 2, 177, 231, 1, 2, 32, 68, 2, 189, 173, 3, 2, 79, 85, 8, 222, - 169, 11, 69, 2, 73, 2, 77, 3, 79, 126, 136, 2, 2, 67, 75, 20, 2, 76, 76, - 188, 2, 4, 77, 65, 78, 32, 194, 8, 79, 80, 2, 83, 69, 20, 6, 84, 65, 84, - 69, 68, 32, 152, 3, 3, 85, 78, 68, 170, 178, 3, 87, 252, 213, 3, 15, 65, - 83, 84, 69, 68, 32, 83, 87, 69, 69, 84, 32, 80, 79, 84, 185, 166, 2, 2, - 66, 79, 5, 251, 138, 11, 69, 10, 130, 1, 69, 64, 4, 32, 79, 70, 32, 101, - 21, 73, 78, 71, 32, 79, 78, 32, 84, 72, 69, 32, 70, 76, 79, 79, 82, 32, - 76, 65, 85, 71, 6, 60, 9, 68, 45, 85, 80, 32, 78, 69, 87, 83, 33, 2, 82, - 32, 2, 11, 80, 2, 175, 131, 2, 65, 4, 28, 3, 67, 79, 65, 23, 83, 2, 131, - 235, 9, 83, 2, 135, 95, 75, 2, 231, 211, 10, 72, 72, 140, 1, 6, 67, 69, - 78, 84, 85, 82, 22, 68, 100, 3, 81, 85, 73, 28, 8, 78, 85, 77, 69, 82, - 65, 76, 32, 182, 4, 83, 114, 85, 135, 235, 7, 65, 2, 159, 215, 5, 73, 6, - 98, 69, 232, 5, 5, 85, 80, 79, 78, 68, 61, 12, 73, 77, 73, 68, 73, 65, - 32, 83, 69, 88, 84, 85, 2, 229, 5, 3, 78, 65, 82, 48, 142, 1, 70, 136, 1, - 3, 79, 78, 69, 134, 1, 83, 66, 84, 232, 14, 10, 82, 69, 86, 69, 82, 83, - 69, 68, 32, 79, 150, 237, 2, 69, 163, 135, 7, 78, 14, 26, 73, 183, 168, - 10, 79, 12, 36, 3, 70, 84, 89, 255, 254, 2, 86, 7, 11, 32, 4, 194, 196, - 5, 84, 177, 221, 4, 5, 69, 65, 82, 76, 89, 11, 11, 32, 8, 50, 72, 41, 8, - 84, 72, 79, 85, 83, 65, 78, 68, 4, 185, 1, 6, 85, 78, 68, 82, 69, 68, 5, - 141, 130, 4, 2, 32, 67, 6, 32, 2, 73, 88, 159, 172, 9, 69, 5, 241, 159, - 10, 2, 32, 76, 10, 42, 69, 150, 253, 2, 87, 239, 174, 6, 72, 4, 11, 78, - 5, 11, 32, 2, 131, 194, 5, 84, 10, 46, 69, 189, 200, 7, 5, 73, 76, 73, - 81, 85, 8, 60, 2, 77, 85, 40, 5, 83, 84, 69, 82, 84, 21, 2, 88, 84, 2, - 17, 2, 78, 67, 2, 231, 199, 7, 73, 2, 207, 234, 7, 73, 4, 18, 65, 23, 85, - 2, 179, 234, 7, 78, 2, 151, 199, 7, 76, 4, 48, 6, 84, 32, 86, 69, 71, 69, - 219, 225, 9, 83, 2, 141, 197, 2, 2, 84, 65, 5, 179, 210, 9, 84, 10, 166, - 2, 70, 32, 11, 72, 69, 65, 86, 89, 32, 66, 76, 65, 67, 75, 52, 24, 76, - 73, 71, 72, 84, 32, 70, 79, 85, 82, 32, 80, 79, 73, 78, 84, 69, 68, 32, - 66, 76, 65, 67, 75, 0, 18, 87, 72, 73, 84, 69, 32, 70, 79, 85, 82, 32, - 80, 79, 73, 78, 84, 69, 68, 161, 53, 8, 67, 65, 80, 73, 84, 65, 76, 32, - 2, 29, 5, 76, 79, 82, 65, 76, 2, 201, 182, 9, 8, 32, 72, 69, 65, 82, 84, - 32, 66, 2, 213, 207, 9, 2, 32, 67, 16, 74, 32, 89, 14, 69, 68, 32, 83, - 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 4, 24, 2, 80, 85, 43, 84, 2, 11, - 83, 2, 209, 151, 10, 2, 72, 80, 2, 147, 222, 3, 65, 12, 68, 2, 83, 72, - 238, 162, 6, 67, 222, 206, 4, 70, 2, 76, 147, 17, 88, 4, 40, 4, 85, 65, - 78, 71, 159, 241, 10, 79, 2, 171, 130, 11, 88, 136, 2, 226, 1, 66, 20, 3, - 71, 66, 89, 40, 5, 76, 69, 45, 68, 69, 40, 3, 77, 73, 32, 154, 5, 78, - 156, 26, 26, 83, 83, 73, 65, 78, 32, 65, 83, 84, 82, 79, 76, 79, 71, 73, - 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 203, 152, 5, 80, 2, 255, 243, - 8, 76, 2, 177, 137, 9, 5, 32, 70, 79, 79, 84, 2, 11, 76, 2, 165, 255, 5, - 2, 65, 89, 62, 68, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 102, 78, 171, - 198, 2, 68, 8, 40, 4, 79, 78, 69, 32, 187, 175, 9, 84, 6, 34, 84, 250, - 139, 9, 72, 47, 81, 2, 167, 141, 9, 72, 36, 33, 6, 85, 77, 66, 69, 82, - 32, 36, 76, 5, 69, 73, 71, 72, 84, 38, 70, 92, 2, 78, 73, 22, 79, 18, 83, - 83, 84, 4, 158, 137, 3, 32, 231, 135, 8, 89, 8, 18, 73, 35, 79, 4, 130, - 2, 86, 235, 158, 9, 70, 4, 136, 2, 2, 85, 82, 195, 158, 9, 82, 4, 77, 2, - 78, 69, 2, 167, 1, 78, 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 4, 206, - 135, 3, 32, 159, 246, 7, 84, 10, 34, 72, 50, 87, 223, 190, 10, 69, 4, 32, - 2, 82, 69, 199, 158, 9, 73, 2, 39, 69, 4, 26, 79, 183, 158, 9, 69, 2, - 187, 134, 3, 32, 182, 1, 32, 3, 73, 67, 32, 147, 25, 78, 178, 1, 220, 1, - 6, 66, 69, 76, 71, 84, 72, 20, 4, 67, 82, 79, 83, 20, 7, 76, 69, 84, 84, - 69, 82, 32, 210, 22, 83, 24, 6, 77, 85, 76, 84, 73, 80, 216, 196, 7, 5, - 65, 82, 76, 65, 85, 161, 202, 1, 7, 84, 86, 73, 77, 65, 68, 85, 2, 135, - 166, 9, 79, 2, 235, 197, 7, 83, 166, 1, 202, 4, 65, 110, 67, 98, 68, 126, - 69, 82, 70, 222, 1, 71, 104, 2, 72, 65, 50, 73, 220, 1, 5, 74, 69, 82, - 65, 78, 34, 75, 58, 76, 234, 1, 79, 128, 1, 13, 82, 65, 73, 68, 79, 32, - 82, 65, 68, 32, 82, 69, 73, 34, 83, 176, 2, 16, 66, 69, 82, 75, 65, 78, - 65, 78, 32, 66, 69, 79, 82, 67, 32, 66, 144, 1, 12, 78, 65, 85, 68, 73, - 90, 32, 78, 89, 68, 32, 78, 110, 84, 194, 1, 87, 128, 91, 7, 85, 82, 85, - 90, 32, 85, 82, 196, 189, 2, 10, 77, 65, 78, 78, 65, 90, 32, 77, 65, 78, - 168, 63, 13, 80, 69, 82, 84, 72, 79, 32, 80, 69, 79, 82, 84, 72, 206, - 199, 3, 89, 158, 214, 3, 81, 2, 86, 2, 88, 3, 90, 8, 222, 4, 69, 174, - 185, 6, 67, 0, 4, 78, 83, 85, 90, 189, 186, 3, 9, 76, 71, 73, 90, 32, 69, - 79, 76, 72, 11, 46, 69, 30, 65, 245, 152, 7, 3, 87, 69, 79, 4, 26, 65, - 211, 133, 11, 78, 2, 191, 219, 9, 76, 11, 84, 6, 79, 84, 84, 69, 68, 45, - 193, 231, 3, 9, 65, 71, 65, 90, 32, 68, 65, 69, 71, 6, 226, 132, 11, 76, - 2, 78, 3, 80, 11, 136, 76, 7, 72, 87, 65, 90, 32, 69, 72, 218, 255, 9, - 65, 206, 55, 84, 63, 78, 12, 120, 13, 82, 65, 78, 75, 83, 32, 67, 65, 83, - 75, 69, 84, 32, 145, 180, 7, 11, 69, 72, 85, 32, 70, 69, 79, 72, 32, 70, - 69, 10, 46, 65, 234, 196, 10, 73, 2, 79, 207, 60, 69, 4, 26, 69, 171, - 130, 11, 67, 2, 151, 216, 9, 83, 9, 26, 69, 159, 201, 10, 65, 4, 52, 7, - 66, 79, 32, 71, 89, 70, 85, 195, 129, 11, 82, 2, 235, 128, 11, 32, 4, - 236, 8, 2, 69, 71, 13, 4, 71, 76, 65, 90, 12, 156, 1, 2, 78, 71, 20, 9, - 83, 65, 90, 32, 73, 83, 32, 73, 83, 20, 5, 87, 65, 90, 32, 69, 216, 198, - 10, 10, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 3, 79, 5, 199, 211, 6, - 87, 2, 183, 191, 10, 83, 2, 163, 254, 10, 79, 2, 11, 32, 2, 147, 255, 10, - 74, 7, 21, 3, 65, 85, 78, 4, 206, 251, 10, 32, 155, 3, 65, 12, 120, 15, - 65, 85, 75, 65, 90, 32, 76, 65, 71, 85, 32, 76, 79, 71, 82, 21, 11, 79, - 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 2, 251, 241, 9, 32, 10, 64, 3, - 65, 82, 32, 158, 4, 72, 62, 77, 66, 79, 131, 191, 10, 89, 2, 159, 230, - 10, 65, 15, 150, 5, 83, 0, 12, 84, 72, 65, 76, 65, 78, 32, 69, 84, 72, - 69, 76, 188, 247, 10, 4, 80, 69, 78, 45, 14, 69, 2, 78, 3, 79, 2, 11, 68, - 2, 247, 194, 10, 32, 26, 150, 1, 72, 244, 2, 18, 73, 71, 69, 76, 32, 76, - 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 83, 208, 253, 6, 5, 79, 87, - 73, 76, 79, 203, 173, 2, 84, 21, 45, 9, 79, 82, 84, 45, 84, 87, 73, 71, - 45, 18, 102, 66, 58, 72, 62, 77, 30, 78, 38, 79, 42, 83, 186, 1, 84, 128, - 173, 6, 2, 65, 82, 163, 144, 4, 89, 2, 33, 6, 74, 65, 82, 75, 65, 78, 2, - 243, 186, 9, 32, 2, 25, 4, 65, 71, 65, 76, 2, 11, 76, 2, 159, 247, 10, - 32, 2, 253, 154, 3, 2, 65, 68, 2, 157, 168, 10, 4, 65, 85, 68, 32, 2, 17, - 2, 83, 83, 2, 211, 216, 10, 32, 2, 11, 79, 2, 195, 253, 6, 76, 4, 116, - 15, 72, 85, 82, 73, 83, 65, 90, 32, 84, 72, 85, 82, 83, 32, 84, 33, 10, - 73, 87, 65, 90, 32, 84, 73, 82, 32, 84, 2, 11, 72, 2, 171, 227, 5, 79, 2, - 17, 2, 89, 82, 2, 187, 217, 10, 32, 5, 41, 8, 85, 78, 74, 79, 32, 87, 89, - 78, 2, 11, 78, 2, 251, 246, 9, 32, 2, 21, 3, 73, 78, 71, 2, 237, 174, 7, - 2, 76, 69, 4, 188, 137, 9, 16, 73, 78, 71, 32, 83, 72, 73, 82, 84, 32, - 87, 73, 84, 72, 32, 83, 187, 178, 1, 69, 12, 120, 3, 66, 73, 78, 2, 78, - 28, 2, 81, 85, 0, 3, 86, 73, 71, 174, 160, 7, 83, 229, 169, 1, 6, 84, 82, - 69, 68, 69, 67, 2, 169, 202, 8, 2, 79, 86, 2, 129, 202, 8, 2, 73, 78, - 200, 40, 244, 1, 2, 32, 73, 22, 65, 162, 26, 67, 138, 5, 69, 166, 11, 72, - 242, 36, 73, 162, 233, 1, 75, 154, 2, 76, 142, 9, 77, 166, 21, 78, 190, - 2, 79, 158, 39, 80, 172, 12, 2, 81, 85, 138, 70, 83, 38, 84, 138, 17, 85, - 150, 43, 87, 186, 1, 89, 247, 178, 5, 71, 2, 183, 201, 9, 78, 198, 2, - 132, 2, 5, 70, 69, 84, 89, 32, 36, 4, 71, 73, 84, 84, 30, 76, 112, 8, 77, - 65, 82, 73, 84, 65, 78, 32, 146, 14, 78, 190, 3, 84, 102, 85, 204, 244, - 2, 2, 73, 76, 242, 91, 88, 144, 148, 6, 15, 75, 69, 32, 66, 79, 84, 84, - 76, 69, 32, 65, 78, 68, 32, 67, 159, 98, 82, 4, 254, 251, 6, 86, 207, - 242, 2, 80, 2, 201, 213, 3, 2, 65, 82, 6, 18, 84, 75, 85, 4, 36, 3, 32, - 83, 72, 235, 202, 9, 73, 2, 11, 65, 2, 171, 175, 10, 75, 2, 227, 228, 9, - 84, 122, 184, 1, 7, 76, 69, 84, 84, 69, 82, 32, 198, 3, 77, 248, 2, 12, - 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 136, 4, 11, 86, 79, 87, - 69, 76, 32, 83, 73, 71, 78, 32, 203, 159, 4, 65, 44, 202, 1, 66, 32, 2, - 68, 65, 22, 73, 38, 75, 22, 76, 34, 83, 46, 84, 182, 2, 65, 212, 231, 5, - 2, 71, 65, 222, 153, 1, 82, 202, 142, 2, 90, 182, 83, 77, 172, 1, 2, 81, - 85, 118, 78, 226, 6, 89, 251, 101, 70, 4, 186, 205, 10, 73, 247, 25, 65, - 2, 151, 224, 9, 76, 6, 178, 233, 10, 78, 2, 84, 3, 89, 2, 223, 231, 9, - 65, 2, 11, 65, 2, 191, 223, 9, 66, 4, 156, 7, 3, 73, 78, 71, 163, 149, 9, - 72, 6, 254, 230, 9, 65, 134, 101, 73, 229, 10, 5, 83, 65, 65, 68, 73, 18, - 96, 4, 65, 82, 75, 32, 165, 1, 15, 79, 68, 73, 70, 73, 69, 82, 32, 76, - 69, 84, 84, 69, 82, 32, 12, 82, 68, 40, 2, 73, 78, 90, 69, 242, 2, 78, - 213, 191, 8, 5, 79, 67, 67, 76, 85, 2, 17, 2, 65, 71, 2, 155, 251, 8, 69, - 5, 17, 2, 45, 65, 2, 203, 228, 9, 76, 6, 46, 69, 184, 6, 2, 83, 72, 131, - 223, 10, 73, 2, 229, 235, 9, 11, 80, 69, 78, 84, 72, 69, 84, 73, 67, 32, - 89, 28, 130, 1, 65, 154, 1, 66, 22, 78, 30, 83, 134, 1, 90, 250, 166, 3, - 84, 156, 149, 7, 9, 77, 69, 76, 79, 68, 73, 67, 32, 81, 3, 81, 10, 76, 3, - 70, 83, 65, 34, 78, 28, 2, 84, 77, 245, 189, 10, 4, 82, 75, 65, 65, 2, - 11, 65, 2, 151, 227, 10, 81, 4, 26, 78, 211, 206, 5, 71, 2, 11, 65, 2, - 243, 189, 10, 65, 2, 165, 143, 3, 2, 69, 81, 4, 64, 4, 72, 73, 89, 89, - 45, 8, 79, 70, 32, 77, 65, 83, 72, 70, 2, 11, 65, 2, 11, 65, 2, 155, 236, - 8, 76, 2, 139, 216, 9, 65, 4, 34, 65, 209, 235, 8, 2, 73, 81, 2, 223, - 223, 9, 69, 30, 92, 5, 76, 79, 78, 71, 32, 54, 79, 66, 83, 174, 205, 6, - 65, 242, 145, 4, 69, 2, 73, 3, 85, 10, 158, 206, 6, 65, 242, 145, 4, 69, - 2, 73, 3, 85, 7, 41, 8, 86, 69, 82, 76, 79, 78, 71, 32, 4, 191, 205, 6, - 65, 4, 26, 72, 183, 219, 5, 85, 2, 129, 150, 6, 3, 79, 82, 84, 10, 68, 8, - 83, 45, 83, 69, 82, 73, 70, 32, 241, 187, 10, 3, 68, 87, 73, 8, 44, 6, - 72, 69, 65, 86, 89, 32, 139, 2, 73, 6, 48, 3, 68, 79, 85, 81, 5, 76, 79, - 87, 32, 68, 4, 11, 66, 4, 21, 3, 76, 69, 32, 4, 84, 6, 84, 85, 82, 78, - 69, 68, 23, 67, 2, 21, 3, 79, 85, 66, 2, 17, 2, 76, 69, 2, 17, 2, 32, 67, - 2, 33, 6, 79, 77, 77, 65, 32, 81, 2, 145, 144, 9, 3, 85, 79, 84, 2, 253, - 151, 10, 10, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, 6, 48, 6, 69, 76, - 76, 73, 84, 69, 143, 200, 5, 85, 5, 25, 4, 32, 65, 78, 84, 2, 147, 160, - 7, 69, 168, 1, 50, 82, 225, 141, 5, 6, 68, 73, 32, 82, 73, 89, 166, 1, - 52, 7, 65, 83, 72, 84, 82, 65, 32, 183, 191, 4, 79, 164, 1, 180, 1, 7, - 76, 69, 84, 84, 69, 82, 32, 212, 1, 5, 83, 73, 71, 78, 32, 194, 21, 68, - 176, 250, 2, 16, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, - 32, 72, 211, 155, 2, 86, 100, 154, 250, 6, 65, 38, 68, 114, 84, 46, 86, - 186, 5, 85, 206, 141, 1, 79, 238, 60, 73, 42, 76, 226, 195, 1, 78, 46, - 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 162, 7, 69, 234, 61, 72, - 2, 77, 2, 82, 3, 89, 8, 218, 184, 6, 67, 234, 216, 3, 65, 239, 1, 86, 52, - 66, 65, 32, 4, 72, 79, 79, 76, 46, 79, 74, 82, 183, 212, 10, 73, 4, 194, - 191, 9, 76, 227, 20, 82, 5, 245, 191, 5, 6, 32, 83, 65, 84, 67, 72, 6, - 36, 3, 82, 80, 73, 203, 154, 9, 79, 4, 242, 132, 10, 79, 135, 18, 85, 36, - 66, 69, 72, 4, 73, 80, 84, 32, 214, 250, 1, 85, 175, 206, 6, 79, 4, 36, - 3, 87, 68, 82, 235, 131, 10, 69, 2, 11, 73, 2, 207, 149, 10, 86, 28, 80, - 8, 67, 65, 80, 73, 84, 65, 76, 32, 86, 76, 81, 6, 83, 77, 65, 76, 76, 32, - 18, 210, 210, 10, 66, 2, 69, 2, 70, 2, 72, 2, 73, 2, 76, 2, 77, 2, 80, 3, - 82, 2, 37, 7, 73, 71, 65, 84, 85, 82, 69, 2, 11, 32, 2, 233, 141, 10, 2, - 69, 84, 8, 174, 209, 10, 69, 2, 71, 2, 76, 3, 79, 220, 1, 130, 2, 65, 30, - 67, 74, 69, 36, 5, 71, 77, 69, 78, 84, 28, 2, 77, 73, 172, 1, 8, 80, 65, - 82, 65, 84, 69, 68, 32, 138, 4, 82, 158, 1, 83, 68, 2, 84, 32, 168, 140, - 5, 8, 87, 73, 78, 71, 32, 78, 69, 69, 202, 145, 3, 88, 190, 106, 68, 233, - 162, 1, 2, 76, 70, 4, 250, 206, 10, 76, 3, 84, 6, 34, 84, 245, 226, 5, 2, - 79, 78, 4, 178, 201, 6, 73, 175, 204, 3, 79, 4, 166, 224, 1, 68, 191, - 132, 1, 45, 23, 189, 191, 4, 2, 69, 68, 6, 212, 84, 28, 68, 73, 82, 69, - 67, 84, 32, 80, 82, 79, 68, 85, 67, 84, 32, 87, 73, 84, 72, 32, 66, 79, - 84, 84, 79, 77, 32, 67, 172, 208, 7, 3, 83, 69, 88, 211, 216, 1, 67, 158, - 1, 48, 6, 66, 76, 79, 67, 75, 32, 203, 182, 9, 83, 156, 1, 88, 9, 81, 85, - 65, 68, 82, 65, 78, 84, 45, 129, 1, 8, 83, 69, 88, 84, 65, 78, 84, 45, - 30, 42, 49, 38, 50, 30, 51, 171, 202, 10, 52, 17, 34, 50, 30, 51, 171, - 202, 10, 52, 9, 26, 51, 171, 202, 10, 52, 5, 167, 202, 10, 52, 126, 58, - 49, 54, 50, 46, 51, 38, 52, 30, 53, 187, 200, 10, 54, 65, 50, 50, 46, 51, - 38, 52, 30, 53, 187, 200, 10, 54, 33, 42, 51, 38, 52, 30, 53, 187, 200, - 10, 54, 17, 34, 52, 30, 53, 187, 200, 10, 54, 9, 26, 53, 187, 200, 10, - 54, 5, 183, 200, 10, 54, 4, 120, 2, 86, 73, 129, 175, 2, 22, 73, 79, 85, - 83, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 83, 89, 77, 66, 79, 76, - 83, 2, 11, 67, 2, 215, 133, 10, 69, 4, 52, 7, 81, 85, 73, 81, 85, 65, 68, - 239, 141, 9, 65, 2, 91, 82, 4, 64, 10, 84, 82, 65, 78, 83, 77, 73, 84, - 32, 83, 151, 187, 6, 77, 2, 11, 84, 2, 223, 252, 8, 65, 134, 3, 102, 65, - 218, 20, 73, 102, 79, 214, 13, 69, 70, 82, 224, 143, 9, 5, 85, 70, 70, - 76, 69, 195, 145, 1, 89, 192, 2, 164, 1, 12, 68, 79, 87, 69, 68, 32, 87, - 72, 73, 84, 69, 32, 56, 9, 76, 76, 79, 87, 32, 80, 65, 78, 32, 62, 82, - 182, 10, 86, 160, 198, 7, 2, 77, 82, 227, 233, 1, 75, 6, 174, 239, 8, 67, - 206, 11, 83, 245, 4, 3, 76, 65, 84, 2, 17, 2, 79, 70, 2, 17, 2, 32, 70, - 2, 187, 136, 7, 79, 210, 1, 40, 4, 65, 68, 65, 32, 167, 194, 10, 75, 208, - 1, 162, 1, 68, 46, 69, 110, 72, 34, 76, 246, 1, 83, 212, 2, 6, 86, 79, - 87, 69, 76, 32, 170, 199, 4, 65, 188, 211, 1, 7, 67, 79, 78, 84, 73, 78, - 85, 195, 143, 4, 79, 24, 194, 224, 6, 79, 66, 65, 255, 235, 1, 73, 4, 84, - 15, 88, 84, 82, 65, 32, 83, 72, 79, 82, 84, 32, 86, 79, 87, 69, 235, 130, - 9, 75, 2, 179, 254, 9, 76, 2, 217, 143, 10, 3, 69, 65, 68, 96, 33, 6, 69, - 84, 84, 69, 82, 32, 96, 170, 225, 6, 65, 38, 68, 114, 84, 46, 86, 186, 5, - 85, 186, 202, 1, 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, - 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 82, 2, 89, 186, 2, 69, 3, - 79, 30, 70, 65, 38, 69, 56, 4, 73, 71, 78, 32, 145, 183, 9, 3, 85, 84, - 82, 2, 193, 251, 9, 4, 78, 68, 72, 73, 6, 212, 205, 2, 5, 67, 84, 73, 79, - 78, 243, 189, 4, 80, 20, 106, 73, 154, 144, 5, 83, 202, 141, 1, 67, 98, - 78, 190, 66, 65, 190, 158, 1, 74, 150, 3, 85, 235, 245, 1, 86, 2, 37, 7, - 78, 86, 69, 82, 84, 69, 68, 2, 181, 157, 6, 2, 32, 67, 46, 60, 6, 77, 79, - 68, 73, 70, 73, 21, 5, 83, 73, 71, 78, 32, 2, 155, 146, 6, 69, 44, 110, - 67, 42, 79, 34, 80, 162, 183, 4, 85, 194, 229, 1, 83, 242, 68, 65, 58, - 86, 166, 202, 1, 73, 199, 140, 2, 69, 4, 193, 157, 6, 5, 65, 78, 68, 82, - 65, 7, 186, 162, 10, 79, 215, 22, 69, 2, 57, 12, 82, 73, 83, 72, 84, 72, - 65, 77, 65, 84, 82, 65, 2, 223, 161, 10, 32, 98, 72, 3, 69, 68, 32, 21, - 11, 73, 65, 78, 32, 76, 69, 84, 84, 69, 82, 32, 2, 215, 250, 9, 73, 96, - 158, 2, 65, 120, 3, 67, 72, 85, 22, 69, 70, 72, 46, 73, 46, 76, 22, 77, - 38, 79, 94, 80, 18, 82, 22, 83, 38, 84, 64, 2, 87, 79, 36, 2, 89, 69, - 212, 243, 4, 2, 74, 85, 166, 228, 2, 68, 202, 13, 90, 218, 88, 70, 182, - 6, 71, 234, 45, 66, 246, 11, 75, 234, 21, 86, 250, 27, 78, 167, 128, 1, - 85, 16, 82, 82, 242, 251, 9, 73, 234, 25, 68, 162, 8, 71, 2, 87, 198, 21, - 83, 147, 1, 72, 4, 170, 166, 9, 82, 163, 142, 1, 69, 2, 255, 145, 10, 82, - 8, 38, 65, 146, 251, 9, 82, 139, 56, 71, 4, 234, 179, 10, 82, 3, 84, 4, - 164, 182, 8, 2, 65, 45, 179, 172, 1, 85, 6, 194, 227, 9, 65, 142, 57, 67, - 215, 22, 70, 2, 207, 168, 8, 79, 4, 146, 158, 5, 69, 227, 250, 3, 73, 12, - 70, 79, 170, 166, 9, 73, 166, 111, 85, 150, 25, 65, 154, 3, 78, 3, 82, 2, - 163, 155, 10, 90, 2, 255, 15, 69, 2, 151, 142, 9, 79, 4, 130, 143, 9, 85, - 191, 162, 1, 79, 6, 26, 72, 215, 148, 10, 79, 4, 218, 131, 6, 73, 223, - 155, 4, 69, 4, 138, 165, 9, 79, 211, 139, 1, 69, 4, 182, 176, 10, 65, 3, - 87, 10, 78, 69, 186, 232, 3, 70, 148, 126, 6, 78, 84, 79, 32, 83, 72, - 131, 201, 5, 80, 2, 171, 233, 9, 76, 50, 252, 1, 2, 79, 84, 32, 6, 80, - 80, 73, 78, 71, 32, 72, 2, 82, 84, 128, 11, 7, 85, 76, 68, 69, 82, 69, - 68, 184, 240, 1, 24, 67, 75, 69, 68, 32, 70, 65, 67, 69, 32, 87, 73, 84, - 72, 32, 69, 88, 80, 76, 79, 68, 73, 78, 71, 234, 155, 3, 86, 199, 215, 4, - 87, 2, 197, 147, 8, 3, 73, 78, 71, 4, 36, 3, 84, 82, 79, 131, 242, 5, 66, - 2, 11, 76, 2, 139, 143, 8, 76, 36, 102, 32, 200, 8, 12, 72, 65, 78, 68, - 32, 70, 79, 82, 77, 65, 84, 32, 250, 182, 6, 67, 171, 236, 3, 83, 24, - 242, 1, 66, 92, 11, 83, 76, 65, 78, 84, 69, 68, 32, 78, 79, 82, 196, 1, - 4, 76, 69, 70, 84, 156, 1, 11, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, - 32, 248, 1, 7, 85, 80, 32, 84, 65, 67, 75, 129, 161, 2, 9, 68, 79, 87, - 78, 32, 84, 65, 67, 75, 4, 88, 14, 65, 67, 75, 83, 76, 65, 78, 84, 69, - 68, 32, 83, 79, 85, 33, 4, 69, 78, 84, 32, 2, 11, 84, 2, 179, 140, 9, 72, - 2, 221, 40, 37, 65, 82, 82, 79, 87, 32, 80, 79, 73, 78, 84, 73, 78, 71, - 32, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, 72, 69, 78, 32, 78, 79, - 82, 84, 72, 32, 69, 4, 116, 24, 87, 65, 82, 68, 83, 32, 72, 65, 82, 80, - 79, 79, 78, 32, 65, 66, 79, 86, 69, 32, 76, 79, 78, 71, 171, 3, 32, 2, - 237, 1, 5, 32, 82, 73, 71, 72, 4, 112, 11, 65, 82, 82, 79, 87, 32, 65, - 66, 79, 86, 69, 29, 13, 72, 65, 82, 80, 79, 79, 78, 32, 65, 66, 79, 86, - 69, 2, 157, 128, 6, 2, 32, 76, 2, 29, 5, 32, 76, 79, 78, 71, 2, 25, 4, - 32, 76, 69, 70, 2, 153, 250, 6, 6, 84, 87, 65, 82, 68, 83, 7, 11, 32, 4, - 76, 13, 65, 66, 79, 86, 69, 32, 83, 72, 79, 82, 84, 32, 68, 251, 131, 2, - 87, 2, 11, 79, 2, 11, 87, 2, 11, 78, 2, 11, 32, 2, 223, 132, 7, 84, 8, - 120, 10, 67, 79, 78, 84, 73, 78, 85, 73, 78, 71, 0, 6, 76, 69, 84, 84, - 69, 82, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 193, 179, 3, 5, 32, 79, - 86, 69, 82, 2, 21, 3, 32, 83, 84, 2, 215, 161, 10, 69, 2, 25, 4, 32, 79, - 80, 69, 2, 207, 146, 9, 78, 4, 26, 73, 179, 160, 10, 85, 2, 247, 160, 10, - 77, 211, 14, 174, 1, 68, 152, 20, 2, 71, 78, 184, 181, 1, 6, 77, 73, 76, - 65, 82, 32, 158, 2, 78, 202, 24, 88, 237, 238, 6, 15, 76, 72, 79, 85, 69, - 84, 84, 69, 32, 79, 70, 32, 74, 65, 80, 252, 1, 40, 5, 68, 72, 65, 77, - 32, 135, 17, 69, 184, 1, 202, 1, 69, 68, 7, 76, 69, 84, 84, 69, 82, 32, - 176, 4, 15, 82, 69, 80, 69, 84, 73, 84, 73, 79, 78, 32, 77, 65, 82, 75, - 50, 83, 164, 8, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 171, 175, - 6, 68, 2, 37, 7, 78, 68, 32, 79, 70, 32, 84, 2, 201, 210, 9, 2, 69, 88, - 102, 214, 1, 65, 98, 84, 242, 188, 6, 68, 158, 1, 86, 186, 5, 85, 186, - 202, 1, 73, 138, 196, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, - 2, 80, 138, 69, 72, 2, 76, 2, 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, 11, - 72, 8, 76, 84, 69, 82, 78, 65, 84, 69, 214, 154, 10, 65, 2, 73, 3, 85, 2, - 235, 245, 9, 32, 14, 134, 1, 72, 252, 231, 5, 19, 87, 79, 45, 67, 73, 82, - 67, 76, 69, 32, 65, 76, 84, 69, 82, 78, 65, 84, 69, 254, 233, 3, 84, 195, - 71, 65, 4, 164, 217, 9, 20, 82, 69, 69, 45, 67, 73, 82, 67, 76, 69, 32, - 65, 76, 84, 69, 82, 78, 65, 84, 69, 147, 64, 65, 6, 11, 45, 6, 186, 152, - 10, 49, 2, 50, 3, 51, 44, 38, 69, 181, 7, 4, 73, 71, 78, 32, 32, 96, 11, - 67, 84, 73, 79, 78, 32, 77, 65, 82, 75, 32, 177, 6, 8, 80, 65, 82, 65, - 84, 79, 82, 32, 28, 80, 11, 68, 79, 85, 66, 76, 69, 32, 82, 73, 78, 71, - 57, 5, 87, 73, 84, 72, 32, 5, 11, 32, 2, 249, 231, 8, 6, 87, 73, 84, 72, - 32, 82, 24, 212, 1, 12, 67, 73, 82, 67, 76, 69, 83, 32, 65, 78, 68, 32, - 116, 5, 81, 85, 65, 68, 82, 0, 4, 83, 69, 80, 84, 12, 16, 82, 65, 89, 83, - 32, 65, 78, 68, 32, 68, 79, 84, 84, 69, 68, 32, 46, 68, 45, 3, 84, 82, - 73, 6, 60, 4, 70, 79, 85, 82, 0, 3, 84, 87, 79, 187, 229, 8, 82, 2, 225, - 207, 6, 8, 32, 69, 78, 67, 76, 79, 83, 85, 2, 83, 85, 6, 42, 68, 28, 3, - 84, 82, 73, 215, 1, 67, 2, 197, 1, 3, 79, 85, 66, 2, 171, 1, 80, 6, 52, - 9, 68, 69, 78, 84, 32, 65, 78, 68, 32, 103, 80, 4, 116, 6, 68, 79, 84, - 84, 69, 68, 49, 14, 85, 45, 83, 72, 65, 80, 69, 68, 32, 79, 82, 78, 65, - 77, 2, 17, 2, 76, 69, 2, 17, 2, 32, 67, 2, 25, 4, 82, 69, 83, 67, 2, 239, - 186, 1, 69, 4, 158, 237, 8, 66, 135, 83, 68, 12, 146, 229, 4, 83, 202, - 141, 1, 67, 98, 78, 138, 216, 3, 65, 239, 1, 86, 26, 74, 65, 94, 86, 210, - 183, 6, 85, 186, 202, 1, 73, 198, 140, 2, 69, 3, 79, 10, 168, 184, 6, 10, - 76, 84, 69, 82, 78, 65, 84, 69, 32, 85, 254, 214, 3, 65, 2, 73, 3, 85, 4, - 11, 79, 4, 33, 6, 67, 65, 76, 73, 67, 32, 4, 255, 183, 6, 82, 68, 84, 12, - 84, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 78, 49, 5, 87, 65, 89, 83, - 32, 52, 178, 156, 1, 50, 222, 176, 3, 48, 131, 2, 49, 16, 56, 5, 66, 76, - 65, 67, 75, 1, 5, 87, 72, 73, 84, 69, 8, 11, 32, 8, 70, 82, 24, 3, 76, - 69, 70, 12, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 21, 3, 73, 71, 72, 2, 11, - 84, 2, 225, 92, 6, 32, 80, 79, 73, 78, 84, 194, 10, 96, 8, 87, 82, 73, - 84, 73, 78, 71, 32, 241, 238, 1, 10, 32, 79, 70, 32, 84, 72, 69, 32, 72, - 79, 192, 10, 136, 3, 4, 65, 73, 82, 32, 192, 1, 2, 66, 82, 102, 67, 138, - 1, 68, 218, 4, 69, 242, 6, 70, 244, 3, 4, 87, 65, 76, 76, 138, 1, 72, - 234, 77, 76, 212, 6, 2, 77, 79, 222, 42, 78, 218, 1, 82, 182, 7, 83, 162, - 5, 84, 180, 10, 5, 71, 82, 65, 83, 80, 184, 5, 30, 85, 80, 80, 69, 82, - 32, 66, 79, 68, 89, 32, 84, 73, 76, 84, 73, 78, 71, 32, 70, 82, 79, 77, - 32, 72, 73, 80, 32, 74, 79, 135, 207, 4, 80, 8, 48, 4, 66, 76, 79, 87, - 29, 4, 83, 85, 67, 75, 4, 58, 32, 211, 226, 4, 73, 4, 30, 32, 61, 3, 73, - 78, 71, 2, 237, 157, 1, 10, 83, 77, 65, 76, 76, 32, 82, 79, 84, 65, 2, - 171, 134, 9, 32, 10, 52, 5, 69, 65, 84, 72, 32, 229, 169, 1, 2, 85, 83, - 4, 140, 164, 2, 2, 69, 88, 1, 2, 73, 78, 10, 40, 6, 72, 69, 69, 75, 83, - 32, 63, 79, 6, 154, 107, 83, 146, 38, 78, 153, 223, 3, 4, 80, 85, 70, 70, - 4, 178, 180, 9, 76, 223, 46, 77, 28, 108, 15, 82, 69, 65, 77, 89, 32, 69, - 89, 69, 66, 82, 79, 87, 83, 32, 165, 1, 7, 89, 78, 65, 77, 73, 67, 32, 8, - 64, 4, 68, 79, 87, 78, 0, 2, 85, 80, 29, 4, 78, 69, 85, 84, 2, 153, 143, - 1, 2, 32, 78, 4, 21, 3, 82, 65, 76, 4, 11, 32, 4, 194, 58, 68, 191, 199, - 9, 85, 20, 180, 1, 11, 69, 86, 69, 82, 89, 32, 79, 84, 72, 69, 82, 30, - 70, 22, 83, 128, 122, 9, 65, 82, 82, 79, 87, 72, 69, 65, 68, 234, 38, 82, - 136, 206, 3, 2, 84, 69, 21, 4, 71, 82, 65, 68, 2, 181, 230, 8, 2, 32, 84, - 2, 163, 146, 6, 65, 6, 68, 11, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, - 83, 151, 227, 8, 76, 5, 203, 151, 1, 32, 54, 64, 2, 89, 69, 172, 227, 4, - 4, 88, 67, 73, 84, 203, 138, 4, 65, 50, 166, 1, 32, 56, 15, 66, 82, 79, - 87, 83, 32, 83, 84, 82, 65, 73, 71, 72, 84, 32, 44, 5, 71, 65, 90, 69, - 45, 140, 2, 7, 76, 65, 83, 72, 69, 83, 32, 65, 2, 83, 32, 6, 220, 150, 1, - 5, 66, 76, 73, 78, 75, 243, 129, 5, 87, 6, 186, 53, 68, 154, 84, 78, 167, - 243, 8, 85, 18, 100, 11, 70, 76, 79, 79, 82, 80, 76, 65, 78, 69, 32, 25, - 10, 87, 65, 76, 76, 80, 76, 65, 78, 69, 32, 8, 82, 83, 207, 45, 67, 10, - 18, 67, 43, 83, 4, 254, 45, 85, 213, 95, 3, 73, 82, 67, 6, 37, 7, 84, 82, - 65, 73, 71, 72, 84, 7, 11, 32, 4, 202, 163, 1, 65, 55, 68, 6, 130, 51, - 68, 180, 173, 4, 4, 70, 76, 85, 84, 139, 154, 5, 85, 14, 112, 5, 72, 65, - 76, 70, 32, 26, 67, 28, 4, 87, 73, 68, 69, 230, 92, 79, 233, 135, 4, 6, - 83, 81, 85, 69, 69, 90, 4, 22, 67, 131, 93, 79, 2, 213, 232, 2, 2, 76, - 79, 4, 162, 67, 32, 217, 61, 4, 78, 73, 78, 71, 38, 204, 1, 28, 65, 67, - 69, 32, 68, 73, 82, 69, 67, 84, 73, 79, 78, 32, 80, 79, 83, 73, 84, 73, - 79, 78, 32, 78, 79, 83, 69, 32, 138, 1, 73, 82, 76, 176, 1, 8, 79, 82, - 69, 72, 69, 65, 68, 32, 187, 158, 7, 85, 6, 88, 10, 85, 80, 32, 79, 82, - 32, 68, 79, 87, 78, 13, 8, 70, 79, 82, 87, 65, 82, 68, 32, 5, 11, 32, 2, - 153, 231, 4, 3, 84, 73, 76, 12, 180, 225, 3, 11, 76, 76, 32, 77, 79, 68, - 73, 70, 73, 69, 82, 131, 195, 2, 78, 12, 44, 4, 73, 67, 75, 32, 29, 3, - 79, 79, 82, 10, 254, 140, 1, 76, 35, 83, 2, 225, 247, 8, 20, 80, 76, 65, - 78, 69, 32, 83, 72, 79, 85, 76, 68, 69, 82, 32, 72, 73, 80, 32, 77, 6, - 166, 89, 87, 222, 38, 67, 47, 78, 156, 4, 34, 65, 133, 75, 3, 69, 65, 68, - 140, 4, 36, 3, 78, 68, 45, 143, 186, 9, 73, 138, 4, 92, 5, 65, 78, 71, - 76, 69, 138, 5, 67, 150, 10, 70, 186, 42, 72, 241, 12, 4, 79, 86, 65, 76, - 37, 11, 32, 34, 188, 1, 5, 73, 78, 68, 69, 88, 176, 1, 7, 76, 73, 84, 84, - 76, 69, 32, 136, 1, 5, 82, 73, 78, 71, 32, 173, 66, 18, 77, 73, 68, 68, - 76, 69, 32, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, 17, 11, 32, 14, - 128, 1, 7, 77, 73, 68, 68, 76, 69, 32, 228, 24, 11, 82, 73, 78, 71, 32, - 76, 73, 84, 84, 76, 69, 241, 42, 5, 84, 72, 85, 77, 66, 4, 174, 70, 76, - 247, 215, 8, 82, 8, 44, 5, 73, 78, 68, 69, 88, 207, 238, 9, 85, 7, 145, - 24, 18, 32, 84, 72, 85, 77, 66, 32, 73, 78, 68, 69, 88, 32, 84, 72, 85, - 77, 66, 4, 108, 22, 68, 79, 87, 78, 32, 77, 73, 68, 68, 76, 69, 32, 84, - 72, 85, 77, 66, 32, 73, 78, 68, 69, 155, 68, 76, 2, 207, 169, 8, 88, 88, - 64, 5, 73, 82, 67, 76, 69, 184, 3, 3, 76, 65, 87, 183, 2, 85, 35, 11, 32, - 32, 116, 5, 73, 78, 68, 69, 88, 200, 1, 7, 76, 73, 84, 84, 76, 69, 32, - 36, 7, 77, 73, 68, 68, 76, 69, 32, 163, 64, 82, 21, 11, 32, 18, 72, 6, - 77, 73, 68, 68, 76, 69, 198, 26, 72, 242, 38, 82, 131, 230, 8, 66, 13, - 11, 32, 10, 64, 5, 67, 82, 79, 83, 83, 198, 64, 84, 82, 76, 247, 215, 8, - 82, 4, 134, 65, 32, 231, 226, 8, 69, 4, 194, 193, 8, 73, 159, 168, 1, 85, - 6, 252, 47, 10, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 191, 185, 9, 85, - 17, 11, 32, 14, 144, 2, 28, 77, 73, 68, 68, 76, 69, 32, 82, 73, 78, 71, - 32, 76, 73, 84, 84, 76, 69, 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 176, - 49, 2, 70, 79, 198, 11, 78, 162, 1, 84, 197, 118, 23, 73, 78, 68, 69, 88, - 32, 84, 72, 85, 77, 66, 32, 67, 85, 82, 86, 69, 32, 84, 72, 85, 77, 66, - 5, 247, 180, 1, 32, 38, 46, 80, 149, 2, 6, 82, 76, 73, 67, 85, 69, 31, - 11, 32, 28, 188, 1, 5, 73, 78, 68, 69, 88, 56, 19, 70, 73, 86, 69, 32, - 70, 73, 78, 71, 69, 82, 83, 32, 83, 80, 82, 69, 65, 68, 196, 50, 7, 77, - 73, 68, 68, 76, 69, 32, 18, 79, 218, 7, 78, 163, 1, 84, 9, 11, 32, 6, 40, - 5, 84, 72, 85, 77, 66, 243, 58, 82, 5, 215, 46, 32, 9, 11, 32, 6, 72, 5, - 73, 78, 68, 69, 88, 0, 6, 77, 73, 68, 68, 76, 69, 179, 71, 79, 2, 193, - 147, 9, 13, 32, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, 32, 172, 2, - 44, 3, 73, 83, 84, 177, 33, 3, 76, 65, 84, 247, 1, 11, 32, 244, 1, 160, - 2, 5, 73, 78, 68, 69, 88, 192, 16, 7, 76, 73, 84, 84, 76, 69, 32, 196, 2, - 7, 77, 73, 68, 68, 76, 69, 32, 200, 4, 5, 82, 73, 78, 71, 32, 132, 2, 5, - 84, 72, 85, 77, 66, 138, 2, 72, 205, 9, 22, 70, 79, 85, 82, 32, 70, 73, - 78, 71, 69, 82, 83, 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 137, 1, 11, - 32, 134, 1, 232, 1, 4, 66, 69, 78, 84, 36, 6, 72, 73, 78, 71, 69, 68, 76, - 6, 77, 73, 68, 68, 76, 69, 168, 7, 2, 67, 85, 64, 6, 84, 72, 85, 77, 66, - 32, 160, 5, 16, 85, 80, 32, 77, 73, 68, 68, 76, 69, 32, 72, 73, 78, 71, - 69, 68, 151, 4, 82, 5, 217, 45, 5, 32, 79, 86, 69, 82, 9, 11, 32, 6, 252, - 20, 8, 77, 73, 68, 68, 76, 69, 32, 85, 167, 172, 8, 76, 71, 11, 32, 68, - 236, 1, 4, 66, 69, 78, 84, 42, 67, 244, 1, 10, 85, 80, 32, 83, 80, 82, - 69, 65, 68, 32, 100, 6, 72, 73, 78, 71, 69, 68, 46, 82, 80, 5, 84, 72, - 85, 77, 66, 188, 28, 14, 83, 84, 82, 65, 73, 71, 72, 84, 32, 84, 72, 85, - 77, 66, 227, 17, 76, 5, 213, 92, 6, 32, 84, 72, 85, 77, 66, 28, 68, 8, - 79, 78, 74, 79, 73, 78, 69, 68, 233, 1, 4, 82, 79, 83, 83, 23, 11, 32, - 20, 144, 1, 6, 67, 85, 80, 80, 69, 68, 28, 6, 84, 72, 85, 77, 66, 32, 68, - 5, 72, 73, 78, 71, 69, 166, 22, 73, 165, 7, 6, 77, 73, 68, 68, 76, 69, 5, - 11, 32, 2, 203, 27, 84, 8, 160, 1, 4, 83, 73, 68, 69, 219, 61, 70, 6, 22, - 69, 159, 47, 32, 4, 223, 15, 68, 5, 241, 30, 7, 32, 83, 80, 82, 69, 65, - 68, 8, 32, 3, 73, 78, 71, 247, 19, 65, 7, 11, 32, 4, 138, 36, 67, 131, - 240, 8, 66, 19, 11, 32, 16, 64, 6, 65, 78, 71, 76, 69, 68, 22, 67, 106, - 72, 163, 146, 9, 66, 5, 167, 221, 5, 32, 6, 74, 85, 230, 7, 73, 241, 25, - 10, 79, 78, 74, 79, 73, 78, 69, 68, 32, 72, 2, 201, 193, 4, 2, 80, 80, 4, + 225, 132, 2, 3, 73, 67, 89, 2, 17, 2, 32, 72, 2, 251, 207, 13, 69, 5, + 175, 235, 13, 32, 4, 60, 6, 69, 68, 69, 83, 84, 82, 245, 207, 9, 3, 73, + 82, 65, 2, 161, 170, 11, 2, 73, 65, 4, 36, 5, 78, 65, 76, 32, 68, 59, 83, + 2, 133, 219, 13, 9, 73, 71, 73, 84, 32, 83, 72, 65, 80, 2, 191, 155, 11, + 77, 6, 38, 45, 145, 224, 9, 3, 70, 79, 82, 4, 76, 8, 66, 82, 69, 65, 75, + 73, 78, 71, 233, 164, 2, 5, 80, 79, 84, 65, 66, 2, 213, 222, 6, 2, 32, + 72, 97, 56, 2, 84, 72, 142, 11, 77, 237, 239, 10, 3, 68, 73, 67, 88, 42, + 32, 149, 206, 6, 4, 69, 65, 83, 84, 86, 96, 5, 69, 65, 83, 84, 32, 148, + 2, 6, 73, 78, 68, 73, 67, 32, 217, 1, 5, 87, 69, 83, 84, 32, 32, 82, 65, + 202, 243, 6, 80, 130, 1, 84, 190, 207, 4, 66, 38, 68, 18, 83, 251, 58, + 87, 14, 40, 4, 82, 82, 79, 87, 179, 239, 6, 78, 13, 11, 32, 10, 96, 9, + 67, 82, 79, 83, 83, 73, 78, 71, 32, 244, 2, 2, 65, 78, 130, 239, 6, 87, + 131, 145, 5, 70, 4, 242, 193, 3, 83, 187, 175, 3, 78, 20, 50, 80, 60, 3, + 81, 85, 65, 66, 82, 255, 127, 70, 2, 37, 7, 76, 65, 67, 69, 72, 79, 76, + 2, 179, 176, 4, 68, 4, 156, 176, 4, 2, 82, 84, 249, 248, 9, 5, 78, 84, + 73, 84, 89, 2, 17, 2, 85, 80, 2, 235, 162, 4, 69, 34, 82, 65, 222, 239, + 6, 80, 130, 1, 84, 190, 207, 4, 66, 38, 68, 18, 83, 251, 58, 87, 16, 34, + 78, 33, 4, 82, 82, 79, 87, 2, 253, 190, 3, 3, 68, 32, 83, 15, 11, 32, 12, + 84, 3, 84, 79, 32, 238, 234, 6, 67, 40, 3, 65, 78, 68, 234, 2, 87, 131, + 145, 5, 70, 4, 246, 235, 6, 67, 173, 216, 6, 4, 76, 79, 78, 71, 56, 54, + 32, 236, 5, 5, 67, 72, 69, 68, 32, 207, 2, 69, 38, 162, 1, 65, 132, 2, 4, + 78, 79, 82, 77, 78, 80, 46, 83, 170, 1, 84, 210, 222, 7, 69, 196, 33, 7, + 73, 68, 69, 78, 84, 73, 67, 190, 203, 4, 71, 38, 76, 135, 80, 67, 10, 88, + 3, 32, 83, 85, 52, 7, 78, 32, 69, 76, 69, 77, 69, 28, 2, 83, 89, 227, + 129, 8, 76, 4, 30, 66, 1, 3, 80, 69, 82, 2, 29, 2, 83, 69, 2, 11, 78, 2, + 139, 121, 84, 2, 37, 7, 77, 80, 84, 79, 84, 73, 67, 2, 17, 2, 65, 76, 2, + 161, 130, 8, 2, 76, 89, 4, 205, 196, 6, 14, 65, 76, 32, 83, 85, 66, 71, + 82, 79, 85, 80, 32, 79, 70, 2, 241, 129, 8, 6, 65, 82, 65, 76, 76, 69, 6, + 48, 6, 81, 85, 65, 82, 69, 32, 223, 219, 13, 73, 4, 68, 5, 73, 77, 65, + 71, 69, 1, 8, 79, 82, 73, 71, 73, 78, 65, 76, 2, 21, 3, 32, 79, 70, 2, + 207, 194, 6, 32, 4, 230, 209, 10, 82, 207, 242, 1, 73, 8, 58, 76, 40, 4, + 82, 73, 71, 72, 133, 1, 3, 85, 80, 80, 4, 36, 2, 69, 70, 133, 1, 2, 79, + 87, 2, 89, 20, 84, 32, 83, 69, 77, 73, 67, 73, 82, 67, 76, 69, 32, 87, + 73, 84, 72, 32, 84, 72, 2, 17, 2, 82, 69, 2, 243, 140, 13, 69, 2, 11, 69, + 2, 41, 8, 82, 32, 82, 73, 71, 72, 84, 45, 2, 133, 144, 3, 6, 83, 72, 65, + 68, 79, 87, 11, 34, 32, 53, 4, 66, 79, 79, 75, 4, 17, 2, 80, 65, 4, 198, + 199, 14, 71, 215, 22, 68, 5, 81, 18, 32, 87, 73, 84, 72, 32, 68, 69, 67, + 79, 82, 65, 84, 73, 86, 69, 32, 67, 2, 235, 137, 4, 79, 34, 102, 77, 196, + 182, 5, 8, 84, 32, 65, 78, 68, 32, 66, 79, 184, 255, 6, 3, 83, 72, 85, + 135, 170, 1, 76, 26, 36, 4, 66, 69, 82, 32, 247, 2, 69, 24, 58, 69, 50, + 70, 42, 83, 66, 84, 57, 4, 78, 73, 78, 69, 4, 204, 1, 3, 73, 71, 72, 21, + 3, 76, 69, 86, 4, 144, 1, 2, 79, 85, 13, 2, 73, 70, 6, 34, 73, 85, 4, 69, + 86, 69, 78, 4, 82, 88, 155, 138, 14, 71, 8, 40, 2, 72, 73, 46, 69, 21, 2, + 87, 69, 2, 11, 82, 2, 17, 2, 84, 69, 2, 11, 69, 2, 135, 200, 7, 78, 4, + 240, 199, 7, 3, 76, 86, 69, 1, 3, 78, 84, 89, 2, 187, 243, 6, 82, 142, 1, + 118, 76, 226, 3, 83, 164, 2, 5, 84, 79, 78, 69, 45, 196, 230, 7, 8, 67, + 73, 82, 67, 76, 69, 68, 32, 179, 247, 4, 68, 92, 88, 6, 69, 84, 84, 69, + 82, 32, 173, 163, 1, 10, 79, 71, 79, 71, 82, 65, 77, 32, 78, 89, 90, 130, + 2, 78, 90, 84, 166, 220, 7, 88, 182, 230, 2, 65, 144, 1, 2, 72, 65, 226, + 51, 82, 210, 147, 1, 79, 150, 61, 68, 2, 77, 2, 80, 254, 203, 1, 69, 234, + 61, 67, 2, 70, 2, 71, 2, 75, 2, 76, 2, 81, 2, 83, 2, 86, 2, 89, 2, 90, + 186, 2, 73, 2, 85, 3, 87, 22, 86, 84, 174, 200, 12, 80, 230, 137, 2, 67, + 2, 75, 2, 81, 2, 82, 2, 89, 187, 2, 65, 6, 142, 210, 14, 83, 2, 88, 187, + 2, 65, 14, 64, 4, 73, 71, 78, 32, 189, 1, 7, 89, 76, 76, 65, 66, 76, 69, + 12, 56, 4, 70, 79, 82, 32, 129, 213, 13, 4, 88, 87, 32, 88, 10, 204, 9, + 2, 76, 79, 230, 164, 3, 84, 156, 94, 8, 73, 78, 86, 69, 82, 84, 69, 66, + 232, 144, 4, 3, 65, 78, 73, 195, 177, 2, 80, 2, 177, 132, 12, 4, 32, 76, + 69, 78, 14, 250, 209, 14, 66, 2, 68, 2, 71, 2, 74, 2, 77, 2, 83, 3, 86, + 254, 14, 226, 2, 66, 226, 1, 67, 226, 5, 71, 244, 6, 4, 73, 76, 32, 68, + 22, 76, 198, 69, 78, 150, 5, 80, 234, 7, 82, 242, 10, 83, 188, 8, 2, 84, + 84, 154, 8, 85, 248, 1, 3, 86, 69, 82, 254, 170, 2, 89, 148, 151, 4, 14, + 70, 70, 73, 67, 69, 32, 66, 85, 73, 76, 68, 73, 78, 71, 154, 185, 1, 72, + 146, 132, 2, 75, 210, 250, 1, 68, 194, 64, 77, 246, 9, 87, 211, 139, 1, + 88, 10, 132, 1, 6, 76, 73, 81, 85, 69, 32, 252, 158, 2, 9, 83, 69, 82, + 86, 69, 82, 32, 69, 89, 189, 29, 8, 74, 69, 67, 84, 32, 82, 69, 80, 6, + 172, 203, 4, 13, 65, 78, 71, 76, 69, 32, 79, 80, 69, 78, 73, 78, 71, 171, + 241, 1, 72, 28, 56, 2, 82, 32, 234, 4, 84, 225, 198, 5, 3, 67, 85, 76, + 22, 156, 1, 11, 65, 77, 79, 85, 78, 84, 32, 79, 70, 32, 67, 22, 66, 198, + 1, 67, 118, 68, 106, 70, 0, 10, 73, 78, 86, 69, 82, 84, 69, 68, 32, 70, + 243, 241, 12, 72, 2, 203, 184, 5, 72, 6, 136, 1, 15, 82, 65, 78, 67, 72, + 32, 66, 65, 78, 75, 32, 73, 68, 69, 78, 156, 131, 5, 5, 69, 76, 84, 32, + 66, 205, 144, 6, 3, 79, 87, 32, 2, 21, 3, 84, 73, 70, 2, 11, 73, 2, 131, + 132, 11, 67, 4, 92, 17, 85, 83, 84, 79, 77, 69, 82, 32, 65, 67, 67, 79, + 85, 78, 84, 32, 78, 243, 201, 1, 72, 2, 159, 161, 6, 85, 4, 44, 5, 79, + 85, 66, 76, 69, 147, 221, 12, 65, 2, 11, 32, 2, 11, 66, 2, 157, 163, 7, + 3, 65, 67, 75, 2, 191, 134, 14, 79, 4, 160, 251, 8, 4, 65, 71, 79, 78, + 197, 195, 3, 2, 79, 80, 60, 48, 4, 72, 65, 77, 32, 185, 195, 14, 2, 79, + 78, 58, 122, 70, 0, 10, 82, 69, 86, 69, 82, 83, 69, 68, 32, 70, 36, 7, + 76, 69, 84, 84, 69, 82, 32, 149, 254, 3, 3, 83, 80, 65, 2, 161, 139, 4, + 4, 69, 65, 84, 72, 52, 196, 1, 2, 65, 73, 22, 66, 2, 80, 34, 67, 36, 2, + 69, 65, 64, 2, 70, 69, 22, 71, 22, 73, 58, 76, 2, 82, 22, 78, 46, 79, 34, + 83, 46, 85, 222, 184, 1, 77, 170, 9, 68, 189, 227, 11, 3, 84, 73, 78, 2, + 155, 179, 14, 76, 2, 11, 69, 2, 219, 190, 12, 73, 4, 226, 151, 8, 69, + 183, 161, 4, 79, 6, 138, 1, 66, 2, 68, 153, 143, 4, 6, 77, 72, 65, 78, + 67, 72, 2, 247, 175, 9, 65, 2, 183, 187, 13, 79, 4, 32, 2, 79, 68, 191, + 194, 13, 70, 2, 195, 137, 8, 72, 2, 243, 154, 12, 85, 4, 132, 172, 13, 3, + 71, 69, 65, 247, 69, 73, 4, 218, 241, 13, 78, 227, 79, 82, 4, 202, 225, + 12, 65, 229, 93, 3, 84, 82, 65, 6, 60, 5, 73, 76, 76, 69, 65, 186, 187, + 12, 65, 251, 132, 2, 82, 2, 207, 240, 13, 78, 2, 247, 148, 13, 82, 182, + 8, 38, 32, 142, 11, 68, 255, 183, 13, 73, 184, 1, 64, 6, 67, 72, 73, 75, + 73, 32, 205, 6, 5, 79, 78, 65, 76, 32, 96, 132, 1, 7, 76, 69, 84, 84, 69, + 82, 32, 148, 3, 2, 77, 85, 62, 71, 74, 80, 164, 216, 3, 2, 82, 69, 202, + 237, 8, 68, 211, 173, 1, 65, 60, 50, 65, 98, 69, 54, 73, 50, 76, 62, 79, + 51, 85, 16, 50, 65, 210, 188, 14, 78, 86, 71, 2, 76, 3, 84, 8, 162, 189, + 14, 74, 2, 75, 2, 77, 3, 87, 8, 214, 246, 13, 68, 198, 13, 82, 222, 56, + 78, 3, 80, 8, 250, 170, 14, 78, 202, 17, 72, 2, 82, 3, 83, 12, 162, 170, + 10, 65, 242, 145, 4, 69, 2, 73, 2, 79, 3, 85, 8, 170, 159, 14, 84, 174, + 28, 66, 2, 72, 3, 86, 8, 198, 235, 13, 78, 226, 79, 67, 2, 68, 3, 89, 4, + 56, 2, 45, 71, 209, 206, 12, 6, 32, 84, 84, 85, 68, 68, 2, 205, 206, 12, + 13, 65, 65, 72, 76, 65, 65, 32, 84, 84, 85, 68, 68, 65, 6, 84, 11, 85, + 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 177, 224, 6, 4, 72, 65, 65, 82, + 4, 48, 8, 68, 79, 85, 66, 76, 69, 32, 77, 3, 77, 2, 185, 242, 13, 3, 85, + 67, 65, 88, 100, 7, 76, 69, 84, 84, 69, 82, 32, 192, 2, 5, 83, 73, 71, + 78, 32, 206, 193, 8, 65, 207, 255, 3, 68, 60, 42, 65, 54, 69, 58, 73, 54, + 79, 59, 85, 13, 178, 183, 14, 66, 2, 68, 2, 72, 2, 76, 3, 87, 13, 158, + 231, 13, 78, 226, 79, 67, 2, 71, 2, 72, 3, 83, 13, 238, 205, 8, 84, 218, + 232, 5, 68, 2, 78, 3, 80, 13, 182, 253, 13, 82, 138, 56, 78, 86, 77, 2, + 79, 3, 89, 13, 186, 239, 13, 68, 218, 52, 78, 202, 17, 74, 2, 75, 3, 82, + 6, 58, 73, 144, 246, 12, 4, 72, 79, 68, 68, 239, 153, 1, 77, 2, 131, 182, + 1, 75, 252, 6, 34, 32, 165, 57, 3, 69, 82, 32, 246, 6, 240, 2, 8, 67, 72, + 73, 78, 69, 83, 69, 32, 44, 10, 72, 85, 78, 71, 65, 82, 73, 65, 78, 32, + 128, 7, 7, 73, 84, 65, 76, 73, 67, 32, 212, 4, 14, 78, 79, 82, 84, 72, + 32, 65, 82, 65, 66, 73, 65, 78, 32, 196, 4, 3, 80, 69, 82, 216, 13, 2, + 83, 79, 144, 13, 14, 84, 85, 82, 75, 73, 67, 32, 76, 69, 84, 84, 69, 82, + 32, 132, 7, 7, 85, 89, 71, 72, 85, 82, 32, 171, 225, 11, 75, 4, 146, 139, + 12, 73, 241, 96, 3, 72, 79, 79, 216, 1, 96, 6, 67, 65, 80, 73, 84, 65, 0, + 4, 83, 77, 65, 76, 233, 5, 7, 78, 85, 77, 66, 69, 82, 32, 102, 45, 9, 76, + 32, 76, 69, 84, 84, 69, 82, 32, 102, 214, 1, 65, 54, 69, 168, 2, 10, 78, + 73, 75, 79, 76, 83, 66, 85, 82, 71, 0, 9, 82, 85, 68, 73, 77, 69, 78, 84, + 65, 42, 79, 32, 5, 83, 72, 79, 82, 84, 22, 85, 168, 242, 3, 5, 67, 76, + 79, 83, 69, 243, 171, 8, 73, 11, 154, 240, 12, 77, 218, 119, 78, 162, 70, + 65, 3, 75, 63, 178, 1, 77, 22, 78, 78, 83, 182, 130, 10, 67, 254, 23, 71, + 2, 76, 2, 84, 198, 135, 2, 90, 218, 137, 2, 66, 2, 68, 2, 69, 2, 70, 2, + 72, 2, 74, 2, 75, 2, 80, 2, 82, 3, 86, 5, 171, 172, 14, 80, 11, 34, 84, + 246, 171, 14, 67, 3, 89, 5, 197, 149, 2, 5, 45, 83, 72, 65, 80, 5, 203, + 171, 14, 90, 4, 11, 32, 4, 214, 148, 14, 79, 3, 85, 7, 186, 148, 14, 69, + 215, 22, 79, 2, 131, 237, 13, 32, 9, 194, 167, 14, 78, 154, 3, 83, 3, 85, + 12, 210, 4, 70, 242, 131, 6, 79, 239, 203, 6, 84, 78, 80, 7, 76, 69, 84, + 84, 69, 82, 32, 169, 3, 8, 78, 85, 77, 69, 82, 65, 76, 32, 70, 190, 1, + 69, 90, 75, 50, 83, 36, 3, 78, 79, 82, 202, 207, 10, 85, 186, 202, 1, 73, + 166, 140, 1, 80, 2, 84, 150, 83, 67, 186, 22, 66, 2, 68, 2, 72, 2, 86, 2, + 89, 2, 90, 214, 22, 65, 3, 79, 23, 214, 254, 9, 83, 194, 159, 2, 82, 254, + 203, 1, 75, 222, 61, 70, 2, 76, 2, 77, 3, 78, 8, 194, 144, 14, 72, 214, + 22, 65, 2, 69, 3, 85, 4, 32, 2, 79, 85, 243, 143, 14, 72, 2, 29, 5, 84, + 72, 69, 82, 78, 2, 253, 154, 13, 2, 32, 84, 8, 38, 70, 222, 207, 12, 84, + 215, 58, 79, 4, 11, 73, 4, 242, 181, 12, 70, 143, 217, 1, 86, 64, 76, 7, + 76, 69, 84, 84, 69, 82, 32, 209, 3, 7, 78, 85, 77, 66, 69, 82, 32, 58, + 210, 1, 65, 38, 71, 38, 72, 30, 75, 38, 84, 74, 90, 234, 106, 77, 140, + 158, 3, 2, 69, 83, 238, 162, 3, 66, 2, 70, 2, 82, 2, 89, 182, 203, 3, 78, + 154, 237, 1, 76, 210, 58, 68, 146, 1, 81, 134, 3, 87, 131, 56, 83, 4, + 134, 194, 3, 76, 167, 145, 10, 73, 4, 254, 243, 12, 72, 191, 156, 1, 69, + 4, 178, 161, 14, 65, 3, 69, 4, 166, 180, 7, 72, 223, 236, 5, 65, 8, 34, + 72, 210, 160, 14, 65, 3, 69, 4, 142, 150, 13, 65, 195, 138, 1, 69, 4, 11, + 65, 4, 206, 209, 13, 73, 227, 79, 72, 6, 190, 153, 6, 84, 163, 236, 6, + 79, 180, 1, 64, 11, 77, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 183, 5, + 83, 76, 228, 1, 2, 67, 72, 22, 68, 66, 69, 22, 73, 30, 77, 2, 78, 30, 80, + 22, 83, 70, 84, 50, 86, 38, 89, 94, 90, 254, 195, 6, 76, 2, 82, 214, 227, + 2, 71, 150, 170, 2, 79, 222, 208, 1, 66, 246, 40, 65, 254, 31, 75, 174, + 45, 72, 187, 2, 85, 2, 215, 216, 7, 69, 6, 26, 90, 183, 138, 14, 79, 4, + 134, 167, 9, 72, 187, 210, 4, 73, 5, 231, 157, 14, 70, 7, 210, 157, 14, + 65, 3, 69, 2, 213, 134, 14, 2, 69, 78, 2, 131, 198, 6, 69, 6, 26, 72, + 151, 137, 14, 73, 4, 228, 165, 9, 3, 67, 72, 79, 3, 79, 4, 26, 83, 211, + 136, 14, 65, 2, 191, 247, 13, 73, 4, 142, 165, 9, 79, 171, 190, 4, 69, + 14, 60, 2, 69, 82, 218, 178, 8, 65, 146, 215, 5, 82, 203, 17, 85, 7, 174, + 155, 14, 73, 3, 85, 4, 142, 164, 9, 72, 187, 210, 4, 65, 104, 88, 4, 73, + 65, 78, 32, 241, 5, 13, 79, 78, 65, 76, 32, 67, 79, 77, 80, 85, 84, 69, + 82, 100, 80, 7, 78, 85, 77, 66, 69, 82, 32, 80, 5, 83, 73, 71, 78, 32, + 251, 222, 10, 87, 10, 42, 84, 234, 188, 8, 72, 255, 192, 4, 79, 6, 238, + 230, 1, 87, 199, 226, 11, 69, 88, 210, 1, 65, 86, 66, 62, 68, 98, 74, 2, + 86, 30, 84, 42, 88, 182, 111, 71, 2, 75, 2, 78, 2, 82, 150, 206, 9, 77, + 146, 143, 3, 83, 218, 69, 67, 2, 70, 2, 72, 2, 76, 2, 80, 2, 89, 2, 90, + 186, 2, 73, 3, 85, 9, 45, 9, 85, 82, 65, 77, 65, 90, 68, 65, 65, 7, 170, + 239, 6, 45, 139, 165, 7, 72, 6, 38, 65, 213, 177, 10, 3, 85, 85, 77, 5, + 231, 147, 14, 71, 10, 34, 65, 234, 149, 14, 73, 3, 85, 7, 37, 7, 72, 89, + 65, 65, 85, 83, 72, 5, 255, 237, 6, 45, 4, 170, 149, 14, 65, 3, 73, 6, + 214, 146, 14, 72, 186, 2, 65, 3, 85, 4, 152, 220, 11, 8, 83, 72, 65, 65, + 89, 65, 84, 72, 207, 184, 2, 65, 5, 181, 147, 5, 31, 32, 87, 73, 84, 72, + 32, 77, 79, 78, 73, 84, 79, 82, 32, 73, 78, 32, 80, 79, 82, 84, 82, 65, + 73, 84, 32, 79, 82, 73, 69, 78, 144, 1, 92, 6, 71, 68, 73, 65, 78, 32, + 141, 7, 12, 85, 84, 72, 32, 65, 82, 65, 66, 73, 65, 78, 32, 80, 58, 70, + 74, 76, 145, 5, 7, 78, 85, 77, 66, 69, 82, 32, 2, 11, 82, 2, 201, 237, + 11, 10, 65, 67, 84, 73, 79, 78, 32, 79, 78, 69, 60, 76, 6, 69, 84, 84, + 69, 82, 32, 149, 4, 8, 73, 71, 65, 84, 85, 82, 69, 32, 58, 234, 1, 65, + 96, 6, 70, 73, 78, 65, 76, 32, 200, 1, 5, 82, 69, 83, 72, 45, 162, 216, + 1, 76, 194, 170, 4, 71, 90, 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, + 75, 174, 81, 66, 170, 225, 4, 78, 134, 2, 84, 2, 87, 218, 103, 80, 171, + 4, 77, 6, 26, 76, 131, 143, 13, 89, 4, 192, 133, 6, 8, 84, 69, 82, 78, + 65, 84, 69, 32, 155, 214, 1, 69, 18, 116, 3, 78, 85, 78, 0, 5, 83, 65, + 68, 72, 69, 0, 3, 84, 65, 87, 190, 216, 1, 65, 134, 211, 6, 66, 135, 203, + 5, 72, 5, 41, 8, 32, 87, 73, 84, 72, 32, 86, 69, 2, 133, 220, 5, 4, 82, + 84, 73, 67, 2, 253, 215, 1, 6, 65, 89, 73, 78, 45, 68, 18, 42, 84, 234, + 131, 6, 79, 255, 148, 6, 70, 10, 42, 72, 162, 217, 1, 87, 199, 226, 11, + 69, 4, 162, 153, 12, 82, 159, 2, 73, 64, 60, 7, 76, 69, 84, 84, 69, 82, + 32, 245, 3, 3, 78, 85, 77, 58, 202, 1, 65, 38, 68, 74, 71, 34, 75, 34, + 83, 78, 84, 254, 43, 90, 254, 166, 1, 76, 50, 81, 214, 205, 1, 82, 246, + 221, 2, 89, 198, 207, 1, 72, 150, 87, 66, 170, 225, 4, 78, 134, 2, 87, + 218, 103, 70, 171, 4, 77, 4, 146, 168, 3, 76, 167, 145, 10, 89, 6, 32, 2, + 72, 65, 151, 212, 1, 65, 4, 246, 166, 8, 76, 207, 180, 5, 68, 4, 134, 45, + 72, 203, 209, 5, 73, 4, 146, 213, 7, 65, 163, 81, 72, 8, 26, 65, 255, + 135, 13, 72, 6, 218, 198, 7, 77, 234, 147, 6, 68, 143, 45, 84, 8, 230, + 90, 72, 194, 167, 11, 69, 219, 134, 1, 65, 6, 56, 4, 66, 69, 82, 32, 145, + 205, 13, 4, 69, 82, 73, 67, 4, 26, 70, 235, 234, 12, 79, 2, 139, 149, 12, + 73, 146, 1, 80, 7, 79, 82, 75, 72, 79, 78, 32, 197, 3, 8, 89, 69, 78, 73, + 83, 69, 73, 32, 84, 54, 65, 202, 1, 69, 122, 73, 30, 79, 135, 151, 12, + 66, 45, 106, 69, 170, 243, 9, 83, 226, 144, 4, 66, 2, 68, 2, 71, 2, 76, + 2, 78, 2, 81, 2, 82, 2, 84, 3, 89, 20, 134, 132, 14, 66, 2, 68, 2, 71, 2, + 75, 2, 76, 2, 78, 2, 82, 2, 83, 2, 84, 3, 89, 20, 74, 78, 182, 230, 13, + 76, 158, 27, 83, 146, 1, 67, 2, 77, 2, 80, 3, 90, 8, 222, 130, 14, 67, 2, + 71, 2, 84, 3, 89, 7, 178, 130, 14, 67, 3, 81, 13, 130, 3, 69, 150, 255, + 13, 80, 2, 81, 3, 84, 62, 38, 65, 170, 1, 69, 86, 73, 23, 79, 39, 98, 69, + 206, 255, 13, 83, 62, 78, 86, 66, 2, 68, 2, 71, 2, 76, 2, 81, 2, 82, 2, + 84, 3, 89, 17, 218, 130, 12, 78, 130, 254, 1, 66, 2, 71, 2, 75, 2, 84, 3, + 89, 15, 46, 78, 218, 254, 13, 83, 146, 1, 67, 3, 90, 6, 230, 255, 13, 67, + 2, 84, 3, 89, 5, 195, 255, 13, 81, 6, 26, 69, 151, 255, 13, 81, 5, 147, + 255, 13, 75, 52, 148, 1, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 36, + 7, 76, 69, 84, 84, 69, 82, 32, 233, 1, 12, 80, 85, 78, 67, 84, 85, 65, + 84, 73, 79, 78, 32, 8, 222, 241, 5, 84, 243, 231, 3, 68, 36, 230, 200, 1, + 65, 186, 206, 1, 82, 222, 220, 2, 76, 58, 90, 34, 83, 66, 89, 168, 210, + 1, 6, 70, 73, 78, 65, 76, 32, 0, 6, 71, 73, 77, 69, 76, 45, 134, 3, 75, + 174, 81, 66, 170, 225, 4, 78, 134, 2, 84, 2, 87, 218, 103, 80, 171, 4, + 77, 8, 56, 4, 84, 87, 79, 32, 174, 212, 11, 70, 187, 131, 1, 66, 4, 158, + 228, 12, 66, 75, 68, 6, 146, 181, 1, 87, 136, 160, 3, 3, 65, 68, 85, 207, + 217, 7, 77, 22, 212, 1, 34, 32, 87, 73, 84, 72, 32, 69, 88, 67, 76, 65, + 77, 65, 84, 73, 79, 78, 32, 77, 65, 82, 75, 32, 87, 73, 84, 72, 32, 76, + 69, 70, 84, 32, 82, 44, 7, 67, 79, 77, 73, 78, 71, 32, 194, 1, 69, 151, + 167, 13, 73, 2, 21, 3, 73, 71, 72, 2, 203, 250, 9, 84, 10, 148, 1, 6, 65, + 85, 84, 79, 77, 79, 20, 7, 70, 73, 82, 69, 32, 69, 78, 144, 225, 2, 2, + 84, 65, 148, 247, 8, 6, 80, 79, 76, 73, 67, 69, 143, 22, 66, 2, 223, 206, + 11, 66, 2, 215, 219, 12, 71, 8, 70, 32, 229, 191, 12, 11, 45, 80, 73, 69, + 67, 69, 32, 83, 87, 73, 77, 6, 40, 4, 68, 79, 84, 32, 175, 173, 10, 66, + 4, 26, 79, 135, 175, 10, 76, 2, 129, 234, 2, 11, 86, 69, 82, 32, 84, 87, + 79, 32, 68, 79, 84, 46, 82, 69, 188, 6, 2, 84, 73, 188, 229, 11, 5, 72, + 73, 85, 67, 72, 147, 183, 1, 80, 36, 70, 78, 201, 5, 12, 82, 65, 84, 73, + 78, 71, 32, 83, 89, 83, 84, 69, 34, 22, 32, 139, 4, 45, 28, 108, 2, 66, + 79, 32, 7, 67, 69, 78, 84, 82, 69, 32, 114, 70, 70, 72, 42, 77, 142, 139, + 7, 83, 135, 244, 3, 76, 4, 242, 239, 13, 79, 155, 3, 88, 8, 50, 84, 174, + 216, 11, 66, 222, 2, 65, 135, 84, 67, 2, 37, 7, 69, 65, 82, 68, 82, 79, + 80, 2, 143, 218, 11, 45, 4, 44, 5, 73, 76, 69, 32, 70, 243, 131, 2, 79, + 2, 239, 131, 2, 79, 2, 17, 2, 65, 78, 2, 151, 191, 10, 68, 4, 57, 12, 65, + 73, 76, 66, 79, 88, 32, 87, 73, 84, 72, 32, 4, 44, 3, 76, 79, 87, 21, 4, + 82, 65, 73, 83, 2, 17, 2, 69, 82, 2, 129, 132, 12, 2, 69, 68, 6, 108, 15, + 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, 80, 85, 84, 32, 221, 204, 12, + 6, 79, 85, 84, 76, 73, 78, 4, 18, 72, 3, 76, 2, 161, 192, 1, 4, 45, 84, + 89, 80, 2, 169, 222, 12, 6, 77, 32, 67, 79, 77, 77, 6, 64, 2, 79, 78, + 253, 177, 1, 8, 67, 65, 76, 32, 68, 73, 83, 67, 2, 247, 207, 11, 32, 208, + 1, 104, 3, 65, 78, 71, 66, 67, 34, 73, 212, 8, 5, 78, 65, 84, 69, 32, 32, + 3, 84, 72, 79, 199, 176, 5, 32, 6, 28, 2, 69, 32, 167, 22, 85, 4, 198, + 150, 12, 66, 203, 78, 72, 4, 186, 174, 13, 85, 223, 61, 65, 188, 1, 48, + 5, 71, 73, 78, 65, 76, 21, 3, 89, 65, 32, 2, 183, 133, 1, 32, 186, 1, + 106, 65, 30, 70, 250, 1, 73, 32, 7, 76, 69, 84, 84, 69, 82, 32, 142, 2, + 83, 218, 1, 86, 159, 240, 11, 68, 4, 182, 137, 10, 73, 3, 85, 12, 41, 8, + 82, 65, 67, 84, 73, 79, 78, 32, 12, 56, 4, 79, 78, 69, 32, 81, 6, 84, 72, + 82, 69, 69, 32, 8, 42, 83, 206, 226, 11, 69, 46, 72, 47, 81, 2, 217, 227, + 11, 4, 73, 88, 84, 69, 4, 26, 83, 227, 228, 11, 81, 2, 145, 136, 8, 4, + 73, 88, 84, 69, 2, 233, 196, 12, 3, 83, 83, 72, 104, 226, 1, 82, 130, + 238, 6, 89, 178, 154, 3, 65, 38, 68, 114, 84, 46, 86, 186, 5, 85, 186, + 202, 1, 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, + 2, 75, 2, 80, 138, 69, 72, 2, 77, 2, 87, 186, 2, 69, 3, 79, 6, 234, 227, + 13, 72, 2, 82, 187, 2, 65, 18, 112, 20, 69, 81, 85, 69, 78, 67, 69, 32, + 70, 79, 82, 32, 76, 69, 84, 84, 69, 82, 32, 82, 29, 4, 73, 71, 78, 32, 4, + 206, 226, 13, 72, 3, 82, 14, 138, 199, 9, 67, 98, 78, 190, 66, 65, 250, + 239, 1, 79, 195, 167, 1, 86, 26, 49, 10, 79, 87, 69, 76, 32, 83, 73, 71, + 78, 32, 26, 206, 140, 10, 65, 38, 85, 22, 86, 166, 202, 1, 73, 198, 140, + 2, 69, 3, 79, 4, 194, 220, 6, 76, 243, 30, 82, 4, 240, 245, 3, 2, 68, 79, + 139, 183, 2, 71, 226, 1, 76, 4, 65, 71, 69, 32, 140, 4, 6, 77, 65, 78, + 89, 65, 32, 251, 221, 13, 67, 144, 1, 56, 6, 67, 65, 80, 73, 84, 65, 1, + 4, 83, 77, 65, 76, 72, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 72, + 194, 1, 65, 38, 69, 90, 75, 42, 79, 22, 84, 246, 229, 6, 72, 254, 250, 4, + 67, 2, 68, 2, 71, 234, 181, 1, 83, 2, 90, 130, 3, 66, 138, 66, 76, 2, 77, + 2, 78, 2, 80, 2, 87, 186, 2, 73, 3, 85, 9, 226, 225, 11, 73, 239, 253, 1, + 72, 15, 26, 72, 179, 143, 13, 73, 10, 134, 202, 9, 84, 226, 151, 2, 67, + 242, 250, 1, 75, 3, 80, 6, 154, 220, 13, 72, 2, 89, 187, 2, 65, 5, 203, + 142, 13, 73, 6, 214, 150, 13, 83, 195, 71, 65, 80, 52, 7, 76, 69, 84, 84, + 69, 82, 32, 187, 233, 11, 68, 60, 246, 1, 65, 38, 67, 22, 68, 38, 75, 34, + 83, 30, 77, 162, 241, 2, 81, 226, 159, 8, 79, 148, 125, 2, 76, 65, 236, + 75, 2, 78, 85, 134, 2, 87, 142, 62, 69, 234, 61, 66, 2, 70, 2, 71, 2, 72, + 2, 74, 2, 82, 2, 84, 2, 88, 2, 89, 186, 2, 73, 3, 85, 7, 194, 250, 2, 76, + 135, 225, 10, 65, 2, 183, 221, 12, 65, 4, 222, 197, 8, 69, 251, 146, 5, + 72, 4, 186, 217, 12, 65, 251, 126, 72, 4, 26, 72, 179, 218, 13, 65, 2, + 219, 218, 12, 73, 124, 68, 11, 79, 77, 65, 78, 32, 83, 73, 89, 65, 81, + 32, 251, 160, 13, 69, 122, 172, 1, 17, 65, 76, 84, 69, 82, 78, 65, 84, + 69, 32, 78, 85, 77, 66, 69, 82, 32, 200, 1, 13, 70, 82, 65, 67, 84, 73, + 79, 78, 32, 79, 78, 69, 32, 48, 3, 77, 65, 82, 47, 78, 26, 54, 70, 50, + 83, 46, 84, 214, 187, 12, 78, 239, 112, 69, 6, 248, 207, 5, 3, 79, 85, + 82, 159, 139, 7, 73, 6, 200, 207, 5, 2, 73, 88, 155, 149, 6, 69, 10, 226, + 184, 2, 69, 12, 2, 87, 79, 247, 171, 9, 72, 4, 26, 83, 175, 208, 11, 72, + 2, 155, 209, 11, 73, 2, 11, 82, 2, 11, 65, 2, 247, 137, 12, 84, 90, 33, + 6, 85, 77, 66, 69, 82, 32, 90, 58, 69, 66, 70, 94, 78, 26, 83, 78, 84, + 179, 177, 5, 79, 10, 25, 4, 73, 71, 72, 84, 11, 226, 182, 2, 89, 227, + 193, 5, 32, 20, 18, 73, 35, 79, 10, 166, 2, 70, 195, 176, 5, 86, 10, 134, + 2, 82, 205, 176, 5, 2, 85, 82, 10, 65, 3, 73, 78, 69, 20, 40, 4, 69, 86, + 69, 78, 1, 2, 73, 88, 11, 166, 1, 84, 219, 245, 7, 32, 24, 34, 72, 50, + 87, 163, 180, 2, 69, 10, 34, 73, 245, 176, 5, 2, 82, 69, 4, 51, 82, 10, + 26, 69, 219, 176, 5, 79, 4, 11, 78, 4, 11, 84, 4, 247, 179, 2, 89, 84, + 34, 84, 217, 177, 11, 2, 78, 67, 82, 42, 66, 37, 6, 76, 73, 78, 69, 68, + 32, 2, 133, 195, 12, 4, 79, 88, 32, 84, 80, 92, 7, 76, 65, 84, 73, 78, + 32, 67, 242, 194, 6, 87, 182, 243, 4, 66, 234, 14, 71, 159, 23, 68, 54, + 186, 174, 7, 65, 215, 222, 4, 82, 12, 18, 72, 43, 76, 2, 17, 2, 69, 65, + 2, 239, 188, 12, 84, 10, 32, 2, 65, 80, 255, 179, 12, 73, 9, 29, 5, 80, + 73, 78, 71, 32, 6, 40, 6, 87, 72, 73, 84, 69, 32, 51, 66, 4, 44, 5, 65, + 78, 68, 32, 66, 151, 138, 10, 83, 2, 253, 137, 10, 4, 76, 65, 67, 75, + 152, 13, 150, 1, 65, 206, 65, 68, 30, 69, 134, 13, 72, 138, 25, 73, 202, + 4, 76, 160, 15, 2, 78, 80, 54, 79, 238, 8, 82, 210, 15, 83, 186, 6, 85, + 239, 177, 12, 77, 158, 6, 134, 2, 68, 38, 71, 212, 1, 11, 72, 65, 87, 72, + 32, 72, 77, 79, 78, 71, 32, 134, 23, 76, 130, 6, 78, 58, 82, 196, 22, 2, + 83, 83, 132, 2, 10, 85, 32, 67, 73, 78, 32, 72, 65, 85, 32, 176, 7, 3, + 87, 32, 80, 152, 252, 7, 2, 67, 75, 233, 141, 5, 4, 80, 69, 82, 67, 5, + 253, 185, 1, 4, 68, 73, 78, 71, 14, 26, 69, 163, 165, 13, 79, 13, 34, 32, + 130, 202, 13, 82, 3, 83, 6, 72, 6, 87, 73, 84, 72, 32, 67, 181, 159, 4, + 6, 70, 65, 67, 73, 78, 71, 4, 50, 85, 145, 237, 7, 6, 73, 82, 67, 76, 69, + 68, 2, 175, 189, 12, 82, 254, 1, 190, 1, 67, 160, 6, 9, 77, 65, 82, 75, + 32, 67, 73, 77, 32, 160, 1, 7, 78, 85, 77, 66, 69, 82, 32, 244, 1, 5, 83, + 73, 71, 78, 32, 144, 10, 7, 86, 79, 87, 69, 76, 32, 75, 223, 191, 11, 68, + 78, 92, 9, 76, 65, 78, 32, 83, 73, 71, 78, 32, 137, 3, 9, 79, 78, 83, 79, + 78, 65, 78, 84, 32, 38, 132, 1, 2, 72, 65, 38, 75, 46, 76, 34, 84, 82, + 86, 30, 89, 148, 9, 2, 88, 89, 172, 5, 2, 80, 72, 174, 1, 70, 165, 2, 2, + 77, 85, 4, 170, 198, 2, 87, 151, 255, 10, 77, 6, 246, 15, 72, 178, 150, + 13, 79, 159, 14, 87, 4, 210, 12, 65, 195, 250, 12, 73, 8, 22, 83, 247, 9, + 72, 6, 160, 197, 2, 3, 72, 69, 69, 158, 193, 9, 65, 3, 87, 4, 234, 196, + 2, 65, 3, 87, 4, 206, 196, 2, 65, 175, 185, 10, 69, 40, 122, 67, 38, 72, + 46, 78, 60, 2, 80, 76, 2, 81, 222, 222, 2, 76, 2, 77, 2, 82, 2, 86, 2, + 88, 2, 89, 247, 189, 10, 65, 4, 230, 223, 2, 72, 247, 189, 10, 65, 6, + 194, 223, 2, 76, 2, 78, 247, 189, 10, 65, 12, 58, 67, 22, 84, 202, 222, + 2, 75, 2, 76, 247, 189, 10, 65, 2, 219, 222, 2, 72, 4, 198, 222, 2, 72, + 3, 83, 14, 42, 75, 50, 83, 38, 84, 167, 175, 13, 72, 4, 26, 72, 231, 130, + 13, 69, 2, 175, 162, 6, 65, 4, 154, 131, 12, 85, 147, 189, 1, 79, 4, 142, + 130, 12, 85, 215, 18, 65, 14, 52, 7, 72, 85, 78, 68, 82, 69, 68, 38, 84, + 79, 77, 4, 108, 2, 32, 77, 195, 190, 13, 83, 8, 24, 2, 69, 78, 51, 82, 6, + 26, 32, 215, 190, 13, 83, 4, 18, 66, 35, 84, 2, 253, 213, 4, 3, 73, 76, + 76, 2, 11, 72, 2, 213, 251, 9, 3, 79, 85, 83, 72, 188, 1, 4, 67, 73, 77, + 32, 246, 2, 72, 32, 3, 73, 66, 32, 22, 77, 86, 78, 50, 84, 124, 4, 86, + 79, 83, 32, 198, 1, 88, 208, 1, 6, 90, 87, 74, 32, 84, 72, 142, 178, 1, + 76, 223, 227, 4, 65, 16, 174, 1, 67, 84, 5, 78, 82, 69, 83, 32, 22, 84, + 164, 252, 11, 7, 80, 85, 66, 32, 68, 65, 87, 153, 189, 1, 16, 72, 65, 73, + 83, 32, 76, 85, 83, 32, 78, 84, 79, 71, 32, 78, 84, 4, 48, 7, 85, 65, 77, + 32, 84, 83, 72, 255, 3, 72, 2, 11, 79, 2, 175, 187, 2, 79, 2, 195, 184, + 1, 84, 6, 52, 3, 88, 87, 86, 161, 151, 10, 4, 83, 79, 86, 32, 5, 209, + 155, 6, 4, 32, 67, 72, 87, 4, 190, 72, 78, 171, 221, 12, 76, 2, 143, 252, + 11, 89, 6, 40, 4, 69, 69, 74, 32, 135, 251, 12, 85, 4, 128, 3, 2, 84, 83, + 57, 2, 83, 85, 4, 26, 84, 187, 252, 8, 81, 2, 135, 185, 2, 85, 6, 196, 1, + 7, 88, 72, 69, 69, 74, 32, 67, 224, 178, 8, 12, 72, 73, 82, 68, 45, 83, + 84, 65, 71, 69, 32, 72, 251, 222, 4, 65, 14, 54, 70, 22, 83, 30, 84, 166, + 69, 76, 195, 251, 7, 78, 2, 167, 164, 13, 69, 2, 173, 152, 6, 2, 69, 69, + 6, 42, 72, 29, 6, 83, 72, 65, 66, 32, 67, 4, 82, 73, 207, 164, 13, 79, 2, + 175, 209, 5, 69, 14, 34, 73, 22, 89, 175, 172, 11, 65, 2, 171, 247, 11, + 65, 10, 40, 4, 69, 69, 77, 32, 243, 149, 13, 79, 8, 84, 3, 78, 84, 88, + 252, 149, 6, 2, 84, 79, 154, 173, 2, 82, 245, 178, 3, 2, 70, 65, 2, 251, + 149, 6, 73, 2, 227, 180, 2, 65, 56, 50, 65, 66, 69, 38, 73, 2, 85, 38, + 79, 39, 87, 20, 170, 1, 65, 2, 73, 2, 85, 2, 87, 134, 178, 13, 66, 3, 86, + 8, 106, 69, 134, 178, 13, 66, 3, 86, 8, 70, 65, 134, 178, 13, 66, 3, 86, + 8, 34, 79, 134, 178, 13, 66, 3, 86, 4, 130, 178, 13, 66, 3, 86, 76, 18, + 76, 23, 77, 2, 247, 243, 12, 65, 74, 74, 32, 104, 6, 89, 82, 69, 78, 69, + 32, 141, 142, 4, 4, 83, 32, 85, 80, 8, 80, 3, 66, 82, 65, 246, 189, 11, + 84, 248, 97, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 247, 141, 13, 78, 64, + 80, 2, 76, 69, 40, 4, 82, 73, 71, 72, 253, 2, 7, 78, 85, 77, 66, 69, 82, + 32, 48, 38, 70, 89, 5, 84, 84, 69, 82, 32, 2, 57, 12, 84, 45, 80, 79, 73, + 78, 84, 73, 78, 71, 32, 70, 2, 229, 231, 5, 2, 76, 69, 46, 224, 1, 5, 70, + 73, 78, 65, 76, 30, 84, 242, 119, 68, 34, 76, 50, 81, 214, 205, 1, 82, + 142, 220, 2, 65, 50, 71, 90, 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, + 75, 174, 81, 66, 170, 225, 4, 78, 134, 2, 87, 218, 103, 80, 171, 4, 77, + 2, 161, 172, 12, 2, 32, 78, 4, 190, 167, 11, 69, 219, 134, 1, 65, 14, + 194, 121, 84, 198, 191, 10, 70, 223, 87, 79, 4, 32, 2, 67, 65, 147, 236, + 12, 68, 2, 191, 149, 12, 75, 188, 2, 94, 65, 220, 1, 11, 69, 78, 84, 72, + 69, 83, 73, 90, 69, 68, 32, 242, 16, 84, 203, 199, 12, 82, 14, 80, 5, 71, + 82, 65, 80, 72, 52, 5, 76, 76, 69, 76, 32, 209, 163, 6, 2, 67, 72, 6, + 186, 248, 9, 32, 250, 223, 1, 85, 235, 147, 1, 79, 6, 44, 5, 87, 73, 84, + 72, 32, 163, 138, 13, 84, 4, 222, 198, 6, 84, 175, 186, 4, 72, 150, 2, + 252, 1, 7, 72, 65, 78, 71, 85, 76, 32, 188, 4, 10, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 32, 188, 7, 18, 75, 79, 82, 69, 65, 78, 32, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 32, 79, 44, 7, 78, 85, 77, 66, 69, 82, 32, 250, + 206, 4, 68, 145, 169, 2, 2, 76, 65, 58, 102, 67, 110, 72, 30, 75, 66, 77, + 34, 78, 34, 80, 62, 82, 30, 83, 26, 84, 73, 5, 73, 69, 85, 78, 71, 10, + 34, 72, 33, 4, 73, 69, 85, 67, 4, 141, 3, 4, 73, 69, 85, 67, 7, 11, 32, + 4, 178, 165, 13, 65, 3, 85, 4, 197, 2, 3, 73, 69, 85, 8, 168, 2, 5, 72, + 73, 69, 85, 75, 13, 5, 73, 89, 69, 79, 75, 4, 245, 1, 4, 73, 69, 85, 77, + 4, 213, 1, 4, 73, 69, 85, 78, 8, 168, 1, 5, 72, 73, 69, 85, 80, 13, 4, + 73, 69, 85, 80, 4, 121, 4, 73, 69, 85, 76, 4, 93, 3, 73, 79, 83, 8, 56, + 5, 72, 73, 69, 85, 84, 13, 5, 73, 75, 69, 85, 84, 4, 11, 72, 5, 139, 160, + 13, 32, 72, 148, 1, 2, 65, 76, 30, 67, 74, 69, 82, 70, 112, 2, 76, 65, + 22, 77, 38, 78, 32, 2, 82, 69, 78, 83, 138, 2, 84, 50, 87, 254, 172, 11, + 72, 239, 82, 79, 2, 237, 144, 8, 2, 76, 73, 4, 32, 2, 79, 78, 179, 150, + 11, 65, 2, 181, 251, 7, 4, 71, 82, 65, 84, 6, 42, 78, 174, 179, 9, 65, + 155, 194, 3, 73, 2, 169, 4, 5, 84, 69, 82, 80, 82, 10, 58, 73, 204, 147, + 12, 5, 69, 83, 84, 73, 86, 139, 19, 79, 6, 208, 2, 3, 78, 65, 78, 130, + 134, 13, 82, 3, 86, 2, 139, 230, 12, 66, 4, 226, 198, 10, 69, 147, 136, + 2, 79, 4, 138, 131, 12, 73, 195, 1, 65, 8, 38, 83, 218, 139, 12, 80, 247, + 111, 65, 4, 190, 214, 6, 79, 183, 199, 6, 84, 18, 58, 69, 34, 79, 22, 80, + 34, 84, 50, 85, 211, 141, 12, 73, 4, 142, 199, 11, 86, 227, 84, 76, 2, + 239, 251, 7, 67, 2, 11, 69, 2, 227, 181, 4, 67, 4, 26, 85, 163, 234, 11, + 79, 2, 219, 138, 13, 68, 4, 26, 80, 247, 155, 13, 78, 2, 21, 3, 69, 82, + 86, 2, 183, 144, 12, 73, 6, 154, 169, 11, 72, 206, 162, 1, 69, 239, 48, + 87, 4, 234, 224, 9, 79, 163, 128, 2, 65, 4, 170, 164, 8, 32, 221, 166, 4, + 2, 74, 69, 22, 42, 69, 46, 70, 42, 78, 30, 83, 51, 84, 4, 216, 1, 3, 73, + 71, 72, 131, 246, 4, 76, 4, 160, 1, 2, 79, 85, 13, 2, 73, 70, 2, 133, 1, + 3, 73, 78, 69, 4, 34, 73, 73, 4, 69, 86, 69, 78, 2, 71, 88, 8, 34, 72, + 46, 87, 207, 200, 12, 69, 2, 11, 73, 2, 11, 82, 2, 175, 194, 11, 84, 4, + 11, 69, 4, 190, 168, 11, 78, 143, 115, 76, 22, 164, 1, 3, 73, 65, 76, + 216, 1, 3, 89, 32, 80, 224, 206, 6, 5, 72, 69, 78, 79, 80, 180, 229, 1, + 6, 78, 69, 82, 83, 72, 73, 225, 219, 3, 6, 32, 65, 76, 84, 69, 82, 12, + 62, 32, 173, 124, 10, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 10, 38, 68, + 41, 5, 76, 73, 78, 69, 32, 2, 229, 174, 4, 5, 73, 70, 70, 69, 82, 8, 254, + 205, 3, 68, 226, 45, 70, 20, 4, 66, 65, 67, 75, 203, 153, 9, 85, 2, 223, + 242, 3, 79, 10, 98, 69, 52, 9, 73, 86, 69, 45, 80, 85, 76, 76, 45, 89, 9, + 80, 79, 82, 84, 32, 67, 79, 78, 84, 4, 176, 242, 9, 4, 78, 71, 69, 82, + 147, 140, 2, 68, 4, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 213, 176, 5, + 6, 45, 79, 85, 84, 80, 85, 2, 239, 253, 11, 82, 114, 192, 1, 12, 71, 76, + 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 62, 76, 156, 3, 3, 82, 73, 83, + 36, 14, 77, 73, 68, 45, 76, 69, 86, 69, 76, 32, 84, 79, 78, 69, 57, 7, + 83, 65, 78, 68, 72, 73, 32, 7, 11, 32, 4, 202, 5, 70, 213, 255, 11, 4, + 86, 65, 82, 73, 82, 72, 6, 69, 84, 84, 69, 82, 32, 209, 2, 7, 79, 87, 45, + 70, 65, 76, 76, 74, 202, 1, 70, 226, 252, 8, 73, 2, 85, 238, 27, 78, 198, + 174, 3, 67, 2, 75, 2, 80, 2, 84, 138, 69, 66, 2, 68, 2, 71, 2, 72, 2, 76, + 2, 77, 2, 82, 2, 83, 2, 86, 2, 90, 186, 2, 65, 2, 69, 3, 79, 20, 44, 5, + 73, 78, 65, 76, 32, 163, 142, 13, 65, 18, 158, 144, 11, 78, 130, 254, 1, + 75, 2, 76, 2, 77, 2, 80, 2, 84, 2, 87, 3, 89, 8, 157, 1, 5, 73, 78, 71, + 32, 84, 7, 11, 32, 4, 192, 1, 5, 76, 79, 78, 71, 32, 15, 70, 12, 66, 84, + 73, 12, 71, 76, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 8, 21, 3, 79, 78, + 69, 9, 11, 32, 6, 32, 4, 76, 79, 78, 71, 27, 70, 5, 11, 32, 2, 11, 70, 2, + 131, 201, 3, 73, 2, 171, 181, 4, 82, 4, 162, 139, 13, 70, 3, 73, 80, 130, + 1, 65, 122, 78, 162, 1, 82, 162, 9, 83, 44, 3, 84, 82, 73, 130, 17, 68, + 157, 156, 12, 9, 79, 80, 76, 69, 32, 72, 85, 71, 71, 12, 50, 67, 50, 78, + 138, 239, 6, 32, 155, 154, 6, 82, 6, 202, 215, 11, 79, 194, 28, 69, 199, + 149, 1, 72, 2, 227, 128, 12, 85, 10, 118, 71, 20, 3, 83, 73, 86, 222, + 179, 1, 84, 156, 188, 4, 10, 32, 79, 86, 69, 82, 32, 83, 84, 65, 77, 187, + 184, 5, 67, 2, 191, 136, 12, 85, 2, 223, 202, 12, 69, 48, 186, 1, 32, + 116, 10, 80, 69, 78, 68, 73, 67, 85, 76, 65, 82, 42, 83, 130, 176, 7, 67, + 252, 9, 10, 77, 65, 78, 69, 78, 84, 32, 80, 65, 80, 237, 133, 2, 8, 70, + 79, 82, 77, 73, 78, 71, 32, 6, 34, 77, 30, 84, 139, 255, 11, 83, 2, 129, + 242, 1, 2, 73, 76, 2, 149, 154, 11, 8, 69, 78, 32, 84, 72, 79, 85, 83, 5, + 213, 139, 9, 5, 32, 87, 73, 84, 72, 32, 60, 2, 79, 78, 154, 75, 80, 157, + 177, 11, 4, 69, 86, 69, 82, 28, 38, 32, 237, 133, 10, 3, 65, 76, 32, 26, + 216, 2, 10, 68, 79, 73, 78, 71, 32, 67, 65, 82, 84, 32, 3, 73, 78, 32, + 92, 5, 87, 73, 84, 72, 32, 184, 224, 7, 4, 70, 82, 79, 87, 204, 13, 27, + 82, 65, 73, 83, 73, 78, 71, 32, 66, 79, 84, 72, 32, 72, 65, 78, 68, 83, + 32, 73, 78, 32, 67, 69, 76, 69, 66, 204, 193, 4, 5, 67, 76, 73, 77, 66, + 213, 45, 11, 66, 79, 87, 73, 78, 71, 32, 68, 69, 69, 80, 2, 11, 87, 2, + 159, 189, 3, 72, 4, 204, 175, 12, 6, 76, 79, 84, 85, 83, 32, 253, 64, 9, + 83, 84, 69, 65, 77, 89, 32, 82, 79, 12, 154, 1, 66, 180, 146, 2, 3, 80, + 79, 85, 188, 165, 1, 2, 67, 82, 244, 132, 6, 6, 70, 79, 76, 68, 69, 68, + 177, 193, 2, 8, 72, 69, 65, 68, 83, 67, 65, 82, 4, 36, 3, 76, 79, 78, + 235, 244, 10, 65, 2, 11, 68, 2, 11, 32, 2, 11, 72, 2, 11, 65, 2, 131, + 198, 12, 73, 4, 180, 169, 9, 2, 69, 84, 151, 206, 2, 79, 2, 209, 153, 9, + 2, 32, 68, 140, 2, 66, 65, 184, 19, 9, 73, 76, 73, 80, 80, 73, 78, 69, + 32, 47, 79, 204, 1, 108, 6, 71, 83, 45, 80, 65, 32, 189, 7, 16, 73, 83, + 84, 79, 83, 32, 68, 73, 83, 67, 32, 83, 73, 71, 78, 32, 112, 100, 7, 76, + 69, 84, 84, 69, 82, 32, 248, 4, 5, 77, 65, 82, 75, 32, 30, 83, 33, 4, 68, + 79, 85, 66, 96, 138, 2, 65, 138, 1, 67, 50, 68, 42, 83, 64, 5, 86, 79, + 73, 67, 69, 178, 129, 9, 71, 202, 173, 3, 78, 82, 84, 46, 75, 2, 80, 2, + 90, 162, 7, 69, 234, 61, 66, 2, 70, 2, 72, 2, 74, 2, 76, 2, 77, 2, 81, 2, + 82, 2, 87, 2, 88, 2, 89, 186, 2, 73, 2, 79, 3, 85, 7, 80, 8, 76, 84, 69, + 82, 78, 65, 84, 69, 21, 8, 83, 80, 73, 82, 65, 84, 69, 68, 2, 163, 246, + 12, 32, 2, 11, 32, 2, 167, 246, 12, 70, 6, 26, 65, 251, 245, 12, 72, 5, + 231, 218, 8, 78, 6, 226, 245, 12, 68, 2, 90, 187, 2, 65, 6, 244, 174, 8, + 4, 77, 65, 76, 76, 198, 198, 4, 72, 187, 2, 65, 4, 34, 68, 21, 4, 76, 69, + 83, 83, 2, 231, 249, 10, 32, 2, 171, 187, 9, 32, 4, 246, 175, 12, 68, 59, + 83, 10, 28, 3, 73, 78, 71, 31, 85, 2, 229, 169, 12, 2, 76, 69, 8, 58, 66, + 213, 170, 12, 8, 80, 69, 82, 70, 73, 88, 69, 68, 6, 209, 189, 8, 13, 74, + 79, 73, 78, 69, 68, 32, 76, 69, 84, 84, 69, 82, 92, 238, 1, 66, 146, 1, + 67, 172, 2, 2, 68, 79, 38, 71, 66, 72, 64, 2, 76, 73, 32, 2, 77, 65, 70, + 80, 162, 1, 82, 38, 83, 150, 1, 84, 70, 87, 200, 228, 5, 2, 70, 76, 176, + 238, 1, 2, 79, 88, 252, 240, 3, 2, 69, 65, 138, 10, 65, 135, 1, 86, 10, + 52, 2, 69, 69, 22, 79, 145, 41, 4, 85, 76, 76, 83, 5, 147, 182, 7, 72, 4, + 32, 2, 79, 77, 175, 242, 12, 87, 2, 11, 69, 2, 203, 153, 12, 82, 16, 34, + 65, 86, 72, 22, 76, 23, 79, 6, 130, 224, 5, 80, 208, 240, 3, 8, 82, 80, + 69, 78, 84, 82, 89, 32, 151, 161, 3, 84, 2, 199, 193, 2, 73, 2, 135, 179, + 11, 85, 6, 26, 76, 33, 2, 77, 66, 2, 11, 85, 2, 227, 160, 12, 77, 5, 37, + 7, 73, 78, 73, 78, 71, 32, 79, 2, 169, 255, 9, 5, 66, 76, 73, 81, 85, 4, + 174, 196, 11, 76, 223, 148, 1, 86, 4, 42, 82, 137, 141, 11, 4, 65, 85, + 78, 84, 2, 131, 181, 11, 65, 6, 42, 69, 238, 219, 7, 79, 243, 255, 2, 73, + 2, 171, 185, 12, 76, 4, 242, 220, 12, 76, 203, 17, 68, 4, 34, 78, 249, + 251, 9, 2, 84, 84, 2, 11, 65, 2, 211, 172, 9, 67, 8, 52, 2, 69, 68, 50, + 76, 181, 176, 7, 3, 65, 80, 89, 2, 25, 4, 69, 83, 84, 82, 2, 231, 160, + 11, 73, 4, 192, 187, 4, 2, 85, 77, 209, 231, 2, 3, 65, 78, 69, 4, 230, + 218, 10, 79, 251, 128, 2, 65, 12, 108, 2, 72, 73, 134, 237, 11, 65, 158, + 45, 76, 128, 19, 3, 84, 82, 65, 177, 39, 7, 77, 65, 76, 76, 32, 65, 88, + 4, 214, 187, 2, 69, 207, 175, 10, 80, 6, 208, 185, 4, 5, 65, 84, 84, 79, + 79, 226, 236, 7, 73, 207, 36, 85, 4, 146, 236, 7, 79, 137, 238, 3, 5, 65, + 86, 89, 32, 66, 4, 250, 244, 1, 83, 25, 4, 68, 79, 85, 66, 60, 56, 8, 69, + 78, 73, 67, 73, 65, 78, 32, 187, 224, 10, 76, 58, 92, 7, 76, 69, 84, 84, + 69, 82, 32, 160, 3, 7, 78, 85, 77, 66, 69, 82, 32, 231, 155, 6, 87, 44, + 234, 1, 65, 34, 68, 22, 72, 22, 81, 22, 83, 58, 84, 226, 130, 2, 87, 154, + 239, 5, 90, 154, 185, 1, 89, 164, 207, 1, 2, 82, 79, 184, 95, 3, 71, 65, + 77, 162, 10, 75, 130, 1, 78, 144, 58, 3, 76, 65, 77, 138, 17, 66, 198, + 30, 80, 171, 4, 77, 4, 170, 229, 11, 76, 199, 49, 73, 2, 199, 192, 3, 69, + 4, 195, 253, 6, 69, 2, 227, 228, 11, 79, 6, 254, 210, 10, 65, 162, 147, + 1, 72, 189, 124, 2, 69, 77, 4, 210, 192, 12, 65, 191, 8, 69, 12, 202, 50, + 84, 203, 170, 4, 79, 40, 104, 2, 67, 75, 66, 71, 62, 76, 90, 78, 178, 1, + 83, 28, 7, 84, 67, 72, 70, 79, 82, 75, 243, 224, 12, 69, 5, 17, 2, 85, + 80, 2, 21, 3, 32, 84, 82, 2, 223, 177, 11, 85, 7, 11, 32, 4, 26, 78, 163, + 166, 12, 70, 2, 131, 216, 11, 79, 6, 52, 4, 69, 32, 79, 70, 246, 92, 67, + 235, 133, 12, 76, 2, 11, 32, 2, 215, 151, 10, 80, 14, 68, 2, 67, 72, 46, + 69, 194, 169, 4, 87, 206, 176, 7, 75, 243, 98, 65, 4, 196, 160, 3, 2, 69, + 68, 231, 176, 8, 73, 4, 28, 2, 32, 68, 239, 73, 65, 2, 253, 134, 5, 2, + 69, 67, 4, 134, 203, 11, 67, 123, 84, 5, 245, 139, 10, 10, 32, 87, 73, + 84, 72, 32, 84, 69, 69, 32, 218, 1, 38, 65, 230, 9, 85, 167, 214, 12, 68, + 176, 1, 78, 67, 128, 1, 12, 78, 67, 75, 32, 67, 79, 78, 83, 84, 65, 78, + 84, 83, 89, 6, 44, 5, 69, 32, 79, 70, 32, 151, 198, 11, 65, 4, 56, 6, 73, + 78, 84, 69, 82, 69, 173, 137, 12, 2, 87, 79, 2, 251, 146, 7, 83, 5, 45, + 9, 32, 79, 86, 69, 82, 32, 84, 87, 79, 2, 11, 32, 2, 159, 202, 12, 80, + 166, 1, 80, 7, 71, 82, 79, 85, 78, 68, 32, 29, 9, 73, 78, 71, 32, 67, 65, + 82, 68, 32, 2, 173, 171, 4, 2, 83, 76, 164, 1, 182, 1, 66, 44, 3, 82, 69, + 68, 0, 5, 87, 72, 73, 84, 69, 42, 70, 74, 75, 38, 69, 34, 83, 36, 3, 81, + 85, 69, 14, 84, 92, 2, 65, 67, 0, 3, 78, 73, 78, 13, 4, 74, 65, 67, 75, + 4, 40, 4, 76, 65, 67, 75, 135, 169, 11, 65, 2, 17, 2, 32, 74, 2, 219, + 237, 1, 79, 18, 30, 79, 249, 1, 2, 73, 86, 10, 128, 2, 2, 85, 82, 239, + 204, 11, 79, 16, 34, 78, 185, 1, 3, 73, 78, 71, 8, 181, 1, 4, 73, 71, 72, + 84, 16, 32, 2, 69, 86, 117, 2, 73, 88, 8, 91, 69, 66, 78, 69, 12, 3, 72, + 82, 69, 12, 2, 87, 79, 161, 1, 5, 82, 85, 77, 80, 45, 8, 23, 78, 8, 11, + 69, 8, 25, 4, 32, 79, 70, 32, 8, 88, 3, 67, 76, 85, 20, 3, 83, 80, 65, + 250, 145, 9, 72, 137, 3, 5, 68, 73, 65, 77, 79, 2, 231, 153, 12, 66, 2, + 171, 193, 11, 68, 42, 90, 50, 190, 146, 10, 49, 134, 196, 2, 51, 2, 52, + 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 7, 190, 214, 12, 48, 3, 49, 41, 46, + 83, 160, 4, 2, 84, 79, 175, 128, 9, 78, 26, 52, 5, 32, 83, 73, 71, 78, + 141, 163, 9, 2, 45, 77, 25, 11, 32, 22, 64, 3, 73, 78, 32, 124, 5, 87, + 73, 84, 72, 32, 215, 255, 3, 65, 6, 34, 76, 22, 82, 195, 173, 11, 84, 2, + 41, 2, 69, 70, 2, 21, 3, 73, 71, 72, 2, 233, 255, 10, 6, 84, 32, 72, 65, + 76, 70, 14, 162, 1, 68, 34, 83, 140, 176, 10, 4, 84, 73, 76, 68, 152, + 123, 5, 66, 76, 65, 67, 75, 201, 38, 16, 67, 73, 82, 67, 85, 77, 70, 76, + 69, 88, 32, 65, 67, 67, 69, 78, 2, 11, 79, 2, 167, 161, 10, 84, 4, 54, + 77, 173, 181, 5, 7, 85, 66, 83, 67, 82, 73, 80, 2, 197, 170, 9, 3, 65, + 76, 76, 11, 33, 6, 32, 70, 79, 82, 77, 32, 8, 162, 222, 10, 70, 71, 84, + 2, 157, 152, 12, 8, 32, 84, 82, 65, 78, 83, 73, 83, 58, 232, 1, 5, 76, + 73, 67, 69, 32, 122, 80, 140, 1, 11, 82, 84, 65, 66, 76, 69, 32, 83, 84, + 69, 82, 22, 83, 158, 1, 84, 146, 1, 85, 196, 1, 4, 87, 69, 82, 32, 210, + 142, 7, 79, 157, 129, 5, 11, 67, 75, 69, 84, 32, 67, 65, 76, 67, 85, 76, + 6, 52, 3, 67, 65, 82, 217, 253, 3, 4, 79, 70, 70, 73, 5, 217, 177, 10, + 11, 83, 32, 82, 69, 86, 79, 76, 86, 73, 78, 71, 6, 76, 13, 32, 68, 73, + 82, 69, 67, 84, 73, 79, 78, 65, 76, 32, 159, 215, 1, 67, 4, 158, 128, 1, + 73, 169, 190, 6, 6, 70, 79, 82, 77, 65, 84, 2, 251, 173, 12, 69, 12, 40, + 2, 69, 73, 22, 84, 243, 140, 5, 73, 2, 195, 252, 11, 68, 8, 36, 3, 65, + 76, 32, 171, 189, 11, 66, 6, 226, 213, 1, 72, 213, 206, 6, 4, 77, 65, 82, + 75, 8, 66, 65, 238, 135, 2, 32, 153, 183, 9, 6, 84, 69, 68, 32, 80, 76, + 4, 26, 66, 239, 171, 12, 84, 2, 29, 5, 76, 69, 32, 87, 65, 2, 243, 48, + 84, 12, 108, 4, 76, 84, 82, 89, 28, 7, 82, 73, 78, 71, 32, 76, 73, 28, 2, + 84, 73, 202, 221, 10, 78, 179, 234, 1, 67, 2, 213, 131, 12, 2, 32, 76, 2, + 205, 179, 5, 2, 81, 85, 4, 149, 223, 10, 2, 78, 71, 8, 24, 2, 79, 78, 47, + 83, 4, 136, 179, 11, 4, 45, 79, 70, 70, 15, 32, 4, 156, 152, 9, 3, 76, + 69, 69, 231, 154, 2, 89, 140, 1, 74, 69, 162, 10, 73, 230, 2, 79, 237, + 221, 9, 6, 65, 89, 69, 82, 32, 66, 102, 132, 1, 6, 71, 78, 65, 78, 84, + 32, 66, 83, 252, 191, 5, 4, 67, 69, 68, 69, 192, 207, 1, 5, 86, 73, 79, + 85, 83, 241, 32, 2, 84, 90, 6, 42, 87, 202, 193, 8, 80, 143, 184, 2, 77, + 2, 199, 199, 7, 79, 70, 176, 1, 27, 69, 78, 84, 65, 84, 73, 79, 78, 32, + 70, 79, 82, 77, 32, 70, 79, 82, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, + 129, 216, 8, 10, 67, 82, 73, 80, 84, 73, 79, 78, 32, 84, 68, 198, 1, 67, + 22, 69, 46, 72, 50, 73, 94, 76, 188, 1, 6, 82, 73, 71, 72, 84, 32, 192, + 2, 6, 87, 65, 86, 89, 32, 76, 178, 156, 4, 83, 252, 217, 4, 9, 84, 87, + 79, 32, 68, 79, 84, 32, 76, 139, 114, 81, 4, 191, 190, 2, 79, 6, 158, + 158, 6, 88, 182, 227, 2, 77, 3, 78, 2, 173, 154, 9, 7, 79, 82, 73, 90, + 79, 78, 84, 4, 49, 10, 68, 69, 79, 71, 82, 65, 80, 72, 73, 67, 4, 11, 32, + 4, 218, 235, 9, 67, 35, 70, 22, 40, 4, 69, 70, 84, 32, 143, 214, 10, 79, + 20, 112, 6, 87, 72, 73, 84, 69, 32, 142, 1, 66, 42, 68, 186, 100, 67, + 166, 7, 65, 222, 203, 7, 80, 238, 7, 83, 39, 84, 4, 162, 2, 67, 255, 99, + 76, 22, 110, 66, 42, 68, 36, 6, 87, 72, 73, 84, 69, 32, 150, 100, 67, + 166, 7, 65, 222, 203, 7, 80, 238, 7, 83, 39, 84, 2, 145, 101, 6, 76, 65, + 67, 75, 32, 76, 2, 197, 107, 5, 79, 85, 66, 76, 69, 6, 74, 67, 17, 14, + 76, 69, 78, 84, 73, 67, 85, 76, 65, 82, 32, 66, 82, 65, 2, 227, 99, 79, + 4, 246, 234, 11, 67, 177, 29, 2, 75, 67, 2, 187, 210, 10, 79, 22, 46, 78, + 156, 1, 2, 86, 65, 231, 164, 12, 77, 10, 34, 84, 133, 211, 6, 2, 67, 69, + 6, 26, 32, 53, 2, 69, 82, 2, 21, 3, 83, 67, 82, 2, 205, 193, 10, 2, 69, + 69, 5, 17, 2, 32, 73, 2, 223, 235, 11, 67, 10, 60, 5, 67, 89, 32, 77, 69, + 29, 6, 84, 69, 32, 85, 83, 69, 2, 213, 171, 7, 2, 83, 83, 8, 26, 32, 231, + 180, 8, 45, 4, 134, 166, 10, 84, 139, 121, 79, 14, 98, 74, 30, 80, 90, + 83, 156, 34, 5, 72, 73, 66, 73, 84, 173, 245, 8, 6, 66, 73, 78, 71, 32, + 67, 2, 213, 167, 5, 2, 69, 67, 6, 64, 6, 79, 82, 84, 73, 79, 78, 137, + 157, 11, 4, 69, 82, 84, 89, 5, 183, 215, 5, 65, 2, 173, 250, 10, 4, 69, + 82, 80, 73, 60, 76, 14, 65, 76, 84, 69, 82, 32, 80, 65, 72, 76, 65, 86, + 73, 32, 215, 5, 89, 58, 172, 1, 15, 70, 79, 85, 82, 32, 68, 79, 84, 83, + 32, 87, 73, 84, 72, 32, 32, 7, 76, 69, 84, 84, 69, 82, 32, 230, 2, 78, + 154, 32, 83, 1, 8, 84, 85, 82, 78, 69, 68, 32, 83, 4, 246, 242, 10, 67, + 247, 114, 68, 36, 166, 1, 65, 22, 68, 34, 76, 22, 77, 50, 87, 254, 169, + 4, 71, 90, 90, 34, 83, 66, 89, 198, 207, 1, 72, 234, 5, 75, 174, 81, 66, + 170, 225, 4, 78, 134, 2, 84, 219, 103, 80, 2, 223, 170, 4, 76, 2, 11, 65, + 2, 227, 210, 6, 76, 2, 251, 170, 4, 65, 2, 25, 4, 69, 77, 45, 81, 2, 255, + 128, 6, 79, 2, 37, 7, 65, 87, 45, 65, 89, 73, 78, 2, 149, 205, 1, 2, 45, + 82, 14, 33, 6, 85, 77, 66, 69, 82, 32, 14, 42, 84, 202, 170, 4, 79, 191, + 236, 2, 70, 8, 42, 87, 250, 191, 10, 72, 207, 162, 1, 69, 4, 182, 194, + 10, 69, 239, 239, 1, 79, 2, 243, 132, 12, 67, 18, 252, 1, 4, 78, 67, 84, + 85, 94, 82, 56, 19, 84, 32, 76, 73, 84, 84, 69, 82, 32, 73, 78, 32, 73, + 84, 83, 32, 80, 76, 65, 178, 151, 1, 83, 132, 42, 20, 66, 76, 73, 67, 32, + 65, 68, 68, 82, 69, 83, 83, 32, 76, 79, 85, 68, 83, 80, 69, 166, 237, 10, + 49, 3, 50, 4, 164, 222, 10, 9, 83, 32, 69, 76, 69, 86, 65, 84, 85, 129, + 147, 1, 5, 65, 84, 73, 79, 78, 4, 32, 2, 80, 76, 155, 152, 12, 83, 2, + 175, 167, 11, 69, 2, 11, 67, 2, 135, 153, 11, 69, 40, 98, 65, 180, 6, 6, + 69, 83, 84, 73, 79, 78, 254, 136, 6, 79, 229, 143, 5, 5, 73, 78, 67, 85, + 78, 30, 104, 2, 68, 82, 240, 4, 9, 84, 69, 82, 78, 73, 79, 78, 32, 73, + 48, 4, 82, 84, 69, 82, 143, 132, 11, 79, 24, 56, 4, 65, 78, 84, 32, 157, + 4, 5, 85, 80, 76, 69, 32, 20, 44, 6, 85, 80, 80, 69, 82, 32, 131, 2, 76, + 16, 56, 4, 76, 69, 70, 84, 249, 1, 5, 82, 73, 71, 72, 84, 11, 29, 5, 32, + 65, 78, 68, 32, 8, 108, 6, 76, 79, 87, 69, 82, 32, 53, 17, 85, 80, 80, + 69, 82, 32, 82, 73, 71, 72, 84, 32, 65, 78, 68, 32, 76, 4, 192, 1, 5, 76, + 69, 70, 84, 32, 159, 254, 11, 82, 4, 11, 79, 4, 11, 87, 4, 213, 254, 11, + 2, 69, 82, 7, 65, 14, 32, 65, 78, 68, 32, 76, 79, 87, 69, 82, 32, 76, 69, + 70, 4, 11, 84, 5, 11, 32, 2, 21, 3, 65, 78, 68, 2, 17, 2, 32, 76, 2, 17, + 2, 79, 87, 2, 137, 213, 10, 2, 69, 82, 4, 22, 73, 239, 37, 80, 2, 177, + 228, 8, 7, 78, 84, 69, 71, 82, 65, 76, 2, 17, 2, 32, 78, 2, 159, 222, 10, + 79, 6, 34, 32, 161, 197, 5, 2, 69, 68, 4, 162, 139, 5, 69, 175, 218, 6, + 77, 220, 9, 114, 65, 142, 8, 69, 220, 27, 6, 72, 73, 78, 79, 67, 69, 34, + 73, 250, 87, 76, 46, 79, 198, 19, 85, 243, 149, 11, 83, 62, 110, 67, 104, + 2, 68, 73, 130, 1, 73, 162, 5, 84, 172, 246, 7, 4, 66, 66, 73, 84, 214, + 238, 3, 90, 235, 56, 77, 6, 40, 4, 73, 78, 71, 32, 159, 250, 8, 67, 4, + 192, 208, 10, 7, 77, 79, 84, 79, 82, 67, 89, 199, 48, 67, 8, 66, 79, 141, + 180, 8, 10, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 7, 168, 184, 6, 4, + 65, 67, 84, 73, 229, 181, 4, 2, 32, 66, 36, 60, 5, 76, 87, 65, 89, 32, + 46, 78, 21, 4, 83, 69, 68, 32, 4, 240, 131, 9, 2, 84, 82, 155, 251, 1, + 67, 5, 243, 133, 11, 66, 28, 152, 1, 3, 68, 79, 84, 34, 73, 48, 4, 72, + 65, 78, 68, 182, 1, 77, 38, 83, 166, 177, 7, 70, 206, 151, 2, 67, 161, + 197, 1, 7, 66, 65, 67, 75, 32, 79, 70, 5, 29, 5, 84, 69, 68, 32, 73, 2, + 209, 40, 8, 78, 84, 69, 82, 80, 79, 76, 65, 7, 33, 6, 32, 87, 73, 84, 72, + 32, 4, 214, 27, 70, 245, 194, 2, 28, 80, 65, 82, 84, 32, 66, 69, 84, 87, + 69, 69, 78, 32, 77, 73, 68, 68, 76, 69, 32, 65, 78, 68, 32, 82, 73, 78, + 71, 6, 230, 151, 11, 67, 2, 68, 3, 82, 4, 60, 9, 77, 65, 76, 76, 32, 76, + 69, 70, 84, 179, 251, 10, 81, 2, 229, 158, 8, 2, 32, 83, 5, 243, 254, 11, + 73, 250, 1, 226, 1, 67, 132, 4, 2, 68, 32, 64, 2, 71, 73, 144, 1, 5, 74, + 65, 78, 71, 32, 202, 4, 76, 32, 8, 77, 73, 78, 68, 69, 82, 32, 82, 34, + 80, 106, 83, 136, 1, 5, 84, 85, 82, 78, 32, 42, 86, 209, 199, 1, 5, 70, + 69, 82, 69, 78, 26, 114, 69, 60, 3, 89, 67, 76, 146, 209, 5, 79, 205, + 155, 4, 13, 82, 69, 65, 84, 73, 79, 78, 65, 76, 32, 86, 69, 72, 4, 38, + 73, 209, 198, 10, 3, 80, 84, 65, 2, 163, 254, 11, 80, 18, 78, 69, 53, 15, + 73, 78, 71, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 2, 29, 5, 68, + 32, 80, 65, 80, 2, 211, 179, 10, 69, 16, 100, 5, 84, 89, 80, 69, 45, 173, + 130, 5, 14, 71, 69, 78, 69, 82, 73, 67, 32, 77, 65, 84, 69, 82, 73, 14, + 58, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 2, 133, 210, 5, 6, 32, + 80, 76, 65, 83, 84, 4, 42, 65, 205, 255, 4, 4, 71, 73, 70, 84, 2, 231, + 190, 3, 80, 54, 120, 4, 83, 84, 69, 82, 213, 244, 5, 20, 79, 78, 65, 76, + 32, 73, 78, 68, 73, 67, 65, 84, 79, 82, 32, 83, 89, 77, 66, 79, 2, 235, + 170, 10, 69, 74, 128, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, + 73, 71, 78, 32, 44, 7, 76, 69, 84, 84, 69, 82, 32, 226, 1, 83, 35, 86, 8, + 146, 151, 10, 78, 130, 254, 1, 72, 3, 82, 46, 162, 1, 78, 186, 253, 7, + 77, 214, 147, 4, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, + 80, 2, 82, 2, 83, 2, 84, 2, 87, 2, 89, 187, 2, 65, 12, 154, 254, 7, 89, + 166, 31, 71, 206, 243, 3, 68, 187, 2, 65, 2, 11, 69, 2, 211, 169, 11, 67, + 18, 64, 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 139, 214, 9, 73, 16, + 54, 69, 182, 209, 11, 65, 186, 64, 73, 2, 79, 3, 85, 7, 234, 145, 12, 65, + 3, 85, 2, 217, 254, 10, 3, 73, 69, 86, 2, 193, 193, 11, 3, 73, 66, 66, 2, + 41, 8, 76, 65, 67, 69, 77, 69, 78, 84, 2, 17, 2, 32, 67, 2, 193, 214, 10, + 5, 72, 65, 82, 65, 67, 8, 32, 2, 84, 82, 231, 254, 6, 80, 6, 152, 138, 8, + 16, 73, 67, 84, 69, 68, 32, 76, 69, 70, 84, 32, 69, 78, 84, 82, 89, 135, + 245, 3, 79, 6, 242, 249, 10, 83, 194, 106, 76, 31, 82, 70, 64, 4, 69, 82, + 83, 69, 197, 246, 3, 6, 79, 76, 86, 73, 78, 71, 68, 30, 32, 169, 3, 2, + 68, 32, 20, 184, 1, 6, 67, 72, 69, 67, 75, 69, 28, 2, 76, 73, 108, 7, 83, + 79, 76, 73, 68, 85, 83, 232, 229, 7, 16, 84, 73, 76, 68, 69, 32, 79, 80, + 69, 82, 65, 84, 79, 82, 32, 65, 195, 253, 2, 73, 2, 197, 243, 10, 2, 82, + 32, 4, 152, 212, 3, 18, 71, 72, 84, 32, 70, 79, 85, 82, 32, 80, 79, 73, + 78, 84, 69, 68, 32, 80, 135, 237, 1, 78, 9, 11, 32, 6, 240, 166, 5, 9, + 80, 82, 69, 67, 69, 68, 73, 78, 71, 166, 161, 3, 79, 251, 154, 1, 87, 48, + 248, 2, 5, 65, 78, 71, 76, 69, 20, 7, 68, 79, 85, 66, 76, 69, 32, 118, + 78, 20, 5, 70, 79, 82, 75, 69, 70, 80, 82, 82, 214, 1, 83, 106, 84, 236, + 238, 6, 30, 72, 65, 78, 68, 32, 87, 73, 84, 72, 32, 77, 73, 68, 68, 76, + 69, 32, 70, 73, 78, 71, 69, 82, 32, 69, 88, 84, 69, 78, 68, 198, 190, 2, + 67, 114, 81, 180, 102, 6, 69, 77, 80, 84, 89, 32, 253, 93, 7, 86, 73, 67, + 84, 79, 82, 89, 5, 247, 231, 3, 32, 6, 40, 3, 80, 82, 73, 41, 3, 83, 84, + 82, 4, 17, 2, 77, 69, 5, 195, 184, 3, 32, 2, 29, 5, 79, 75, 69, 32, 78, + 2, 155, 187, 6, 79, 2, 49, 10, 68, 32, 80, 65, 82, 65, 71, 82, 65, 80, 2, + 179, 4, 72, 4, 36, 3, 73, 76, 67, 239, 235, 10, 82, 2, 11, 82, 2, 217, + 254, 10, 2, 79, 87, 6, 156, 1, 17, 65, 73, 83, 69, 68, 32, 72, 65, 78, + 68, 32, 87, 73, 84, 72, 32, 70, 148, 107, 8, 79, 84, 65, 84, 69, 68, 32, + 70, 253, 176, 6, 4, 73, 71, 72, 84, 2, 209, 112, 9, 73, 78, 71, 69, 82, + 83, 32, 83, 80, 4, 156, 134, 1, 17, 65, 78, 83, 45, 83, 69, 82, 73, 70, + 32, 67, 65, 80, 73, 84, 65, 76, 191, 174, 7, 69, 10, 88, 4, 73, 76, 68, + 69, 28, 7, 82, 73, 80, 76, 69, 32, 80, 225, 160, 7, 3, 72, 85, 77, 5, + 237, 235, 4, 2, 32, 69, 2, 143, 232, 10, 82, 2, 11, 82, 2, 143, 196, 11, + 79, 147, 4, 228, 1, 4, 66, 66, 79, 78, 152, 1, 3, 67, 69, 32, 60, 3, 71, + 72, 84, 188, 81, 2, 78, 71, 252, 1, 23, 83, 73, 78, 71, 32, 68, 73, 65, + 71, 79, 78, 65, 76, 32, 67, 82, 79, 83, 83, 73, 78, 71, 32, 198, 222, 5, + 65, 227, 165, 4, 70, 19, 37, 7, 32, 65, 82, 82, 79, 87, 32, 16, 88, 3, + 76, 69, 70, 0, 4, 82, 73, 71, 72, 178, 197, 4, 85, 161, 142, 7, 3, 68, + 79, 87, 4, 207, 252, 1, 84, 4, 26, 67, 135, 244, 9, 66, 2, 157, 145, 1, + 3, 82, 65, 67, 224, 3, 110, 32, 190, 36, 45, 152, 12, 11, 72, 65, 78, 68, + 32, 73, 78, 84, 69, 82, 73, 29, 6, 87, 65, 82, 68, 83, 32, 202, 1, 166, + 2, 65, 132, 6, 2, 66, 76, 62, 67, 184, 1, 2, 68, 79, 242, 1, 70, 60, 2, + 72, 65, 176, 5, 13, 74, 85, 83, 84, 73, 70, 73, 69, 68, 32, 76, 69, 70, + 20, 2, 76, 79, 66, 78, 82, 79, 122, 80, 148, 1, 2, 82, 65, 58, 83, 154, + 6, 84, 160, 5, 9, 86, 69, 82, 84, 73, 67, 65, 76, 32, 147, 1, 87, 28, 22, + 78, 163, 4, 82, 22, 24, 2, 68, 32, 39, 71, 4, 170, 50, 76, 21, 3, 85, 80, + 80, 18, 26, 69, 17, 2, 76, 69, 2, 203, 26, 82, 17, 11, 32, 14, 154, 1, + 66, 44, 8, 68, 79, 84, 84, 69, 68, 32, 83, 2, 83, 112, 5, 87, 73, 84, 72, + 32, 189, 212, 10, 12, 86, 65, 82, 73, 65, 78, 84, 32, 87, 73, 84, 72, 4, + 173, 210, 10, 6, 82, 65, 67, 75, 69, 84, 2, 37, 7, 85, 66, 83, 84, 73, + 84, 85, 2, 25, 4, 84, 73, 79, 78, 2, 21, 3, 32, 77, 65, 2, 171, 138, 1, + 82, 4, 68, 11, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 90, 139, 247, 8, + 65, 2, 141, 218, 10, 5, 73, 71, 90, 65, 71, 6, 18, 67, 79, 82, 2, 41, 8, + 32, 71, 82, 69, 65, 84, 69, 82, 2, 249, 24, 4, 45, 84, 72, 65, 4, 41, 8, + 79, 87, 32, 87, 73, 84, 72, 32, 4, 144, 234, 7, 7, 67, 73, 82, 67, 76, + 69, 68, 207, 182, 2, 83, 4, 25, 4, 65, 67, 75, 32, 4, 130, 27, 76, 223, + 218, 7, 84, 12, 38, 85, 166, 26, 79, 243, 235, 2, 69, 8, 53, 11, 82, 76, + 89, 32, 66, 82, 65, 67, 75, 69, 84, 9, 11, 32, 6, 44, 4, 77, 73, 68, 68, + 250, 10, 76, 27, 85, 2, 221, 186, 10, 2, 76, 69, 12, 38, 84, 41, 5, 85, + 66, 76, 69, 32, 2, 137, 17, 6, 84, 69, 68, 32, 83, 85, 10, 50, 65, 94, + 87, 214, 162, 3, 81, 199, 199, 4, 80, 4, 162, 31, 78, 173, 161, 3, 15, + 82, 82, 79, 87, 32, 87, 73, 84, 72, 32, 82, 79, 85, 78, 68, 2, 139, 24, + 73, 6, 26, 73, 155, 131, 3, 76, 4, 238, 215, 8, 86, 191, 97, 83, 28, 32, + 3, 76, 70, 32, 187, 4, 78, 26, 128, 1, 8, 65, 78, 68, 32, 76, 69, 70, 84, + 62, 66, 90, 70, 82, 72, 50, 82, 58, 84, 70, 87, 246, 13, 76, 22, 85, 175, + 227, 8, 77, 2, 29, 5, 32, 72, 65, 76, 70, 2, 201, 217, 8, 2, 32, 87, 6, + 11, 76, 6, 40, 4, 65, 67, 75, 32, 183, 188, 10, 79, 4, 158, 154, 10, 67, + 207, 11, 83, 4, 58, 79, 237, 156, 3, 8, 76, 89, 73, 78, 71, 32, 83, 65, + 2, 131, 202, 9, 76, 2, 209, 216, 8, 7, 79, 82, 73, 90, 79, 78, 84, 2, 33, + 6, 85, 78, 78, 73, 78, 71, 2, 203, 238, 6, 32, 2, 153, 173, 5, 12, 82, + 73, 80, 76, 69, 32, 68, 65, 83, 72, 32, 72, 2, 209, 167, 10, 4, 72, 73, + 84, 69, 2, 173, 152, 1, 16, 68, 32, 84, 69, 76, 69, 80, 72, 79, 78, 69, + 32, 82, 69, 67, 69, 4, 187, 231, 7, 84, 2, 145, 152, 11, 11, 87, 32, 80, + 65, 82, 65, 80, 72, 82, 65, 83, 2, 177, 4, 16, 79, 82, 77, 65, 76, 32, + 70, 65, 67, 84, 79, 82, 32, 83, 69, 77, 8, 74, 85, 166, 221, 8, 78, 225, + 189, 1, 8, 80, 69, 78, 32, 83, 81, 85, 65, 2, 221, 233, 10, 6, 84, 69, + 82, 32, 74, 79, 8, 49, 10, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 9, 11, + 32, 6, 34, 76, 26, 85, 255, 196, 9, 69, 2, 157, 37, 2, 79, 87, 2, 133, + 37, 2, 80, 80, 2, 217, 10, 10, 73, 83, 69, 68, 32, 79, 77, 73, 83, 83, + 40, 62, 45, 70, 69, 78, 73, 68, 2, 80, 69, 126, 81, 227, 2, 85, 2, 173, + 128, 8, 12, 83, 72, 65, 80, 69, 68, 32, 66, 65, 71, 32, 68, 4, 26, 77, + 191, 236, 8, 86, 2, 217, 212, 10, 7, 73, 68, 73, 82, 69, 67, 84, 4, 210, + 150, 3, 78, 169, 252, 7, 8, 68, 69, 87, 65, 89, 83, 32, 85, 8, 32, 4, 65, + 75, 69, 82, 67, 69, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 246, 252, 3, 79, + 55, 84, 2, 137, 5, 2, 67, 72, 20, 57, 12, 85, 65, 82, 69, 32, 66, 82, 65, + 67, 75, 69, 84, 21, 11, 32, 18, 84, 3, 76, 79, 87, 0, 3, 85, 80, 80, 28, + 5, 87, 73, 84, 72, 32, 227, 191, 9, 69, 2, 245, 230, 3, 2, 69, 82, 12, + 96, 8, 84, 73, 67, 75, 32, 73, 78, 32, 230, 6, 81, 166, 236, 7, 85, 134, + 126, 68, 135, 193, 2, 83, 4, 244, 229, 3, 6, 66, 79, 84, 84, 79, 77, 1, + 3, 84, 79, 80, 2, 165, 4, 6, 66, 83, 84, 73, 84, 85, 26, 54, 72, 130, 3, + 82, 130, 223, 7, 79, 235, 204, 2, 65, 14, 62, 73, 116, 5, 79, 85, 71, 72, + 84, 45, 4, 82, 69, 69, 32, 4, 21, 3, 82, 68, 32, 4, 68, 4, 73, 78, 68, + 85, 221, 211, 1, 7, 87, 72, 73, 84, 69, 32, 82, 2, 215, 166, 11, 67, 2, + 11, 32, 2, 213, 136, 3, 3, 66, 85, 66, 8, 60, 9, 81, 85, 65, 82, 84, 69, + 82, 83, 32, 151, 230, 8, 69, 6, 34, 76, 22, 85, 139, 236, 8, 66, 2, 37, + 2, 79, 87, 2, 17, 2, 80, 80, 2, 227, 230, 8, 69, 8, 34, 65, 89, 4, 73, + 65, 78, 71, 2, 33, 6, 78, 83, 80, 79, 83, 73, 2, 11, 84, 2, 17, 2, 73, + 79, 2, 147, 138, 11, 78, 6, 32, 2, 76, 69, 159, 229, 8, 85, 5, 41, 8, 32, + 65, 66, 79, 86, 69, 32, 76, 2, 181, 178, 9, 2, 69, 70, 6, 18, 66, 95, 82, + 4, 68, 9, 65, 82, 32, 87, 73, 84, 72, 32, 81, 213, 191, 10, 2, 79, 88, 2, + 211, 223, 8, 85, 2, 189, 188, 9, 3, 85, 76, 69, 14, 22, 72, 203, 1, 73, + 12, 25, 4, 73, 84, 69, 32, 12, 54, 67, 54, 76, 206, 210, 7, 80, 238, 7, + 83, 39, 84, 4, 26, 79, 163, 207, 7, 85, 2, 65, 3, 82, 78, 69, 2, 41, 8, + 69, 78, 84, 73, 67, 85, 76, 65, 2, 183, 134, 11, 82, 2, 225, 199, 6, 6, + 71, 71, 76, 89, 32, 70, 62, 118, 70, 226, 2, 72, 128, 1, 9, 80, 79, 73, + 78, 84, 73, 78, 71, 32, 214, 4, 83, 197, 1, 6, 84, 79, 45, 76, 69, 70, + 18, 33, 6, 65, 67, 73, 78, 71, 32, 18, 116, 14, 65, 82, 77, 69, 78, 73, + 65, 78, 32, 69, 84, 69, 82, 78, 20, 4, 66, 65, 83, 83, 16, 3, 70, 73, 83, + 87, 83, 2, 255, 159, 8, 73, 2, 175, 43, 73, 6, 26, 72, 151, 214, 11, 84, + 5, 11, 32, 2, 233, 176, 8, 6, 87, 73, 84, 72, 32, 79, 8, 140, 208, 3, 10, + 86, 65, 83, 84, 73, 32, 83, 73, 71, 78, 195, 223, 4, 78, 2, 81, 18, 65, + 78, 68, 69, 68, 32, 73, 78, 84, 69, 82, 76, 65, 67, 69, 68, 32, 80, 2, + 21, 3, 69, 78, 84, 2, 251, 150, 10, 65, 30, 90, 65, 30, 67, 94, 68, 58, + 77, 58, 82, 182, 1, 83, 74, 84, 210, 172, 8, 69, 179, 124, 71, 4, 90, 78, + 159, 175, 8, 84, 2, 29, 5, 85, 82, 86, 69, 68, 2, 17, 2, 32, 65, 2, 11, + 78, 2, 217, 255, 10, 2, 71, 76, 4, 136, 131, 3, 5, 79, 85, 66, 76, 69, + 179, 188, 6, 73, 2, 165, 184, 10, 9, 65, 71, 78, 73, 70, 89, 73, 78, 71, + 10, 38, 79, 154, 178, 9, 65, 235, 29, 73, 6, 92, 5, 67, 75, 69, 84, 32, + 213, 177, 9, 12, 76, 76, 69, 82, 32, 67, 79, 65, 83, 84, 69, 82, 4, 176, + 43, 3, 66, 79, 79, 143, 208, 10, 83, 2, 11, 84, 2, 21, 3, 73, 67, 75, 2, + 185, 187, 6, 4, 32, 70, 73, 71, 2, 239, 234, 7, 65, 4, 46, 72, 85, 7, 73, + 68, 69, 32, 65, 82, 67, 2, 17, 2, 65, 68, 2, 17, 2, 69, 68, 2, 209, 172, + 10, 6, 32, 87, 72, 73, 84, 69, 2, 11, 32, 2, 201, 239, 8, 8, 67, 76, 79, + 67, 75, 87, 73, 83, 8, 17, 2, 84, 32, 8, 86, 73, 40, 4, 79, 86, 69, 82, + 176, 134, 5, 5, 69, 77, 66, 69, 68, 139, 133, 6, 77, 2, 17, 2, 83, 79, 2, + 131, 135, 1, 76, 2, 135, 155, 3, 82, 2, 141, 187, 10, 2, 79, 82, 214, 1, + 160, 1, 5, 65, 82, 82, 79, 87, 130, 9, 66, 86, 68, 210, 1, 70, 122, 72, + 178, 6, 76, 26, 79, 34, 80, 50, 82, 70, 83, 94, 84, 206, 8, 87, 202, 197, + 8, 67, 47, 81, 75, 26, 32, 195, 147, 9, 45, 70, 94, 65, 170, 2, 70, 110, + 84, 184, 1, 5, 87, 73, 84, 72, 32, 129, 160, 1, 4, 79, 86, 69, 82, 12, + 40, 5, 66, 79, 86, 69, 32, 143, 1, 78, 10, 70, 82, 216, 163, 1, 5, 83, + 72, 79, 82, 84, 222, 194, 3, 65, 55, 84, 4, 37, 7, 69, 86, 69, 82, 83, + 69, 32, 4, 138, 230, 4, 65, 55, 84, 2, 61, 13, 68, 32, 85, 80, 80, 69, + 82, 32, 65, 78, 68, 32, 76, 2, 17, 2, 79, 87, 2, 129, 213, 8, 2, 69, 82, + 6, 25, 4, 82, 79, 77, 32, 6, 36, 3, 66, 65, 82, 187, 213, 8, 68, 5, 189, + 1, 6, 32, 84, 79, 32, 66, 76, 10, 56, 7, 72, 82, 79, 85, 71, 72, 32, 65, + 3, 79, 32, 66, 6, 224, 224, 4, 3, 83, 85, 80, 234, 207, 4, 71, 247, 149, + 2, 88, 4, 26, 76, 139, 141, 11, 65, 2, 153, 247, 9, 3, 65, 67, 75, 40, + 140, 1, 6, 67, 79, 82, 78, 69, 82, 26, 68, 98, 76, 86, 80, 30, 83, 38, + 84, 138, 210, 8, 77, 38, 78, 122, 69, 150, 153, 1, 72, 171, 165, 1, 86, + 2, 209, 18, 2, 32, 68, 4, 11, 79, 4, 40, 4, 84, 84, 69, 68, 203, 219, 7, + 85, 2, 17, 2, 32, 83, 2, 163, 177, 11, 84, 6, 26, 79, 231, 210, 8, 65, 4, + 26, 87, 251, 194, 11, 79, 2, 157, 201, 3, 2, 69, 82, 2, 193, 145, 9, 2, + 76, 85, 6, 146, 211, 8, 77, 203, 191, 2, 84, 10, 154, 16, 73, 171, 3, 65, + 8, 58, 65, 204, 11, 5, 79, 84, 84, 79, 77, 187, 199, 8, 76, 2, 145, 2, 2, + 67, 75, 14, 48, 6, 79, 85, 66, 76, 69, 32, 167, 225, 8, 65, 12, 40, 5, + 65, 82, 82, 79, 87, 211, 18, 68, 11, 26, 32, 143, 137, 9, 45, 6, 26, 87, + 167, 215, 8, 70, 4, 25, 4, 73, 84, 72, 32, 4, 186, 143, 11, 86, 79, 83, + 4, 40, 4, 82, 79, 78, 84, 195, 210, 8, 73, 2, 193, 209, 8, 14, 45, 84, + 73, 76, 84, 69, 68, 32, 83, 72, 65, 68, 79, 87, 30, 26, 65, 251, 213, 8, + 69, 26, 48, 6, 82, 80, 79, 79, 78, 32, 131, 248, 10, 78, 24, 80, 10, 87, + 73, 84, 72, 32, 66, 65, 82, 66, 32, 197, 152, 1, 4, 79, 86, 69, 82, 22, + 44, 4, 68, 79, 87, 78, 173, 1, 2, 85, 80, 10, 26, 32, 231, 219, 8, 87, 8, + 76, 8, 65, 66, 79, 86, 69, 32, 76, 69, 18, 66, 166, 211, 8, 70, 179, 5, + 84, 2, 227, 2, 70, 2, 253, 222, 4, 7, 69, 76, 79, 87, 32, 76, 79, 12, 26, + 32, 187, 218, 8, 87, 10, 60, 6, 65, 66, 79, 86, 69, 32, 154, 210, 8, 70, + 179, 5, 84, 6, 22, 76, 155, 1, 82, 4, 32, 2, 69, 70, 187, 221, 4, 79, 2, + 213, 144, 2, 24, 84, 87, 65, 82, 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, + 32, 87, 73, 84, 72, 32, 66, 65, 82, 66, 2, 21, 3, 73, 71, 72, 2, 105, 24, + 84, 87, 65, 82, 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, + 72, 32, 66, 65, 82, 66, 2, 11, 32, 2, 139, 241, 1, 68, 2, 141, 1, 2, 69, + 70, 2, 201, 212, 8, 3, 80, 69, 78, 4, 202, 216, 8, 65, 233, 206, 1, 3, + 85, 83, 72, 4, 36, 3, 73, 71, 72, 223, 228, 10, 79, 2, 11, 84, 2, 171, 1, + 45, 6, 32, 2, 81, 85, 215, 207, 8, 65, 4, 26, 73, 239, 207, 8, 65, 2, + 229, 215, 8, 2, 71, 71, 54, 38, 79, 60, 2, 82, 73, 227, 4, 87, 2, 11, 80, + 2, 11, 32, 2, 253, 199, 8, 4, 83, 72, 65, 68, 34, 40, 5, 65, 78, 71, 76, + 69, 255, 3, 80, 30, 56, 8, 45, 72, 69, 65, 68, 69, 68, 32, 251, 219, 8, + 32, 28, 52, 5, 65, 82, 82, 79, 87, 202, 212, 8, 68, 39, 80, 25, 11, 32, + 22, 64, 8, 79, 86, 69, 82, 32, 76, 69, 70, 22, 87, 135, 208, 8, 84, 2, + 183, 207, 8, 84, 18, 25, 4, 73, 84, 72, 32, 18, 128, 1, 7, 68, 79, 85, + 66, 76, 69, 32, 36, 7, 76, 79, 78, 71, 32, 84, 73, 230, 207, 8, 66, 158, + 1, 77, 34, 78, 34, 86, 35, 72, 4, 166, 138, 9, 72, 195, 247, 1, 86, 4, + 11, 80, 4, 11, 32, 4, 18, 68, 35, 85, 2, 181, 208, 8, 3, 79, 87, 78, 2, + 151, 208, 8, 80, 4, 21, 3, 76, 69, 32, 4, 138, 3, 68, 203, 145, 10, 65, + 18, 11, 79, 18, 56, 8, 45, 72, 69, 65, 68, 69, 68, 32, 175, 210, 8, 32, + 16, 76, 6, 65, 82, 82, 79, 87, 32, 213, 1, 8, 84, 82, 73, 80, 76, 69, 32, + 68, 14, 44, 5, 87, 73, 84, 72, 32, 179, 198, 8, 70, 12, 42, 84, 210, 198, + 7, 68, 235, 183, 3, 86, 8, 26, 65, 243, 209, 8, 82, 6, 17, 2, 73, 76, 7, + 33, 6, 32, 87, 73, 84, 72, 32, 4, 250, 197, 7, 68, 235, 183, 3, 86, 2, + 249, 132, 1, 2, 65, 83, 8, 58, 65, 21, 10, 72, 73, 84, 69, 32, 65, 82, + 82, 79, 87, 2, 207, 206, 8, 86, 7, 11, 32, 4, 216, 193, 2, 4, 70, 82, 79, + 77, 219, 145, 6, 87, 19, 66, 32, 136, 1, 6, 69, 68, 32, 80, 76, 65, 21, + 3, 73, 78, 71, 12, 82, 66, 22, 80, 212, 201, 4, 2, 73, 78, 26, 69, 154, + 158, 3, 79, 195, 198, 2, 65, 2, 239, 153, 11, 85, 2, 11, 79, 2, 135, 232, + 10, 73, 2, 247, 245, 10, 78, 2, 209, 199, 3, 2, 32, 66, 4, 24, 2, 70, 65, + 75, 83, 2, 17, 2, 76, 76, 2, 21, 3, 73, 78, 71, 2, 177, 231, 1, 2, 32, + 68, 2, 189, 173, 3, 2, 79, 85, 8, 222, 169, 11, 69, 2, 73, 2, 77, 3, 79, + 126, 136, 2, 2, 67, 75, 20, 2, 76, 76, 188, 2, 4, 77, 65, 78, 32, 194, 8, + 79, 80, 2, 83, 69, 20, 6, 84, 65, 84, 69, 68, 32, 152, 3, 3, 85, 78, 68, + 170, 178, 3, 87, 252, 213, 3, 15, 65, 83, 84, 69, 68, 32, 83, 87, 69, 69, + 84, 32, 80, 79, 84, 185, 166, 2, 2, 66, 79, 5, 251, 138, 11, 69, 10, 130, + 1, 69, 64, 4, 32, 79, 70, 32, 101, 21, 73, 78, 71, 32, 79, 78, 32, 84, + 72, 69, 32, 70, 76, 79, 79, 82, 32, 76, 65, 85, 71, 6, 60, 9, 68, 45, 85, + 80, 32, 78, 69, 87, 83, 33, 2, 82, 32, 2, 11, 80, 2, 175, 131, 2, 65, 4, + 28, 3, 67, 79, 65, 23, 83, 2, 131, 235, 9, 83, 2, 135, 95, 75, 2, 231, + 211, 10, 72, 72, 140, 1, 6, 67, 69, 78, 84, 85, 82, 22, 68, 100, 3, 81, + 85, 73, 28, 8, 78, 85, 77, 69, 82, 65, 76, 32, 182, 4, 83, 114, 85, 135, + 235, 7, 65, 2, 159, 215, 5, 73, 6, 98, 69, 232, 5, 5, 85, 80, 79, 78, 68, + 61, 12, 73, 77, 73, 68, 73, 65, 32, 83, 69, 88, 84, 85, 2, 229, 5, 3, 78, + 65, 82, 48, 142, 1, 70, 136, 1, 3, 79, 78, 69, 134, 1, 83, 66, 84, 232, + 14, 10, 82, 69, 86, 69, 82, 83, 69, 68, 32, 79, 150, 237, 2, 69, 163, + 135, 7, 78, 14, 26, 73, 183, 168, 10, 79, 12, 36, 3, 70, 84, 89, 255, + 254, 2, 86, 7, 11, 32, 4, 194, 196, 5, 84, 177, 221, 4, 5, 69, 65, 82, + 76, 89, 11, 11, 32, 8, 50, 72, 41, 8, 84, 72, 79, 85, 83, 65, 78, 68, 4, + 185, 1, 6, 85, 78, 68, 82, 69, 68, 5, 141, 130, 4, 2, 32, 67, 6, 32, 2, + 73, 88, 159, 172, 9, 69, 5, 241, 159, 10, 2, 32, 76, 10, 42, 69, 150, + 253, 2, 87, 239, 174, 6, 72, 4, 11, 78, 5, 11, 32, 2, 131, 194, 5, 84, + 10, 46, 69, 189, 200, 7, 5, 73, 76, 73, 81, 85, 8, 60, 2, 77, 85, 40, 5, + 83, 84, 69, 82, 84, 21, 2, 88, 84, 2, 17, 2, 78, 67, 2, 231, 199, 7, 73, + 2, 207, 234, 7, 73, 4, 18, 65, 23, 85, 2, 179, 234, 7, 78, 2, 151, 199, + 7, 76, 4, 48, 6, 84, 32, 86, 69, 71, 69, 219, 225, 9, 83, 2, 141, 197, 2, + 2, 84, 65, 5, 179, 210, 9, 84, 10, 166, 2, 70, 32, 11, 72, 69, 65, 86, + 89, 32, 66, 76, 65, 67, 75, 52, 24, 76, 73, 71, 72, 84, 32, 70, 79, 85, + 82, 32, 80, 79, 73, 78, 84, 69, 68, 32, 66, 76, 65, 67, 75, 0, 18, 87, + 72, 73, 84, 69, 32, 70, 79, 85, 82, 32, 80, 79, 73, 78, 84, 69, 68, 161, + 53, 8, 67, 65, 80, 73, 84, 65, 76, 32, 2, 29, 5, 76, 79, 82, 65, 76, 2, + 201, 182, 9, 8, 32, 72, 69, 65, 82, 84, 32, 66, 2, 213, 207, 9, 2, 32, + 67, 16, 74, 32, 89, 14, 69, 68, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, + 82, 32, 4, 24, 2, 80, 85, 43, 84, 2, 11, 83, 2, 209, 151, 10, 2, 72, 80, + 2, 147, 222, 3, 65, 12, 68, 2, 83, 72, 238, 162, 6, 67, 222, 206, 4, 70, + 2, 76, 147, 17, 88, 4, 40, 4, 85, 65, 78, 71, 159, 241, 10, 79, 2, 171, + 130, 11, 88, 136, 2, 226, 1, 66, 20, 3, 71, 66, 89, 40, 5, 76, 69, 45, + 68, 69, 40, 3, 77, 73, 32, 154, 5, 78, 156, 26, 26, 83, 83, 73, 65, 78, + 32, 65, 83, 84, 82, 79, 76, 79, 71, 73, 67, 65, 76, 32, 83, 89, 77, 66, + 79, 76, 32, 203, 152, 5, 80, 2, 255, 243, 8, 76, 2, 177, 137, 9, 5, 32, + 70, 79, 79, 84, 2, 11, 76, 2, 165, 255, 5, 2, 65, 89, 62, 68, 9, 70, 82, + 65, 67, 84, 73, 79, 78, 32, 102, 78, 171, 198, 2, 68, 8, 40, 4, 79, 78, + 69, 32, 187, 175, 9, 84, 6, 34, 84, 250, 139, 9, 72, 47, 81, 2, 167, 141, + 9, 72, 36, 33, 6, 85, 77, 66, 69, 82, 32, 36, 76, 5, 69, 73, 71, 72, 84, + 38, 70, 92, 2, 78, 73, 22, 79, 18, 83, 83, 84, 4, 158, 137, 3, 32, 231, + 135, 8, 89, 8, 18, 73, 35, 79, 4, 130, 2, 86, 235, 158, 9, 70, 4, 136, 2, + 2, 85, 82, 195, 158, 9, 82, 4, 77, 2, 78, 69, 2, 167, 1, 78, 8, 40, 4, + 69, 86, 69, 78, 1, 2, 73, 88, 4, 206, 135, 3, 32, 159, 246, 7, 84, 10, + 34, 72, 50, 87, 223, 190, 10, 69, 4, 32, 2, 82, 69, 199, 158, 9, 73, 2, + 39, 69, 4, 26, 79, 183, 158, 9, 69, 2, 187, 134, 3, 32, 182, 1, 32, 3, + 73, 67, 32, 147, 25, 78, 178, 1, 220, 1, 6, 66, 69, 76, 71, 84, 72, 20, + 4, 67, 82, 79, 83, 20, 7, 76, 69, 84, 84, 69, 82, 32, 210, 22, 83, 24, 6, + 77, 85, 76, 84, 73, 80, 216, 196, 7, 5, 65, 82, 76, 65, 85, 161, 202, 1, + 7, 84, 86, 73, 77, 65, 68, 85, 2, 135, 166, 9, 79, 2, 235, 197, 7, 83, + 166, 1, 202, 4, 65, 110, 67, 98, 68, 126, 69, 82, 70, 222, 1, 71, 104, 2, + 72, 65, 50, 73, 220, 1, 5, 74, 69, 82, 65, 78, 34, 75, 58, 76, 234, 1, + 79, 128, 1, 13, 82, 65, 73, 68, 79, 32, 82, 65, 68, 32, 82, 69, 73, 34, + 83, 176, 2, 16, 66, 69, 82, 75, 65, 78, 65, 78, 32, 66, 69, 79, 82, 67, + 32, 66, 144, 1, 12, 78, 65, 85, 68, 73, 90, 32, 78, 89, 68, 32, 78, 110, + 84, 194, 1, 87, 128, 91, 7, 85, 82, 85, 90, 32, 85, 82, 196, 189, 2, 10, + 77, 65, 78, 78, 65, 90, 32, 77, 65, 78, 168, 63, 13, 80, 69, 82, 84, 72, + 79, 32, 80, 69, 79, 82, 84, 72, 206, 199, 3, 89, 158, 214, 3, 81, 2, 86, + 2, 88, 3, 90, 8, 222, 4, 69, 174, 185, 6, 67, 0, 4, 78, 83, 85, 90, 189, + 186, 3, 9, 76, 71, 73, 90, 32, 69, 79, 76, 72, 11, 46, 69, 30, 65, 245, + 152, 7, 3, 87, 69, 79, 4, 26, 65, 211, 133, 11, 78, 2, 191, 219, 9, 76, + 11, 84, 6, 79, 84, 84, 69, 68, 45, 193, 231, 3, 9, 65, 71, 65, 90, 32, + 68, 65, 69, 71, 6, 226, 132, 11, 76, 2, 78, 3, 80, 11, 136, 76, 7, 72, + 87, 65, 90, 32, 69, 72, 218, 255, 9, 65, 206, 55, 84, 63, 78, 12, 120, + 13, 82, 65, 78, 75, 83, 32, 67, 65, 83, 75, 69, 84, 32, 145, 180, 7, 11, + 69, 72, 85, 32, 70, 69, 79, 72, 32, 70, 69, 10, 46, 65, 234, 196, 10, 73, + 2, 79, 207, 60, 69, 4, 26, 69, 171, 130, 11, 67, 2, 151, 216, 9, 83, 9, + 26, 69, 159, 201, 10, 65, 4, 52, 7, 66, 79, 32, 71, 89, 70, 85, 195, 129, + 11, 82, 2, 235, 128, 11, 32, 4, 236, 8, 2, 69, 71, 13, 4, 71, 76, 65, 90, + 12, 156, 1, 2, 78, 71, 20, 9, 83, 65, 90, 32, 73, 83, 32, 73, 83, 20, 5, + 87, 65, 90, 32, 69, 216, 198, 10, 10, 67, 69, 76, 65, 78, 68, 73, 67, 45, + 89, 3, 79, 5, 199, 211, 6, 87, 2, 183, 191, 10, 83, 2, 163, 254, 10, 79, + 2, 11, 32, 2, 147, 255, 10, 74, 7, 21, 3, 65, 85, 78, 4, 206, 251, 10, + 32, 155, 3, 65, 12, 120, 15, 65, 85, 75, 65, 90, 32, 76, 65, 71, 85, 32, + 76, 79, 71, 82, 21, 11, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 2, + 251, 241, 9, 32, 10, 64, 3, 65, 82, 32, 158, 4, 72, 62, 77, 66, 79, 131, + 191, 10, 89, 2, 159, 230, 10, 65, 15, 150, 5, 83, 0, 12, 84, 72, 65, 76, + 65, 78, 32, 69, 84, 72, 69, 76, 188, 247, 10, 4, 80, 69, 78, 45, 14, 69, + 2, 78, 3, 79, 2, 11, 68, 2, 247, 194, 10, 32, 26, 150, 1, 72, 244, 2, 18, + 73, 71, 69, 76, 32, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 83, + 208, 253, 6, 5, 79, 87, 73, 76, 79, 203, 173, 2, 84, 21, 45, 9, 79, 82, + 84, 45, 84, 87, 73, 71, 45, 18, 102, 66, 58, 72, 62, 77, 30, 78, 38, 79, + 42, 83, 186, 1, 84, 128, 173, 6, 2, 65, 82, 163, 144, 4, 89, 2, 33, 6, + 74, 65, 82, 75, 65, 78, 2, 243, 186, 9, 32, 2, 25, 4, 65, 71, 65, 76, 2, + 11, 76, 2, 159, 247, 10, 32, 2, 253, 154, 3, 2, 65, 68, 2, 157, 168, 10, + 4, 65, 85, 68, 32, 2, 17, 2, 83, 83, 2, 211, 216, 10, 32, 2, 11, 79, 2, + 195, 253, 6, 76, 4, 116, 15, 72, 85, 82, 73, 83, 65, 90, 32, 84, 72, 85, + 82, 83, 32, 84, 33, 10, 73, 87, 65, 90, 32, 84, 73, 82, 32, 84, 2, 11, + 72, 2, 171, 227, 5, 79, 2, 17, 2, 89, 82, 2, 187, 217, 10, 32, 5, 41, 8, + 85, 78, 74, 79, 32, 87, 89, 78, 2, 11, 78, 2, 251, 246, 9, 32, 2, 21, 3, + 73, 78, 71, 2, 237, 174, 7, 2, 76, 69, 4, 188, 137, 9, 16, 73, 78, 71, + 32, 83, 72, 73, 82, 84, 32, 87, 73, 84, 72, 32, 83, 187, 178, 1, 69, 12, + 120, 3, 66, 73, 78, 2, 78, 28, 2, 81, 85, 0, 3, 86, 73, 71, 174, 160, 7, + 83, 229, 169, 1, 6, 84, 82, 69, 68, 69, 67, 2, 169, 202, 8, 2, 79, 86, 2, + 129, 202, 8, 2, 73, 78, 200, 40, 244, 1, 2, 32, 73, 22, 65, 162, 26, 67, + 138, 5, 69, 166, 11, 72, 242, 36, 73, 162, 233, 1, 75, 154, 2, 76, 142, + 9, 77, 166, 21, 78, 190, 2, 79, 158, 39, 80, 172, 12, 2, 81, 85, 138, 70, + 83, 38, 84, 138, 17, 85, 150, 43, 87, 186, 1, 89, 247, 178, 5, 71, 2, + 183, 201, 9, 78, 198, 2, 132, 2, 5, 70, 69, 84, 89, 32, 36, 4, 71, 73, + 84, 84, 30, 76, 112, 8, 77, 65, 82, 73, 84, 65, 78, 32, 146, 14, 78, 190, + 3, 84, 102, 85, 204, 244, 2, 2, 73, 76, 242, 91, 88, 144, 148, 6, 15, 75, + 69, 32, 66, 79, 84, 84, 76, 69, 32, 65, 78, 68, 32, 67, 159, 98, 82, 4, + 254, 251, 6, 86, 207, 242, 2, 80, 2, 201, 213, 3, 2, 65, 82, 6, 18, 84, + 75, 85, 4, 36, 3, 32, 83, 72, 235, 202, 9, 73, 2, 11, 65, 2, 171, 175, + 10, 75, 2, 227, 228, 9, 84, 122, 184, 1, 7, 76, 69, 84, 84, 69, 82, 32, + 198, 3, 77, 248, 2, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, + 136, 4, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 203, 159, 4, 65, + 44, 202, 1, 66, 32, 2, 68, 65, 22, 73, 38, 75, 22, 76, 34, 83, 46, 84, + 182, 2, 65, 212, 231, 5, 2, 71, 65, 222, 153, 1, 82, 202, 142, 2, 90, + 182, 83, 77, 172, 1, 2, 81, 85, 118, 78, 226, 6, 89, 251, 101, 70, 4, + 186, 205, 10, 73, 247, 25, 65, 2, 151, 224, 9, 76, 6, 178, 233, 10, 78, + 2, 84, 3, 89, 2, 223, 231, 9, 65, 2, 11, 65, 2, 191, 223, 9, 66, 4, 156, + 7, 3, 73, 78, 71, 163, 149, 9, 72, 6, 254, 230, 9, 65, 134, 101, 73, 229, + 10, 5, 83, 65, 65, 68, 73, 18, 96, 4, 65, 82, 75, 32, 165, 1, 15, 79, 68, + 73, 70, 73, 69, 82, 32, 76, 69, 84, 84, 69, 82, 32, 12, 82, 68, 40, 2, + 73, 78, 90, 69, 242, 2, 78, 213, 191, 8, 5, 79, 67, 67, 76, 85, 2, 17, 2, + 65, 71, 2, 155, 251, 8, 69, 5, 17, 2, 45, 65, 2, 203, 228, 9, 76, 6, 46, + 69, 184, 6, 2, 83, 72, 131, 223, 10, 73, 2, 229, 235, 9, 11, 80, 69, 78, + 84, 72, 69, 84, 73, 67, 32, 89, 28, 130, 1, 65, 154, 1, 66, 22, 78, 30, + 83, 134, 1, 90, 250, 166, 3, 84, 156, 149, 7, 9, 77, 69, 76, 79, 68, 73, + 67, 32, 81, 3, 81, 10, 76, 3, 70, 83, 65, 34, 78, 28, 2, 84, 77, 245, + 189, 10, 4, 82, 75, 65, 65, 2, 11, 65, 2, 151, 227, 10, 81, 4, 26, 78, + 211, 206, 5, 71, 2, 11, 65, 2, 243, 189, 10, 65, 2, 165, 143, 3, 2, 69, + 81, 4, 64, 4, 72, 73, 89, 89, 45, 8, 79, 70, 32, 77, 65, 83, 72, 70, 2, + 11, 65, 2, 11, 65, 2, 155, 236, 8, 76, 2, 139, 216, 9, 65, 4, 34, 65, + 209, 235, 8, 2, 73, 81, 2, 223, 223, 9, 69, 30, 92, 5, 76, 79, 78, 71, + 32, 54, 79, 66, 83, 174, 205, 6, 65, 242, 145, 4, 69, 2, 73, 3, 85, 10, + 158, 206, 6, 65, 242, 145, 4, 69, 2, 73, 3, 85, 7, 41, 8, 86, 69, 82, 76, + 79, 78, 71, 32, 4, 191, 205, 6, 65, 4, 26, 72, 183, 219, 5, 85, 2, 129, + 150, 6, 3, 79, 82, 84, 10, 68, 8, 83, 45, 83, 69, 82, 73, 70, 32, 241, + 187, 10, 3, 68, 87, 73, 8, 44, 6, 72, 69, 65, 86, 89, 32, 139, 2, 73, 6, + 48, 3, 68, 79, 85, 81, 5, 76, 79, 87, 32, 68, 4, 11, 66, 4, 21, 3, 76, + 69, 32, 4, 84, 6, 84, 85, 82, 78, 69, 68, 23, 67, 2, 21, 3, 79, 85, 66, + 2, 17, 2, 76, 69, 2, 17, 2, 32, 67, 2, 33, 6, 79, 77, 77, 65, 32, 81, 2, + 145, 144, 9, 3, 85, 79, 84, 2, 253, 151, 10, 10, 78, 84, 69, 82, 82, 79, + 66, 65, 78, 71, 6, 48, 6, 69, 76, 76, 73, 84, 69, 143, 200, 5, 85, 5, 25, + 4, 32, 65, 78, 84, 2, 147, 160, 7, 69, 168, 1, 50, 82, 225, 141, 5, 6, + 68, 73, 32, 82, 73, 89, 166, 1, 52, 7, 65, 83, 72, 84, 82, 65, 32, 183, + 191, 4, 79, 164, 1, 180, 1, 7, 76, 69, 84, 84, 69, 82, 32, 212, 1, 5, 83, + 73, 71, 78, 32, 194, 21, 68, 176, 250, 2, 16, 67, 79, 78, 83, 79, 78, 65, + 78, 84, 32, 83, 73, 71, 78, 32, 72, 211, 155, 2, 86, 100, 154, 250, 6, + 65, 38, 68, 114, 84, 46, 86, 186, 5, 85, 206, 141, 1, 79, 238, 60, 73, + 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, + 80, 162, 7, 69, 234, 61, 72, 2, 77, 2, 82, 3, 89, 8, 218, 184, 6, 67, + 234, 216, 3, 65, 239, 1, 86, 52, 66, 65, 32, 4, 72, 79, 79, 76, 46, 79, + 74, 82, 183, 212, 10, 73, 4, 194, 191, 9, 76, 227, 20, 82, 5, 245, 191, + 5, 6, 32, 83, 65, 84, 67, 72, 6, 36, 3, 82, 80, 73, 203, 154, 9, 79, 4, + 242, 132, 10, 79, 135, 18, 85, 36, 66, 69, 72, 4, 73, 80, 84, 32, 214, + 250, 1, 85, 175, 206, 6, 79, 4, 36, 3, 87, 68, 82, 235, 131, 10, 69, 2, + 11, 73, 2, 207, 149, 10, 86, 28, 80, 8, 67, 65, 80, 73, 84, 65, 76, 32, + 86, 76, 81, 6, 83, 77, 65, 76, 76, 32, 18, 210, 210, 10, 66, 2, 69, 2, + 70, 2, 72, 2, 73, 2, 76, 2, 77, 2, 80, 3, 82, 2, 37, 7, 73, 71, 65, 84, + 85, 82, 69, 2, 11, 32, 2, 233, 141, 10, 2, 69, 84, 8, 174, 209, 10, 69, + 2, 71, 2, 76, 3, 79, 220, 1, 130, 2, 65, 30, 67, 74, 69, 36, 5, 71, 77, + 69, 78, 84, 28, 2, 77, 73, 172, 1, 8, 80, 65, 82, 65, 84, 69, 68, 32, + 138, 4, 82, 158, 1, 83, 68, 2, 84, 32, 168, 140, 5, 8, 87, 73, 78, 71, + 32, 78, 69, 69, 202, 145, 3, 88, 190, 106, 68, 233, 162, 1, 2, 76, 70, 4, + 250, 206, 10, 76, 3, 84, 6, 34, 84, 245, 226, 5, 2, 79, 78, 4, 178, 201, + 6, 73, 175, 204, 3, 79, 4, 166, 224, 1, 68, 191, 132, 1, 45, 23, 189, + 191, 4, 2, 69, 68, 6, 212, 84, 28, 68, 73, 82, 69, 67, 84, 32, 80, 82, + 79, 68, 85, 67, 84, 32, 87, 73, 84, 72, 32, 66, 79, 84, 84, 79, 77, 32, + 67, 172, 208, 7, 3, 83, 69, 88, 211, 216, 1, 67, 158, 1, 48, 6, 66, 76, + 79, 67, 75, 32, 203, 182, 9, 83, 156, 1, 88, 9, 81, 85, 65, 68, 82, 65, + 78, 84, 45, 129, 1, 8, 83, 69, 88, 84, 65, 78, 84, 45, 30, 42, 49, 38, + 50, 30, 51, 171, 202, 10, 52, 17, 34, 50, 30, 51, 171, 202, 10, 52, 9, + 26, 51, 171, 202, 10, 52, 5, 167, 202, 10, 52, 126, 58, 49, 54, 50, 46, + 51, 38, 52, 30, 53, 187, 200, 10, 54, 65, 50, 50, 46, 51, 38, 52, 30, 53, + 187, 200, 10, 54, 33, 42, 51, 38, 52, 30, 53, 187, 200, 10, 54, 17, 34, + 52, 30, 53, 187, 200, 10, 54, 9, 26, 53, 187, 200, 10, 54, 5, 183, 200, + 10, 54, 4, 120, 2, 86, 73, 129, 175, 2, 22, 73, 79, 85, 83, 32, 70, 65, + 67, 69, 32, 87, 73, 84, 72, 32, 83, 89, 77, 66, 79, 76, 83, 2, 11, 67, 2, + 215, 133, 10, 69, 4, 52, 7, 81, 85, 73, 81, 85, 65, 68, 239, 141, 9, 65, + 2, 91, 82, 4, 64, 10, 84, 82, 65, 78, 83, 77, 73, 84, 32, 83, 151, 187, + 6, 77, 2, 11, 84, 2, 223, 252, 8, 65, 134, 3, 102, 65, 218, 20, 73, 102, + 79, 214, 13, 69, 70, 82, 224, 143, 9, 5, 85, 70, 70, 76, 69, 195, 145, 1, + 89, 192, 2, 164, 1, 12, 68, 79, 87, 69, 68, 32, 87, 72, 73, 84, 69, 32, + 56, 9, 76, 76, 79, 87, 32, 80, 65, 78, 32, 62, 82, 182, 10, 86, 160, 198, + 7, 2, 77, 82, 227, 233, 1, 75, 6, 174, 239, 8, 67, 206, 11, 83, 245, 4, + 3, 76, 65, 84, 2, 17, 2, 79, 70, 2, 17, 2, 32, 70, 2, 187, 136, 7, 79, + 210, 1, 40, 4, 65, 68, 65, 32, 167, 194, 10, 75, 208, 1, 162, 1, 68, 46, + 69, 110, 72, 34, 76, 246, 1, 83, 212, 2, 6, 86, 79, 87, 69, 76, 32, 170, + 199, 4, 65, 188, 211, 1, 7, 67, 79, 78, 84, 73, 78, 85, 195, 143, 4, 79, + 24, 194, 224, 6, 79, 66, 65, 255, 235, 1, 73, 4, 84, 15, 88, 84, 82, 65, + 32, 83, 72, 79, 82, 84, 32, 86, 79, 87, 69, 235, 130, 9, 75, 2, 179, 254, + 9, 76, 2, 217, 143, 10, 3, 69, 65, 68, 96, 33, 6, 69, 84, 84, 69, 82, 32, + 96, 170, 225, 6, 65, 38, 68, 114, 84, 46, 86, 186, 5, 85, 186, 202, 1, + 73, 42, 76, 226, 195, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, + 2, 80, 138, 69, 72, 2, 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, 30, 70, 65, + 38, 69, 56, 4, 73, 71, 78, 32, 145, 183, 9, 3, 85, 84, 82, 2, 193, 251, + 9, 4, 78, 68, 72, 73, 6, 212, 205, 2, 5, 67, 84, 73, 79, 78, 243, 189, 4, + 80, 20, 106, 73, 154, 144, 5, 83, 202, 141, 1, 67, 98, 78, 190, 66, 65, + 190, 158, 1, 74, 150, 3, 85, 235, 245, 1, 86, 2, 37, 7, 78, 86, 69, 82, + 84, 69, 68, 2, 181, 157, 6, 2, 32, 67, 46, 60, 6, 77, 79, 68, 73, 70, 73, + 21, 5, 83, 73, 71, 78, 32, 2, 155, 146, 6, 69, 44, 110, 67, 42, 79, 34, + 80, 162, 183, 4, 85, 194, 229, 1, 83, 242, 68, 65, 58, 86, 166, 202, 1, + 73, 199, 140, 2, 69, 4, 193, 157, 6, 5, 65, 78, 68, 82, 65, 7, 186, 162, + 10, 79, 215, 22, 69, 2, 57, 12, 82, 73, 83, 72, 84, 72, 65, 77, 65, 84, + 82, 65, 2, 223, 161, 10, 32, 98, 72, 3, 69, 68, 32, 21, 11, 73, 65, 78, + 32, 76, 69, 84, 84, 69, 82, 32, 2, 215, 250, 9, 73, 96, 158, 2, 65, 120, + 3, 67, 72, 85, 22, 69, 70, 72, 46, 73, 46, 76, 22, 77, 38, 79, 94, 80, + 18, 82, 22, 83, 38, 84, 64, 2, 87, 79, 36, 2, 89, 69, 212, 243, 4, 2, 74, + 85, 166, 228, 2, 68, 202, 13, 90, 218, 88, 70, 182, 6, 71, 234, 45, 66, + 246, 11, 75, 234, 21, 86, 250, 27, 78, 167, 128, 1, 85, 16, 82, 82, 242, + 251, 9, 73, 234, 25, 68, 162, 8, 71, 2, 87, 198, 21, 83, 147, 1, 72, 4, + 170, 166, 9, 82, 163, 142, 1, 69, 2, 255, 145, 10, 82, 8, 38, 65, 146, + 251, 9, 82, 139, 56, 71, 4, 234, 179, 10, 82, 3, 84, 4, 164, 182, 8, 2, + 65, 45, 179, 172, 1, 85, 6, 194, 227, 9, 65, 142, 57, 67, 215, 22, 70, 2, + 207, 168, 8, 79, 4, 146, 158, 5, 69, 227, 250, 3, 73, 12, 70, 79, 170, + 166, 9, 73, 166, 111, 85, 150, 25, 65, 154, 3, 78, 3, 82, 2, 163, 155, + 10, 90, 2, 255, 15, 69, 2, 151, 142, 9, 79, 4, 130, 143, 9, 85, 191, 162, + 1, 79, 6, 26, 72, 215, 148, 10, 79, 4, 218, 131, 6, 73, 223, 155, 4, 69, + 4, 138, 165, 9, 79, 211, 139, 1, 69, 4, 182, 176, 10, 65, 3, 87, 10, 78, + 69, 186, 232, 3, 70, 148, 126, 6, 78, 84, 79, 32, 83, 72, 131, 201, 5, + 80, 2, 171, 233, 9, 76, 50, 252, 1, 2, 79, 84, 32, 6, 80, 80, 73, 78, 71, + 32, 72, 2, 82, 84, 128, 11, 7, 85, 76, 68, 69, 82, 69, 68, 184, 240, 1, + 24, 67, 75, 69, 68, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 69, 88, + 80, 76, 79, 68, 73, 78, 71, 234, 155, 3, 86, 199, 215, 4, 87, 2, 197, + 147, 8, 3, 73, 78, 71, 4, 36, 3, 84, 82, 79, 131, 242, 5, 66, 2, 11, 76, + 2, 139, 143, 8, 76, 36, 102, 32, 200, 8, 12, 72, 65, 78, 68, 32, 70, 79, + 82, 77, 65, 84, 32, 250, 182, 6, 67, 171, 236, 3, 83, 24, 242, 1, 66, 92, + 11, 83, 76, 65, 78, 84, 69, 68, 32, 78, 79, 82, 196, 1, 4, 76, 69, 70, + 84, 156, 1, 11, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 32, 248, 1, 7, + 85, 80, 32, 84, 65, 67, 75, 129, 161, 2, 9, 68, 79, 87, 78, 32, 84, 65, + 67, 75, 4, 88, 14, 65, 67, 75, 83, 76, 65, 78, 84, 69, 68, 32, 83, 79, + 85, 33, 4, 69, 78, 84, 32, 2, 11, 84, 2, 179, 140, 9, 72, 2, 221, 40, 37, + 65, 82, 82, 79, 87, 32, 80, 79, 73, 78, 84, 73, 78, 71, 32, 68, 79, 87, + 78, 87, 65, 82, 68, 83, 32, 84, 72, 69, 78, 32, 78, 79, 82, 84, 72, 32, + 69, 4, 116, 24, 87, 65, 82, 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, 32, + 65, 66, 79, 86, 69, 32, 76, 79, 78, 71, 171, 3, 32, 2, 237, 1, 5, 32, 82, + 73, 71, 72, 4, 112, 11, 65, 82, 82, 79, 87, 32, 65, 66, 79, 86, 69, 29, + 13, 72, 65, 82, 80, 79, 79, 78, 32, 65, 66, 79, 86, 69, 2, 157, 128, 6, + 2, 32, 76, 2, 29, 5, 32, 76, 79, 78, 71, 2, 25, 4, 32, 76, 69, 70, 2, + 153, 250, 6, 6, 84, 87, 65, 82, 68, 83, 7, 11, 32, 4, 76, 13, 65, 66, 79, + 86, 69, 32, 83, 72, 79, 82, 84, 32, 68, 251, 131, 2, 87, 2, 11, 79, 2, + 11, 87, 2, 11, 78, 2, 11, 32, 2, 223, 132, 7, 84, 8, 120, 10, 67, 79, 78, + 84, 73, 78, 85, 73, 78, 71, 0, 6, 76, 69, 84, 84, 69, 82, 40, 4, 68, 79, + 87, 78, 1, 2, 85, 80, 2, 193, 179, 3, 5, 32, 79, 86, 69, 82, 2, 21, 3, + 32, 83, 84, 2, 215, 161, 10, 69, 2, 25, 4, 32, 79, 80, 69, 2, 207, 146, + 9, 78, 4, 26, 73, 179, 160, 10, 85, 2, 247, 160, 10, 77, 211, 14, 174, 1, + 68, 152, 20, 2, 71, 78, 184, 181, 1, 6, 77, 73, 76, 65, 82, 32, 158, 2, + 78, 202, 24, 88, 237, 238, 6, 15, 76, 72, 79, 85, 69, 84, 84, 69, 32, 79, + 70, 32, 74, 65, 80, 252, 1, 40, 5, 68, 72, 65, 77, 32, 135, 17, 69, 184, + 1, 202, 1, 69, 68, 7, 76, 69, 84, 84, 69, 82, 32, 176, 4, 15, 82, 69, 80, + 69, 84, 73, 84, 73, 79, 78, 32, 77, 65, 82, 75, 50, 83, 164, 8, 11, 86, + 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 171, 175, 6, 68, 2, 37, 7, 78, + 68, 32, 79, 70, 32, 84, 2, 201, 210, 9, 2, 69, 88, 102, 214, 1, 65, 98, + 84, 242, 188, 6, 68, 158, 1, 86, 186, 5, 85, 186, 202, 1, 73, 138, 196, + 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 138, 69, 72, 2, + 76, 2, 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, 11, 72, 8, 76, 84, 69, 82, + 78, 65, 84, 69, 214, 154, 10, 65, 2, 73, 3, 85, 2, 235, 245, 9, 32, 14, + 134, 1, 72, 252, 231, 5, 19, 87, 79, 45, 67, 73, 82, 67, 76, 69, 32, 65, + 76, 84, 69, 82, 78, 65, 84, 69, 254, 233, 3, 84, 195, 71, 65, 4, 164, + 217, 9, 20, 82, 69, 69, 45, 67, 73, 82, 67, 76, 69, 32, 65, 76, 84, 69, + 82, 78, 65, 84, 69, 147, 64, 65, 6, 11, 45, 6, 186, 152, 10, 49, 2, 50, + 3, 51, 44, 38, 69, 181, 7, 4, 73, 71, 78, 32, 32, 96, 11, 67, 84, 73, 79, + 78, 32, 77, 65, 82, 75, 32, 177, 6, 8, 80, 65, 82, 65, 84, 79, 82, 32, + 28, 80, 11, 68, 79, 85, 66, 76, 69, 32, 82, 73, 78, 71, 57, 5, 87, 73, + 84, 72, 32, 5, 11, 32, 2, 249, 231, 8, 6, 87, 73, 84, 72, 32, 82, 24, + 212, 1, 12, 67, 73, 82, 67, 76, 69, 83, 32, 65, 78, 68, 32, 116, 5, 81, + 85, 65, 68, 82, 0, 4, 83, 69, 80, 84, 12, 16, 82, 65, 89, 83, 32, 65, 78, + 68, 32, 68, 79, 84, 84, 69, 68, 32, 46, 68, 45, 3, 84, 82, 73, 6, 60, 4, + 70, 79, 85, 82, 0, 3, 84, 87, 79, 187, 229, 8, 82, 2, 225, 207, 6, 8, 32, + 69, 78, 67, 76, 79, 83, 85, 2, 83, 85, 6, 42, 68, 28, 3, 84, 82, 73, 215, + 1, 67, 2, 197, 1, 3, 79, 85, 66, 2, 171, 1, 80, 6, 52, 9, 68, 69, 78, 84, + 32, 65, 78, 68, 32, 103, 80, 4, 116, 6, 68, 79, 84, 84, 69, 68, 49, 14, + 85, 45, 83, 72, 65, 80, 69, 68, 32, 79, 82, 78, 65, 77, 2, 17, 2, 76, 69, + 2, 17, 2, 32, 67, 2, 25, 4, 82, 69, 83, 67, 2, 239, 186, 1, 69, 4, 158, + 237, 8, 66, 135, 83, 68, 12, 146, 229, 4, 83, 202, 141, 1, 67, 98, 78, + 138, 216, 3, 65, 239, 1, 86, 26, 74, 65, 94, 86, 210, 183, 6, 85, 186, + 202, 1, 73, 198, 140, 2, 69, 3, 79, 10, 168, 184, 6, 10, 76, 84, 69, 82, + 78, 65, 84, 69, 32, 85, 254, 214, 3, 65, 2, 73, 3, 85, 4, 11, 79, 4, 33, + 6, 67, 65, 76, 73, 67, 32, 4, 255, 183, 6, 82, 68, 84, 12, 84, 73, 67, + 32, 76, 69, 84, 84, 69, 82, 32, 78, 49, 5, 87, 65, 89, 83, 32, 52, 178, + 156, 1, 50, 222, 176, 3, 48, 131, 2, 49, 16, 56, 5, 66, 76, 65, 67, 75, + 1, 5, 87, 72, 73, 84, 69, 8, 11, 32, 8, 70, 82, 24, 3, 76, 69, 70, 12, 4, + 68, 79, 87, 78, 1, 2, 85, 80, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 225, + 92, 6, 32, 80, 79, 73, 78, 84, 194, 10, 96, 8, 87, 82, 73, 84, 73, 78, + 71, 32, 241, 238, 1, 10, 32, 79, 70, 32, 84, 72, 69, 32, 72, 79, 192, 10, + 136, 3, 4, 65, 73, 82, 32, 192, 1, 2, 66, 82, 102, 67, 138, 1, 68, 218, + 4, 69, 242, 6, 70, 244, 3, 4, 87, 65, 76, 76, 138, 1, 72, 234, 77, 76, + 212, 6, 2, 77, 79, 222, 42, 78, 218, 1, 82, 182, 7, 83, 162, 5, 84, 180, + 10, 5, 71, 82, 65, 83, 80, 184, 5, 30, 85, 80, 80, 69, 82, 32, 66, 79, + 68, 89, 32, 84, 73, 76, 84, 73, 78, 71, 32, 70, 82, 79, 77, 32, 72, 73, + 80, 32, 74, 79, 135, 207, 4, 80, 8, 48, 4, 66, 76, 79, 87, 29, 4, 83, 85, + 67, 75, 4, 58, 32, 211, 226, 4, 73, 4, 30, 32, 61, 3, 73, 78, 71, 2, 237, + 157, 1, 10, 83, 77, 65, 76, 76, 32, 82, 79, 84, 65, 2, 171, 134, 9, 32, + 10, 52, 5, 69, 65, 84, 72, 32, 229, 169, 1, 2, 85, 83, 4, 140, 164, 2, 2, + 69, 88, 1, 2, 73, 78, 10, 40, 6, 72, 69, 69, 75, 83, 32, 63, 79, 6, 154, + 107, 83, 146, 38, 78, 153, 223, 3, 4, 80, 85, 70, 70, 4, 178, 180, 9, 76, + 223, 46, 77, 28, 108, 15, 82, 69, 65, 77, 89, 32, 69, 89, 69, 66, 82, 79, + 87, 83, 32, 165, 1, 7, 89, 78, 65, 77, 73, 67, 32, 8, 64, 4, 68, 79, 87, + 78, 0, 2, 85, 80, 29, 4, 78, 69, 85, 84, 2, 153, 143, 1, 2, 32, 78, 4, + 21, 3, 82, 65, 76, 4, 11, 32, 4, 194, 58, 68, 191, 199, 9, 85, 20, 180, + 1, 11, 69, 86, 69, 82, 89, 32, 79, 84, 72, 69, 82, 30, 70, 22, 83, 128, + 122, 9, 65, 82, 82, 79, 87, 72, 69, 65, 68, 234, 38, 82, 136, 206, 3, 2, + 84, 69, 21, 4, 71, 82, 65, 68, 2, 181, 230, 8, 2, 32, 84, 2, 163, 146, 6, + 65, 6, 68, 11, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, 83, 151, 227, 8, + 76, 5, 203, 151, 1, 32, 54, 64, 2, 89, 69, 172, 227, 4, 4, 88, 67, 73, + 84, 203, 138, 4, 65, 50, 166, 1, 32, 56, 15, 66, 82, 79, 87, 83, 32, 83, + 84, 82, 65, 73, 71, 72, 84, 32, 44, 5, 71, 65, 90, 69, 45, 140, 2, 7, 76, + 65, 83, 72, 69, 83, 32, 65, 2, 83, 32, 6, 220, 150, 1, 5, 66, 76, 73, 78, + 75, 243, 129, 5, 87, 6, 186, 53, 68, 154, 84, 78, 167, 243, 8, 85, 18, + 100, 11, 70, 76, 79, 79, 82, 80, 76, 65, 78, 69, 32, 25, 10, 87, 65, 76, + 76, 80, 76, 65, 78, 69, 32, 8, 82, 83, 207, 45, 67, 10, 18, 67, 43, 83, + 4, 254, 45, 85, 213, 95, 3, 73, 82, 67, 6, 37, 7, 84, 82, 65, 73, 71, 72, + 84, 7, 11, 32, 4, 202, 163, 1, 65, 55, 68, 6, 130, 51, 68, 180, 173, 4, + 4, 70, 76, 85, 84, 139, 154, 5, 85, 14, 112, 5, 72, 65, 76, 70, 32, 26, + 67, 28, 4, 87, 73, 68, 69, 230, 92, 79, 233, 135, 4, 6, 83, 81, 85, 69, + 69, 90, 4, 22, 67, 131, 93, 79, 2, 213, 232, 2, 2, 76, 79, 4, 162, 67, + 32, 217, 61, 4, 78, 73, 78, 71, 38, 204, 1, 28, 65, 67, 69, 32, 68, 73, + 82, 69, 67, 84, 73, 79, 78, 32, 80, 79, 83, 73, 84, 73, 79, 78, 32, 78, + 79, 83, 69, 32, 138, 1, 73, 82, 76, 176, 1, 8, 79, 82, 69, 72, 69, 65, + 68, 32, 187, 158, 7, 85, 6, 88, 10, 85, 80, 32, 79, 82, 32, 68, 79, 87, + 78, 13, 8, 70, 79, 82, 87, 65, 82, 68, 32, 5, 11, 32, 2, 153, 231, 4, 3, + 84, 73, 76, 12, 180, 225, 3, 11, 76, 76, 32, 77, 79, 68, 73, 70, 73, 69, + 82, 131, 195, 2, 78, 12, 44, 4, 73, 67, 75, 32, 29, 3, 79, 79, 82, 10, + 254, 140, 1, 76, 35, 83, 2, 225, 247, 8, 20, 80, 76, 65, 78, 69, 32, 83, + 72, 79, 85, 76, 68, 69, 82, 32, 72, 73, 80, 32, 77, 6, 166, 89, 87, 222, + 38, 67, 47, 78, 156, 4, 34, 65, 133, 75, 3, 69, 65, 68, 140, 4, 36, 3, + 78, 68, 45, 143, 186, 9, 73, 138, 4, 92, 5, 65, 78, 71, 76, 69, 138, 5, + 67, 150, 10, 70, 186, 42, 72, 241, 12, 4, 79, 86, 65, 76, 37, 11, 32, 34, + 188, 1, 5, 73, 78, 68, 69, 88, 176, 1, 7, 76, 73, 84, 84, 76, 69, 32, + 136, 1, 5, 82, 73, 78, 71, 32, 173, 66, 18, 77, 73, 68, 68, 76, 69, 32, + 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, 17, 11, 32, 14, 128, 1, 7, + 77, 73, 68, 68, 76, 69, 32, 228, 24, 11, 82, 73, 78, 71, 32, 76, 73, 84, + 84, 76, 69, 241, 42, 5, 84, 72, 85, 77, 66, 4, 174, 70, 76, 247, 215, 8, + 82, 8, 44, 5, 73, 78, 68, 69, 88, 207, 238, 9, 85, 7, 145, 24, 18, 32, + 84, 72, 85, 77, 66, 32, 73, 78, 68, 69, 88, 32, 84, 72, 85, 77, 66, 4, + 108, 22, 68, 79, 87, 78, 32, 77, 73, 68, 68, 76, 69, 32, 84, 72, 85, 77, + 66, 32, 73, 78, 68, 69, 155, 68, 76, 2, 207, 169, 8, 88, 88, 64, 5, 73, + 82, 67, 76, 69, 184, 3, 3, 76, 65, 87, 183, 2, 85, 35, 11, 32, 32, 116, + 5, 73, 78, 68, 69, 88, 200, 1, 7, 76, 73, 84, 84, 76, 69, 32, 36, 7, 77, + 73, 68, 68, 76, 69, 32, 163, 64, 82, 21, 11, 32, 18, 72, 6, 77, 73, 68, + 68, 76, 69, 198, 26, 72, 242, 38, 82, 131, 230, 8, 66, 13, 11, 32, 10, + 64, 5, 67, 82, 79, 83, 83, 198, 64, 84, 82, 76, 247, 215, 8, 82, 4, 134, + 65, 32, 231, 226, 8, 69, 4, 194, 193, 8, 73, 159, 168, 1, 85, 6, 252, 47, + 10, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 191, 185, 9, 85, 17, 11, 32, + 14, 144, 2, 28, 77, 73, 68, 68, 76, 69, 32, 82, 73, 78, 71, 32, 76, 73, + 84, 84, 76, 69, 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 176, 49, 2, 70, + 79, 198, 11, 78, 162, 1, 84, 197, 118, 23, 73, 78, 68, 69, 88, 32, 84, + 72, 85, 77, 66, 32, 67, 85, 82, 86, 69, 32, 84, 72, 85, 77, 66, 5, 247, + 180, 1, 32, 38, 46, 80, 149, 2, 6, 82, 76, 73, 67, 85, 69, 31, 11, 32, + 28, 188, 1, 5, 73, 78, 68, 69, 88, 56, 19, 70, 73, 86, 69, 32, 70, 73, + 78, 71, 69, 82, 83, 32, 83, 80, 82, 69, 65, 68, 196, 50, 7, 77, 73, 68, + 68, 76, 69, 32, 18, 79, 218, 7, 78, 163, 1, 84, 9, 11, 32, 6, 40, 5, 84, + 72, 85, 77, 66, 243, 58, 82, 5, 215, 46, 32, 9, 11, 32, 6, 72, 5, 73, 78, + 68, 69, 88, 0, 6, 77, 73, 68, 68, 76, 69, 179, 71, 79, 2, 193, 147, 9, + 13, 32, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, 32, 172, 2, 44, 3, + 73, 83, 84, 177, 33, 3, 76, 65, 84, 247, 1, 11, 32, 244, 1, 160, 2, 5, + 73, 78, 68, 69, 88, 192, 16, 7, 76, 73, 84, 84, 76, 69, 32, 196, 2, 7, + 77, 73, 68, 68, 76, 69, 32, 200, 4, 5, 82, 73, 78, 71, 32, 132, 2, 5, 84, + 72, 85, 77, 66, 138, 2, 72, 205, 9, 22, 70, 79, 85, 82, 32, 70, 73, 78, + 71, 69, 82, 83, 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 137, 1, 11, 32, + 134, 1, 232, 1, 4, 66, 69, 78, 84, 36, 6, 72, 73, 78, 71, 69, 68, 76, 6, + 77, 73, 68, 68, 76, 69, 168, 7, 2, 67, 85, 64, 6, 84, 72, 85, 77, 66, 32, + 160, 5, 16, 85, 80, 32, 77, 73, 68, 68, 76, 69, 32, 72, 73, 78, 71, 69, + 68, 151, 4, 82, 5, 217, 45, 5, 32, 79, 86, 69, 82, 9, 11, 32, 6, 252, 20, + 8, 77, 73, 68, 68, 76, 69, 32, 85, 167, 172, 8, 76, 71, 11, 32, 68, 236, + 1, 4, 66, 69, 78, 84, 42, 67, 244, 1, 10, 85, 80, 32, 83, 80, 82, 69, 65, + 68, 32, 100, 6, 72, 73, 78, 71, 69, 68, 46, 82, 80, 5, 84, 72, 85, 77, + 66, 188, 28, 14, 83, 84, 82, 65, 73, 71, 72, 84, 32, 84, 72, 85, 77, 66, + 227, 17, 76, 5, 213, 92, 6, 32, 84, 72, 85, 77, 66, 28, 68, 8, 79, 78, + 74, 79, 73, 78, 69, 68, 233, 1, 4, 82, 79, 83, 83, 23, 11, 32, 20, 144, + 1, 6, 67, 85, 80, 80, 69, 68, 28, 6, 84, 72, 85, 77, 66, 32, 68, 5, 72, + 73, 78, 71, 69, 166, 22, 73, 165, 7, 6, 77, 73, 68, 68, 76, 69, 5, 11, + 32, 2, 203, 27, 84, 8, 160, 1, 4, 83, 73, 68, 69, 219, 61, 70, 6, 22, 69, + 159, 47, 32, 4, 223, 15, 68, 5, 241, 30, 7, 32, 83, 80, 82, 69, 65, 68, + 8, 32, 3, 73, 78, 71, 247, 19, 65, 7, 11, 32, 4, 138, 36, 67, 131, 240, + 8, 66, 19, 11, 32, 16, 64, 6, 65, 78, 71, 76, 69, 68, 22, 67, 106, 72, + 163, 146, 9, 66, 5, 167, 221, 5, 32, 6, 74, 85, 230, 7, 73, 241, 25, 10, + 79, 78, 74, 79, 73, 78, 69, 68, 32, 72, 2, 201, 193, 4, 2, 80, 80, 4, 194, 33, 73, 217, 26, 2, 79, 79, 40, 164, 1, 7, 65, 78, 71, 76, 69, 68, 32, 46, 67, 220, 1, 14, 70, 79, 82, 87, 65, 82, 68, 32, 73, 78, 68, 69, 88, 32, 32, 4, 72, 79, 79, 75, 53, 4, 83, 73, 68, 69, 4, 128, 1, 2, 73, @@ -10001,397 +9973,289 @@ static const unsigned int dawg_pos_to_codepoint[] = { 12881, 12885, 12884, 12887, 12886, 12883, 12882, 12889, 12888, 9323, 9330, 10050, 12342, 10679, 10681, 8853, 8858, 10680, 128981, 9098, 8855, 10686, 10026, 127278, 127245, 8860, 10678, 10689, 128983, 11198, 94, - 10768, 127914, 127961, 127750, 195088, 195089, 195090, 195091, 195092, - 195093, 195094, 195095, 195096, 195097, 195098, 195099, 195100, 195101, - 195072, 195073, 195074, 195075, 195076, 195077, 195078, 195079, 195080, - 195081, 195082, 195083, 195084, 195085, 195086, 195087, 194560, 194561, - 194562, 194563, 194564, 194565, 194566, 194567, 194568, 194569, 194570, - 194571, 194572, 194573, 194574, 194575, 194576, 194577, 194578, 194579, - 194580, 194581, 194582, 194583, 194584, 194585, 194586, 194587, 194588, - 194589, 194590, 194591, 194592, 194593, 194594, 194595, 194596, 194597, - 194598, 194599, 194600, 194601, 194602, 194603, 194604, 194605, 194606, - 194607, 194608, 194609, 194610, 194611, 194612, 194613, 194614, 194615, - 194616, 194617, 194618, 194619, 194620, 194621, 194622, 194623, 194624, - 194625, 194626, 194627, 194628, 194629, 194630, 194631, 194632, 194633, - 194634, 194635, 194636, 194637, 194638, 194639, 194640, 194641, 194642, - 194643, 194644, 194645, 194646, 194647, 194648, 194649, 194650, 194651, - 194652, 194653, 194654, 194655, 194656, 194657, 194658, 194659, 194660, - 194661, 194662, 194663, 194664, 194665, 194666, 194667, 194668, 194669, - 194670, 194671, 194672, 194673, 194674, 194675, 194676, 194677, 194678, - 194679, 194680, 194681, 194682, 194683, 194684, 194685, 194686, 194687, - 194688, 194689, 194690, 194691, 194692, 194693, 194694, 194695, 194696, - 194697, 194698, 194699, 194700, 194701, 194702, 194703, 194704, 194705, - 194706, 194707, 194708, 194709, 194710, 194711, 194712, 194713, 194714, - 194715, 194716, 194717, 194718, 194719, 194720, 194721, 194722, 194723, - 194724, 194725, 194726, 194727, 194728, 194729, 194730, 194731, 194732, - 194733, 194734, 194735, 194736, 194737, 194738, 194739, 194740, 194741, - 194742, 194743, 194744, 194745, 194746, 194747, 194748, 194749, 194750, - 194751, 194752, 194753, 194754, 194755, 194756, 194757, 194758, 194759, - 194760, 194761, 194762, 194763, 194764, 194765, 194766, 194767, 194768, - 194769, 194770, 194771, 194772, 194773, 194774, 194775, 194776, 194777, - 194778, 194779, 194780, 194781, 194782, 194783, 194784, 194785, 194786, - 194787, 194788, 194789, 194790, 194791, 194792, 194793, 194794, 194795, - 194796, 194797, 194798, 194799, 194800, 194801, 194802, 194803, 194804, - 194805, 194806, 194807, 194808, 194809, 194810, 194811, 194812, 194813, - 194814, 194815, 194816, 194817, 194818, 194819, 194820, 194821, 194822, - 194823, 194824, 194825, 194826, 194827, 194828, 194829, 194830, 194831, - 194832, 194833, 194834, 194835, 194836, 194837, 194838, 194839, 194840, - 194841, 194842, 194843, 194844, 194845, 194846, 194847, 194848, 194849, - 194850, 194851, 194852, 194853, 194854, 194855, 194856, 194857, 194858, - 194859, 194860, 194861, 194862, 194863, 194864, 194865, 194866, 194867, - 194868, 194869, 194870, 194871, 194872, 194873, 194874, 194875, 194876, - 194877, 194878, 194879, 194880, 194881, 194882, 194883, 194884, 194885, - 194886, 194887, 194888, 194889, 194890, 194891, 194892, 194893, 194894, - 194895, 194896, 194897, 194898, 194899, 194900, 194901, 194902, 194903, - 194904, 194905, 194906, 194907, 194908, 194909, 194910, 194911, 194912, - 194913, 194914, 194915, 194916, 194917, 194918, 194919, 194920, 194921, - 194922, 194923, 194924, 194925, 194926, 194927, 194928, 194929, 194930, - 194931, 194932, 194933, 194934, 194935, 194936, 194937, 194938, 194939, - 194940, 194941, 194942, 194943, 194944, 194945, 194946, 194947, 194948, - 194949, 194950, 194951, 194952, 194953, 194954, 194955, 194956, 194957, - 194958, 194959, 194960, 194961, 194962, 194963, 194964, 194965, 194966, - 194967, 194968, 194969, 194970, 194971, 194972, 194973, 194974, 194975, - 194976, 194977, 194978, 194979, 194980, 194981, 194982, 194983, 194984, - 194985, 194986, 194987, 194988, 194989, 194990, 194991, 194992, 194993, - 194994, 194995, 194996, 194997, 194998, 194999, 195000, 195001, 195002, - 195003, 195004, 195005, 195006, 195007, 195008, 195009, 195010, 195011, - 195012, 195013, 195014, 195015, 195016, 195017, 195018, 195019, 195020, - 195021, 195022, 195023, 195024, 195025, 195026, 195027, 195028, 195029, - 195030, 195031, 195032, 195033, 195034, 195035, 195036, 195037, 195038, - 195039, 195040, 195041, 195042, 195043, 195044, 195045, 195046, 195047, - 195048, 195049, 195050, 195051, 195052, 195053, 195054, 195055, 195056, - 195057, 195058, 195059, 195060, 195061, 195062, 195063, 195064, 195065, - 195066, 195067, 195068, 195069, 195070, 195071, 64096, 64097, 64098, - 64099, 64100, 64101, 64102, 64103, 64104, 64105, 64106, 64107, 64108, - 64109, 64000, 64001, 64002, 64003, 64004, 64005, 64006, 64007, 64008, - 64009, 64010, 64011, 64012, 64013, 64014, 64015, 64016, 64017, 64018, - 64019, 64020, 64021, 64022, 64023, 64024, 64025, 64026, 64027, 64028, - 64029, 64030, 64031, 64032, 64033, 64034, 64035, 64036, 64037, 64038, - 64039, 64040, 64041, 64042, 64043, 64044, 64045, 64046, 64047, 64048, - 64049, 64050, 64051, 64052, 64053, 64054, 64055, 64056, 64057, 64058, - 64059, 64060, 64061, 64062, 64063, 64064, 64065, 64066, 64067, 64068, - 64069, 64070, 64071, 64072, 64073, 64074, 64075, 64076, 64077, 64078, - 64079, 64080, 64081, 64082, 64083, 64084, 64085, 64086, 64087, 64088, - 64089, 64090, 64091, 64092, 64093, 64094, 64095, 64112, 64113, 64114, - 64115, 64116, 64117, 64118, 64119, 64120, 64121, 64122, 64123, 64124, - 64125, 64126, 64127, 64128, 64129, 64130, 64131, 64132, 64133, 64134, - 64135, 64136, 64137, 64138, 64139, 64140, 64141, 64142, 64143, 64144, - 64145, 64146, 64147, 64148, 64149, 64150, 64151, 64152, 64153, 64154, - 64155, 64156, 64157, 64158, 64159, 64160, 64161, 64162, 64163, 64164, - 64165, 64166, 64167, 64168, 64169, 64170, 64171, 64172, 64173, 64174, - 64175, 64176, 64177, 64178, 64179, 64180, 64181, 64182, 64183, 64184, - 64185, 64186, 64187, 64188, 64189, 64190, 64191, 64192, 64193, 64194, - 64195, 64196, 64197, 64198, 64199, 64200, 64201, 64202, 64203, 64204, - 64205, 64206, 64207, 64208, 64209, 64210, 64211, 64212, 64213, 64214, - 64215, 64216, 64217, 63744, 63745, 63746, 63747, 63748, 63749, 63750, - 63751, 63752, 63753, 63754, 63755, 63756, 63757, 63758, 63759, 63760, - 63761, 63762, 63763, 63764, 63765, 63766, 63767, 63768, 63769, 63770, - 63771, 63772, 63773, 63774, 63775, 63776, 63777, 63778, 63779, 63780, - 63781, 63782, 63783, 63784, 63785, 63786, 63787, 63788, 63789, 63790, - 63791, 63792, 63793, 63794, 63795, 63796, 63797, 63798, 63799, 63800, - 63801, 63802, 63803, 63804, 63805, 63806, 63807, 63808, 63809, 63810, - 63811, 63812, 63813, 63814, 63815, 63816, 63817, 63818, 63819, 63820, - 63821, 63822, 63823, 63824, 63825, 63826, 63827, 63828, 63829, 63830, - 63831, 63832, 63833, 63834, 63835, 63836, 63837, 63838, 63839, 63840, - 63841, 63842, 63843, 63844, 63845, 63846, 63847, 63848, 63849, 63850, - 63851, 63852, 63853, 63854, 63855, 63856, 63857, 63858, 63859, 63860, - 63861, 63862, 63863, 63864, 63865, 63866, 63867, 63868, 63869, 63870, - 63871, 63872, 63873, 63874, 63875, 63876, 63877, 63878, 63879, 63880, - 63881, 63882, 63883, 63884, 63885, 63886, 63887, 63888, 63889, 63890, - 63891, 63892, 63893, 63894, 63895, 63896, 63897, 63898, 63899, 63900, - 63901, 63902, 63903, 63904, 63905, 63906, 63907, 63908, 63909, 63910, - 63911, 63912, 63913, 63914, 63915, 63916, 63917, 63918, 63919, 63920, - 63921, 63922, 63923, 63924, 63925, 63926, 63927, 63928, 63929, 63930, - 63931, 63932, 63933, 63934, 63935, 63936, 63937, 63938, 63939, 63940, - 63941, 63942, 63943, 63944, 63945, 63946, 63947, 63948, 63949, 63950, - 63951, 63952, 63953, 63954, 63955, 63956, 63957, 63958, 63959, 63960, - 63961, 63962, 63963, 63964, 63965, 63966, 63967, 63968, 63969, 63970, - 63971, 63972, 63973, 63974, 63975, 63976, 63977, 63978, 63979, 63980, - 63981, 63982, 63983, 63984, 63985, 63986, 63987, 63988, 63989, 63990, - 63991, 63992, 63993, 63994, 63995, 63996, 63997, 63998, 63999, 11946, - 12003, 11910, 11963, 11962, 11950, 11992, 12012, 12000, 12005, 11996, - 12010, 11984, 11988, 11994, 11987, 11952, 12007, 11977, 11976, 11973, - 12019, 11993, 12014, 11995, 12016, 12006, 12002, 11979, 11936, 11983, - 11905, 11970, 11943, 11931, 11914, 11934, 11944, 11999, 11998, 11997, - 11960, 11947, 11939, 11978, 11968, 11967, 11966, 12004, 11927, 11926, - 12001, 11975, 11928, 12018, 12013, 12015, 12011, 11945, 11986, 11985, - 11921, 11920, 11919, 11918, 11964, 11957, 11990, 11989, 11935, 11965, - 11933, 11941, 11940, 11909, 11991, 11959, 11929, 11904, 11908, 11907, - 11906, 11915, 11942, 11974, 11980, 12008, 12009, 11951, 11925, 11924, - 11922, 11949, 11948, 11917, 11916, 11958, 11932, 12017, 11911, 11923, - 11969, 11982, 11981, 11938, 11937, 11972, 11971, 11956, 11955, 11954, - 11953, 11913, 11912, 11961, 12752, 12743, 12748, 12768, 12772, 12757, - 12741, 12750, 12769, 12747, 12749, 12744, 12742, 12746, 12758, 12754, - 12763, 12770, 12764, 12753, 12740, 12767, 12760, 12759, 12745, 12773, - 12766, 12762, 12755, 12761, 12736, 12765, 12739, 12737, 12738, 12756, - 12751, 12771, 128079, 127916, 127963, 128385, 129346, 127867, 128203, - 128346, 128358, 128343, 128355, 128340, 128352, 128339, 128351, 128344, - 128356, 128336, 128348, 128342, 128354, 128341, 128353, 128345, 128357, - 128347, 128359, 128337, 128349, 128338, 128350, 10561, 8754, 128259, - 10227, 128472, 128257, 128258, 8631, 11118, 8635, 8753, 10959, 10961, - 10960, 10962, 127746, 10828, 10832, 128234, 128235, 128272, 128213, - 10829, 8272, 9729, 127786, 127785, 127784, 127783, 129313, 9114, 129715, - 127864, 129381, 58, 8788, 8353, 128165, 6867, 7625, 7623, 769, 791, 833, - 8410, 8404, 8423, 857, 8432, 7677, 844, 774, 7627, 814, 810, 838, 70459, - 780, 812, 784, 8409, 8405, 787, 789, 806, 65062, 65069, 42609, 1160, - 11774, 11744, 11768, 11747, 11757, 11765, 42654, 11751, 11752, 11753, - 11756, 42613, 11775, 11772, 42655, 11767, 11754, 42619, 11763, 11762, - 42618, 42615, 42612, 42617, 11770, 42614, 11771, 11773, 11769, 11759, - 42616, 11760, 11758, 11748, 11749, 11761, 11746, 11764, 11755, 11745, - 11750, 11766, 42621, 1156, 1158, 1159, 1157, 42608, 42610, 1155, 65070, - 65071, 1161, 42620, 123023, 42607, 770, 813, 807, 43248, 43244, 43245, - 43246, 43247, 43242, 43243, 43249, 43237, 43236, 43239, 43238, 43235, - 43234, 43232, 43241, 43233, 43240, 7675, 776, 804, 6876, 6833, 775, 7672, - 856, 803, 7674, 6877, 7617, 7616, 6886, 6887, 779, 861, 860, 865, 7676, - 6863, 7629, 862, 863, 6840, 831, 6858, 6857, 6844, 866, 6891, 858, 864, - 65058, 65059, 8422, 840, 782, 783, 819, 6832, 798, 6875, 6835, 8413, - 8416, 8418, 8414, 8419, 8420, 8415, 839, 6888, 850, 8412, 6874, 122892, - 122884, 122891, 122890, 122921, 122919, 122889, 122916, 122900, 122907, - 122910, 122901, 122908, 122880, 122920, 122881, 122909, 122903, 122922, - 122883, 122895, 122894, 122896, 122898, 122899, 122882, 122885, 122912, - 122911, 122913, 122918, 122915, 122888, 122886, 122904, 122902, 122897, - 122893, 70508, 70507, 70506, 70505, 70504, 70502, 70503, 70515, 70513, - 70514, 70516, 70512, 768, 790, 832, 6865, 7624, 7621, 847, 119363, - 119362, 119364, 835, 834, 837, 836, 777, 843, 795, 785, 815, 826, 6883, - 811, 6855, 6834, 7632, 12442, 12441, 7671, 7670, 7643, 7646, 7647, 7649, - 7650, 867, 7666, 7655, 7636, 7637, 7638, 872, 7639, 868, 7663, 7641, - 7659, 7635, 869, 7640, 6860, 6861, 6862, 7645, 7660, 7653, 870, 7667, - 7661, 871, 7668, 7664, 876, 7651, 7626, 877, 6848, 7652, 7658, 7656, - 7657, 7665, 6847, 873, 7642, 874, 7644, 875, 7648, 7662, 878, 879, 7654, - 6889, 841, 794, 852, 7678, 8430, 8406, 6849, 6851, 796, 849, 8400, 792, - 6880, 845, 8417, 8429, 8426, 65056, 65063, 65057, 65064, 6841, 8427, 824, - 822, 8402, 818, 772, 65060, 65067, 65061, 65068, 817, 6869, 7620, 6872, - 7622, 7628, 800, 6882, 6854, 842, 66424, 66425, 66423, 66426, 66422, - 6839, 808, 7630, 773, 6846, 6845, 6843, 801, 799, 6856, 8421, 788, 802, - 7679, 854, 848, 853, 8431, 8407, 825, 855, 8401, 6850, 6852, 793, 6881, - 8428, 8408, 805, 778, 7631, 859, 823, 821, 8403, 6873, 6853, 827, 6884, - 6842, 7619, 7618, 828, 6885, 8411, 771, 65065, 65066, 820, 816, 6859, - 8424, 6836, 786, 797, 7669, 846, 6890, 7633, 7634, 809, 781, 830, 6864, - 6870, 6866, 6871, 6868, 7673, 8425, 6838, 6837, 851, 829, 8274, 64, 44, - 128476, 9092, 8705, 129517, 9732, 127882, 128533, 128534, 128119, 128679, - 8715, 8883, 8885, 8954, 8955, 8957, 8750, 127899, 983187, 9089, 127978, - 9010, 9740, 10861, 127859, 127850, 127834, 11505, 11504, 11503, 11464, - 11392, 11506, 11499, 11501, 11446, 11452, 11458, 11466, 11442, 11448, - 11450, 11398, 1006, 1002, 11396, 1000, 11406, 998, 11436, 11412, 11420, - 996, 11434, 11472, 11414, 11422, 11478, 11468, 11470, 11476, 11474, - 11482, 11460, 11480, 11454, 11462, 11444, 11486, 11488, 11484, 11490, - 11440, 1004, 994, 11456, 11402, 11428, 11408, 11430, 11404, 11394, 11438, - 11424, 11410, 11426, 11400, 11416, 11418, 11432, 66298, 66289, 66295, - 66286, 66294, 66285, 66299, 66290, 66291, 66297, 66288, 66296, 66287, - 66293, 66284, 66292, 66283, 66282, 66277, 66276, 66279, 66278, 66275, - 66274, 66281, 66273, 66280, 66272, 11517, 11518, 11514, 11515, 11516, - 11513, 11465, 11393, 11507, 11500, 11502, 11447, 11453, 11459, 11467, - 11443, 11449, 11451, 11399, 1007, 1003, 11397, 1001, 11407, 999, 11437, - 11413, 11421, 997, 11435, 11473, 11415, 11423, 11479, 11469, 11471, - 11477, 11475, 11483, 11461, 11481, 11455, 11463, 11445, 11487, 11489, - 11485, 11491, 11441, 1005, 995, 11457, 11403, 11429, 11409, 11431, 11405, - 11395, 11439, 11425, 11411, 11427, 11401, 11417, 11419, 11433, 11497, - 11492, 11493, 11494, 11498, 11495, 11496, 11519, 127279, 169, 11855, - 8792, 129720, 9012, 9013, 119661, 119660, 119663, 119662, 119659, 119658, - 119665, 119657, 119664, 119652, 119651, 119654, 119653, 119650, 119649, - 119656, 119648, 119655, 128715, 128145, 128004, 128046, 9904, 129689, - 129509, 983074, 128179, 127769, 129431, 127951, 9769, 9768, 11856, 11857, - 128322, 128321, 10060, 127370, 127884, 9876, 9932, 128010, 129360, - 128081, 8354, 129660, 128575, 128546, 128302, 129408, 8731, 74794, 74771, - 74861, 74780, 74820, 74821, 74765, 74758, 74853, 74856, 74855, 74854, - 74791, 74801, 74844, 74836, 74837, 74809, 74755, 74829, 74777, 74786, - 74768, 74858, 74762, 74834, 74835, 74808, 74812, 74814, 74815, 74813, - 74754, 74828, 74776, 74785, 74790, 74800, 74767, 74857, 74761, 74839, - 74838, 74822, 74825, 74823, 74824, 74795, 74772, 74862, 74781, 74766, - 74759, 74849, 74850, 74840, 74847, 74848, 74851, 74831, 74804, 74773, - 74782, 74845, 74842, 74796, 74852, 74818, 74819, 74817, 74793, 74770, - 74860, 74779, 74764, 74757, 74802, 74803, 74792, 74756, 74830, 74769, - 74859, 74778, 74816, 74763, 74806, 74807, 74833, 74788, 74789, 74798, - 74799, 74810, 74811, 74753, 74827, 74775, 74784, 74760, 74752, 74826, - 74832, 74805, 74841, 74774, 74783, 74787, 74797, 74846, 74843, 74867, - 74868, 74866, 74865, 74864, 73728, 73734, 73731, 73733, 73735, 73736, - 73730, 73732, 73729, 73738, 73742, 73741, 73744, 73745, 74881, 73747, - 73748, 73740, 73739, 74608, 74880, 73746, 73743, 73749, 73750, 73753, - 73752, 73754, 73755, 73751, 74609, 73756, 74882, 73757, 73759, 73758, - 73760, 73765, 73766, 73762, 73763, 73768, 73761, 73767, 73764, 73770, - 73769, 73771, 74610, 73772, 73773, 73776, 73777, 73775, 73774, 73778, - 73780, 73781, 73782, 73784, 73788, 73789, 73787, 73785, 73786, 73791, - 73790, 73783, 73779, 73737, 73792, 73793, 74883, 73795, 74884, 74885, - 74886, 73796, 73797, 73798, 73799, 73800, 73794, 73801, 73804, 73803, - 73802, 73805, 74887, 73806, 73807, 73808, 73809, 73810, 73811, 73812, - 73813, 73814, 73815, 73816, 73817, 73818, 73819, 73820, 73821, 73822, - 73823, 73825, 73826, 73829, 73830, 73831, 73828, 73836, 74611, 73837, - 73833, 73835, 73827, 73832, 73834, 73824, 74889, 74612, 73839, 73840, - 73841, 74888, 73838, 73842, 73844, 74891, 74890, 73845, 73846, 74892, - 73847, 73848, 73849, 74613, 73843, 73850, 73852, 73853, 73851, 73854, - 73855, 74614, 73856, 73857, 74894, 74895, 74893, 74896, 74897, 74900, - 74901, 74902, 74899, 74908, 74909, 74907, 74906, 74911, 74912, 74910, - 74913, 74914, 74915, 74916, 74920, 74919, 74898, 74905, 74903, 74904, - 74917, 74918, 73858, 73860, 73861, 73862, 73863, 73864, 73865, 73859, - 73866, 73868, 73867, 73869, 73873, 73874, 73870, 73871, 74922, 74921, - 73872, 73875, 73879, 73883, 73884, 73880, 73881, 73882, 73885, 73887, - 74923, 73886, 73888, 74924, 73889, 74927, 74930, 74931, 74925, 74928, - 74929, 74932, 74926, 73890, 73891, 73892, 73893, 73895, 73896, 73900, - 73901, 73902, 73903, 73904, 73905, 73906, 74616, 74933, 73907, 73908, - 73899, 73897, 73898, 74615, 73894, 73877, 73876, 73878, 73909, 73911, - 73912, 73914, 73913, 73916, 74617, 73917, 74618, 73918, 73915, 74934, - 73920, 73919, 73921, 73922, 73924, 73925, 74935, 74936, 74937, 73926, - 73923, 73929, 73930, 73927, 73928, 74938, 74939, 73932, 74941, 74940, - 73931, 73933, 73934, 73935, 73936, 73937, 74942, 73938, 73939, 73941, - 73940, 73943, 73942, 73945, 73944, 73946, 73947, 74943, 73948, 73949, - 74944, 74945, 74946, 73950, 74947, 73951, 74948, 74949, 74950, 73952, - 73953, 73957, 73958, 73959, 74951, 73955, 73956, 73960, 73962, 73963, - 73964, 73961, 74952, 73954, 73965, 73966, 74953, 73967, 73968, 73969, - 73970, 73971, 73972, 73974, 73975, 73978, 73977, 73976, 73910, 73979, - 73980, 73981, 73973, 73982, 73983, 74954, 74619, 73984, 73985, 73986, - 73987, 73988, 73990, 73989, 73994, 73995, 73998, 73996, 73997, 73999, - 73992, 73993, 74001, 74955, 74004, 74003, 74005, 74002, 74000, 73991, - 74620, 74006, 74008, 74009, 74010, 74956, 74012, 74011, 74013, 74014, - 74957, 74015, 74016, 74017, 74019, 74020, 74021, 74024, 74023, 74022, - 74007, 74018, 74025, 74026, 74958, 74027, 74028, 74029, 74030, 74959, - 74031, 74033, 74036, 74035, 74032, 74034, 74037, 74038, 74039, 74040, - 74043, 74044, 74042, 74041, 74045, 74046, 74621, 74047, 74050, 74052, - 74051, 74053, 74054, 74058, 74057, 74055, 74056, 74059, 74060, 74061, - 74062, 74064, 74065, 74063, 74066, 74067, 74048, 74070, 74049, 74068, - 74069, 74071, 74072, 74073, 74074, 74622, 74075, 74623, 74077, 74076, - 74078, 74079, 74960, 74080, 74081, 74082, 74085, 74086, 74084, 74083, - 74087, 74624, 74090, 74089, 74088, 74091, 74092, 74625, 74093, 74094, - 74096, 74097, 74961, 74095, 74099, 74627, 74098, 74100, 74101, 74103, - 74102, 74104, 74105, 74115, 74629, 74114, 74112, 74113, 74110, 74111, - 74117, 74116, 74118, 74630, 74119, 74962, 74963, 74631, 74122, 74123, - 74120, 74121, 74626, 74107, 74106, 74628, 74108, 74109, 74124, 74125, - 74126, 74131, 74132, 74128, 74129, 74130, 74133, 74134, 74135, 74136, - 74137, 983267, 74138, 74139, 74140, 74141, 74142, 74607, 74127, 74144, - 74146, 74147, 74145, 74152, 74153, 74150, 74151, 74148, 74149, 74154, - 74155, 74157, 74158, 74163, 74164, 74165, 74160, 74161, 74156, 74159, - 74162, 74143, 74166, 74167, 74168, 74169, 74170, 74171, 74172, 74175, - 74173, 74174, 74176, 74177, 74182, 74183, 74180, 74181, 74632, 74186, - 74184, 74185, 74188, 74190, 74189, 74187, 74194, 74195, 74193, 74191, - 74192, 74196, 74197, 74198, 74199, 74200, 74201, 74202, 74205, 74206, - 74207, 74208, 74204, 74209, 74211, 74210, 74212, 74213, 74215, 74214, - 74216, 74218, 74217, 74964, 74178, 74179, 74203, 74219, 74220, 74223, - 74224, 74221, 74222, 74966, 74967, 74974, 74973, 74972, 74969, 74970, - 74971, 74975, 74968, 74965, 74977, 74976, 74980, 74981, 74982, 74984, - 74985, 74978, 74979, 74983, 74986, 74987, 74988, 74989, 74990, 74991, - 74993, 74997, 74996, 74998, 74995, 74994, 74992, 74999, 75000, 75003, - 75004, 75005, 75006, 75001, 75002, 75009, 75015, 75016, 75019, 75017, - 75018, 75013, 75012, 75010, 75011, 75014, 75021, 75030, 75029, 75027, - 75024, 75025, 75028, 75022, 75026, 75023, 75008, 75020, 75031, 75032, - 75007, 74226, 74227, 74228, 74229, 74230, 74225, 74231, 74233, 74234, - 74232, 74235, 74237, 74258, 74259, 75033, 74261, 74633, 74260, 74240, - 74634, 74241, 74243, 75035, 74246, 74247, 74245, 74248, 74249, 74250, - 74251, 75036, 75037, 74254, 74255, 74635, 74256, 75038, 74242, 74252, - 74253, 75034, 74238, 74239, 74244, 74257, 74263, 74265, 74264, 74266, - 74269, 74270, 74271, 74236, 74262, 74267, 74268, 74272, 74273, 74274, - 74278, 74279, 74275, 74276, 74277, 74280, 74281, 74636, 74282, 75039, - 74283, 74284, 74290, 74294, 74295, 75041, 75040, 74292, 74293, 74291, - 74296, 74297, 74298, 74299, 74300, 74637, 74301, 74286, 74287, 74285, - 74289, 74288, 74302, 74304, 74307, 74305, 74306, 74308, 74310, 74309, - 74311, 74303, 74638, 74312, 74314, 74313, 74315, 74316, 74319, 74321, - 74320, 74639, 74322, 74324, 74325, 74323, 74642, 75043, 74326, 75044, - 75046, 75047, 74327, 75048, 74329, 74328, 75049, 74330, 74332, 74333, - 74331, 75050, 75051, 74334, 75052, 74335, 75042, 74641, 75045, 74640, - 74317, 74336, 74318, 74337, 74338, 983266, 983265, 74643, 74339, 74347, - 74348, 74342, 74343, 74341, 74344, 74340, 74346, 74345, 74349, 74355, - 74354, 74350, 74352, 74358, 74359, 74353, 74357, 74351, 74356, 74360, - 74361, 74362, 74363, 74364, 74365, 74366, 74644, 74367, 74375, 74376, - 74368, 74369, 74373, 74374, 74370, 74371, 74372, 74377, 74378, 74379, - 74380, 74381, 74382, 74645, 74383, 74384, 74385, 74386, 74387, 74389, - 74408, 75053, 74388, 74646, 74395, 74394, 75055, 74400, 74399, 75056, - 74401, 74406, 74402, 74403, 74404, 74405, 74391, 74392, 74396, 74398, - 75054, 74397, 74393, 74390, 74407, 74409, 74410, 74411, 74412, 74413, - 74414, 74421, 74422, 74419, 74417, 74420, 74416, 74418, 74415, 74423, - 75057, 74424, 74425, 74426, 75058, 74428, 74429, 75059, 75060, 75061, - 74427, 74432, 74434, 74433, 74430, 74431, 74435, 74437, 74436, 74438, - 74441, 74440, 74444, 74445, 74446, 74448, 74447, 74443, 74449, 74442, - 74439, 74451, 74453, 74452, 74450, 74454, 74455, 74456, 74457, 75063, - 75062, 74458, 74459, 75064, 74460, 74461, 74462, 74463, 74465, 74464, - 74466, 74468, 74469, 74471, 74472, 74473, 74474, 74467, 74470, 74475, - 74477, 74478, 74479, 74476, 74480, 74481, 74482, 74483, 74488, 74486, - 74487, 74485, 74489, 74484, 74490, 75065, 74491, 74494, 74497, 74499, - 74500, 74498, 74495, 74647, 74496, 74501, 74504, 75066, 75067, 74505, - 74506, 74502, 74503, 74492, 74493, 74507, 74510, 74512, 74511, 74649, - 74509, 74508, 74515, 74516, 74522, 74523, 74519, 74520, 74517, 74518, - 74521, 74524, 74534, 74535, 74525, 74526, 74648, 74527, 74528, 74529, - 74531, 74532, 74533, 74530, 74536, 74538, 74537, 74539, 75068, 74540, - 74541, 74542, 74545, 74546, 74547, 75069, 74544, 74543, 74549, 74550, - 74551, 74552, 74553, 75070, 74555, 74556, 74558, 74557, 74559, 74560, - 74562, 74564, 74563, 75072, 74566, 75071, 74570, 74569, 74572, 74574, - 74573, 74554, 74567, 74571, 74565, 74561, 74568, 74575, 74576, 74548, - 74577, 74581, 74579, 74580, 74578, 74584, 74583, 74582, 74586, 74587, - 74588, 74585, 74513, 74514, 74589, 74591, 74590, 74593, 75073, 74592, - 74595, 74598, 74599, 74596, 74601, 74597, 74600, 74602, 75074, 74603, - 75075, 74604, 74605, 74606, 74594, 9982, 129380, 11232, 129473, 8911, - 8910, 10160, 9130, 129356, 128177, 164, 127835, 10081, 128707, 127854, - 129362, 129385, 67594, 67595, 67596, 67597, 67598, 67599, 67600, 67601, - 67602, 67603, 67604, 67605, 67606, 67607, 67608, 67609, 67610, 67611, - 67612, 67613, 67614, 67615, 67616, 67617, 67618, 67619, 67620, 67621, - 67622, 67623, 67624, 67625, 67626, 67627, 67628, 67629, 67630, 67631, - 67632, 67633, 67634, 67635, 67636, 67637, 67589, 67592, 67644, 67647, - 67639, 67640, 67584, 67585, 67586, 67587, 67588, 77712, 77713, 77714, - 77715, 77716, 77717, 77718, 77719, 77722, 77723, 77720, 77721, 77724, - 77725, 77726, 77727, 77728, 77729, 77730, 77731, 77732, 77733, 77734, - 77735, 77736, 77737, 77738, 77739, 77740, 77741, 77742, 77743, 77744, - 77745, 77746, 77747, 77748, 77749, 77750, 77751, 77752, 77753, 77754, - 77755, 77756, 77757, 77758, 77773, 77774, 77768, 77769, 77770, 77771, - 77772, 77775, 77776, 77777, 77788, 77789, 77790, 77791, 77792, 77793, - 77794, 77795, 77796, 77759, 77760, 77761, 77762, 77763, 77764, 77765, - 77766, 77767, 77778, 77779, 77780, 77781, 77782, 77783, 77784, 77785, - 77786, 77787, 77797, 77798, 77799, 77800, 77801, 77802, 77803, 77804, - 77805, 77806, 77807, 77808, 77809, 77810, 1126, 1033, 1300, 42574, 1034, - 1055, 1190, 1316, 1136, 1146, 42564, 42592, 42580, 1296, 1302, 1058, - 42634, 1196, 1035, 42640, 42638, 1062, 42642, 7305, 42636, 1059, 1266, - 1264, 1262, 1144, 1028, 1040, 1234, 1232, 1212, 1214, 1248, 1192, 1310, - 1256, 1258, 1184, 42602, 1130, 42572, 42586, 1030, 1041, 1063, 1268, - 1206, 1208, 42584, 42650, 42630, 1026, 42568, 42604, 42648, 1029, 42562, - 1322, 42632, 1039, 42626, 1324, 42624, 1044, 1069, 1051, 1312, 1326, - 1221, 1298, 1053, 1314, 1186, 1320, 1225, 1223, 1056, 1166, 1260, 1057, - 1194, 1052, 1229, 1060, 1043, 1172, 1168, 1270, 1170, 1274, 1027, 1061, - 1202, 1276, 1278, 1066, 42644, 1048, 1252, 1037, 1250, 1045, 1024, 1238, - 1025, 42588, 1128, 1132, 42578, 42582, 1124, 42566, 1140, 1142, 1050, - 1178, 1219, 1180, 1182, 1286, 1282, 1280, 1288, 1290, 1292, 1294, 1284, - 1152, 1227, 1036, 1134, 42600, 42570, 1054, 1120, 1148, 1254, 1150, 1240, - 1242, 1049, 1162, 1038, 1210, 1318, 1065, 42646, 1064, 42596, 42598, - 1068, 42594, 1198, 1200, 1164, 1071, 1304, 1122, 1067, 1272, 42576, 1031, - 42590, 1070, 1047, 1246, 1176, 42560, 1046, 1244, 1174, 1217, 42628, - 1138, 1032, 1042, 1308, 1306, 1236, 1204, 1188, 42622, 42606, 1216, 7467, - 42623, 1072, 1235, 1233, 1213, 1215, 1249, 1193, 1311, 1257, 1259, 1185, - 42603, 1131, 42573, 42587, 1110, 1073, 1095, 1269, 1207, 1209, 42585, - 42651, 42631, 1106, 42569, 42605, 42649, 1109, 42563, 1323, 42633, 1119, - 42627, 1325, 42625, 1076, 1101, 1083, 1313, 1327, 1222, 1299, 1085, 1315, - 1187, 1321, 1226, 1224, 1088, 1167, 1261, 1089, 1195, 1084, 1230, 1092, - 1075, 1173, 1169, 1271, 1171, 1275, 1107, 1093, 1203, 1277, 1279, 1098, - 42645, 1080, 1253, 1117, 1251, 1077, 1104, 1239, 1105, 42589, 1129, 1133, - 42579, 42583, 1125, 42567, 1141, 1143, 1082, 1179, 1220, 1181, 1183, - 1287, 1283, 1281, 1289, 1291, 1293, 1295, 1285, 1153, 1228, 1116, 1135, - 1127, 7297, 1113, 1301, 42601, 42571, 42575, 7298, 1114, 1086, 1121, - 1149, 1255, 1151, 1087, 1191, 1317, 1231, 1137, 42565, 42593, 42581, - 1297, 1147, 7296, 1303, 1241, 1243, 1081, 1163, 1118, 1211, 1319, 1097, - 42647, 1096, 42597, 42599, 1100, 42595, 1199, 1201, 1165, 7302, 7303, - 7300, 1090, 42635, 1197, 1115, 42641, 42639, 1094, 7301, 42643, 7306, - 42637, 1091, 1267, 1265, 1263, 1145, 1108, 7304, 7299, 1309, 1103, 1305, - 1123, 1099, 1273, 42577, 1111, 42591, 1102, 1079, 1247, 1177, 42561, - 1078, 1245, 1175, 1218, 42629, 1139, 1112, 1074, 1307, 1237, 1205, 1189, - 122984, 122962, 122986, 122985, 122965, 122976, 122971, 122974, 122964, - 122983, 122977, 122981, 122982, 122980, 122978, 122967, 122968, 122969, - 122966, 122979, 122973, 122963, 122970, 122961, 122972, 122975, 1154, - 9005, 127744, 983201, 983188, 983172, 8224, 11830, 11831, 128481, 128131, - 127841, 128374, 9619, 11843, 128168, 10143, 65101, 65097, 8504, 983081, - 983084, 983086, 983088, 983090, 983162, 9110, 9192, 127795, 128475, 8451, - 176, 8457, 983120, 128666, 8796, 983119, 9161, 9159, 9153, 9156, 9162, - 9160, 9154, 9157, 9164, 9151, 9163, 9150, 9158, 9152, 9155, 117829, - 117828, 127980, 127962, 9739, 66589, 66591, 66596, 66597, 66587, 66585, - 66594, 66595, 66593, 66599, 66562, 66563, 66564, 66565, 66561, 66560, - 66568, 66569, 66570, 66571, 66567, 66566, 66598, 66573, 66588, 66579, - 66592, 66590, 66581, 66578, 66580, 66582, 66577, 66586, 66575, 66584, - 66583, 66574, 66572, 66576, 66629, 66631, 66636, 66637, 66627, 66625, - 66634, 66635, 66633, 66639, 66602, 66603, 66604, 66605, 66601, 66600, - 66608, 66609, 66610, 66611, 66607, 66606, 66638, 66613, 66628, 66619, - 66632, 66630, 66621, 66618, 66620, 66622, 66617, 66626, 66615, 66624, - 66623, 66614, 66612, 66616, 127964, 127965, 128421, 128468, 2388, 2416, - 43258, 2387, 43257, 72448, 72449, 43259, 2309, 2310, 2320, 2324, 2421, - 43262, 2330, 2418, 2317, 2321, 2331, 2396, 2430, 2338, 2337, 2343, 2342, - 2429, 2394, 2328, 2427, 2327, 2426, 2361, 2350, 2424, 2308, 2318, 2322, - 2358, 2359, 2360, 2431, 2349, 2348, 2393, 2326, 2325, 2397, 2353, 2352, - 2323, 2420, 2419, 2399, 2351, 2313, 2314, 2423, 2422, 2345, 2339, 2329, - 2334, 2344, 2333, 2428, 2332, 2356, 2355, 2354, 2336, 2335, 2341, 2340, - 2315, 2400, 2316, 2401, 2357, 2311, 2312, 2347, 2346, 2425, 2395, 2398, - 2392, 2319, 983644, 983643, 983646, 983647, 983649, 983648, 983642, + 10768, 127914, 127961, 127750, 11946, 12003, 11910, 11963, 11962, 11950, + 11992, 12012, 12000, 12005, 11996, 12010, 11984, 11988, 11994, 11987, + 11952, 12007, 11977, 11976, 11973, 12019, 11993, 12014, 11995, 12016, + 12006, 12002, 11979, 11936, 11983, 11905, 11970, 11943, 11931, 11914, + 11934, 11944, 11999, 11998, 11997, 11960, 11947, 11939, 11978, 11968, + 11967, 11966, 12004, 11927, 11926, 12001, 11975, 11928, 12018, 12013, + 12015, 12011, 11945, 11986, 11985, 11921, 11920, 11919, 11918, 11964, + 11957, 11990, 11989, 11935, 11965, 11933, 11941, 11940, 11909, 11991, + 11959, 11929, 11904, 11908, 11907, 11906, 11915, 11942, 11974, 11980, + 12008, 12009, 11951, 11925, 11924, 11922, 11949, 11948, 11917, 11916, + 11958, 11932, 12017, 11911, 11923, 11969, 11982, 11981, 11938, 11937, + 11972, 11971, 11956, 11955, 11954, 11953, 11913, 11912, 11961, 12752, + 12743, 12748, 12768, 12772, 12757, 12741, 12750, 12769, 12747, 12749, + 12744, 12742, 12746, 12758, 12754, 12763, 12770, 12764, 12753, 12740, + 12767, 12760, 12759, 12745, 12773, 12766, 12762, 12755, 12761, 12736, + 12765, 12739, 12737, 12738, 12756, 12751, 12771, 128079, 127916, 127963, + 128385, 129346, 127867, 128203, 128346, 128358, 128343, 128355, 128340, + 128352, 128339, 128351, 128344, 128356, 128336, 128348, 128342, 128354, + 128341, 128353, 128345, 128357, 128347, 128359, 128337, 128349, 128338, + 128350, 10561, 8754, 128259, 10227, 128472, 128257, 128258, 8631, 11118, + 8635, 8753, 10959, 10961, 10960, 10962, 127746, 10828, 10832, 128234, + 128235, 128272, 128213, 10829, 8272, 9729, 127786, 127785, 127784, + 127783, 129313, 9114, 129715, 127864, 129381, 58, 8788, 8353, 128165, + 6867, 7625, 7623, 769, 791, 833, 8410, 8404, 8423, 857, 8432, 7677, 844, + 774, 7627, 814, 810, 838, 70459, 780, 812, 784, 8409, 8405, 787, 789, + 806, 65062, 65069, 42609, 1160, 11774, 11744, 11768, 11747, 11757, 11765, + 42654, 11751, 11752, 11753, 11756, 42613, 11775, 11772, 42655, 11767, + 11754, 42619, 11763, 11762, 42618, 42615, 42612, 42617, 11770, 42614, + 11771, 11773, 11769, 11759, 42616, 11760, 11758, 11748, 11749, 11761, + 11746, 11764, 11755, 11745, 11750, 11766, 42621, 1156, 1158, 1159, 1157, + 42608, 42610, 1155, 65070, 65071, 1161, 42620, 123023, 42607, 770, 813, + 807, 43248, 43244, 43245, 43246, 43247, 43242, 43243, 43249, 43237, + 43236, 43239, 43238, 43235, 43234, 43232, 43241, 43233, 43240, 7675, 776, + 804, 6876, 6833, 775, 7672, 856, 803, 7674, 6877, 7617, 7616, 6886, 6887, + 779, 861, 860, 865, 7676, 6863, 7629, 862, 863, 6840, 831, 6858, 6857, + 6844, 866, 6891, 858, 864, 65058, 65059, 8422, 840, 782, 783, 819, 6832, + 798, 6875, 6835, 8413, 8416, 8418, 8414, 8419, 8420, 8415, 839, 6888, + 850, 8412, 6874, 122892, 122884, 122891, 122890, 122921, 122919, 122889, + 122916, 122900, 122907, 122910, 122901, 122908, 122880, 122920, 122881, + 122909, 122903, 122922, 122883, 122895, 122894, 122896, 122898, 122899, + 122882, 122885, 122912, 122911, 122913, 122918, 122915, 122888, 122886, + 122904, 122902, 122897, 122893, 70508, 70507, 70506, 70505, 70504, 70502, + 70503, 70515, 70513, 70514, 70516, 70512, 768, 790, 832, 6865, 7624, + 7621, 847, 119363, 119362, 119364, 835, 834, 837, 836, 777, 843, 795, + 785, 815, 826, 6883, 811, 6855, 6834, 7632, 12442, 12441, 7671, 7670, + 7643, 7646, 7647, 7649, 7650, 867, 7666, 7655, 7636, 7637, 7638, 872, + 7639, 868, 7663, 7641, 7659, 7635, 869, 7640, 6860, 6861, 6862, 7645, + 7660, 7653, 870, 7667, 7661, 871, 7668, 7664, 876, 7651, 7626, 877, 6848, + 7652, 7658, 7656, 7657, 7665, 6847, 873, 7642, 874, 7644, 875, 7648, + 7662, 878, 879, 7654, 6889, 841, 794, 852, 7678, 8430, 8406, 6849, 6851, + 796, 849, 8400, 792, 6880, 845, 8417, 8429, 8426, 65056, 65063, 65057, + 65064, 6841, 8427, 824, 822, 8402, 818, 772, 65060, 65067, 65061, 65068, + 817, 6869, 7620, 6872, 7622, 7628, 800, 6882, 6854, 842, 66424, 66425, + 66423, 66426, 66422, 6839, 808, 7630, 773, 6846, 6845, 6843, 801, 799, + 6856, 8421, 788, 802, 7679, 854, 848, 853, 8431, 8407, 825, 855, 8401, + 6850, 6852, 793, 6881, 8428, 8408, 805, 778, 7631, 859, 823, 821, 8403, + 6873, 6853, 827, 6884, 6842, 7619, 7618, 828, 6885, 8411, 771, 65065, + 65066, 820, 816, 6859, 8424, 6836, 786, 797, 7669, 846, 6890, 7633, 7634, + 809, 781, 830, 6864, 6870, 6866, 6871, 6868, 7673, 8425, 6838, 6837, 851, + 829, 8274, 64, 44, 128476, 9092, 8705, 129517, 9732, 127882, 128533, + 128534, 128119, 128679, 8715, 8883, 8885, 8954, 8955, 8957, 8750, 127899, + 983187, 9089, 127978, 9010, 9740, 10861, 127859, 127850, 127834, 11505, + 11504, 11503, 11464, 11392, 11506, 11499, 11501, 11446, 11452, 11458, + 11466, 11442, 11448, 11450, 11398, 1006, 1002, 11396, 1000, 11406, 998, + 11436, 11412, 11420, 996, 11434, 11472, 11414, 11422, 11478, 11468, + 11470, 11476, 11474, 11482, 11460, 11480, 11454, 11462, 11444, 11486, + 11488, 11484, 11490, 11440, 1004, 994, 11456, 11402, 11428, 11408, 11430, + 11404, 11394, 11438, 11424, 11410, 11426, 11400, 11416, 11418, 11432, + 66298, 66289, 66295, 66286, 66294, 66285, 66299, 66290, 66291, 66297, + 66288, 66296, 66287, 66293, 66284, 66292, 66283, 66282, 66277, 66276, + 66279, 66278, 66275, 66274, 66281, 66273, 66280, 66272, 11517, 11518, + 11514, 11515, 11516, 11513, 11465, 11393, 11507, 11500, 11502, 11447, + 11453, 11459, 11467, 11443, 11449, 11451, 11399, 1007, 1003, 11397, 1001, + 11407, 999, 11437, 11413, 11421, 997, 11435, 11473, 11415, 11423, 11479, + 11469, 11471, 11477, 11475, 11483, 11461, 11481, 11455, 11463, 11445, + 11487, 11489, 11485, 11491, 11441, 1005, 995, 11457, 11403, 11429, 11409, + 11431, 11405, 11395, 11439, 11425, 11411, 11427, 11401, 11417, 11419, + 11433, 11497, 11492, 11493, 11494, 11498, 11495, 11496, 11519, 127279, + 169, 11855, 8792, 129720, 9012, 9013, 119661, 119660, 119663, 119662, + 119659, 119658, 119665, 119657, 119664, 119652, 119651, 119654, 119653, + 119650, 119649, 119656, 119648, 119655, 128715, 128145, 128004, 128046, + 9904, 129689, 129509, 983074, 128179, 127769, 129431, 127951, 9769, 9768, + 11856, 11857, 128322, 128321, 10060, 127370, 127884, 9876, 9932, 128010, + 129360, 128081, 8354, 129660, 128575, 128546, 128302, 129408, 8731, + 74794, 74771, 74861, 74780, 74820, 74821, 74765, 74758, 74853, 74856, + 74855, 74854, 74791, 74801, 74844, 74836, 74837, 74809, 74755, 74829, + 74777, 74786, 74768, 74858, 74762, 74834, 74835, 74808, 74812, 74814, + 74815, 74813, 74754, 74828, 74776, 74785, 74790, 74800, 74767, 74857, + 74761, 74839, 74838, 74822, 74825, 74823, 74824, 74795, 74772, 74862, + 74781, 74766, 74759, 74849, 74850, 74840, 74847, 74848, 74851, 74831, + 74804, 74773, 74782, 74845, 74842, 74796, 74852, 74818, 74819, 74817, + 74793, 74770, 74860, 74779, 74764, 74757, 74802, 74803, 74792, 74756, + 74830, 74769, 74859, 74778, 74816, 74763, 74806, 74807, 74833, 74788, + 74789, 74798, 74799, 74810, 74811, 74753, 74827, 74775, 74784, 74760, + 74752, 74826, 74832, 74805, 74841, 74774, 74783, 74787, 74797, 74846, + 74843, 74867, 74868, 74866, 74865, 74864, 73728, 73734, 73731, 73733, + 73735, 73736, 73730, 73732, 73729, 73738, 73742, 73741, 73744, 73745, + 74881, 73747, 73748, 73740, 73739, 74608, 74880, 73746, 73743, 73749, + 73750, 73753, 73752, 73754, 73755, 73751, 74609, 73756, 74882, 73757, + 73759, 73758, 73760, 73765, 73766, 73762, 73763, 73768, 73761, 73767, + 73764, 73770, 73769, 73771, 74610, 73772, 73773, 73776, 73777, 73775, + 73774, 73778, 73780, 73781, 73782, 73784, 73788, 73789, 73787, 73785, + 73786, 73791, 73790, 73783, 73779, 73737, 73792, 73793, 74883, 73795, + 74884, 74885, 74886, 73796, 73797, 73798, 73799, 73800, 73794, 73801, + 73804, 73803, 73802, 73805, 74887, 73806, 73807, 73808, 73809, 73810, + 73811, 73812, 73813, 73814, 73815, 73816, 73817, 73818, 73819, 73820, + 73821, 73822, 73823, 73825, 73826, 73829, 73830, 73831, 73828, 73836, + 74611, 73837, 73833, 73835, 73827, 73832, 73834, 73824, 74889, 74612, + 73839, 73840, 73841, 74888, 73838, 73842, 73844, 74891, 74890, 73845, + 73846, 74892, 73847, 73848, 73849, 74613, 73843, 73850, 73852, 73853, + 73851, 73854, 73855, 74614, 73856, 73857, 74894, 74895, 74893, 74896, + 74897, 74900, 74901, 74902, 74899, 74908, 74909, 74907, 74906, 74911, + 74912, 74910, 74913, 74914, 74915, 74916, 74920, 74919, 74898, 74905, + 74903, 74904, 74917, 74918, 73858, 73860, 73861, 73862, 73863, 73864, + 73865, 73859, 73866, 73868, 73867, 73869, 73873, 73874, 73870, 73871, + 74922, 74921, 73872, 73875, 73879, 73883, 73884, 73880, 73881, 73882, + 73885, 73887, 74923, 73886, 73888, 74924, 73889, 74927, 74930, 74931, + 74925, 74928, 74929, 74932, 74926, 73890, 73891, 73892, 73893, 73895, + 73896, 73900, 73901, 73902, 73903, 73904, 73905, 73906, 74616, 74933, + 73907, 73908, 73899, 73897, 73898, 74615, 73894, 73877, 73876, 73878, + 73909, 73911, 73912, 73914, 73913, 73916, 74617, 73917, 74618, 73918, + 73915, 74934, 73920, 73919, 73921, 73922, 73924, 73925, 74935, 74936, + 74937, 73926, 73923, 73929, 73930, 73927, 73928, 74938, 74939, 73932, + 74941, 74940, 73931, 73933, 73934, 73935, 73936, 73937, 74942, 73938, + 73939, 73941, 73940, 73943, 73942, 73945, 73944, 73946, 73947, 74943, + 73948, 73949, 74944, 74945, 74946, 73950, 74947, 73951, 74948, 74949, + 74950, 73952, 73953, 73957, 73958, 73959, 74951, 73955, 73956, 73960, + 73962, 73963, 73964, 73961, 74952, 73954, 73965, 73966, 74953, 73967, + 73968, 73969, 73970, 73971, 73972, 73974, 73975, 73978, 73977, 73976, + 73910, 73979, 73980, 73981, 73973, 73982, 73983, 74954, 74619, 73984, + 73985, 73986, 73987, 73988, 73990, 73989, 73994, 73995, 73998, 73996, + 73997, 73999, 73992, 73993, 74001, 74955, 74004, 74003, 74005, 74002, + 74000, 73991, 74620, 74006, 74008, 74009, 74010, 74956, 74012, 74011, + 74013, 74014, 74957, 74015, 74016, 74017, 74019, 74020, 74021, 74024, + 74023, 74022, 74007, 74018, 74025, 74026, 74958, 74027, 74028, 74029, + 74030, 74959, 74031, 74033, 74036, 74035, 74032, 74034, 74037, 74038, + 74039, 74040, 74043, 74044, 74042, 74041, 74045, 74046, 74621, 74047, + 74050, 74052, 74051, 74053, 74054, 74058, 74057, 74055, 74056, 74059, + 74060, 74061, 74062, 74064, 74065, 74063, 74066, 74067, 74048, 74070, + 74049, 74068, 74069, 74071, 74072, 74073, 74074, 74622, 74075, 74623, + 74077, 74076, 74078, 74079, 74960, 74080, 74081, 74082, 74085, 74086, + 74084, 74083, 74087, 74624, 74090, 74089, 74088, 74091, 74092, 74625, + 74093, 74094, 74096, 74097, 74961, 74095, 74099, 74627, 74098, 74100, + 74101, 74103, 74102, 74104, 74105, 74115, 74629, 74114, 74112, 74113, + 74110, 74111, 74117, 74116, 74118, 74630, 74119, 74962, 74963, 74631, + 74122, 74123, 74120, 74121, 74626, 74107, 74106, 74628, 74108, 74109, + 74124, 74125, 74126, 74131, 74132, 74128, 74129, 74130, 74133, 74134, + 74135, 74136, 74137, 983267, 74138, 74139, 74140, 74141, 74142, 74607, + 74127, 74144, 74146, 74147, 74145, 74152, 74153, 74150, 74151, 74148, + 74149, 74154, 74155, 74157, 74158, 74163, 74164, 74165, 74160, 74161, + 74156, 74159, 74162, 74143, 74166, 74167, 74168, 74169, 74170, 74171, + 74172, 74175, 74173, 74174, 74176, 74177, 74182, 74183, 74180, 74181, + 74632, 74186, 74184, 74185, 74188, 74190, 74189, 74187, 74194, 74195, + 74193, 74191, 74192, 74196, 74197, 74198, 74199, 74200, 74201, 74202, + 74205, 74206, 74207, 74208, 74204, 74209, 74211, 74210, 74212, 74213, + 74215, 74214, 74216, 74218, 74217, 74964, 74178, 74179, 74203, 74219, + 74220, 74223, 74224, 74221, 74222, 74966, 74967, 74974, 74973, 74972, + 74969, 74970, 74971, 74975, 74968, 74965, 74977, 74976, 74980, 74981, + 74982, 74984, 74985, 74978, 74979, 74983, 74986, 74987, 74988, 74989, + 74990, 74991, 74993, 74997, 74996, 74998, 74995, 74994, 74992, 74999, + 75000, 75003, 75004, 75005, 75006, 75001, 75002, 75009, 75015, 75016, + 75019, 75017, 75018, 75013, 75012, 75010, 75011, 75014, 75021, 75030, + 75029, 75027, 75024, 75025, 75028, 75022, 75026, 75023, 75008, 75020, + 75031, 75032, 75007, 74226, 74227, 74228, 74229, 74230, 74225, 74231, + 74233, 74234, 74232, 74235, 74237, 74258, 74259, 75033, 74261, 74633, + 74260, 74240, 74634, 74241, 74243, 75035, 74246, 74247, 74245, 74248, + 74249, 74250, 74251, 75036, 75037, 74254, 74255, 74635, 74256, 75038, + 74242, 74252, 74253, 75034, 74238, 74239, 74244, 74257, 74263, 74265, + 74264, 74266, 74269, 74270, 74271, 74236, 74262, 74267, 74268, 74272, + 74273, 74274, 74278, 74279, 74275, 74276, 74277, 74280, 74281, 74636, + 74282, 75039, 74283, 74284, 74290, 74294, 74295, 75041, 75040, 74292, + 74293, 74291, 74296, 74297, 74298, 74299, 74300, 74637, 74301, 74286, + 74287, 74285, 74289, 74288, 74302, 74304, 74307, 74305, 74306, 74308, + 74310, 74309, 74311, 74303, 74638, 74312, 74314, 74313, 74315, 74316, + 74319, 74321, 74320, 74639, 74322, 74324, 74325, 74323, 74642, 75043, + 74326, 75044, 75046, 75047, 74327, 75048, 74329, 74328, 75049, 74330, + 74332, 74333, 74331, 75050, 75051, 74334, 75052, 74335, 75042, 74641, + 75045, 74640, 74317, 74336, 74318, 74337, 74338, 983266, 983265, 74643, + 74339, 74347, 74348, 74342, 74343, 74341, 74344, 74340, 74346, 74345, + 74349, 74355, 74354, 74350, 74352, 74358, 74359, 74353, 74357, 74351, + 74356, 74360, 74361, 74362, 74363, 74364, 74365, 74366, 74644, 74367, + 74375, 74376, 74368, 74369, 74373, 74374, 74370, 74371, 74372, 74377, + 74378, 74379, 74380, 74381, 74382, 74645, 74383, 74384, 74385, 74386, + 74387, 74389, 74408, 75053, 74388, 74646, 74395, 74394, 75055, 74400, + 74399, 75056, 74401, 74406, 74402, 74403, 74404, 74405, 74391, 74392, + 74396, 74398, 75054, 74397, 74393, 74390, 74407, 74409, 74410, 74411, + 74412, 74413, 74414, 74421, 74422, 74419, 74417, 74420, 74416, 74418, + 74415, 74423, 75057, 74424, 74425, 74426, 75058, 74428, 74429, 75059, + 75060, 75061, 74427, 74432, 74434, 74433, 74430, 74431, 74435, 74437, + 74436, 74438, 74441, 74440, 74444, 74445, 74446, 74448, 74447, 74443, + 74449, 74442, 74439, 74451, 74453, 74452, 74450, 74454, 74455, 74456, + 74457, 75063, 75062, 74458, 74459, 75064, 74460, 74461, 74462, 74463, + 74465, 74464, 74466, 74468, 74469, 74471, 74472, 74473, 74474, 74467, + 74470, 74475, 74477, 74478, 74479, 74476, 74480, 74481, 74482, 74483, + 74488, 74486, 74487, 74485, 74489, 74484, 74490, 75065, 74491, 74494, + 74497, 74499, 74500, 74498, 74495, 74647, 74496, 74501, 74504, 75066, + 75067, 74505, 74506, 74502, 74503, 74492, 74493, 74507, 74510, 74512, + 74511, 74649, 74509, 74508, 74515, 74516, 74522, 74523, 74519, 74520, + 74517, 74518, 74521, 74524, 74534, 74535, 74525, 74526, 74648, 74527, + 74528, 74529, 74531, 74532, 74533, 74530, 74536, 74538, 74537, 74539, + 75068, 74540, 74541, 74542, 74545, 74546, 74547, 75069, 74544, 74543, + 74549, 74550, 74551, 74552, 74553, 75070, 74555, 74556, 74558, 74557, + 74559, 74560, 74562, 74564, 74563, 75072, 74566, 75071, 74570, 74569, + 74572, 74574, 74573, 74554, 74567, 74571, 74565, 74561, 74568, 74575, + 74576, 74548, 74577, 74581, 74579, 74580, 74578, 74584, 74583, 74582, + 74586, 74587, 74588, 74585, 74513, 74514, 74589, 74591, 74590, 74593, + 75073, 74592, 74595, 74598, 74599, 74596, 74601, 74597, 74600, 74602, + 75074, 74603, 75075, 74604, 74605, 74606, 74594, 9982, 129380, 11232, + 129473, 8911, 8910, 10160, 9130, 129356, 128177, 164, 127835, 10081, + 128707, 127854, 129362, 129385, 67594, 67595, 67596, 67597, 67598, 67599, + 67600, 67601, 67602, 67603, 67604, 67605, 67606, 67607, 67608, 67609, + 67610, 67611, 67612, 67613, 67614, 67615, 67616, 67617, 67618, 67619, + 67620, 67621, 67622, 67623, 67624, 67625, 67626, 67627, 67628, 67629, + 67630, 67631, 67632, 67633, 67634, 67635, 67636, 67637, 67589, 67592, + 67644, 67647, 67639, 67640, 67584, 67585, 67586, 67587, 67588, 77712, + 77713, 77714, 77715, 77716, 77717, 77718, 77719, 77722, 77723, 77720, + 77721, 77724, 77725, 77726, 77727, 77728, 77729, 77730, 77731, 77732, + 77733, 77734, 77735, 77736, 77737, 77738, 77739, 77740, 77741, 77742, + 77743, 77744, 77745, 77746, 77747, 77748, 77749, 77750, 77751, 77752, + 77753, 77754, 77755, 77756, 77757, 77758, 77773, 77774, 77768, 77769, + 77770, 77771, 77772, 77775, 77776, 77777, 77788, 77789, 77790, 77791, + 77792, 77793, 77794, 77795, 77796, 77759, 77760, 77761, 77762, 77763, + 77764, 77765, 77766, 77767, 77778, 77779, 77780, 77781, 77782, 77783, + 77784, 77785, 77786, 77787, 77797, 77798, 77799, 77800, 77801, 77802, + 77803, 77804, 77805, 77806, 77807, 77808, 77809, 77810, 1126, 1033, 1300, + 42574, 1034, 1055, 1190, 1316, 1136, 1146, 42564, 42592, 42580, 1296, + 1302, 1058, 42634, 1196, 1035, 42640, 42638, 1062, 42642, 7305, 42636, + 1059, 1266, 1264, 1262, 1144, 1028, 1040, 1234, 1232, 1212, 1214, 1248, + 1192, 1310, 1256, 1258, 1184, 42602, 1130, 42572, 42586, 1030, 1041, + 1063, 1268, 1206, 1208, 42584, 42650, 42630, 1026, 42568, 42604, 42648, + 1029, 42562, 1322, 42632, 1039, 42626, 1324, 42624, 1044, 1069, 1051, + 1312, 1326, 1221, 1298, 1053, 1314, 1186, 1320, 1225, 1223, 1056, 1166, + 1260, 1057, 1194, 1052, 1229, 1060, 1043, 1172, 1168, 1270, 1170, 1274, + 1027, 1061, 1202, 1276, 1278, 1066, 42644, 1048, 1252, 1037, 1250, 1045, + 1024, 1238, 1025, 42588, 1128, 1132, 42578, 42582, 1124, 42566, 1140, + 1142, 1050, 1178, 1219, 1180, 1182, 1286, 1282, 1280, 1288, 1290, 1292, + 1294, 1284, 1152, 1227, 1036, 1134, 42600, 42570, 1054, 1120, 1148, 1254, + 1150, 1240, 1242, 1049, 1162, 1038, 1210, 1318, 1065, 42646, 1064, 42596, + 42598, 1068, 42594, 1198, 1200, 1164, 1071, 1304, 1122, 1067, 1272, + 42576, 1031, 42590, 1070, 1047, 1246, 1176, 42560, 1046, 1244, 1174, + 1217, 42628, 1138, 1032, 1042, 1308, 1306, 1236, 1204, 1188, 42622, + 42606, 1216, 7467, 42623, 1072, 1235, 1233, 1213, 1215, 1249, 1193, 1311, + 1257, 1259, 1185, 42603, 1131, 42573, 42587, 1110, 1073, 1095, 1269, + 1207, 1209, 42585, 42651, 42631, 1106, 42569, 42605, 42649, 1109, 42563, + 1323, 42633, 1119, 42627, 1325, 42625, 1076, 1101, 1083, 1313, 1327, + 1222, 1299, 1085, 1315, 1187, 1321, 1226, 1224, 1088, 1167, 1261, 1089, + 1195, 1084, 1230, 1092, 1075, 1173, 1169, 1271, 1171, 1275, 1107, 1093, + 1203, 1277, 1279, 1098, 42645, 1080, 1253, 1117, 1251, 1077, 1104, 1239, + 1105, 42589, 1129, 1133, 42579, 42583, 1125, 42567, 1141, 1143, 1082, + 1179, 1220, 1181, 1183, 1287, 1283, 1281, 1289, 1291, 1293, 1295, 1285, + 1153, 1228, 1116, 1135, 1127, 7297, 1113, 1301, 42601, 42571, 42575, + 7298, 1114, 1086, 1121, 1149, 1255, 1151, 1087, 1191, 1317, 1231, 1137, + 42565, 42593, 42581, 1297, 1147, 7296, 1303, 1241, 1243, 1081, 1163, + 1118, 1211, 1319, 1097, 42647, 1096, 42597, 42599, 1100, 42595, 1199, + 1201, 1165, 7302, 7303, 7300, 1090, 42635, 1197, 1115, 42641, 42639, + 1094, 7301, 42643, 7306, 42637, 1091, 1267, 1265, 1263, 1145, 1108, 7304, + 7299, 1309, 1103, 1305, 1123, 1099, 1273, 42577, 1111, 42591, 1102, 1079, + 1247, 1177, 42561, 1078, 1245, 1175, 1218, 42629, 1139, 1112, 1074, 1307, + 1237, 1205, 1189, 122984, 122962, 122986, 122985, 122965, 122976, 122971, + 122974, 122964, 122983, 122977, 122981, 122982, 122980, 122978, 122967, + 122968, 122969, 122966, 122979, 122973, 122963, 122970, 122961, 122972, + 122975, 1154, 9005, 127744, 983201, 983188, 983172, 8224, 11830, 11831, + 128481, 128131, 127841, 128374, 9619, 11843, 128168, 10143, 65101, 65097, + 8504, 983081, 983084, 983086, 983088, 983090, 983162, 9110, 9192, 127795, + 128475, 8451, 176, 8457, 983120, 128666, 8796, 983119, 9161, 9159, 9153, + 9156, 9162, 9160, 9154, 9157, 9164, 9151, 9163, 9150, 9158, 9152, 9155, + 117829, 117828, 127980, 127962, 9739, 66589, 66591, 66596, 66597, 66587, + 66585, 66594, 66595, 66593, 66599, 66562, 66563, 66564, 66565, 66561, + 66560, 66568, 66569, 66570, 66571, 66567, 66566, 66598, 66573, 66588, + 66579, 66592, 66590, 66581, 66578, 66580, 66582, 66577, 66586, 66575, + 66584, 66583, 66574, 66572, 66576, 66629, 66631, 66636, 66637, 66627, + 66625, 66634, 66635, 66633, 66639, 66602, 66603, 66604, 66605, 66601, + 66600, 66608, 66609, 66610, 66611, 66607, 66606, 66638, 66613, 66628, + 66619, 66632, 66630, 66621, 66618, 66620, 66622, 66617, 66626, 66615, + 66624, 66623, 66614, 66612, 66616, 127964, 127965, 128421, 128468, 2388, + 2416, 43258, 2387, 43257, 72448, 72449, 43259, 2309, 2310, 2320, 2324, + 2421, 43262, 2330, 2418, 2317, 2321, 2331, 2396, 2430, 2338, 2337, 2343, + 2342, 2429, 2394, 2328, 2427, 2327, 2426, 2361, 2350, 2424, 2308, 2318, + 2322, 2358, 2359, 2360, 2431, 2349, 2348, 2393, 2326, 2325, 2397, 2353, + 2352, 2323, 2420, 2419, 2399, 2351, 2313, 2314, 2423, 2422, 2345, 2339, + 2329, 2334, 2344, 2333, 2428, 2332, 2356, 2355, 2354, 2336, 2335, 2341, + 2340, 2315, 2400, 2316, 2401, 2357, 2311, 2312, 2347, 2346, 2425, 2395, + 2398, 2392, 2319, 983644, 983643, 983646, 983647, 983649, 983648, 983642, 983645, 72450, 72451, 72452, 72453, 2305, 43255, 43251, 43254, 43253, 72455, 72454, 72456, 43250, 43260, 2304, 72457, 2364, 2365, 2306, 43252, 43256, 2417, 2381, 2307, 2386, 2385, 2366, 2376, 2380, 2383, 43263, 2389, @@ -10582,619 +10446,219 @@ static const unsigned int dawg_pos_to_codepoint[] = { 78845, 78846, 78847, 78848, 78849, 78850, 78851, 78852, 78853, 78854, 78855, 78856, 78857, 78858, 78859, 78860, 78837, 78838, 78839, 78840, 78841, 78235, 78236, 78237, 78238, 78239, 78240, 78241, 78242, 78504, - 78505, 78506, 78507, 78508, 78509, 78510, 78944, 78945, 78946, 78947, - 78948, 78949, 78950, 78951, 78952, 78953, 78954, 78955, 78956, 78957, - 78958, 78959, 78960, 78961, 78962, 78963, 78964, 78965, 78966, 78967, - 78968, 78969, 78970, 78971, 78972, 78973, 78974, 78975, 78976, 78977, - 78978, 78979, 78980, 78981, 78982, 78983, 78984, 78985, 78986, 78987, - 78988, 78989, 78990, 78991, 78992, 78993, 78994, 78995, 78996, 78997, - 78998, 78999, 79000, 79001, 79002, 79003, 79004, 79005, 79006, 79007, - 79008, 79009, 79010, 79011, 79012, 79013, 79014, 79015, 79016, 79017, - 79018, 79019, 79020, 79021, 79022, 79023, 79024, 79025, 79026, 79027, - 79028, 79029, 79030, 79031, 79032, 79033, 79034, 79035, 79036, 79037, - 79038, 79039, 79040, 79041, 79042, 79043, 79044, 79045, 79046, 79047, - 79048, 79049, 79050, 79051, 79052, 79053, 79054, 79055, 79056, 79057, - 79058, 79059, 79060, 79061, 79062, 79063, 79064, 79065, 79066, 79067, - 79068, 79069, 79070, 79071, 79072, 79073, 79074, 79075, 79076, 79077, - 79078, 79079, 79080, 79081, 79082, 79083, 79084, 79085, 79086, 79087, - 79088, 79089, 79090, 79091, 79092, 79093, 79094, 79095, 79096, 79097, - 79098, 79099, 79100, 79101, 79102, 79103, 79104, 79105, 79106, 79107, - 79108, 79109, 79110, 79111, 79112, 79113, 79114, 79115, 79116, 79117, - 79118, 79119, 79120, 79121, 79122, 79123, 79124, 79125, 79126, 79127, - 79128, 79129, 79130, 79131, 79132, 79133, 79134, 79135, 79136, 79137, - 79138, 79139, 79140, 79141, 79142, 79143, 79144, 79145, 79146, 79147, - 79148, 79149, 79150, 79151, 79152, 79153, 79154, 79155, 79156, 79157, - 79158, 79159, 79160, 79161, 79162, 79163, 79164, 79165, 79166, 79167, - 79168, 79169, 79170, 79171, 79172, 79173, 79174, 79175, 79176, 79177, - 79178, 79179, 79180, 79181, 79182, 79183, 79184, 79185, 79186, 79187, - 79188, 79189, 79190, 79191, 79192, 79193, 79194, 79195, 79196, 79197, - 79198, 79199, 79200, 79201, 79202, 79203, 79204, 79205, 79206, 79207, - 79208, 79209, 79210, 79211, 79212, 79213, 79214, 79215, 79216, 79217, - 79218, 79219, 79220, 79221, 79222, 79223, 79224, 79225, 79226, 79227, - 79228, 79229, 79230, 79231, 79232, 79233, 79234, 79235, 79236, 79237, - 79238, 79239, 79240, 79241, 79242, 79243, 79244, 79245, 79246, 79247, - 79248, 79249, 79250, 79251, 79252, 79253, 79254, 79255, 79256, 79257, - 79258, 79259, 79260, 79261, 79262, 79263, 79264, 79265, 79266, 79267, - 79268, 79269, 79270, 79271, 79272, 79273, 79274, 79275, 79276, 79277, - 79278, 79279, 79280, 79281, 79282, 79283, 79284, 79285, 79286, 79287, - 79288, 79289, 79290, 79291, 79292, 79293, 79294, 79295, 79296, 79297, - 79298, 79299, 79300, 79301, 79302, 79303, 79304, 79305, 79306, 79307, - 79308, 79309, 79310, 79311, 79312, 79313, 79314, 79315, 79316, 79317, - 79318, 79319, 79320, 79321, 79322, 79323, 79324, 79325, 79326, 79327, - 79328, 79329, 79330, 79331, 79332, 79333, 79334, 79335, 79336, 79337, - 79338, 79339, 79340, 79341, 79342, 79343, 79344, 79345, 79346, 79347, - 79348, 79349, 79350, 79351, 79352, 79353, 79354, 79355, 79356, 79357, - 79358, 79359, 79360, 79361, 79362, 79363, 79364, 79365, 79366, 79367, - 79368, 79369, 79370, 79371, 79372, 79373, 79374, 79375, 79376, 79377, - 79378, 79379, 79380, 79381, 79382, 79383, 79384, 79385, 79386, 79387, - 79388, 79389, 79390, 79391, 79392, 79393, 79394, 79395, 79396, 79397, - 79398, 79399, 79400, 79401, 79402, 79403, 79404, 79405, 79406, 79407, - 79408, 79409, 79410, 79411, 79412, 79413, 79414, 79415, 79416, 79417, - 79418, 79419, 79420, 79421, 79422, 79423, 79424, 79425, 79426, 79427, - 79428, 79429, 79430, 79431, 79432, 79433, 79434, 79435, 79436, 79437, - 79438, 79439, 79440, 79441, 79442, 79443, 79444, 79445, 79446, 79447, - 79448, 79449, 79450, 79451, 79452, 79453, 79454, 79455, 79456, 79457, - 79458, 79459, 79460, 79461, 79462, 79463, 79464, 79465, 79466, 79467, - 79468, 79469, 79470, 79471, 79472, 79473, 79474, 79475, 79476, 79477, - 79478, 79479, 79480, 79481, 79482, 79483, 79484, 79485, 79486, 79487, - 79488, 79489, 79490, 79491, 79492, 79493, 79494, 79495, 79496, 79497, - 79498, 79499, 79500, 79501, 79502, 79503, 79504, 79505, 79506, 79507, - 79508, 79509, 79510, 79511, 79512, 79513, 79514, 79515, 79516, 79517, - 79518, 79519, 79520, 79521, 79522, 79523, 79524, 79525, 79526, 79527, - 79528, 79529, 79530, 79531, 79532, 79533, 79534, 79535, 79536, 79537, - 79538, 79539, 79540, 79541, 79542, 79543, 79544, 79545, 79546, 79547, - 79548, 79549, 79550, 79551, 79552, 79553, 79554, 79555, 79556, 79557, - 79558, 79559, 79560, 79561, 79562, 79563, 79564, 79565, 79566, 79567, - 79568, 79569, 79570, 79571, 79572, 79573, 79574, 79575, 79576, 79577, - 79578, 79579, 79580, 79581, 79582, 79583, 79584, 79585, 79586, 79587, - 79588, 79589, 79590, 79591, 79592, 79593, 79594, 79595, 79596, 79597, - 79598, 79599, 79600, 79601, 79602, 79603, 79604, 79605, 79606, 79607, - 79608, 79609, 79610, 79611, 79612, 79613, 79614, 79615, 79616, 79617, - 79618, 79619, 79620, 79621, 79622, 79623, 79624, 79625, 79626, 79627, - 79628, 79629, 79630, 79631, 79632, 79633, 79634, 79635, 79636, 79637, - 79638, 79639, 79640, 79641, 79642, 79643, 79644, 79645, 79646, 79647, - 79648, 79649, 79650, 79651, 79652, 79653, 79654, 79655, 79656, 79657, - 79658, 79659, 79660, 79661, 79662, 79663, 79664, 79665, 79666, 79667, - 79668, 79669, 79670, 79671, 79672, 79673, 79674, 79675, 79676, 79677, - 79678, 79679, 79680, 79681, 79682, 79683, 79684, 79685, 79686, 79687, - 79688, 79689, 79690, 79691, 79692, 79693, 79694, 79695, 79696, 79697, - 79698, 79699, 79700, 79701, 79702, 79703, 79704, 79705, 79706, 79707, - 79708, 79709, 79710, 79711, 79712, 79713, 79714, 79715, 79716, 79717, - 79718, 79719, 79720, 79721, 79722, 79723, 79724, 79725, 79726, 79727, - 79728, 79729, 79730, 79731, 79732, 79733, 79734, 79735, 79736, 79737, - 79738, 79739, 79740, 79741, 79742, 79743, 79744, 79745, 79746, 79747, - 79748, 79749, 79750, 79751, 79752, 79753, 79754, 79755, 79756, 79757, - 79758, 79759, 79760, 79761, 79762, 79763, 79764, 79765, 79766, 79767, - 79768, 79769, 79770, 79771, 79772, 79773, 79774, 79775, 79776, 79777, - 79778, 79779, 79780, 79781, 79782, 79783, 79784, 79785, 79786, 79787, - 79788, 79789, 79790, 79791, 79792, 79793, 79794, 79795, 79796, 79797, - 79798, 79799, 79800, 79801, 79802, 79803, 79804, 79805, 79806, 79807, - 79808, 79809, 79810, 79811, 79812, 79813, 79814, 79815, 79816, 79817, - 79818, 79819, 79820, 79821, 79822, 79823, 79824, 79825, 79826, 79827, - 79828, 79829, 79830, 79831, 79832, 79833, 79834, 79835, 79836, 79837, - 79838, 79839, 79840, 79841, 79842, 79843, 79844, 79845, 79846, 79847, - 79848, 79849, 79850, 79851, 79852, 79853, 79854, 79855, 79856, 79857, - 79858, 79859, 79860, 79861, 79862, 79863, 79864, 79865, 79866, 79867, - 79868, 79869, 79870, 79871, 79872, 79873, 79874, 79875, 79876, 79877, - 79878, 79879, 79880, 79881, 79882, 79883, 79884, 79885, 79886, 79887, - 79888, 79889, 79890, 79891, 79892, 79893, 79894, 79895, 79896, 79897, - 79898, 79899, 79900, 79901, 79902, 79903, 79904, 79905, 79906, 79907, - 79908, 79909, 79910, 79911, 79912, 79913, 79914, 79915, 79916, 79917, - 79918, 79919, 79920, 79921, 79922, 79923, 79924, 79925, 79926, 79927, - 79928, 79929, 79930, 79931, 79932, 79933, 79934, 79935, 79936, 79937, - 79938, 79939, 79940, 79941, 79942, 79943, 79944, 79945, 79946, 79947, - 79948, 79949, 79950, 79951, 79952, 79953, 79954, 79955, 79956, 79957, - 79958, 79959, 79960, 79961, 79962, 79963, 79964, 79965, 79966, 79967, - 79968, 79969, 79970, 79971, 79972, 79973, 79974, 79975, 79976, 79977, - 79978, 79979, 79980, 79981, 79982, 79983, 79984, 79985, 79986, 79987, - 79988, 79989, 79990, 79991, 79992, 79993, 79994, 79995, 79996, 79997, - 79998, 79999, 80000, 80001, 80002, 80003, 80004, 80005, 80006, 80007, - 80008, 80009, 80010, 80011, 80012, 80013, 80014, 80015, 80016, 80017, - 80018, 80019, 80020, 80021, 80022, 80023, 80024, 80025, 80026, 80027, - 80028, 80029, 80030, 80031, 80032, 80033, 80034, 80035, 80036, 80037, - 80038, 80039, 80040, 80041, 80042, 80043, 80044, 80045, 80046, 80047, - 80048, 80049, 80050, 80051, 80052, 80053, 80054, 80055, 80056, 80057, - 80058, 80059, 80060, 80061, 80062, 80063, 80064, 80065, 80066, 80067, - 80068, 80069, 80070, 80071, 80072, 80073, 80074, 80075, 80076, 80077, - 80078, 80079, 80080, 80081, 80082, 80083, 80084, 80085, 80086, 80087, - 80088, 80089, 80090, 80091, 80092, 80093, 80094, 80095, 80096, 80097, - 80098, 80099, 80100, 80101, 80102, 80103, 80104, 80105, 80106, 80107, - 80108, 80109, 80110, 80111, 80112, 80113, 80114, 80115, 80116, 80117, - 80118, 80119, 80120, 80121, 80122, 80123, 80124, 80125, 80126, 80127, - 80128, 80129, 80130, 80131, 80132, 80133, 80134, 80135, 80136, 80137, - 80138, 80139, 80140, 80141, 80142, 80143, 80144, 80145, 80146, 80147, - 80148, 80149, 80150, 80151, 80152, 80153, 80154, 80155, 80156, 80157, - 80158, 80159, 80160, 80161, 80162, 80163, 80164, 80165, 80166, 80167, - 80168, 80169, 80170, 80171, 80172, 80173, 80174, 80175, 80176, 80177, - 80178, 80179, 80180, 80181, 80182, 80183, 80184, 80185, 80186, 80187, - 80188, 80189, 80190, 80191, 80192, 80193, 80194, 80195, 80196, 80197, - 80198, 80199, 80200, 80201, 80202, 80203, 80204, 80205, 80206, 80207, - 80208, 80209, 80210, 80211, 80212, 80213, 80214, 80215, 80216, 80217, - 80218, 80219, 80220, 80221, 80222, 80223, 80224, 80225, 80226, 80227, - 80228, 80229, 80230, 80231, 80232, 80233, 80234, 80235, 80236, 80237, - 80238, 80239, 80240, 80241, 80242, 80243, 80244, 80245, 80246, 80247, - 80248, 80249, 80250, 80251, 80252, 80253, 80254, 80255, 80256, 80257, - 80258, 80259, 80260, 80261, 80262, 80263, 80264, 80265, 80266, 80267, - 80268, 80269, 80270, 80271, 80272, 80273, 80274, 80275, 80276, 80277, - 80278, 80279, 80280, 80281, 80282, 80283, 80284, 80285, 80286, 80287, - 80288, 80289, 80290, 80291, 80292, 80293, 80294, 80295, 80296, 80297, - 80298, 80299, 80300, 80301, 80302, 80303, 80304, 80305, 80306, 80307, - 80308, 80309, 80310, 80311, 80312, 80313, 80314, 80315, 80316, 80317, - 80318, 80319, 80320, 80321, 80322, 80323, 80324, 80325, 80326, 80327, - 80328, 80329, 80330, 80331, 80332, 80333, 80334, 80335, 80336, 80337, - 80338, 80339, 80340, 80341, 80342, 80343, 80344, 80345, 80346, 80347, - 80348, 80349, 80350, 80351, 80352, 80353, 80354, 80355, 80356, 80357, - 80358, 80359, 80360, 80361, 80362, 80363, 80364, 80365, 80366, 80367, - 80368, 80369, 80370, 80371, 80372, 80373, 80374, 80375, 80376, 80377, - 80378, 80379, 80380, 80381, 80382, 80383, 80384, 80385, 80386, 80387, - 80388, 80389, 80390, 80391, 80392, 80393, 80394, 80395, 80396, 80397, - 80398, 80399, 80400, 80401, 80402, 80403, 80404, 80405, 80406, 80407, - 80408, 80409, 80410, 80411, 80412, 80413, 80414, 80415, 80416, 80417, - 80418, 80419, 80420, 80421, 80422, 80423, 80424, 80425, 80426, 80427, - 80428, 80429, 80430, 80431, 80432, 80433, 80434, 80435, 80436, 80437, - 80438, 80439, 80440, 80441, 80442, 80443, 80444, 80445, 80446, 80447, - 80448, 80449, 80450, 80451, 80452, 80453, 80454, 80455, 80456, 80457, - 80458, 80459, 80460, 80461, 80462, 80463, 80464, 80465, 80466, 80467, - 80468, 80469, 80470, 80471, 80472, 80473, 80474, 80475, 80476, 80477, - 80478, 80479, 80480, 80481, 80482, 80483, 80484, 80485, 80486, 80487, - 80488, 80489, 80490, 80491, 80492, 80493, 80494, 80495, 80496, 80497, - 80498, 80499, 80500, 80501, 80502, 80503, 80504, 80505, 80506, 80507, - 80508, 80509, 80510, 80511, 80512, 80513, 80514, 80515, 80516, 80517, - 80518, 80519, 80520, 80521, 80522, 80523, 80524, 80525, 80526, 80527, - 80528, 80529, 80530, 80531, 80532, 80533, 80534, 80535, 80536, 80537, - 80538, 80539, 80540, 80541, 80542, 80543, 80544, 80545, 80546, 80547, - 80548, 80549, 80550, 80551, 80552, 80553, 80554, 80555, 80556, 80557, - 80558, 80559, 80560, 80561, 80562, 80563, 80564, 80565, 80566, 80567, - 80568, 80569, 80570, 80571, 80572, 80573, 80574, 80575, 80576, 80577, - 80578, 80579, 80580, 80581, 80582, 80583, 80584, 80585, 80586, 80587, - 80588, 80589, 80590, 80591, 80592, 80593, 80594, 80595, 80596, 80597, - 80598, 80599, 80600, 80601, 80602, 80603, 80604, 80605, 80606, 80607, - 80608, 80609, 80610, 80611, 80612, 80613, 80614, 80615, 80616, 80617, - 80618, 80619, 80620, 80621, 80622, 80623, 80624, 80625, 80626, 80627, - 80628, 80629, 80630, 80631, 80632, 80633, 80634, 80635, 80636, 80637, - 80638, 80639, 80640, 80641, 80642, 80643, 80644, 80645, 80646, 80647, - 80648, 80649, 80650, 80651, 80652, 80653, 80654, 80655, 80656, 80657, - 80658, 80659, 80660, 80661, 80662, 80663, 80664, 80665, 80666, 80667, - 80668, 80669, 80670, 80671, 80672, 80673, 80674, 80675, 80676, 80677, - 80678, 80679, 80680, 80681, 80682, 80683, 80684, 80685, 80686, 80687, - 80688, 80689, 80690, 80691, 80692, 80693, 80694, 80695, 80696, 80697, - 80698, 80699, 80700, 80701, 80702, 80703, 80704, 80705, 80706, 80707, - 80708, 80709, 80710, 80711, 80712, 80713, 80714, 80715, 80716, 80717, - 80718, 80719, 80720, 80721, 80722, 80723, 80724, 80725, 80726, 80727, - 80728, 80729, 80730, 80731, 80732, 80733, 80734, 80735, 80736, 80737, - 80738, 80739, 80740, 80741, 80742, 80743, 80744, 80745, 80746, 80747, - 80748, 80749, 80750, 80751, 80752, 80753, 80754, 80755, 80756, 80757, - 80758, 80759, 80760, 80761, 80762, 80763, 80764, 80765, 80766, 80767, - 80768, 80769, 80770, 80771, 80772, 80773, 80774, 80775, 80776, 80777, - 80778, 80779, 80780, 80781, 80782, 80783, 80784, 80785, 80786, 80787, - 80788, 80789, 80790, 80791, 80792, 80793, 80794, 80795, 80796, 80797, - 80798, 80799, 80800, 80801, 80802, 80803, 80804, 80805, 80806, 80807, - 80808, 80809, 80810, 80811, 80812, 80813, 80814, 80815, 80816, 80817, - 80818, 80819, 80820, 80821, 80822, 80823, 80824, 80825, 80826, 80827, - 80828, 80829, 80830, 80831, 80832, 80833, 80834, 80835, 80836, 80837, - 80838, 80839, 80840, 80841, 80842, 80843, 80844, 80845, 80846, 80847, - 80848, 80849, 80850, 80851, 80852, 80853, 80854, 80855, 80856, 80857, - 80858, 80859, 80860, 80861, 80862, 80863, 80864, 80865, 80866, 80867, - 80868, 80869, 80870, 80871, 80872, 80873, 80874, 80875, 80876, 80877, - 80878, 80879, 80880, 80881, 80882, 80883, 80884, 80885, 80886, 80887, - 80888, 80889, 80890, 80891, 80892, 80893, 80894, 80895, 80896, 80897, - 80898, 80899, 80900, 80901, 80902, 80903, 80904, 80905, 80906, 80907, - 80908, 80909, 80910, 80911, 80912, 80913, 80914, 80915, 80916, 80917, - 80918, 80919, 80920, 80921, 80922, 80923, 80924, 80925, 80926, 80927, - 80928, 80929, 80930, 80931, 80932, 80933, 80934, 80935, 80936, 80937, - 80938, 80939, 80940, 80941, 80942, 80943, 80944, 80945, 80946, 80947, - 80948, 80949, 80950, 80951, 80952, 80953, 80954, 80955, 80956, 80957, - 80958, 80959, 80960, 80961, 80962, 80963, 80964, 80965, 80966, 80967, - 80968, 80969, 80970, 80971, 80972, 80973, 80974, 80975, 80976, 80977, - 80978, 80979, 80980, 80981, 80982, 80983, 80984, 80985, 80986, 80987, - 80988, 80989, 80990, 80991, 80992, 80993, 80994, 80995, 80996, 80997, - 80998, 80999, 81000, 81001, 81002, 81003, 81004, 81005, 81006, 81007, - 81008, 81009, 81010, 81011, 81012, 81013, 81014, 81015, 81016, 81017, - 81018, 81019, 81020, 81021, 81022, 81023, 81024, 81025, 81026, 81027, - 81028, 81029, 81030, 81031, 81032, 81033, 81034, 81035, 81036, 81037, - 81038, 81039, 81040, 81041, 81042, 81043, 81044, 81045, 81046, 81047, - 81048, 81049, 81050, 81051, 81052, 81053, 81054, 81055, 81056, 81057, - 81058, 81059, 81060, 81061, 81062, 81063, 81064, 81065, 81066, 81067, - 81068, 81069, 81070, 81071, 81072, 81073, 81074, 81075, 81076, 81077, - 81078, 81079, 81080, 81081, 81082, 81083, 81084, 81085, 81086, 81087, - 81088, 81089, 81090, 81091, 81092, 81093, 81094, 81095, 81096, 81097, - 81098, 81099, 81100, 81101, 81102, 81103, 81104, 81105, 81106, 81107, - 81108, 81109, 81110, 81111, 81112, 81113, 81114, 81115, 81116, 81117, - 81118, 81119, 81120, 81121, 81122, 81123, 81124, 81125, 81126, 81127, - 81128, 81129, 81130, 81131, 81132, 81133, 81134, 81135, 81136, 81137, - 81138, 81139, 81140, 81141, 81142, 81143, 81144, 81145, 81146, 81147, - 81148, 81149, 81150, 81151, 81152, 81153, 81154, 81155, 81156, 81157, - 81158, 81159, 81160, 81161, 81162, 81163, 81164, 81165, 81166, 81167, - 81168, 81169, 81170, 81171, 81172, 81173, 81174, 81175, 81176, 81177, - 81178, 81179, 81180, 81181, 81182, 81183, 81184, 81185, 81186, 81187, - 81188, 81189, 81190, 81191, 81192, 81193, 81194, 81195, 81196, 81197, - 81198, 81199, 81200, 81201, 81202, 81203, 81204, 81205, 81206, 81207, - 81208, 81209, 81210, 81211, 81212, 81213, 81214, 81215, 81216, 81217, - 81218, 81219, 81220, 81221, 81222, 81223, 81224, 81225, 81226, 81227, - 81228, 81229, 81230, 81231, 81232, 81233, 81234, 81235, 81236, 81237, - 81238, 81239, 81240, 81241, 81242, 81243, 81244, 81245, 81246, 81247, - 81248, 81249, 81250, 81251, 81252, 81253, 81254, 81255, 81256, 81257, - 81258, 81259, 81260, 81261, 81262, 81263, 81264, 81265, 81266, 81267, - 81268, 81269, 81270, 81271, 81272, 81273, 81274, 81275, 81276, 81277, - 81278, 81279, 81280, 81281, 81282, 81283, 81284, 81285, 81286, 81287, - 81288, 81289, 81290, 81291, 81292, 81293, 81294, 81295, 81296, 81297, - 81298, 81299, 81300, 81301, 81302, 81303, 81304, 81305, 81306, 81307, - 81308, 81309, 81310, 81311, 81312, 81313, 81314, 81315, 81316, 81317, - 81318, 81319, 81320, 81321, 81322, 81323, 81324, 81325, 81326, 81327, - 81328, 81329, 81330, 81331, 81332, 81333, 81334, 81335, 81336, 81337, - 81338, 81339, 81340, 81341, 81342, 81343, 81344, 81345, 81346, 81347, - 81348, 81349, 81350, 81351, 81352, 81353, 81354, 81355, 81356, 81357, - 81358, 81359, 81360, 81361, 81362, 81363, 81364, 81365, 81366, 81367, - 81368, 81369, 81370, 81371, 81372, 81373, 81374, 81375, 81376, 81377, - 81378, 81379, 81380, 81381, 81382, 81383, 81384, 81385, 81386, 81387, - 81388, 81389, 81390, 81391, 81392, 81393, 81394, 81395, 81396, 81397, - 81398, 81399, 81400, 81401, 81402, 81403, 81404, 81405, 81406, 81407, - 81408, 81409, 81410, 81411, 81412, 81413, 81414, 81415, 81416, 81417, - 81418, 81419, 81420, 81421, 81422, 81423, 81424, 81425, 81426, 81427, - 81428, 81429, 81430, 81431, 81432, 81433, 81434, 81435, 81436, 81437, - 81438, 81439, 81440, 81441, 81442, 81443, 81444, 81445, 81446, 81447, - 81448, 81449, 81450, 81451, 81452, 81453, 81454, 81455, 81456, 81457, - 81458, 81459, 81460, 81461, 81462, 81463, 81464, 81465, 81466, 81467, - 81468, 81469, 81470, 81471, 81472, 81473, 81474, 81475, 81476, 81477, - 81478, 81479, 81480, 81481, 81482, 81483, 81484, 81485, 81486, 81487, - 81488, 81489, 81490, 81491, 81492, 81493, 81494, 81495, 81496, 81497, - 81498, 81499, 81500, 81501, 81502, 81503, 81504, 81505, 81506, 81507, - 81508, 81509, 81510, 81511, 81512, 81513, 81514, 81515, 81516, 81517, - 81518, 81519, 81520, 81521, 81522, 81523, 81524, 81525, 81526, 81527, - 81528, 81529, 81530, 81531, 81532, 81533, 81534, 81535, 81536, 81537, - 81538, 81539, 81540, 81541, 81542, 81543, 81544, 81545, 81546, 81547, - 81548, 81549, 81550, 81551, 81552, 81553, 81554, 81555, 81556, 81557, - 81558, 81559, 81560, 81561, 81562, 81563, 81564, 81565, 81566, 81567, - 81568, 81569, 81570, 81571, 81572, 81573, 81574, 81575, 81576, 81577, - 81578, 81579, 81580, 81581, 81582, 81583, 81584, 81585, 81586, 81587, - 81588, 81589, 81590, 81591, 81592, 81593, 81594, 81595, 81596, 81597, - 81598, 81599, 81600, 81601, 81602, 81603, 81604, 81605, 81606, 81607, - 81608, 81609, 81610, 81611, 81612, 81613, 81614, 81615, 81616, 81617, - 81618, 81619, 81620, 81621, 81622, 81623, 81624, 81625, 81626, 81627, - 81628, 81629, 81630, 81631, 81632, 81633, 81634, 81635, 81636, 81637, - 81638, 81639, 81640, 81641, 81642, 81643, 81644, 81645, 81646, 81647, - 81648, 81649, 81650, 81651, 81652, 81653, 81654, 81655, 81656, 81657, - 81658, 81659, 81660, 81661, 81662, 81663, 81664, 81665, 81666, 81667, - 81668, 81669, 81670, 81671, 81672, 81673, 81674, 81675, 81676, 81677, - 81678, 81679, 81680, 81681, 81682, 81683, 81684, 81685, 81686, 81687, - 81688, 81689, 81690, 81691, 81692, 81693, 81694, 81695, 81696, 81697, - 81698, 81699, 81700, 81701, 81702, 81703, 81704, 81705, 81706, 81707, - 81708, 81709, 81710, 81711, 81712, 81713, 81714, 81715, 81716, 81717, - 81718, 81719, 81720, 81721, 81722, 81723, 81724, 81725, 81726, 81727, - 81728, 81729, 81730, 81731, 81732, 81733, 81734, 81735, 81736, 81737, - 81738, 81739, 81740, 81741, 81742, 81743, 81744, 81745, 81746, 81747, - 81748, 81749, 81750, 81751, 81752, 81753, 81754, 81755, 81756, 81757, - 81758, 81759, 81760, 81761, 81762, 81763, 81764, 81765, 81766, 81767, - 81768, 81769, 81770, 81771, 81772, 81773, 81774, 81775, 81776, 81777, - 81778, 81779, 81780, 81781, 81782, 81783, 81784, 81785, 81786, 81787, - 81788, 81789, 81790, 81791, 81792, 81793, 81794, 81795, 81796, 81797, - 81798, 81799, 81800, 81801, 81802, 81803, 81804, 81805, 81806, 81807, - 81808, 81809, 81810, 81811, 81812, 81813, 81814, 81815, 81816, 81817, - 81818, 81819, 81820, 81821, 81822, 81823, 81824, 81825, 81826, 81827, - 81828, 81829, 81830, 81831, 81832, 81833, 81834, 81835, 81836, 81837, - 81838, 81839, 81840, 81841, 81842, 81843, 81844, 81845, 81846, 81847, - 81848, 81849, 81850, 81851, 81852, 81853, 81854, 81855, 81856, 81857, - 81858, 81859, 81860, 81861, 81862, 81863, 81864, 81865, 81866, 81867, - 81868, 81869, 81870, 81871, 81872, 81873, 81874, 81875, 81876, 81877, - 81878, 81879, 81880, 81881, 81882, 81883, 81884, 81885, 81886, 81887, - 81888, 81889, 81890, 81891, 81892, 81893, 81894, 81895, 81896, 81897, - 81898, 81899, 81900, 81901, 81902, 81903, 81904, 81905, 81906, 81907, - 81908, 81909, 81910, 81911, 81912, 81913, 81914, 81915, 81916, 81917, - 81918, 81919, 82928, 82929, 82930, 82931, 82932, 82933, 82934, 82935, - 82936, 82937, 82938, 82688, 82689, 82690, 82691, 82692, 82693, 82694, - 82695, 82696, 82697, 82698, 82699, 82700, 82701, 82702, 82703, 82704, - 82705, 82706, 82707, 82708, 82709, 82710, 82711, 82712, 82713, 82714, - 82715, 82716, 82717, 82718, 82719, 82720, 82721, 82722, 82723, 82724, - 82725, 82726, 82727, 82728, 82729, 82730, 82731, 82732, 82733, 82734, - 82735, 82736, 82737, 82738, 82739, 82740, 82741, 82742, 82743, 82744, - 82745, 82746, 82747, 82748, 82749, 82750, 82751, 82752, 82753, 82754, - 82755, 82756, 82757, 82758, 82759, 82760, 82761, 82762, 82763, 82764, - 82765, 82766, 82767, 82768, 82769, 82770, 82771, 82772, 82773, 82774, - 82775, 82776, 82777, 82778, 82779, 82780, 82781, 82782, 82783, 82784, - 82785, 82786, 82787, 82788, 82789, 82790, 82791, 82792, 82793, 82794, - 82795, 82796, 82797, 82798, 82799, 82800, 82801, 82802, 82803, 82804, - 82805, 82806, 82807, 82808, 82809, 82810, 82811, 82812, 82813, 82814, - 82815, 82816, 82817, 82818, 82819, 82820, 82821, 82822, 82823, 82824, - 82825, 82826, 82827, 82828, 82829, 82830, 82831, 82832, 82833, 82834, - 82835, 82836, 82837, 82838, 82839, 82840, 82841, 82842, 82843, 82844, - 82845, 82846, 82847, 82848, 82849, 82850, 82851, 82852, 82853, 82854, - 82855, 82856, 82857, 82858, 82859, 82860, 82861, 82862, 82863, 82864, - 82865, 82866, 82867, 82868, 82869, 82870, 82871, 82872, 82873, 82874, - 82875, 82876, 82877, 82878, 82879, 82880, 82881, 82882, 82883, 82884, - 82885, 82886, 82887, 82888, 82889, 82890, 82891, 82892, 82893, 82894, - 82895, 82896, 82897, 82898, 82899, 82900, 82901, 82902, 82903, 82904, - 82905, 82906, 82907, 82908, 82909, 82910, 82911, 82912, 82913, 82914, - 82915, 82916, 82917, 82918, 82919, 82920, 82921, 82922, 82923, 82924, - 82925, 82926, 82927, 81920, 81921, 81922, 81923, 81924, 81925, 81926, - 81927, 81928, 81929, 81930, 81931, 81932, 81933, 81934, 81935, 81936, - 81937, 81938, 81939, 81940, 81941, 81942, 81943, 81944, 81945, 81946, - 81947, 81948, 81949, 81950, 81951, 81952, 81953, 81954, 81955, 81956, - 81957, 81958, 81959, 81960, 81961, 81962, 81963, 81964, 81965, 81966, - 81967, 81968, 81969, 81970, 81971, 81972, 81973, 81974, 81975, 81976, - 81977, 81978, 81979, 81980, 81981, 81982, 81983, 81984, 81985, 81986, - 81987, 81988, 81989, 81990, 81991, 81992, 81993, 81994, 81995, 81996, - 81997, 81998, 81999, 82000, 82001, 82002, 82003, 82004, 82005, 82006, - 82007, 82008, 82009, 82010, 82011, 82012, 82013, 82014, 82015, 82016, - 82017, 82018, 82019, 82020, 82021, 82022, 82023, 82024, 82025, 82026, - 82027, 82028, 82029, 82030, 82031, 82032, 82033, 82034, 82035, 82036, - 82037, 82038, 82039, 82040, 82041, 82042, 82043, 82044, 82045, 82046, - 82047, 82048, 82049, 82050, 82051, 82052, 82053, 82054, 82055, 82056, - 82057, 82058, 82059, 82060, 82061, 82062, 82063, 82064, 82065, 82066, - 82067, 82068, 82069, 82070, 82071, 82072, 82073, 82074, 82075, 82076, - 82077, 82078, 82079, 82080, 82081, 82082, 82083, 82084, 82085, 82086, - 82087, 82088, 82089, 82090, 82091, 82092, 82093, 82094, 82095, 82096, - 82097, 82098, 82099, 82100, 82101, 82102, 82103, 82104, 82105, 82106, - 82107, 82108, 82109, 82110, 82111, 82112, 82113, 82114, 82115, 82116, - 82117, 82118, 82119, 82120, 82121, 82122, 82123, 82124, 82125, 82126, - 82127, 82128, 82129, 82130, 82131, 82132, 82133, 82134, 82135, 82136, - 82137, 82138, 82139, 82140, 82141, 82142, 82143, 82144, 82145, 82146, - 82147, 82148, 82149, 82150, 82151, 82152, 82153, 82154, 82155, 82156, - 82157, 82158, 82159, 82160, 82161, 82162, 82163, 82164, 82165, 82166, - 82167, 82168, 82169, 82170, 82171, 82172, 82173, 82174, 82175, 82176, - 82177, 82178, 82179, 82180, 82181, 82182, 82183, 82184, 82185, 82186, - 82187, 82188, 82189, 82190, 82191, 82192, 82193, 82194, 82195, 82196, - 82197, 82198, 82199, 82200, 82201, 82202, 82203, 82204, 82205, 82206, - 82207, 82208, 82209, 82210, 82211, 82212, 82213, 82214, 82215, 82216, - 82217, 82218, 82219, 82220, 82221, 82222, 82223, 82224, 82225, 82226, - 82227, 82228, 82229, 82230, 82231, 82232, 82233, 82234, 82235, 82236, - 82237, 82238, 82239, 82240, 82241, 82242, 82243, 82244, 82245, 82246, - 82247, 82248, 82249, 82250, 82251, 82252, 82253, 82254, 82255, 82256, - 82257, 82258, 82259, 82260, 82261, 82262, 82263, 82264, 82265, 82266, - 82267, 82268, 82269, 82270, 82271, 82272, 82273, 82274, 82275, 82276, - 82277, 82278, 82279, 82280, 82281, 82282, 82283, 82284, 82285, 82286, - 82287, 82288, 82289, 82290, 82291, 82292, 82293, 82294, 82295, 82296, - 82297, 82298, 82299, 82300, 82301, 82302, 82303, 82304, 82305, 82306, - 82307, 82308, 82309, 82310, 82311, 82312, 82313, 82314, 82315, 82316, - 82317, 82318, 82319, 82320, 82321, 82322, 82323, 82324, 82325, 82326, - 82327, 82328, 82329, 82330, 82331, 82332, 82333, 82334, 82335, 82336, - 82337, 82338, 82339, 82340, 82341, 82342, 82343, 82344, 82345, 82346, - 82347, 82348, 82349, 82350, 82351, 82352, 82353, 82354, 82355, 82356, - 82357, 82358, 82359, 82360, 82361, 82362, 82363, 82364, 82365, 82366, - 82367, 82368, 82369, 82370, 82371, 82372, 82373, 82374, 82375, 82376, - 82377, 82378, 82379, 82380, 82381, 82382, 82383, 82384, 82385, 82386, - 82387, 82388, 82389, 82390, 82391, 82392, 82393, 82394, 82395, 82396, - 82397, 82398, 82399, 82400, 82401, 82402, 82403, 82404, 82405, 82406, - 82407, 82408, 82409, 82410, 82411, 82412, 82413, 82414, 82415, 82416, - 82417, 82418, 82419, 82420, 82421, 82422, 82423, 82424, 82425, 82426, - 82427, 82428, 82429, 82430, 82431, 82432, 82433, 82434, 82435, 82436, - 82437, 82438, 82439, 82440, 82441, 82442, 82443, 82444, 82445, 82446, - 82447, 82448, 82449, 82450, 82451, 82452, 82453, 82454, 82455, 82456, - 82457, 82458, 82459, 82460, 82461, 82462, 82463, 82464, 82465, 82466, - 82467, 82468, 82469, 82470, 82471, 82472, 82473, 82474, 82475, 82476, - 82477, 82478, 82479, 82480, 82481, 82482, 82483, 82484, 82485, 82486, - 82487, 82488, 82489, 82490, 82491, 82492, 82493, 82494, 82495, 82496, - 82497, 82498, 82499, 82500, 82501, 82502, 82503, 82504, 82505, 82506, - 82507, 82508, 82509, 82510, 82511, 82512, 82513, 82514, 82515, 82516, - 82517, 82518, 82519, 82520, 82521, 82522, 82523, 82524, 82525, 82526, - 82527, 82528, 82529, 82530, 82531, 82532, 82533, 82534, 82535, 82536, - 82537, 82538, 82539, 82540, 82541, 82542, 82543, 82544, 82545, 82546, - 82547, 82548, 82549, 82550, 82551, 82552, 82553, 82554, 82555, 82556, - 82557, 82558, 82559, 82560, 82561, 82562, 82563, 82564, 82565, 82566, - 82567, 82568, 82569, 82570, 82571, 82572, 82573, 82574, 82575, 82576, - 82577, 82578, 82579, 82580, 82581, 82582, 82583, 82584, 82585, 82586, - 82587, 82588, 82589, 82590, 82591, 82592, 82593, 82594, 82595, 82596, - 82597, 82598, 82599, 82600, 82601, 82602, 82603, 82604, 82605, 82606, - 82607, 82608, 82609, 82610, 82611, 82612, 82613, 82614, 82615, 82616, - 82617, 82618, 82619, 82620, 82621, 82622, 82623, 82624, 82625, 82626, - 82627, 82628, 82629, 82630, 82631, 82632, 82633, 82634, 82635, 82636, - 82637, 82638, 82639, 82640, 82641, 82642, 82643, 82644, 82645, 82646, - 82647, 82648, 82649, 82650, 82651, 82652, 82653, 82654, 82655, 82656, - 82657, 82658, 82659, 82660, 82661, 82662, 82663, 82664, 82665, 82666, - 82667, 82668, 82669, 82670, 82671, 82672, 82673, 82674, 82675, 82676, - 82677, 82678, 82679, 82680, 82681, 82682, 82683, 82684, 82685, 82686, - 82687, 118470, 129370, 10037, 10039, 10036, 10049, 117865, 117866, 10058, - 10035, 9834, 66854, 66853, 66827, 66826, 66833, 66832, 66821, 66837, - 66836, 66835, 66842, 66841, 66824, 66823, 66819, 66818, 66822, 66820, - 66855, 66831, 66844, 66843, 66846, 66845, 66852, 66851, 66817, 66825, - 66828, 66830, 66834, 66839, 66840, 66848, 66849, 66816, 66829, 66838, - 66847, 66850, 128268, 128294, 128161, 8961, 9191, 8712, 8946, 8953, 8947, - 8952, 8950, 8949, 10969, 10194, 128024, 128727, 69608, 69621, 69603, - 69611, 69618, 69619, 69600, 69615, 69602, 69606, 69614, 69617, 69620, - 69609, 69604, 69607, 69610, 69601, 69613, 69605, 69616, 69612, 69622, - 129501, 983101, 129456, 129457, 129459, 129458, 127995, 127996, 127997, - 127998, 127999, 128453, 128454, 128455, 129721, 128460, 128461, 8709, - 10675, 10676, 10674, 10673, 128459, 9091, 8193, 8212, 8195, 8192, 8211, - 8194, 983179, 8718, 983178, 983135, 983099, 983048, 983095, 983046, - 983064, 128282, 983051, 983050, 9993, 128388, 128233, 9094, 983067, - 983100, 983049, 8926, 8927, 8925, 8924, 8797, 8917, 61, 10865, 10867, - 11072, 10609, 10723, 10724, 10926, 11257, 11158, 10871, 10854, 10862, - 8789, 10872, 8781, 8794, 10738, 10736, 10734, 10739, 10737, 10735, 11249, - 11248, 9003, 8998, 983105, 983104, 8494, 8793, 983136, 4957, 4959, 4958, - 4963, 4965, 4978, 4988, 4980, 4979, 4987, 4985, 4982, 4981, 4986, 4984, - 4983, 4968, 4966, 4964, 4960, 4999, 4998, 4711, 4997, 43816, 43819, - 43821, 43820, 43818, 43822, 43817, 4704, 4707, 4710, 11653, 4709, 4708, - 4706, 4705, 43808, 43811, 43813, 43812, 43810, 43814, 43809, 11704, - 11707, 11709, 11708, 11706, 11710, 11705, 11688, 11691, 11693, 11692, - 11690, 11694, 11689, 4904, 4907, 4910, 11664, 4909, 4908, 4911, 4906, - 4905, 4728, 4731, 4734, 11655, 4733, 4732, 4735, 4730, 4729, 43789, - 43788, 43787, 43786, 43790, 43785, 4856, 4859, 4862, 11661, 4861, 4860, - 4863, 4858, 4857, 43797, 43796, 43795, 43794, 43798, 43793, 4848, 4851, - 4854, 11660, 4853, 4852, 4855, 4850, 4849, 5003, 5002, 4943, 5001, 4936, - 4939, 4941, 4940, 4954, 4938, 4942, 4937, 4873, 124916, 124915, 124924, - 124923, 124910, 124909, 124926, 124925, 124922, 124921, 124920, 124919, - 124918, 124917, 124914, 124913, 124912, 124904, 11667, 4895, 11670, - 11669, 11668, 4888, 4891, 4893, 4892, 4890, 4894, 4889, 4768, 4771, 4774, - 11658, 4773, 4772, 4775, 4770, 4769, 4880, 4883, 4885, 4884, 4882, 11736, - 11739, 11741, 11740, 11738, 11742, 11737, 4872, 4875, 4878, 4879, 4877, - 4876, 4874, 124907, 124906, 4631, 124905, 124896, 124899, 124901, 124900, - 124898, 124902, 124897, 4624, 4627, 4629, 4628, 4626, 4630, 4625, 4608, - 4611, 4614, 4615, 4613, 4612, 4610, 4609, 4800, 4803, 4805, 4804, 4802, - 4792, 4795, 4797, 4796, 4794, 4798, 4793, 4784, 4787, 4789, 4788, 4786, - 11720, 11723, 11725, 11724, 11722, 11726, 11721, 4776, 4779, 4782, 4783, - 4781, 4780, 4778, 4777, 4995, 4994, 4639, 4993, 4632, 4635, 4638, 11649, - 4637, 4636, 4953, 4634, 4633, 4760, 4763, 4766, 11657, 4765, 4764, 4767, - 4762, 4761, 4752, 4755, 4758, 11656, 4757, 4756, 4759, 4754, 4753, 4912, - 4816, 4819, 4821, 4820, 4818, 4822, 4817, 4915, 4918, 11665, 4917, 4916, - 4919, 4914, 4913, 5007, 5006, 4951, 5005, 4944, 4947, 4950, 11666, 4949, - 4948, 4946, 4945, 4696, 4699, 4701, 4700, 4698, 4688, 4691, 4693, 4692, - 4690, 4694, 4689, 4680, 4683, 4685, 4684, 4682, 11712, 11715, 11717, - 11716, 11714, 11718, 11713, 4672, 4675, 4678, 4679, 4677, 4676, 4674, - 4673, 4648, 4651, 4654, 11650, 4653, 4652, 4655, 4952, 4650, 4649, 4661, - 4996, 5000, 4992, 5004, 4660, 4664, 4667, 4670, 11652, 4669, 4668, 4671, - 4666, 4665, 4640, 4643, 4645, 4644, 4647, 4642, 4646, 4641, 11680, 11683, - 11685, 11684, 11682, 11686, 11681, 4656, 4659, 4662, 11651, 4663, 4658, - 4657, 4896, 4899, 4902, 11663, 4901, 4900, 4903, 4898, 4897, 43781, - 43780, 43779, 43778, 43782, 43777, 4928, 4931, 4934, 4935, 4933, 4932, - 4930, 4929, 4920, 4923, 4925, 4924, 4927, 4922, 4926, 4921, 4720, 4723, - 4726, 11654, 4725, 4724, 4727, 4722, 4721, 4864, 4867, 4870, 11662, 4869, - 4868, 4871, 4866, 4865, 4616, 4619, 4622, 11648, 4621, 4620, 4623, 4618, - 4617, 4808, 4811, 4814, 4815, 4813, 4812, 4810, 4809, 4840, 4843, 4846, - 4847, 4845, 4844, 4842, 4841, 4744, 4747, 4749, 4748, 4746, 11728, 11731, - 11733, 11732, 11730, 11734, 11729, 4736, 4739, 4742, 4743, 4741, 4740, - 4738, 4737, 4832, 4835, 4837, 4836, 4839, 4834, 4838, 4833, 11696, 11699, - 11701, 11700, 11698, 11702, 11697, 4824, 4827, 4830, 11659, 4829, 4828, - 4831, 4826, 4825, 4712, 4715, 4717, 4716, 4719, 4714, 4718, 4713, 5009, - 5016, 5012, 5015, 5013, 5017, 5010, 5011, 5014, 5008, 4973, 4972, 4975, - 4974, 4971, 4970, 4977, 4969, 4976, 4962, 4967, 4961, 983096, 983047, - 127984, 127972, 8352, 8364, 118472, 8455, 8265, 33, 8761, 118269, 118270, - 118271, 118274, 128529, 128942, 128954, 128948, 128905, 128915, 128935, - 128125, 1781, 1780, 1783, 1782, 1779, 1778, 1776, 1785, 1777, 1784, - 128065, 128083, 128064, 128231, 9167, 127794, 983180, 128523, 128561, - 129312, 128531, 129301, 128567, 129488, 128582, 128558, 129326, 128560, - 129762, 129320, 128581, 129395, 129763, 129402, 128539, 128540, 128541, - 128514, 129298, 129769, 129323, 128580, 128548, 129764, 129396, 128566, - 129318, 128134, 128536, 129401, 8507, 127981, 10540, 10543, 9950, 127810, - 129478, 128439, 128224, 128106, 9771, 127877, 129498, 128552, 129718, - 170, 9792, 127905, 9972, 129338, 8210, 8199, 129775, 128193, 128452, - 983107, 128253, 127902, 129734, 10765, 128293, 128658, 129519, 127879, - 127878, 129512, 9789, 127771, 127763, 8296, 129351, 128031, 127907, 9673, - 127845, 128074, 8281, 11821, 127953, 129407, 129747, 9189, 117910, 9971, - 129449, 128170, 9884, 118466, 10086, 9880, 8277, 127924, 128190, 128563, - 129672, 129712, 128760, 117834, 117835, 118011, 129359, 128389, 127787, - 127745, 129709, 128448, 129462, 128099, 127860, 127869, 11792, 10972, - 129376, 118476, 983071, 8704, 8873, 10021, 11156, 8280, 8283, 10019, - 127808, 10018, 128966, 8732, 8197, 9970, 129749, 129418, 8260, 8543, - 128444, 128446, 128445, 118458, 127839, 8355, 129398, 10156, 128037, - 8994, 128550, 128056, 127844, 127773, 127765, 10199, 9608, 46, 65342, - 65312, 65292, 65306, 65504, 65375, 65371, 65288, 65339, 65308, 65313, - 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, - 65324, 65325, 65326, 65327, 65328, 65329, 65330, 65331, 65332, 65333, - 65334, 65335, 65336, 65337, 65338, 65345, 65346, 65347, 65348, 65349, - 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, - 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, - 65370, 65343, 65506, 65283, 65505, 65285, 65291, 65376, 65373, 65289, - 65341, 65340, 65307, 65295, 65509, 65507, 65287, 65286, 65290, 65284, - 65301, 65300, 65303, 65302, 65299, 65298, 65296, 65305, 65297, 65304, - 65309, 65281, 65344, 65310, 65293, 65282, 65311, 65510, 65374, 65294, - 65508, 65372, 8289, 9905, 118280, 9981, 9179, 983215, 983216, 983217, - 983219, 983108, 983236, 983072, 68972, 68971, 68973, 68970, 68964, 68965, - 68959, 68961, 68948, 68945, 68954, 68960, 68953, 68963, 68949, 68947, - 68952, 68946, 68962, 68958, 68950, 68957, 68951, 68955, 68956, 68944, - 68996, 68997, 68991, 68993, 68980, 68977, 68986, 68992, 68985, 68995, - 68981, 68979, 68984, 68978, 68994, 68990, 68982, 68989, 68983, 68987, - 68988, 68976, 68943, 68969, 68941, 68938, 68939, 68940, 68942, 68975, - 68974, 69006, 69007, 68933, 68932, 68935, 68934, 68931, 68930, 68928, - 68937, 68929, 68936, 129476, 127922, 9881, 9965, 9966, 128142, 9802, - 118501, 118506, 118498, 118503, 118510, 118505, 118502, 118508, 118499, - 118504, 118497, 118507, 118509, 118496, 118500, 118511, 8782, 8785, 8762, - 4301, 4256, 4288, 4292, 4290, 4293, 4289, 4281, 4285, 4284, 4282, 4278, - 4258, 4287, 4283, 4277, 4265, 4276, 4270, 4280, 4273, 4271, 4262, 4263, - 4274, 4266, 4272, 4257, 4267, 4286, 4268, 4279, 4261, 4259, 4260, 4264, - 4269, 4275, 4295, 4291, 11565, 11520, 11552, 11556, 11554, 11557, 11553, - 11545, 11549, 11548, 11546, 11542, 11522, 11551, 11547, 11541, 11529, - 11540, 11534, 11544, 11537, 11535, 11526, 11527, 11538, 11530, 11536, - 11521, 11531, 11550, 11532, 11543, 11525, 11523, 11524, 11528, 11533, - 11539, 11559, 11555, 983955, 4323, 4349, 4346, 4304, 4329, 4333, 4332, - 4330, 4344, 4308, 4326, 4306, 4340, 4350, 4336, 4338, 4341, 4337, 4335, - 4331, 4325, 4313, 4351, 4314, 4324, 4318, 4328, 4321, 4345, 4311, 4322, - 4319, 4310, 4320, 4305, 4315, 4334, 4316, 4327, 4309, 4307, 4312, 4317, - 4343, 4339, 4342, 7357, 7354, 7312, 7337, 7341, 7340, 7338, 7352, 7316, - 7334, 7314, 7348, 7358, 7344, 7346, 7349, 7345, 7343, 7339, 7333, 7321, - 7359, 7322, 7332, 7326, 7336, 7329, 7353, 7319, 7330, 7327, 7318, 7328, - 7313, 7323, 7342, 7324, 7335, 7317, 7315, 7320, 7325, 7331, 7351, 7347, - 7350, 4347, 8368, 12307, 129502, 8503, 129754, 128103, 128714, 129426, - 11264, 11304, 11265, 11311, 11293, 11276, 11268, 11271, 11287, 11306, - 11267, 11275, 11274, 11305, 11303, 11307, 11273, 11310, 11278, 11279, - 11280, 11281, 11289, 11282, 11290, 11283, 11291, 11308, 11294, 11284, - 11298, 11300, 11301, 11285, 11309, 11292, 11266, 11269, 11296, 11295, - 11297, 11302, 11299, 11272, 11270, 11288, 11286, 11277, 11312, 11352, - 11313, 11359, 11341, 11324, 11316, 11319, 11335, 11354, 11315, 11323, - 11322, 11353, 11351, 11355, 11321, 11358, 11326, 11327, 11328, 11329, - 11337, 11330, 11338, 11331, 11339, 11356, 11342, 11332, 11346, 11348, - 11349, 11333, 11357, 11340, 11314, 11317, 11344, 11343, 11345, 11350, - 11347, 11320, 11318, 11336, 11334, 11325, 129371, 127760, 127775, 129508, - 10726, 129349, 128016, 66356, 66352, 66376, 66359, 66358, 66375, 66378, - 66369, 66365, 66368, 66357, 66370, 66360, 66372, 66373, 66367, 66374, - 66353, 66377, 66355, 66364, 66361, 66363, 66371, 66366, 66354, 66362, - 129421, 129405, 128893, 129727, 127948, 127891, 70495, 70494, 70411, - 70496, 70412, 70497, 70453, 70405, 70406, 70416, 70420, 70434, 70433, - 70439, 70438, 70432, 70431, 70437, 70436, 70409, 70410, 70407, 70408, - 70451, 70450, 70425, 70435, 70430, 70440, 70454, 70455, 70456, 70445, - 70444, 70427, 70426, 70424, 70423, 70429, 70428, 70422, 70421, 70443, - 70442, 70419, 70415, 70457, 70446, 70448, 70447, 70400, 70401, 70460, - 70461, 70402, 70493, 70477, 70403, 70487, 70462, 70472, 70476, 70465, - 70466, 70467, 70468, 70498, 70499, 70463, 70464, 70475, 70471, 70480, 96, - 127815, 10896, 10894, 10900, 10892, 10898, 10616, 10890, 10888, 10917, - 8935, 8809, 10878, 10882, 10884, 10880, 10886, 8819, 8805, 8823, 10916, - 8807, 8923, 10919, 10921, 10874, 10876, 8919, 62, 65860, 65863, 65878, - 65866, 65873, 65859, 65861, 65868, 65875, 65862, 65870, 65864, 65871, - 65867, 65874, 65857, 65869, 65876, 65856, 65858, 65865, 65877, 65872, - 65879, 65903, 65885, 65904, 65907, 65908, 65900, 65883, 65886, 65896, - 65890, 65882, 65880, 65891, 65902, 65906, 65897, 65899, 65893, 65892, - 65884, 65881, 65898, 65905, 65887, 65901, 65894, 65895, 65888, 65889, - 903, 65927, 65926, 913, 7945, 7949, 8077, 7947, 8075, 7951, 8079, 8073, - 7944, 7948, 8076, 7946, 8074, 7950, 8078, 8072, 8124, 8120, 8122, 8123, - 902, 8121, 882, 919, 7977, 7981, 8093, 7979, 8091, 7983, 8095, 8089, - 7976, 7980, 8092, 7978, 8090, 7982, 8094, 8088, 8140, 8139, 8138, 905, - 917, 7961, 7965, 7963, 7960, 7964, 7962, 8137, 8136, 904, 921, 7993, - 7999, 7997, 7995, 938, 7992, 7998, 7996, 7994, 8152, 8154, 8155, 906, - 8153, 937, 8041, 8045, 8109, 8043, 8107, 8047, 8111, 8105, 8040, 8044, - 8108, 8042, 8106, 8046, 8110, 8104, 8188, 8187, 8186, 911, 927, 8009, - 8013, 8011, 8008, 8012, 8010, 8185, 8184, 908, 929, 8172, 931, 1018, - 1015, 933, 8025, 8031, 8029, 8027, 939, 8168, 8170, 8171, 910, 8169, 886, - 934, 936, 928, 920, 932, 916, 922, 915, 935, 914, 880, 918, 923, 895, - 924, 925, 926, 1017, 1023, 1021, 1022, 975, 1012, 8129, 8174, 8173, 901, - 65915, 8190, 8159, 8158, 8157, 65920, 65919, 119325, 119331, 119332, - 119333, 119334, 119335, 119336, 119337, 119326, 119338, 119339, 119340, - 119341, 119342, 119343, 119344, 119345, 119346, 119347, 119348, 119349, - 119327, 119350, 119351, 119352, 119353, 119354, 119355, 119356, 119328, - 119357, 119358, 119359, 119360, 119361, 119329, 119330, 65933, 1008, 983, - 8125, 65922, 7466, 7464, 7462, 43877, 7465, 7463, 992, 986, 984, 990, - 988, 1011, 885, 1010, 1013, 65923, 884, 65921, 119365, 65925, 65909, - 65910, 65931, 8189, 65924, 65916, 8126, 8127, 8143, 8142, 8141, 8128, - 981, 982, 1020, 1009, 1014, 945, 8112, 8048, 8114, 7937, 7941, 8069, - 7943, 8071, 7939, 8067, 8065, 7936, 7940, 8068, 7942, 8070, 7938, 8066, - 8064, 8118, 8119, 8049, 8116, 8115, 940, 8113, 985, 883, 989, 948, 949, - 7953, 7957, 7955, 7952, 7956, 7954, 8051, 8050, 941, 951, 7969, 7973, - 8085, 7975, 8087, 7971, 8083, 8081, 7968, 7972, 8084, 7974, 8086, 7970, - 8082, 8080, 8134, 8135, 8053, 8132, 8052, 8130, 8131, 942, 953, 7985, - 7991, 7989, 7987, 970, 8151, 8147, 8146, 912, 7984, 7990, 7988, 7986, - 8150, 8144, 8054, 8055, 943, 8145, 965, 8017, 8023, 8021, 8019, 971, - 8167, 8163, 8162, 944, 8016, 8022, 8020, 8018, 8166, 8160, 8058, 8059, - 973, 8161, 954, 991, 969, 8033, 8037, 8101, 8039, 8103, 8035, 8099, 8097, - 8032, 8036, 8100, 8038, 8102, 8034, 8098, 8096, 8182, 8183, 8061, 8180, - 8060, 8178, 8179, 974, 959, 8001, 8005, 8003, 8000, 8004, 8002, 8057, - 8056, 972, 887, 966, 968, 960, 961, 8165, 8164, 993, 1019, 987, 963, - 1016, 952, 964, 962, 947, 967, 946, 881, 950, 955, 956, 957, 958, 893, - 891, 892, 7527, 7530, 7529, 7528, 7526, 65952, 65932, 65918, 65912, 977, - 65929, 65917, 65911, 900, 65914, 979, 980, 978, 8175, 119297, 119315, - 119316, 119317, 119318, 119319, 119300, 119320, 119321, 119322, 119323, - 119324, 119296, 119305, 119306, 119307, 119308, 119309, 119310, 119311, - 119312, 119313, 119314, 119298, 119299, 119301, 119302, 119303, 119304, - 890, 65913, 976, 65928, 65930, 894, 127823, 128215, 128154, 129367, - 129654, 128512, 129322, 129321, 128513, 128568, 128556, 983110, 11218, - 128151, 8370, 128130, 127928, 129454, 2693, 2694, 2704, 2708, 2722, 2721, - 2727, 2726, 2720, 2719, 2725, 2724, 2699, 2784, 2700, 2785, 2741, 2697, - 2698, 2695, 2696, 2739, 2738, 2809, 2713, 2723, 2718, 2728, 2742, 2743, - 2744, 2733, 2732, 2715, 2714, 2712, 2711, 2717, 2716, 2710, 2709, 2731, - 2730, 2745, 2734, 2736, 2735, 2703, 2707, 2814, 2689, 2812, 2815, 2813, - 2811, 2810, 2748, 2749, 2690, 2765, 2691, 2757, 2761, 2750, 2760, 2764, - 2753, 2754, 2755, 2756, 2786, 2787, 2751, 2752, 2759, 2763, 2701, 2705, - 2800, 2801, 2795, 2794, 2797, 2796, 2793, 2792, 2790, 2799, 2791, 2798, - 2768, 73092, 73082, 73056, 73057, 73064, 73067, 73091, 73090, 73081, - 73080, 73086, 73085, 73076, 73075, 73060, 73061, 73058, 73059, 73087, - 73077, 73071, 73070, 73084, 73083, 73079, 73078, 73089, 73088, 73074, - 73073, 73094, 73093, 73066, 73063, 73095, 73072, 73096, 73097, 73069, - 73068, 73110, 73109, 73098, 73105, 73108, 73101, 73102, 73099, 73100, - 73107, 73104, 73111, 73125, 73124, 73127, 73126, 73123, 73122, 73120, - 73129, 73121, 73128, 73112, 2678, 2673, 2650, 2584, 2583, 2649, 2582, - 2581, 2565, 2566, 2576, 2580, 2594, 2593, 2599, 2598, 2652, 2608, 2592, - 2591, 2597, 2596, 2569, 2570, 2567, 2568, 2611, 2610, 2585, 2595, 2590, - 2600, 2605, 2604, 2587, 2586, 2589, 2588, 2603, 2602, 2614, 2616, 2579, - 2575, 2654, 2617, 2606, 2613, 2607, 2651, 983656, 983655, 983654, 983653, - 983658, 983657, 2561, 2562, 2641, 2620, 2677, 2637, 2563, 2622, 2632, - 2636, 2625, 2626, 2623, 2624, 2635, 2631, 2672, 2674, 2676, 2667, 2666, - 2669, 2668, 2665, 2664, 2662, 2671, 2663, 2670, 2675, 90412, 90414, + 78505, 78506, 78507, 78508, 78509, 78510, 118470, 129370, 10037, 10039, + 10036, 10049, 117865, 117866, 10058, 10035, 9834, 66854, 66853, 66827, + 66826, 66833, 66832, 66821, 66837, 66836, 66835, 66842, 66841, 66824, + 66823, 66819, 66818, 66822, 66820, 66855, 66831, 66844, 66843, 66846, + 66845, 66852, 66851, 66817, 66825, 66828, 66830, 66834, 66839, 66840, + 66848, 66849, 66816, 66829, 66838, 66847, 66850, 128268, 128294, 128161, + 8961, 9191, 8712, 8946, 8953, 8947, 8952, 8950, 8949, 10969, 10194, + 128024, 128727, 69608, 69621, 69603, 69611, 69618, 69619, 69600, 69615, + 69602, 69606, 69614, 69617, 69620, 69609, 69604, 69607, 69610, 69601, + 69613, 69605, 69616, 69612, 69622, 129501, 983101, 129456, 129457, + 129459, 129458, 127995, 127996, 127997, 127998, 127999, 128453, 128454, + 128455, 129721, 128460, 128461, 8709, 10675, 10676, 10674, 10673, 128459, + 9091, 8193, 8212, 8195, 8192, 8211, 8194, 983179, 8718, 983178, 983135, + 983099, 983048, 983095, 983046, 983064, 128282, 983051, 983050, 9993, + 128388, 128233, 9094, 983067, 983100, 983049, 8926, 8927, 8925, 8924, + 8797, 8917, 61, 10865, 10867, 11072, 10609, 10723, 10724, 10926, 11257, + 11158, 10871, 10854, 10862, 8789, 10872, 8781, 8794, 10738, 10736, 10734, + 10739, 10737, 10735, 11249, 11248, 9003, 8998, 983105, 983104, 8494, + 8793, 983136, 4957, 4959, 4958, 4963, 4965, 4978, 4988, 4980, 4979, 4987, + 4985, 4982, 4981, 4986, 4984, 4983, 4968, 4966, 4964, 4960, 4999, 4998, + 4711, 4997, 43816, 43819, 43821, 43820, 43818, 43822, 43817, 4704, 4707, + 4710, 11653, 4709, 4708, 4706, 4705, 43808, 43811, 43813, 43812, 43810, + 43814, 43809, 11704, 11707, 11709, 11708, 11706, 11710, 11705, 11688, + 11691, 11693, 11692, 11690, 11694, 11689, 4904, 4907, 4910, 11664, 4909, + 4908, 4911, 4906, 4905, 4728, 4731, 4734, 11655, 4733, 4732, 4735, 4730, + 4729, 43789, 43788, 43787, 43786, 43790, 43785, 4856, 4859, 4862, 11661, + 4861, 4860, 4863, 4858, 4857, 43797, 43796, 43795, 43794, 43798, 43793, + 4848, 4851, 4854, 11660, 4853, 4852, 4855, 4850, 4849, 5003, 5002, 4943, + 5001, 4936, 4939, 4941, 4940, 4954, 4938, 4942, 4937, 4873, 124916, + 124915, 124924, 124923, 124910, 124909, 124926, 124925, 124922, 124921, + 124920, 124919, 124918, 124917, 124914, 124913, 124912, 124904, 11667, + 4895, 11670, 11669, 11668, 4888, 4891, 4893, 4892, 4890, 4894, 4889, + 4768, 4771, 4774, 11658, 4773, 4772, 4775, 4770, 4769, 4880, 4883, 4885, + 4884, 4882, 11736, 11739, 11741, 11740, 11738, 11742, 11737, 4872, 4875, + 4878, 4879, 4877, 4876, 4874, 124907, 124906, 4631, 124905, 124896, + 124899, 124901, 124900, 124898, 124902, 124897, 4624, 4627, 4629, 4628, + 4626, 4630, 4625, 4608, 4611, 4614, 4615, 4613, 4612, 4610, 4609, 4800, + 4803, 4805, 4804, 4802, 4792, 4795, 4797, 4796, 4794, 4798, 4793, 4784, + 4787, 4789, 4788, 4786, 11720, 11723, 11725, 11724, 11722, 11726, 11721, + 4776, 4779, 4782, 4783, 4781, 4780, 4778, 4777, 4995, 4994, 4639, 4993, + 4632, 4635, 4638, 11649, 4637, 4636, 4953, 4634, 4633, 4760, 4763, 4766, + 11657, 4765, 4764, 4767, 4762, 4761, 4752, 4755, 4758, 11656, 4757, 4756, + 4759, 4754, 4753, 4912, 4816, 4819, 4821, 4820, 4818, 4822, 4817, 4915, + 4918, 11665, 4917, 4916, 4919, 4914, 4913, 5007, 5006, 4951, 5005, 4944, + 4947, 4950, 11666, 4949, 4948, 4946, 4945, 4696, 4699, 4701, 4700, 4698, + 4688, 4691, 4693, 4692, 4690, 4694, 4689, 4680, 4683, 4685, 4684, 4682, + 11712, 11715, 11717, 11716, 11714, 11718, 11713, 4672, 4675, 4678, 4679, + 4677, 4676, 4674, 4673, 4648, 4651, 4654, 11650, 4653, 4652, 4655, 4952, + 4650, 4649, 4661, 4996, 5000, 4992, 5004, 4660, 4664, 4667, 4670, 11652, + 4669, 4668, 4671, 4666, 4665, 4640, 4643, 4645, 4644, 4647, 4642, 4646, + 4641, 11680, 11683, 11685, 11684, 11682, 11686, 11681, 4656, 4659, 4662, + 11651, 4663, 4658, 4657, 4896, 4899, 4902, 11663, 4901, 4900, 4903, 4898, + 4897, 43781, 43780, 43779, 43778, 43782, 43777, 4928, 4931, 4934, 4935, + 4933, 4932, 4930, 4929, 4920, 4923, 4925, 4924, 4927, 4922, 4926, 4921, + 4720, 4723, 4726, 11654, 4725, 4724, 4727, 4722, 4721, 4864, 4867, 4870, + 11662, 4869, 4868, 4871, 4866, 4865, 4616, 4619, 4622, 11648, 4621, 4620, + 4623, 4618, 4617, 4808, 4811, 4814, 4815, 4813, 4812, 4810, 4809, 4840, + 4843, 4846, 4847, 4845, 4844, 4842, 4841, 4744, 4747, 4749, 4748, 4746, + 11728, 11731, 11733, 11732, 11730, 11734, 11729, 4736, 4739, 4742, 4743, + 4741, 4740, 4738, 4737, 4832, 4835, 4837, 4836, 4839, 4834, 4838, 4833, + 11696, 11699, 11701, 11700, 11698, 11702, 11697, 4824, 4827, 4830, 11659, + 4829, 4828, 4831, 4826, 4825, 4712, 4715, 4717, 4716, 4719, 4714, 4718, + 4713, 5009, 5016, 5012, 5015, 5013, 5017, 5010, 5011, 5014, 5008, 4973, + 4972, 4975, 4974, 4971, 4970, 4977, 4969, 4976, 4962, 4967, 4961, 983096, + 983047, 127984, 127972, 8352, 8364, 118472, 8455, 8265, 33, 8761, 118269, + 118270, 118271, 118274, 128529, 128942, 128954, 128948, 128905, 128915, + 128935, 128125, 1781, 1780, 1783, 1782, 1779, 1778, 1776, 1785, 1777, + 1784, 128065, 128083, 128064, 128231, 9167, 127794, 983180, 128523, + 128561, 129312, 128531, 129301, 128567, 129488, 128582, 128558, 129326, + 128560, 129762, 129320, 128581, 129395, 129763, 129402, 128539, 128540, + 128541, 128514, 129298, 129769, 129323, 128580, 128548, 129764, 129396, + 128566, 129318, 128134, 128536, 129401, 8507, 127981, 10540, 10543, 9950, + 127810, 129478, 128439, 128224, 128106, 9771, 127877, 129498, 128552, + 129718, 170, 9792, 127905, 9972, 129338, 8210, 8199, 129775, 128193, + 128452, 983107, 128253, 127902, 129734, 10765, 128293, 128658, 129519, + 127879, 127878, 129512, 9789, 127771, 127763, 8296, 129351, 128031, + 127907, 9673, 127845, 128074, 8281, 11821, 127953, 129407, 129747, 9189, + 117910, 9971, 129449, 128170, 9884, 118466, 10086, 9880, 8277, 127924, + 128190, 128563, 129672, 129712, 128760, 117834, 117835, 118011, 129359, + 128389, 127787, 127745, 129709, 128448, 129462, 128099, 127860, 127869, + 11792, 10972, 129376, 118476, 983071, 8704, 8873, 10021, 11156, 8280, + 8283, 10019, 127808, 10018, 128966, 8732, 8197, 9970, 129749, 129418, + 8260, 8543, 128444, 128446, 128445, 118458, 127839, 8355, 129398, 10156, + 128037, 8994, 128550, 128056, 127844, 127773, 127765, 10199, 9608, 46, + 65342, 65312, 65292, 65306, 65504, 65375, 65371, 65288, 65339, 65308, + 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, + 65323, 65324, 65325, 65326, 65327, 65328, 65329, 65330, 65331, 65332, + 65333, 65334, 65335, 65336, 65337, 65338, 65345, 65346, 65347, 65348, + 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, + 65359, 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, + 65369, 65370, 65343, 65506, 65283, 65505, 65285, 65291, 65376, 65373, + 65289, 65341, 65340, 65307, 65295, 65509, 65507, 65287, 65286, 65290, + 65284, 65301, 65300, 65303, 65302, 65299, 65298, 65296, 65305, 65297, + 65304, 65309, 65281, 65344, 65310, 65293, 65282, 65311, 65510, 65374, + 65294, 65508, 65372, 8289, 9905, 118280, 9981, 9179, 983215, 983216, + 983217, 983219, 983108, 983236, 983072, 68972, 68971, 68973, 68970, + 68964, 68965, 68959, 68961, 68948, 68945, 68954, 68960, 68953, 68963, + 68949, 68947, 68952, 68946, 68962, 68958, 68950, 68957, 68951, 68955, + 68956, 68944, 68996, 68997, 68991, 68993, 68980, 68977, 68986, 68992, + 68985, 68995, 68981, 68979, 68984, 68978, 68994, 68990, 68982, 68989, + 68983, 68987, 68988, 68976, 68943, 68969, 68941, 68938, 68939, 68940, + 68942, 68975, 68974, 69006, 69007, 68933, 68932, 68935, 68934, 68931, + 68930, 68928, 68937, 68929, 68936, 129476, 127922, 9881, 9965, 9966, + 128142, 9802, 118501, 118506, 118498, 118503, 118510, 118505, 118502, + 118508, 118499, 118504, 118497, 118507, 118509, 118496, 118500, 118511, + 8782, 8785, 8762, 4301, 4256, 4288, 4292, 4290, 4293, 4289, 4281, 4285, + 4284, 4282, 4278, 4258, 4287, 4283, 4277, 4265, 4276, 4270, 4280, 4273, + 4271, 4262, 4263, 4274, 4266, 4272, 4257, 4267, 4286, 4268, 4279, 4261, + 4259, 4260, 4264, 4269, 4275, 4295, 4291, 11565, 11520, 11552, 11556, + 11554, 11557, 11553, 11545, 11549, 11548, 11546, 11542, 11522, 11551, + 11547, 11541, 11529, 11540, 11534, 11544, 11537, 11535, 11526, 11527, + 11538, 11530, 11536, 11521, 11531, 11550, 11532, 11543, 11525, 11523, + 11524, 11528, 11533, 11539, 11559, 11555, 983955, 4323, 4349, 4346, 4304, + 4329, 4333, 4332, 4330, 4344, 4308, 4326, 4306, 4340, 4350, 4336, 4338, + 4341, 4337, 4335, 4331, 4325, 4313, 4351, 4314, 4324, 4318, 4328, 4321, + 4345, 4311, 4322, 4319, 4310, 4320, 4305, 4315, 4334, 4316, 4327, 4309, + 4307, 4312, 4317, 4343, 4339, 4342, 7357, 7354, 7312, 7337, 7341, 7340, + 7338, 7352, 7316, 7334, 7314, 7348, 7358, 7344, 7346, 7349, 7345, 7343, + 7339, 7333, 7321, 7359, 7322, 7332, 7326, 7336, 7329, 7353, 7319, 7330, + 7327, 7318, 7328, 7313, 7323, 7342, 7324, 7335, 7317, 7315, 7320, 7325, + 7331, 7351, 7347, 7350, 4347, 8368, 12307, 129502, 8503, 129754, 128103, + 128714, 129426, 11264, 11304, 11265, 11311, 11293, 11276, 11268, 11271, + 11287, 11306, 11267, 11275, 11274, 11305, 11303, 11307, 11273, 11310, + 11278, 11279, 11280, 11281, 11289, 11282, 11290, 11283, 11291, 11308, + 11294, 11284, 11298, 11300, 11301, 11285, 11309, 11292, 11266, 11269, + 11296, 11295, 11297, 11302, 11299, 11272, 11270, 11288, 11286, 11277, + 11312, 11352, 11313, 11359, 11341, 11324, 11316, 11319, 11335, 11354, + 11315, 11323, 11322, 11353, 11351, 11355, 11321, 11358, 11326, 11327, + 11328, 11329, 11337, 11330, 11338, 11331, 11339, 11356, 11342, 11332, + 11346, 11348, 11349, 11333, 11357, 11340, 11314, 11317, 11344, 11343, + 11345, 11350, 11347, 11320, 11318, 11336, 11334, 11325, 129371, 127760, + 127775, 129508, 10726, 129349, 128016, 66356, 66352, 66376, 66359, 66358, + 66375, 66378, 66369, 66365, 66368, 66357, 66370, 66360, 66372, 66373, + 66367, 66374, 66353, 66377, 66355, 66364, 66361, 66363, 66371, 66366, + 66354, 66362, 129421, 129405, 128893, 129727, 127948, 127891, 70495, + 70494, 70411, 70496, 70412, 70497, 70453, 70405, 70406, 70416, 70420, + 70434, 70433, 70439, 70438, 70432, 70431, 70437, 70436, 70409, 70410, + 70407, 70408, 70451, 70450, 70425, 70435, 70430, 70440, 70454, 70455, + 70456, 70445, 70444, 70427, 70426, 70424, 70423, 70429, 70428, 70422, + 70421, 70443, 70442, 70419, 70415, 70457, 70446, 70448, 70447, 70400, + 70401, 70460, 70461, 70402, 70493, 70477, 70403, 70487, 70462, 70472, + 70476, 70465, 70466, 70467, 70468, 70498, 70499, 70463, 70464, 70475, + 70471, 70480, 96, 127815, 10896, 10894, 10900, 10892, 10898, 10616, + 10890, 10888, 10917, 8935, 8809, 10878, 10882, 10884, 10880, 10886, 8819, + 8805, 8823, 10916, 8807, 8923, 10919, 10921, 10874, 10876, 8919, 62, + 65860, 65863, 65878, 65866, 65873, 65859, 65861, 65868, 65875, 65862, + 65870, 65864, 65871, 65867, 65874, 65857, 65869, 65876, 65856, 65858, + 65865, 65877, 65872, 65879, 65903, 65885, 65904, 65907, 65908, 65900, + 65883, 65886, 65896, 65890, 65882, 65880, 65891, 65902, 65906, 65897, + 65899, 65893, 65892, 65884, 65881, 65898, 65905, 65887, 65901, 65894, + 65895, 65888, 65889, 903, 65927, 65926, 913, 7945, 7949, 8077, 7947, + 8075, 7951, 8079, 8073, 7944, 7948, 8076, 7946, 8074, 7950, 8078, 8072, + 8124, 8120, 8122, 8123, 902, 8121, 882, 919, 7977, 7981, 8093, 7979, + 8091, 7983, 8095, 8089, 7976, 7980, 8092, 7978, 8090, 7982, 8094, 8088, + 8140, 8139, 8138, 905, 917, 7961, 7965, 7963, 7960, 7964, 7962, 8137, + 8136, 904, 921, 7993, 7999, 7997, 7995, 938, 7992, 7998, 7996, 7994, + 8152, 8154, 8155, 906, 8153, 937, 8041, 8045, 8109, 8043, 8107, 8047, + 8111, 8105, 8040, 8044, 8108, 8042, 8106, 8046, 8110, 8104, 8188, 8187, + 8186, 911, 927, 8009, 8013, 8011, 8008, 8012, 8010, 8185, 8184, 908, 929, + 8172, 931, 1018, 1015, 933, 8025, 8031, 8029, 8027, 939, 8168, 8170, + 8171, 910, 8169, 886, 934, 936, 928, 920, 932, 916, 922, 915, 935, 914, + 880, 918, 923, 895, 924, 925, 926, 1017, 1023, 1021, 1022, 975, 1012, + 8129, 8174, 8173, 901, 65915, 8190, 8159, 8158, 8157, 65920, 65919, + 119325, 119331, 119332, 119333, 119334, 119335, 119336, 119337, 119326, + 119338, 119339, 119340, 119341, 119342, 119343, 119344, 119345, 119346, + 119347, 119348, 119349, 119327, 119350, 119351, 119352, 119353, 119354, + 119355, 119356, 119328, 119357, 119358, 119359, 119360, 119361, 119329, + 119330, 65933, 1008, 983, 8125, 65922, 7466, 7464, 7462, 43877, 7465, + 7463, 992, 986, 984, 990, 988, 1011, 885, 1010, 1013, 65923, 884, 65921, + 119365, 65925, 65909, 65910, 65931, 8189, 65924, 65916, 8126, 8127, 8143, + 8142, 8141, 8128, 981, 982, 1020, 1009, 1014, 945, 8112, 8048, 8114, + 7937, 7941, 8069, 7943, 8071, 7939, 8067, 8065, 7936, 7940, 8068, 7942, + 8070, 7938, 8066, 8064, 8118, 8119, 8049, 8116, 8115, 940, 8113, 985, + 883, 989, 948, 949, 7953, 7957, 7955, 7952, 7956, 7954, 8051, 8050, 941, + 951, 7969, 7973, 8085, 7975, 8087, 7971, 8083, 8081, 7968, 7972, 8084, + 7974, 8086, 7970, 8082, 8080, 8134, 8135, 8053, 8132, 8052, 8130, 8131, + 942, 953, 7985, 7991, 7989, 7987, 970, 8151, 8147, 8146, 912, 7984, 7990, + 7988, 7986, 8150, 8144, 8054, 8055, 943, 8145, 965, 8017, 8023, 8021, + 8019, 971, 8167, 8163, 8162, 944, 8016, 8022, 8020, 8018, 8166, 8160, + 8058, 8059, 973, 8161, 954, 991, 969, 8033, 8037, 8101, 8039, 8103, 8035, + 8099, 8097, 8032, 8036, 8100, 8038, 8102, 8034, 8098, 8096, 8182, 8183, + 8061, 8180, 8060, 8178, 8179, 974, 959, 8001, 8005, 8003, 8000, 8004, + 8002, 8057, 8056, 972, 887, 966, 968, 960, 961, 8165, 8164, 993, 1019, + 987, 963, 1016, 952, 964, 962, 947, 967, 946, 881, 950, 955, 956, 957, + 958, 893, 891, 892, 7527, 7530, 7529, 7528, 7526, 65952, 65932, 65918, + 65912, 977, 65929, 65917, 65911, 900, 65914, 979, 980, 978, 8175, 119297, + 119315, 119316, 119317, 119318, 119319, 119300, 119320, 119321, 119322, + 119323, 119324, 119296, 119305, 119306, 119307, 119308, 119309, 119310, + 119311, 119312, 119313, 119314, 119298, 119299, 119301, 119302, 119303, + 119304, 890, 65913, 976, 65928, 65930, 894, 127823, 128215, 128154, + 129367, 129654, 128512, 129322, 129321, 128513, 128568, 128556, 983110, + 11218, 128151, 8370, 128130, 127928, 129454, 2693, 2694, 2704, 2708, + 2722, 2721, 2727, 2726, 2720, 2719, 2725, 2724, 2699, 2784, 2700, 2785, + 2741, 2697, 2698, 2695, 2696, 2739, 2738, 2809, 2713, 2723, 2718, 2728, + 2742, 2743, 2744, 2733, 2732, 2715, 2714, 2712, 2711, 2717, 2716, 2710, + 2709, 2731, 2730, 2745, 2734, 2736, 2735, 2703, 2707, 2814, 2689, 2812, + 2815, 2813, 2811, 2810, 2748, 2749, 2690, 2765, 2691, 2757, 2761, 2750, + 2760, 2764, 2753, 2754, 2755, 2756, 2786, 2787, 2751, 2752, 2759, 2763, + 2701, 2705, 2800, 2801, 2795, 2794, 2797, 2796, 2793, 2792, 2790, 2799, + 2791, 2798, 2768, 73092, 73082, 73056, 73057, 73064, 73067, 73091, 73090, + 73081, 73080, 73086, 73085, 73076, 73075, 73060, 73061, 73058, 73059, + 73087, 73077, 73071, 73070, 73084, 73083, 73079, 73078, 73089, 73088, + 73074, 73073, 73094, 73093, 73066, 73063, 73095, 73072, 73096, 73097, + 73069, 73068, 73110, 73109, 73098, 73105, 73108, 73101, 73102, 73099, + 73100, 73107, 73104, 73111, 73125, 73124, 73127, 73126, 73123, 73122, + 73120, 73129, 73121, 73128, 73112, 2678, 2673, 2650, 2584, 2583, 2649, + 2582, 2581, 2565, 2566, 2576, 2580, 2594, 2593, 2599, 2598, 2652, 2608, + 2592, 2591, 2597, 2596, 2569, 2570, 2567, 2568, 2611, 2610, 2585, 2595, + 2590, 2600, 2605, 2604, 2587, 2586, 2589, 2588, 2603, 2602, 2614, 2616, + 2579, 2575, 2654, 2617, 2606, 2613, 2607, 2651, 983656, 983655, 983654, + 983653, 983658, 983657, 2561, 2562, 2641, 2620, 2677, 2637, 2563, 2622, + 2632, 2636, 2625, 2626, 2623, 2624, 2635, 2631, 2672, 2674, 2676, 2667, + 2666, 2669, 2668, 2665, 2664, 2662, 2671, 2663, 2670, 2675, 90412, 90414, 90411, 90410, 90373, 90388, 90382, 90381, 90387, 90386, 90380, 90379, 90385, 90384, 90392, 90391, 90375, 90374, 90372, 90371, 90377, 90376, 90370, 90369, 90390, 90389, 90378, 90396, 90393, 90395, 90397, 90383, @@ -11471,1008 +10935,911 @@ static const unsigned int dawg_pos_to_codepoint[] = { 68136, 68138, 68137, 68144, 68096, 68165, 68164, 68166, 68167, 68179, 68178, 68183, 68176, 68182, 68181, 68184, 68180, 68177, 68152, 68153, 68109, 68154, 68111, 68110, 68099, 68101, 68097, 68102, 68098, 68108, - 68159, 68168, 129711, 101120, 101121, 101122, 101123, 101124, 101125, - 101126, 101127, 101128, 101129, 101130, 101131, 101132, 101133, 101134, - 101135, 101136, 101137, 101138, 101139, 101140, 101141, 101142, 101143, - 101144, 101145, 101146, 101147, 101148, 101149, 101150, 101151, 101152, - 101153, 101154, 101155, 101156, 101157, 101158, 101159, 101160, 101161, - 101162, 101163, 101164, 101165, 101166, 101167, 101168, 101169, 101170, - 101171, 101172, 101173, 101174, 101175, 101176, 101177, 101178, 101179, - 101180, 101181, 101182, 101183, 101184, 101185, 101186, 101187, 101188, - 101189, 101190, 101191, 101192, 101193, 101194, 101195, 101196, 101197, - 101198, 101199, 101200, 101201, 101202, 101203, 101204, 101205, 101206, - 101207, 101208, 101209, 101210, 101211, 101212, 101213, 101214, 101215, - 101216, 101217, 101218, 101219, 101220, 101221, 101222, 101223, 101224, - 101225, 101226, 101227, 101228, 101229, 101230, 101231, 101232, 101233, - 101234, 101235, 101236, 101237, 101238, 101239, 101240, 101241, 101242, - 101243, 101244, 101245, 101246, 101247, 101248, 101249, 101250, 101251, - 101252, 101253, 101254, 101255, 101256, 101257, 101258, 101259, 101260, - 101261, 101262, 101263, 101264, 101265, 101266, 101267, 101268, 101269, - 101270, 101271, 101272, 101273, 101274, 101275, 101276, 101277, 101278, - 101279, 101280, 101281, 101282, 101283, 101284, 101285, 101286, 101287, - 101288, 101289, 101290, 101291, 101292, 101293, 101294, 101295, 101296, - 101297, 101298, 101299, 101300, 101301, 101302, 101303, 101304, 101305, - 101306, 101307, 101308, 101309, 101310, 101311, 101312, 101313, 101314, - 101315, 101316, 101317, 101318, 101319, 101320, 101321, 101322, 101323, - 101324, 101325, 101326, 101327, 101328, 101329, 101330, 101331, 101332, - 101333, 101334, 101335, 101336, 101337, 101338, 101339, 101340, 101341, - 101342, 101343, 101344, 101345, 101346, 101347, 101348, 101349, 101350, - 101351, 101352, 101353, 101354, 101355, 101356, 101357, 101358, 101359, - 101360, 101361, 101362, 101363, 101364, 101365, 101366, 101367, 101368, - 101369, 101370, 101371, 101372, 101373, 101374, 101375, 101584, 101585, - 101586, 101587, 101588, 101589, 101376, 101377, 101378, 101379, 101380, - 101381, 101382, 101383, 101384, 101385, 101386, 101387, 101388, 101389, - 101390, 101391, 101392, 101393, 101394, 101395, 101396, 101397, 101398, - 101399, 101400, 101401, 101402, 101403, 101404, 101405, 101406, 101407, - 101408, 101409, 101410, 101411, 101412, 101413, 101414, 101415, 101416, - 101417, 101418, 101419, 101420, 101421, 101422, 101423, 101424, 101425, - 101426, 101427, 101428, 101429, 101430, 101431, 101432, 101433, 101434, - 101435, 101436, 101437, 101438, 101439, 101440, 101441, 101442, 101443, - 101444, 101445, 101446, 101447, 101448, 101449, 101450, 101451, 101452, - 101453, 101454, 101455, 101456, 101457, 101458, 101459, 101460, 101461, - 101462, 101463, 101464, 101465, 101466, 101467, 101468, 101469, 101470, - 101471, 101472, 101473, 101474, 101475, 101476, 101477, 101478, 101479, - 101480, 101481, 101482, 101483, 101484, 101485, 101486, 101487, 101488, - 101489, 101490, 101491, 101492, 101493, 101494, 101495, 101496, 101497, - 101498, 101499, 101500, 101501, 101502, 101503, 101504, 101505, 101506, - 101507, 101508, 101509, 101510, 101511, 101512, 101513, 101514, 101515, - 101516, 101517, 101518, 101519, 101520, 101521, 101522, 101523, 101524, - 101525, 101526, 101527, 101528, 101529, 101530, 101531, 101532, 101533, - 101534, 101535, 101536, 101537, 101538, 101539, 101540, 101541, 101542, - 101543, 101544, 101545, 101546, 101547, 101548, 101549, 101550, 101551, - 101552, 101553, 101554, 101555, 101556, 101557, 101558, 101559, 101560, - 101561, 101562, 101563, 101564, 101565, 101566, 101567, 101568, 101569, - 101570, 101571, 101572, 101573, 101574, 101575, 101576, 101577, 101578, - 101579, 101580, 101581, 101582, 101583, 101631, 94180, 983960, 983965, - 983970, 983975, 983962, 983964, 983961, 983963, 983957, 983959, 983956, - 983958, 983977, 983979, 983978, 983972, 983974, 983967, 983969, 983971, - 983973, 983966, 983968, 983989, 983983, 983985, 983986, 983987, 983980, - 983982, 983984, 983981, 983976, 983988, 6107, 6052, 6064, 6051, 6067, - 6066, 6065, 6055, 6057, 6058, 6056, 6053, 6054, 6063, 983994, 983991, - 983992, 983993, 6061, 6062, 6059, 6060, 6022, 6024, 6021, 6023, 6017, - 6019, 6016, 6018, 6020, 6030, 6025, 6035, 6037, 6039, 6038, 6046, 6045, - 6047, 6032, 6034, 6027, 6029, 6031, 6033, 6026, 6028, 6049, 6043, 6040, - 6042, 6044, 6041, 6036, 6048, 6050, 6108, 6109, 6095, 6096, 6099, 6091, - 6101, 6104, 6102, 6098, 6094, 6100, 6106, 6092, 6087, 6090, 6093, 6103, - 6105, 6088, 6086, 6089, 6097, 6652, 6636, 6655, 6639, 6653, 6637, 6654, - 6638, 6651, 6635, 6650, 6634, 6133, 6137, 6136, 6134, 6135, 6130, 6132, - 6131, 6129, 6128, 6624, 6648, 6632, 6649, 6633, 6647, 6631, 6646, 6630, - 6645, 6629, 6642, 6626, 6640, 6643, 6627, 6644, 6628, 6641, 6625, 6069, - 6068, 6070, 983996, 6082, 6083, 6085, 6071, 6080, 6072, 6078, 983995, - 6084, 6073, 6079, 6074, 983990, 6075, 6077, 6076, 6081, 6117, 6116, 6119, - 6118, 6115, 6114, 6112, 6121, 6113, 6120, 70204, 70201, 70200, 70208, - 70185, 70178, 70179, 70177, 70155, 70156, 70154, 70172, 70167, 70166, - 70173, 70171, 70161, 70160, 70144, 70145, 70149, 70151, 70165, 70164, - 70170, 70169, 70187, 70183, 70157, 70168, 70163, 70174, 70159, 70158, - 70153, 70152, 70176, 70175, 70186, 70180, 70207, 70182, 70184, 70181, - 70148, 70146, 70150, 70147, 70199, 70206, 70198, 70197, 70196, 70203, - 70209, 70188, 70193, 70195, 70189, 70190, 70192, 70194, 70191, 70202, - 70205, 70357, 70358, 70356, 70333, 70334, 70332, 70345, 70347, 70344, - 70352, 70351, 70340, 70339, 70338, 70320, 70321, 70327, 70329, 70346, - 70361, 70343, 70342, 70350, 70349, 70324, 70325, 70322, 70323, 70335, - 70348, 70341, 70353, 70337, 70336, 70331, 70330, 70355, 70354, 70364, - 70365, 70366, 70362, 70359, 70363, 70360, 70326, 70328, 70377, 70378, - 70367, 70368, 70374, 70376, 70371, 70372, 70369, 70370, 70373, 70375, - 70389, 70388, 70391, 70390, 70387, 70386, 70384, 70393, 70385, 70392, - 93521, 93520, 93525, 93524, 93519, 93518, 93523, 93522, 93512, 93517, - 93526, 93530, 93529, 93514, 93513, 93511, 93510, 93516, 93515, 93509, - 93508, 93528, 93527, 93537, 93536, 93538, 93534, 93531, 93533, 93535, - 93532, 93507, 93505, 93549, 93548, 93504, 93547, 93506, 93539, 93544, - 93546, 93541, 93542, 93543, 93540, 93545, 93551, 93550, 93557, 93556, - 93559, 93558, 93555, 93554, 93552, 93561, 93553, 93560, 128143, 128535, - 128537, 128538, 128573, 128139, 129373, 8365, 128088, 129665, 129486, - 129698, 12927, 128040, 11235, 129404, 127991, 129357, 128030, 129692, - 128728, 917505, 3805, 3804, 983206, 983207, 3743, 3741, 3807, 3806, 3714, - 3716, 3713, 983209, 3747, 3749, 3730, 3729, 3736, 3728, 3727, 3731, 3726, - 3744, 3721, 3718, 3724, 3756, 3740, 3742, 3739, 3752, 3753, 3754, 3722, - 3734, 3735, 3733, 3755, 3758, 3719, 3725, 3737, 3738, 3720, 3732, 3745, - 983208, 3751, 3746, 3757, 3773, 3772, 3770, 3785, 3786, 3787, 3784, 3760, - 3762, 3780, 3763, 3779, 3761, 3771, 3766, 3767, 3768, 3769, 3776, 3777, - 3764, 3765, 3778, 3782, 3790, 3759, 3797, 3796, 3799, 3798, 3795, 3794, - 3792, 3801, 3793, 3800, 3788, 3789, 128996, 129003, 128309, 128311, - 128998, 128994, 129001, 68413, 68415, 128992, 128310, 128999, 68412, - 68414, 118324, 118319, 118322, 118323, 118303, 118304, 118336, 118331, - 118328, 118315, 118314, 118306, 118316, 118318, 118334, 118335, 118333, - 118327, 118339, 118341, 118342, 118340, 118320, 118338, 118332, 118302, - 118325, 118309, 118317, 118307, 118313, 118326, 118329, 118312, 118330, - 118352, 118348, 118351, 118350, 118347, 118344, 118345, 118343, 118349, - 118346, 118305, 118321, 118301, 118299, 118298, 118310, 118311, 118308, - 118300, 118337, 11004, 10201, 10200, 10782, 128995, 129002, 128308, - 128997, 128993, 129000, 9711, 10923, 10925, 8382, 9790, 127772, 127767, - 65, 258, 7858, 7856, 7854, 7862, 7860, 550, 480, 7840, 512, 196, 478, - 197, 506, 7680, 256, 983564, 194, 7848, 7846, 7844, 7852, 7850, 461, - 7842, 260, 983590, 983592, 192, 193, 514, 195, 570, 198, 508, 482, 42946, - 393, 11373, 42808, 42810, 42802, 42804, 42806, 42812, 66, 386, 42902, - 7686, 7684, 7682, 385, 579, 42822, 42932, 67, 199, 7688, 264, 268, 262, - 42948, 391, 42898, 266, 571, 42960, 42796, 42798, 42862, 42931, 68, 498, - 453, 42951, 272, 7696, 7698, 270, 395, 7694, 7692, 7690, 394, 497, 452, - 42964, 42962, 69, 552, 7708, 202, 983586, 7874, 7872, 7870, 983584, 7878, - 7876, 7704, 282, 278, 983598, 983600, 7864, 516, 203, 7868, 7706, 274, - 7700, 7702, 983570, 983572, 983574, 7866, 280, 983594, 983596, 200, 201, - 518, 276, 582, 439, 494, 440, 42786, 42788, 42858, 208, 425, 330, 70, - 401, 7710, 42904, 71, 290, 284, 486, 500, 286, 7712, 42912, 403, 288, - 484, 577, 42938, 42940, 42942, 404, 983199, 72, 7722, 7720, 292, 542, - 7718, 11367, 7716, 7714, 42922, 294, 11381, 502, 42790, 73, 520, 7882, - 304, 207, 7726, 206, 463, 298, 983566, 296, 7724, 7880, 302, 983604, - 983606, 204, 205, 522, 300, 407, 42873, 42875, 42877, 42882, 42884, - 42886, 406, 42860, 74, 308, 42930, 983608, 584, 75, 310, 488, 42818, - 11369, 7730, 42816, 42820, 7728, 7732, 42914, 408, 76, 42925, 573, 11360, - 7734, 7736, 11362, 319, 456, 321, 315, 7740, 317, 42824, 313, 7738, - 983610, 42970, 42972, 455, 77, 7742, 7746, 7744, 983612, 11374, 7930, - 7932, 42966, 78, 325, 7754, 327, 459, 544, 7752, 413, 504, 323, 42896, - 7750, 7748, 42916, 209, 458, 79, 42826, 42828, 332, 7760, 7762, 415, 212, - 7892, 7890, 7888, 7896, 7894, 465, 214, 554, 558, 560, 7884, 524, 336, - 490, 492, 216, 510, 213, 7758, 7756, 556, 983576, 983578, 983580, 416, - 7902, 7900, 7898, 7906, 7904, 7886, 210, 211, 526, 334, 42944, 400, 390, - 42934, 418, 42830, 546, 80, 42834, 11363, 42832, 42836, 7764, 420, 7766, - 42958, 81, 42840, 42838, 82, 342, 344, 7770, 7772, 7768, 528, 983614, - 11364, 340, 7774, 530, 42918, 588, 42842, 42997, 42923, 42814, 398, - 42844, 42955, 83, 352, 7782, 350, 536, 348, 346, 7780, 7778, 7784, 7776, - 42956, 42953, 11390, 983582, 42920, 42949, 586, 42926, 42891, 7838, - 42968, 42924, 399, 84, 354, 7792, 538, 356, 574, 7788, 7786, 7790, 430, - 428, 358, 42878, 11375, 11376, 42893, 42928, 42880, 412, 42929, 581, 222, - 42852, 42854, 388, 444, 423, 42794, 42792, 85, 219, 7798, 467, 220, 473, - 475, 471, 469, 7794, 532, 368, 7908, 431, 7916, 7914, 7912, 7920, 7918, - 7910, 362, 7802, 983568, 983620, 983622, 370, 983616, 983618, 360, 7800, - 7796, 217, 218, 534, 364, 366, 42936, 580, 433, 86, 42846, 7806, 7804, - 434, 42850, 42906, 42908, 42910, 42856, 42848, 87, 372, 7812, 7816, 7814, - 7808, 7810, 11378, 503, 88, 7820, 7818, 89, 374, 376, 7924, 7822, 7922, - 435, 7926, 7934, 221, 562, 7928, 590, 540, 90, 7824, 381, 377, 11371, - 7826, 379, 7828, 11391, 437, 42950, 548, 306, 338, 10013, 43007, 43005, - 43006, 43003, 43004, 42999, 450, 7461, 684, 664, 685, 662, 122638, 446, - 661, 426, 674, 451, 122634, 7431, 7430, 7459, 618, 641, 671, 122628, - 7436, 7439, 7440, 630, 7445, 640, 7438, 7449, 43846, 42870, 7451, 11387, - 122626, 122640, 43002, 7450, 665, 7427, 610, 667, 7424, 7425, 7428, 7429, - 42800, 668, 7434, 7435, 7437, 628, 7448, 42927, 42801, 7452, 7456, 7457, - 655, 7458, 663, 122639, 42895, 443, 447, 448, 449, 660, 673, 7460, 422, - 7547, 7550, 97, 259, 7859, 7857, 7855, 7863, 7861, 551, 481, 7841, 513, - 228, 479, 229, 507, 7681, 7834, 7567, 257, 983565, 226, 7849, 7847, 7845, - 7853, 7851, 462, 7843, 261, 983591, 983593, 224, 225, 515, 227, 11365, - 43825, 230, 983624, 509, 483, 42947, 593, 7568, 42809, 42811, 42803, - 42805, 42807, 42813, 98, 387, 42903, 7687, 7532, 7552, 7685, 7683, 595, - 384, 43824, 43827, 629, 43853, 43837, 43838, 43826, 42823, 7447, 42933, - 99, 231, 7689, 265, 597, 269, 263, 42900, 122653, 392, 42899, 267, 572, - 43859, 43860, 43861, 42961, 666, 631, 606, 42797, 42799, 42863, 100, - 42952, 273, 396, 598, 7697, 7699, 545, 271, 122661, 7533, 7695, 599, - 7569, 7553, 7693, 7691, 676, 122642, 122649, 7839, 567, 607, 644, 305, - 42965, 43848, 43850, 42963, 499, 454, 675, 677, 43878, 568, 42865, 101, - 553, 7709, 234, 983587, 7875, 7873, 7871, 983585, 7879, 7877, 7705, 283, - 279, 983599, 983601, 7865, 517, 235, 11384, 7869, 7707, 275, 7701, 7703, - 983571, 983573, 983575, 43828, 7867, 281, 983595, 983597, 232, 233, 519, - 277, 7570, 583, 42787, 42789, 331, 43836, 122644, 643, 122635, 122636, - 7563, 646, 7576, 658, 441, 659, 495, 122648, 7578, 442, 42859, 240, 102, - 7534, 7554, 402, 7711, 42905, 681, 122624, 103, 291, 285, 487, 501, 287, - 7713, 7555, 42913, 608, 289, 485, 578, 42939, 42941, 42943, 611, 983200, - 104, 7723, 7721, 293, 543, 7719, 11368, 7717, 7715, 7830, 42901, 614, - 295, 11382, 983631, 983632, 42791, 615, 405, 105, 238, 464, 239, 7727, - 983602, 983588, 983603, 7883, 521, 299, 983567, 303, 983605, 983607, 297, - 7725, 7881, 236, 237, 523, 301, 616, 122650, 7574, 42874, 42876, 7545, - 42883, 42885, 42887, 43876, 43840, 617, 7548, 43873, 42861, 106, 309, - 669, 496, 983609, 585, 107, 311, 489, 42819, 11370, 7731, 42817, 42821, - 7729, 7733, 7556, 42915, 409, 312, 108, 620, 122643, 410, 316, 7741, 564, - 318, 7735, 7737, 43832, 11361, 619, 43833, 320, 122662, 42825, 314, 7739, - 43831, 621, 42894, 122641, 7557, 983611, 322, 42971, 411, 622, 122629, - 43829, 383, 7836, 7835, 7837, 682, 683, 42866, 457, 109, 7743, 43834, - 7535, 7558, 7747, 7745, 983613, 625, 7931, 7933, 42967, 42867, 110, 326, - 7755, 43835, 565, 328, 414, 7753, 626, 122663, 7536, 505, 324, 42897, - 7751, 7749, 7559, 627, 42917, 241, 329, 983589, 42868, 460, 111, 244, - 7893, 7891, 7889, 7897, 7895, 466, 246, 555, 559, 561, 7885, 525, 337, - 42827, 11386, 42829, 333, 7761, 7763, 491, 493, 248, 511, 245, 7759, - 7757, 557, 983577, 983579, 983581, 417, 7903, 7901, 7899, 7907, 7905, - 7887, 242, 243, 527, 335, 122651, 42945, 596, 983625, 983626, 7575, - 43839, 43874, 603, 7571, 42935, 419, 42831, 547, 112, 42835, 7549, 42833, - 42837, 7765, 7537, 7560, 421, 7767, 42959, 632, 113, 42841, 672, 587, - 42839, 569, 114, 343, 43849, 345, 7771, 7773, 7769, 529, 638, 7539, - 122646, 7775, 636, 983615, 637, 122664, 7538, 341, 531, 7561, 42919, 589, - 43847, 42843, 42998, 604, 7572, 605, 639, 122625, 600, 122631, 8580, - 42815, 122627, 42869, 42845, 612, 115, 347, 7781, 353, 7783, 351, 537, - 349, 122654, 7779, 7785, 7777, 42957, 42954, 575, 983583, 122665, 7540, - 7562, 42921, 642, 42892, 43872, 601, 983629, 983630, 7573, 602, 43851, - 43852, 609, 43830, 223, 7441, 7442, 7443, 7455, 7454, 7453, 42969, 645, - 43845, 116, 355, 7793, 539, 566, 357, 11366, 7831, 7789, 7787, 122666, - 7541, 7791, 427, 429, 122633, 648, 359, 679, 122647, 122652, 7546, 254, - 42853, 42855, 389, 445, 424, 7446, 42795, 397, 613, 686, 687, 7433, - 42879, 7444, 43842, 43841, 43843, 43844, 7432, 633, 43880, 122645, 634, - 122632, 11385, 635, 647, 122637, 652, 983627, 983628, 592, 594, 7426, - 623, 624, 654, 122630, 43857, 477, 7543, 670, 42881, 653, 42871, 680, - 678, 43879, 11383, 42793, 117, 649, 43855, 251, 7799, 468, 252, 474, 476, - 472, 470, 7795, 533, 369, 7909, 432, 7917, 7915, 7913, 7921, 7919, 7911, - 363, 7803, 983569, 983621, 983623, 371, 983617, 983619, 7577, 367, 361, - 7801, 7797, 249, 43854, 42937, 250, 535, 365, 43858, 650, 7551, 7531, - 43856, 42872, 43875, 118, 42847, 7807, 7564, 11380, 11377, 7805, 651, - 42851, 42907, 42909, 42911, 42857, 42849, 119, 373, 7813, 7817, 7815, - 7809, 7811, 7832, 11379, 120, 7821, 7819, 43863, 43864, 43865, 43862, - 7565, 121, 375, 255, 7925, 7823, 7923, 436, 7927, 7935, 43866, 591, 253, - 563, 7929, 7833, 541, 122, 378, 7825, 657, 382, 11372, 7827, 380, 7829, - 576, 438, 7542, 7566, 656, 549, 64256, 64259, 64260, 64257, 64258, 307, - 64261, 64262, 339, 8347, 8340, 8336, 8337, 8341, 7522, 11388, 8342, 8343, - 8344, 8345, 8338, 8346, 7523, 8348, 7524, 7525, 8339, 129726, 127811, - 129388, 129897, 129916, 129947, 10203, 10202, 129899, 129917, 117902, - 128494, 12296, 10641, 10643, 11058, 11056, 10576, 10571, 10570, 10574, - 12304, 10647, 123, 9128, 9129, 9127, 12300, 8968, 9948, 10714, 12298, - 8220, 11816, 11780, 129287, 129284, 129285, 129283, 129286, 9686, 11240, - 9612, 129977, 117924, 118288, 129970, 118285, 118283, 118435, 118440, - 129940, 129932, 128379, 128709, 11804, 10204, 9614, 9615, 129999, 10197, - 8596, 8700, 8697, 8622, 10568, 8660, 10500, 8654, 8621, 11012, 8703, - 11020, 129112, 11108, 11788, 10181, 8907, 9609, 8216, 11814, 128488, 91, - 9123, 9121, 10639, 10637, 8261, 10635, 11863, 11861, 9122, 11778, 10703, - 129900, 11785, 117771, 129985, 128492, 118434, 118441, 9610, 9613, 12308, - 129998, 8867, 12302, 10627, 12310, 10629, 12314, 12312, 10712, 128398, - 9611, 10620, 8970, 130027, 130019, 8905, 40, 9117, 9115, 9116, 11808, - 9144, 9001, 117856, 118265, 10748, 171, 117774, 128269, 117920, 117846, - 117922, 117911, 117861, 117762, 117918, 117880, 10553, 10154, 1422, - 117832, 117906, 117908, 129307, 4054, 4056, 117872, 117876, 9958, 8294, - 8237, 8234, 8206, 8592, 10563, 11074, 11083, 11082, 10611, 129973, 10618, - 10615, 11070, 8676, 8633, 10525, 129032, 8619, 11064, 8698, 10566, - 129040, 129024, 8602, 11024, 11025, 8610, 11066, 11065, 129028, 129176, - 129044, 8617, 8695, 8612, 10527, 129216, 8646, 10521, 129192, 129184, - 11144, 11013, 10603, 10599, 10590, 10582, 8637, 10594, 10602, 10598, - 10586, 10578, 8636, 8651, 129778, 129088, 129092, 11104, 11136, 11130, - 983241, 11174, 11172, 129064, 129060, 129056, 129072, 129068, 11120, - 11114, 11140, 129168, 10510, 8666, 129186, 11067, 11069, 11068, 11244, - 11061, 11060, 11062, 11063, 8606, 8678, 129172, 8604, 8656, 10498, 8653, - 10502, 10523, 10508, 8672, 129194, 129076, 129188, 8701, 8647, 129783, - 129190, 128620, 8668, 129080, 129104, 129084, 11077, 9804, 128006, 7213, - 7221, 7216, 7220, 7215, 7214, 7217, 7218, 7219, 7170, 7169, 7168, 7184, - 7183, 7182, 7247, 7193, 7180, 7188, 7187, 7186, 7185, 7172, 7171, 7198, - 7197, 7190, 7189, 7173, 7177, 7181, 7192, 7191, 7246, 7245, 7179, 7178, - 7175, 7174, 7201, 7200, 7176, 7196, 7195, 7199, 7202, 7194, 7203, 7227, - 7231, 7230, 7228, 7229, 7223, 7222, 7205, 7204, 7210, 7211, 7208, 7209, - 7206, 7212, 7207, 7237, 7236, 7239, 7238, 7235, 7234, 7232, 7241, 7233, - 7240, 10897, 10895, 10893, 10899, 10891, 10614, 10889, 10887, 8922, 8934, - 8808, 10918, 10920, 10885, 10877, 10881, 10883, 10879, 8818, 8804, 8822, - 8806, 10873, 10875, 8918, 60, 118480, 128210, 127898, 127819, 129461, - 128626, 128955, 128969, 128943, 11212, 128964, 10099, 128648, 10098, - 9617, 128937, 128949, 128978, 128960, 129653, 128910, 10072, 128930, - 128504, 9735, 128498, 128497, 6429, 6404, 6403, 6412, 6430, 6411, 6421, - 6410, 6405, 6415, 6425, 6426, 6427, 6419, 6418, 6407, 6406, 6414, 6413, - 6409, 6408, 6402, 6401, 6417, 6416, 6428, 6423, 6420, 6422, 6424, 6458, - 6457, 6459, 6464, 6449, 6452, 6450, 6448, 6456, 6454, 6453, 6455, 6451, - 6442, 6443, 6441, 6432, 6436, 6438, 6440, 6437, 6439, 6435, 6433, 6434, - 6400, 6468, 6469, 6475, 6474, 6477, 6476, 6473, 6472, 6470, 6479, 6471, - 6478, 13007, 10770, 10771, 10772, 983062, 8232, 983068, 983143, 67143, - 67146, 67151, 67165, 67166, 67167, 67157, 67158, 67159, 67160, 67161, - 67162, 67163, 67164, 67171, 67172, 67173, 67168, 67169, 67170, 67174, - 67175, 67176, 67177, 67178, 67179, 67230, 67231, 67180, 67181, 67182, - 67183, 67184, 67185, 67186, 67187, 67188, 67189, 67190, 67191, 67192, - 67193, 67194, 67195, 67196, 67197, 67198, 67199, 67200, 67201, 67202, - 67203, 67204, 67205, 67206, 67207, 67208, 67209, 67210, 67211, 67212, - 67213, 67214, 67215, 67216, 67217, 67218, 67219, 67220, 67221, 67222, - 67223, 67224, 67225, 67226, 67227, 67228, 67229, 67232, 67233, 67234, - 67235, 67236, 67237, 67238, 67239, 67240, 67241, 67242, 67243, 67244, - 67245, 67246, 67247, 67248, 67249, 67250, 67251, 67252, 67253, 67254, - 67255, 67256, 67257, 67258, 67259, 67260, 67261, 67262, 67263, 67264, - 67274, 67275, 67276, 67277, 67278, 67279, 67280, 67281, 67282, 67283, - 67284, 67285, 67286, 67287, 67288, 67289, 67290, 67291, 67292, 67293, - 67294, 67295, 67296, 67297, 67298, 67299, 67300, 67301, 67302, 67303, - 67304, 67265, 67266, 67267, 67268, 67269, 67270, 67271, 67272, 67273, - 67325, 67326, 67327, 67328, 67329, 67330, 67305, 67306, 67307, 67308, - 67309, 67310, 67311, 67312, 67313, 67314, 67315, 67316, 67317, 67318, - 67319, 67320, 67321, 67322, 67323, 67324, 67331, 67332, 67333, 67334, - 67335, 67336, 67337, 67338, 67349, 67350, 67351, 67352, 67353, 67354, - 67355, 67356, 67357, 67358, 67359, 67360, 67361, 67362, 67363, 67364, - 67365, 67366, 67367, 67368, 67378, 67379, 67380, 67381, 67382, 67369, - 67370, 67371, 67372, 67373, 67374, 67375, 67376, 67377, 67339, 67340, - 67341, 67342, 67343, 67344, 67345, 67346, 67347, 67348, 67401, 67404, - 67403, 67402, 67400, 67398, 67393, 67397, 67395, 67394, 67399, 67392, - 67396, 67408, 67409, 67410, 67406, 67407, 67405, 67411, 67413, 67412, - 67424, 67425, 67426, 67427, 67428, 67429, 67430, 67431, 67081, 67082, - 67083, 67084, 67085, 67087, 67088, 67089, 67090, 67091, 67092, 67093, - 67094, 67086, 67095, 67096, 67097, 67098, 67100, 67101, 67102, 67103, - 67104, 67105, 67106, 67107, 67108, 67109, 67110, 67111, 67112, 67113, - 67114, 67115, 67116, 67117, 67118, 67119, 67120, 67121, 67122, 67123, - 67124, 67125, 67126, 67127, 67128, 67129, 67130, 67131, 67132, 67133, - 67134, 67135, 67136, 67137, 67138, 67139, 67140, 67141, 67142, 67072, - 67073, 67074, 67075, 67076, 67077, 67078, 67079, 67080, 67145, 67147, - 67148, 67149, 67150, 67154, 67155, 67144, 67152, 67153, 67156, 67099, - 65667, 65668, 65669, 65670, 65671, 65672, 65673, 65675, 65674, 65677, - 65676, 65665, 65664, 65666, 65681, 65679, 65680, 65682, 65678, 65686, - 65685, 65687, 65693, 65690, 65691, 65692, 65694, 65703, 65696, 65695, - 65697, 65698, 65699, 65701, 65702, 65707, 65706, 65704, 65705, 65708, - 65709, 65710, 65711, 65712, 65713, 65719, 65717, 65714, 65715, 65716, - 65718, 65720, 65721, 65722, 65723, 65724, 65725, 65726, 65727, 65728, - 65729, 65731, 65730, 65732, 65733, 65737, 65734, 65735, 65736, 65738, - 65739, 65740, 65741, 65743, 65742, 65744, 65745, 65747, 65748, 65752, - 65749, 65750, 65751, 65753, 65754, 65755, 65756, 65757, 65779, 65780, - 65781, 65782, 65783, 65784, 65785, 65759, 65760, 65761, 65762, 65763, - 65764, 65765, 65766, 65767, 65768, 65769, 65770, 65771, 65772, 65773, - 65774, 65775, 65776, 65777, 65778, 65758, 65786, 65683, 65684, 65689, - 65688, 65700, 65746, 65561, 65543, 65587, 65582, 65589, 65536, 65541, - 65579, 65566, 65571, 65596, 65569, 65584, 65544, 65559, 65540, 65557, - 65560, 65580, 65606, 65600, 65599, 65577, 65562, 65538, 65573, 65563, - 65609, 65588, 65549, 65568, 65537, 65581, 65574, 65601, 65542, 65593, - 65583, 65594, 65552, 65547, 65605, 65578, 65545, 65585, 65586, 65546, - 65570, 65591, 65564, 65565, 65607, 65610, 65611, 65553, 65590, 65550, - 65539, 65576, 65608, 65551, 65554, 65592, 65603, 65597, 65567, 65572, - 65558, 65555, 65612, 65602, 65556, 65613, 65604, 65620, 65621, 65623, - 65624, 65626, 65627, 65628, 65629, 65622, 65616, 65617, 65619, 65618, - 65625, 128391, 128279, 128482, 128132, 42237, 42235, 42232, 42234, 42236, - 42233, 42206, 42205, 42197, 42196, 42204, 42195, 42228, 42229, 42230, - 42213, 42208, 42224, 42225, 42203, 42202, 42221, 42198, 42216, 42214, - 42200, 42199, 42194, 42193, 42219, 42210, 73648, 42220, 42211, 42212, - 42222, 42223, 42227, 42231, 42192, 42217, 42201, 42209, 42207, 42218, - 42215, 42226, 42238, 42239, 8356, 8374, 129409, 129422, 9806, 128274, - 983079, 983076, 128271, 117785, 117786, 117784, 117783, 117782, 117781, - 8743, 10848, 10846, 10833, 10844, 10842, 10847, 8744, 10841, 10851, - 10850, 10834, 10845, 10843, 10982, 10188, 129688, 10231, 129240, 10234, - 10206, 10232, 10237, 10229, 10235, 11059, 129236, 10230, 129238, 129239, - 129232, 10236, 10233, 10238, 129233, 129234, 10239, 10205, 129524, - 128884, 129719, 128140, 127977, 128261, 129707, 12319, 8270, 11847, - 11848, 95, 118273, 9691, 118276, 118291, 129935, 118436, 118447, 9604, - 9697, 117765, 128394, 129852, 129853, 129870, 129872, 129868, 129856, - 129871, 129869, 129854, 129873, 129855, 128395, 128396, 128393, 10559, - 117934, 117936, 117932, 117930, 117972, 9695, 117960, 117948, 117964, - 117968, 117952, 117956, 117944, 117940, 117817, 129951, 9722, 117820, - 128397, 118428, 117935, 117937, 117933, 117931, 117973, 9694, 117961, - 117949, 117965, 117969, 117953, 117957, 117945, 117941, 117818, 10558, - 128318, 10065, 129950, 9727, 117823, 117767, 129863, 129865, 129867, - 129864, 129861, 129866, 129859, 129862, 129860, 129857, 129858, 10195, - 118431, 10063, 9998, 9987, 118429, 117821, 118430, 117822, 130021, 9605, - 118425, 118426, 118424, 117816, 118427, 117819, 9602, 9601, 9607, 9603, - 118437, 118446, 9606, 129903, 9674, 10208, 129438, 128557, 127853, - 129523, 128886, 129729, 66190, 66192, 66187, 66196, 66199, 66185, 66200, - 66178, 66179, 66176, 66201, 66177, 66202, 66191, 66193, 66181, 66180, - 66203, 66182, 66186, 66189, 66195, 66188, 66197, 66198, 66194, 66183, - 66204, 66184, 67887, 67892, 67881, 67895, 67891, 67886, 67872, 67893, - 67876, 67894, 67883, 67896, 67873, 67897, 67875, 67889, 67874, 67878, - 67880, 67882, 67884, 67890, 67885, 67888, 67877, 67879, 67903, 129317, - 983226, 983234, 983224, 983229, 8468, 129433, 983065, 129668, 129522, - 129497, 69986, 69981, 69991, 69985, 69984, 69990, 69989, 70002, 69997, - 69983, 69982, 69988, 69987, 69995, 69994, 69978, 69977, 69976, 69975, - 69980, 69979, 69974, 69973, 69993, 69992, 70001, 69998, 69996, 70000, - 69999, 69968, 69971, 69969, 69972, 69970, 70006, 70005, 70003, 70004, - 127012, 127019, 127008, 126990, 126999, 126976, 127005, 126987, 126996, - 127004, 126986, 126995, 126979, 127009, 126991, 127000, 127001, 126983, - 126992, 127011, 127010, 126977, 127007, 126989, 126998, 127006, 126988, - 126997, 127015, 127014, 127003, 126985, 126994, 127002, 126984, 126993, - 126978, 126982, 127017, 126981, 126980, 127016, 127018, 127013, 73464, - 73442, 73451, 73448, 73444, 73449, 73447, 73441, 73450, 73440, 73454, - 73445, 73443, 73453, 73456, 73446, 73455, 73452, 73457, 73463, 73461, - 73459, 73462, 73460, 73458, 128892, 3449, 3435, 3434, 3437, 3436, 3433, - 3432, 3430, 3439, 3431, 3438, 3419, 3420, 3446, 3417, 3422, 3416, 3447, - 3444, 3443, 3448, 3418, 3421, 3445, 3333, 3423, 3334, 3344, 3348, 3453, - 3454, 3414, 3451, 3450, 3452, 3455, 3412, 3413, 3355, 3354, 3406, 3362, - 3361, 3367, 3366, 3360, 3386, 3359, 3365, 3364, 3332, 3339, 3424, 3340, - 3425, 3381, 3369, 3363, 3353, 3358, 3368, 3380, 3379, 3378, 3377, 3376, - 3337, 3338, 3346, 3347, 3335, 3336, 3382, 3383, 3384, 3373, 3372, 3352, - 3351, 3357, 3356, 3350, 3349, 3371, 3370, 3342, 3343, 3385, 3374, 3375, - 3441, 3442, 3440, 3328, 3388, 3329, 3387, 3405, 3331, 3389, 3330, 3407, - 3390, 3400, 3404, 3393, 3394, 3395, 3396, 3426, 3427, 3402, 3403, 3391, - 3392, 3398, 3399, 3415, 9895, 9894, 9893, 9794, 10016, 129443, 128104, - 128372, 129333, 128114, 128115, 128378, 128107, 2137, 2122, 2121, 2133, - 2120, 2126, 2132, 2129, 2136, 2113, 2115, 2114, 2116, 2123, 2124, 2125, - 2128, 2130, 2131, 2118, 2134, 2117, 2112, 2127, 2119, 2135, 2138, 2139, - 2142, 68288, 68314, 68313, 68290, 68289, 68293, 68308, 68292, 68291, - 68300, 68299, 68298, 68297, 68306, 68304, 68320, 68318, 68323, 68312, - 68317, 68322, 68309, 68302, 68324, 68305, 68319, 68307, 68321, 68303, - 68294, 68301, 68311, 68295, 68316, 68315, 68310, 68331, 68335, 68334, - 68333, 68332, 68340, 68339, 68338, 68342, 68337, 68341, 68336, 68296, - 68326, 68325, 128094, 129469, 8380, 128368, 129389, 9967, 127809, 129671, - 72835, 72834, 72827, 72826, 72836, 72828, 72821, 72825, 72829, 72823, - 72822, 72819, 72818, 72831, 72830, 72844, 72845, 72838, 72839, 72840, - 72832, 72820, 72846, 72824, 72843, 72833, 72842, 72837, 72841, 72847, - 72886, 72885, 72867, 72866, 72859, 72858, 72868, 72860, 72853, 72857, - 72861, 72855, 72854, 72851, 72850, 72863, 72862, 72876, 72877, 72870, - 72871, 72864, 72852, 72878, 72856, 72875, 72865, 72874, 72869, 72873, - 72879, 72880, 72883, 72881, 72884, 72882, 72816, 72817, 9901, 129355, - 73007, 72980, 72979, 72983, 72982, 72988, 73008, 72987, 72960, 72961, - 72968, 72971, 72985, 72984, 72990, 72989, 72964, 72965, 72962, 72963, - 73005, 72999, 73006, 72973, 72972, 72976, 72986, 72981, 72991, 73001, - 73002, 73003, 72995, 72994, 72978, 72977, 72975, 72974, 72993, 72992, - 73004, 72996, 72998, 73000, 72997, 72966, 72969, 73031, 73030, 73027, - 73028, 73026, 73025, 73024, 73014, 73009, 73020, 73023, 73012, 73013, - 73010, 73011, 73018, 73021, 73029, 73045, 73044, 73047, 73046, 73043, - 73042, 73040, 73049, 73041, 73048, 186, 127405, 12348, 119811, 120778, - 120491, 119827, 120495, 120505, 120507, 119808, 120488, 119809, 120489, - 119833, 120493, 119812, 120492, 120494, 119814, 120490, 119816, 120496, - 119818, 120497, 119819, 120498, 119822, 120502, 120512, 119823, 120509, - 120511, 120503, 119825, 120504, 119826, 120506, 119828, 120508, 119810, - 120510, 119820, 120499, 119821, 120500, 119831, 120501, 119813, 119815, - 119817, 119824, 119829, 119830, 119832, 119837, 120779, 120517, 119834, - 120514, 119835, 120515, 119859, 120519, 119838, 120518, 120520, 119839, - 120531, 119840, 120516, 119842, 120522, 119844, 120523, 119845, 120524, - 119848, 120528, 120538, 119849, 120535, 120537, 120529, 119851, 120530, - 119852, 120532, 119853, 120521, 120533, 119854, 120534, 119836, 120536, - 119846, 120525, 119847, 120526, 119857, 120527, 119841, 119843, 119850, - 119855, 119856, 119858, 120016, 120017, 120018, 120019, 120020, 120021, - 120022, 120023, 120024, 120025, 120026, 120027, 120028, 120029, 120030, - 120031, 120032, 120033, 120034, 120035, 120036, 120037, 120038, 120039, - 120040, 120041, 120042, 120043, 120044, 120045, 120046, 120047, 120048, - 120049, 120050, 120051, 120052, 120053, 120054, 120055, 120056, 120057, - 120058, 120059, 120060, 120061, 120062, 120063, 120064, 120065, 120066, - 120067, 119931, 120611, 120621, 120623, 119912, 120604, 119913, 120605, - 119937, 120609, 119915, 120607, 119916, 120608, 120610, 119918, 120606, - 119920, 120612, 119922, 120613, 119923, 120614, 119926, 120618, 120628, - 119927, 120625, 120627, 120619, 119929, 120620, 119930, 120622, 119932, - 120624, 119914, 120626, 119924, 120615, 119925, 120616, 119935, 120617, - 119917, 119919, 119921, 119928, 119933, 119934, 119936, 120656, 120658, - 120629, 120659, 120655, 120661, 120660, 119938, 120630, 119939, 120631, - 119963, 120635, 119941, 120633, 119942, 120634, 120636, 119943, 120647, - 119944, 120632, 119946, 120638, 119948, 120639, 119949, 120640, 119952, - 120644, 120654, 119953, 120651, 120653, 120645, 119955, 120646, 119956, - 120648, 119957, 120637, 120649, 119958, 120650, 119940, 120652, 119950, - 120641, 119951, 120642, 119961, 120643, 119945, 119947, 119954, 119959, - 119960, 119962, 120657, 120540, 120542, 120513, 120543, 120539, 120545, - 120544, 120541, 120172, 120173, 120174, 120175, 120176, 120177, 120178, - 120179, 120180, 120181, 120182, 120183, 120184, 120185, 120186, 120187, - 120188, 120189, 120190, 120191, 120192, 120193, 120194, 120195, 120196, - 120197, 120198, 120199, 120200, 120201, 120202, 120203, 120204, 120205, - 120206, 120207, 120208, 120209, 120210, 120211, 120212, 120213, 120214, - 120215, 120216, 120217, 120218, 120219, 120220, 120221, 120222, 120223, - 120787, 120786, 120789, 120788, 120785, 120784, 120782, 120791, 120783, - 120790, 120120, 120121, 120123, 120124, 120125, 120126, 120128, 120129, - 120130, 120131, 120132, 120134, 120138, 120139, 120140, 120141, 120142, - 120143, 120144, 120146, 120147, 120148, 120149, 120150, 120151, 120152, - 120153, 120154, 120155, 120156, 120157, 120158, 120159, 120160, 120161, - 120162, 120163, 120164, 120165, 120166, 120167, 120168, 120169, 120170, - 120171, 120797, 120796, 120799, 120798, 120795, 120794, 120792, 120801, - 120793, 120800, 120068, 120069, 120071, 120072, 120073, 120074, 120077, - 120078, 120079, 120080, 120081, 120082, 120083, 120084, 120086, 120087, - 120088, 120089, 120090, 120091, 120092, 120094, 120095, 120096, 120097, - 120098, 120099, 120100, 120101, 120102, 120103, 120104, 120105, 120106, - 120107, 120108, 120109, 120110, 120111, 120112, 120113, 120114, 120115, - 120116, 120117, 120118, 120119, 10189, 119889, 120484, 120485, 120575, - 119886, 120572, 119887, 120573, 119911, 120577, 119890, 120576, 120578, - 119891, 120589, 119892, 120574, 119894, 120580, 119896, 120581, 119897, - 120582, 119900, 120586, 120596, 119901, 120593, 120595, 120587, 119903, - 120588, 119904, 120590, 119905, 120579, 120591, 119906, 120592, 119888, - 120594, 119898, 120583, 119899, 120584, 119909, 120585, 119895, 119902, - 119907, 119908, 119910, 119879, 120553, 120563, 120565, 119860, 120546, - 119861, 120547, 119885, 120551, 119863, 120549, 119864, 120550, 120552, - 119866, 120548, 119868, 120554, 119870, 120555, 119871, 120556, 119874, - 120560, 120570, 119875, 120567, 120569, 120561, 119877, 120562, 119878, - 120564, 119880, 120566, 119862, 120568, 119872, 120557, 119873, 120558, - 119883, 120559, 119865, 119867, 119869, 119876, 119881, 119882, 119884, - 120598, 120600, 120571, 120601, 120597, 120603, 120602, 120599, 120432, - 120433, 120434, 120435, 120436, 120437, 120438, 120439, 120440, 120441, - 120442, 120443, 120444, 120445, 120446, 120447, 120448, 120449, 120450, - 120451, 120452, 120453, 120454, 120455, 120456, 120457, 120458, 120459, - 120460, 120461, 120462, 120463, 120464, 120465, 120466, 120467, 120468, - 120469, 120470, 120471, 120472, 120473, 120474, 120475, 120476, 120477, - 120478, 120479, 120480, 120481, 120482, 120483, 120827, 120826, 120829, - 120828, 120825, 120824, 120822, 120831, 120823, 120830, 10215, 10221, - 10219, 10217, 10223, 10187, 10214, 10220, 10218, 10216, 10222, 120399, - 120727, 120737, 120739, 120380, 120720, 120381, 120721, 120405, 120725, - 120383, 120723, 120384, 120724, 120726, 120386, 120722, 120388, 120728, - 120390, 120729, 120391, 120730, 120394, 120734, 120744, 120395, 120741, - 120743, 120735, 120397, 120736, 120398, 120738, 120400, 120740, 120382, - 120742, 120392, 120731, 120393, 120732, 120403, 120733, 120385, 120387, - 120389, 120396, 120401, 120402, 120404, 120772, 120774, 120745, 120775, - 120771, 120777, 120776, 120406, 120746, 120407, 120747, 120431, 120751, - 120409, 120749, 120410, 120750, 120752, 120411, 120763, 120412, 120748, - 120414, 120754, 120416, 120755, 120417, 120756, 120420, 120760, 120770, - 120421, 120767, 120769, 120761, 120423, 120762, 120424, 120764, 120425, - 120753, 120765, 120426, 120766, 120408, 120768, 120418, 120757, 120419, - 120758, 120429, 120759, 120413, 120415, 120422, 120427, 120428, 120430, - 120773, 120295, 120669, 120679, 120681, 120276, 120662, 120277, 120663, - 120301, 120667, 120279, 120665, 120280, 120666, 120668, 120282, 120664, - 120284, 120670, 120286, 120671, 120287, 120672, 120290, 120676, 120686, - 120291, 120683, 120685, 120677, 120293, 120678, 120294, 120680, 120296, - 120682, 120278, 120684, 120288, 120673, 120289, 120674, 120299, 120675, - 120281, 120283, 120285, 120292, 120297, 120298, 120300, 120714, 120716, - 120687, 120717, 120713, 120719, 120718, 120302, 120688, 120303, 120689, - 120327, 120693, 120305, 120691, 120306, 120692, 120694, 120307, 120705, - 120308, 120690, 120310, 120696, 120312, 120697, 120313, 120698, 120316, - 120702, 120712, 120317, 120709, 120711, 120703, 120319, 120704, 120320, - 120706, 120321, 120695, 120707, 120322, 120708, 120304, 120710, 120314, - 120699, 120315, 120700, 120325, 120701, 120309, 120311, 120318, 120323, - 120324, 120326, 120715, 120817, 120816, 120819, 120818, 120815, 120814, - 120812, 120821, 120813, 120820, 120328, 120329, 120330, 120331, 120332, - 120333, 120334, 120335, 120336, 120337, 120338, 120339, 120340, 120341, - 120342, 120343, 120344, 120345, 120346, 120347, 120348, 120349, 120350, - 120351, 120352, 120353, 120354, 120355, 120356, 120357, 120358, 120359, - 120360, 120361, 120362, 120363, 120364, 120365, 120366, 120367, 120368, - 120369, 120370, 120371, 120372, 120373, 120374, 120375, 120376, 120377, - 120378, 120379, 120224, 120225, 120226, 120227, 120228, 120229, 120230, - 120231, 120232, 120233, 120234, 120235, 120236, 120237, 120238, 120239, - 120240, 120241, 120242, 120243, 120244, 120245, 120246, 120247, 120248, - 120249, 120250, 120251, 120252, 120253, 120254, 120255, 120256, 120257, - 120258, 120259, 120260, 120261, 120262, 120263, 120264, 120265, 120266, - 120267, 120268, 120269, 120270, 120271, 120272, 120273, 120274, 120275, - 120807, 120806, 120809, 120808, 120805, 120804, 120802, 120811, 120803, - 120810, 119964, 119966, 119967, 119970, 119973, 119974, 119977, 119978, - 119979, 119980, 119982, 119983, 119984, 119985, 119986, 119987, 119988, - 119989, 119990, 119991, 119992, 119993, 119995, 119997, 119998, 119999, - 120000, 120001, 120002, 120003, 120005, 120006, 120007, 120008, 120009, - 120010, 120011, 120012, 120013, 120014, 120015, 129481, 119528, 119538, - 119531, 119535, 119525, 119524, 119534, 119529, 119539, 119527, 119537, - 119526, 119536, 119533, 119523, 119532, 119522, 119530, 119520, 119521, - 128470, 175, 8737, 10667, 10666, 10671, 10669, 10670, 10668, 10665, - 10664, 10651, 10653, 8798, 127830, 129470, 129471, 93773, 93764, 93790, - 93787, 983274, 93783, 983273, 93782, 93772, 93766, 93791, 93779, 93789, - 93786, 93776, 93777, 93785, 93775, 93770, 93769, 93771, 93774, 93780, - 93760, 93767, 93781, 93788, 93761, 93768, 93778, 93762, 93763, 93784, - 93765, 93847, 93827, 93846, 93826, 93845, 93825, 93844, 93829, 93828, - 93831, 93830, 93824, 93833, 93832, 93837, 93836, 93834, 93842, 93835, - 93838, 93839, 93843, 93840, 93841, 93805, 93796, 93822, 93819, 983276, - 93815, 983275, 93814, 93804, 93798, 93823, 93811, 93821, 93818, 93808, - 93809, 93817, 93807, 93802, 93801, 93803, 93806, 93812, 93792, 93799, - 93813, 93820, 93793, 93800, 93810, 93794, 93795, 93816, 93797, 93849, - 93850, 93848, 11859, 11852, 11860, 128901, 9899, 10090, 10091, 128967, - 128965, 128944, 10100, 10088, 10092, 10101, 10089, 10093, 8287, 9618, - 128971, 128950, 128938, 9900, 118512, 128963, 128961, 10073, 128974, - 128956, 9898, 128911, 128931, 43761, 44013, 43762, 43760, 44011, 43994, - 43989, 43974, 43746, 43993, 43991, 43751, 43750, 43992, 43986, 43987, - 43990, 43968, 43995, 43976, 43973, 43999, 43977, 44001, 43752, 43747, - 43972, 43998, 43984, 43969, 43753, 43754, 43975, 44000, 43978, 43749, - 43748, 43983, 44002, 43970, 43996, 43971, 43997, 43981, 43988, 43979, - 43985, 43980, 43982, 43744, 43745, 44012, 43763, 43764, 44005, 43757, - 43759, 43758, 44009, 44003, 44007, 44006, 44004, 43755, 44008, 43756, - 44010, 43765, 43766, 44021, 44020, 44023, 44022, 44019, 44018, 44016, - 44025, 44017, 44024, 118475, 129760, 127816, 125140, 125137, 125136, - 125139, 125141, 125138, 125142, 124928, 124929, 124930, 124936, 124937, - 124949, 124950, 124948, 124938, 124956, 124990, 124992, 124974, 124955, - 124964, 124963, 124991, 124957, 124962, 124976, 124996, 124997, 124998, - 124982, 124983, 124984, 125004, 124975, 125003, 125005, 125011, 125018, - 125028, 125029, 125012, 125019, 125020, 125027, 125013, 125035, 124942, - 124934, 125090, 125046, 125078, 125033, 124946, 125048, 125037, 125070, - 125000, 125095, 125121, 124951, 125044, 125041, 125072, 124987, 125066, - 125076, 125074, 125009, 125107, 125108, 125068, 125124, 124945, 125002, - 124931, 125089, 125022, 124980, 125099, 124986, 125100, 125080, 125119, - 124933, 125021, 125015, 125071, 124985, 125117, 125056, 124993, 125039, - 125049, 125043, 125024, 124932, 125047, 125097, 124959, 125069, 125088, - 124999, 125123, 124952, 125036, 125026, 125001, 125085, 124960, 125057, - 125073, 124966, 125098, 125014, 125091, 124989, 125007, 124978, 124940, - 125106, 125050, 125030, 125092, 124941, 125060, 125077, 125102, 125094, - 125053, 125040, 125055, 125104, 125103, 124939, 125017, 124961, 125112, - 125087, 124970, 124971, 124969, 125023, 124979, 125042, 124947, 125086, - 125075, 125051, 125111, 124968, 124944, 125038, 125096, 125016, 125118, - 125109, 124953, 125059, 125052, 125006, 124958, 125093, 125115, 125054, - 124988, 125008, 125084, 125061, 125064, 125120, 125063, 124967, 124977, - 124965, 125031, 983279, 125081, 125082, 983280, 125010, 125067, 124973, - 125032, 124935, 125116, 125122, 125101, 124994, 124995, 125113, 125058, - 125079, 125114, 125065, 125034, 125083, 124954, 125062, 125105, 125110, - 125045, 124943, 124972, 124981, 125025, 125131, 125130, 125133, 125132, - 125129, 125128, 125135, 125127, 125134, 128334, 128697, 68028, 68093, - 68090, 68089, 68086, 68029, 68092, 68091, 68095, 68088, 68087, 68094, - 68000, 68016, 68020, 68021, 68022, 68009, 68010, 68015, 68017, 68014, - 68013, 68018, 68006, 68023, 68012, 68008, 68007, 68019, 68011, 68005, - 68004, 68001, 68002, 68003, 68031, 68030, 68039, 68075, 68057, 68084, - 68066, 68036, 68054, 68081, 68063, 68045, 68072, 68035, 68053, 68080, - 68062, 68044, 68071, 68040, 68076, 68058, 68085, 68067, 68038, 68056, - 68083, 68065, 68047, 68074, 68037, 68055, 68082, 68064, 68046, 68073, - 68034, 68052, 68079, 68061, 68043, 68070, 68033, 68051, 68078, 68060, - 68042, 68069, 68041, 68068, 68032, 68050, 68077, 68059, 67974, 67975, - 67982, 67983, 67978, 67979, 67980, 67981, 67987, 67988, 67989, 67992, - 67993, 67994, 67995, 67996, 67986, 67985, 67990, 67997, 67984, 67977, - 67976, 67991, 67973, 67972, 67968, 67969, 67970, 67971, 67998, 67999, - 9791, 129500, 983173, 9170, 9172, 9177, 9176, 9175, 9173, 9174, 9171, - 9169, 128647, 118467, 128221, 94015, 93989, 93971, 93958, 94019, 94021, - 93953, 94023, 93999, 93995, 94008, 93981, 93979, 93967, 93963, 93993, - 93992, 93983, 93977, 93976, 93975, 93974, 93968, 94032, 93988, 93987, - 93973, 93972, 93997, 93996, 93969, 94106, 94107, 94108, 94109, 94110, - 94111, 94002, 94026, 94022, 94003, 94004, 94010, 93980, 93978, 94099, - 94100, 94101, 94102, 94103, 94104, 94105, 93998, 93994, 94007, 94025, - 93966, 93962, 94024, 93961, 93960, 94000, 94009, 93964, 93965, 94001, - 93970, 93984, 93954, 94017, 94014, 94016, 94013, 94006, 94012, 94005, - 94011, 93986, 93985, 93955, 93952, 94020, 93990, 93957, 93956, 93959, - 93982, 94018, 93991, 94035, 94034, 94033, 94031, 94098, 94096, 94097, - 94095, 94036, 94039, 94040, 94067, 94068, 94038, 94037, 94073, 94075, - 94045, 94071, 94069, 94046, 94047, 94085, 94074, 94049, 94050, 94051, - 94052, 94053, 94086, 94057, 94054, 94084, 94055, 94056, 94041, 94082, - 94048, 94081, 94042, 94076, 94058, 94059, 94060, 94061, 94063, 94064, - 94079, 94087, 94062, 94065, 94080, 94066, 94072, 94070, 94044, 94043, - 94077, 94078, 94083, 983239, 983240, 128300, 127908, 181, 129440, 117772, - 129986, 130022, 130023, 183, 8943, 129686, 127894, 127756, 8357, 128189, - 128469, 128656, 8722, 10793, 10794, 10796, 10795, 10810, 8770, 8723, - 10751, 129694, 129705, 128241, 128242, 128244, 129339, 8871, 71232, - 71229, 71236, 71231, 71230, 71216, 71226, 71228, 71219, 71220, 71221, - 71222, 71223, 71224, 71217, 71218, 71225, 71227, 71234, 71233, 71253, - 71252, 71255, 71254, 71251, 71250, 71248, 71257, 71249, 71256, 71168, - 71169, 71179, 71181, 71195, 71194, 71200, 71199, 71193, 71192, 71198, - 71197, 71174, 71175, 71176, 71177, 71210, 71172, 71173, 71170, 71171, - 71215, 71209, 71186, 71196, 71191, 71201, 71211, 71212, 71213, 71205, - 71204, 71188, 71187, 71185, 71184, 71190, 71189, 71183, 71182, 71203, - 71202, 71214, 71206, 71208, 71207, 71178, 71180, 71235, 43867, 67512, - 714, 700, 67509, 761, 763, 7470, 7471, 7487, 7474, 7483, 7476, 43000, - 7484, 7485, 7468, 7469, 42994, 7472, 7473, 42995, 7475, 7477, 7478, 7479, - 7480, 7481, 7482, 7486, 42996, 42993, 7488, 7489, 11389, 7490, 723, 722, - 42755, 42753, 42757, 42759, 42754, 42752, 42756, 42758, 42652, 122956, - 122958, 122929, 122954, 122932, 122952, 122943, 122987, 122946, 122938, - 122939, 122942, 122960, 122941, 122959, 122989, 122955, 122950, 122948, - 122944, 122951, 122988, 122953, 122934, 122935, 122936, 122933, 122949, - 122931, 122957, 122930, 122947, 122937, 122928, 122940, 122945, 42653, - 7544, 710, 735, 42889, 67510, 42776, 42775, 42777, 750, 698, 725, 709, - 984011, 42765, 42760, 42770, 741, 984012, 42769, 42764, 42774, 745, 762, - 764, 715, 704, 67507, 4348, 42766, 42761, 42771, 742, 721, 67511, 42888, - 42768, 42763, 751, 767, 753, 42773, 717, 754, 755, 744, 759, 719, 718, - 42783, 752, 716, 42778, 703, 43882, 706, 713, 42767, 42762, 42772, 743, - 758, 757, 756, 727, 766, 726, 697, 42780, 42782, 42781, 42779, 760, 705, - 67508, 701, 67513, 702, 43883, 707, 734, 42890, 765, 7491, 7493, 7516, - 67459, 7495, 7601, 7509, 67461, 7517, 7580, 7590, 694, 7591, 67474, - 67476, 7595, 67484, 67491, 67456, 67460, 67478, 7600, 67498, 7608, 67506, - 67471, 67492, 7581, 7521, 7496, 67468, 67469, 67467, 67466, 7519, 7585, - 67480, 67463, 67465, 67464, 7611, 7613, 7612, 7497, 7604, 7582, 7614, - 7505, 7584, 67472, 7501, 7518, 7520, 67475, 736, 688, 689, 67477, 43868, - 67479, 7504, 7596, 7588, 7589, 690, 7592, 737, 43869, 43870, 7593, 67485, - 7594, 67483, 67481, 67482, 67486, 67487, 43001, 7599, 7598, 7506, 67490, - 7499, 7507, 7510, 7602, 691, 67497, 67496, 67473, 740, 7583, 67470, 738, - 67514, 7603, 7586, 7498, 7513, 7511, 7605, 67503, 67499, 67502, 7508, - 67500, 67501, 7492, 7579, 7494, 7514, 7597, 7500, 692, 67494, 67495, 693, - 67488, 67489, 7587, 7502, 7610, 43881, 7615, 7512, 43871, 7606, 7607, - 7515, 67504, 7609, 7503, 67493, 695, 739, 696, 42784, 42785, 67458, - 67457, 720, 699, 724, 708, 749, 42864, 748, 712, 747, 746, 10762, 128184, - 128176, 129297, 71266, 6165, 6164, 6167, 6166, 6163, 6162, 6160, 6169, - 6161, 6168, 6159, 6157, 6156, 6155, 6147, 6149, 71271, 71272, 6176, 6279, - 6272, 6295, 6273, 6289, 6274, 6313, 6286, 6311, 6310, 6280, 6276, 6275, - 6282, 6287, 6278, 6285, 6284, 6288, 6277, 6291, 6290, 6293, 6294, 6292, - 6283, 6281, 6185, 6196, 6264, 6210, 6190, 6303, 6305, 6307, 6300, 6302, - 6304, 6312, 6298, 6301, 6314, 6308, 6309, 6299, 6306, 6263, 6262, 6260, - 6261, 6259, 6244, 6252, 6245, 6253, 6254, 6248, 6238, 6239, 6257, 6247, - 6256, 6242, 6258, 6255, 6241, 6240, 6249, 6251, 6250, 6243, 6246, 6237, - 6193, 6192, 6297, 6296, 6218, 6236, 6225, 6234, 6227, 6235, 6211, 6222, - 6232, 6228, 6224, 6226, 6233, 6214, 6216, 6215, 6217, 6219, 6231, 6223, - 6220, 6221, 6230, 6229, 6212, 6213, 6204, 6194, 6209, 6207, 6205, 6206, - 6203, 6202, 6208, 6191, 6177, 6183, 6179, 6181, 6180, 6182, 6186, 6195, - 6201, 6189, 6197, 6184, 6187, 6188, 6199, 6200, 6198, 6178, 71273, 71275, - 71274, 6151, 71265, 71270, 71269, 6144, 71268, 71264, 71267, 71276, 6150, - 6158, 6148, 6146, 6152, 6153, 6154, 6145, 9866, 9867, 119552, 9101, - 128669, 128018, 128053, 127889, 129390, 118261, 128496, 129742, 129439, - 128332, 129334, 128741, 128757, 129468, 128739, 9968, 128670, 128672, - 128693, 128507, 128001, 129700, 128045, 128068, 128511, 127909, 92748, - 92744, 92761, 92750, 92739, 92751, 92737, 92754, 92749, 92753, 92743, - 92752, 92757, 92766, 92736, 92741, 92746, 92764, 92745, 92765, 92755, - 92756, 92763, 92762, 92747, 92760, 92758, 92738, 92740, 92759, 92742, - 92783, 92782, 92773, 92772, 92775, 92774, 92771, 92770, 92768, 92777, - 92769, 92776, 70291, 70292, 70290, 70297, 70296, 70293, 70287, 70298, - 70312, 70311, 70306, 70285, 70284, 70289, 70288, 70295, 70294, 70303, - 70301, 70283, 70282, 70280, 70278, 70277, 70276, 70300, 70299, 70310, - 70307, 70304, 70309, 70308, 70305, 70272, 70275, 70273, 70274, 70313, - 127926, 215, 10804, 10805, 10807, 10811, 10801, 10800, 10005, 8844, 8845, - 8846, 8888, 127812, 117860, 9838, 9839, 9837, 127929, 127896, 119161, - 119159, 119155, 119157, 119061, 119060, 119224, 119235, 119132, 119058, - 119059, 119255, 119253, 119130, 119131, 119163, 119169, 119149, 119167, - 119168, 119210, 119178, 119173, 119211, 119150, 119151, 119152, 119153, - 119154, 119175, 119212, 119213, 119166, 119164, 119141, 119142, 119176, - 119179, 119143, 119144, 119145, 119165, 119177, 119170, 119174, 119092, - 119052, 119247, 119186, 119073, 119109, 119093, 119050, 119220, 119221, - 119044, 119049, 119187, 119209, 119082, 119041, 119083, 119077, 119078, - 119162, 119160, 119208, 119156, 119158, 119136, 119102, 119056, 119057, - 119146, 119147, 119148, 119042, 119066, 119065, 119069, 119185, 119074, - 119075, 119076, 119231, 119232, 119085, 119084, 119070, 119071, 119072, - 119218, 119217, 119189, 119188, 119248, 119249, 119172, 119171, 119216, - 119134, 119100, 119206, 119262, 119270, 119271, 119263, 119268, 119269, - 119272, 119264, 119267, 119266, 119265, 119274, 119223, 119234, 119233, - 119046, 119222, 119184, 119227, 119237, 119228, 119122, 119123, 119081, - 119098, 119207, 119129, 119087, 119086, 119128, 119140, 119106, 119062, - 119195, 119204, 119205, 119196, 119197, 119198, 119199, 119200, 119201, - 119202, 119203, 119094, 119095, 119126, 119108, 119215, 119214, 119261, - 119252, 119257, 119258, 119183, 119090, 119091, 119135, 119101, 119096, - 119097, 119053, 119054, 119055, 119048, 119043, 119047, 119180, 119254, - 119259, 119225, 119236, 119226, 119229, 119238, 119230, 119051, 119045, - 119089, 119088, 119040, 119067, 119068, 119137, 119103, 119139, 119105, - 119110, 119111, 119250, 119181, 119273, 119243, 119244, 119245, 119246, - 119242, 119240, 119239, 119241, 119064, 119138, 119104, 119063, 119256, - 119260, 119190, 119118, 119119, 119120, 119121, 119112, 119113, 119116, - 119117, 119114, 119115, 119124, 119125, 119191, 119193, 119194, 119127, - 119251, 119107, 119133, 119099, 119219, 119192, 119182, 127932, 127925, - 8811, 8810, 4158, 4156, 4157, 4155, 4192, 4191, 4190, 4226, 4129, 43642, - 4138, 4135, 4208, 4207, 4206, 4159, 4099, 4098, 4097, 43625, 43624, - 43626, 43623, 43622, 43621, 43627, 43618, 43617, 43630, 43629, 43620, - 43619, 983244, 43631, 43616, 43635, 43628, 43633, 43634, 4096, 4188, - 4189, 4187, 4186, 4136, 4121, 4106, 4111, 4100, 4105, 4116, 4238, 4123, - 4176, 43491, 4218, 4220, 43490, 4221, 4224, 43492, 4223, 43489, 4216, - 43488, 4215, 4214, 4213, 4219, 4222, 4225, 4217, 4130, 43646, 43647, - 4193, 4177, 4126, 4112, 43503, 43495, 43502, 43501, 43516, 43515, 43518, - 43517, 43498, 43497, 43500, 43499, 43514, 43496, 4108, 4107, 4113, 4198, - 4197, 4125, 4110, 4109, 4115, 4114, 4133, 4134, 4178, 4179, 4180, 4181, - 4131, 4132, 4128, 4124, 4120, 4119, 4102, 4101, 4104, 4103, 4118, 4117, - 4127, 4122, 4137, 43636, 43637, 43638, 43632, 43494, 4245, 4244, 4247, - 4246, 4243, 4242, 4240, 4249, 4241, 4248, 4154, 4150, 4250, 4251, 4237, - 4235, 4236, 4231, 4232, 4233, 4234, 43493, 4171, 43644, 43645, 4201, - 4202, 4203, 4204, 4205, 4151, 4239, 43643, 4170, 4153, 4152, 43639, - 43641, 43640, 4174, 4172, 4255, 4254, 4175, 4173, 71391, 71390, 71393, - 71392, 71389, 71388, 71386, 71395, 71387, 71394, 4195, 4196, 43509, - 43508, 43511, 43510, 43507, 43506, 43504, 43513, 43505, 43512, 4146, - 4252, 4253, 4140, 4209, 4212, 4210, 4211, 4147, 4148, 4228, 4229, 4230, - 4227, 4194, 4145, 4149, 4199, 4200, 4139, 4143, 4144, 4182, 4183, 4184, - 4185, 4141, 4142, 71381, 71380, 71383, 71382, 71379, 71378, 71376, 71385, - 71377, 71384, 4165, 4164, 4167, 4166, 4163, 4162, 4160, 4169, 4161, 4168, - 983218, 983232, 983174, 10753, 10754, 10752, 8720, 10761, 10757, 10758, - 8721, 8899, 10756, 10755, 11007, 8896, 8897, 8898, 8719, 67712, 67728, - 67740, 67724, 67726, 67714, 67732, 67718, 67730, 67723, 67742, 67717, - 67729, 67738, 67739, 67713, 67735, 67716, 67721, 67734, 67737, 67741, - 67725, 67719, 67722, 67727, 67715, 67733, 67720, 67736, 67731, 67758, - 67752, 67753, 67757, 67751, 67759, 67756, 67754, 67755, 8711, 124117, - 124120, 124119, 124121, 124118, 124132, 124136, 124133, 124138, 124137, - 124134, 124135, 124122, 124124, 124126, 124123, 124125, 124112, 124116, - 124114, 124113, 124115, 124127, 124128, 124129, 124130, 124131, 124140, - 124143, 124142, 124139, 124141, 124149, 124148, 124151, 124150, 124147, - 124146, 124144, 124153, 124145, 124152, 128133, 8358, 8892, 72102, 72103, - 72138, 72096, 72097, 72107, 72109, 72123, 72122, 72128, 72127, 72144, - 72136, 72121, 72120, 72126, 72125, 72100, 72101, 72098, 72099, 72143, - 72137, 72114, 72124, 72119, 72129, 72139, 72140, 72141, 72133, 72132, - 72116, 72115, 72113, 72112, 72118, 72117, 72111, 72110, 72131, 72130, - 72142, 72134, 72135, 72106, 72108, 72162, 72161, 72158, 72160, 72159, - 72164, 72150, 72151, 72145, 72155, 72157, 72148, 72149, 72146, 72147, - 72154, 72156, 72163, 8302, 127966, 129314, 128219, 129535, 8239, 983092, - 983197, 983128, 9471, 9453, 9460, 9452, 9458, 9451, 9454, 9455, 9459, - 9456, 9457, 127312, 127313, 127314, 127315, 127316, 127317, 127318, - 127319, 127320, 127321, 127322, 127323, 127324, 127325, 127326, 127327, - 127328, 127329, 127330, 127331, 127332, 127333, 127334, 127335, 127336, - 127337, 128982, 128984, 129982, 129981, 129983, 127344, 127345, 127346, - 127347, 127348, 127349, 127350, 127351, 127352, 127353, 127354, 127355, - 127356, 127357, 127358, 127359, 127360, 127361, 127362, 127363, 127364, - 127365, 127366, 127367, 127368, 127369, 129204, 129205, 129207, 129988, - 10062, 127374, 127371, 127375, 129206, 127372, 127373, 983091, 8879, - 8840, 8841, 8775, 8821, 8817, 8825, 8820, 8816, 8824, 129670, 129722, - 11228, 129540, 129544, 129565, 129586, 129603, 129607, 129561, 129536, - 129557, 129599, 129539, 129560, 129602, 129610, 129613, 129541, 129562, - 129604, 129537, 129558, 129600, 129538, 129559, 129601, 129581, 129578, - 129582, 129583, 129579, 129580, 128528, 9906, 127770, 127761, 8362, 6595, - 6594, 6599, 6598, 6597, 6596, 6593, 6566, 6530, 6567, 6531, 6570, 6537, - 6532, 6544, 6543, 6536, 6542, 6549, 6548, 6562, 6561, 6554, 6560, 6556, - 6550, 6528, 6555, 6538, 6568, 6533, 6569, 6534, 6571, 6540, 6535, 6547, - 6546, 6539, 6545, 6552, 6551, 6565, 6564, 6557, 6563, 6559, 6553, 6529, - 6558, 6541, 6622, 6623, 6600, 6601, 6618, 6577, 6587, 6582, 6586, 6578, - 6592, 6583, 6584, 6590, 6589, 6579, 6585, 6591, 6580, 6588, 6576, 6581, - 6613, 6612, 6615, 6614, 6611, 6610, 6608, 6617, 6609, 6616, 983063, - 70732, 70746, 70731, 70741, 70740, 70743, 70742, 70739, 70738, 70736, - 70745, 70737, 70744, 70734, 70675, 70674, 70681, 70680, 70692, 70686, - 70691, 70751, 70662, 70663, 70664, 70665, 70656, 70657, 70667, 70669, - 70685, 70684, 70690, 70689, 70683, 70682, 70688, 70687, 70660, 70661, - 70658, 70659, 70705, 70706, 70707, 70696, 70695, 70677, 70676, 70673, - 70672, 70679, 70678, 70671, 70670, 70703, 70702, 70698, 70697, 70694, - 70693, 70701, 70700, 70708, 70704, 70699, 70666, 70668, 70723, 70726, - 70727, 70724, 70752, 70728, 70753, 70722, 70725, 70730, 70750, 70747, - 70709, 70719, 70721, 70712, 70713, 70714, 70715, 70716, 70717, 70710, - 70711, 70718, 70720, 70735, 70749, 70733, 70729, 11154, 11155, 128240, - 9112, 983131, 9798, 11209, 128084, 129299, 983132, 128985, 129399, - 127747, 2035, 2031, 2032, 2033, 2030, 2034, 2027, 2028, 2029, 2040, 2045, - 2046, 1989, 1988, 1991, 1990, 1987, 1986, 1984, 1993, 1985, 1992, 2042, - 2008, 2001, 2025, 2024, 2026, 2006, 2002, 2019, 2016, 2018, 2023, 2010, - 2009, 2000, 1999, 2007, 1997, 1995, 2012, 2003, 2013, 2020, 2014, 2015, - 2017, 2004, 2011, 2005, 2021, 2022, 1994, 1996, 1998, 2037, 2036, 2039, - 2038, 2041, 2047, 983127, 128691, 9940, 128683, 128695, 128370, 128286, - 128245, 128685, 8303, 65934, 8209, 128689, 10973, 8893, 8599, 10542, - 10545, 10536, 10532, 129209, 10530, 128602, 128594, 128610, 11111, 11127, - 11016, 8663, 129109, 11008, 43063, 43062, 43065, 43064, 43059, 43060, - 43057, 43056, 43061, 43058, 10529, 8598, 8689, 8632, 10546, 10535, 10531, - 129208, 128600, 128592, 128608, 11110, 11126, 11017, 8662, 129108, 11009, - 128746, 8882, 8884, 8379, 8836, 8837, 8713, 8772, 8777, 8938, 8940, 8742, - 8930, 8931, 172, 8877, 8769, 8813, 8800, 8802, 8815, 8814, 9083, 128323, - 10159, 128324, 10161, 128456, 128457, 128458, 128211, 128212, 128067, - 118012, 160, 9369, 9362, 9365, 9366, 9367, 35, 9368, 9364, 9361, 9363, - 9371, 9370, 8470, 110960, 110961, 110962, 110963, 110964, 110965, 110966, - 110967, 110968, 110969, 110970, 110971, 110972, 110973, 110974, 110975, - 110976, 110977, 110978, 110979, 110980, 110981, 110982, 110983, 110984, - 110985, 110986, 110987, 110988, 110989, 110990, 110991, 110992, 110993, - 110994, 110995, 110996, 110997, 110998, 110999, 111000, 111001, 111002, - 111003, 111004, 111005, 111006, 111007, 111008, 111009, 111010, 111011, - 111012, 111013, 111014, 111015, 111016, 111017, 111018, 111019, 111020, - 111021, 111022, 111023, 111024, 111025, 111026, 111027, 111028, 111029, - 111030, 111031, 111032, 111033, 111034, 111035, 111036, 111037, 111038, - 111039, 111040, 111041, 111042, 111043, 111044, 111045, 111046, 111047, - 111048, 111049, 111050, 111051, 111052, 111053, 111054, 111055, 111056, - 111057, 111058, 111059, 111060, 111061, 111062, 111063, 111064, 111065, - 111066, 111067, 111068, 111069, 111070, 111071, 111072, 111073, 111074, - 111075, 111076, 111077, 111078, 111079, 111080, 111081, 111082, 111083, - 111084, 111085, 111086, 111087, 111088, 111089, 111090, 111091, 111092, - 111093, 111094, 111095, 111096, 111097, 111098, 111099, 111100, 111101, - 111102, 111103, 111104, 111105, 111106, 111107, 111108, 111109, 111110, - 111111, 111112, 111113, 111114, 111115, 111116, 111117, 111118, 111119, - 111120, 111121, 111122, 111123, 111124, 111125, 111126, 111127, 111128, - 111129, 111130, 111131, 111132, 111133, 111134, 111135, 111136, 111137, - 111138, 111139, 111140, 111141, 111142, 111143, 111144, 111145, 111146, - 111147, 111148, 111149, 111150, 111151, 111152, 111153, 111154, 111155, - 111156, 111157, 111158, 111159, 111160, 111161, 111162, 111163, 111164, - 111165, 111166, 111167, 111168, 111169, 111170, 111171, 111172, 111173, - 111174, 111175, 111176, 111177, 111178, 111179, 111180, 111181, 111182, - 111183, 111184, 111185, 111186, 111187, 111188, 111189, 111190, 111191, - 111192, 111193, 111194, 111195, 111196, 111197, 111198, 111199, 111200, - 111201, 111202, 111203, 111204, 111205, 111206, 111207, 111208, 111209, - 111210, 111211, 111212, 111213, 111214, 111215, 111216, 111217, 111218, - 111219, 111220, 111221, 111222, 111223, 111224, 111225, 111226, 111227, - 111228, 111229, 111230, 111231, 111232, 111233, 111234, 111235, 111236, - 111237, 111238, 111239, 111240, 111241, 111242, 111243, 111244, 111245, - 111246, 111247, 111248, 111249, 111250, 111251, 111252, 111253, 111254, - 111255, 111256, 111257, 111258, 111259, 111260, 111261, 111262, 111263, - 111264, 111265, 111266, 111267, 111268, 111269, 111270, 111271, 111272, - 111273, 111274, 111275, 111276, 111277, 111278, 111279, 111280, 111281, - 111282, 111283, 111284, 111285, 111286, 111287, 111288, 111289, 111290, - 111291, 111292, 111293, 111294, 111295, 111296, 111297, 111298, 111299, - 111300, 111301, 111302, 111303, 111304, 111305, 111306, 111307, 111308, - 111309, 111310, 111311, 111312, 111313, 111314, 111315, 111316, 111317, - 111318, 111319, 111320, 111321, 111322, 111323, 111324, 111325, 111326, - 111327, 111328, 111329, 111330, 111331, 111332, 111333, 111334, 111335, - 111336, 111337, 111338, 111339, 111340, 111341, 111342, 111343, 111344, - 111345, 111346, 111347, 111348, 111349, 111350, 111351, 111352, 111353, - 111354, 111355, 94177, 128297, 983041, 983040, 123149, 123155, 123138, - 123166, 123164, 123148, 123143, 123161, 123153, 123152, 123141, 123137, - 123156, 123139, 123163, 123142, 123172, 123173, 123140, 123167, 123171, - 123158, 123176, 123177, 123165, 123151, 123168, 123136, 123169, 123162, - 123178, 123179, 123144, 123157, 123170, 123150, 123145, 123159, 123146, - 123154, 123160, 123147, 123174, 123175, 123180, 123214, 123193, 123192, - 123195, 123194, 123191, 123196, 123197, 123184, 123190, 123189, 123186, - 123185, 123188, 123187, 123215, 123205, 123204, 123207, 123206, 123203, - 123202, 123200, 123209, 123201, 123208, 117776, 983231, 983066, 10663, - 10662, 11869, 9215, 65532, 9287, 9286, 9284, 9285, 9289, 9281, 9290, - 9288, 9282, 9283, 9280, 128721, 128025, 128885, 5787, 5788, 5776, 5761, - 5786, 5770, 5769, 5781, 5779, 5785, 5763, 5772, 5780, 5784, 5762, 5775, - 5773, 5765, 5777, 5782, 5764, 5774, 5783, 5766, 5778, 5771, 5767, 5768, - 5760, 731, 128738, 7265, 7264, 7266, 7267, 7261, 7260, 7262, 7259, 7280, - 7282, 7281, 7279, 7271, 7270, 7272, 7269, 7258, 7263, 7278, 7268, 7283, - 7273, 7284, 7285, 7287, 7286, 7276, 7274, 7275, 7277, 7290, 7288, 7289, - 7295, 7294, 7292, 7291, 7253, 7252, 7255, 7254, 7251, 7250, 7248, 7257, - 7249, 7256, 7293, 124374, 124376, 124375, 124377, 124378, 124379, 124392, - 124396, 124395, 124397, 124394, 124393, 124380, 124381, 124383, 124384, - 124385, 124382, 124368, 124371, 124370, 124369, 124372, 124373, 124386, - 124388, 124390, 124389, 124387, 124391, 124399, 124400, 124398, 124415, - 124406, 124405, 124408, 124407, 124404, 124403, 124401, 124410, 124402, - 124409, 94179, 94178, 68736, 68739, 68744, 68737, 68756, 68745, 68760, - 68769, 68761, 68775, 68785, 68741, 68762, 68772, 68773, 68740, 68777, - 68742, 68749, 68750, 68758, 68759, 68774, 68776, 68783, 68784, 68738, - 68743, 68747, 68748, 68751, 68754, 68755, 68768, 68770, 68782, 68765, - 68780, 68766, 68781, 68763, 68767, 68764, 68771, 68778, 68757, 68786, - 68779, 68746, 68752, 68753, 68800, 68803, 68808, 68801, 68820, 68809, - 68824, 68833, 68825, 68839, 68849, 68805, 68826, 68836, 68837, 68804, - 68841, 68806, 68813, 68814, 68822, 68823, 68838, 68840, 68847, 68848, - 68802, 68807, 68811, 68812, 68815, 68818, 68819, 68832, 68834, 68846, - 68829, 68844, 68830, 68845, 68827, 68831, 68828, 68835, 68842, 68821, - 68850, 68843, 68810, 68816, 68817, 68861, 68859, 68858, 68862, 68863, - 68860, 66308, 66324, 66318, 66335, 66323, 66331, 66327, 66330, 66315, - 66316, 66317, 66329, 66314, 66306, 66322, 66351, 66321, 66350, 66326, - 66334, 66313, 66333, 66328, 66320, 66312, 66325, 66332, 66305, 66307, - 66311, 66309, 66349, 66310, 66304, 66319, 66339, 66337, 66338, 66336, - 68241, 68242, 68246, 68244, 68226, 68224, 68237, 68235, 68249, 68251, - 68247, 68233, 68248, 68252, 68227, 68234, 68230, 68239, 68232, 68240, - 68231, 68250, 68236, 68225, 68243, 68245, 68228, 68229, 68238, 68255, - 68254, 68253, 66404, 66390, 66392, 66387, 66388, 66411, 66393, 66421, - 66418, 66396, 66397, 66399, 66406, 66405, 66401, 66413, 66402, 66398, - 66414, 66415, 66416, 66408, 66420, 66417, 66407, 66419, 66389, 66391, - 66395, 66400, 66386, 66409, 66410, 66385, 66384, 66394, 66412, 66403, - 66516, 66514, 66515, 66517, 66513, 66464, 66504, 66505, 66506, 66482, - 66510, 66511, 66477, 66508, 66509, 66478, 66479, 66473, 66474, 66490, - 66491, 66480, 66475, 66476, 66507, 66471, 66469, 66470, 66467, 66468, - 66484, 66485, 66492, 66493, 66486, 66487, 66488, 66497, 66498, 66495, - 66472, 66483, 66499, 66494, 66481, 66489, 66496, 66465, 66466, 66512, - 128435, 118450, 69414, 69395, 69376, 69394, 69391, 69392, 69398, 69399, - 69403, 69404, 69377, 69379, 69382, 69400, 69388, 69380, 69384, 69393, - 69397, 69401, 69386, 69381, 69385, 69387, 69378, 69390, 69402, 69383, - 69396, 69389, 69415, 69407, 69412, 69411, 69406, 69410, 69405, 69413, - 69409, 69408, 68209, 68210, 68217, 68211, 68213, 68214, 68212, 68203, - 68205, 68207, 68206, 68202, 68198, 68220, 68219, 68215, 68201, 68216, - 68193, 68196, 68199, 68218, 68192, 68194, 68200, 68204, 68197, 68208, - 68195, 68222, 68221, 68223, 68608, 68619, 68627, 68623, 68634, 68640, - 68644, 68668, 68670, 68677, 68632, 68669, 68671, 68617, 68625, 68621, - 68638, 68643, 68660, 68666, 68675, 68630, 68648, 68653, 68646, 68650, - 68641, 68673, 68658, 68642, 68655, 68628, 68611, 68657, 68662, 68614, - 68615, 68636, 68656, 68664, 68679, 68680, 68609, 68610, 68645, 68654, - 68620, 68624, 68635, 68678, 68633, 68672, 68652, 68618, 68626, 68622, - 68639, 68661, 68667, 68676, 68631, 68613, 68649, 68647, 68651, 68674, - 68659, 68629, 68612, 68663, 68616, 68637, 68665, 69509, 69508, 69507, - 69506, 69488, 69502, 69496, 69505, 69492, 69499, 69501, 69503, 69494, - 69493, 69490, 69495, 69489, 69498, 69504, 69491, 69500, 69497, 69511, - 69512, 69513, 69510, 128477, 128117, 129491, 128116, 129746, 128283, - 128664, 128753, 128662, 128660, 128653, 11819, 8228, 128431, 129649, - 129477, 128214, 9251, 10044, 10027, 10034, 10011, 128194, 128449, 128080, - 128237, 128236, 10180, 10179, 128275, 9103, 9104, 10174, 983191, 8997, - 128191, 128440, 9934, 9741, 128217, 129505, 129447, 128895, 129741, 8886, - 2902, 2903, 2933, 2934, 2931, 2930, 2935, 2932, 2928, 2909, 2908, 2864, - 2911, 2863, 2821, 2822, 2832, 2836, 2850, 2849, 2855, 2854, 2848, 2847, - 2853, 2852, 2827, 2912, 2828, 2913, 2869, 2825, 2826, 2823, 2824, 2867, - 2866, 2841, 2851, 2846, 2856, 2870, 2871, 2872, 2861, 2860, 2843, 2842, - 2840, 2839, 2845, 2844, 2838, 2837, 2859, 2858, 2873, 2862, 2929, 2831, - 2835, 983660, 983659, 2817, 2876, 2877, 2818, 2901, 2893, 2819, 2878, - 2888, 2892, 2881, 2882, 2883, 2884, 2914, 2915, 2879, 2880, 2887, 2891, - 2923, 2922, 2925, 2924, 2921, 2920, 2918, 2927, 2919, 2926, 64830, 64831, - 9766, 117826, 10183, 66736, 66737, 66738, 66739, 66743, 66763, 66761, - 66742, 66749, 66757, 66744, 66768, 66750, 66748, 66754, 66755, 66764, - 66762, 66760, 66746, 66745, 66741, 66765, 66769, 66759, 66758, 66771, - 66770, 66740, 66751, 66752, 66753, 66756, 66767, 66747, 66766, 66776, - 66777, 66778, 66779, 66783, 66803, 66801, 66782, 66789, 66797, 66784, - 66808, 66790, 66788, 66794, 66795, 66804, 66802, 66800, 66786, 66785, - 66781, 66805, 66809, 66799, 66798, 66811, 66810, 66780, 66791, 66792, - 66793, 66796, 66807, 66787, 66806, 66710, 66688, 66715, 66699, 66694, - 66698, 66703, 66693, 66697, 66696, 66705, 66702, 66713, 66717, 66704, - 66706, 66707, 66711, 66716, 66689, 66701, 66700, 66708, 66691, 66695, - 66690, 66692, 66709, 66712, 66714, 66725, 66724, 66727, 66726, 66723, - 66722, 66720, 66729, 66721, 66728, 983192, 126257, 126264, 126258, - 126259, 126265, 126260, 126263, 126267, 126255, 126266, 126256, 126262, - 126261, 126269, 126268, 126254, 126216, 126225, 126252, 126234, 126243, - 126222, 126249, 126213, 126231, 126240, 126221, 126248, 126212, 126230, - 126239, 126217, 126226, 126253, 126235, 126244, 126215, 126224, 126251, - 126233, 126242, 126214, 126223, 126250, 126232, 126241, 126220, 126247, - 126211, 126229, 126238, 126219, 126246, 126210, 126228, 126237, 126218, - 126245, 126209, 126227, 126236, 129446, 128228, 117974, 117975, 117976, - 117977, 117978, 117979, 117980, 117981, 117982, 117983, 117984, 117985, - 117986, 117987, 117988, 117989, 117990, 117991, 117992, 117993, 117994, - 117995, 117996, 117997, 117998, 117999, 10015, 9885, 10029, 10009, - 118005, 118004, 118007, 118006, 118003, 118002, 118000, 118009, 118001, - 118008, 8485, 129397, 128471, 11195, 11194, 11196, 8254, 129450, 127970, - 118459, 8486, 128076, 127842, 128329, 129417, 128002, 983122, 983121, - 128463, 128195, 128479, 128196, 128223, 128464, 128724, 93059, 93065, - 93064, 93058, 93070, 93056, 93055, 93053, 93062, 93069, 93061, 93066, - 93071, 93068, 93054, 93057, 93063, 93067, 93060, 92967, 92975, 92965, - 92969, 92959, 92968, 92971, 92957, 92962, 92960, 92972, 92970, 92963, - 92958, 92966, 92961, 92956, 92974, 92964, 92973, 92979, 92978, 92980, - 92977, 92976, 92982, 92981, 93023, 93020, 93024, 93021, 93019, 93025, - 93022, 93043, 92985, 93047, 93044, 93045, 92997, 93046, 93042, 93032, - 93029, 92995, 93038, 92993, 93041, 93035, 93033, 93037, 93030, 93039, - 92987, 92992, 92986, 92983, 92984, 93027, 92994, 93034, 92988, 92990, - 92989, 92991, 93028, 92996, 93031, 93040, 93036, 92954, 92955, 92938, - 92939, 92932, 92933, 92942, 92943, 92950, 92951, 92928, 92929, 92936, - 92937, 92948, 92949, 92930, 92931, 92944, 92945, 92934, 92935, 92940, - 92941, 92946, 92947, 92952, 92953, 93013, 93012, 93015, 93014, 93011, - 93010, 93008, 93017, 93009, 93016, 9908, 11801, 127796, 129779, 129780, - 67703, 67693, 67688, 67702, 67683, 67691, 67699, 67700, 67680, 67696, - 67682, 67686, 67695, 67698, 67701, 67689, 67684, 67687, 67690, 67681, - 67694, 67685, 67697, 67692, 67704, 67711, 67706, 67707, 67710, 67709, - 67708, 67705, 129330, 129374, 128060, 8233, 11853, 11791, 10995, 10994, - 8741, 129666, 12809, 12823, 12808, 12822, 12828, 12813, 12827, 12810, - 12824, 12800, 12814, 12804, 12818, 12801, 12815, 12812, 12826, 12805, - 12819, 12803, 12817, 12806, 12820, 12811, 12825, 12802, 12816, 12807, - 12821, 12863, 12855, 12858, 12861, 12847, 12839, 12854, 12843, 12836, - 12864, 12835, 12856, 12846, 12842, 12840, 12852, 12862, 12865, 12857, - 12867, 12838, 12866, 12851, 12853, 12859, 12849, 12860, 12848, 12837, - 12834, 12841, 12833, 12845, 12844, 12850, 12832, 12830, 12829, 9349, - 9342, 9345, 9346, 9350, 9347, 9348, 9344, 9351, 9343, 9341, 9336, 9335, - 9338, 9337, 9334, 9333, 9340, 9332, 9339, 127248, 127249, 127250, 127251, - 127252, 127253, 127254, 127255, 127256, 127257, 127258, 127259, 127260, - 127261, 127262, 127263, 127264, 127265, 127266, 127267, 127268, 127269, - 127270, 127271, 127272, 127273, 9372, 9373, 9374, 9375, 9376, 9377, 9378, - 9379, 9380, 9381, 9382, 9383, 9384, 9385, 9386, 9387, 9388, 9389, 9390, - 9391, 9392, 9393, 9394, 9395, 9396, 9397, 8706, 983147, 983146, 983149, - 983150, 9853, 127881, 118468, 128890, 12880, 12349, 129436, 128755, - 11261, 9105, 9106, 128706, 72437, 72440, 72432, 72416, 72419, 72413, - 72417, 72415, 72412, 72414, 72418, 72420, 72403, 72407, 72411, 72409, - 72410, 72391, 72400, 72404, 72397, 72394, 72385, 72401, 72384, 72399, - 72398, 72396, 72388, 72393, 72392, 72386, 72387, 72402, 72395, 72390, - 72389, 72405, 72406, 72408, 72436, 72435, 72438, 72439, 72422, 72421, - 72424, 72425, 72431, 72433, 72434, 72428, 72427, 72429, 72430, 72423, - 72426, 128062, 128230, 128206, 983228, 983237, 129434, 9774, 127825, - 129372, 129755, 127824, 128039, 128532, 9956, 128390, 9999, 8240, 8241, - 8524, 10178, 10977, 129336, 129496, 129494, 128113, 9977, 128590, 129733, - 128591, 129493, 128589, 128588, 129495, 128583, 128187, 8966, 128547, 37, - 9854, 127917, 8359, 8369, 129515, 128694, 129730, 43101, 43117, 43120, - 43076, 43123, 43077, 43115, 43090, 43082, 43094, 43098, 43099, 43119, - 43118, 43109, 43074, 43075, 43116, 43079, 43083, 43089, 43088, 43114, - 43113, 43081, 43080, 43073, 43072, 43085, 43084, 43092, 43093, 43104, - 43110, 43086, 43108, 43100, 43078, 43097, 43087, 43106, 43096, 43091, - 43107, 43095, 43102, 43105, 43103, 43127, 43126, 43124, 43121, 43111, - 43112, 43122, 43125, 66033, 66023, 66017, 66010, 66027, 66003, 66018, - 66028, 66004, 66012, 66022, 66020, 66045, 66019, 66031, 66041, 66007, - 66006, 66025, 66026, 66038, 66016, 66013, 66014, 66000, 66001, 66034, - 66036, 66037, 66029, 66011, 66024, 66015, 66021, 66042, 66043, 66002, - 66008, 66032, 66005, 66044, 66040, 66039, 66030, 66009, 66035, 5941, - 5942, 67840, 67855, 67843, 67844, 67847, 67858, 67857, 67860, 67854, - 67861, 67848, 67845, 67846, 67849, 67859, 67842, 67850, 67853, 67851, - 67841, 67856, 67852, 67864, 67866, 67867, 67863, 67862, 67865, 67871, - 11227, 9935, 128763, 128022, 128061, 128055, 128169, 182, 128138, 129292, - 129295, 127885, 127821, 10031, 129655, 129669, 9811, 128299, 8916, 10970, - 129383, 8984, 128720, 129703, 8462, 8463, 128733, 127183, 127136, 127167, - 127199, 127188, 127140, 127156, 127172, 127200, 127189, 127141, 127157, - 127173, 127196, 127148, 127164, 127180, 127198, 127150, 127166, 127182, - 127192, 127144, 127160, 127176, 127191, 127143, 127159, 127175, 127190, - 127142, 127158, 127174, 127197, 127149, 127165, 127181, 127194, 127146, - 127162, 127178, 127187, 127139, 127155, 127171, 127186, 127138, 127154, - 127170, 127202, 127220, 127221, 127201, 127210, 127211, 127212, 127213, - 127214, 127215, 127216, 127217, 127218, 127219, 127203, 127204, 127205, - 127206, 127207, 127208, 127209, 127185, 127137, 127153, 127169, 127193, - 127145, 127161, 127177, 127195, 127147, 127163, 127179, 983151, 43, - 10797, 10798, 10809, 10789, 10786, 10791, 10790, 10788, 10792, 10787, - 10866, 177, 9799, 11222, 11221, 11220, 11219, 129696, 983148, 117777, - 128659, 128680, 128110, 8297, 8236, 127871, 128254, 11239, 128239, 12306, - 12320, 128238, 8982, 128688, 129364, 127858, 129716, 127831, 129751, - 128574, 128545, 163, 128093, 9212, 9213, 9214, 9211, 128041, 128425, - 129328, 129732, 129731, 65043, 65040, 65045, 65073, 65074, 65049, 65041, - 65042, 65091, 65047, 65083, 65085, 65089, 65079, 65087, 65077, 65095, - 65081, 65075, 65084, 65086, 65092, 983261, 65048, 65090, 65080, 65088, - 65078, 65096, 65082, 65076, 65044, 65072, 65046, 8478, 8826, 10937, - 10933, 10927, 10929, 10935, 10931, 8936, 8830, 8828, 8880, 9111, 129384, - 9113, 128424, 128438, 129332, 128120, 983193, 983166, 983163, 983164, - 983167, 8242, 8965, 8759, 8733, 8522, 11224, 128711, 129455, 128255, - 68507, 68508, 68480, 68483, 68490, 68491, 68485, 68482, 68486, 68493, - 68495, 68496, 68488, 68484, 68487, 68489, 68481, 68492, 68497, 68494, - 68526, 68522, 68523, 68525, 68521, 68527, 68524, 68505, 68506, 118473, - 11854, 8200, 128156, 128091, 128686, 128204, 128226, 983165, 983168, - 983194, 9624, 9625, 9626, 9627, 9628, 9629, 9630, 9631, 9622, 9623, - 10764, 8279, 10774, 9833, 128894, 8264, 63, 8799, 34, 9915, 127949, - 127950, 129437, 128251, 9762, 128280, 9143, 128740, 128643, 9926, 127752, - 11827, 11783, 11782, 9995, 128400, 128406, 127338, 127339, 127340, - 129996, 11787, 9994, 11828, 129306, 128000, 8758, 128007, 128048, 129682, - 128015, 129534, 117778, 9852, 9843, 9844, 9845, 9846, 9847, 9848, 9849, - 9850, 983113, 128665, 127822, 129511, 174, 127462, 127463, 127464, + 68159, 68168, 129711, 983960, 983965, 983970, 983975, 983962, 983964, + 983961, 983963, 983957, 983959, 983956, 983958, 983977, 983979, 983978, + 983972, 983974, 983967, 983969, 983971, 983973, 983966, 983968, 983989, + 983983, 983985, 983986, 983987, 983980, 983982, 983984, 983981, 983976, + 983988, 6107, 6052, 6064, 6051, 6067, 6066, 6065, 6055, 6057, 6058, 6056, + 6053, 6054, 6063, 983994, 983991, 983992, 983993, 6061, 6062, 6059, 6060, + 6022, 6024, 6021, 6023, 6017, 6019, 6016, 6018, 6020, 6030, 6025, 6035, + 6037, 6039, 6038, 6046, 6045, 6047, 6032, 6034, 6027, 6029, 6031, 6033, + 6026, 6028, 6049, 6043, 6040, 6042, 6044, 6041, 6036, 6048, 6050, 6108, + 6109, 6095, 6096, 6099, 6091, 6101, 6104, 6102, 6098, 6094, 6100, 6106, + 6092, 6087, 6090, 6093, 6103, 6105, 6088, 6086, 6089, 6097, 6652, 6636, + 6655, 6639, 6653, 6637, 6654, 6638, 6651, 6635, 6650, 6634, 6133, 6137, + 6136, 6134, 6135, 6130, 6132, 6131, 6129, 6128, 6624, 6648, 6632, 6649, + 6633, 6647, 6631, 6646, 6630, 6645, 6629, 6642, 6626, 6640, 6643, 6627, + 6644, 6628, 6641, 6625, 6069, 6068, 6070, 983996, 6082, 6083, 6085, 6071, + 6080, 6072, 6078, 983995, 6084, 6073, 6079, 6074, 983990, 6075, 6077, + 6076, 6081, 6117, 6116, 6119, 6118, 6115, 6114, 6112, 6121, 6113, 6120, + 70204, 70201, 70200, 70208, 70185, 70178, 70179, 70177, 70155, 70156, + 70154, 70172, 70167, 70166, 70173, 70171, 70161, 70160, 70144, 70145, + 70149, 70151, 70165, 70164, 70170, 70169, 70187, 70183, 70157, 70168, + 70163, 70174, 70159, 70158, 70153, 70152, 70176, 70175, 70186, 70180, + 70207, 70182, 70184, 70181, 70148, 70146, 70150, 70147, 70199, 70206, + 70198, 70197, 70196, 70203, 70209, 70188, 70193, 70195, 70189, 70190, + 70192, 70194, 70191, 70202, 70205, 70357, 70358, 70356, 70333, 70334, + 70332, 70345, 70347, 70344, 70352, 70351, 70340, 70339, 70338, 70320, + 70321, 70327, 70329, 70346, 70361, 70343, 70342, 70350, 70349, 70324, + 70325, 70322, 70323, 70335, 70348, 70341, 70353, 70337, 70336, 70331, + 70330, 70355, 70354, 70364, 70365, 70366, 70362, 70359, 70363, 70360, + 70326, 70328, 70377, 70378, 70367, 70368, 70374, 70376, 70371, 70372, + 70369, 70370, 70373, 70375, 70389, 70388, 70391, 70390, 70387, 70386, + 70384, 70393, 70385, 70392, 94180, 93521, 93520, 93525, 93524, 93519, + 93518, 93523, 93522, 93512, 93517, 93526, 93530, 93529, 93514, 93513, + 93511, 93510, 93516, 93515, 93509, 93508, 93528, 93527, 93537, 93536, + 93538, 93534, 93531, 93533, 93535, 93532, 93507, 93505, 93549, 93548, + 93504, 93547, 93506, 93539, 93544, 93546, 93541, 93542, 93543, 93540, + 93545, 93551, 93550, 93557, 93556, 93559, 93558, 93555, 93554, 93552, + 93561, 93553, 93560, 128143, 128535, 128537, 128538, 128573, 128139, + 129373, 8365, 128088, 129665, 129486, 129698, 12927, 128040, 11235, + 129404, 127991, 129357, 128030, 129692, 128728, 917505, 3805, 3804, + 983206, 983207, 3743, 3741, 3807, 3806, 3714, 3716, 3713, 983209, 3747, + 3749, 3730, 3729, 3736, 3728, 3727, 3731, 3726, 3744, 3721, 3718, 3724, + 3756, 3740, 3742, 3739, 3752, 3753, 3754, 3722, 3734, 3735, 3733, 3755, + 3758, 3719, 3725, 3737, 3738, 3720, 3732, 3745, 983208, 3751, 3746, 3757, + 3773, 3772, 3770, 3785, 3786, 3787, 3784, 3760, 3762, 3780, 3763, 3779, + 3761, 3771, 3766, 3767, 3768, 3769, 3776, 3777, 3764, 3765, 3778, 3782, + 3790, 3759, 3797, 3796, 3799, 3798, 3795, 3794, 3792, 3801, 3793, 3800, + 3788, 3789, 128996, 129003, 128309, 128311, 128998, 128994, 129001, + 68413, 68415, 128992, 128310, 128999, 68412, 68414, 118324, 118319, + 118322, 118323, 118303, 118304, 118336, 118331, 118328, 118315, 118314, + 118306, 118316, 118318, 118334, 118335, 118333, 118327, 118339, 118341, + 118342, 118340, 118320, 118338, 118332, 118302, 118325, 118309, 118317, + 118307, 118313, 118326, 118329, 118312, 118330, 118352, 118348, 118351, + 118350, 118347, 118344, 118345, 118343, 118349, 118346, 118305, 118321, + 118301, 118299, 118298, 118310, 118311, 118308, 118300, 118337, 11004, + 10201, 10200, 10782, 128995, 129002, 128308, 128997, 128993, 129000, + 9711, 10923, 10925, 8382, 9790, 127772, 127767, 65, 258, 7858, 7856, + 7854, 7862, 7860, 550, 480, 7840, 512, 196, 478, 197, 506, 7680, 256, + 983564, 194, 7848, 7846, 7844, 7852, 7850, 461, 7842, 260, 983590, + 983592, 192, 193, 514, 195, 570, 198, 508, 482, 42946, 393, 11373, 42808, + 42810, 42802, 42804, 42806, 42812, 66, 386, 42902, 7686, 7684, 7682, 385, + 579, 42822, 42932, 67, 199, 7688, 264, 268, 262, 42948, 391, 42898, 266, + 571, 42960, 42796, 42798, 42862, 42931, 68, 498, 453, 42951, 272, 7696, + 7698, 270, 395, 7694, 7692, 7690, 394, 497, 452, 42964, 42962, 69, 552, + 7708, 202, 983586, 7874, 7872, 7870, 983584, 7878, 7876, 7704, 282, 278, + 983598, 983600, 7864, 516, 203, 7868, 7706, 274, 7700, 7702, 983570, + 983572, 983574, 7866, 280, 983594, 983596, 200, 201, 518, 276, 582, 439, + 494, 440, 42786, 42788, 42858, 208, 425, 330, 70, 401, 7710, 42904, 71, + 290, 284, 486, 500, 286, 7712, 42912, 403, 288, 484, 577, 42938, 42940, + 42942, 404, 983199, 72, 7722, 7720, 292, 542, 7718, 11367, 7716, 7714, + 42922, 294, 11381, 502, 42790, 73, 520, 7882, 304, 207, 7726, 206, 463, + 298, 983566, 296, 7724, 7880, 302, 983604, 983606, 204, 205, 522, 300, + 407, 42873, 42875, 42877, 42882, 42884, 42886, 406, 42860, 74, 308, + 42930, 983608, 584, 75, 310, 488, 42818, 11369, 7730, 42816, 42820, 7728, + 7732, 42914, 408, 76, 42925, 573, 11360, 7734, 7736, 11362, 319, 456, + 321, 315, 7740, 317, 42824, 313, 7738, 983610, 42970, 42972, 455, 77, + 7742, 7746, 7744, 983612, 11374, 7930, 7932, 42966, 78, 325, 7754, 327, + 459, 544, 7752, 413, 504, 323, 42896, 7750, 7748, 42916, 209, 458, 79, + 42826, 42828, 332, 7760, 7762, 415, 212, 7892, 7890, 7888, 7896, 7894, + 465, 214, 554, 558, 560, 7884, 524, 336, 490, 492, 216, 510, 213, 7758, + 7756, 556, 983576, 983578, 983580, 416, 7902, 7900, 7898, 7906, 7904, + 7886, 210, 211, 526, 334, 42944, 400, 390, 42934, 418, 42830, 546, 80, + 42834, 11363, 42832, 42836, 7764, 420, 7766, 42958, 81, 42840, 42838, 82, + 342, 344, 7770, 7772, 7768, 528, 983614, 11364, 340, 7774, 530, 42918, + 588, 42842, 42997, 42923, 42814, 398, 42844, 42955, 83, 352, 7782, 350, + 536, 348, 346, 7780, 7778, 7784, 7776, 42956, 42953, 11390, 983582, + 42920, 42949, 586, 42926, 42891, 7838, 42968, 42924, 399, 84, 354, 7792, + 538, 356, 574, 7788, 7786, 7790, 430, 428, 358, 42878, 11375, 11376, + 42893, 42928, 42880, 412, 42929, 581, 222, 42852, 42854, 388, 444, 423, + 42794, 42792, 85, 219, 7798, 467, 220, 473, 475, 471, 469, 7794, 532, + 368, 7908, 431, 7916, 7914, 7912, 7920, 7918, 7910, 362, 7802, 983568, + 983620, 983622, 370, 983616, 983618, 360, 7800, 7796, 217, 218, 534, 364, + 366, 42936, 580, 433, 86, 42846, 7806, 7804, 434, 42850, 42906, 42908, + 42910, 42856, 42848, 87, 372, 7812, 7816, 7814, 7808, 7810, 11378, 503, + 88, 7820, 7818, 89, 374, 376, 7924, 7822, 7922, 435, 7926, 7934, 221, + 562, 7928, 590, 540, 90, 7824, 381, 377, 11371, 7826, 379, 7828, 11391, + 437, 42950, 548, 306, 338, 10013, 43007, 43005, 43006, 43003, 43004, + 42999, 450, 7461, 684, 664, 685, 662, 122638, 446, 661, 426, 674, 451, + 122634, 7431, 7430, 7459, 618, 641, 671, 122628, 7436, 7439, 7440, 630, + 7445, 640, 7438, 7449, 43846, 42870, 7451, 11387, 122626, 122640, 43002, + 7450, 665, 7427, 610, 667, 7424, 7425, 7428, 7429, 42800, 668, 7434, + 7435, 7437, 628, 7448, 42927, 42801, 7452, 7456, 7457, 655, 7458, 663, + 122639, 42895, 443, 447, 448, 449, 660, 673, 7460, 422, 7547, 7550, 97, + 259, 7859, 7857, 7855, 7863, 7861, 551, 481, 7841, 513, 228, 479, 229, + 507, 7681, 7834, 7567, 257, 983565, 226, 7849, 7847, 7845, 7853, 7851, + 462, 7843, 261, 983591, 983593, 224, 225, 515, 227, 11365, 43825, 230, + 983624, 509, 483, 42947, 593, 7568, 42809, 42811, 42803, 42805, 42807, + 42813, 98, 387, 42903, 7687, 7532, 7552, 7685, 7683, 595, 384, 43824, + 43827, 629, 43853, 43837, 43838, 43826, 42823, 7447, 42933, 99, 231, + 7689, 265, 597, 269, 263, 42900, 122653, 392, 42899, 267, 572, 43859, + 43860, 43861, 42961, 666, 631, 606, 42797, 42799, 42863, 100, 42952, 273, + 396, 598, 7697, 7699, 545, 271, 122661, 7533, 7695, 599, 7569, 7553, + 7693, 7691, 676, 122642, 122649, 7839, 567, 607, 644, 305, 42965, 43848, + 43850, 42963, 499, 454, 675, 677, 43878, 568, 42865, 101, 553, 7709, 234, + 983587, 7875, 7873, 7871, 983585, 7879, 7877, 7705, 283, 279, 983599, + 983601, 7865, 517, 235, 11384, 7869, 7707, 275, 7701, 7703, 983571, + 983573, 983575, 43828, 7867, 281, 983595, 983597, 232, 233, 519, 277, + 7570, 583, 42787, 42789, 331, 43836, 122644, 643, 122635, 122636, 7563, + 646, 7576, 658, 441, 659, 495, 122648, 7578, 442, 42859, 240, 102, 7534, + 7554, 402, 7711, 42905, 681, 122624, 103, 291, 285, 487, 501, 287, 7713, + 7555, 42913, 608, 289, 485, 578, 42939, 42941, 42943, 611, 983200, 104, + 7723, 7721, 293, 543, 7719, 11368, 7717, 7715, 7830, 42901, 614, 295, + 11382, 983631, 983632, 42791, 615, 405, 105, 238, 464, 239, 7727, 983602, + 983588, 983603, 7883, 521, 299, 983567, 303, 983605, 983607, 297, 7725, + 7881, 236, 237, 523, 301, 616, 122650, 7574, 42874, 42876, 7545, 42883, + 42885, 42887, 43876, 43840, 617, 7548, 43873, 42861, 106, 309, 669, 496, + 983609, 585, 107, 311, 489, 42819, 11370, 7731, 42817, 42821, 7729, 7733, + 7556, 42915, 409, 312, 108, 620, 122643, 410, 316, 7741, 564, 318, 7735, + 7737, 43832, 11361, 619, 43833, 320, 122662, 42825, 314, 7739, 43831, + 621, 42894, 122641, 7557, 983611, 322, 42971, 411, 622, 122629, 43829, + 383, 7836, 7835, 7837, 682, 683, 42866, 457, 109, 7743, 43834, 7535, + 7558, 7747, 7745, 983613, 625, 7931, 7933, 42967, 42867, 110, 326, 7755, + 43835, 565, 328, 414, 7753, 626, 122663, 7536, 505, 324, 42897, 7751, + 7749, 7559, 627, 42917, 241, 329, 983589, 42868, 460, 111, 244, 7893, + 7891, 7889, 7897, 7895, 466, 246, 555, 559, 561, 7885, 525, 337, 42827, + 11386, 42829, 333, 7761, 7763, 491, 493, 248, 511, 245, 7759, 7757, 557, + 983577, 983579, 983581, 417, 7903, 7901, 7899, 7907, 7905, 7887, 242, + 243, 527, 335, 122651, 42945, 596, 983625, 983626, 7575, 43839, 43874, + 603, 7571, 42935, 419, 42831, 547, 112, 42835, 7549, 42833, 42837, 7765, + 7537, 7560, 421, 7767, 42959, 632, 113, 42841, 672, 587, 42839, 569, 114, + 343, 43849, 345, 7771, 7773, 7769, 529, 638, 7539, 122646, 7775, 636, + 983615, 637, 122664, 7538, 341, 531, 7561, 42919, 589, 43847, 42843, + 42998, 604, 7572, 605, 639, 122625, 600, 122631, 8580, 42815, 122627, + 42869, 42845, 612, 115, 347, 7781, 353, 7783, 351, 537, 349, 122654, + 7779, 7785, 7777, 42957, 42954, 575, 983583, 122665, 7540, 7562, 42921, + 642, 42892, 43872, 601, 983629, 983630, 7573, 602, 43851, 43852, 609, + 43830, 223, 7441, 7442, 7443, 7455, 7454, 7453, 42969, 645, 43845, 116, + 355, 7793, 539, 566, 357, 11366, 7831, 7789, 7787, 122666, 7541, 7791, + 427, 429, 122633, 648, 359, 679, 122647, 122652, 7546, 254, 42853, 42855, + 389, 445, 424, 7446, 42795, 397, 613, 686, 687, 7433, 42879, 7444, 43842, + 43841, 43843, 43844, 7432, 633, 43880, 122645, 634, 122632, 11385, 635, + 647, 122637, 652, 983627, 983628, 592, 594, 7426, 623, 624, 654, 122630, + 43857, 477, 7543, 670, 42881, 653, 42871, 680, 678, 43879, 11383, 42793, + 117, 649, 43855, 251, 7799, 468, 252, 474, 476, 472, 470, 7795, 533, 369, + 7909, 432, 7917, 7915, 7913, 7921, 7919, 7911, 363, 7803, 983569, 983621, + 983623, 371, 983617, 983619, 7577, 367, 361, 7801, 7797, 249, 43854, + 42937, 250, 535, 365, 43858, 650, 7551, 7531, 43856, 42872, 43875, 118, + 42847, 7807, 7564, 11380, 11377, 7805, 651, 42851, 42907, 42909, 42911, + 42857, 42849, 119, 373, 7813, 7817, 7815, 7809, 7811, 7832, 11379, 120, + 7821, 7819, 43863, 43864, 43865, 43862, 7565, 121, 375, 255, 7925, 7823, + 7923, 436, 7927, 7935, 43866, 591, 253, 563, 7929, 7833, 541, 122, 378, + 7825, 657, 382, 11372, 7827, 380, 7829, 576, 438, 7542, 7566, 656, 549, + 64256, 64259, 64260, 64257, 64258, 307, 64261, 64262, 339, 8347, 8340, + 8336, 8337, 8341, 7522, 11388, 8342, 8343, 8344, 8345, 8338, 8346, 7523, + 8348, 7524, 7525, 8339, 129726, 127811, 129388, 129897, 129916, 129947, + 10203, 10202, 129899, 129917, 117902, 128494, 12296, 10641, 10643, 11058, + 11056, 10576, 10571, 10570, 10574, 12304, 10647, 123, 9128, 9129, 9127, + 12300, 8968, 9948, 10714, 12298, 8220, 11816, 11780, 129287, 129284, + 129285, 129283, 129286, 9686, 11240, 9612, 129977, 117924, 118288, + 129970, 118285, 118283, 118435, 118440, 129940, 129932, 128379, 128709, + 11804, 10204, 9614, 9615, 129999, 10197, 8596, 8700, 8697, 8622, 10568, + 8660, 10500, 8654, 8621, 11012, 8703, 11020, 129112, 11108, 11788, 10181, + 8907, 9609, 8216, 11814, 128488, 91, 9123, 9121, 10639, 10637, 8261, + 10635, 11863, 11861, 9122, 11778, 10703, 129900, 11785, 117771, 129985, + 128492, 118434, 118441, 9610, 9613, 12308, 129998, 8867, 12302, 10627, + 12310, 10629, 12314, 12312, 10712, 128398, 9611, 10620, 8970, 130027, + 130019, 8905, 40, 9117, 9115, 9116, 11808, 9144, 9001, 117856, 118265, + 10748, 171, 117774, 128269, 117920, 117846, 117922, 117911, 117861, + 117762, 117918, 117880, 10553, 10154, 1422, 117832, 117906, 117908, + 129307, 4054, 4056, 117872, 117876, 9958, 8294, 8237, 8234, 8206, 8592, + 10563, 11074, 11083, 11082, 10611, 129973, 10618, 10615, 11070, 8676, + 8633, 10525, 129032, 8619, 11064, 8698, 10566, 129040, 129024, 8602, + 11024, 11025, 8610, 11066, 11065, 129028, 129176, 129044, 8617, 8695, + 8612, 10527, 129216, 8646, 10521, 129192, 129184, 11144, 11013, 10603, + 10599, 10590, 10582, 8637, 10594, 10602, 10598, 10586, 10578, 8636, 8651, + 129778, 129088, 129092, 11104, 11136, 11130, 983241, 11174, 11172, + 129064, 129060, 129056, 129072, 129068, 11120, 11114, 11140, 129168, + 10510, 8666, 129186, 11067, 11069, 11068, 11244, 11061, 11060, 11062, + 11063, 8606, 8678, 129172, 8604, 8656, 10498, 8653, 10502, 10523, 10508, + 8672, 129194, 129076, 129188, 8701, 8647, 129783, 129190, 128620, 8668, + 129080, 129104, 129084, 11077, 9804, 128006, 7213, 7221, 7216, 7220, + 7215, 7214, 7217, 7218, 7219, 7170, 7169, 7168, 7184, 7183, 7182, 7247, + 7193, 7180, 7188, 7187, 7186, 7185, 7172, 7171, 7198, 7197, 7190, 7189, + 7173, 7177, 7181, 7192, 7191, 7246, 7245, 7179, 7178, 7175, 7174, 7201, + 7200, 7176, 7196, 7195, 7199, 7202, 7194, 7203, 7227, 7231, 7230, 7228, + 7229, 7223, 7222, 7205, 7204, 7210, 7211, 7208, 7209, 7206, 7212, 7207, + 7237, 7236, 7239, 7238, 7235, 7234, 7232, 7241, 7233, 7240, 10897, 10895, + 10893, 10899, 10891, 10614, 10889, 10887, 8922, 8934, 8808, 10918, 10920, + 10885, 10877, 10881, 10883, 10879, 8818, 8804, 8822, 8806, 10873, 10875, + 8918, 60, 118480, 128210, 127898, 127819, 129461, 128626, 128955, 128969, + 128943, 11212, 128964, 10099, 128648, 10098, 9617, 128937, 128949, + 128978, 128960, 129653, 128910, 10072, 128930, 128504, 9735, 128498, + 128497, 6429, 6404, 6403, 6412, 6430, 6411, 6421, 6410, 6405, 6415, 6425, + 6426, 6427, 6419, 6418, 6407, 6406, 6414, 6413, 6409, 6408, 6402, 6401, + 6417, 6416, 6428, 6423, 6420, 6422, 6424, 6458, 6457, 6459, 6464, 6449, + 6452, 6450, 6448, 6456, 6454, 6453, 6455, 6451, 6442, 6443, 6441, 6432, + 6436, 6438, 6440, 6437, 6439, 6435, 6433, 6434, 6400, 6468, 6469, 6475, + 6474, 6477, 6476, 6473, 6472, 6470, 6479, 6471, 6478, 13007, 10770, + 10771, 10772, 983062, 8232, 983068, 983143, 67143, 67146, 67151, 67165, + 67166, 67167, 67157, 67158, 67159, 67160, 67161, 67162, 67163, 67164, + 67171, 67172, 67173, 67168, 67169, 67170, 67174, 67175, 67176, 67177, + 67178, 67179, 67230, 67231, 67180, 67181, 67182, 67183, 67184, 67185, + 67186, 67187, 67188, 67189, 67190, 67191, 67192, 67193, 67194, 67195, + 67196, 67197, 67198, 67199, 67200, 67201, 67202, 67203, 67204, 67205, + 67206, 67207, 67208, 67209, 67210, 67211, 67212, 67213, 67214, 67215, + 67216, 67217, 67218, 67219, 67220, 67221, 67222, 67223, 67224, 67225, + 67226, 67227, 67228, 67229, 67232, 67233, 67234, 67235, 67236, 67237, + 67238, 67239, 67240, 67241, 67242, 67243, 67244, 67245, 67246, 67247, + 67248, 67249, 67250, 67251, 67252, 67253, 67254, 67255, 67256, 67257, + 67258, 67259, 67260, 67261, 67262, 67263, 67264, 67274, 67275, 67276, + 67277, 67278, 67279, 67280, 67281, 67282, 67283, 67284, 67285, 67286, + 67287, 67288, 67289, 67290, 67291, 67292, 67293, 67294, 67295, 67296, + 67297, 67298, 67299, 67300, 67301, 67302, 67303, 67304, 67265, 67266, + 67267, 67268, 67269, 67270, 67271, 67272, 67273, 67325, 67326, 67327, + 67328, 67329, 67330, 67305, 67306, 67307, 67308, 67309, 67310, 67311, + 67312, 67313, 67314, 67315, 67316, 67317, 67318, 67319, 67320, 67321, + 67322, 67323, 67324, 67331, 67332, 67333, 67334, 67335, 67336, 67337, + 67338, 67349, 67350, 67351, 67352, 67353, 67354, 67355, 67356, 67357, + 67358, 67359, 67360, 67361, 67362, 67363, 67364, 67365, 67366, 67367, + 67368, 67378, 67379, 67380, 67381, 67382, 67369, 67370, 67371, 67372, + 67373, 67374, 67375, 67376, 67377, 67339, 67340, 67341, 67342, 67343, + 67344, 67345, 67346, 67347, 67348, 67401, 67404, 67403, 67402, 67400, + 67398, 67393, 67397, 67395, 67394, 67399, 67392, 67396, 67408, 67409, + 67410, 67406, 67407, 67405, 67411, 67413, 67412, 67424, 67425, 67426, + 67427, 67428, 67429, 67430, 67431, 67081, 67082, 67083, 67084, 67085, + 67087, 67088, 67089, 67090, 67091, 67092, 67093, 67094, 67086, 67095, + 67096, 67097, 67098, 67100, 67101, 67102, 67103, 67104, 67105, 67106, + 67107, 67108, 67109, 67110, 67111, 67112, 67113, 67114, 67115, 67116, + 67117, 67118, 67119, 67120, 67121, 67122, 67123, 67124, 67125, 67126, + 67127, 67128, 67129, 67130, 67131, 67132, 67133, 67134, 67135, 67136, + 67137, 67138, 67139, 67140, 67141, 67142, 67072, 67073, 67074, 67075, + 67076, 67077, 67078, 67079, 67080, 67145, 67147, 67148, 67149, 67150, + 67154, 67155, 67144, 67152, 67153, 67156, 67099, 65667, 65668, 65669, + 65670, 65671, 65672, 65673, 65675, 65674, 65677, 65676, 65665, 65664, + 65666, 65681, 65679, 65680, 65682, 65678, 65686, 65685, 65687, 65693, + 65690, 65691, 65692, 65694, 65703, 65696, 65695, 65697, 65698, 65699, + 65701, 65702, 65707, 65706, 65704, 65705, 65708, 65709, 65710, 65711, + 65712, 65713, 65719, 65717, 65714, 65715, 65716, 65718, 65720, 65721, + 65722, 65723, 65724, 65725, 65726, 65727, 65728, 65729, 65731, 65730, + 65732, 65733, 65737, 65734, 65735, 65736, 65738, 65739, 65740, 65741, + 65743, 65742, 65744, 65745, 65747, 65748, 65752, 65749, 65750, 65751, + 65753, 65754, 65755, 65756, 65757, 65779, 65780, 65781, 65782, 65783, + 65784, 65785, 65759, 65760, 65761, 65762, 65763, 65764, 65765, 65766, + 65767, 65768, 65769, 65770, 65771, 65772, 65773, 65774, 65775, 65776, + 65777, 65778, 65758, 65786, 65683, 65684, 65689, 65688, 65700, 65746, + 65561, 65543, 65587, 65582, 65589, 65536, 65541, 65579, 65566, 65571, + 65596, 65569, 65584, 65544, 65559, 65540, 65557, 65560, 65580, 65606, + 65600, 65599, 65577, 65562, 65538, 65573, 65563, 65609, 65588, 65549, + 65568, 65537, 65581, 65574, 65601, 65542, 65593, 65583, 65594, 65552, + 65547, 65605, 65578, 65545, 65585, 65586, 65546, 65570, 65591, 65564, + 65565, 65607, 65610, 65611, 65553, 65590, 65550, 65539, 65576, 65608, + 65551, 65554, 65592, 65603, 65597, 65567, 65572, 65558, 65555, 65612, + 65602, 65556, 65613, 65604, 65620, 65621, 65623, 65624, 65626, 65627, + 65628, 65629, 65622, 65616, 65617, 65619, 65618, 65625, 128391, 128279, + 128482, 128132, 42237, 42235, 42232, 42234, 42236, 42233, 42206, 42205, + 42197, 42196, 42204, 42195, 42228, 42229, 42230, 42213, 42208, 42224, + 42225, 42203, 42202, 42221, 42198, 42216, 42214, 42200, 42199, 42194, + 42193, 42219, 42210, 73648, 42220, 42211, 42212, 42222, 42223, 42227, + 42231, 42192, 42217, 42201, 42209, 42207, 42218, 42215, 42226, 42238, + 42239, 8356, 8374, 129409, 129422, 9806, 128274, 983079, 983076, 128271, + 117785, 117786, 117784, 117783, 117782, 117781, 8743, 10848, 10846, + 10833, 10844, 10842, 10847, 8744, 10841, 10851, 10850, 10834, 10845, + 10843, 10982, 10188, 129688, 10231, 129240, 10234, 10206, 10232, 10237, + 10229, 10235, 11059, 129236, 10230, 129238, 129239, 129232, 10236, 10233, + 10238, 129233, 129234, 10239, 10205, 129524, 128884, 129719, 128140, + 127977, 128261, 129707, 12319, 8270, 11847, 11848, 95, 118273, 9691, + 118276, 118291, 129935, 118436, 118447, 9604, 9697, 117765, 128394, + 129852, 129853, 129870, 129872, 129868, 129856, 129871, 129869, 129854, + 129873, 129855, 128395, 128396, 128393, 10559, 117934, 117936, 117932, + 117930, 117972, 9695, 117960, 117948, 117964, 117968, 117952, 117956, + 117944, 117940, 117817, 129951, 9722, 117820, 128397, 118428, 117935, + 117937, 117933, 117931, 117973, 9694, 117961, 117949, 117965, 117969, + 117953, 117957, 117945, 117941, 117818, 10558, 128318, 10065, 129950, + 9727, 117823, 117767, 129863, 129865, 129867, 129864, 129861, 129866, + 129859, 129862, 129860, 129857, 129858, 10195, 118431, 10063, 9998, 9987, + 118429, 117821, 118430, 117822, 130021, 9605, 118425, 118426, 118424, + 117816, 118427, 117819, 9602, 9601, 9607, 9603, 118437, 118446, 9606, + 129903, 9674, 10208, 129438, 128557, 127853, 129523, 128886, 129729, + 66190, 66192, 66187, 66196, 66199, 66185, 66200, 66178, 66179, 66176, + 66201, 66177, 66202, 66191, 66193, 66181, 66180, 66203, 66182, 66186, + 66189, 66195, 66188, 66197, 66198, 66194, 66183, 66204, 66184, 67887, + 67892, 67881, 67895, 67891, 67886, 67872, 67893, 67876, 67894, 67883, + 67896, 67873, 67897, 67875, 67889, 67874, 67878, 67880, 67882, 67884, + 67890, 67885, 67888, 67877, 67879, 67903, 129317, 983226, 983234, 983224, + 983229, 8468, 129433, 983065, 129668, 129522, 129497, 69986, 69981, + 69991, 69985, 69984, 69990, 69989, 70002, 69997, 69983, 69982, 69988, + 69987, 69995, 69994, 69978, 69977, 69976, 69975, 69980, 69979, 69974, + 69973, 69993, 69992, 70001, 69998, 69996, 70000, 69999, 69968, 69971, + 69969, 69972, 69970, 70006, 70005, 70003, 70004, 127012, 127019, 127008, + 126990, 126999, 126976, 127005, 126987, 126996, 127004, 126986, 126995, + 126979, 127009, 126991, 127000, 127001, 126983, 126992, 127011, 127010, + 126977, 127007, 126989, 126998, 127006, 126988, 126997, 127015, 127014, + 127003, 126985, 126994, 127002, 126984, 126993, 126978, 126982, 127017, + 126981, 126980, 127016, 127018, 127013, 73464, 73442, 73451, 73448, + 73444, 73449, 73447, 73441, 73450, 73440, 73454, 73445, 73443, 73453, + 73456, 73446, 73455, 73452, 73457, 73463, 73461, 73459, 73462, 73460, + 73458, 128892, 3449, 3435, 3434, 3437, 3436, 3433, 3432, 3430, 3439, + 3431, 3438, 3419, 3420, 3446, 3417, 3422, 3416, 3447, 3444, 3443, 3448, + 3418, 3421, 3445, 3333, 3423, 3334, 3344, 3348, 3453, 3454, 3414, 3451, + 3450, 3452, 3455, 3412, 3413, 3355, 3354, 3406, 3362, 3361, 3367, 3366, + 3360, 3386, 3359, 3365, 3364, 3332, 3339, 3424, 3340, 3425, 3381, 3369, + 3363, 3353, 3358, 3368, 3380, 3379, 3378, 3377, 3376, 3337, 3338, 3346, + 3347, 3335, 3336, 3382, 3383, 3384, 3373, 3372, 3352, 3351, 3357, 3356, + 3350, 3349, 3371, 3370, 3342, 3343, 3385, 3374, 3375, 3441, 3442, 3440, + 3328, 3388, 3329, 3387, 3405, 3331, 3389, 3330, 3407, 3390, 3400, 3404, + 3393, 3394, 3395, 3396, 3426, 3427, 3402, 3403, 3391, 3392, 3398, 3399, + 3415, 9895, 9894, 9893, 9794, 10016, 129443, 128104, 128372, 129333, + 128114, 128115, 128378, 128107, 2137, 2122, 2121, 2133, 2120, 2126, 2132, + 2129, 2136, 2113, 2115, 2114, 2116, 2123, 2124, 2125, 2128, 2130, 2131, + 2118, 2134, 2117, 2112, 2127, 2119, 2135, 2138, 2139, 2142, 68288, 68314, + 68313, 68290, 68289, 68293, 68308, 68292, 68291, 68300, 68299, 68298, + 68297, 68306, 68304, 68320, 68318, 68323, 68312, 68317, 68322, 68309, + 68302, 68324, 68305, 68319, 68307, 68321, 68303, 68294, 68301, 68311, + 68295, 68316, 68315, 68310, 68331, 68335, 68334, 68333, 68332, 68340, + 68339, 68338, 68342, 68337, 68341, 68336, 68296, 68326, 68325, 128094, + 129469, 8380, 128368, 129389, 9967, 127809, 129671, 72835, 72834, 72827, + 72826, 72836, 72828, 72821, 72825, 72829, 72823, 72822, 72819, 72818, + 72831, 72830, 72844, 72845, 72838, 72839, 72840, 72832, 72820, 72846, + 72824, 72843, 72833, 72842, 72837, 72841, 72847, 72886, 72885, 72867, + 72866, 72859, 72858, 72868, 72860, 72853, 72857, 72861, 72855, 72854, + 72851, 72850, 72863, 72862, 72876, 72877, 72870, 72871, 72864, 72852, + 72878, 72856, 72875, 72865, 72874, 72869, 72873, 72879, 72880, 72883, + 72881, 72884, 72882, 72816, 72817, 9901, 129355, 73007, 72980, 72979, + 72983, 72982, 72988, 73008, 72987, 72960, 72961, 72968, 72971, 72985, + 72984, 72990, 72989, 72964, 72965, 72962, 72963, 73005, 72999, 73006, + 72973, 72972, 72976, 72986, 72981, 72991, 73001, 73002, 73003, 72995, + 72994, 72978, 72977, 72975, 72974, 72993, 72992, 73004, 72996, 72998, + 73000, 72997, 72966, 72969, 73031, 73030, 73027, 73028, 73026, 73025, + 73024, 73014, 73009, 73020, 73023, 73012, 73013, 73010, 73011, 73018, + 73021, 73029, 73045, 73044, 73047, 73046, 73043, 73042, 73040, 73049, + 73041, 73048, 186, 127405, 12348, 119811, 120778, 120491, 119827, 120495, + 120505, 120507, 119808, 120488, 119809, 120489, 119833, 120493, 119812, + 120492, 120494, 119814, 120490, 119816, 120496, 119818, 120497, 119819, + 120498, 119822, 120502, 120512, 119823, 120509, 120511, 120503, 119825, + 120504, 119826, 120506, 119828, 120508, 119810, 120510, 119820, 120499, + 119821, 120500, 119831, 120501, 119813, 119815, 119817, 119824, 119829, + 119830, 119832, 119837, 120779, 120517, 119834, 120514, 119835, 120515, + 119859, 120519, 119838, 120518, 120520, 119839, 120531, 119840, 120516, + 119842, 120522, 119844, 120523, 119845, 120524, 119848, 120528, 120538, + 119849, 120535, 120537, 120529, 119851, 120530, 119852, 120532, 119853, + 120521, 120533, 119854, 120534, 119836, 120536, 119846, 120525, 119847, + 120526, 119857, 120527, 119841, 119843, 119850, 119855, 119856, 119858, + 120016, 120017, 120018, 120019, 120020, 120021, 120022, 120023, 120024, + 120025, 120026, 120027, 120028, 120029, 120030, 120031, 120032, 120033, + 120034, 120035, 120036, 120037, 120038, 120039, 120040, 120041, 120042, + 120043, 120044, 120045, 120046, 120047, 120048, 120049, 120050, 120051, + 120052, 120053, 120054, 120055, 120056, 120057, 120058, 120059, 120060, + 120061, 120062, 120063, 120064, 120065, 120066, 120067, 119931, 120611, + 120621, 120623, 119912, 120604, 119913, 120605, 119937, 120609, 119915, + 120607, 119916, 120608, 120610, 119918, 120606, 119920, 120612, 119922, + 120613, 119923, 120614, 119926, 120618, 120628, 119927, 120625, 120627, + 120619, 119929, 120620, 119930, 120622, 119932, 120624, 119914, 120626, + 119924, 120615, 119925, 120616, 119935, 120617, 119917, 119919, 119921, + 119928, 119933, 119934, 119936, 120656, 120658, 120629, 120659, 120655, + 120661, 120660, 119938, 120630, 119939, 120631, 119963, 120635, 119941, + 120633, 119942, 120634, 120636, 119943, 120647, 119944, 120632, 119946, + 120638, 119948, 120639, 119949, 120640, 119952, 120644, 120654, 119953, + 120651, 120653, 120645, 119955, 120646, 119956, 120648, 119957, 120637, + 120649, 119958, 120650, 119940, 120652, 119950, 120641, 119951, 120642, + 119961, 120643, 119945, 119947, 119954, 119959, 119960, 119962, 120657, + 120540, 120542, 120513, 120543, 120539, 120545, 120544, 120541, 120172, + 120173, 120174, 120175, 120176, 120177, 120178, 120179, 120180, 120181, + 120182, 120183, 120184, 120185, 120186, 120187, 120188, 120189, 120190, + 120191, 120192, 120193, 120194, 120195, 120196, 120197, 120198, 120199, + 120200, 120201, 120202, 120203, 120204, 120205, 120206, 120207, 120208, + 120209, 120210, 120211, 120212, 120213, 120214, 120215, 120216, 120217, + 120218, 120219, 120220, 120221, 120222, 120223, 120787, 120786, 120789, + 120788, 120785, 120784, 120782, 120791, 120783, 120790, 120120, 120121, + 120123, 120124, 120125, 120126, 120128, 120129, 120130, 120131, 120132, + 120134, 120138, 120139, 120140, 120141, 120142, 120143, 120144, 120146, + 120147, 120148, 120149, 120150, 120151, 120152, 120153, 120154, 120155, + 120156, 120157, 120158, 120159, 120160, 120161, 120162, 120163, 120164, + 120165, 120166, 120167, 120168, 120169, 120170, 120171, 120797, 120796, + 120799, 120798, 120795, 120794, 120792, 120801, 120793, 120800, 120068, + 120069, 120071, 120072, 120073, 120074, 120077, 120078, 120079, 120080, + 120081, 120082, 120083, 120084, 120086, 120087, 120088, 120089, 120090, + 120091, 120092, 120094, 120095, 120096, 120097, 120098, 120099, 120100, + 120101, 120102, 120103, 120104, 120105, 120106, 120107, 120108, 120109, + 120110, 120111, 120112, 120113, 120114, 120115, 120116, 120117, 120118, + 120119, 10189, 119889, 120484, 120485, 120575, 119886, 120572, 119887, + 120573, 119911, 120577, 119890, 120576, 120578, 119891, 120589, 119892, + 120574, 119894, 120580, 119896, 120581, 119897, 120582, 119900, 120586, + 120596, 119901, 120593, 120595, 120587, 119903, 120588, 119904, 120590, + 119905, 120579, 120591, 119906, 120592, 119888, 120594, 119898, 120583, + 119899, 120584, 119909, 120585, 119895, 119902, 119907, 119908, 119910, + 119879, 120553, 120563, 120565, 119860, 120546, 119861, 120547, 119885, + 120551, 119863, 120549, 119864, 120550, 120552, 119866, 120548, 119868, + 120554, 119870, 120555, 119871, 120556, 119874, 120560, 120570, 119875, + 120567, 120569, 120561, 119877, 120562, 119878, 120564, 119880, 120566, + 119862, 120568, 119872, 120557, 119873, 120558, 119883, 120559, 119865, + 119867, 119869, 119876, 119881, 119882, 119884, 120598, 120600, 120571, + 120601, 120597, 120603, 120602, 120599, 120432, 120433, 120434, 120435, + 120436, 120437, 120438, 120439, 120440, 120441, 120442, 120443, 120444, + 120445, 120446, 120447, 120448, 120449, 120450, 120451, 120452, 120453, + 120454, 120455, 120456, 120457, 120458, 120459, 120460, 120461, 120462, + 120463, 120464, 120465, 120466, 120467, 120468, 120469, 120470, 120471, + 120472, 120473, 120474, 120475, 120476, 120477, 120478, 120479, 120480, + 120481, 120482, 120483, 120827, 120826, 120829, 120828, 120825, 120824, + 120822, 120831, 120823, 120830, 10215, 10221, 10219, 10217, 10223, 10187, + 10214, 10220, 10218, 10216, 10222, 120399, 120727, 120737, 120739, + 120380, 120720, 120381, 120721, 120405, 120725, 120383, 120723, 120384, + 120724, 120726, 120386, 120722, 120388, 120728, 120390, 120729, 120391, + 120730, 120394, 120734, 120744, 120395, 120741, 120743, 120735, 120397, + 120736, 120398, 120738, 120400, 120740, 120382, 120742, 120392, 120731, + 120393, 120732, 120403, 120733, 120385, 120387, 120389, 120396, 120401, + 120402, 120404, 120772, 120774, 120745, 120775, 120771, 120777, 120776, + 120406, 120746, 120407, 120747, 120431, 120751, 120409, 120749, 120410, + 120750, 120752, 120411, 120763, 120412, 120748, 120414, 120754, 120416, + 120755, 120417, 120756, 120420, 120760, 120770, 120421, 120767, 120769, + 120761, 120423, 120762, 120424, 120764, 120425, 120753, 120765, 120426, + 120766, 120408, 120768, 120418, 120757, 120419, 120758, 120429, 120759, + 120413, 120415, 120422, 120427, 120428, 120430, 120773, 120295, 120669, + 120679, 120681, 120276, 120662, 120277, 120663, 120301, 120667, 120279, + 120665, 120280, 120666, 120668, 120282, 120664, 120284, 120670, 120286, + 120671, 120287, 120672, 120290, 120676, 120686, 120291, 120683, 120685, + 120677, 120293, 120678, 120294, 120680, 120296, 120682, 120278, 120684, + 120288, 120673, 120289, 120674, 120299, 120675, 120281, 120283, 120285, + 120292, 120297, 120298, 120300, 120714, 120716, 120687, 120717, 120713, + 120719, 120718, 120302, 120688, 120303, 120689, 120327, 120693, 120305, + 120691, 120306, 120692, 120694, 120307, 120705, 120308, 120690, 120310, + 120696, 120312, 120697, 120313, 120698, 120316, 120702, 120712, 120317, + 120709, 120711, 120703, 120319, 120704, 120320, 120706, 120321, 120695, + 120707, 120322, 120708, 120304, 120710, 120314, 120699, 120315, 120700, + 120325, 120701, 120309, 120311, 120318, 120323, 120324, 120326, 120715, + 120817, 120816, 120819, 120818, 120815, 120814, 120812, 120821, 120813, + 120820, 120328, 120329, 120330, 120331, 120332, 120333, 120334, 120335, + 120336, 120337, 120338, 120339, 120340, 120341, 120342, 120343, 120344, + 120345, 120346, 120347, 120348, 120349, 120350, 120351, 120352, 120353, + 120354, 120355, 120356, 120357, 120358, 120359, 120360, 120361, 120362, + 120363, 120364, 120365, 120366, 120367, 120368, 120369, 120370, 120371, + 120372, 120373, 120374, 120375, 120376, 120377, 120378, 120379, 120224, + 120225, 120226, 120227, 120228, 120229, 120230, 120231, 120232, 120233, + 120234, 120235, 120236, 120237, 120238, 120239, 120240, 120241, 120242, + 120243, 120244, 120245, 120246, 120247, 120248, 120249, 120250, 120251, + 120252, 120253, 120254, 120255, 120256, 120257, 120258, 120259, 120260, + 120261, 120262, 120263, 120264, 120265, 120266, 120267, 120268, 120269, + 120270, 120271, 120272, 120273, 120274, 120275, 120807, 120806, 120809, + 120808, 120805, 120804, 120802, 120811, 120803, 120810, 119964, 119966, + 119967, 119970, 119973, 119974, 119977, 119978, 119979, 119980, 119982, + 119983, 119984, 119985, 119986, 119987, 119988, 119989, 119990, 119991, + 119992, 119993, 119995, 119997, 119998, 119999, 120000, 120001, 120002, + 120003, 120005, 120006, 120007, 120008, 120009, 120010, 120011, 120012, + 120013, 120014, 120015, 129481, 119528, 119538, 119531, 119535, 119525, + 119524, 119534, 119529, 119539, 119527, 119537, 119526, 119536, 119533, + 119523, 119532, 119522, 119530, 119520, 119521, 128470, 175, 8737, 10667, + 10666, 10671, 10669, 10670, 10668, 10665, 10664, 10651, 10653, 8798, + 127830, 129470, 129471, 93773, 93764, 93790, 93787, 983274, 93783, + 983273, 93782, 93772, 93766, 93791, 93779, 93789, 93786, 93776, 93777, + 93785, 93775, 93770, 93769, 93771, 93774, 93780, 93760, 93767, 93781, + 93788, 93761, 93768, 93778, 93762, 93763, 93784, 93765, 93847, 93827, + 93846, 93826, 93845, 93825, 93844, 93829, 93828, 93831, 93830, 93824, + 93833, 93832, 93837, 93836, 93834, 93842, 93835, 93838, 93839, 93843, + 93840, 93841, 93805, 93796, 93822, 93819, 983276, 93815, 983275, 93814, + 93804, 93798, 93823, 93811, 93821, 93818, 93808, 93809, 93817, 93807, + 93802, 93801, 93803, 93806, 93812, 93792, 93799, 93813, 93820, 93793, + 93800, 93810, 93794, 93795, 93816, 93797, 93849, 93850, 93848, 11859, + 11852, 11860, 128901, 9899, 10090, 10091, 128967, 128965, 128944, 10100, + 10088, 10092, 10101, 10089, 10093, 8287, 9618, 128971, 128950, 128938, + 9900, 118512, 128963, 128961, 10073, 128974, 128956, 9898, 128911, + 128931, 43761, 44013, 43762, 43760, 44011, 43994, 43989, 43974, 43746, + 43993, 43991, 43751, 43750, 43992, 43986, 43987, 43990, 43968, 43995, + 43976, 43973, 43999, 43977, 44001, 43752, 43747, 43972, 43998, 43984, + 43969, 43753, 43754, 43975, 44000, 43978, 43749, 43748, 43983, 44002, + 43970, 43996, 43971, 43997, 43981, 43988, 43979, 43985, 43980, 43982, + 43744, 43745, 44012, 43763, 43764, 44005, 43757, 43759, 43758, 44009, + 44003, 44007, 44006, 44004, 43755, 44008, 43756, 44010, 43765, 43766, + 44021, 44020, 44023, 44022, 44019, 44018, 44016, 44025, 44017, 44024, + 118475, 129760, 127816, 125140, 125137, 125136, 125139, 125141, 125138, + 125142, 124928, 124929, 124930, 124936, 124937, 124949, 124950, 124948, + 124938, 124956, 124990, 124992, 124974, 124955, 124964, 124963, 124991, + 124957, 124962, 124976, 124996, 124997, 124998, 124982, 124983, 124984, + 125004, 124975, 125003, 125005, 125011, 125018, 125028, 125029, 125012, + 125019, 125020, 125027, 125013, 125035, 124942, 124934, 125090, 125046, + 125078, 125033, 124946, 125048, 125037, 125070, 125000, 125095, 125121, + 124951, 125044, 125041, 125072, 124987, 125066, 125076, 125074, 125009, + 125107, 125108, 125068, 125124, 124945, 125002, 124931, 125089, 125022, + 124980, 125099, 124986, 125100, 125080, 125119, 124933, 125021, 125015, + 125071, 124985, 125117, 125056, 124993, 125039, 125049, 125043, 125024, + 124932, 125047, 125097, 124959, 125069, 125088, 124999, 125123, 124952, + 125036, 125026, 125001, 125085, 124960, 125057, 125073, 124966, 125098, + 125014, 125091, 124989, 125007, 124978, 124940, 125106, 125050, 125030, + 125092, 124941, 125060, 125077, 125102, 125094, 125053, 125040, 125055, + 125104, 125103, 124939, 125017, 124961, 125112, 125087, 124970, 124971, + 124969, 125023, 124979, 125042, 124947, 125086, 125075, 125051, 125111, + 124968, 124944, 125038, 125096, 125016, 125118, 125109, 124953, 125059, + 125052, 125006, 124958, 125093, 125115, 125054, 124988, 125008, 125084, + 125061, 125064, 125120, 125063, 124967, 124977, 124965, 125031, 983279, + 125081, 125082, 983280, 125010, 125067, 124973, 125032, 124935, 125116, + 125122, 125101, 124994, 124995, 125113, 125058, 125079, 125114, 125065, + 125034, 125083, 124954, 125062, 125105, 125110, 125045, 124943, 124972, + 124981, 125025, 125131, 125130, 125133, 125132, 125129, 125128, 125135, + 125127, 125134, 128334, 128697, 68028, 68093, 68090, 68089, 68086, 68029, + 68092, 68091, 68095, 68088, 68087, 68094, 68000, 68016, 68020, 68021, + 68022, 68009, 68010, 68015, 68017, 68014, 68013, 68018, 68006, 68023, + 68012, 68008, 68007, 68019, 68011, 68005, 68004, 68001, 68002, 68003, + 68031, 68030, 68039, 68075, 68057, 68084, 68066, 68036, 68054, 68081, + 68063, 68045, 68072, 68035, 68053, 68080, 68062, 68044, 68071, 68040, + 68076, 68058, 68085, 68067, 68038, 68056, 68083, 68065, 68047, 68074, + 68037, 68055, 68082, 68064, 68046, 68073, 68034, 68052, 68079, 68061, + 68043, 68070, 68033, 68051, 68078, 68060, 68042, 68069, 68041, 68068, + 68032, 68050, 68077, 68059, 67974, 67975, 67982, 67983, 67978, 67979, + 67980, 67981, 67987, 67988, 67989, 67992, 67993, 67994, 67995, 67996, + 67986, 67985, 67990, 67997, 67984, 67977, 67976, 67991, 67973, 67972, + 67968, 67969, 67970, 67971, 67998, 67999, 9791, 129500, 983173, 9170, + 9172, 9177, 9176, 9175, 9173, 9174, 9171, 9169, 128647, 118467, 128221, + 94015, 93989, 93971, 93958, 94019, 94021, 93953, 94023, 93999, 93995, + 94008, 93981, 93979, 93967, 93963, 93993, 93992, 93983, 93977, 93976, + 93975, 93974, 93968, 94032, 93988, 93987, 93973, 93972, 93997, 93996, + 93969, 94106, 94107, 94108, 94109, 94110, 94111, 94002, 94026, 94022, + 94003, 94004, 94010, 93980, 93978, 94099, 94100, 94101, 94102, 94103, + 94104, 94105, 93998, 93994, 94007, 94025, 93966, 93962, 94024, 93961, + 93960, 94000, 94009, 93964, 93965, 94001, 93970, 93984, 93954, 94017, + 94014, 94016, 94013, 94006, 94012, 94005, 94011, 93986, 93985, 93955, + 93952, 94020, 93990, 93957, 93956, 93959, 93982, 94018, 93991, 94035, + 94034, 94033, 94031, 94098, 94096, 94097, 94095, 94036, 94039, 94040, + 94067, 94068, 94038, 94037, 94073, 94075, 94045, 94071, 94069, 94046, + 94047, 94085, 94074, 94049, 94050, 94051, 94052, 94053, 94086, 94057, + 94054, 94084, 94055, 94056, 94041, 94082, 94048, 94081, 94042, 94076, + 94058, 94059, 94060, 94061, 94063, 94064, 94079, 94087, 94062, 94065, + 94080, 94066, 94072, 94070, 94044, 94043, 94077, 94078, 94083, 983239, + 983240, 128300, 127908, 181, 129440, 117772, 129986, 130022, 130023, 183, + 8943, 129686, 127894, 127756, 8357, 128189, 128469, 128656, 8722, 10793, + 10794, 10796, 10795, 10810, 8770, 8723, 10751, 129694, 129705, 128241, + 128242, 128244, 129339, 8871, 71232, 71229, 71236, 71231, 71230, 71216, + 71226, 71228, 71219, 71220, 71221, 71222, 71223, 71224, 71217, 71218, + 71225, 71227, 71234, 71233, 71253, 71252, 71255, 71254, 71251, 71250, + 71248, 71257, 71249, 71256, 71168, 71169, 71179, 71181, 71195, 71194, + 71200, 71199, 71193, 71192, 71198, 71197, 71174, 71175, 71176, 71177, + 71210, 71172, 71173, 71170, 71171, 71215, 71209, 71186, 71196, 71191, + 71201, 71211, 71212, 71213, 71205, 71204, 71188, 71187, 71185, 71184, + 71190, 71189, 71183, 71182, 71203, 71202, 71214, 71206, 71208, 71207, + 71178, 71180, 71235, 43867, 67512, 714, 700, 67509, 761, 763, 7470, 7471, + 7487, 7474, 7483, 7476, 43000, 7484, 7485, 7468, 7469, 42994, 7472, 7473, + 42995, 7475, 7477, 7478, 7479, 7480, 7481, 7482, 7486, 42996, 42993, + 7488, 7489, 11389, 7490, 723, 722, 42755, 42753, 42757, 42759, 42754, + 42752, 42756, 42758, 42652, 122956, 122958, 122929, 122954, 122932, + 122952, 122943, 122987, 122946, 122938, 122939, 122942, 122960, 122941, + 122959, 122989, 122955, 122950, 122948, 122944, 122951, 122988, 122953, + 122934, 122935, 122936, 122933, 122949, 122931, 122957, 122930, 122947, + 122937, 122928, 122940, 122945, 42653, 7544, 710, 735, 42889, 67510, + 42776, 42775, 42777, 750, 698, 725, 709, 984011, 42765, 42760, 42770, + 741, 984012, 42769, 42764, 42774, 745, 762, 764, 715, 704, 67507, 4348, + 42766, 42761, 42771, 742, 721, 67511, 42888, 42768, 42763, 751, 767, 753, + 42773, 717, 754, 755, 744, 759, 719, 718, 42783, 752, 716, 42778, 703, + 43882, 706, 713, 42767, 42762, 42772, 743, 758, 757, 756, 727, 766, 726, + 697, 42780, 42782, 42781, 42779, 760, 705, 67508, 701, 67513, 702, 43883, + 707, 734, 42890, 765, 7491, 7493, 7516, 67459, 7495, 7601, 7509, 67461, + 7517, 7580, 7590, 694, 7591, 67474, 67476, 7595, 67484, 67491, 67456, + 67460, 67478, 7600, 67498, 7608, 67506, 67471, 67492, 7581, 7521, 7496, + 67468, 67469, 67467, 67466, 7519, 7585, 67480, 67463, 67465, 67464, 7611, + 7613, 7612, 7497, 7604, 7582, 7614, 7505, 7584, 67472, 7501, 7518, 7520, + 67475, 736, 688, 689, 67477, 43868, 67479, 7504, 7596, 7588, 7589, 690, + 7592, 737, 43869, 43870, 7593, 67485, 7594, 67483, 67481, 67482, 67486, + 67487, 43001, 7599, 7598, 7506, 67490, 7499, 7507, 7510, 7602, 691, + 67497, 67496, 67473, 740, 7583, 67470, 738, 67514, 7603, 7586, 7498, + 7513, 7511, 7605, 67503, 67499, 67502, 7508, 67500, 67501, 7492, 7579, + 7494, 7514, 7597, 7500, 692, 67494, 67495, 693, 67488, 67489, 7587, 7502, + 7610, 43881, 7615, 7512, 43871, 7606, 7607, 7515, 67504, 7609, 7503, + 67493, 695, 739, 696, 42784, 42785, 67458, 67457, 720, 699, 724, 708, + 749, 42864, 748, 712, 747, 746, 10762, 128184, 128176, 129297, 71266, + 6165, 6164, 6167, 6166, 6163, 6162, 6160, 6169, 6161, 6168, 6159, 6157, + 6156, 6155, 6147, 6149, 71271, 71272, 6176, 6279, 6272, 6295, 6273, 6289, + 6274, 6313, 6286, 6311, 6310, 6280, 6276, 6275, 6282, 6287, 6278, 6285, + 6284, 6288, 6277, 6291, 6290, 6293, 6294, 6292, 6283, 6281, 6185, 6196, + 6264, 6210, 6190, 6303, 6305, 6307, 6300, 6302, 6304, 6312, 6298, 6301, + 6314, 6308, 6309, 6299, 6306, 6263, 6262, 6260, 6261, 6259, 6244, 6252, + 6245, 6253, 6254, 6248, 6238, 6239, 6257, 6247, 6256, 6242, 6258, 6255, + 6241, 6240, 6249, 6251, 6250, 6243, 6246, 6237, 6193, 6192, 6297, 6296, + 6218, 6236, 6225, 6234, 6227, 6235, 6211, 6222, 6232, 6228, 6224, 6226, + 6233, 6214, 6216, 6215, 6217, 6219, 6231, 6223, 6220, 6221, 6230, 6229, + 6212, 6213, 6204, 6194, 6209, 6207, 6205, 6206, 6203, 6202, 6208, 6191, + 6177, 6183, 6179, 6181, 6180, 6182, 6186, 6195, 6201, 6189, 6197, 6184, + 6187, 6188, 6199, 6200, 6198, 6178, 71273, 71275, 71274, 6151, 71265, + 71270, 71269, 6144, 71268, 71264, 71267, 71276, 6150, 6158, 6148, 6146, + 6152, 6153, 6154, 6145, 9866, 9867, 119552, 9101, 128669, 128018, 128053, + 127889, 129390, 118261, 128496, 129742, 129439, 128332, 129334, 128741, + 128757, 129468, 128739, 9968, 128670, 128672, 128693, 128507, 128001, + 129700, 128045, 128068, 128511, 127909, 92748, 92744, 92761, 92750, + 92739, 92751, 92737, 92754, 92749, 92753, 92743, 92752, 92757, 92766, + 92736, 92741, 92746, 92764, 92745, 92765, 92755, 92756, 92763, 92762, + 92747, 92760, 92758, 92738, 92740, 92759, 92742, 92783, 92782, 92773, + 92772, 92775, 92774, 92771, 92770, 92768, 92777, 92769, 92776, 70291, + 70292, 70290, 70297, 70296, 70293, 70287, 70298, 70312, 70311, 70306, + 70285, 70284, 70289, 70288, 70295, 70294, 70303, 70301, 70283, 70282, + 70280, 70278, 70277, 70276, 70300, 70299, 70310, 70307, 70304, 70309, + 70308, 70305, 70272, 70275, 70273, 70274, 70313, 127926, 215, 10804, + 10805, 10807, 10811, 10801, 10800, 10005, 8844, 8845, 8846, 8888, 127812, + 117860, 9838, 9839, 9837, 127929, 127896, 119161, 119159, 119155, 119157, + 119061, 119060, 119224, 119235, 119132, 119058, 119059, 119255, 119253, + 119130, 119131, 119163, 119169, 119149, 119167, 119168, 119210, 119178, + 119173, 119211, 119150, 119151, 119152, 119153, 119154, 119175, 119212, + 119213, 119166, 119164, 119141, 119142, 119176, 119179, 119143, 119144, + 119145, 119165, 119177, 119170, 119174, 119092, 119052, 119247, 119186, + 119073, 119109, 119093, 119050, 119220, 119221, 119044, 119049, 119187, + 119209, 119082, 119041, 119083, 119077, 119078, 119162, 119160, 119208, + 119156, 119158, 119136, 119102, 119056, 119057, 119146, 119147, 119148, + 119042, 119066, 119065, 119069, 119185, 119074, 119075, 119076, 119231, + 119232, 119085, 119084, 119070, 119071, 119072, 119218, 119217, 119189, + 119188, 119248, 119249, 119172, 119171, 119216, 119134, 119100, 119206, + 119262, 119270, 119271, 119263, 119268, 119269, 119272, 119264, 119267, + 119266, 119265, 119274, 119223, 119234, 119233, 119046, 119222, 119184, + 119227, 119237, 119228, 119122, 119123, 119081, 119098, 119207, 119129, + 119087, 119086, 119128, 119140, 119106, 119062, 119195, 119204, 119205, + 119196, 119197, 119198, 119199, 119200, 119201, 119202, 119203, 119094, + 119095, 119126, 119108, 119215, 119214, 119261, 119252, 119257, 119258, + 119183, 119090, 119091, 119135, 119101, 119096, 119097, 119053, 119054, + 119055, 119048, 119043, 119047, 119180, 119254, 119259, 119225, 119236, + 119226, 119229, 119238, 119230, 119051, 119045, 119089, 119088, 119040, + 119067, 119068, 119137, 119103, 119139, 119105, 119110, 119111, 119250, + 119181, 119273, 119243, 119244, 119245, 119246, 119242, 119240, 119239, + 119241, 119064, 119138, 119104, 119063, 119256, 119260, 119190, 119118, + 119119, 119120, 119121, 119112, 119113, 119116, 119117, 119114, 119115, + 119124, 119125, 119191, 119193, 119194, 119127, 119251, 119107, 119133, + 119099, 119219, 119192, 119182, 127932, 127925, 8811, 8810, 4158, 4156, + 4157, 4155, 4192, 4191, 4190, 4226, 4129, 43642, 4138, 4135, 4208, 4207, + 4206, 4159, 4099, 4098, 4097, 43625, 43624, 43626, 43623, 43622, 43621, + 43627, 43618, 43617, 43630, 43629, 43620, 43619, 983244, 43631, 43616, + 43635, 43628, 43633, 43634, 4096, 4188, 4189, 4187, 4186, 4136, 4121, + 4106, 4111, 4100, 4105, 4116, 4238, 4123, 4176, 43491, 4218, 4220, 43490, + 4221, 4224, 43492, 4223, 43489, 4216, 43488, 4215, 4214, 4213, 4219, + 4222, 4225, 4217, 4130, 43646, 43647, 4193, 4177, 4126, 4112, 43503, + 43495, 43502, 43501, 43516, 43515, 43518, 43517, 43498, 43497, 43500, + 43499, 43514, 43496, 4108, 4107, 4113, 4198, 4197, 4125, 4110, 4109, + 4115, 4114, 4133, 4134, 4178, 4179, 4180, 4181, 4131, 4132, 4128, 4124, + 4120, 4119, 4102, 4101, 4104, 4103, 4118, 4117, 4127, 4122, 4137, 43636, + 43637, 43638, 43632, 43494, 4245, 4244, 4247, 4246, 4243, 4242, 4240, + 4249, 4241, 4248, 4154, 4150, 4250, 4251, 4237, 4235, 4236, 4231, 4232, + 4233, 4234, 43493, 4171, 43644, 43645, 4201, 4202, 4203, 4204, 4205, + 4151, 4239, 43643, 4170, 4153, 4152, 43639, 43641, 43640, 4174, 4172, + 4255, 4254, 4175, 4173, 71391, 71390, 71393, 71392, 71389, 71388, 71386, + 71395, 71387, 71394, 4195, 4196, 43509, 43508, 43511, 43510, 43507, + 43506, 43504, 43513, 43505, 43512, 4146, 4252, 4253, 4140, 4209, 4212, + 4210, 4211, 4147, 4148, 4228, 4229, 4230, 4227, 4194, 4145, 4149, 4199, + 4200, 4139, 4143, 4144, 4182, 4183, 4184, 4185, 4141, 4142, 71381, 71380, + 71383, 71382, 71379, 71378, 71376, 71385, 71377, 71384, 4165, 4164, 4167, + 4166, 4163, 4162, 4160, 4169, 4161, 4168, 983218, 983232, 983174, 10753, + 10754, 10752, 8720, 10761, 10757, 10758, 8721, 8899, 10756, 10755, 11007, + 8896, 8897, 8898, 8719, 67712, 67728, 67740, 67724, 67726, 67714, 67732, + 67718, 67730, 67723, 67742, 67717, 67729, 67738, 67739, 67713, 67735, + 67716, 67721, 67734, 67737, 67741, 67725, 67719, 67722, 67727, 67715, + 67733, 67720, 67736, 67731, 67758, 67752, 67753, 67757, 67751, 67759, + 67756, 67754, 67755, 8711, 124117, 124120, 124119, 124121, 124118, + 124132, 124136, 124133, 124138, 124137, 124134, 124135, 124122, 124124, + 124126, 124123, 124125, 124112, 124116, 124114, 124113, 124115, 124127, + 124128, 124129, 124130, 124131, 124140, 124143, 124142, 124139, 124141, + 124149, 124148, 124151, 124150, 124147, 124146, 124144, 124153, 124145, + 124152, 128133, 8358, 8892, 72102, 72103, 72138, 72096, 72097, 72107, + 72109, 72123, 72122, 72128, 72127, 72144, 72136, 72121, 72120, 72126, + 72125, 72100, 72101, 72098, 72099, 72143, 72137, 72114, 72124, 72119, + 72129, 72139, 72140, 72141, 72133, 72132, 72116, 72115, 72113, 72112, + 72118, 72117, 72111, 72110, 72131, 72130, 72142, 72134, 72135, 72106, + 72108, 72162, 72161, 72158, 72160, 72159, 72164, 72150, 72151, 72145, + 72155, 72157, 72148, 72149, 72146, 72147, 72154, 72156, 72163, 8302, + 127966, 129314, 128219, 129535, 8239, 983092, 983197, 983128, 9471, 9453, + 9460, 9452, 9458, 9451, 9454, 9455, 9459, 9456, 9457, 127312, 127313, + 127314, 127315, 127316, 127317, 127318, 127319, 127320, 127321, 127322, + 127323, 127324, 127325, 127326, 127327, 127328, 127329, 127330, 127331, + 127332, 127333, 127334, 127335, 127336, 127337, 128982, 128984, 129982, + 129981, 129983, 127344, 127345, 127346, 127347, 127348, 127349, 127350, + 127351, 127352, 127353, 127354, 127355, 127356, 127357, 127358, 127359, + 127360, 127361, 127362, 127363, 127364, 127365, 127366, 127367, 127368, + 127369, 129204, 129205, 129207, 129988, 10062, 127374, 127371, 127375, + 129206, 127372, 127373, 983091, 8879, 8840, 8841, 8775, 8821, 8817, 8825, + 8820, 8816, 8824, 129670, 129722, 11228, 129540, 129544, 129565, 129586, + 129603, 129607, 129561, 129536, 129557, 129599, 129539, 129560, 129602, + 129610, 129613, 129541, 129562, 129604, 129537, 129558, 129600, 129538, + 129559, 129601, 129581, 129578, 129582, 129583, 129579, 129580, 128528, + 9906, 127770, 127761, 8362, 6595, 6594, 6599, 6598, 6597, 6596, 6593, + 6566, 6530, 6567, 6531, 6570, 6537, 6532, 6544, 6543, 6536, 6542, 6549, + 6548, 6562, 6561, 6554, 6560, 6556, 6550, 6528, 6555, 6538, 6568, 6533, + 6569, 6534, 6571, 6540, 6535, 6547, 6546, 6539, 6545, 6552, 6551, 6565, + 6564, 6557, 6563, 6559, 6553, 6529, 6558, 6541, 6622, 6623, 6600, 6601, + 6618, 6577, 6587, 6582, 6586, 6578, 6592, 6583, 6584, 6590, 6589, 6579, + 6585, 6591, 6580, 6588, 6576, 6581, 6613, 6612, 6615, 6614, 6611, 6610, + 6608, 6617, 6609, 6616, 983063, 70732, 70746, 70731, 70741, 70740, 70743, + 70742, 70739, 70738, 70736, 70745, 70737, 70744, 70734, 70675, 70674, + 70681, 70680, 70692, 70686, 70691, 70751, 70662, 70663, 70664, 70665, + 70656, 70657, 70667, 70669, 70685, 70684, 70690, 70689, 70683, 70682, + 70688, 70687, 70660, 70661, 70658, 70659, 70705, 70706, 70707, 70696, + 70695, 70677, 70676, 70673, 70672, 70679, 70678, 70671, 70670, 70703, + 70702, 70698, 70697, 70694, 70693, 70701, 70700, 70708, 70704, 70699, + 70666, 70668, 70723, 70726, 70727, 70724, 70752, 70728, 70753, 70722, + 70725, 70730, 70750, 70747, 70709, 70719, 70721, 70712, 70713, 70714, + 70715, 70716, 70717, 70710, 70711, 70718, 70720, 70735, 70749, 70733, + 70729, 11154, 11155, 128240, 9112, 983131, 9798, 11209, 128084, 129299, + 983132, 128985, 129399, 127747, 2035, 2031, 2032, 2033, 2030, 2034, 2027, + 2028, 2029, 2040, 2045, 2046, 1989, 1988, 1991, 1990, 1987, 1986, 1984, + 1993, 1985, 1992, 2042, 2008, 2001, 2025, 2024, 2026, 2006, 2002, 2019, + 2016, 2018, 2023, 2010, 2009, 2000, 1999, 2007, 1997, 1995, 2012, 2003, + 2013, 2020, 2014, 2015, 2017, 2004, 2011, 2005, 2021, 2022, 1994, 1996, + 1998, 2037, 2036, 2039, 2038, 2041, 2047, 983127, 128691, 9940, 128683, + 128695, 128370, 128286, 128245, 128685, 8303, 65934, 8209, 128689, 10973, + 8893, 8599, 10542, 10545, 10536, 10532, 129209, 10530, 128602, 128594, + 128610, 11111, 11127, 11016, 8663, 129109, 11008, 43063, 43062, 43065, + 43064, 43059, 43060, 43057, 43056, 43061, 43058, 10529, 8598, 8689, 8632, + 10546, 10535, 10531, 129208, 128600, 128592, 128608, 11110, 11126, 11017, + 8662, 129108, 11009, 128746, 8882, 8884, 8379, 8836, 8837, 8713, 8772, + 8777, 8938, 8940, 8742, 8930, 8931, 172, 8877, 8769, 8813, 8800, 8802, + 8815, 8814, 9083, 128323, 10159, 128324, 10161, 128456, 128457, 128458, + 128211, 128212, 128067, 118012, 160, 9369, 9362, 9365, 9366, 9367, 35, + 9368, 9364, 9361, 9363, 9371, 9370, 8470, 128297, 94177, 983041, 983040, + 123149, 123155, 123138, 123166, 123164, 123148, 123143, 123161, 123153, + 123152, 123141, 123137, 123156, 123139, 123163, 123142, 123172, 123173, + 123140, 123167, 123171, 123158, 123176, 123177, 123165, 123151, 123168, + 123136, 123169, 123162, 123178, 123179, 123144, 123157, 123170, 123150, + 123145, 123159, 123146, 123154, 123160, 123147, 123174, 123175, 123180, + 123214, 123193, 123192, 123195, 123194, 123191, 123196, 123197, 123184, + 123190, 123189, 123186, 123185, 123188, 123187, 123215, 123205, 123204, + 123207, 123206, 123203, 123202, 123200, 123209, 123201, 123208, 117776, + 983231, 983066, 10663, 10662, 11869, 9215, 65532, 9287, 9286, 9284, 9285, + 9289, 9281, 9290, 9288, 9282, 9283, 9280, 128721, 128025, 128885, 5787, + 5788, 5776, 5761, 5786, 5770, 5769, 5781, 5779, 5785, 5763, 5772, 5780, + 5784, 5762, 5775, 5773, 5765, 5777, 5782, 5764, 5774, 5783, 5766, 5778, + 5771, 5767, 5768, 5760, 731, 128738, 7265, 7264, 7266, 7267, 7261, 7260, + 7262, 7259, 7280, 7282, 7281, 7279, 7271, 7270, 7272, 7269, 7258, 7263, + 7278, 7268, 7283, 7273, 7284, 7285, 7287, 7286, 7276, 7274, 7275, 7277, + 7290, 7288, 7289, 7295, 7294, 7292, 7291, 7253, 7252, 7255, 7254, 7251, + 7250, 7248, 7257, 7249, 7256, 7293, 124374, 124376, 124375, 124377, + 124378, 124379, 124392, 124396, 124395, 124397, 124394, 124393, 124380, + 124381, 124383, 124384, 124385, 124382, 124368, 124371, 124370, 124369, + 124372, 124373, 124386, 124388, 124390, 124389, 124387, 124391, 124399, + 124400, 124398, 124415, 124406, 124405, 124408, 124407, 124404, 124403, + 124401, 124410, 124402, 124409, 94179, 94178, 68736, 68739, 68744, 68737, + 68756, 68745, 68760, 68769, 68761, 68775, 68785, 68741, 68762, 68772, + 68773, 68740, 68777, 68742, 68749, 68750, 68758, 68759, 68774, 68776, + 68783, 68784, 68738, 68743, 68747, 68748, 68751, 68754, 68755, 68768, + 68770, 68782, 68765, 68780, 68766, 68781, 68763, 68767, 68764, 68771, + 68778, 68757, 68786, 68779, 68746, 68752, 68753, 68800, 68803, 68808, + 68801, 68820, 68809, 68824, 68833, 68825, 68839, 68849, 68805, 68826, + 68836, 68837, 68804, 68841, 68806, 68813, 68814, 68822, 68823, 68838, + 68840, 68847, 68848, 68802, 68807, 68811, 68812, 68815, 68818, 68819, + 68832, 68834, 68846, 68829, 68844, 68830, 68845, 68827, 68831, 68828, + 68835, 68842, 68821, 68850, 68843, 68810, 68816, 68817, 68861, 68859, + 68858, 68862, 68863, 68860, 66308, 66324, 66318, 66335, 66323, 66331, + 66327, 66330, 66315, 66316, 66317, 66329, 66314, 66306, 66322, 66351, + 66321, 66350, 66326, 66334, 66313, 66333, 66328, 66320, 66312, 66325, + 66332, 66305, 66307, 66311, 66309, 66349, 66310, 66304, 66319, 66339, + 66337, 66338, 66336, 68241, 68242, 68246, 68244, 68226, 68224, 68237, + 68235, 68249, 68251, 68247, 68233, 68248, 68252, 68227, 68234, 68230, + 68239, 68232, 68240, 68231, 68250, 68236, 68225, 68243, 68245, 68228, + 68229, 68238, 68255, 68254, 68253, 66404, 66390, 66392, 66387, 66388, + 66411, 66393, 66421, 66418, 66396, 66397, 66399, 66406, 66405, 66401, + 66413, 66402, 66398, 66414, 66415, 66416, 66408, 66420, 66417, 66407, + 66419, 66389, 66391, 66395, 66400, 66386, 66409, 66410, 66385, 66384, + 66394, 66412, 66403, 66516, 66514, 66515, 66517, 66513, 66464, 66504, + 66505, 66506, 66482, 66510, 66511, 66477, 66508, 66509, 66478, 66479, + 66473, 66474, 66490, 66491, 66480, 66475, 66476, 66507, 66471, 66469, + 66470, 66467, 66468, 66484, 66485, 66492, 66493, 66486, 66487, 66488, + 66497, 66498, 66495, 66472, 66483, 66499, 66494, 66481, 66489, 66496, + 66465, 66466, 66512, 128435, 118450, 69414, 69395, 69376, 69394, 69391, + 69392, 69398, 69399, 69403, 69404, 69377, 69379, 69382, 69400, 69388, + 69380, 69384, 69393, 69397, 69401, 69386, 69381, 69385, 69387, 69378, + 69390, 69402, 69383, 69396, 69389, 69415, 69407, 69412, 69411, 69406, + 69410, 69405, 69413, 69409, 69408, 68209, 68210, 68217, 68211, 68213, + 68214, 68212, 68203, 68205, 68207, 68206, 68202, 68198, 68220, 68219, + 68215, 68201, 68216, 68193, 68196, 68199, 68218, 68192, 68194, 68200, + 68204, 68197, 68208, 68195, 68222, 68221, 68223, 68608, 68619, 68627, + 68623, 68634, 68640, 68644, 68668, 68670, 68677, 68632, 68669, 68671, + 68617, 68625, 68621, 68638, 68643, 68660, 68666, 68675, 68630, 68648, + 68653, 68646, 68650, 68641, 68673, 68658, 68642, 68655, 68628, 68611, + 68657, 68662, 68614, 68615, 68636, 68656, 68664, 68679, 68680, 68609, + 68610, 68645, 68654, 68620, 68624, 68635, 68678, 68633, 68672, 68652, + 68618, 68626, 68622, 68639, 68661, 68667, 68676, 68631, 68613, 68649, + 68647, 68651, 68674, 68659, 68629, 68612, 68663, 68616, 68637, 68665, + 69509, 69508, 69507, 69506, 69488, 69502, 69496, 69505, 69492, 69499, + 69501, 69503, 69494, 69493, 69490, 69495, 69489, 69498, 69504, 69491, + 69500, 69497, 69511, 69512, 69513, 69510, 128477, 128117, 129491, 128116, + 129746, 128283, 128664, 128753, 128662, 128660, 128653, 11819, 8228, + 128431, 129649, 129477, 128214, 9251, 10044, 10027, 10034, 10011, 128194, + 128449, 128080, 128237, 128236, 10180, 10179, 128275, 9103, 9104, 10174, + 983191, 8997, 128191, 128440, 9934, 9741, 128217, 129505, 129447, 128895, + 129741, 8886, 2902, 2903, 2933, 2934, 2931, 2930, 2935, 2932, 2928, 2909, + 2908, 2864, 2911, 2863, 2821, 2822, 2832, 2836, 2850, 2849, 2855, 2854, + 2848, 2847, 2853, 2852, 2827, 2912, 2828, 2913, 2869, 2825, 2826, 2823, + 2824, 2867, 2866, 2841, 2851, 2846, 2856, 2870, 2871, 2872, 2861, 2860, + 2843, 2842, 2840, 2839, 2845, 2844, 2838, 2837, 2859, 2858, 2873, 2862, + 2929, 2831, 2835, 983660, 983659, 2817, 2876, 2877, 2818, 2901, 2893, + 2819, 2878, 2888, 2892, 2881, 2882, 2883, 2884, 2914, 2915, 2879, 2880, + 2887, 2891, 2923, 2922, 2925, 2924, 2921, 2920, 2918, 2927, 2919, 2926, + 64830, 64831, 9766, 117826, 10183, 66736, 66737, 66738, 66739, 66743, + 66763, 66761, 66742, 66749, 66757, 66744, 66768, 66750, 66748, 66754, + 66755, 66764, 66762, 66760, 66746, 66745, 66741, 66765, 66769, 66759, + 66758, 66771, 66770, 66740, 66751, 66752, 66753, 66756, 66767, 66747, + 66766, 66776, 66777, 66778, 66779, 66783, 66803, 66801, 66782, 66789, + 66797, 66784, 66808, 66790, 66788, 66794, 66795, 66804, 66802, 66800, + 66786, 66785, 66781, 66805, 66809, 66799, 66798, 66811, 66810, 66780, + 66791, 66792, 66793, 66796, 66807, 66787, 66806, 66710, 66688, 66715, + 66699, 66694, 66698, 66703, 66693, 66697, 66696, 66705, 66702, 66713, + 66717, 66704, 66706, 66707, 66711, 66716, 66689, 66701, 66700, 66708, + 66691, 66695, 66690, 66692, 66709, 66712, 66714, 66725, 66724, 66727, + 66726, 66723, 66722, 66720, 66729, 66721, 66728, 983192, 126257, 126264, + 126258, 126259, 126265, 126260, 126263, 126267, 126255, 126266, 126256, + 126262, 126261, 126269, 126268, 126254, 126216, 126225, 126252, 126234, + 126243, 126222, 126249, 126213, 126231, 126240, 126221, 126248, 126212, + 126230, 126239, 126217, 126226, 126253, 126235, 126244, 126215, 126224, + 126251, 126233, 126242, 126214, 126223, 126250, 126232, 126241, 126220, + 126247, 126211, 126229, 126238, 126219, 126246, 126210, 126228, 126237, + 126218, 126245, 126209, 126227, 126236, 129446, 128228, 117974, 117975, + 117976, 117977, 117978, 117979, 117980, 117981, 117982, 117983, 117984, + 117985, 117986, 117987, 117988, 117989, 117990, 117991, 117992, 117993, + 117994, 117995, 117996, 117997, 117998, 117999, 10015, 9885, 10029, + 10009, 118005, 118004, 118007, 118006, 118003, 118002, 118000, 118009, + 118001, 118008, 8485, 129397, 128471, 11195, 11194, 11196, 8254, 129450, + 127970, 118459, 8486, 128076, 127842, 128329, 129417, 128002, 983122, + 983121, 128463, 128195, 128479, 128196, 128223, 128464, 128724, 93059, + 93065, 93064, 93058, 93070, 93056, 93055, 93053, 93062, 93069, 93061, + 93066, 93071, 93068, 93054, 93057, 93063, 93067, 93060, 92967, 92975, + 92965, 92969, 92959, 92968, 92971, 92957, 92962, 92960, 92972, 92970, + 92963, 92958, 92966, 92961, 92956, 92974, 92964, 92973, 92979, 92978, + 92980, 92977, 92976, 92982, 92981, 93023, 93020, 93024, 93021, 93019, + 93025, 93022, 93043, 92985, 93047, 93044, 93045, 92997, 93046, 93042, + 93032, 93029, 92995, 93038, 92993, 93041, 93035, 93033, 93037, 93030, + 93039, 92987, 92992, 92986, 92983, 92984, 93027, 92994, 93034, 92988, + 92990, 92989, 92991, 93028, 92996, 93031, 93040, 93036, 92954, 92955, + 92938, 92939, 92932, 92933, 92942, 92943, 92950, 92951, 92928, 92929, + 92936, 92937, 92948, 92949, 92930, 92931, 92944, 92945, 92934, 92935, + 92940, 92941, 92946, 92947, 92952, 92953, 93013, 93012, 93015, 93014, + 93011, 93010, 93008, 93017, 93009, 93016, 9908, 11801, 127796, 129779, + 129780, 67703, 67693, 67688, 67702, 67683, 67691, 67699, 67700, 67680, + 67696, 67682, 67686, 67695, 67698, 67701, 67689, 67684, 67687, 67690, + 67681, 67694, 67685, 67697, 67692, 67704, 67711, 67706, 67707, 67710, + 67709, 67708, 67705, 129330, 129374, 128060, 8233, 11853, 11791, 10995, + 10994, 8741, 129666, 12809, 12823, 12808, 12822, 12828, 12813, 12827, + 12810, 12824, 12800, 12814, 12804, 12818, 12801, 12815, 12812, 12826, + 12805, 12819, 12803, 12817, 12806, 12820, 12811, 12825, 12802, 12816, + 12807, 12821, 12863, 12855, 12858, 12861, 12847, 12839, 12854, 12843, + 12836, 12864, 12835, 12856, 12846, 12842, 12840, 12852, 12862, 12865, + 12857, 12867, 12838, 12866, 12851, 12853, 12859, 12849, 12860, 12848, + 12837, 12834, 12841, 12833, 12845, 12844, 12850, 12832, 12830, 12829, + 9349, 9342, 9345, 9346, 9350, 9347, 9348, 9344, 9351, 9343, 9341, 9336, + 9335, 9338, 9337, 9334, 9333, 9340, 9332, 9339, 127248, 127249, 127250, + 127251, 127252, 127253, 127254, 127255, 127256, 127257, 127258, 127259, + 127260, 127261, 127262, 127263, 127264, 127265, 127266, 127267, 127268, + 127269, 127270, 127271, 127272, 127273, 9372, 9373, 9374, 9375, 9376, + 9377, 9378, 9379, 9380, 9381, 9382, 9383, 9384, 9385, 9386, 9387, 9388, + 9389, 9390, 9391, 9392, 9393, 9394, 9395, 9396, 9397, 8706, 983147, + 983146, 983149, 983150, 9853, 127881, 118468, 128890, 12880, 12349, + 129436, 128755, 11261, 9105, 9106, 128706, 72437, 72440, 72432, 72416, + 72419, 72413, 72417, 72415, 72412, 72414, 72418, 72420, 72403, 72407, + 72411, 72409, 72410, 72391, 72400, 72404, 72397, 72394, 72385, 72401, + 72384, 72399, 72398, 72396, 72388, 72393, 72392, 72386, 72387, 72402, + 72395, 72390, 72389, 72405, 72406, 72408, 72436, 72435, 72438, 72439, + 72422, 72421, 72424, 72425, 72431, 72433, 72434, 72428, 72427, 72429, + 72430, 72423, 72426, 128062, 128230, 128206, 983228, 983237, 129434, + 9774, 127825, 129372, 129755, 127824, 128039, 128532, 9956, 128390, 9999, + 8240, 8241, 8524, 10178, 10977, 129336, 129496, 129494, 128113, 9977, + 128590, 129733, 128591, 129493, 128589, 128588, 129495, 128583, 128187, + 8966, 128547, 37, 9854, 127917, 8359, 8369, 129515, 128694, 129730, + 43101, 43117, 43120, 43076, 43123, 43077, 43115, 43090, 43082, 43094, + 43098, 43099, 43119, 43118, 43109, 43074, 43075, 43116, 43079, 43083, + 43089, 43088, 43114, 43113, 43081, 43080, 43073, 43072, 43085, 43084, + 43092, 43093, 43104, 43110, 43086, 43108, 43100, 43078, 43097, 43087, + 43106, 43096, 43091, 43107, 43095, 43102, 43105, 43103, 43127, 43126, + 43124, 43121, 43111, 43112, 43122, 43125, 66033, 66023, 66017, 66010, + 66027, 66003, 66018, 66028, 66004, 66012, 66022, 66020, 66045, 66019, + 66031, 66041, 66007, 66006, 66025, 66026, 66038, 66016, 66013, 66014, + 66000, 66001, 66034, 66036, 66037, 66029, 66011, 66024, 66015, 66021, + 66042, 66043, 66002, 66008, 66032, 66005, 66044, 66040, 66039, 66030, + 66009, 66035, 5941, 5942, 67840, 67855, 67843, 67844, 67847, 67858, + 67857, 67860, 67854, 67861, 67848, 67845, 67846, 67849, 67859, 67842, + 67850, 67853, 67851, 67841, 67856, 67852, 67864, 67866, 67867, 67863, + 67862, 67865, 67871, 11227, 9935, 128763, 128022, 128061, 128055, 128169, + 182, 128138, 129292, 129295, 127885, 127821, 10031, 129655, 129669, 9811, + 128299, 8916, 10970, 129383, 8984, 128720, 129703, 8462, 8463, 128733, + 127183, 127136, 127167, 127199, 127188, 127140, 127156, 127172, 127200, + 127189, 127141, 127157, 127173, 127196, 127148, 127164, 127180, 127198, + 127150, 127166, 127182, 127192, 127144, 127160, 127176, 127191, 127143, + 127159, 127175, 127190, 127142, 127158, 127174, 127197, 127149, 127165, + 127181, 127194, 127146, 127162, 127178, 127187, 127139, 127155, 127171, + 127186, 127138, 127154, 127170, 127202, 127220, 127221, 127201, 127210, + 127211, 127212, 127213, 127214, 127215, 127216, 127217, 127218, 127219, + 127203, 127204, 127205, 127206, 127207, 127208, 127209, 127185, 127137, + 127153, 127169, 127193, 127145, 127161, 127177, 127195, 127147, 127163, + 127179, 983151, 43, 10797, 10798, 10809, 10789, 10786, 10791, 10790, + 10788, 10792, 10787, 10866, 177, 9799, 11222, 11221, 11220, 11219, + 129696, 983148, 117777, 128659, 128680, 128110, 8297, 8236, 127871, + 128254, 11239, 128239, 12306, 12320, 128238, 8982, 128688, 129364, + 127858, 129716, 127831, 129751, 128574, 128545, 163, 128093, 9212, 9213, + 9214, 9211, 128041, 128425, 129328, 129732, 129731, 65043, 65040, 65045, + 65073, 65074, 65049, 65041, 65042, 65091, 65047, 65083, 65085, 65089, + 65079, 65087, 65077, 65095, 65081, 65075, 65084, 65086, 65092, 983261, + 65048, 65090, 65080, 65088, 65078, 65096, 65082, 65076, 65044, 65072, + 65046, 8478, 8826, 10937, 10933, 10927, 10929, 10935, 10931, 8936, 8830, + 8828, 8880, 9111, 129384, 9113, 128424, 128438, 129332, 128120, 983193, + 983166, 983163, 983164, 983167, 8242, 8965, 8759, 8733, 8522, 11224, + 128711, 129455, 128255, 68507, 68508, 68480, 68483, 68490, 68491, 68485, + 68482, 68486, 68493, 68495, 68496, 68488, 68484, 68487, 68489, 68481, + 68492, 68497, 68494, 68526, 68522, 68523, 68525, 68521, 68527, 68524, + 68505, 68506, 118473, 11854, 8200, 128156, 128091, 128686, 128204, + 128226, 983165, 983168, 983194, 9624, 9625, 9626, 9627, 9628, 9629, 9630, + 9631, 9622, 9623, 10764, 8279, 10774, 9833, 128894, 8264, 63, 8799, 34, + 9915, 127949, 127950, 129437, 128251, 9762, 128280, 9143, 128740, 128643, + 9926, 127752, 11827, 11783, 11782, 9995, 128400, 128406, 127338, 127339, + 127340, 129996, 11787, 9994, 11828, 129306, 128000, 8758, 128007, 128048, + 129682, 128015, 129534, 117778, 9852, 9843, 9844, 9845, 9846, 9847, 9848, + 9849, 9850, 983113, 128665, 127822, 129511, 174, 127462, 127463, 127464, 127465, 127466, 127467, 127468, 127469, 127470, 127471, 127472, 127473, 127474, 127475, 127476, 127477, 127478, 127479, 127480, 127481, 127482, 127483, 127484, 127485, 127486, 127487, 43344, 43343, 43346, 43345, @@ -13436,7 +12803,7 @@ static const unsigned int dawg_pos_to_codepoint[] = { }; #define DAWG_CODEPOINT_TO_POS_SHIFT 8 -#define DAWG_CODEPOINT_TO_POS_NOTFOUND 41412 +#define DAWG_CODEPOINT_TO_POS_NOTFOUND 35536 static const unsigned char dawg_codepoint_to_pos_index1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, @@ -13451,24 +12818,23 @@ static const unsigned char dawg_codepoint_to_pos_index1[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 66, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 52, 52, 52, 52, 52, 52, 52, 52, 52, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 136, 52, 52, 52, 52, 52, 52, 137, 138, 139, 140, 52, 141, 142, 143, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 144, 145, 146, 147, 148, 149, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 52, 52, 52, 52, 52, 52, 52, 52, 52, 110, 111, 112, + 113, 114, 115, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 116, 117, 118, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 119, 52, 52, 52, 52, + 52, 52, 120, 121, 122, 123, 52, 124, 125, 126, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 150, 151, 152, 153, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 154, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 52, 52, 52, 52, 170, 171, 172, 173, 52, 174, 175, 176, - 177, 178, 179, 52, 52, 180, 181, 182, 52, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 127, 128, 129, 52, 52, 130, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 131, 132, 133, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 134, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 52, + 52, 52, 52, 150, 151, 152, 153, 52, 154, 155, 156, 157, 158, 159, 52, 52, + 160, 161, 162, 52, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, @@ -13481,7 +12847,6 @@ static const unsigned char dawg_codepoint_to_pos_index1[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 195, 196, 197, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, @@ -13638,8 +13003,9 @@ static const unsigned char dawg_codepoint_to_pos_index1[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 198, 199, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 175, + 176, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, @@ -13652,8 +13018,8 @@ static const unsigned char dawg_codepoint_to_pos_index1[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 200, 201, 202, 203, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 177, 178, 179, 180, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, @@ -13681,221 +13047,216 @@ static const unsigned char dawg_codepoint_to_pos_index1[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, }; static const unsigned short dawg_codepoint_to_pos_index2[] = { - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 34311, 17490, 31931, 29628, 11221, 31502, 371, 1054, 24321, - 32155, 2570, 31753, 8585, 20621, 17673, 34150, 11004, 10989, 11001, - 10998, 10983, 10980, 10995, 10992, 11007, 10986, 8161, 32765, 24564, - 16926, 18304, 31929, 8584, 22906, 22952, 22962, 22978, 22995, 23040, - 23044, 23061, 23075, 23104, 23109, 23121, 23141, 23150, 23166, 23216, - 23225, 23228, 23249, 23273, 23302, 23341, 23352, 23361, 23364, 23378, - 24283, 32056, 32169, 6924, 25337, 18275, 23470, 23520, 23540, 23563, - 23599, 23658, 23666, 23684, 23703, 23740, 23746, 23760, 23799, 23812, - 23836, 23893, 23905, 23911, 23949, 23991, 24064, 24112, 24126, 24135, - 24143, 24159, 24224, 39287, 32118, 37693, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 29622, - 20975, 6233, 31795, 10083, 39859, 5039, 32747, 10971, 8779, 17569, 24331, - 29602, 34101, 31979, 27023, 10686, 31765, 34937, 34936, 4, 27754, 31650, - 27760, 6229, 34940, 25990, 32216, 39421, 39419, 39427, 20978, 22935, - 22936, 22924, 22938, 22917, 22919, 22940, 22963, 23026, 23027, 22998, - 23013, 23091, 23092, 23081, 23079, 23037, 23164, 23205, 23206, 23173, - 23191, 23180, 28467, 23189, 23333, 23334, 23303, 23306, 23373, 23294, - 23981, 23501, 23502, 23490, 23504, 23481, 23483, 23507, 23541, 23632, - 23633, 23602, 23617, 23721, 23722, 23704, 23706, 23657, 23831, 23875, - 23876, 23837, 23861, 23844, 11132, 23859, 24099, 24102, 24067, 24070, - 24154, 24013, 24145, 22922, 23488, 22907, 23471, 22932, 23498, 22967, - 23546, 22965, 23543, 22971, 23551, 22966, 23545, 22985, 23571, 22982, - 23565, 23016, 23621, 23029, 23635, 23008, 23612, 23023, 23629, 23007, - 23611, 23046, 23668, 23049, 23671, 23053, 23676, 23045, 23667, 23064, - 23687, 23071, 23696, 23085, 23718, 23083, 23713, 23094, 23724, 23088, - 23715, 23078, 23587, 23390, 24179, 23105, 23741, 23110, 23747, 23759, - 23135, 23777, 23131, 23764, 23133, 23767, 23128, 23774, 23130, 23785, - 23159, 23824, 23151, 23813, 23153, 23817, 23832, 23039, 23640, 23169, - 23854, 23208, 23878, 23186, 23850, 23391, 24182, 23237, 23928, 23229, - 23912, 23230, 23914, 23255, 23950, 23254, 23956, 23252, 23954, 23250, - 23952, 23274, 23992, 23277, 23996, 23284, 24008, 23330, 24096, 23322, - 24086, 23336, 24104, 23337, 24095, 23313, 24077, 23327, 24091, 23353, - 24127, 23365, 24144, 23366, 23381, 24160, 23384, 24166, 23380, 24163, - 23791, 23529, 22958, 22953, 23521, 23297, 24016, 23211, 22969, 23549, - 22944, 22990, 22986, 23566, 24021, 23246, 23272, 23210, 23041, 23661, - 23052, 23059, 23702, 23102, 23095, 23120, 23758, 23763, 23787, 23291, - 23157, 23818, 23172, 23198, 23868, 23213, 23890, 23222, 23901, 23467, - 23299, 24018, 23038, 23408, 24004, 23283, 24005, 23282, 23315, 24079, - 23340, 23345, 23370, 24149, 23387, 24169, 23031, 23033, 23650, 23655, - 23460, 23298, 24017, 23406, 23461, 23462, 23463, 23399, 23410, 22992, - 22980, 23593, 23140, 23129, 23798, 23165, 23154, 23835, 22930, 23496, - 23082, 23705, 23179, 23843, 23305, 24069, 23310, 24074, 23309, 24073, - 23307, 24071, 23308, 24072, 24053, 22918, 23482, 22914, 23478, 22942, - 23510, 23054, 23677, 23047, 23669, 23111, 23748, 23187, 23857, 23188, - 23858, 23032, 23652, 23743, 22991, 22979, 23592, 23048, 23670, 23073, - 23360, 23158, 23823, 22920, 23484, 22941, 23509, 23190, 23860, 22916, - 23480, 22937, 23503, 23012, 23616, 23028, 23634, 23076, 23712, 23093, - 23723, 23185, 23849, 23207, 23877, 23234, 23918, 23239, 23929, 23312, - 24076, 23335, 24103, 23253, 23955, 23276, 23994, 23377, 24158, 23065, - 23688, 23155, 23570, 23215, 23892, 23389, 24173, 22913, 23477, 22996, - 23600, 23181, 23845, 23194, 23864, 23182, 23846, 23183, 23847, 23374, - 24155, 23766, 23816, 23995, 23584, 23597, 23910, 22939, 22972, 23552, - 23123, 23278, 23963, 24168, 23055, 23678, 22959, 23339, 23293, 23030, - 23637, 23108, 23745, 23266, 23908, 23241, 23932, 23376, 24153, 24045, - 23512, 24046, 23528, 23881, 23544, 23567, 23575, 23941, 23972, 23976, - 23887, 23936, 23938, 23559, 23585, 23675, 23979, 23437, 23682, 23948, - 24022, 23695, 23701, 23725, 23736, 23415, 23772, 23761, 23780, 23788, - 24048, 24049, 23807, 23820, 23829, 23448, 23532, 23422, 23558, 23904, - 24033, 24036, 24039, 23923, 23925, 23919, 23939, 23424, 23416, 23969, - 23643, 23586, 23989, 23647, 24040, 24007, 24065, 24106, 24119, 24042, - 24057, 24050, 23455, 24172, 24162, 23649, 23651, 23464, 23407, 23404, - 23457, 23402, 23435, 23557, 23438, 23444, 23742, 24055, 23417, 23907, - 23465, 23409, 23594, 23580, 23595, 24060, 24009, 24059, 23664, 23795, - 23796, 23401, 23403, 24023, 24024, 28085, 28086, 28094, 28116, 28143, - 28146, 28041, 28163, 28165, 28014, 27957, 28171, 27867, 28022, 28024, - 28000, 27973, 28020, 28002, 28026, 28173, 27959, 27949, 6162, 28177, - 28003, 27866, 27972, 27998, 27989, 27995, 27994, 28170, 27980, 27901, - 27900, 28172, 27958, 28013, 28011, 5032, 11327, 32348, 30158, 34059, - 11386, 28027, 27950, 28084, 28096, 28123, 28164, 28120, 27964, 27979, - 28007, 27992, 27969, 28179, 28178, 28176, 28174, 27956, 27985, 27997, - 27987, 27990, 27991, 28010, 28009, 28008, 27993, 28019, 27869, 27970, - 27870, 27971, 28029, 28012, 27986, 8379, 8168, 8252, 8554, 8489, 8512, - 8178, 8278, 8274, 8393, 8538, 8288, 8184, 8570, 8310, 8311, 8186, 8396, - 8562, 8189, 8520, 8190, 8380, 8169, 8473, 8533, 8463, 8395, 8470, 8563, - 8314, 8517, 8500, 8516, 8521, 8281, 8275, 8537, 8191, 8254, 8510, 8569, - 8181, 8400, 8185, 8253, 8180, 8397, 8558, 8494, 8488, 8312, 8557, 8542, - 8486, 8541, 8485, 8528, 8398, 8546, 8551, 8582, 8571, 8298, 8381, 8170, - 8390, 8389, 8392, 8391, 8182, 8324, 8309, 8462, 8503, 8394, 8177, 8475, - 8565, 8385, 8524, 8471, 8326, 8581, 8464, 8525, 8523, 8529, 8280, 8174, - 8304, 8540, 8290, 8289, 8295, 8296, 8305, 8291, 8302, 8413, 8421, 8426, - 8434, 8437, 8419, 8451, 8453, 8455, 8440, 8443, 8458, 8459, 18489, 18753, - 18384, 18620, 18571, 18567, 18478, 18735, 41412, 41412, 18810, 18760, - 18761, 18759, 18815, 18492, 41412, 41412, 41412, 41412, 18775, 18505, - 18382, 18358, 18415, 18405, 18429, 41412, 18461, 41412, 18476, 18451, - 18667, 18361, 18488, 18486, 18484, 18406, 18490, 18385, 18482, 18416, - 18485, 18491, 18493, 18494, 18495, 18452, 18481, 18462, 41412, 18464, - 18483, 18467, 18479, 18487, 18480, 18431, 18421, 18472, 18617, 18632, - 18657, 18676, 18687, 18592, 18752, 18750, 18622, 18623, 18754, 18633, - 18747, 18658, 18698, 18755, 18756, 18757, 18758, 18725, 18738, 18739, - 18749, 18745, 18748, 18678, 18736, 18751, 18737, 18700, 18663, 18683, - 18734, 18696, 18724, 18500, 18812, 18771, 18779, 18777, 18778, 18587, - 18588, 18552, 18563, 18619, 18562, 18744, 18565, 18621, 18564, 18699, - 18561, 18742, 8660, 8754, 8638, 8732, 8634, 8728, 8632, 8726, 8630, 8724, - 8659, 8753, 8629, 8723, 18551, 18590, 18568, 18566, 18501, 18569, 18591, - 18466, 18746, 18496, 18465, 18743, 18589, 18498, 18499, 18497, 10350, - 10352, 10299, 10338, 10274, 10303, 10290, 10409, 10422, 10245, 10248, - 10262, 10377, 10347, 10390, 10307, 10275, 10291, 10423, 10332, 10311, - 10349, 10416, 10412, 10345, 10388, 10362, 10313, 10329, 10318, 10381, - 10249, 10324, 10327, 10259, 10269, 10331, 10339, 10265, 10292, 10395, - 10393, 10343, 10406, 10398, 10312, 10411, 10403, 10434, 10450, 10624, - 10491, 10470, 10508, 10617, 10613, 10504, 10566, 10521, 10472, 10488, - 10477, 10547, 10552, 10483, 10486, 10584, 10595, 10490, 10498, 10590, - 10451, 10573, 10571, 10502, 10607, 10576, 10471, 10612, 10604, 10509, - 10511, 10458, 10497, 10600, 10462, 10449, 10610, 10623, 10540, 10546, - 10587, 10536, 10506, 10568, 10466, 10382, 10548, 10405, 10606, 10358, - 10517, 10244, 10538, 10354, 10513, 10287, 10446, 10355, 10514, 10378, - 10537, 10252, 10556, 10421, 10622, 10360, 10519, 10361, 10520, 10273, - 10599, 10253, 10561, 10383, 10549, 10385, 10551, 10375, 10534, 10655, - 8245, 8239, 8242, 8240, 8241, 8195, 8248, 10389, 10567, 10402, 10580, - 10325, 10484, 10334, 10493, 10336, 10495, 10333, 10492, 10418, 10619, - 10414, 10615, 10363, 10522, 10365, 10524, 10366, 10525, 10285, 10444, - 10320, 10479, 10428, 10628, 10250, 10553, 10281, 10440, 10328, 10487, - 10261, 10586, 10400, 10578, 10401, 10579, 10340, 10499, 10427, 10627, - 10294, 10453, 10295, 10454, 10391, 10569, 10278, 10437, 10279, 10438, - 10431, 10419, 10620, 10364, 10523, 10316, 10475, 10323, 10482, 10322, - 10481, 10376, 10535, 10330, 10489, 10555, 10277, 10436, 10276, 10435, - 10426, 10626, 10351, 10510, 10386, 10564, 10387, 10565, 10417, 10618, - 10413, 10614, 10280, 10439, 10348, 10507, 10346, 10505, 10384, 10550, - 10283, 10442, 10284, 10443, 10326, 10485, 10272, 10598, 10271, 10597, - 10270, 10596, 10293, 10452, 10335, 10494, 10407, 10608, 10337, 10496, - 10341, 10500, 10342, 10501, 10369, 10528, 10368, 10527, 10374, 10533, - 10367, 10526, 10370, 10529, 10371, 10530, 10372, 10531, 10373, 10532, - 10257, 10560, 10317, 10476, 10246, 10541, 10258, 10563, 10404, 10605, - 10425, 10625, 10424, 10603, 10282, 10441, 10314, 10473, 10319, 10478, - 10251, 10554, 10392, 10570, 10321, 10480, 10305, 10464, 10309, 10468, - 10315, 10474, 41412, 2488, 2495, 2479, 2501, 2475, 2499, 2476, 2477, - 2466, 2498, 2494, 2491, 2493, 2471, 2483, 2500, 2481, 2478, 2469, 2496, - 2467, 2497, 2486, 2490, 2470, 2485, 2480, 2474, 2487, 2489, 2465, 2473, - 2472, 2468, 2484, 2482, 2502, 2492, 41412, 41412, 2552, 2464, 2505, 2504, - 2503, 2556, 2463, 2525, 2528, 2538, 2516, 2544, 2512, 2542, 2513, 2514, - 2527, 2541, 2537, 2534, 2536, 2508, 2520, 2543, 2518, 2515, 2506, 2539, - 2531, 2540, 2523, 2530, 2507, 2522, 2517, 2511, 2524, 2529, 2526, 2510, - 2509, 2533, 2521, 2519, 2545, 2535, 2546, 2532, 2555, 2553, 41412, 41412, - 32203, 24344, 2554, 41412, 19963, 19966, 19967, 19974, 19975, 19971, - 19978, 19976, 19961, 19973, 19970, 19954, 19955, 19956, 19964, 19969, - 19962, 19951, 19959, 19960, 19957, 19958, 19953, 19965, 19968, 19972, - 19979, 19980, 19952, 19977, 20058, 20073, 20062, 20060, 20061, 20063, - 20075, 20071, 20066, 20067, 20064, 20065, 20069, 20059, 20077, 20083, - 20070, 20080, 20072, 20074, 20081, 20057, 20056, 20082, 20068, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 19981, 19988, 20031, - 20029, 20006, 20037, 20011, 20008, 20023, 20048, 19997, 19991, 20033, - 20003, 20035, 20002, 20009, 20013, 19987, 19999, 19994, 20001, 20027, - 20004, 20021, 20015, 20025, 41412, 41412, 41412, 41412, 20084, 20052, - 20055, 20053, 20079, 20078, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 2306, 2340, 1099, 2341, 2342, 2305, - 2451, 2452, 2317, 2449, 2450, 2644, 1067, 1080, 2312, 2346, 2339, 2345, - 2337, 2338, 2347, 2365, 2353, 2382, 2349, 2401, 2400, 2333, 1387, 1089, - 2439, 2447, 1342, 1294, 1157, 1147, 1577, 1150, 1593, 1129, 1171, 1519, - 1518, 1541, 1320, 1279, 1361, 1196, 1536, 1440, 1620, 1474, 1487, 1466, - 1212, 1496, 1615, 1119, 1266, 1348, 1345, 1241, 1240, 1239, 2427, 1246, - 1431, 1331, 1366, 1379, 1403, 1296, 1572, 1165, 1584, 1097, 1078, 1109, - 1091, 1074, 1105, 2334, 2404, 2159, 1104, 1103, 2403, 2323, 2160, 2448, - 2443, 2442, 2444, 2318, 1092, 2446, 2459, 2461, 2458, 2457, 2454, 2453, - 2456, 2455, 2462, 2460, 2310, 1085, 2441, 1100, 1224, 1226, 1493, 1162, - 1154, 1153, 1316, 1317, 1319, 1558, 1318, 1546, 1552, 1191, 1527, 1526, - 1419, 1531, 1186, 1289, 1287, 1398, 1227, 1286, 1506, 1513, 1221, 1206, - 1203, 1204, 1209, 1218, 1232, 1199, 1205, 1457, 1443, 1454, 1451, 1444, - 1452, 1447, 1328, 1450, 1475, 1478, 1479, 1469, 1468, 1500, 1122, 1225, - 1249, 1247, 1565, 1251, 1426, 1434, 1435, 1343, 1495, 1337, 1336, 1388, - 1334, 1257, 1260, 1389, 1259, 1273, 1258, 1370, 1368, 1372, 1371, 1414, - 1404, 1460, 1412, 1409, 1307, 1508, 1304, 1297, 1298, 1522, 1581, 1355, - 1612, 1557, 1609, 1358, 1580, 1564, 1235, 1603, 1598, 1574, 1624, 1602, - 1585, 1588, 1101, 1170, 2356, 2355, 2358, 2357, 2384, 2364, 2362, 1090, - 2426, 2381, 2380, 2350, 2359, 2399, 2360, 2402, 2387, 2376, 2378, 2314, - 1088, 1087, 2322, 2398, 1198, 1448, 17510, 17512, 17509, 17508, 17505, - 17504, 17507, 17506, 17513, 17511, 1488, 1213, 1268, 2344, 2343, 1303, - 35067, 35141, 35138, 35139, 35135, 35076, 35063, 35064, 35140, 35137, - 35062, 35072, 35071, 35070, 41412, 35060, 35108, 35104, 35118, 35114, - 35115, 35078, 35077, 35079, 35121, 35119, 35080, 35111, 35112, 35116, - 35117, 35109, 35081, 35093, 35120, 35100, 35107, 35122, 35094, 35098, - 35106, 35110, 35099, 35105, 35113, 35095, 35097, 35096, 35127, 35126, - 35125, 35130, 35129, 35128, 35132, 35131, 35066, 35065, 35075, 35074, - 35073, 35069, 35068, 35133, 35147, 35148, 35134, 35145, 35144, 35143, - 35142, 35124, 35123, 35146, 35061, 41412, 41412, 35101, 35102, 35103, - 1177, 1180, 1175, 1176, 1178, 1179, 1173, 1288, 1285, 1202, 1197, 1445, - 1481, 1124, 1120, 1123, 1252, 1250, 1350, 1346, 1344, 1382, 1381, 1410, - 1407, 1408, 1373, 1446, 1449, 1480, 1284, 1282, 1477, 1441, 1283, 1156, - 1155, 1238, 1237, 1236, 1576, 1575, 1587, 1586, 1280, 1482, 1476, 1333, - 37261, 37274, 37270, 37287, 37286, 37265, 37262, 37250, 37281, 37266, - 37255, 37254, 37277, 37264, 37257, 37258, 37275, 37253, 37283, 37276, - 37288, 37269, 37268, 37267, 37279, 37260, 37263, 37278, 37284, 37273, - 37272, 37252, 37280, 37285, 37251, 37259, 37256, 37282, 37246, 37245, - 37292, 37248, 37293, 37291, 37247, 37249, 37290, 37289, 37294, 37271, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 29486, 29488, 29485, 29484, 29481, 29480, - 29483, 29482, 29489, 29487, 29521, 29508, 29522, 29507, 29523, 29505, - 29504, 29492, 29497, 29510, 29516, 29518, 29496, 29506, 29491, 29503, - 29502, 29517, 29509, 29511, 29513, 29514, 29499, 29515, 29500, 29498, - 29512, 29519, 29520, 29501, 29494, 29493, 29495, 29474, 29475, 29476, - 29472, 29469, 29470, 29471, 29473, 29468, 29525, 29524, 29527, 29526, - 29477, 29528, 29490, 41412, 41412, 29478, 29479, 29529, 32575, 32562, - 32576, 32564, 32567, 32563, 32578, 32566, 32573, 32582, 32568, 32569, - 32579, 32581, 32570, 32565, 32583, 32574, 32580, 32577, 32571, 32572, - 32585, 32586, 32589, 32584, 32590, 32587, 32609, 32619, 32614, 32608, - 32618, 32613, 32607, 32617, 32591, 32615, 32611, 32621, 32592, 32610, - 32620, 32612, 32616, 32588, 41412, 41412, 32599, 32593, 32595, 32598, - 32596, 32600, 32622, 32605, 32603, 32606, 32602, 32604, 32597, 32601, - 32594, 41412, 25779, 25766, 25768, 25767, 25769, 25778, 25776, 25781, - 25761, 25759, 25758, 25770, 25771, 25772, 25762, 25780, 25773, 25764, - 25774, 25775, 25763, 25760, 25777, 25782, 25765, 25757, 25783, 25784, - 41412, 41412, 25785, 41412, 35086, 35091, 35087, 35089, 35085, 35084, - 35088, 35092, 35083, 35082, 35090, 41412, 41412, 41412, 41412, 41412, - 1143, 1133, 1144, 1160, 1142, 1130, 1139, 1136, 1140, 1138, 1161, 1135, - 1146, 1132, 1134, 1145, 1131, 1137, 1141, 2428, 2429, 2431, 1539, 1064, - 2316, 1411, 1281, 1501, 1499, 1347, 2445, 1413, 2313, 2315, 41412, 41412, - 41412, 41412, 41412, 2311, 2366, 2392, 2391, 2394, 2158, 2408, 1084, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 28435, 12481, 26055, 24148, 10207, 25626, 371, 1054, 18841, + 26279, 2570, 25877, 7571, 15612, 12664, 28274, 9990, 9975, 9987, 9984, + 9969, 9966, 9981, 9978, 9993, 9972, 7147, 26889, 19084, 11917, 13295, + 26053, 7570, 17426, 17472, 17482, 17498, 17515, 17560, 17564, 17581, + 17595, 17624, 17629, 17641, 17661, 17670, 17686, 17736, 17745, 17748, + 17769, 17793, 17822, 17861, 17872, 17881, 17884, 17898, 18803, 26180, + 26293, 6924, 19857, 13266, 17990, 18040, 18060, 18083, 18119, 18178, + 18186, 18204, 18223, 18260, 18266, 18280, 18319, 18332, 18356, 18413, + 18425, 18431, 18469, 18511, 18584, 18632, 18646, 18655, 18663, 18679, + 18744, 33411, 26242, 31817, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 24142, 15966, 6233, + 25919, 9069, 33983, 5039, 26871, 9957, 7765, 12560, 18851, 24122, 28225, + 26103, 21543, 9672, 25889, 29061, 29060, 4, 22274, 25774, 22280, 6229, + 29064, 20510, 26340, 33545, 33543, 33551, 15969, 17455, 17456, 17444, + 17458, 17437, 17439, 17460, 17483, 17546, 17547, 17518, 17533, 17611, + 17612, 17601, 17599, 17557, 17684, 17725, 17726, 17693, 17711, 17700, + 22987, 17709, 17853, 17854, 17823, 17826, 17893, 17814, 18501, 18021, + 18022, 18010, 18024, 18001, 18003, 18027, 18061, 18152, 18153, 18122, + 18137, 18241, 18242, 18224, 18226, 18177, 18351, 18395, 18396, 18357, + 18381, 18364, 10118, 18379, 18619, 18622, 18587, 18590, 18674, 18533, + 18665, 17442, 18008, 17427, 17991, 17452, 18018, 17487, 18066, 17485, + 18063, 17491, 18071, 17486, 18065, 17505, 18091, 17502, 18085, 17536, + 18141, 17549, 18155, 17528, 18132, 17543, 18149, 17527, 18131, 17566, + 18188, 17569, 18191, 17573, 18196, 17565, 18187, 17584, 18207, 17591, + 18216, 17605, 18238, 17603, 18233, 17614, 18244, 17608, 18235, 17598, + 18107, 17910, 18699, 17625, 18261, 17630, 18267, 18279, 17655, 18297, + 17651, 18284, 17653, 18287, 17648, 18294, 17650, 18305, 17679, 18344, + 17671, 18333, 17673, 18337, 18352, 17559, 18160, 17689, 18374, 17728, + 18398, 17706, 18370, 17911, 18702, 17757, 18448, 17749, 18432, 17750, + 18434, 17775, 18470, 17774, 18476, 17772, 18474, 17770, 18472, 17794, + 18512, 17797, 18516, 17804, 18528, 17850, 18616, 17842, 18606, 17856, + 18624, 17857, 18615, 17833, 18597, 17847, 18611, 17873, 18647, 17885, + 18664, 17886, 17901, 18680, 17904, 18686, 17900, 18683, 18311, 18049, + 17478, 17473, 18041, 17817, 18536, 17731, 17489, 18069, 17464, 17510, + 17506, 18086, 18541, 17766, 17792, 17730, 17561, 18181, 17572, 17579, + 18222, 17622, 17615, 17640, 18278, 18283, 18307, 17811, 17677, 18338, + 17692, 17718, 18388, 17733, 18410, 17742, 18421, 17987, 17819, 18538, + 17558, 17928, 18524, 17803, 18525, 17802, 17835, 18599, 17860, 17865, + 17890, 18669, 17907, 18689, 17551, 17553, 18170, 18175, 17980, 17818, + 18537, 17926, 17981, 17982, 17983, 17919, 17930, 17512, 17500, 18113, + 17660, 17649, 18318, 17685, 17674, 18355, 17450, 18016, 17602, 18225, + 17699, 18363, 17825, 18589, 17830, 18594, 17829, 18593, 17827, 18591, + 17828, 18592, 18573, 17438, 18002, 17434, 17998, 17462, 18030, 17574, + 18197, 17567, 18189, 17631, 18268, 17707, 18377, 17708, 18378, 17552, + 18172, 18263, 17511, 17499, 18112, 17568, 18190, 17593, 17880, 17678, + 18343, 17440, 18004, 17461, 18029, 17710, 18380, 17436, 18000, 17457, + 18023, 17532, 18136, 17548, 18154, 17596, 18232, 17613, 18243, 17705, + 18369, 17727, 18397, 17754, 18438, 17759, 18449, 17832, 18596, 17855, + 18623, 17773, 18475, 17796, 18514, 17897, 18678, 17585, 18208, 17675, + 18090, 17735, 18412, 17909, 18693, 17433, 17997, 17516, 18120, 17701, + 18365, 17714, 18384, 17702, 18366, 17703, 18367, 17894, 18675, 18286, + 18336, 18515, 18104, 18117, 18430, 17459, 17492, 18072, 17643, 17798, + 18483, 18688, 17575, 18198, 17479, 17859, 17813, 17550, 18157, 17628, + 18265, 17786, 18428, 17761, 18452, 17896, 18673, 18565, 18032, 18566, + 18048, 18401, 18064, 18087, 18095, 18461, 18492, 18496, 18407, 18456, + 18458, 18079, 18105, 18195, 18499, 17957, 18202, 18468, 18542, 18215, + 18221, 18245, 18256, 17935, 18292, 18281, 18300, 18308, 18568, 18569, + 18327, 18340, 18349, 17968, 18052, 17942, 18078, 18424, 18553, 18556, + 18559, 18443, 18445, 18439, 18459, 17944, 17936, 18489, 18163, 18106, + 18509, 18167, 18560, 18527, 18585, 18626, 18639, 18562, 18577, 18570, + 17975, 18692, 18682, 18169, 18171, 17984, 17927, 17924, 17977, 17922, + 17955, 18077, 17958, 17964, 18262, 18575, 17937, 18427, 17985, 17929, + 18114, 18100, 18115, 18580, 18529, 18579, 18184, 18315, 18316, 17921, + 17923, 18543, 18544, 22605, 22606, 22614, 22636, 22663, 22666, 22561, + 22683, 22685, 22534, 22477, 22691, 22387, 22542, 22544, 22520, 22493, + 22540, 22522, 22546, 22693, 22479, 22469, 6162, 22697, 22523, 22386, + 22492, 22518, 22509, 22515, 22514, 22690, 22500, 22421, 22420, 22692, + 22478, 22533, 22531, 5032, 10313, 26472, 24282, 28183, 10372, 22547, + 22470, 22604, 22616, 22643, 22684, 22640, 22484, 22499, 22527, 22512, + 22489, 22699, 22698, 22696, 22694, 22476, 22505, 22517, 22507, 22510, + 22511, 22530, 22529, 22528, 22513, 22539, 22389, 22490, 22390, 22491, + 22549, 22532, 22506, 7365, 7154, 7238, 7540, 7475, 7498, 7164, 7264, + 7260, 7379, 7524, 7274, 7170, 7556, 7296, 7297, 7172, 7382, 7548, 7175, + 7506, 7176, 7366, 7155, 7459, 7519, 7449, 7381, 7456, 7549, 7300, 7503, + 7486, 7502, 7507, 7267, 7261, 7523, 7177, 7240, 7496, 7555, 7167, 7386, + 7171, 7239, 7166, 7383, 7544, 7480, 7474, 7298, 7543, 7528, 7472, 7527, + 7471, 7514, 7384, 7532, 7537, 7568, 7557, 7284, 7367, 7156, 7376, 7375, + 7378, 7377, 7168, 7310, 7295, 7448, 7489, 7380, 7163, 7461, 7551, 7371, + 7510, 7457, 7312, 7567, 7450, 7511, 7509, 7515, 7266, 7160, 7290, 7526, + 7276, 7275, 7281, 7282, 7291, 7277, 7288, 7399, 7407, 7412, 7420, 7423, + 7405, 7437, 7439, 7441, 7426, 7429, 7444, 7445, 13480, 13744, 13375, + 13611, 13562, 13558, 13469, 13726, 35536, 35536, 13801, 13751, 13752, + 13750, 13806, 13483, 35536, 35536, 35536, 35536, 13766, 13496, 13373, + 13349, 13406, 13396, 13420, 35536, 13452, 35536, 13467, 13442, 13658, + 13352, 13479, 13477, 13475, 13397, 13481, 13376, 13473, 13407, 13476, + 13482, 13484, 13485, 13486, 13443, 13472, 13453, 35536, 13455, 13474, + 13458, 13470, 13478, 13471, 13422, 13412, 13463, 13608, 13623, 13648, + 13667, 13678, 13583, 13743, 13741, 13613, 13614, 13745, 13624, 13738, + 13649, 13689, 13746, 13747, 13748, 13749, 13716, 13729, 13730, 13740, + 13736, 13739, 13669, 13727, 13742, 13728, 13691, 13654, 13674, 13725, + 13687, 13715, 13491, 13803, 13762, 13770, 13768, 13769, 13578, 13579, + 13543, 13554, 13610, 13553, 13735, 13556, 13612, 13555, 13690, 13552, + 13733, 7646, 7740, 7624, 7718, 7620, 7714, 7618, 7712, 7616, 7710, 7645, + 7739, 7615, 7709, 13542, 13581, 13559, 13557, 13492, 13560, 13582, 13457, + 13737, 13487, 13456, 13734, 13580, 13489, 13490, 13488, 9336, 9338, 9285, + 9324, 9260, 9289, 9276, 9395, 9408, 9231, 9234, 9248, 9363, 9333, 9376, + 9293, 9261, 9277, 9409, 9318, 9297, 9335, 9402, 9398, 9331, 9374, 9348, + 9299, 9315, 9304, 9367, 9235, 9310, 9313, 9245, 9255, 9317, 9325, 9251, + 9278, 9381, 9379, 9329, 9392, 9384, 9298, 9397, 9389, 9420, 9436, 9610, + 9477, 9456, 9494, 9603, 9599, 9490, 9552, 9507, 9458, 9474, 9463, 9533, + 9538, 9469, 9472, 9570, 9581, 9476, 9484, 9576, 9437, 9559, 9557, 9488, + 9593, 9562, 9457, 9598, 9590, 9495, 9497, 9444, 9483, 9586, 9448, 9435, + 9596, 9609, 9526, 9532, 9573, 9522, 9492, 9554, 9452, 9368, 9534, 9391, + 9592, 9344, 9503, 9230, 9524, 9340, 9499, 9273, 9432, 9341, 9500, 9364, + 9523, 9238, 9542, 9407, 9608, 9346, 9505, 9347, 9506, 9259, 9585, 9239, + 9547, 9369, 9535, 9371, 9537, 9361, 9520, 9641, 7231, 7225, 7228, 7226, + 7227, 7181, 7234, 9375, 9553, 9388, 9566, 9311, 9470, 9320, 9479, 9322, + 9481, 9319, 9478, 9404, 9605, 9400, 9601, 9349, 9508, 9351, 9510, 9352, + 9511, 9271, 9430, 9306, 9465, 9414, 9614, 9236, 9539, 9267, 9426, 9314, + 9473, 9247, 9572, 9386, 9564, 9387, 9565, 9326, 9485, 9413, 9613, 9280, + 9439, 9281, 9440, 9377, 9555, 9264, 9423, 9265, 9424, 9417, 9405, 9606, + 9350, 9509, 9302, 9461, 9309, 9468, 9308, 9467, 9362, 9521, 9316, 9475, + 9541, 9263, 9422, 9262, 9421, 9412, 9612, 9337, 9496, 9372, 9550, 9373, + 9551, 9403, 9604, 9399, 9600, 9266, 9425, 9334, 9493, 9332, 9491, 9370, + 9536, 9269, 9428, 9270, 9429, 9312, 9471, 9258, 9584, 9257, 9583, 9256, + 9582, 9279, 9438, 9321, 9480, 9393, 9594, 9323, 9482, 9327, 9486, 9328, + 9487, 9355, 9514, 9354, 9513, 9360, 9519, 9353, 9512, 9356, 9515, 9357, + 9516, 9358, 9517, 9359, 9518, 9243, 9546, 9303, 9462, 9232, 9527, 9244, + 9549, 9390, 9591, 9411, 9611, 9410, 9589, 9268, 9427, 9300, 9459, 9305, + 9464, 9237, 9540, 9378, 9556, 9307, 9466, 9291, 9450, 9295, 9454, 9301, + 9460, 35536, 2488, 2495, 2479, 2501, 2475, 2499, 2476, 2477, 2466, 2498, + 2494, 2491, 2493, 2471, 2483, 2500, 2481, 2478, 2469, 2496, 2467, 2497, + 2486, 2490, 2470, 2485, 2480, 2474, 2487, 2489, 2465, 2473, 2472, 2468, + 2484, 2482, 2502, 2492, 35536, 35536, 2552, 2464, 2505, 2504, 2503, 2556, + 2463, 2525, 2528, 2538, 2516, 2544, 2512, 2542, 2513, 2514, 2527, 2541, + 2537, 2534, 2536, 2508, 2520, 2543, 2518, 2515, 2506, 2539, 2531, 2540, + 2523, 2530, 2507, 2522, 2517, 2511, 2524, 2529, 2526, 2510, 2509, 2533, + 2521, 2519, 2545, 2535, 2546, 2532, 2555, 2553, 35536, 35536, 26327, + 18864, 2554, 35536, 14954, 14957, 14958, 14965, 14966, 14962, 14969, + 14967, 14952, 14964, 14961, 14945, 14946, 14947, 14955, 14960, 14953, + 14942, 14950, 14951, 14948, 14949, 14944, 14956, 14959, 14963, 14970, + 14971, 14943, 14968, 15049, 15064, 15053, 15051, 15052, 15054, 15066, + 15062, 15057, 15058, 15055, 15056, 15060, 15050, 15068, 15074, 15061, + 15071, 15063, 15065, 15072, 15048, 15047, 15073, 15059, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 14972, 14979, 15022, 15020, + 14997, 15028, 15002, 14999, 15014, 15039, 14988, 14982, 15024, 14994, + 15026, 14993, 15000, 15004, 14978, 14990, 14985, 14992, 15018, 14995, + 15012, 15006, 15016, 35536, 35536, 35536, 35536, 15075, 15043, 15046, + 15044, 15070, 15069, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 2306, 2340, 1099, 2341, 2342, 2305, 2451, + 2452, 2317, 2449, 2450, 2644, 1067, 1080, 2312, 2346, 2339, 2345, 2337, + 2338, 2347, 2365, 2353, 2382, 2349, 2401, 2400, 2333, 1387, 1089, 2439, + 2447, 1342, 1294, 1157, 1147, 1577, 1150, 1593, 1129, 1171, 1519, 1518, + 1541, 1320, 1279, 1361, 1196, 1536, 1440, 1620, 1474, 1487, 1466, 1212, + 1496, 1615, 1119, 1266, 1348, 1345, 1241, 1240, 1239, 2427, 1246, 1431, + 1331, 1366, 1379, 1403, 1296, 1572, 1165, 1584, 1097, 1078, 1109, 1091, + 1074, 1105, 2334, 2404, 2159, 1104, 1103, 2403, 2323, 2160, 2448, 2443, + 2442, 2444, 2318, 1092, 2446, 2459, 2461, 2458, 2457, 2454, 2453, 2456, + 2455, 2462, 2460, 2310, 1085, 2441, 1100, 1224, 1226, 1493, 1162, 1154, + 1153, 1316, 1317, 1319, 1558, 1318, 1546, 1552, 1191, 1527, 1526, 1419, + 1531, 1186, 1289, 1287, 1398, 1227, 1286, 1506, 1513, 1221, 1206, 1203, + 1204, 1209, 1218, 1232, 1199, 1205, 1457, 1443, 1454, 1451, 1444, 1452, + 1447, 1328, 1450, 1475, 1478, 1479, 1469, 1468, 1500, 1122, 1225, 1249, + 1247, 1565, 1251, 1426, 1434, 1435, 1343, 1495, 1337, 1336, 1388, 1334, + 1257, 1260, 1389, 1259, 1273, 1258, 1370, 1368, 1372, 1371, 1414, 1404, + 1460, 1412, 1409, 1307, 1508, 1304, 1297, 1298, 1522, 1581, 1355, 1612, + 1557, 1609, 1358, 1580, 1564, 1235, 1603, 1598, 1574, 1624, 1602, 1585, + 1588, 1101, 1170, 2356, 2355, 2358, 2357, 2384, 2364, 2362, 1090, 2426, + 2381, 2380, 2350, 2359, 2399, 2360, 2402, 2387, 2376, 2378, 2314, 1088, + 1087, 2322, 2398, 1198, 1448, 12501, 12503, 12500, 12499, 12496, 12495, + 12498, 12497, 12504, 12502, 1488, 1213, 1268, 2344, 2343, 1303, 29191, + 29265, 29262, 29263, 29259, 29200, 29187, 29188, 29264, 29261, 29186, + 29196, 29195, 29194, 35536, 29184, 29232, 29228, 29242, 29238, 29239, + 29202, 29201, 29203, 29245, 29243, 29204, 29235, 29236, 29240, 29241, + 29233, 29205, 29217, 29244, 29224, 29231, 29246, 29218, 29222, 29230, + 29234, 29223, 29229, 29237, 29219, 29221, 29220, 29251, 29250, 29249, + 29254, 29253, 29252, 29256, 29255, 29190, 29189, 29199, 29198, 29197, + 29193, 29192, 29257, 29271, 29272, 29258, 29269, 29268, 29267, 29266, + 29248, 29247, 29270, 29185, 35536, 35536, 29225, 29226, 29227, 1177, + 1180, 1175, 1176, 1178, 1179, 1173, 1288, 1285, 1202, 1197, 1445, 1481, + 1124, 1120, 1123, 1252, 1250, 1350, 1346, 1344, 1382, 1381, 1410, 1407, + 1408, 1373, 1446, 1449, 1480, 1284, 1282, 1477, 1441, 1283, 1156, 1155, + 1238, 1237, 1236, 1576, 1575, 1587, 1586, 1280, 1482, 1476, 1333, 31385, + 31398, 31394, 31411, 31410, 31389, 31386, 31374, 31405, 31390, 31379, + 31378, 31401, 31388, 31381, 31382, 31399, 31377, 31407, 31400, 31412, + 31393, 31392, 31391, 31403, 31384, 31387, 31402, 31408, 31397, 31396, + 31376, 31404, 31409, 31375, 31383, 31380, 31406, 31370, 31369, 31416, + 31372, 31417, 31415, 31371, 31373, 31414, 31413, 31418, 31395, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 24006, 24008, 24005, 24004, 24001, 24000, 24003, + 24002, 24009, 24007, 24041, 24028, 24042, 24027, 24043, 24025, 24024, + 24012, 24017, 24030, 24036, 24038, 24016, 24026, 24011, 24023, 24022, + 24037, 24029, 24031, 24033, 24034, 24019, 24035, 24020, 24018, 24032, + 24039, 24040, 24021, 24014, 24013, 24015, 23994, 23995, 23996, 23992, + 23989, 23990, 23991, 23993, 23988, 24045, 24044, 24047, 24046, 23997, + 24048, 24010, 35536, 35536, 23998, 23999, 24049, 26699, 26686, 26700, + 26688, 26691, 26687, 26702, 26690, 26697, 26706, 26692, 26693, 26703, + 26705, 26694, 26689, 26707, 26698, 26704, 26701, 26695, 26696, 26709, + 26710, 26713, 26708, 26714, 26711, 26733, 26743, 26738, 26732, 26742, + 26737, 26731, 26741, 26715, 26739, 26735, 26745, 26716, 26734, 26744, + 26736, 26740, 26712, 35536, 35536, 26723, 26717, 26719, 26722, 26720, + 26724, 26746, 26729, 26727, 26730, 26726, 26728, 26721, 26725, 26718, + 35536, 20299, 20286, 20288, 20287, 20289, 20298, 20296, 20301, 20281, + 20279, 20278, 20290, 20291, 20292, 20282, 20300, 20293, 20284, 20294, + 20295, 20283, 20280, 20297, 20302, 20285, 20277, 20303, 20304, 35536, + 35536, 20305, 35536, 29210, 29215, 29211, 29213, 29209, 29208, 29212, + 29216, 29207, 29206, 29214, 35536, 35536, 35536, 35536, 35536, 1143, + 1133, 1144, 1160, 1142, 1130, 1139, 1136, 1140, 1138, 1161, 1135, 1146, + 1132, 1134, 1145, 1131, 1137, 1141, 2428, 2429, 2431, 1539, 1064, 2316, + 1411, 1281, 1501, 1499, 1347, 2445, 1413, 2313, 2315, 35536, 35536, + 35536, 35536, 35536, 2311, 2366, 2392, 2391, 2394, 2158, 2408, 1084, 1102, 1174, 1181, 1321, 1498, 1248, 1432, 1367, 1380, 1599, 1601, 1453, 1573, 1465, 1378, 1200, 1467, 1261, 1494, 1623, 1121, 1335, 1433, 1172, 1420, 1524, 1442, 1600, 1117, 1115, 1118, 1421, 1525, 1547, 1507, 1349, @@ -13904,4827 +13265,4243 @@ static const unsigned short dawg_codepoint_to_pos_index2[] = { 2370, 2369, 2371, 2374, 2373, 2352, 2361, 1086, 2440, 1070, 1068, 1072, 1071, 1069, 1073, 2434, 2436, 2438, 2433, 2435, 2437, 2309, 2308, 2307, 2375, 1094, 1093, 1106, 1630, 2319, 1629, 2321, 1081, 1082, 2320, 1077, - 2161, 10905, 10895, 10909, 10914, 10830, 10804, 10805, 10874, 10875, - 10850, 10851, 10869, 10871, 10812, 10831, 10882, 10806, 10813, 10832, - 10845, 10807, 10841, 10840, 10825, 10823, 10856, 10810, 10814, 10861, - 10859, 10857, 10866, 10865, 10818, 10817, 10855, 10868, 10867, 10820, - 10819, 10858, 10854, 10877, 10876, 10838, 10837, 10828, 10849, 10844, - 10843, 10864, 10863, 10862, 10873, 10833, 10834, 10835, 10827, 10927, - 10926, 10907, 10908, 10917, 10939, 10940, 10929, 10930, 10935, 10936, - 10923, 10933, 10941, 10918, 10924, 10934, 10925, 10919, 10913, 10928, - 10920, 10955, 10916, 10915, 10799, 10796, 10922, 10932, 10931, 10881, - 10839, 10822, 10879, 10815, 10842, 10880, 10848, 10870, 10872, 10937, - 10938, 10943, 10942, 10950, 10952, 10949, 10948, 10945, 10944, 10947, - 10946, 10953, 10951, 10797, 10912, 10811, 10847, 10846, 10808, 10853, - 10852, 10829, 10878, 10826, 10824, 10860, 10821, 10816, 10836, 3599, - 3667, 3670, 3672, 41412, 3623, 3624, 3637, 3638, 3635, 3636, 3617, 3619, - 41412, 41412, 3659, 3625, 41412, 41412, 3660, 3626, 3610, 3607, 3651, - 3650, 3639, 3649, 3648, 3653, 3652, 3641, 3632, 3631, 3628, 3627, 3640, - 3634, 3633, 3630, 3629, 3642, 41412, 3655, 3654, 3647, 3646, 3658, 3622, - 3611, 41412, 3657, 41412, 41412, 41412, 3643, 3644, 3645, 3656, 41412, - 41412, 3668, 3669, 3674, 3683, 3684, 3677, 3678, 3679, 3680, 41412, - 41412, 3685, 3675, 41412, 41412, 3686, 3676, 3671, 3608, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 3600, 41412, 41412, 41412, - 41412, 3615, 3614, 41412, 3621, 3618, 3620, 3681, 3682, 41412, 41412, - 3693, 3695, 3692, 3691, 3688, 3687, 3690, 3689, 3696, 3694, 3613, 3612, - 3662, 3661, 3601, 3605, 3604, 3603, 3602, 3606, 3673, 3697, 3616, 3598, - 3666, 41412, 41412, 19044, 19045, 19050, 41412, 18996, 18997, 19012, - 19013, 19010, 19011, 41412, 41412, 41412, 41412, 19031, 18998, 41412, - 41412, 19030, 18999, 18995, 18994, 18992, 18991, 19016, 19023, 19022, - 19025, 19024, 19018, 19007, 19006, 19001, 19000, 19017, 19009, 19008, - 19003, 19002, 19019, 41412, 19027, 19026, 19021, 19020, 19034, 19036, - 19005, 41412, 19015, 19014, 41412, 19035, 19028, 41412, 19029, 19033, - 41412, 41412, 19047, 41412, 19051, 19056, 19057, 19054, 19055, 41412, - 41412, 41412, 41412, 19059, 19052, 41412, 41412, 19058, 19053, 19049, - 41412, 41412, 41412, 19046, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 18993, 18990, 19037, 19004, 41412, 19032, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 19069, 19071, 19068, 19067, 19064, 19063, - 19066, 19065, 19072, 19070, 19060, 18989, 19061, 19073, 19062, 19048, - 18988, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 18884, 18892, 18894, 41412, 18834, 18835, 18853, 18854, 18851, - 18852, 18846, 18848, 18910, 41412, 18881, 18836, 18911, 41412, 18882, - 18837, 18874, 18873, 18870, 18869, 18858, 18868, 18867, 18872, 18871, - 18860, 18843, 18842, 18839, 18838, 18859, 18845, 18844, 18841, 18840, - 18861, 41412, 18876, 18875, 18866, 18865, 18878, 18880, 18879, 41412, - 18856, 18855, 41412, 18850, 18862, 18863, 18864, 18877, 41412, 41412, - 18890, 18891, 18897, 18906, 18907, 18900, 18901, 18902, 18903, 18895, - 41412, 18908, 18898, 18896, 41412, 18909, 18899, 18893, 41412, 41412, - 18924, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 18847, 18849, 18904, 18905, - 41412, 41412, 18920, 18922, 18919, 18918, 18915, 18914, 18917, 18916, - 18923, 18921, 18912, 18913, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 18857, 18889, 18888, 18885, 18887, 18883, 18886, 41412, 30802, - 30805, 30808, 41412, 30753, 30754, 30772, 30773, 30770, 30771, 30765, - 30767, 41412, 41412, 30798, 30755, 41412, 41412, 30799, 30756, 30792, - 30791, 30788, 30787, 30776, 30786, 30785, 30790, 30789, 30778, 30762, - 30761, 30758, 30757, 30777, 30764, 30763, 30760, 30759, 30779, 41412, - 30794, 30793, 30784, 30783, 30796, 30752, 30750, 41412, 30775, 30774, - 41412, 30769, 30780, 30781, 30782, 30795, 41412, 41412, 30803, 30804, - 30809, 30818, 30819, 30812, 30813, 30814, 30815, 41412, 41412, 30820, - 30810, 41412, 41412, 30821, 30811, 30807, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 30806, 30739, 30740, 41412, 41412, 41412, 41412, - 30749, 30748, 41412, 30751, 30766, 30768, 30816, 30817, 41412, 41412, - 30828, 30830, 30827, 30826, 30823, 30822, 30825, 30824, 30831, 30829, - 30747, 30797, 30744, 30743, 30746, 30741, 30742, 30745, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 35760, 35777, - 41412, 35723, 35724, 35736, 35737, 35732, 35733, 41412, 41412, 41412, - 35741, 35742, 35725, 41412, 35734, 35735, 35726, 35746, 41412, 41412, - 41412, 35718, 35743, 41412, 35745, 41412, 35719, 35721, 41412, 41412, - 41412, 35717, 35722, 41412, 41412, 41412, 35720, 35716, 35748, 41412, - 41412, 41412, 35747, 35750, 35731, 35730, 35729, 35728, 35727, 35749, - 35738, 35739, 35740, 35744, 41412, 41412, 41412, 41412, 36050, 36057, - 36058, 36053, 36054, 41412, 41412, 41412, 36059, 36060, 36051, 41412, - 36055, 36056, 36052, 35776, 41412, 41412, 36063, 41412, 41412, 41412, - 41412, 41412, 41412, 35652, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 35689, 35691, - 35688, 35687, 35684, 35683, 35686, 35685, 35692, 35690, 35754, 35752, - 35753, 35682, 36062, 36061, 35681, 35679, 35651, 35757, 35755, 41412, - 41412, 41412, 41412, 41412, 37126, 37127, 37132, 37134, 37125, 37086, - 37087, 37102, 37103, 37098, 37099, 37093, 37095, 41412, 37119, 37120, - 37088, 41412, 37100, 37101, 37089, 37116, 37115, 37112, 37111, 37075, - 37110, 37109, 37114, 37113, 37077, 37082, 37081, 37069, 37068, 37076, - 37085, 37083, 37072, 37070, 37073, 41412, 37118, 37117, 37108, 37107, - 37122, 37123, 37080, 37079, 37092, 37091, 37090, 37097, 37104, 37105, - 37106, 37121, 41412, 41412, 37130, 37131, 37135, 37146, 37147, 37138, - 37139, 37140, 37141, 41412, 37148, 37149, 37136, 41412, 37144, 37145, - 37137, 37133, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 37124, - 37060, 41412, 37084, 37071, 37078, 41412, 37059, 37074, 41412, 41412, - 37094, 37096, 37142, 37143, 41412, 41412, 37156, 37158, 37155, 37154, - 37151, 37150, 37153, 37152, 37159, 37157, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 37128, 37067, 37065, 37063, 37061, 37066, 37064, - 37062, 37129, 21436, 21435, 21440, 21444, 21437, 21384, 21385, 21410, - 21411, 21406, 21407, 21401, 21403, 41412, 21427, 21428, 21386, 41412, - 21408, 21409, 21387, 21424, 21423, 21420, 21419, 21381, 21418, 21417, - 21422, 21421, 21383, 21398, 21397, 21389, 21388, 21382, 21400, 21399, - 21391, 21390, 21379, 41412, 21426, 21425, 21416, 21415, 21431, 21432, - 21396, 21395, 21394, 21393, 41412, 21405, 21412, 21413, 21414, 21430, - 41412, 41412, 21438, 21439, 21447, 21458, 21459, 21450, 21451, 21452, - 21453, 41412, 21460, 21461, 21448, 41412, 21456, 21457, 21449, 21443, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 21433, 21446, 41412, - 41412, 41412, 41412, 41412, 21445, 21380, 21429, 41412, 21402, 21404, - 21454, 21455, 41412, 41412, 21468, 21470, 21467, 21466, 21463, 21462, - 21465, 21464, 21471, 21469, 41412, 21441, 21442, 21434, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 25719, 25721, 25726, 25724, 25676, 25650, 25652, 25696, 25697, 25692, - 25693, 25677, 25679, 41412, 25711, 25712, 25653, 41412, 25694, 25695, - 25654, 25708, 25707, 25704, 25703, 25684, 25665, 25664, 25706, 25705, - 25685, 25673, 25671, 25668, 25667, 25683, 25675, 25674, 25670, 25669, - 25686, 25682, 25710, 25709, 25702, 25701, 25714, 25715, 25691, 25690, - 25689, 25688, 25687, 25681, 25698, 25699, 25700, 25713, 25672, 25722, - 25720, 25725, 25728, 25739, 25740, 25731, 25732, 25733, 25734, 41412, - 25741, 25742, 25729, 41412, 25737, 25738, 25730, 25723, 25666, 25727, - 41412, 41412, 41412, 41412, 25662, 25663, 25657, 25743, 25642, 25640, - 25647, 25637, 25638, 25648, 25641, 25651, 25678, 25680, 25735, 25736, - 41412, 41412, 25633, 25635, 25632, 25631, 25628, 25627, 25630, 25629, - 25636, 25634, 25718, 25716, 25717, 25645, 25644, 25649, 25639, 25643, - 25646, 25626, 25659, 25658, 25660, 25655, 25656, 25661, 41412, 33959, - 33958, 33960, 41412, 33904, 33901, 33889, 33888, 33912, 33911, 33914, - 33913, 33910, 33909, 33908, 33907, 33906, 33905, 33902, 33933, 33932, - 33903, 41412, 41412, 41412, 33898, 33923, 33896, 33921, 33946, 33936, - 33895, 33920, 33897, 33922, 33943, 33944, 33937, 33890, 33915, 33892, - 33917, 33927, 33934, 33891, 33916, 33893, 33918, 33930, 41412, 33935, - 33899, 33924, 33894, 33919, 33925, 33900, 33942, 33940, 41412, 33929, - 41412, 41412, 33941, 33945, 33928, 33931, 33939, 33926, 33938, 41412, - 41412, 41412, 33957, 41412, 41412, 41412, 41412, 33977, 33969, 33964, - 33970, 33965, 33971, 41412, 33966, 41412, 33967, 33972, 33963, 33976, - 33973, 33974, 33975, 33968, 41412, 41412, 41412, 41412, 41412, 41412, - 33953, 33955, 33952, 33951, 33948, 33947, 33950, 33949, 33956, 33954, - 41412, 41412, 33961, 33962, 33978, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 37313, 37310, 37308, - 37307, 37309, 37311, 37327, 37296, 37298, 37297, 37356, 37299, 37368, - 37300, 37365, 37361, 37358, 37359, 37329, 37301, 37364, 37363, 37360, - 37362, 37330, 37295, 37336, 37333, 37302, 37334, 37303, 37335, 37325, - 37369, 37337, 37338, 37315, 37317, 37366, 37354, 37353, 37355, 37306, - 37314, 37370, 37305, 37331, 37339, 37319, 37342, 37344, 37349, 37350, - 37346, 37347, 37345, 37348, 37332, 41412, 41412, 41412, 41412, 37371, - 37351, 37343, 37352, 37341, 37340, 37316, 37324, 37323, 37322, 37320, - 37321, 37318, 37357, 37328, 37367, 37304, 37378, 37380, 37377, 37376, - 37373, 37372, 37375, 37374, 37381, 37379, 37326, 37312, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 22743, 22741, 41412, 22742, 41412, - 22756, 22771, 22775, 22755, 22765, 41412, 22757, 22772, 22753, 22751, - 22750, 22748, 22747, 22752, 22776, 22768, 22766, 22767, 22749, 22773, - 22774, 22761, 22759, 22738, 22760, 22737, 22754, 22777, 22780, 22745, - 41412, 22746, 41412, 22779, 22762, 22763, 22764, 22769, 22758, 22781, - 22770, 22807, 22789, 22794, 22790, 22792, 22802, 22803, 22796, 22797, - 22798, 22799, 22784, 22795, 22783, 22782, 41412, 41412, 22800, 22801, - 22804, 22793, 22791, 41412, 22805, 41412, 22788, 22785, 22786, 22787, - 22818, 22819, 22806, 41412, 22814, 22816, 22813, 22812, 22809, 22808, - 22811, 22810, 22817, 22815, 41412, 41412, 22734, 22733, 22740, 22739, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 37605, 37512, 37510, 37511, 37520, 37508, 37505, 37509, - 37529, 37500, 37498, 37521, 37536, 37530, 37526, 37533, 37525, 37528, - 37527, 37504, 37513, 37496, 37495, 37423, 37424, 37422, 37544, 37545, - 37546, 37548, 37549, 37547, 37445, 37447, 37444, 37443, 37440, 37439, - 37442, 37441, 37448, 37446, 37437, 37434, 37433, 37430, 37429, 37432, - 37431, 37438, 37436, 37435, 37501, 37523, 37503, 37522, 37506, 37532, - 37514, 37515, 37516, 37517, 37555, 37541, 37454, 37452, 37482, 37481, - 37464, 37480, 37479, 37489, 41412, 37466, 37474, 37473, 37459, 37458, - 37465, 37476, 37475, 37463, 37462, 37467, 37484, 37483, 37478, 37477, - 37491, 37472, 37471, 37461, 37460, 37492, 37485, 37486, 37487, 37493, - 37456, 37490, 37468, 37469, 37470, 37488, 37494, 37451, 37457, 37453, - 37455, 41412, 41412, 41412, 41412, 37629, 37625, 37626, 37617, 37618, - 37619, 37620, 37621, 37622, 37627, 37628, 37623, 37624, 37552, 37553, - 37615, 37616, 37543, 37557, 37518, 37535, 37539, 37554, 37540, 37542, - 37537, 37538, 37556, 37604, 37603, 37602, 37569, 37568, 37588, 37587, - 37570, 37586, 37585, 37595, 41412, 37572, 37580, 37579, 37562, 37561, - 37571, 37582, 37581, 37566, 37565, 37573, 37590, 37589, 37584, 37583, - 37597, 37578, 37577, 37564, 37563, 37599, 37591, 37592, 37593, 37600, - 37598, 37596, 37574, 37575, 37576, 37594, 37601, 37567, 37559, 37560, - 37558, 41412, 37449, 37450, 37426, 37427, 37428, 37425, 37606, 37613, - 37611, 37614, 37612, 37607, 37610, 37609, 37608, 41412, 37551, 37550, - 37499, 37502, 37524, 37519, 37507, 32208, 24349, 32209, 24350, 37534, - 37531, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 28762, 28741, - 28740, 28739, 28771, 28839, 28838, 28841, 28840, 28772, 28769, 28817, - 28816, 28823, 28822, 28770, 28801, 28818, 28825, 28824, 28773, 28843, - 28842, 28837, 28836, 28768, 28845, 28775, 28835, 28821, 28800, 28844, - 28834, 28731, 28795, 28832, 28833, 28826, 28827, 28734, 28767, 28846, - 28733, 28938, 28922, 28945, 28946, 28939, 28940, 28934, 28919, 28927, - 28928, 28935, 28863, 28882, 28887, 28886, 28862, 28726, 28724, 28725, - 28723, 28738, 28963, 28965, 28962, 28961, 28958, 28957, 28960, 28959, - 28966, 28964, 28885, 28874, 28892, 28896, 28891, 28895, 28776, 28799, - 28828, 28829, 28830, 28831, 28941, 28942, 28943, 28944, 28766, 28765, - 28763, 28764, 28729, 28728, 28727, 28798, 28933, 28907, 28908, 28820, - 28819, 28936, 28937, 28877, 28878, 28879, 28880, 28881, 28737, 28736, - 28735, 28923, 28925, 28926, 28924, 28790, 28789, 28788, 28786, 28794, - 28778, 28791, 28779, 28781, 28792, 28784, 28782, 28793, 28730, 28932, - 28929, 28930, 28931, 28869, 28870, 28871, 28872, 28867, 28868, 28866, - 28774, 28883, 28858, 28860, 28857, 28856, 28853, 28852, 28855, 28854, - 28861, 28859, 28864, 28865, 28920, 28921, 28894, 28893, 17885, 17911, - 17896, 17917, 17918, 17916, 17906, 17907, 17919, 17900, 17909, 17912, - 17914, 17920, 17902, 17905, 17910, 17904, 17908, 17921, 17901, 17899, - 17895, 17915, 17903, 17891, 17894, 17898, 17893, 17892, 17913, 17897, - 17886, 17890, 17888, 17923, 17887, 17889, 41412, 17922, 41412, 41412, - 41412, 41412, 41412, 17884, 41412, 41412, 17968, 17999, 17976, 18005, - 17974, 18004, 17997, 17994, 18006, 17986, 17988, 18000, 18002, 18007, - 17990, 17996, 17998, 17992, 17995, 17965, 17989, 17985, 17975, 18003, - 17991, 17969, 17972, 17984, 17971, 17970, 18001, 17983, 17979, 17982, - 17980, 18009, 17977, 17981, 18010, 18008, 17973, 17993, 17967, 18057, - 27975, 17966, 17978, 17987, 19305, 19379, 19313, 19384, 19377, 19341, - 19308, 19323, 19381, 19355, 19373, 19287, 19285, 19371, 19272, 19307, - 19391, 19320, 19394, 19315, 19380, 19317, 19316, 19388, 19351, 19375, - 19354, 19300, 19310, 19304, 19333, 19338, 19337, 19324, 19328, 19326, - 19329, 19330, 19327, 19335, 19334, 19336, 19331, 19302, 19303, 19362, - 19368, 19367, 19360, 19365, 19356, 19357, 19359, 19370, 19364, 19363, - 19361, 19366, 19358, 19369, 19277, 19276, 19282, 19281, 19340, 19297, - 19296, 19294, 19289, 19299, 19290, 19383, 19293, 19292, 19295, 19288, - 19392, 19286, 19279, 19275, 19284, 19280, 19273, 19274, 19278, 19283, - 19321, 19301, 19382, 19393, 19306, 19319, 19314, 19318, 19385, 19396, - 19634, 19540, 19550, 19598, 19602, 19552, 19551, 19604, 19603, 19579, - 19631, 19632, 19589, 19610, 19590, 19630, 19629, 19633, 19619, 19556, - 19608, 19563, 19548, 19549, 19600, 19599, 19554, 19555, 19553, 19606, - 19607, 19587, 19586, 19582, 19580, 19588, 19611, 19612, 19613, 19618, - 19617, 19595, 19596, 19594, 19591, 19597, 19624, 19623, 19622, 19621, - 19620, 19628, 19626, 19562, 19559, 19609, 19564, 19566, 19573, 19577, - 19575, 19565, 19541, 19543, 19546, 19545, 19578, 19547, 19601, 19605, - 19584, 19585, 19416, 19517, 19419, 19439, 19442, 19446, 19521, 19467, - 19468, 19473, 19477, 19486, 19489, 19482, 19494, 19426, 19456, 19459, - 19495, 19512, 19408, 19399, 19402, 19425, 19530, 19452, 19403, 19418, - 19420, 19445, 19444, 19448, 19447, 19443, 19528, 19522, 19470, 19493, - 19487, 19488, 19507, 19474, 19476, 19481, 19480, 19471, 19485, 19483, - 19472, 19490, 19436, 19433, 19427, 19432, 19431, 19429, 19434, 19438, - 19415, 19457, 19461, 19466, 19414, 19497, 19505, 19498, 19501, 19449, - 19410, 19411, 19520, 19409, 19531, 19535, 19538, 19454, 19413, 19406, - 19404, 19405, 19407, 19539, 19422, 19423, 19421, 19417, 19424, 19518, - 17155, 17162, 17161, 17156, 17160, 17159, 17157, 17158, 17382, 17390, - 17389, 17383, 17387, 17386, 17384, 17388, 17148, 17154, 17152, 17149, - 17151, 17150, 17153, 17139, 17199, 17207, 17206, 17200, 17204, 17203, - 17201, 17197, 17311, 17318, 17316, 17312, 17314, 17313, 17317, 17315, - 17286, 17295, 17294, 17287, 17291, 17290, 17288, 17292, 17326, 17332, - 17331, 17327, 17301, 17296, 17328, 17330, 17302, 17310, 17309, 17303, - 17307, 17306, 17304, 17308, 17278, 17285, 17284, 17279, 17283, 17282, - 17280, 17281, 17266, 41412, 17270, 17267, 17269, 17268, 41412, 41412, - 17259, 17265, 17263, 17260, 17262, 17261, 17264, 41412, 17254, 41412, - 17258, 17255, 17257, 17256, 41412, 41412, 16989, 16996, 16995, 16990, - 16994, 16993, 16991, 16980, 17451, 17458, 17456, 17452, 17454, 17453, - 17457, 17455, 17364, 17372, 17371, 17365, 17369, 17368, 17366, 17370, - 17027, 17035, 17034, 17028, 17032, 17031, 17029, 17033, 17419, 17426, - 17425, 17420, 17424, 17423, 17421, 17422, 17407, 41412, 17411, 17408, - 17410, 17409, 41412, 41412, 17217, 17225, 17224, 17218, 17222, 17221, - 17219, 17223, 17208, 17216, 17215, 17209, 17213, 17212, 17210, 17214, - 17109, 17117, 17116, 17110, 17114, 17113, 17111, 17115, 17187, 17194, - 17193, 17188, 17192, 17191, 17189, 17190, 17175, 41412, 17179, 17176, - 17178, 17177, 41412, 41412, 17168, 17174, 17172, 17169, 17171, 17170, - 17173, 41412, 17163, 41412, 17167, 17164, 17166, 17165, 41412, 41412, - 17391, 17398, 17397, 17392, 17396, 17395, 17393, 17394, 17227, 17233, - 17231, 17228, 17230, 17229, 17232, 41412, 17442, 17450, 17449, 17443, - 17447, 17446, 17444, 17448, 17427, 17434, 17432, 17428, 17430, 17429, - 17433, 17431, 17399, 17406, 17405, 17400, 17404, 17403, 17401, 17402, - 17057, 17065, 17064, 17058, 17062, 17061, 17059, 17063, 17042, 17050, - 17049, 17043, 17047, 17046, 17044, 17048, 17373, 17381, 17380, 17374, - 17378, 17377, 17375, 17379, 17130, 17078, 17136, 17131, 17135, 17134, - 17132, 17133, 17118, 41412, 17122, 17119, 17121, 17120, 41412, 41412, - 17102, 17108, 17106, 17103, 17105, 17104, 17107, 17098, 17333, 17341, - 17340, 17334, 17338, 17337, 17335, 17339, 17018, 17026, 17025, 17019, - 17023, 17022, 17020, 17024, 17226, 17241, 17240, 17234, 17238, 17237, - 17235, 17239, 17356, 17363, 17361, 17357, 17359, 17358, 17362, 17360, - 17348, 17355, 17354, 17349, 17353, 17352, 17350, 17351, 17070, 17077, - 17075, 17071, 17073, 17072, 17076, 17068, 17246, 17253, 17252, 17247, - 17251, 17250, 17248, 17244, 17293, 17205, 17074, 41412, 41412, 16958, - 16960, 16959, 16977, 17480, 17478, 16961, 16976, 16962, 16975, 17479, - 16974, 17476, 17474, 17473, 17470, 17469, 17472, 17471, 17477, 17475, - 16963, 16966, 16965, 16970, 16969, 16973, 16972, 16968, 16971, 16967, - 16964, 41412, 41412, 41412, 17299, 17198, 17196, 17195, 17297, 16981, - 16979, 16978, 17298, 17069, 17067, 17066, 17300, 17245, 17243, 17242, - 17468, 17459, 17465, 17466, 17461, 17463, 17467, 17462, 17460, 17464, - 41412, 41412, 41412, 41412, 41412, 41412, 6484, 6485, 6486, 6487, 6488, - 6489, 6447, 6483, 6448, 6449, 6450, 6451, 6452, 6412, 6413, 6414, 6415, - 6416, 6417, 6453, 6454, 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, - 6463, 6418, 6411, 6419, 6420, 6421, 6422, 6423, 6424, 6465, 6466, 6467, - 6468, 6469, 6470, 6426, 6425, 6427, 6428, 6429, 6430, 6431, 6405, 6444, - 6406, 6445, 6407, 6446, 6408, 6409, 6410, 6404, 6432, 6433, 6434, 6435, - 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6471, 6472, 6473, 6474, - 6475, 6476, 6477, 6478, 6479, 6480, 6481, 6482, 6464, 41412, 41412, 6564, - 6565, 6566, 6567, 6568, 6550, 41412, 41412, 5626, 5598, 5371, 5628, 5629, - 5778, 5792, 6075, 5582, 5442, 5369, 5370, 5952, 6042, 6062, 6040, 6063, - 6041, 6044, 6038, 6045, 6039, 5707, 6059, 6036, 6060, 6037, 5708, 5373, - 6076, 6094, 5615, 5614, 5616, 5617, 5609, 5610, 5607, 5606, 5619, 5613, - 5618, 5608, 5600, 5630, 5791, 5377, 5812, 5805, 5810, 5811, 5807, 5808, - 6066, 5440, 5441, 5803, 5804, 5802, 5981, 5800, 5979, 5801, 5980, 5795, - 5977, 5796, 5978, 5798, 5975, 5799, 5976, 6065, 5794, 5974, 5433, 5951, - 5934, 5949, 5950, 5947, 5948, 6073, 5404, 5417, 5932, 5933, 5942, 6034, - 5940, 6032, 5941, 6033, 5938, 6030, 5939, 6031, 5936, 6028, 5937, 6029, - 5713, 5894, 5929, 5930, 5931, 5928, 5649, 5643, 5647, 5648, 5645, 5646, - 6068, 5641, 5642, 5640, 6026, 5638, 6024, 5639, 6025, 5636, 6022, 5637, - 6023, 5633, 6020, 5634, 6021, 5710, 5631, 5632, 5874, 5875, 5876, 5873, - 5597, 5584, 5595, 5596, 5593, 5594, 6067, 5401, 5583, 5591, 6019, 5589, - 6017, 5590, 6018, 5587, 6015, 5588, 6016, 5585, 6013, 5586, 6014, 5709, - 5400, 5850, 5675, 5683, 5692, 5693, 5678, 5679, 6070, 5681, 5682, 5691, - 5973, 5689, 5971, 5690, 5972, 5687, 5969, 5688, 5970, 5685, 5967, 5686, - 5968, 5711, 5674, 5966, 5694, 5375, 5851, 5767, 5728, 5765, 5766, 5755, - 5756, 6071, 5699, 5727, 5764, 5992, 5758, 5990, 5759, 5991, 5712, 5695, - 5473, 5768, 5673, 5660, 5671, 5672, 5669, 5670, 6069, 5658, 5659, 5668, - 5960, 5666, 5958, 5667, 5959, 5664, 5956, 5665, 5957, 5662, 5954, 5663, - 5955, 5650, 5953, 5676, 5893, 5853, 5891, 5892, 5872, 5877, 6072, 5833, - 5852, 5886, 6012, 5884, 6010, 5885, 6011, 5882, 6008, 5883, 6009, 5880, - 6006, 5881, 6007, 5705, 5832, 5376, 5879, 5396, 5680, 5703, 5706, 5701, - 5702, 5704, 5700, 5871, 5869, 5870, 5863, 5864, 5866, 5867, 5862, 6005, - 5860, 6003, 5861, 6004, 5855, 6001, 5856, 6002, 5858, 5999, 5859, 6000, - 5854, 6093, 6079, 6091, 6092, 6081, 6082, 6074, 6077, 6078, 6090, 5989, - 6088, 5987, 6089, 5988, 6086, 5985, 6087, 5986, 6084, 5983, 6085, 5984, - 5714, 6064, 5397, 5982, 5849, 5831, 5815, 5965, 5825, 5829, 5830, 5827, - 5828, 5963, 5823, 5824, 5961, 5817, 5994, 5813, 5993, 5677, 5625, 5604, - 5605, 5620, 5622, 5623, 5602, 5603, 5624, 6035, 5601, 5913, 5698, 5911, - 5696, 5912, 5697, 5909, 5910, 5907, 5908, 5905, 6027, 5895, 5926, 5927, - 5923, 5921, 5920, 5944, 5945, 5946, 5943, 5753, 5751, 5752, 5749, 5750, - 5747, 5748, 5746, 5754, 5627, 5772, 5776, 5777, 5774, 5775, 5770, 5771, - 5769, 5918, 5919, 5914, 5917, 5996, 5997, 5998, 5995, 5733, 5737, 5738, - 5735, 5736, 5731, 5732, 5730, 5739, 5847, 5848, 5843, 5846, 6055, 6056, - 6057, 6054, 6046, 5656, 5657, 5654, 5655, 5652, 5653, 5651, 5903, 5901, - 5902, 5899, 5900, 5897, 5898, 5896, 5374, 5393, 5394, 5395, 5392, 5381, - 5382, 5383, 5380, 5389, 5390, 5391, 5388, 5385, 5386, 5387, 5384, 5838, - 5839, 5835, 5837, 5423, 5422, 5418, 5419, 5421, 5420, 5569, 5568, 5564, - 5565, 5567, 5566, 5575, 5574, 5570, 5571, 5573, 5572, 5439, 5438, 5434, - 5435, 5437, 5436, 5533, 5532, 5528, 5529, 5531, 5530, 5527, 5526, 5522, - 5523, 5525, 5524, 5496, 5495, 5491, 5492, 5494, 5493, 5490, 5432, 5431, - 5428, 5429, 5430, 5426, 5469, 5468, 5464, 5465, 5467, 5466, 5463, 5462, - 5458, 5459, 5461, 5460, 5457, 5476, 5475, 5470, 5471, 5474, 5472, 5563, - 5562, 5558, 5559, 5561, 5560, 5581, 5580, 5576, 5577, 5579, 5578, 5456, - 5840, 5455, 5450, 5451, 5454, 5842, 5453, 5449, 5448, 5444, 5445, 5447, - 5446, 5551, 5550, 5546, 5547, 5549, 5548, 5410, 5409, 5405, 5406, 5408, - 5407, 5545, 5544, 5540, 5541, 5543, 5542, 5509, 5508, 5504, 5505, 5507, - 5506, 5515, 5514, 5510, 5511, 5513, 5512, 5503, 5502, 5498, 5499, 5501, - 5500, 5497, 5443, 5416, 5415, 5411, 5412, 5414, 5413, 5489, 5488, 5484, - 5485, 5487, 5486, 5483, 5482, 5478, 5479, 5481, 5480, 5477, 5539, 5538, - 5534, 5535, 5537, 5536, 5557, 5556, 5552, 5553, 5555, 5554, 5521, 5520, - 5516, 5517, 5519, 5518, 5592, 5621, 5773, 5734, 5744, 5745, 5742, 5743, - 5740, 5741, 6053, 6051, 6052, 6049, 6050, 6047, 6048, 6058, 5379, 30157, - 30132, 30143, 30139, 30149, 30146, 30152, 30155, 30156, 30135, 30134, - 30154, 30140, 30145, 30150, 30144, 30131, 30147, 30153, 30137, 30141, - 30136, 30148, 30151, 30142, 30138, 30133, 30129, 30130, 41412, 41412, - 41412, 32482, 32538, 32532, 32536, 32535, 32530, 32528, 32475, 32460, - 32506, 32459, 32458, 32503, 32518, 32505, 32509, 32510, 32512, 32498, - 32464, 32497, 32483, 32476, 32484, 32486, 32531, 32488, 32487, 32501, - 32515, 32527, 32517, 32469, 32491, 32472, 32495, 32485, 32500, 32521, - 32492, 32534, 32461, 32524, 32523, 32519, 32462, 32540, 32529, 32520, - 32467, 32526, 32514, 32470, 32508, 32473, 32533, 32502, 32516, 32499, - 32468, 32490, 32489, 32471, 32507, 32474, 32494, 32466, 32465, 32463, - 32525, 32504, 32522, 32493, 32537, 32539, 32541, 32542, 32457, 32543, - 32544, 32456, 32496, 32513, 32511, 32480, 32479, 32481, 32478, 32477, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 35250, 35267, 35268, - 35258, 35256, 35252, 35264, 35255, 35253, 35261, 35254, 35260, 35266, - 35262, 35259, 35265, 35263, 35257, 35271, 35272, 35270, 35269, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 35251, 19806, - 19807, 19808, 19797, 19795, 19791, 19803, 19794, 19792, 19800, 19793, - 19799, 19805, 19801, 19798, 19804, 19802, 19796, 19810, 19811, 19809, - 31612, 31613, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 5092, 5093, 5094, 5083, 5081, 5077, 5089, 5080, 5078, 5086, 5079, - 5085, 5091, 5087, 5084, 5090, 5088, 5082, 5095, 5096, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 35286, 35287, 35288, 35278, 35277, 35273, 35283, 35276, 35274, 35281, - 35275, 35280, 35285, 41412, 35279, 35284, 35282, 41412, 35289, 35290, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 22394, 22392, 22395, 22393, 22396, 22390, 22388, 22391, - 22389, 22398, 22412, 22408, 22413, 22409, 22397, 22410, 22406, 22411, - 22407, 22399, 22420, 22400, 22402, 22401, 22416, 22419, 22417, 22415, - 22418, 22404, 22403, 22405, 22421, 22414, 22422, 22369, 22367, 22377, - 22378, 22373, 22376, 22374, 22375, 22386, 22387, 22384, 22385, 22379, - 22368, 22372, 22371, 22370, 22489, 22488, 22490, 22495, 22497, 22501, - 22503, 22505, 22507, 22506, 22498, 22502, 22496, 22508, 22492, 22493, - 22500, 22494, 22443, 22437, 22442, 22444, 22438, 22428, 22436, 22439, - 22433, 22425, 22426, 22445, 22432, 22427, 22434, 22429, 22431, 22440, - 22430, 22441, 22435, 22366, 22423, 22424, 41412, 41412, 22515, 22517, - 22514, 22513, 22510, 22509, 22512, 22511, 22518, 22516, 41412, 41412, - 41412, 41412, 41412, 41412, 22467, 22466, 22463, 22465, 22464, 22458, - 22461, 22462, 22460, 22459, 41412, 41412, 41412, 41412, 41412, 41412, - 28342, 28354, 28350, 28199, 28349, 28200, 28347, 28338, 28351, 28352, - 28353, 28198, 28197, 28196, 28348, 28195, 28191, 28193, 28190, 28189, - 28186, 28185, 28188, 28187, 28194, 28192, 41412, 41412, 41412, 41412, - 41412, 41412, 28203, 28317, 28334, 28319, 28321, 28320, 28322, 28318, - 28328, 28231, 28323, 28329, 28330, 28326, 28235, 28316, 28278, 28277, - 28308, 28324, 28232, 28327, 28333, 28331, 28332, 28325, 28314, 28313, - 28307, 28311, 28312, 28310, 28315, 28309, 28234, 28287, 28305, 28306, - 28294, 28296, 28295, 28297, 28281, 28298, 28301, 28302, 28288, 28300, - 28291, 28283, 28292, 28285, 28290, 28304, 28303, 28299, 28289, 28293, - 28284, 28286, 28282, 28276, 28261, 28262, 28270, 28269, 28266, 28274, - 28255, 28257, 28275, 28264, 28260, 28271, 28273, 28272, 28256, 28258, - 28259, 28268, 28265, 28263, 28267, 28254, 28252, 28253, 28251, 28250, - 28233, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 28205, 28207, - 28209, 28216, 28215, 28223, 28219, 28204, 28214, 28230, 28217, 28229, - 28221, 28220, 28211, 28218, 28222, 28208, 28225, 28224, 28228, 28226, - 28227, 28206, 28280, 28279, 28243, 28248, 28239, 28244, 28240, 28236, - 28241, 28237, 28249, 28238, 28246, 28247, 28213, 28212, 28242, 28210, - 28245, 41412, 41412, 41412, 41412, 41412, 5793, 5378, 5372, 6061, 5809, - 5806, 5797, 5935, 5644, 5635, 5684, 5757, 5729, 5661, 5878, 5834, 5865, - 5868, 5857, 6083, 6080, 5826, 5762, 5782, 5763, 5783, 5760, 5780, 5761, - 5781, 5822, 5820, 5821, 5818, 5819, 5816, 5789, 5790, 5787, 5786, 5788, - 5779, 5784, 5785, 5599, 6043, 5612, 5611, 5814, 5964, 5962, 5906, 5904, - 5925, 5924, 5922, 5916, 5915, 5845, 5844, 5836, 5425, 5402, 5427, 5424, - 5841, 5452, 5398, 5399, 5403, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 24647, 24614, 24613, 24594, 24593, 24600, - 24608, 24607, 24612, 24611, 24599, 24597, 24595, 24610, 24609, 24601, - 24616, 24615, 24606, 24605, 24619, 24598, 24620, 24618, 24621, 24602, - 24603, 24604, 24617, 24592, 24596, 41412, 24638, 24645, 24646, 24644, - 24639, 24642, 24640, 24643, 24641, 24637, 24635, 24636, 41412, 41412, - 41412, 41412, 24629, 24626, 24628, 24634, 24627, 24632, 24631, 24633, - 24630, 24623, 24622, 24624, 41412, 41412, 41412, 41412, 24625, 41412, - 41412, 41412, 24648, 24649, 24656, 24658, 24655, 24654, 24651, 24650, - 24653, 24652, 24659, 24657, 35311, 35323, 35306, 35303, 35321, 35324, - 35305, 35304, 35318, 35313, 35312, 35319, 35316, 35322, 35317, 35320, - 35310, 35302, 35307, 35291, 35325, 35295, 35296, 35314, 35309, 35308, - 35315, 35294, 35292, 35293, 41412, 41412, 35297, 35298, 35299, 35300, - 35301, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 29300, 29322, 29282, 29284, 29287, 29304, 29306, 29309, - 29290, 29286, 29302, 29312, 29308, 29324, 29291, 29289, 29288, 29313, - 29311, 29310, 29293, 29292, 29299, 29315, 29314, 29321, 29296, 29301, - 29298, 29318, 29323, 29320, 29297, 29295, 29294, 29319, 29317, 29316, - 29281, 29283, 29303, 29305, 29285, 29307, 41412, 41412, 41412, 41412, - 29345, 29330, 29334, 29340, 29343, 29346, 29332, 29336, 29337, 29341, - 29333, 29331, 29344, 29339, 29338, 29342, 29335, 29280, 29275, 29274, - 29279, 29278, 29277, 29276, 29327, 29328, 41412, 41412, 41412, 41412, - 41412, 41412, 29353, 29355, 29352, 29351, 29348, 29347, 29350, 29349, - 29356, 29354, 29329, 41412, 41412, 41412, 29325, 29326, 22468, 22487, - 22480, 22483, 22485, 22478, 22476, 22474, 22470, 22472, 22457, 22455, - 22447, 22451, 22453, 22449, 22481, 22486, 22479, 22482, 22484, 22477, - 22475, 22473, 22469, 22471, 22456, 22454, 22446, 22450, 22452, 22448, - 5061, 5058, 5050, 5049, 5063, 5055, 5048, 5047, 5066, 5057, 5054, 5053, - 5056, 5060, 5052, 5051, 5068, 5064, 5062, 5067, 5065, 5069, 5059, 5072, - 5074, 5071, 5073, 5070, 41412, 41412, 5076, 5075, 35359, 35357, 35358, - 35375, 35374, 35373, 35399, 35365, 35364, 35378, 35385, 35377, 35400, - 35393, 35360, 35405, 35376, 35392, 35369, 35368, 35382, 35381, 35401, - 35404, 35367, 35366, 35370, 35380, 35383, 35379, 35406, 35386, 35372, - 35391, 35394, 35387, 35389, 35407, 35361, 35362, 35363, 35371, 35390, - 35408, 35384, 35397, 35398, 35395, 35396, 35403, 35402, 35388, 35356, - 35331, 35330, 35328, 35419, 35326, 35327, 35329, 35332, 35333, 35334, - 41412, 35427, 35434, 35438, 35435, 35444, 35450, 35451, 35449, 35448, - 35446, 35447, 35439, 35440, 35443, 35452, 35436, 35442, 35437, 35445, - 35441, 35418, 35431, 35432, 35411, 35412, 35413, 35422, 35421, 35414, - 41412, 41412, 35335, 35342, 35344, 35341, 35340, 35337, 35336, 35339, - 35338, 35345, 35343, 41412, 41412, 41412, 41412, 41412, 41412, 35352, - 35354, 35351, 35350, 35347, 35346, 35349, 35348, 35355, 35353, 41412, - 41412, 41412, 41412, 41412, 41412, 35428, 35429, 35426, 35417, 35410, - 35430, 35423, 35420, 35415, 35416, 35424, 35425, 35409, 35433, 41412, - 41412, 8313, 8277, 8402, 8316, 8561, 8580, 8579, 8509, 8297, 8483, 8548, - 8515, 8301, 8514, 8513, 8450, 8444, 8468, 8531, 8469, 8532, 8545, 8502, - 8401, 8518, 8300, 8299, 8559, 8428, 8429, 8430, 8293, 8572, 8382, 8574, - 8165, 8576, 8495, 8573, 8575, 8497, 8544, 8328, 8315, 8276, 8283, 41412, - 41412, 8474, 8534, 8501, 8399, 8547, 8552, 8286, 8287, 8325, 8461, 8566, - 8303, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 2762, 2761, 2763, 2760, 2764, 2671, 2672, 2688, 2689, 2692, 2693, - 2710, 2711, 2701, 2702, 2685, 2675, 2690, 2691, 2696, 2698, 2686, 2687, - 2705, 2678, 2679, 2694, 2695, 2706, 2717, 2716, 2682, 2681, 2704, 2715, - 2718, 2680, 2683, 2703, 2707, 2708, 2676, 2677, 2723, 2725, 2709, 2700, - 2724, 2713, 2714, 2712, 2722, 2765, 2776, 2779, 2780, 2770, 2771, 2768, - 2769, 2766, 2767, 2772, 2773, 2775, 2774, 2777, 2778, 2781, 2697, 2699, - 2719, 2684, 2720, 2721, 2673, 2674, 41412, 2670, 2669, 2789, 2791, 2788, - 2787, 2784, 2783, 2786, 2785, 2792, 2790, 2757, 2754, 2782, 2667, 2668, - 2666, 2756, 2743, 2741, 2744, 2735, 2736, 2742, 2738, 2740, 2739, 2737, - 2733, 2732, 2728, 2726, 2730, 2729, 2727, 2731, 2734, 2753, 2752, 2751, - 2750, 2745, 2747, 2748, 2749, 2746, 2758, 2755, 2759, 34858, 34856, - 34857, 34809, 34844, 34846, 34811, 34845, 34821, 34822, 34829, 34837, - 34832, 34823, 34830, 34834, 34843, 34824, 34838, 34831, 34825, 34836, - 34814, 34839, 34827, 34835, 34842, 34818, 34816, 34840, 34820, 34841, - 34833, 34804, 34805, 34806, 34864, 34863, 34865, 34862, 34860, 34861, - 34855, 34859, 34807, 34808, 34828, 34819, 34872, 34874, 34871, 34870, - 34867, 34866, 34869, 34868, 34875, 34873, 34803, 34817, 34815, 34826, - 34812, 34813, 3557, 3543, 3551, 3535, 3523, 3547, 3546, 3532, 3538, 3531, - 3524, 3555, 3541, 3533, 3550, 3534, 3552, 3549, 3554, 3539, 3522, 3537, - 3544, 3527, 3545, 3540, 3525, 3556, 3542, 3529, 3553, 3536, 3530, 3548, - 3528, 3526, 3558, 3559, 3566, 3572, 3569, 3573, 3574, 3570, 3575, 3571, - 3567, 3568, 3520, 3521, 3560, 3561, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 3565, 3563, 3564, 3562, 24476, 24475, 24474, 24488, - 24487, 24493, 24503, 24502, 24506, 24494, 24501, 24500, 24482, 24495, - 24479, 24478, 24477, 24486, 24485, 24484, 24483, 24492, 24491, 24497, - 24496, 24481, 24511, 24508, 24507, 24490, 24489, 24509, 24505, 24504, - 24510, 24512, 24521, 24520, 24526, 24528, 24524, 24525, 24522, 24523, - 24527, 24465, 24470, 24469, 24467, 24471, 24472, 24473, 24468, 24466, - 24519, 24518, 41412, 41412, 41412, 24513, 24516, 24517, 24515, 24514, - 24535, 24537, 24534, 24533, 24530, 24529, 24532, 24531, 24538, 24536, - 41412, 41412, 41412, 24499, 24498, 24480, 30203, 30205, 30202, 30201, - 30198, 30197, 30200, 30199, 30206, 30204, 30176, 30167, 30165, 30164, - 30166, 30177, 30161, 30160, 30162, 30163, 30179, 30175, 30173, 30172, - 30174, 30181, 30187, 30188, 30186, 30189, 30178, 30171, 30168, 30170, - 30169, 30180, 30182, 30183, 30185, 30184, 30191, 30192, 30190, 30196, - 30195, 30207, 30194, 30193, 10562, 10539, 10545, 10602, 10583, 10591, - 10581, 10582, 10601, 10267, 10593, 41412, 41412, 41412, 41412, 41412, - 18013, 18044, 18021, 18050, 18019, 18049, 18042, 18039, 18051, 18031, - 18033, 18045, 18047, 18052, 18035, 18041, 18043, 18037, 18040, 18053, - 18034, 18030, 18020, 18048, 18036, 18014, 18017, 18029, 18016, 18015, - 18046, 18028, 18024, 18027, 18025, 18055, 18022, 18026, 18056, 18054, - 18018, 18038, 18012, 41412, 41412, 18011, 18023, 18032, 34854, 34852, - 34853, 34851, 34850, 34849, 34848, 34847, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 39257, 39270, 39259, 39237, 39251, 39265, - 39266, 39267, 39252, 39268, 39255, 39263, 39258, 39256, 39264, 39262, - 39261, 39269, 39250, 39248, 39239, 39246, 39238, 39249, 39247, 39228, - 39229, 39231, 39232, 39244, 39242, 39243, 39241, 39230, 39234, 39240, - 39253, 39236, 39245, 39233, 39260, 39254, 39235, 41412, 41412, 41412, - 41412, 41412, 23439, 23440, 24047, 23436, 23441, 23442, 23413, 23412, - 24032, 24025, 23445, 23446, 23419, 23447, 23425, 23420, 23421, 23982, - 23983, 23984, 24027, 23423, 24019, 23538, 23449, 23426, 23434, 23429, - 23452, 23987, 23986, 23985, 23453, 23454, 23456, 23414, 23466, 23400, - 18557, 18560, 18556, 18559, 18555, 10432, 27880, 27881, 27871, 27872, - 27883, 27884, 27874, 27886, 27876, 27887, 27888, 27889, 27890, 27891, - 27892, 27875, 27878, 27879, 27893, 27873, 27896, 27897, 27899, 28030, - 28137, 28031, 28139, 28034, 28059, 28073, 28127, 28112, 28142, 28080, - 28150, 28161, 28090, 28077, 28110, 28113, 28134, 28036, 28114, 28129, - 28154, 28128, 28140, 28158, 28032, 28038, 28081, 28064, 28082, 28058, - 24188, 24196, 24198, 24199, 18766, 18762, 18765, 18764, 18763, 24108, - 23524, 23573, 23659, 23802, 23822, 23899, 23927, 23920, 23966, 24002, - 24170, 24054, 27948, 23730, 24012, 23468, 23737, 23895, 23469, 24107, - 23525, 23577, 23660, 23673, 23756, 23783, 23803, 23828, 23900, 23930, - 23967, 23646, 24115, 24142, 24171, 23487, 23513, 23576, 23636, 23888, - 23937, 23975, 23727, 23884, 23648, 24094, 23654, 28138, 28039, 28057, - 28075, 28121, 28078, 28065, 28126, 28149, 28092, 28093, 28040, 28042, - 28095, 28099, 28101, 28045, 28091, 28141, 28109, 28108, 28051, 28035, - 28115, 28125, 28074, 28130, 28156, 28157, 28053, 28160, 28151, 28070, - 28072, 28071, 28076, 28153, 8285, 8284, 8550, 8549, 8496, 8384, 8498, - 8167, 8383, 8166, 8442, 8179, 8499, 8294, 8511, 8539, 8403, 8567, 8568, - 8425, 8416, 8417, 8418, 8420, 8427, 8423, 8452, 8408, 8454, 8431, 8409, - 8410, 8456, 8411, 8412, 8441, 8445, 8433, 8460, 8415, 8447, 8448, 8446, - 8424, 8432, 8436, 8457, 8422, 8439, 8449, 8414, 8435, 8438, 8564, 8407, - 8406, 8279, 8577, 8282, 8273, 8292, 8176, 8465, 8522, 22921, 23485, - 22957, 23527, 22956, 23526, 22955, 23523, 22964, 23542, 22989, 23579, - 22988, 23578, 22987, 23574, 22983, 23568, 22984, 23569, 23017, 23622, - 23018, 23623, 23006, 23610, 23015, 23620, 22997, 23601, 23042, 23662, - 23050, 23672, 23069, 23692, 23068, 23691, 23066, 23689, 23063, 23686, - 23062, 23685, 23086, 23719, 23080, 23707, 23117, 23754, 23114, 23751, - 23118, 23755, 23125, 23768, 23126, 23769, 23136, 23778, 23132, 23765, - 23142, 23800, 23144, 23805, 23143, 23804, 23162, 23827, 23161, 23826, - 23156, 23819, 23152, 23814, 23193, 23863, 23192, 23862, 23170, 23855, - 23171, 23856, 23221, 23898, 23223, 23902, 23233, 23917, 23231, 23915, - 23232, 23916, 23238, 23922, 23259, 23960, 23257, 23958, 23256, 23951, - 23251, 23953, 23258, 23959, 23280, 24000, 23279, 23999, 23281, 24003, - 23275, 23993, 23311, 24075, 23332, 24098, 23304, 24068, 23331, 24097, - 23323, 24087, 23344, 24118, 23343, 24114, 23357, 24131, 23358, 24132, - 23354, 24128, 23356, 24130, 23355, 24129, 23363, 24137, 23362, 24136, - 23368, 24147, 23379, 24161, 23383, 24165, 23385, 24167, 23693, 23998, - 24133, 24157, 23486, 23793, 23792, 23794, 23269, 23583, 22915, 23479, - 22931, 23497, 22927, 23493, 22926, 23492, 22925, 23491, 22929, 23495, - 22928, 23494, 22910, 23474, 22909, 23473, 22908, 23472, 22912, 23476, - 22911, 23475, 23011, 23615, 23022, 23628, 23014, 23619, 23002, 23606, - 23001, 23605, 23000, 23604, 23005, 23609, 23004, 23608, 23087, 23720, - 23077, 23711, 23184, 23848, 23204, 23874, 23176, 23840, 23175, 23839, - 23174, 23838, 23178, 23842, 23177, 23841, 23201, 23871, 23200, 23870, - 23199, 23869, 23203, 23873, 23202, 23872, 23314, 24078, 23321, 24085, - 23318, 24082, 23317, 24081, 23316, 24080, 23320, 24084, 23319, 24083, - 23369, 24148, 23367, 24146, 23371, 24150, 23375, 24156, 23147, 23808, - 23148, 23809, 23372, 24151, 18604, 18596, 18609, 18601, 18605, 18597, - 18607, 18599, 18370, 18362, 18373, 18365, 18371, 18363, 18375, 18367, - 18627, 18624, 18629, 18626, 18628, 18625, 41412, 41412, 18410, 18407, - 18412, 18409, 18411, 18408, 41412, 41412, 18642, 18634, 18647, 18639, - 18643, 18635, 18645, 18637, 18394, 18386, 18397, 18389, 18395, 18387, - 18399, 18391, 18668, 18659, 18671, 18662, 18670, 18661, 18669, 18660, - 18422, 18417, 18425, 18420, 18424, 18419, 18423, 18418, 18729, 18726, - 18731, 18728, 18730, 18727, 41412, 41412, 18456, 18453, 18458, 18455, - 18457, 18454, 41412, 41412, 18688, 18679, 18691, 18682, 18690, 18681, - 18689, 18680, 41412, 18468, 41412, 18471, 41412, 18470, 41412, 18469, - 18709, 18701, 18714, 18706, 18710, 18702, 18712, 18704, 18440, 18432, - 18443, 18435, 18441, 18433, 18445, 18437, 18594, 18614, 18631, 18630, - 18654, 18652, 18674, 18675, 18733, 18732, 18694, 18695, 18721, 18719, - 41412, 41412, 18611, 18603, 18610, 18602, 18606, 18598, 18608, 18600, - 18377, 18369, 18374, 18366, 18372, 18364, 18376, 18368, 18649, 18641, - 18648, 18640, 18644, 18636, 18646, 18638, 18401, 18393, 18398, 18390, - 18396, 18388, 18400, 18392, 18716, 18708, 18715, 18707, 18711, 18703, - 18713, 18705, 18447, 18439, 18444, 18436, 18442, 18434, 18446, 18438, - 18593, 18618, 18595, 18616, 18615, 41412, 18612, 18613, 18379, 18383, - 18380, 18381, 18378, 18553, 18581, 18582, 18586, 18502, 18655, 18656, - 18653, 41412, 18650, 18651, 18414, 18413, 18404, 18403, 18402, 18585, - 18584, 18583, 18673, 18677, 18666, 18665, 41412, 41412, 18672, 18664, - 18426, 18430, 18427, 18428, 41412, 18510, 18509, 18508, 18693, 18697, - 18686, 18685, 18741, 18740, 18692, 18684, 18473, 18477, 18474, 18475, - 18463, 18504, 18503, 18780, 41412, 41412, 18722, 18723, 18720, 41412, - 18717, 18718, 18460, 18459, 18450, 18449, 18448, 18578, 18507, 41412, - 16898, 16895, 16900, 16897, 37416, 17650, 33984, 17575, 31904, 37389, - 19135, 41218, 41217, 41219, 24357, 32233, 20617, 29541, 17574, 16899, - 16896, 20561, 11383, 11357, 24280, 32163, 33859, 33857, 24233, 32128, - 11356, 11351, 10661, 11350, 5097, 38001, 30706, 38148, 20584, 20620, - 24665, 31245, 24356, 32232, 31778, 24355, 32231, 29142, 31481, 31482, - 31864, 11365, 38015, 32071, 32065, 32079, 6109, 33858, 33860, 32088, - 11387, 20959, 31059, 38199, 6395, 6110, 2572, 20619, 17654, 24288, 32174, - 11388, 31928, 17489, 37790, 32070, 3956, 3998, 25334, 32076, 8150, 38160, - 8583, 34967, 20977, 17614, 37396, 31924, 17643, 17600, 38149, 17644, - 11329, 38026, 39278, 27150, 39824, 17777, 20979, 20981, 20980, 41412, - 24354, 32230, 17593, 31777, 20873, 7, 20872, 6, 29137, 29539, 34938, - 34926, 41412, 41412, 34933, 34932, 34935, 34934, 34925, 34939, 34929, - 34931, 34924, 34928, 34930, 34927, 34768, 34770, 34767, 34766, 34763, - 34762, 34765, 34764, 34758, 34769, 34759, 34761, 34757, 34756, 34760, - 41412, 24185, 24186, 24194, 24200, 24184, 24187, 24190, 24191, 24192, - 24193, 24195, 24183, 24197, 41412, 41412, 41412, 17485, 8163, 8829, - 17661, 25273, 27765, 29070, 31505, 32553, 39828, 29273, 11323, 17486, - 22718, 38036, 11505, 18058, 31506, 18830, 2585, 20625, 6228, 25274, - 34320, 37161, 20863, 38118, 29591, 25839, 32422, 22902, 3862, 34300, - 32714, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 8472, 8530, 8487, 8543, 8172, 8188, - 8467, 8527, 8536, 8187, 8171, 8553, 8327, 8317, 8320, 8323, 8318, 8476, - 8319, 8321, 8322, 8519, 8308, 8173, 8560, 8578, 8478, 8484, 8535, 8477, - 8466, 8526, 8175, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 0, 100, 11399, 10685, - 6232, 6111, 5362, 17488, 32742, 10687, 32739, 32731, 4046, 11400, 31667, - 31668, 32732, 4047, 32733, 32740, 25511, 11401, 29635, 34216, 32735, - 11397, 11402, 32736, 4048, 11403, 31840, 32049, 32845, 37055, 37986, - 39271, 11404, 31053, 31063, 20976, 4049, 38141, 21773, 963, 32728, 4045, - 16955, 32738, 32729, 32730, 38125, 32734, 32741, 348, 3753, 18061, 10674, - 20870, 32410, 17554, 11411, 11410, 11396, 11398, 11412, 38134, 38135, - 32075, 38136, 11409, 11405, 11406, 11407, 11408, 31868, 38120, 31483, - 2643, 38138, 35046, 39422, 39420, 39424, 39425, 39430, 39418, 39429, - 39428, 39416, 39423, 39415, 39417, 39426, 39414, 39431, 17655, 32378, - 32389, 32390, 32377, 32374, 32383, 32385, 32393, 32394, 32386, 32392, - 32388, 32371, 32379, 32375, 32381, 34046, 34050, 34051, 34045, 34042, - 34054, 34053, 34041, 34055, 34052, 34040, 34049, 34044, 34047, 34043, - 34048, 32382, 32376, 32387, 32391, 23943, 32384, 32373, 32372, 32380, - 39432, 38129, 38128, 41412, 41412, 41412, 41412, 24358, 38350, 32235, - 11441, 24262, 38221, 29572, 29545, 34188, 34203, 24378, 32259, 24442, - 32336, 24439, 38400, 32335, 11477, 24381, 32262, 24389, 38363, 32242, - 11455, 38222, 24387, 32268, 24372, 32254, 24270, 24265, 11481, 38360, - 38361, 11450, 11451, 32250, 11442, 974, 8134, 29574, 24369, 979, 8136, - 24408, 24402, 38377, 38374, 32295, 32289, 11492, 11489, 32270, 38352, - 24392, 24454, 38403, 32302, 11500, 24409, 32296, 24445, 24269, 32278, - 24443, 38367, 32276, 11482, 24267, 38224, 29585, 29558, 34200, 34213, - 24429, 32326, 24458, 32306, 38353, 11443, 24449, 38368, 32282, 11483, - 24368, 32249, 24440, 38404, 32337, 11479, 38409, 38405, 38407, 38406, - 38411, 38412, 32338, 29573, 34191, 38226, 32115, 11453, 37404, 24388, - 32269, 24264, 24374, 32252, 24263, 24453, 32301, 24272, 17639, 8588, - 31391, 37383, 37382, 16888, 20791, 29026, 16837, 29594, 34026, 8596, - 11149, 34019, 16902, 28985, 28973, 28977, 27769, 27776, 11324, 11131, - 32850, 2571, 32347, 5098, 34547, 8835, 17649, 31867, 20864, 32105, 959, - 27024, 34323, 11135, 11150, 31250, 29599, 25288, 25295, 20952, 38201, - 20937, 11354, 38025, 8602, 34960, 39410, 8137, 8128, 976, 37384, 3754, - 31959, 31866, 11325, 17491, 17883, 20605, 37694, 32077, 20973, 33979, - 39832, 29604, 27775, 2578, 29595, 1058, 1061, 29229, 364, 29596, 366, - 38016, 361, 16941, 17881, 11141, 1062, 17882, 1059, 20754, 8162, 16939, - 32345, 32346, 8781, 16956, 16942, 34712, 10690, 16924, 27035, 31930, - 29606, 20630, 29607, 34749, 24558, 18294, 24560, 18297, 24549, 18287, - 28722, 28721, 3752, 29605, 29609, 29608, 29234, 29231, 24557, 18293, - 29233, 29230, 24559, 18295, 29235, 29232, 31841, 34786, 31850, 34795, - 31849, 34794, 11152, 11155, 34774, 34946, 29592, 29593, 34780, 34952, - 29227, 29228, 34779, 34951, 28475, 28476, 28477, 34420, 34509, 34422, - 34511, 34355, 34362, 6909, 6855, 6914, 6647, 6660, 6910, 6636, 6919, - 6661, 34680, 34673, 34694, 34628, 32192, 24306, 11418, 38230, 2579, - 27784, 38033, 17640, 38019, 11381, 11154, 29603, 11157, 29226, 31851, - 34796, 29589, 8597, 29590, 8598, 30738, 20753, 28478, 20376, 20960, - 39853, 29071, 29544, 32111, 32188, 28982, 28983, 28984, 28978, 10969, - 11326, 34714, 11133, 4474, 24320, 32150, 24278, 32161, 32078, 10078, - 10077, 11375, 11374, 11353, 11378, 31661, 16925, 24563, 18303, 39321, - 39320, 24547, 18298, 16923, 16922, 16920, 16921, 11153, 11156, 29600, - 29601, 34421, 34510, 24548, 18286, 31848, 34793, 29597, 11147, 29598, - 11148, 39277, 27761, 38229, 11421, 16838, 16840, 34027, 16843, 16842, - 34028, 16841, 16839, 8599, 8600, 34020, 8601, 34021, 41130, 10970, 16835, - 20599, 38213, 11422, 31865, 31500, 39596, 24229, 32123, 24317, 32132, - 4457, 4454, 37934, 37930, 32068, 34453, 2567, 32752, 32748, 37053, 31786, - 39334, 31664, 38132, 39587, 20597, 37929, 37933, 4453, 4456, 37923, 4451, - 17665, 34086, 38214, 30728, 16952, 39837, 21775, 24327, 32213, 16951, - 3700, 10656, 362, 35056, 37950, 11142, 8607, 34011, 8783, 8784, 1004, + 2161, 9891, 9881, 9895, 9900, 9816, 9790, 9791, 9860, 9861, 9836, 9837, + 9855, 9857, 9798, 9817, 9868, 9792, 9799, 9818, 9831, 9793, 9827, 9826, + 9811, 9809, 9842, 9796, 9800, 9847, 9845, 9843, 9852, 9851, 9804, 9803, + 9841, 9854, 9853, 9806, 9805, 9844, 9840, 9863, 9862, 9824, 9823, 9814, + 9835, 9830, 9829, 9850, 9849, 9848, 9859, 9819, 9820, 9821, 9813, 9913, + 9912, 9893, 9894, 9903, 9925, 9926, 9915, 9916, 9921, 9922, 9909, 9919, + 9927, 9904, 9910, 9920, 9911, 9905, 9899, 9914, 9906, 9941, 9902, 9901, + 9785, 9782, 9908, 9918, 9917, 9867, 9825, 9808, 9865, 9801, 9828, 9866, + 9834, 9856, 9858, 9923, 9924, 9929, 9928, 9936, 9938, 9935, 9934, 9931, + 9930, 9933, 9932, 9939, 9937, 9783, 9898, 9797, 9833, 9832, 9794, 9839, + 9838, 9815, 9864, 9812, 9810, 9846, 9807, 9802, 9822, 3599, 3667, 3670, + 3672, 35536, 3623, 3624, 3637, 3638, 3635, 3636, 3617, 3619, 35536, + 35536, 3659, 3625, 35536, 35536, 3660, 3626, 3610, 3607, 3651, 3650, + 3639, 3649, 3648, 3653, 3652, 3641, 3632, 3631, 3628, 3627, 3640, 3634, + 3633, 3630, 3629, 3642, 35536, 3655, 3654, 3647, 3646, 3658, 3622, 3611, + 35536, 3657, 35536, 35536, 35536, 3643, 3644, 3645, 3656, 35536, 35536, + 3668, 3669, 3674, 3683, 3684, 3677, 3678, 3679, 3680, 35536, 35536, 3685, + 3675, 35536, 35536, 3686, 3676, 3671, 3608, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 3600, 35536, 35536, 35536, 35536, 3615, 3614, + 35536, 3621, 3618, 3620, 3681, 3682, 35536, 35536, 3693, 3695, 3692, + 3691, 3688, 3687, 3690, 3689, 3696, 3694, 3613, 3612, 3662, 3661, 3601, + 3605, 3604, 3603, 3602, 3606, 3673, 3697, 3616, 3598, 3666, 35536, 35536, + 14035, 14036, 14041, 35536, 13987, 13988, 14003, 14004, 14001, 14002, + 35536, 35536, 35536, 35536, 14022, 13989, 35536, 35536, 14021, 13990, + 13986, 13985, 13983, 13982, 14007, 14014, 14013, 14016, 14015, 14009, + 13998, 13997, 13992, 13991, 14008, 14000, 13999, 13994, 13993, 14010, + 35536, 14018, 14017, 14012, 14011, 14025, 14027, 13996, 35536, 14006, + 14005, 35536, 14026, 14019, 35536, 14020, 14024, 35536, 35536, 14038, + 35536, 14042, 14047, 14048, 14045, 14046, 35536, 35536, 35536, 35536, + 14050, 14043, 35536, 35536, 14049, 14044, 14040, 35536, 35536, 35536, + 14037, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 13984, 13981, + 14028, 13995, 35536, 14023, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 14060, 14062, 14059, 14058, 14055, 14054, 14057, 14056, 14063, + 14061, 14051, 13980, 14052, 14064, 14053, 14039, 13979, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 13875, 13883, + 13885, 35536, 13825, 13826, 13844, 13845, 13842, 13843, 13837, 13839, + 13901, 35536, 13872, 13827, 13902, 35536, 13873, 13828, 13865, 13864, + 13861, 13860, 13849, 13859, 13858, 13863, 13862, 13851, 13834, 13833, + 13830, 13829, 13850, 13836, 13835, 13832, 13831, 13852, 35536, 13867, + 13866, 13857, 13856, 13869, 13871, 13870, 35536, 13847, 13846, 35536, + 13841, 13853, 13854, 13855, 13868, 35536, 35536, 13881, 13882, 13888, + 13897, 13898, 13891, 13892, 13893, 13894, 13886, 35536, 13899, 13889, + 13887, 35536, 13900, 13890, 13884, 35536, 35536, 13915, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 13838, 13840, 13895, 13896, 35536, 35536, 13911, + 13913, 13910, 13909, 13906, 13905, 13908, 13907, 13914, 13912, 13903, + 13904, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 13848, 13880, + 13879, 13876, 13878, 13874, 13877, 35536, 24926, 24929, 24932, 35536, + 24877, 24878, 24896, 24897, 24894, 24895, 24889, 24891, 35536, 35536, + 24922, 24879, 35536, 35536, 24923, 24880, 24916, 24915, 24912, 24911, + 24900, 24910, 24909, 24914, 24913, 24902, 24886, 24885, 24882, 24881, + 24901, 24888, 24887, 24884, 24883, 24903, 35536, 24918, 24917, 24908, + 24907, 24920, 24876, 24874, 35536, 24899, 24898, 35536, 24893, 24904, + 24905, 24906, 24919, 35536, 35536, 24927, 24928, 24933, 24942, 24943, + 24936, 24937, 24938, 24939, 35536, 35536, 24944, 24934, 35536, 35536, + 24945, 24935, 24931, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 24930, 24863, 24864, 35536, 35536, 35536, 35536, 24873, 24872, 35536, + 24875, 24890, 24892, 24940, 24941, 35536, 35536, 24952, 24954, 24951, + 24950, 24947, 24946, 24949, 24948, 24955, 24953, 24871, 24921, 24868, + 24867, 24870, 24865, 24866, 24869, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 29884, 29901, 35536, 29847, 29848, + 29860, 29861, 29856, 29857, 35536, 35536, 35536, 29865, 29866, 29849, + 35536, 29858, 29859, 29850, 29870, 35536, 35536, 35536, 29842, 29867, + 35536, 29869, 35536, 29843, 29845, 35536, 35536, 35536, 29841, 29846, + 35536, 35536, 35536, 29844, 29840, 29872, 35536, 35536, 35536, 29871, + 29874, 29855, 29854, 29853, 29852, 29851, 29873, 29862, 29863, 29864, + 29868, 35536, 35536, 35536, 35536, 30174, 30181, 30182, 30177, 30178, + 35536, 35536, 35536, 30183, 30184, 30175, 35536, 30179, 30180, 30176, + 29900, 35536, 35536, 30187, 35536, 35536, 35536, 35536, 35536, 35536, + 29776, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 29813, 29815, 29812, 29811, 29808, + 29807, 29810, 29809, 29816, 29814, 29878, 29876, 29877, 29806, 30186, + 30185, 29805, 29803, 29775, 29881, 29879, 35536, 35536, 35536, 35536, + 35536, 31250, 31251, 31256, 31258, 31249, 31210, 31211, 31226, 31227, + 31222, 31223, 31217, 31219, 35536, 31243, 31244, 31212, 35536, 31224, + 31225, 31213, 31240, 31239, 31236, 31235, 31199, 31234, 31233, 31238, + 31237, 31201, 31206, 31205, 31193, 31192, 31200, 31209, 31207, 31196, + 31194, 31197, 35536, 31242, 31241, 31232, 31231, 31246, 31247, 31204, + 31203, 31216, 31215, 31214, 31221, 31228, 31229, 31230, 31245, 35536, + 35536, 31254, 31255, 31259, 31270, 31271, 31262, 31263, 31264, 31265, + 35536, 31272, 31273, 31260, 35536, 31268, 31269, 31261, 31257, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 31248, 31184, 35536, 31208, + 31195, 31202, 35536, 31183, 31198, 35536, 35536, 31218, 31220, 31266, + 31267, 35536, 35536, 31280, 31282, 31279, 31278, 31275, 31274, 31277, + 31276, 31283, 31281, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 31252, 31191, 31189, 31187, 31185, 31190, 31188, 31186, 31253, 16427, + 16426, 16431, 16435, 16428, 16375, 16376, 16401, 16402, 16397, 16398, + 16392, 16394, 35536, 16418, 16419, 16377, 35536, 16399, 16400, 16378, + 16415, 16414, 16411, 16410, 16372, 16409, 16408, 16413, 16412, 16374, + 16389, 16388, 16380, 16379, 16373, 16391, 16390, 16382, 16381, 16370, + 35536, 16417, 16416, 16407, 16406, 16422, 16423, 16387, 16386, 16385, + 16384, 35536, 16396, 16403, 16404, 16405, 16421, 35536, 35536, 16429, + 16430, 16438, 16449, 16450, 16441, 16442, 16443, 16444, 35536, 16451, + 16452, 16439, 35536, 16447, 16448, 16440, 16434, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 16424, 16437, 35536, 35536, 35536, 35536, + 35536, 16436, 16371, 16420, 35536, 16393, 16395, 16445, 16446, 35536, + 35536, 16459, 16461, 16458, 16457, 16454, 16453, 16456, 16455, 16462, + 16460, 35536, 16432, 16433, 16425, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 20239, 20241, 20246, + 20244, 20196, 20170, 20172, 20216, 20217, 20212, 20213, 20197, 20199, + 35536, 20231, 20232, 20173, 35536, 20214, 20215, 20174, 20228, 20227, + 20224, 20223, 20204, 20185, 20184, 20226, 20225, 20205, 20193, 20191, + 20188, 20187, 20203, 20195, 20194, 20190, 20189, 20206, 20202, 20230, + 20229, 20222, 20221, 20234, 20235, 20211, 20210, 20209, 20208, 20207, + 20201, 20218, 20219, 20220, 20233, 20192, 20242, 20240, 20245, 20248, + 20259, 20260, 20251, 20252, 20253, 20254, 35536, 20261, 20262, 20249, + 35536, 20257, 20258, 20250, 20243, 20186, 20247, 35536, 35536, 35536, + 35536, 20182, 20183, 20177, 20263, 20162, 20160, 20167, 20157, 20158, + 20168, 20161, 20171, 20198, 20200, 20255, 20256, 35536, 35536, 20153, + 20155, 20152, 20151, 20148, 20147, 20150, 20149, 20156, 20154, 20238, + 20236, 20237, 20165, 20164, 20169, 20159, 20163, 20166, 20146, 20179, + 20178, 20180, 20175, 20176, 20181, 35536, 28083, 28082, 28084, 35536, + 28028, 28025, 28013, 28012, 28036, 28035, 28038, 28037, 28034, 28033, + 28032, 28031, 28030, 28029, 28026, 28057, 28056, 28027, 35536, 35536, + 35536, 28022, 28047, 28020, 28045, 28070, 28060, 28019, 28044, 28021, + 28046, 28067, 28068, 28061, 28014, 28039, 28016, 28041, 28051, 28058, + 28015, 28040, 28017, 28042, 28054, 35536, 28059, 28023, 28048, 28018, + 28043, 28049, 28024, 28066, 28064, 35536, 28053, 35536, 35536, 28065, + 28069, 28052, 28055, 28063, 28050, 28062, 35536, 35536, 35536, 28081, + 35536, 35536, 35536, 35536, 28101, 28093, 28088, 28094, 28089, 28095, + 35536, 28090, 35536, 28091, 28096, 28087, 28100, 28097, 28098, 28099, + 28092, 35536, 35536, 35536, 35536, 35536, 35536, 28077, 28079, 28076, + 28075, 28072, 28071, 28074, 28073, 28080, 28078, 35536, 35536, 28085, + 28086, 28102, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 31437, 31434, 31432, 31431, 31433, 31435, + 31451, 31420, 31422, 31421, 31480, 31423, 31492, 31424, 31489, 31485, + 31482, 31483, 31453, 31425, 31488, 31487, 31484, 31486, 31454, 31419, + 31460, 31457, 31426, 31458, 31427, 31459, 31449, 31493, 31461, 31462, + 31439, 31441, 31490, 31478, 31477, 31479, 31430, 31438, 31494, 31429, + 31455, 31463, 31443, 31466, 31468, 31473, 31474, 31470, 31471, 31469, + 31472, 31456, 35536, 35536, 35536, 35536, 31495, 31475, 31467, 31476, + 31465, 31464, 31440, 31448, 31447, 31446, 31444, 31445, 31442, 31481, + 31452, 31491, 31428, 31502, 31504, 31501, 31500, 31497, 31496, 31499, + 31498, 31505, 31503, 31450, 31436, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 17263, 17261, 35536, 17262, 35536, 17276, 17291, 17295, + 17275, 17285, 35536, 17277, 17292, 17273, 17271, 17270, 17268, 17267, + 17272, 17296, 17288, 17286, 17287, 17269, 17293, 17294, 17281, 17279, + 17258, 17280, 17257, 17274, 17297, 17300, 17265, 35536, 17266, 35536, + 17299, 17282, 17283, 17284, 17289, 17278, 17301, 17290, 17327, 17309, + 17314, 17310, 17312, 17322, 17323, 17316, 17317, 17318, 17319, 17304, + 17315, 17303, 17302, 35536, 35536, 17320, 17321, 17324, 17313, 17311, + 35536, 17325, 35536, 17308, 17305, 17306, 17307, 17338, 17339, 17326, + 35536, 17334, 17336, 17333, 17332, 17329, 17328, 17331, 17330, 17337, + 17335, 35536, 35536, 17254, 17253, 17260, 17259, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 31729, + 31636, 31634, 31635, 31644, 31632, 31629, 31633, 31653, 31624, 31622, + 31645, 31660, 31654, 31650, 31657, 31649, 31652, 31651, 31628, 31637, + 31620, 31619, 31547, 31548, 31546, 31668, 31669, 31670, 31672, 31673, + 31671, 31569, 31571, 31568, 31567, 31564, 31563, 31566, 31565, 31572, + 31570, 31561, 31558, 31557, 31554, 31553, 31556, 31555, 31562, 31560, + 31559, 31625, 31647, 31627, 31646, 31630, 31656, 31638, 31639, 31640, + 31641, 31679, 31665, 31578, 31576, 31606, 31605, 31588, 31604, 31603, + 31613, 35536, 31590, 31598, 31597, 31583, 31582, 31589, 31600, 31599, + 31587, 31586, 31591, 31608, 31607, 31602, 31601, 31615, 31596, 31595, + 31585, 31584, 31616, 31609, 31610, 31611, 31617, 31580, 31614, 31592, + 31593, 31594, 31612, 31618, 31575, 31581, 31577, 31579, 35536, 35536, + 35536, 35536, 31753, 31749, 31750, 31741, 31742, 31743, 31744, 31745, + 31746, 31751, 31752, 31747, 31748, 31676, 31677, 31739, 31740, 31667, + 31681, 31642, 31659, 31663, 31678, 31664, 31666, 31661, 31662, 31680, + 31728, 31727, 31726, 31693, 31692, 31712, 31711, 31694, 31710, 31709, + 31719, 35536, 31696, 31704, 31703, 31686, 31685, 31695, 31706, 31705, + 31690, 31689, 31697, 31714, 31713, 31708, 31707, 31721, 31702, 31701, + 31688, 31687, 31723, 31715, 31716, 31717, 31724, 31722, 31720, 31698, + 31699, 31700, 31718, 31725, 31691, 31683, 31684, 31682, 35536, 31573, + 31574, 31550, 31551, 31552, 31549, 31730, 31737, 31735, 31738, 31736, + 31731, 31734, 31733, 31732, 35536, 31675, 31674, 31623, 31626, 31648, + 31643, 31631, 26332, 18869, 26333, 18870, 31658, 31655, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 23282, 23261, 23260, 23259, 23291, + 23359, 23358, 23361, 23360, 23292, 23289, 23337, 23336, 23343, 23342, + 23290, 23321, 23338, 23345, 23344, 23293, 23363, 23362, 23357, 23356, + 23288, 23365, 23295, 23355, 23341, 23320, 23364, 23354, 23251, 23315, + 23352, 23353, 23346, 23347, 23254, 23287, 23366, 23253, 23458, 23442, + 23465, 23466, 23459, 23460, 23454, 23439, 23447, 23448, 23455, 23383, + 23402, 23407, 23406, 23382, 23246, 23244, 23245, 23243, 23258, 23483, + 23485, 23482, 23481, 23478, 23477, 23480, 23479, 23486, 23484, 23405, + 23394, 23412, 23416, 23411, 23415, 23296, 23319, 23348, 23349, 23350, + 23351, 23461, 23462, 23463, 23464, 23286, 23285, 23283, 23284, 23249, + 23248, 23247, 23318, 23453, 23427, 23428, 23340, 23339, 23456, 23457, + 23397, 23398, 23399, 23400, 23401, 23257, 23256, 23255, 23443, 23445, + 23446, 23444, 23310, 23309, 23308, 23306, 23314, 23298, 23311, 23299, + 23301, 23312, 23304, 23302, 23313, 23250, 23452, 23449, 23450, 23451, + 23389, 23390, 23391, 23392, 23387, 23388, 23386, 23294, 23403, 23378, + 23380, 23377, 23376, 23373, 23372, 23375, 23374, 23381, 23379, 23384, + 23385, 23440, 23441, 23414, 23413, 12876, 12902, 12887, 12908, 12909, + 12907, 12897, 12898, 12910, 12891, 12900, 12903, 12905, 12911, 12893, + 12896, 12901, 12895, 12899, 12912, 12892, 12890, 12886, 12906, 12894, + 12882, 12885, 12889, 12884, 12883, 12904, 12888, 12877, 12881, 12879, + 12914, 12878, 12880, 35536, 12913, 35536, 35536, 35536, 35536, 35536, + 12875, 35536, 35536, 12959, 12990, 12967, 12996, 12965, 12995, 12988, + 12985, 12997, 12977, 12979, 12991, 12993, 12998, 12981, 12987, 12989, + 12983, 12986, 12956, 12980, 12976, 12966, 12994, 12982, 12960, 12963, + 12975, 12962, 12961, 12992, 12974, 12970, 12973, 12971, 13000, 12968, + 12972, 13001, 12999, 12964, 12984, 12958, 13048, 22495, 12957, 12969, + 12978, 14296, 14370, 14304, 14375, 14368, 14332, 14299, 14314, 14372, + 14346, 14364, 14278, 14276, 14362, 14263, 14298, 14382, 14311, 14385, + 14306, 14371, 14308, 14307, 14379, 14342, 14366, 14345, 14291, 14301, + 14295, 14324, 14329, 14328, 14315, 14319, 14317, 14320, 14321, 14318, + 14326, 14325, 14327, 14322, 14293, 14294, 14353, 14359, 14358, 14351, + 14356, 14347, 14348, 14350, 14361, 14355, 14354, 14352, 14357, 14349, + 14360, 14268, 14267, 14273, 14272, 14331, 14288, 14287, 14285, 14280, + 14290, 14281, 14374, 14284, 14283, 14286, 14279, 14383, 14277, 14270, + 14266, 14275, 14271, 14264, 14265, 14269, 14274, 14312, 14292, 14373, + 14384, 14297, 14310, 14305, 14309, 14376, 14387, 14625, 14531, 14541, + 14589, 14593, 14543, 14542, 14595, 14594, 14570, 14622, 14623, 14580, + 14601, 14581, 14621, 14620, 14624, 14610, 14547, 14599, 14554, 14539, + 14540, 14591, 14590, 14545, 14546, 14544, 14597, 14598, 14578, 14577, + 14573, 14571, 14579, 14602, 14603, 14604, 14609, 14608, 14586, 14587, + 14585, 14582, 14588, 14615, 14614, 14613, 14612, 14611, 14619, 14617, + 14553, 14550, 14600, 14555, 14557, 14564, 14568, 14566, 14556, 14532, + 14534, 14537, 14536, 14569, 14538, 14592, 14596, 14575, 14576, 14407, + 14508, 14410, 14430, 14433, 14437, 14512, 14458, 14459, 14464, 14468, + 14477, 14480, 14473, 14485, 14417, 14447, 14450, 14486, 14503, 14399, + 14390, 14393, 14416, 14521, 14443, 14394, 14409, 14411, 14436, 14435, + 14439, 14438, 14434, 14519, 14513, 14461, 14484, 14478, 14479, 14498, + 14465, 14467, 14472, 14471, 14462, 14476, 14474, 14463, 14481, 14427, + 14424, 14418, 14423, 14422, 14420, 14425, 14429, 14406, 14448, 14452, + 14457, 14405, 14488, 14496, 14489, 14492, 14440, 14401, 14402, 14511, + 14400, 14522, 14526, 14529, 14445, 14404, 14397, 14395, 14396, 14398, + 14530, 14413, 14414, 14412, 14408, 14415, 14509, 12146, 12153, 12152, + 12147, 12151, 12150, 12148, 12149, 12373, 12381, 12380, 12374, 12378, + 12377, 12375, 12379, 12139, 12145, 12143, 12140, 12142, 12141, 12144, + 12130, 12190, 12198, 12197, 12191, 12195, 12194, 12192, 12188, 12302, + 12309, 12307, 12303, 12305, 12304, 12308, 12306, 12277, 12286, 12285, + 12278, 12282, 12281, 12279, 12283, 12317, 12323, 12322, 12318, 12292, + 12287, 12319, 12321, 12293, 12301, 12300, 12294, 12298, 12297, 12295, + 12299, 12269, 12276, 12275, 12270, 12274, 12273, 12271, 12272, 12257, + 35536, 12261, 12258, 12260, 12259, 35536, 35536, 12250, 12256, 12254, + 12251, 12253, 12252, 12255, 35536, 12245, 35536, 12249, 12246, 12248, + 12247, 35536, 35536, 11980, 11987, 11986, 11981, 11985, 11984, 11982, + 11971, 12442, 12449, 12447, 12443, 12445, 12444, 12448, 12446, 12355, + 12363, 12362, 12356, 12360, 12359, 12357, 12361, 12018, 12026, 12025, + 12019, 12023, 12022, 12020, 12024, 12410, 12417, 12416, 12411, 12415, + 12414, 12412, 12413, 12398, 35536, 12402, 12399, 12401, 12400, 35536, + 35536, 12208, 12216, 12215, 12209, 12213, 12212, 12210, 12214, 12199, + 12207, 12206, 12200, 12204, 12203, 12201, 12205, 12100, 12108, 12107, + 12101, 12105, 12104, 12102, 12106, 12178, 12185, 12184, 12179, 12183, + 12182, 12180, 12181, 12166, 35536, 12170, 12167, 12169, 12168, 35536, + 35536, 12159, 12165, 12163, 12160, 12162, 12161, 12164, 35536, 12154, + 35536, 12158, 12155, 12157, 12156, 35536, 35536, 12382, 12389, 12388, + 12383, 12387, 12386, 12384, 12385, 12218, 12224, 12222, 12219, 12221, + 12220, 12223, 35536, 12433, 12441, 12440, 12434, 12438, 12437, 12435, + 12439, 12418, 12425, 12423, 12419, 12421, 12420, 12424, 12422, 12390, + 12397, 12396, 12391, 12395, 12394, 12392, 12393, 12048, 12056, 12055, + 12049, 12053, 12052, 12050, 12054, 12033, 12041, 12040, 12034, 12038, + 12037, 12035, 12039, 12364, 12372, 12371, 12365, 12369, 12368, 12366, + 12370, 12121, 12069, 12127, 12122, 12126, 12125, 12123, 12124, 12109, + 35536, 12113, 12110, 12112, 12111, 35536, 35536, 12093, 12099, 12097, + 12094, 12096, 12095, 12098, 12089, 12324, 12332, 12331, 12325, 12329, + 12328, 12326, 12330, 12009, 12017, 12016, 12010, 12014, 12013, 12011, + 12015, 12217, 12232, 12231, 12225, 12229, 12228, 12226, 12230, 12347, + 12354, 12352, 12348, 12350, 12349, 12353, 12351, 12339, 12346, 12345, + 12340, 12344, 12343, 12341, 12342, 12061, 12068, 12066, 12062, 12064, + 12063, 12067, 12059, 12237, 12244, 12243, 12238, 12242, 12241, 12239, + 12235, 12284, 12196, 12065, 35536, 35536, 11949, 11951, 11950, 11968, + 12471, 12469, 11952, 11967, 11953, 11966, 12470, 11965, 12467, 12465, + 12464, 12461, 12460, 12463, 12462, 12468, 12466, 11954, 11957, 11956, + 11961, 11960, 11964, 11963, 11959, 11962, 11958, 11955, 35536, 35536, + 35536, 12290, 12189, 12187, 12186, 12288, 11972, 11970, 11969, 12289, + 12060, 12058, 12057, 12291, 12236, 12234, 12233, 12459, 12450, 12456, + 12457, 12452, 12454, 12458, 12453, 12451, 12455, 35536, 35536, 35536, + 35536, 35536, 35536, 6484, 6485, 6486, 6487, 6488, 6489, 6447, 6483, + 6448, 6449, 6450, 6451, 6452, 6412, 6413, 6414, 6415, 6416, 6417, 6453, + 6454, 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, 6463, 6418, 6411, + 6419, 6420, 6421, 6422, 6423, 6424, 6465, 6466, 6467, 6468, 6469, 6470, + 6426, 6425, 6427, 6428, 6429, 6430, 6431, 6405, 6444, 6406, 6445, 6407, + 6446, 6408, 6409, 6410, 6404, 6432, 6433, 6434, 6435, 6436, 6437, 6438, + 6439, 6440, 6441, 6442, 6443, 6471, 6472, 6473, 6474, 6475, 6476, 6477, + 6478, 6479, 6480, 6481, 6482, 6464, 35536, 35536, 6564, 6565, 6566, 6567, + 6568, 6550, 35536, 35536, 5626, 5598, 5371, 5628, 5629, 5778, 5792, 6075, + 5582, 5442, 5369, 5370, 5952, 6042, 6062, 6040, 6063, 6041, 6044, 6038, + 6045, 6039, 5707, 6059, 6036, 6060, 6037, 5708, 5373, 6076, 6094, 5615, + 5614, 5616, 5617, 5609, 5610, 5607, 5606, 5619, 5613, 5618, 5608, 5600, + 5630, 5791, 5377, 5812, 5805, 5810, 5811, 5807, 5808, 6066, 5440, 5441, + 5803, 5804, 5802, 5981, 5800, 5979, 5801, 5980, 5795, 5977, 5796, 5978, + 5798, 5975, 5799, 5976, 6065, 5794, 5974, 5433, 5951, 5934, 5949, 5950, + 5947, 5948, 6073, 5404, 5417, 5932, 5933, 5942, 6034, 5940, 6032, 5941, + 6033, 5938, 6030, 5939, 6031, 5936, 6028, 5937, 6029, 5713, 5894, 5929, + 5930, 5931, 5928, 5649, 5643, 5647, 5648, 5645, 5646, 6068, 5641, 5642, + 5640, 6026, 5638, 6024, 5639, 6025, 5636, 6022, 5637, 6023, 5633, 6020, + 5634, 6021, 5710, 5631, 5632, 5874, 5875, 5876, 5873, 5597, 5584, 5595, + 5596, 5593, 5594, 6067, 5401, 5583, 5591, 6019, 5589, 6017, 5590, 6018, + 5587, 6015, 5588, 6016, 5585, 6013, 5586, 6014, 5709, 5400, 5850, 5675, + 5683, 5692, 5693, 5678, 5679, 6070, 5681, 5682, 5691, 5973, 5689, 5971, + 5690, 5972, 5687, 5969, 5688, 5970, 5685, 5967, 5686, 5968, 5711, 5674, + 5966, 5694, 5375, 5851, 5767, 5728, 5765, 5766, 5755, 5756, 6071, 5699, + 5727, 5764, 5992, 5758, 5990, 5759, 5991, 5712, 5695, 5473, 5768, 5673, + 5660, 5671, 5672, 5669, 5670, 6069, 5658, 5659, 5668, 5960, 5666, 5958, + 5667, 5959, 5664, 5956, 5665, 5957, 5662, 5954, 5663, 5955, 5650, 5953, + 5676, 5893, 5853, 5891, 5892, 5872, 5877, 6072, 5833, 5852, 5886, 6012, + 5884, 6010, 5885, 6011, 5882, 6008, 5883, 6009, 5880, 6006, 5881, 6007, + 5705, 5832, 5376, 5879, 5396, 5680, 5703, 5706, 5701, 5702, 5704, 5700, + 5871, 5869, 5870, 5863, 5864, 5866, 5867, 5862, 6005, 5860, 6003, 5861, + 6004, 5855, 6001, 5856, 6002, 5858, 5999, 5859, 6000, 5854, 6093, 6079, + 6091, 6092, 6081, 6082, 6074, 6077, 6078, 6090, 5989, 6088, 5987, 6089, + 5988, 6086, 5985, 6087, 5986, 6084, 5983, 6085, 5984, 5714, 6064, 5397, + 5982, 5849, 5831, 5815, 5965, 5825, 5829, 5830, 5827, 5828, 5963, 5823, + 5824, 5961, 5817, 5994, 5813, 5993, 5677, 5625, 5604, 5605, 5620, 5622, + 5623, 5602, 5603, 5624, 6035, 5601, 5913, 5698, 5911, 5696, 5912, 5697, + 5909, 5910, 5907, 5908, 5905, 6027, 5895, 5926, 5927, 5923, 5921, 5920, + 5944, 5945, 5946, 5943, 5753, 5751, 5752, 5749, 5750, 5747, 5748, 5746, + 5754, 5627, 5772, 5776, 5777, 5774, 5775, 5770, 5771, 5769, 5918, 5919, + 5914, 5917, 5996, 5997, 5998, 5995, 5733, 5737, 5738, 5735, 5736, 5731, + 5732, 5730, 5739, 5847, 5848, 5843, 5846, 6055, 6056, 6057, 6054, 6046, + 5656, 5657, 5654, 5655, 5652, 5653, 5651, 5903, 5901, 5902, 5899, 5900, + 5897, 5898, 5896, 5374, 5393, 5394, 5395, 5392, 5381, 5382, 5383, 5380, + 5389, 5390, 5391, 5388, 5385, 5386, 5387, 5384, 5838, 5839, 5835, 5837, + 5423, 5422, 5418, 5419, 5421, 5420, 5569, 5568, 5564, 5565, 5567, 5566, + 5575, 5574, 5570, 5571, 5573, 5572, 5439, 5438, 5434, 5435, 5437, 5436, + 5533, 5532, 5528, 5529, 5531, 5530, 5527, 5526, 5522, 5523, 5525, 5524, + 5496, 5495, 5491, 5492, 5494, 5493, 5490, 5432, 5431, 5428, 5429, 5430, + 5426, 5469, 5468, 5464, 5465, 5467, 5466, 5463, 5462, 5458, 5459, 5461, + 5460, 5457, 5476, 5475, 5470, 5471, 5474, 5472, 5563, 5562, 5558, 5559, + 5561, 5560, 5581, 5580, 5576, 5577, 5579, 5578, 5456, 5840, 5455, 5450, + 5451, 5454, 5842, 5453, 5449, 5448, 5444, 5445, 5447, 5446, 5551, 5550, + 5546, 5547, 5549, 5548, 5410, 5409, 5405, 5406, 5408, 5407, 5545, 5544, + 5540, 5541, 5543, 5542, 5509, 5508, 5504, 5505, 5507, 5506, 5515, 5514, + 5510, 5511, 5513, 5512, 5503, 5502, 5498, 5499, 5501, 5500, 5497, 5443, + 5416, 5415, 5411, 5412, 5414, 5413, 5489, 5488, 5484, 5485, 5487, 5486, + 5483, 5482, 5478, 5479, 5481, 5480, 5477, 5539, 5538, 5534, 5535, 5537, + 5536, 5557, 5556, 5552, 5553, 5555, 5554, 5521, 5520, 5516, 5517, 5519, + 5518, 5592, 5621, 5773, 5734, 5744, 5745, 5742, 5743, 5740, 5741, 6053, + 6051, 6052, 6049, 6050, 6047, 6048, 6058, 5379, 24281, 24256, 24267, + 24263, 24273, 24270, 24276, 24279, 24280, 24259, 24258, 24278, 24264, + 24269, 24274, 24268, 24255, 24271, 24277, 24261, 24265, 24260, 24272, + 24275, 24266, 24262, 24257, 24253, 24254, 35536, 35536, 35536, 26606, + 26662, 26656, 26660, 26659, 26654, 26652, 26599, 26584, 26630, 26583, + 26582, 26627, 26642, 26629, 26633, 26634, 26636, 26622, 26588, 26621, + 26607, 26600, 26608, 26610, 26655, 26612, 26611, 26625, 26639, 26651, + 26641, 26593, 26615, 26596, 26619, 26609, 26624, 26645, 26616, 26658, + 26585, 26648, 26647, 26643, 26586, 26664, 26653, 26644, 26591, 26650, + 26638, 26594, 26632, 26597, 26657, 26626, 26640, 26623, 26592, 26614, + 26613, 26595, 26631, 26598, 26618, 26590, 26589, 26587, 26649, 26628, + 26646, 26617, 26661, 26663, 26665, 26666, 26581, 26667, 26668, 26580, + 26620, 26637, 26635, 26604, 26603, 26605, 26602, 26601, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 29374, 29391, 29392, 29382, 29380, + 29376, 29388, 29379, 29377, 29385, 29378, 29384, 29390, 29386, 29383, + 29389, 29387, 29381, 29395, 29396, 29394, 29393, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 29375, 14797, 14798, 14799, + 14788, 14786, 14782, 14794, 14785, 14783, 14791, 14784, 14790, 14796, + 14792, 14789, 14795, 14793, 14787, 14801, 14802, 14800, 25736, 25737, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 5092, + 5093, 5094, 5083, 5081, 5077, 5089, 5080, 5078, 5086, 5079, 5085, 5091, + 5087, 5084, 5090, 5088, 5082, 5095, 5096, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 29410, 29411, + 29412, 29402, 29401, 29397, 29407, 29400, 29398, 29405, 29399, 29404, + 29409, 35536, 29403, 29408, 29406, 35536, 29413, 29414, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 16913, 16911, 16914, 16912, 16915, 16909, 16907, 16910, 16908, 16917, + 16931, 16927, 16932, 16928, 16916, 16929, 16925, 16930, 16926, 16918, + 16939, 16919, 16921, 16920, 16935, 16938, 16936, 16934, 16937, 16923, + 16922, 16924, 16940, 16933, 16941, 16888, 16886, 16896, 16897, 16892, + 16895, 16893, 16894, 16905, 16906, 16903, 16904, 16898, 16887, 16891, + 16890, 16889, 17008, 17007, 17009, 17014, 17016, 17020, 17022, 17024, + 17026, 17025, 17017, 17021, 17015, 17027, 17011, 17012, 17019, 17013, + 16962, 16956, 16961, 16963, 16957, 16947, 16955, 16958, 16952, 16944, + 16945, 16964, 16951, 16946, 16953, 16948, 16950, 16959, 16949, 16960, + 16954, 16885, 16942, 16943, 35536, 35536, 17034, 17036, 17033, 17032, + 17029, 17028, 17031, 17030, 17037, 17035, 35536, 35536, 35536, 35536, + 35536, 35536, 16986, 16985, 16982, 16984, 16983, 16977, 16980, 16981, + 16979, 16978, 35536, 35536, 35536, 35536, 35536, 35536, 22862, 22874, + 22870, 22719, 22869, 22720, 22867, 22858, 22871, 22872, 22873, 22718, + 22717, 22716, 22868, 22715, 22711, 22713, 22710, 22709, 22706, 22705, + 22708, 22707, 22714, 22712, 35536, 35536, 35536, 35536, 35536, 35536, + 22723, 22837, 22854, 22839, 22841, 22840, 22842, 22838, 22848, 22751, + 22843, 22849, 22850, 22846, 22755, 22836, 22798, 22797, 22828, 22844, + 22752, 22847, 22853, 22851, 22852, 22845, 22834, 22833, 22827, 22831, + 22832, 22830, 22835, 22829, 22754, 22807, 22825, 22826, 22814, 22816, + 22815, 22817, 22801, 22818, 22821, 22822, 22808, 22820, 22811, 22803, + 22812, 22805, 22810, 22824, 22823, 22819, 22809, 22813, 22804, 22806, + 22802, 22796, 22781, 22782, 22790, 22789, 22786, 22794, 22775, 22777, + 22795, 22784, 22780, 22791, 22793, 22792, 22776, 22778, 22779, 22788, + 22785, 22783, 22787, 22774, 22772, 22773, 22771, 22770, 22753, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 22725, 22727, 22729, 22736, + 22735, 22743, 22739, 22724, 22734, 22750, 22737, 22749, 22741, 22740, + 22731, 22738, 22742, 22728, 22745, 22744, 22748, 22746, 22747, 22726, + 22800, 22799, 22763, 22768, 22759, 22764, 22760, 22756, 22761, 22757, + 22769, 22758, 22766, 22767, 22733, 22732, 22762, 22730, 22765, 35536, + 35536, 35536, 35536, 35536, 5793, 5378, 5372, 6061, 5809, 5806, 5797, + 5935, 5644, 5635, 5684, 5757, 5729, 5661, 5878, 5834, 5865, 5868, 5857, + 6083, 6080, 5826, 5762, 5782, 5763, 5783, 5760, 5780, 5761, 5781, 5822, + 5820, 5821, 5818, 5819, 5816, 5789, 5790, 5787, 5786, 5788, 5779, 5784, + 5785, 5599, 6043, 5612, 5611, 5814, 5964, 5962, 5906, 5904, 5925, 5924, + 5922, 5916, 5915, 5845, 5844, 5836, 5425, 5402, 5427, 5424, 5841, 5452, + 5398, 5399, 5403, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 19167, 19134, 19133, 19114, 19113, 19120, 19128, 19127, + 19132, 19131, 19119, 19117, 19115, 19130, 19129, 19121, 19136, 19135, + 19126, 19125, 19139, 19118, 19140, 19138, 19141, 19122, 19123, 19124, + 19137, 19112, 19116, 35536, 19158, 19165, 19166, 19164, 19159, 19162, + 19160, 19163, 19161, 19157, 19155, 19156, 35536, 35536, 35536, 35536, + 19149, 19146, 19148, 19154, 19147, 19152, 19151, 19153, 19150, 19143, + 19142, 19144, 35536, 35536, 35536, 35536, 19145, 35536, 35536, 35536, + 19168, 19169, 19176, 19178, 19175, 19174, 19171, 19170, 19173, 19172, + 19179, 19177, 29435, 29447, 29430, 29427, 29445, 29448, 29429, 29428, + 29442, 29437, 29436, 29443, 29440, 29446, 29441, 29444, 29434, 29426, + 29431, 29415, 29449, 29419, 29420, 29438, 29433, 29432, 29439, 29418, + 29416, 29417, 35536, 35536, 29421, 29422, 29423, 29424, 29425, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 23820, 23842, 23802, 23804, 23807, 23824, 23826, 23829, 23810, 23806, + 23822, 23832, 23828, 23844, 23811, 23809, 23808, 23833, 23831, 23830, + 23813, 23812, 23819, 23835, 23834, 23841, 23816, 23821, 23818, 23838, + 23843, 23840, 23817, 23815, 23814, 23839, 23837, 23836, 23801, 23803, + 23823, 23825, 23805, 23827, 35536, 35536, 35536, 35536, 23865, 23850, + 23854, 23860, 23863, 23866, 23852, 23856, 23857, 23861, 23853, 23851, + 23864, 23859, 23858, 23862, 23855, 23800, 23795, 23794, 23799, 23798, + 23797, 23796, 23847, 23848, 35536, 35536, 35536, 35536, 35536, 35536, + 23873, 23875, 23872, 23871, 23868, 23867, 23870, 23869, 23876, 23874, + 23849, 35536, 35536, 35536, 23845, 23846, 16987, 17006, 16999, 17002, + 17004, 16997, 16995, 16993, 16989, 16991, 16976, 16974, 16966, 16970, + 16972, 16968, 17000, 17005, 16998, 17001, 17003, 16996, 16994, 16992, + 16988, 16990, 16975, 16973, 16965, 16969, 16971, 16967, 5061, 5058, 5050, + 5049, 5063, 5055, 5048, 5047, 5066, 5057, 5054, 5053, 5056, 5060, 5052, + 5051, 5068, 5064, 5062, 5067, 5065, 5069, 5059, 5072, 5074, 5071, 5073, + 5070, 35536, 35536, 5076, 5075, 29483, 29481, 29482, 29499, 29498, 29497, + 29523, 29489, 29488, 29502, 29509, 29501, 29524, 29517, 29484, 29529, + 29500, 29516, 29493, 29492, 29506, 29505, 29525, 29528, 29491, 29490, + 29494, 29504, 29507, 29503, 29530, 29510, 29496, 29515, 29518, 29511, + 29513, 29531, 29485, 29486, 29487, 29495, 29514, 29532, 29508, 29521, + 29522, 29519, 29520, 29527, 29526, 29512, 29480, 29455, 29454, 29452, + 29543, 29450, 29451, 29453, 29456, 29457, 29458, 35536, 29551, 29558, + 29562, 29559, 29568, 29574, 29575, 29573, 29572, 29570, 29571, 29563, + 29564, 29567, 29576, 29560, 29566, 29561, 29569, 29565, 29542, 29555, + 29556, 29535, 29536, 29537, 29546, 29545, 29538, 35536, 35536, 29459, + 29466, 29468, 29465, 29464, 29461, 29460, 29463, 29462, 29469, 29467, + 35536, 35536, 35536, 35536, 35536, 35536, 29476, 29478, 29475, 29474, + 29471, 29470, 29473, 29472, 29479, 29477, 35536, 35536, 35536, 35536, + 35536, 35536, 29552, 29553, 29550, 29541, 29534, 29554, 29547, 29544, + 29539, 29540, 29548, 29549, 29533, 29557, 35536, 35536, 7299, 7263, 7388, + 7302, 7547, 7566, 7565, 7495, 7283, 7469, 7534, 7501, 7287, 7500, 7499, + 7436, 7430, 7454, 7517, 7455, 7518, 7531, 7488, 7387, 7504, 7286, 7285, + 7545, 7414, 7415, 7416, 7279, 7558, 7368, 7560, 7151, 7562, 7481, 7559, + 7561, 7483, 7530, 7314, 7301, 7262, 7269, 35536, 35536, 7460, 7520, 7487, + 7385, 7533, 7538, 7272, 7273, 7311, 7447, 7552, 7289, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 2762, 2761, 2763, + 2760, 2764, 2671, 2672, 2688, 2689, 2692, 2693, 2710, 2711, 2701, 2702, + 2685, 2675, 2690, 2691, 2696, 2698, 2686, 2687, 2705, 2678, 2679, 2694, + 2695, 2706, 2717, 2716, 2682, 2681, 2704, 2715, 2718, 2680, 2683, 2703, + 2707, 2708, 2676, 2677, 2723, 2725, 2709, 2700, 2724, 2713, 2714, 2712, + 2722, 2765, 2776, 2779, 2780, 2770, 2771, 2768, 2769, 2766, 2767, 2772, + 2773, 2775, 2774, 2777, 2778, 2781, 2697, 2699, 2719, 2684, 2720, 2721, + 2673, 2674, 35536, 2670, 2669, 2789, 2791, 2788, 2787, 2784, 2783, 2786, + 2785, 2792, 2790, 2757, 2754, 2782, 2667, 2668, 2666, 2756, 2743, 2741, + 2744, 2735, 2736, 2742, 2738, 2740, 2739, 2737, 2733, 2732, 2728, 2726, + 2730, 2729, 2727, 2731, 2734, 2753, 2752, 2751, 2750, 2745, 2747, 2748, + 2749, 2746, 2758, 2755, 2759, 28982, 28980, 28981, 28933, 28968, 28970, + 28935, 28969, 28945, 28946, 28953, 28961, 28956, 28947, 28954, 28958, + 28967, 28948, 28962, 28955, 28949, 28960, 28938, 28963, 28951, 28959, + 28966, 28942, 28940, 28964, 28944, 28965, 28957, 28928, 28929, 28930, + 28988, 28987, 28989, 28986, 28984, 28985, 28979, 28983, 28931, 28932, + 28952, 28943, 28996, 28998, 28995, 28994, 28991, 28990, 28993, 28992, + 28999, 28997, 28927, 28941, 28939, 28950, 28936, 28937, 3557, 3543, 3551, + 3535, 3523, 3547, 3546, 3532, 3538, 3531, 3524, 3555, 3541, 3533, 3550, + 3534, 3552, 3549, 3554, 3539, 3522, 3537, 3544, 3527, 3545, 3540, 3525, + 3556, 3542, 3529, 3553, 3536, 3530, 3548, 3528, 3526, 3558, 3559, 3566, + 3572, 3569, 3573, 3574, 3570, 3575, 3571, 3567, 3568, 3520, 3521, 3560, + 3561, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 3565, 3563, + 3564, 3562, 18996, 18995, 18994, 19008, 19007, 19013, 19023, 19022, + 19026, 19014, 19021, 19020, 19002, 19015, 18999, 18998, 18997, 19006, + 19005, 19004, 19003, 19012, 19011, 19017, 19016, 19001, 19031, 19028, + 19027, 19010, 19009, 19029, 19025, 19024, 19030, 19032, 19041, 19040, + 19046, 19048, 19044, 19045, 19042, 19043, 19047, 18985, 18990, 18989, + 18987, 18991, 18992, 18993, 18988, 18986, 19039, 19038, 35536, 35536, + 35536, 19033, 19036, 19037, 19035, 19034, 19055, 19057, 19054, 19053, + 19050, 19049, 19052, 19051, 19058, 19056, 35536, 35536, 35536, 19019, + 19018, 19000, 24327, 24329, 24326, 24325, 24322, 24321, 24324, 24323, + 24330, 24328, 24300, 24291, 24289, 24288, 24290, 24301, 24285, 24284, + 24286, 24287, 24303, 24299, 24297, 24296, 24298, 24305, 24311, 24312, + 24310, 24313, 24302, 24295, 24292, 24294, 24293, 24304, 24306, 24307, + 24309, 24308, 24315, 24316, 24314, 24320, 24319, 24331, 24318, 24317, + 9548, 9525, 9531, 9588, 9569, 9577, 9567, 9568, 9587, 9253, 9579, 35536, + 35536, 35536, 35536, 35536, 13004, 13035, 13012, 13041, 13010, 13040, + 13033, 13030, 13042, 13022, 13024, 13036, 13038, 13043, 13026, 13032, + 13034, 13028, 13031, 13044, 13025, 13021, 13011, 13039, 13027, 13005, + 13008, 13020, 13007, 13006, 13037, 13019, 13015, 13018, 13016, 13046, + 13013, 13017, 13047, 13045, 13009, 13029, 13003, 35536, 35536, 13002, + 13014, 13023, 28978, 28976, 28977, 28975, 28974, 28973, 28972, 28971, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 33381, 33394, + 33383, 33361, 33375, 33389, 33390, 33391, 33376, 33392, 33379, 33387, + 33382, 33380, 33388, 33386, 33385, 33393, 33374, 33372, 33363, 33370, + 33362, 33373, 33371, 33352, 33353, 33355, 33356, 33368, 33366, 33367, + 33365, 33354, 33358, 33364, 33377, 33360, 33369, 33357, 33384, 33378, + 33359, 35536, 35536, 35536, 35536, 35536, 17959, 17960, 18567, 17956, + 17961, 17962, 17933, 17932, 18552, 18545, 17965, 17966, 17939, 17967, + 17945, 17940, 17941, 18502, 18503, 18504, 18547, 17943, 18539, 18058, + 17969, 17946, 17954, 17949, 17972, 18507, 18506, 18505, 17973, 17974, + 17976, 17934, 17986, 17920, 13548, 13551, 13547, 13550, 13546, 9418, + 22400, 22401, 22391, 22392, 22403, 22404, 22394, 22406, 22396, 22407, + 22408, 22409, 22410, 22411, 22412, 22395, 22398, 22399, 22413, 22393, + 22416, 22417, 22419, 22550, 22657, 22551, 22659, 22554, 22579, 22593, + 22647, 22632, 22662, 22600, 22670, 22681, 22610, 22597, 22630, 22633, + 22654, 22556, 22634, 22649, 22674, 22648, 22660, 22678, 22552, 22558, + 22601, 22584, 22602, 22578, 18708, 18716, 18718, 18719, 13757, 13753, + 13756, 13755, 13754, 18628, 18044, 18093, 18179, 18322, 18342, 18419, + 18447, 18440, 18486, 18522, 18690, 18574, 22468, 18250, 18532, 17988, + 18257, 18415, 17989, 18627, 18045, 18097, 18180, 18193, 18276, 18303, + 18323, 18348, 18420, 18450, 18487, 18166, 18635, 18662, 18691, 18007, + 18033, 18096, 18156, 18408, 18457, 18495, 18247, 18404, 18168, 18614, + 18174, 22658, 22559, 22577, 22595, 22641, 22598, 22585, 22646, 22669, + 22612, 22613, 22560, 22562, 22615, 22619, 22621, 22565, 22611, 22661, + 22629, 22628, 22571, 22555, 22635, 22645, 22594, 22650, 22676, 22677, + 22573, 22680, 22671, 22590, 22592, 22591, 22596, 22673, 7271, 7270, 7536, + 7535, 7482, 7370, 7484, 7153, 7369, 7152, 7428, 7165, 7485, 7280, 7497, + 7525, 7389, 7553, 7554, 7411, 7402, 7403, 7404, 7406, 7413, 7409, 7438, + 7394, 7440, 7417, 7395, 7396, 7442, 7397, 7398, 7427, 7431, 7419, 7446, + 7401, 7433, 7434, 7432, 7410, 7418, 7422, 7443, 7408, 7425, 7435, 7400, + 7421, 7424, 7550, 7393, 7392, 7265, 7563, 7268, 7259, 7278, 7162, 7451, + 7508, 17441, 18005, 17477, 18047, 17476, 18046, 17475, 18043, 17484, + 18062, 17509, 18099, 17508, 18098, 17507, 18094, 17503, 18088, 17504, + 18089, 17537, 18142, 17538, 18143, 17526, 18130, 17535, 18140, 17517, + 18121, 17562, 18182, 17570, 18192, 17589, 18212, 17588, 18211, 17586, + 18209, 17583, 18206, 17582, 18205, 17606, 18239, 17600, 18227, 17637, + 18274, 17634, 18271, 17638, 18275, 17645, 18288, 17646, 18289, 17656, + 18298, 17652, 18285, 17662, 18320, 17664, 18325, 17663, 18324, 17682, + 18347, 17681, 18346, 17676, 18339, 17672, 18334, 17713, 18383, 17712, + 18382, 17690, 18375, 17691, 18376, 17741, 18418, 17743, 18422, 17753, + 18437, 17751, 18435, 17752, 18436, 17758, 18442, 17779, 18480, 17777, + 18478, 17776, 18471, 17771, 18473, 17778, 18479, 17800, 18520, 17799, + 18519, 17801, 18523, 17795, 18513, 17831, 18595, 17852, 18618, 17824, + 18588, 17851, 18617, 17843, 18607, 17864, 18638, 17863, 18634, 17877, + 18651, 17878, 18652, 17874, 18648, 17876, 18650, 17875, 18649, 17883, + 18657, 17882, 18656, 17888, 18667, 17899, 18681, 17903, 18685, 17905, + 18687, 18213, 18518, 18653, 18677, 18006, 18313, 18312, 18314, 17789, + 18103, 17435, 17999, 17451, 18017, 17447, 18013, 17446, 18012, 17445, + 18011, 17449, 18015, 17448, 18014, 17430, 17994, 17429, 17993, 17428, + 17992, 17432, 17996, 17431, 17995, 17531, 18135, 17542, 18148, 17534, + 18139, 17522, 18126, 17521, 18125, 17520, 18124, 17525, 18129, 17524, + 18128, 17607, 18240, 17597, 18231, 17704, 18368, 17724, 18394, 17696, + 18360, 17695, 18359, 17694, 18358, 17698, 18362, 17697, 18361, 17721, + 18391, 17720, 18390, 17719, 18389, 17723, 18393, 17722, 18392, 17834, + 18598, 17841, 18605, 17838, 18602, 17837, 18601, 17836, 18600, 17840, + 18604, 17839, 18603, 17889, 18668, 17887, 18666, 17891, 18670, 17895, + 18676, 17667, 18328, 17668, 18329, 17892, 18671, 13595, 13587, 13600, + 13592, 13596, 13588, 13598, 13590, 13361, 13353, 13364, 13356, 13362, + 13354, 13366, 13358, 13618, 13615, 13620, 13617, 13619, 13616, 35536, + 35536, 13401, 13398, 13403, 13400, 13402, 13399, 35536, 35536, 13633, + 13625, 13638, 13630, 13634, 13626, 13636, 13628, 13385, 13377, 13388, + 13380, 13386, 13378, 13390, 13382, 13659, 13650, 13662, 13653, 13661, + 13652, 13660, 13651, 13413, 13408, 13416, 13411, 13415, 13410, 13414, + 13409, 13720, 13717, 13722, 13719, 13721, 13718, 35536, 35536, 13447, + 13444, 13449, 13446, 13448, 13445, 35536, 35536, 13679, 13670, 13682, + 13673, 13681, 13672, 13680, 13671, 35536, 13459, 35536, 13462, 35536, + 13461, 35536, 13460, 13700, 13692, 13705, 13697, 13701, 13693, 13703, + 13695, 13431, 13423, 13434, 13426, 13432, 13424, 13436, 13428, 13585, + 13605, 13622, 13621, 13645, 13643, 13665, 13666, 13724, 13723, 13685, + 13686, 13712, 13710, 35536, 35536, 13602, 13594, 13601, 13593, 13597, + 13589, 13599, 13591, 13368, 13360, 13365, 13357, 13363, 13355, 13367, + 13359, 13640, 13632, 13639, 13631, 13635, 13627, 13637, 13629, 13392, + 13384, 13389, 13381, 13387, 13379, 13391, 13383, 13707, 13699, 13706, + 13698, 13702, 13694, 13704, 13696, 13438, 13430, 13435, 13427, 13433, + 13425, 13437, 13429, 13584, 13609, 13586, 13607, 13606, 35536, 13603, + 13604, 13370, 13374, 13371, 13372, 13369, 13544, 13572, 13573, 13577, + 13493, 13646, 13647, 13644, 35536, 13641, 13642, 13405, 13404, 13395, + 13394, 13393, 13576, 13575, 13574, 13664, 13668, 13657, 13656, 35536, + 35536, 13663, 13655, 13417, 13421, 13418, 13419, 35536, 13501, 13500, + 13499, 13684, 13688, 13677, 13676, 13732, 13731, 13683, 13675, 13464, + 13468, 13465, 13466, 13454, 13495, 13494, 13771, 35536, 35536, 13713, + 13714, 13711, 35536, 13708, 13709, 13451, 13450, 13441, 13440, 13439, + 13569, 13498, 35536, 11889, 11886, 11891, 11888, 31540, 12641, 28108, + 12566, 26028, 31513, 14126, 35342, 35341, 35343, 18877, 26357, 15608, + 24061, 12565, 11890, 11887, 15552, 10369, 10343, 18800, 26287, 27983, + 27981, 18753, 26252, 10342, 10337, 9647, 10336, 5097, 32125, 24830, + 32272, 15575, 15611, 19185, 25369, 18876, 26356, 25902, 18875, 26355, + 23662, 25605, 25606, 25988, 10351, 32139, 26195, 26189, 26203, 6109, + 27982, 27984, 26212, 10373, 15950, 25183, 32323, 6395, 6110, 2572, 15610, + 12645, 18808, 26298, 10374, 26052, 12480, 31914, 26194, 3956, 3998, + 19854, 26200, 7136, 32284, 7569, 29091, 15968, 12605, 31520, 26048, + 12634, 12591, 32273, 12635, 10315, 32150, 33402, 21670, 33948, 12768, + 15970, 15972, 15971, 35536, 18874, 26354, 12584, 25901, 15864, 7, 15863, + 6, 23657, 24059, 29062, 29050, 35536, 35536, 29057, 29056, 29059, 29058, + 29049, 29063, 29053, 29055, 29048, 29052, 29054, 29051, 28892, 28894, + 28891, 28890, 28887, 28886, 28889, 28888, 28882, 28893, 28883, 28885, + 28881, 28880, 28884, 35536, 18705, 18706, 18714, 18720, 18704, 18707, + 18710, 18711, 18712, 18713, 18715, 18703, 18717, 35536, 35536, 35536, + 12476, 7149, 7815, 12652, 19793, 22285, 23590, 25629, 26677, 33952, + 23793, 10309, 12477, 17238, 32160, 10491, 13049, 25630, 13821, 2585, + 15616, 6228, 19794, 28444, 31285, 15854, 32242, 24111, 20359, 26546, + 17422, 3862, 28424, 26838, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 7458, 7516, 7473, + 7529, 7158, 7174, 7453, 7513, 7522, 7173, 7157, 7539, 7313, 7303, 7306, + 7309, 7304, 7462, 7305, 7307, 7308, 7505, 7294, 7159, 7546, 7564, 7464, + 7470, 7521, 7463, 7452, 7512, 7161, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 0, + 100, 10385, 9671, 6232, 6111, 5362, 12479, 26866, 9673, 26863, 26855, + 4046, 10386, 25791, 25792, 26856, 4047, 26857, 26864, 20031, 10387, + 24155, 28340, 26859, 10383, 10388, 26860, 4048, 10389, 25964, 26173, + 26969, 31179, 32110, 33395, 10390, 25177, 25187, 15967, 4049, 32265, + 16764, 963, 26852, 4045, 11946, 26862, 26853, 26854, 32249, 26858, 26865, + 348, 3753, 13052, 9660, 15861, 26534, 12545, 10397, 10396, 10382, 10384, + 10398, 32258, 32259, 26199, 32260, 10395, 10391, 10392, 10393, 10394, + 25992, 32244, 25607, 2643, 32262, 29170, 33546, 33544, 33548, 33549, + 33554, 33542, 33553, 33552, 33540, 33547, 33539, 33541, 33550, 33538, + 33555, 12646, 26502, 26513, 26514, 26501, 26498, 26507, 26509, 26517, + 26518, 26510, 26516, 26512, 26495, 26503, 26499, 26505, 28170, 28174, + 28175, 28169, 28166, 28178, 28177, 28165, 28179, 28176, 28164, 28173, + 28168, 28171, 28167, 28172, 26506, 26500, 26511, 26515, 18463, 26508, + 26497, 26496, 26504, 33556, 32253, 32252, 35536, 35536, 35536, 35536, + 18878, 32474, 26359, 10427, 18782, 32345, 24092, 24065, 28312, 28327, + 18898, 26383, 18962, 26460, 18959, 32524, 26459, 10463, 18901, 26386, + 18909, 32487, 26366, 10441, 32346, 18907, 26392, 18892, 26378, 18790, + 18785, 10467, 32484, 32485, 10436, 10437, 26374, 10428, 974, 7120, 24094, + 18889, 979, 7122, 18928, 18922, 32501, 32498, 26419, 26413, 10478, 10475, + 26394, 32476, 18912, 18974, 32527, 26426, 10486, 18929, 26420, 18965, + 18789, 26402, 18963, 32491, 26400, 10468, 18787, 32348, 24105, 24078, + 28324, 28337, 18949, 26450, 18978, 26430, 32477, 10429, 18969, 32492, + 26406, 10469, 18888, 26373, 18960, 32528, 26461, 10465, 32533, 32529, + 32531, 32530, 32535, 32536, 26462, 24093, 28315, 32350, 26239, 10439, + 31528, 18908, 26393, 18784, 18894, 26376, 18783, 18973, 26425, 18792, + 12630, 7574, 25515, 31507, 31506, 11879, 15782, 23546, 11828, 24114, + 28150, 7582, 10135, 28143, 11893, 23505, 23493, 23497, 22289, 22296, + 10310, 10117, 26974, 2571, 26471, 5098, 28671, 7821, 12640, 25991, 15855, + 26229, 959, 21544, 28447, 10121, 10136, 25374, 24119, 19808, 19815, + 15943, 32325, 15928, 10340, 32149, 7588, 29084, 33534, 7123, 7114, 976, + 31508, 3754, 26083, 25990, 10311, 12482, 12874, 15596, 31818, 26201, + 15964, 28103, 33956, 24124, 22295, 2578, 24115, 1058, 1061, 23749, 364, + 24116, 366, 32140, 361, 11932, 12872, 10127, 1062, 12873, 1059, 15745, + 7148, 11930, 26469, 26470, 7767, 11947, 11933, 28836, 9676, 11915, 21555, + 26054, 24126, 15621, 24127, 28873, 19078, 13285, 19080, 13288, 19069, + 13278, 23242, 23241, 3752, 24125, 24129, 24128, 23754, 23751, 19077, + 13284, 23753, 23750, 19079, 13286, 23755, 23752, 25965, 28910, 25974, + 28919, 25973, 28918, 10138, 10141, 28898, 29070, 24112, 24113, 28904, + 29076, 23747, 23748, 28903, 29075, 22995, 22996, 22997, 28544, 28633, + 28546, 28635, 28479, 28486, 6909, 6855, 6914, 6647, 6660, 6910, 6636, + 6919, 6661, 28804, 28797, 28818, 28752, 26316, 18826, 10404, 32354, 2579, + 22304, 32157, 12631, 32143, 10367, 10140, 24123, 10143, 23746, 25975, + 28920, 24109, 7583, 24110, 7584, 24862, 15744, 22998, 15367, 15951, + 33977, 23591, 24064, 26235, 26312, 23502, 23503, 23504, 23498, 9955, + 10312, 28838, 10119, 4474, 18840, 26274, 18798, 26285, 26202, 9064, 9063, + 10361, 10360, 10339, 10364, 25785, 11916, 19083, 13294, 33445, 33444, + 19067, 13289, 11914, 11913, 11911, 11912, 10139, 10142, 24120, 24121, + 28545, 28634, 19068, 13277, 25972, 28917, 24117, 10133, 24118, 10134, + 33401, 22281, 32353, 10407, 11829, 11831, 28151, 11834, 11833, 28152, + 11832, 11830, 7585, 7586, 28144, 7587, 28145, 35254, 9956, 11826, 15590, + 32337, 10408, 25989, 25624, 33720, 18749, 26247, 18837, 26256, 4457, + 4454, 32058, 32054, 26192, 28577, 2567, 26876, 26872, 31177, 25910, + 33458, 25788, 32256, 33711, 15588, 32053, 32057, 4453, 4456, 32047, 4451, + 12656, 28210, 32338, 24852, 11943, 33961, 16766, 18847, 26337, 11942, + 3700, 9642, 362, 29180, 32074, 10128, 7593, 28135, 7769, 7770, 1004, 1042, 1028, 1016, 1017, 1033, 1014, 984, 989, 1039, 1044, 1030, 1029, 1024, 1031, 1012, 1036, 1025, 1032, 987, 996, 995, 1018, 1021, 997, 1050, 1023, 1047, 993, 1022, 1020, 1048, 1000, 1019, 1035, 994, 1001, 1010, 988, 1049, 1034, 985, 1015, 1046, 991, 1040, 1009, 986, 998, 1011, 1052, 1051, 990, 992, 1053, 1041, 1038, 1027, 1026, 999, 1045, 1002, 1037, - 1007, 1006, 1043, 1003, 1008, 1005, 29610, 32110, 33041, 3595, 39293, - 20936, 8605, 11056, 16894, 8587, 39741, 16916, 367, 20087, 6691, 6913, - 5038, 38200, 28358, 20623, 30724, 30725, 31405, 31406, 11051, 34104, - 1013, 10681, 31852, 29458, 31854, 8157, 24323, 24324, 24322, 32157, - 32158, 32156, 24285, 24292, 24284, 32171, 32178, 32170, 24227, 24225, - 24226, 10080, 32121, 32119, 32120, 20947, 20565, 38282, 38321, 34799, - 34797, 37937, 4460, 4461, 31939, 24326, 32194, 20574, 20575, 20576, - 20577, 10703, 10701, 10705, 10694, 10698, 10706, 10695, 10699, 10704, - 10693, 10697, 10692, 10696, 10702, 10700, 34388, 32050, 17518, 39288, - 27597, 27589, 27596, 27590, 27594, 27595, 27593, 27592, 27591, 11672, - 17781, 37925, 4464, 37907, 4463, 37938, 4467, 39750, 3701, 34740, 17605, - 8, 16836, 10682, 3987, 3949, 4030, 3926, 3988, 3950, 3990, 230, 34738, - 37702, 20598, 3966, 3969, 3971, 3963, 11379, 4009, 3871, 31800, 31797, - 31798, 31799, 30113, 35041, 35049, 35050, 35030, 35028, 35031, 35042, - 35013, 35014, 35035, 35037, 35036, 35034, 35015, 35047, 35048, 35017, - 35026, 35025, 35024, 35023, 35039, 35053, 35029, 35016, 35027, 35051, - 35032, 35033, 35044, 35043, 35045, 35054, 35018, 4053, 30711, 35040, - 35021, 35052, 35020, 35019, 35022, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 30125, 30120, 30123, - 30124, 30117, 30118, 30116, 30115, 30122, 30119, 30121, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 6657, - 6654, 6653, 6650, 6649, 6652, 6651, 6658, 6656, 6878, 6858, 6903, 6891, - 6873, 6861, 6877, 6875, 6857, 6904, 6892, 31337, 31335, 31334, 31331, - 31330, 31333, 31332, 31338, 31336, 31329, 31320, 31328, 31326, 31321, - 31322, 31324, 31325, 31319, 31323, 31327, 10991, 11003, 11000, 10985, - 10982, 10997, 10994, 11009, 10988, 29631, 29624, 29632, 29630, 29625, - 29626, 29627, 29629, 29623, 29634, 29633, 31365, 31366, 31367, 31368, - 31369, 31370, 31371, 31372, 31373, 31374, 31375, 31376, 31377, 31378, - 31379, 31380, 31381, 31382, 31383, 31384, 31385, 31386, 31387, 31388, - 31389, 31390, 6801, 6802, 6803, 6804, 6805, 6806, 6807, 6808, 6809, 6810, - 6811, 6812, 6813, 6814, 6815, 6816, 6817, 6818, 6819, 6820, 6821, 6822, - 6823, 6824, 6825, 6826, 6827, 6828, 6829, 6830, 6831, 6832, 6833, 6834, - 6835, 6836, 6837, 6838, 6839, 6840, 6841, 6842, 6843, 6844, 6845, 6846, - 6847, 6848, 6849, 6850, 6851, 6852, 6655, 29151, 29149, 29147, 29152, - 29153, 29155, 29156, 29150, 29154, 29148, 11345, 11343, 11342, 11339, - 11338, 11341, 11340, 11346, 11344, 11337, 29146, 4586, 4532, 4602, 4518, - 4595, 4531, 4594, 4530, 4593, 4529, 4592, 4528, 4583, 4502, 4496, 4525, - 4582, 4500, 4494, 4524, 4601, 4630, 4624, 4517, 4600, 4628, 4622, 4515, - 4609, 4646, 4623, 4495, 4643, 4501, 4629, 4521, 4608, 4645, 4621, 4493, - 4642, 4499, 4627, 4520, 4581, 4536, 4614, 4504, 4498, 4617, 4539, 4523, - 4599, 4535, 4613, 4631, 4625, 4616, 4538, 4516, 4607, 4537, 4615, 4644, - 4620, 4497, 4641, 4541, 4619, 4534, 4612, 4503, 4626, 4618, 4540, 4519, - 4585, 4527, 4584, 4526, 4492, 4488, 4509, 4506, 4484, 4508, 4505, 4483, - 4636, 4633, 4487, 4635, 4632, 4486, 4648, 4639, 4491, 4647, 4638, 4490, - 4510, 4507, 4482, 4637, 4634, 4485, 4649, 4640, 4489, 4543, 4542, 4544, - 4545, 4574, 4568, 4578, 4590, 4597, 4611, 4580, 4511, 4513, 4533, 4522, - 4591, 4598, 4512, 4514, 38259, 25435, 25434, 25437, 25345, 25427, 25440, - 25436, 17672, 24279, 24302, 24315, 24243, 24303, 24258, 24259, 32136, - 24579, 27151, 10668, 38307, 32153, 31921, 31922, 31913, 31914, 31915, - 31916, 31917, 31918, 31919, 31920, 4007, 39728, 39737, 39731, 34566, - 34575, 34565, 34572, 34574, 34564, 4004, 39725, 4000, 39713, 4037, 39760, - 3981, 39709, 4032, 39757, 4031, 39756, 3989, 39717, 3994, 39716, 3993, - 39715, 3928, 39672, 3927, 39671, 3954, 39698, 3953, 39697, 3952, 39696, - 3918, 39661, 39662, 17597, 25442, 39647, 11328, 6630, 5101, 3867, 6622, - 6631, 6623, 6628, 6627, 6629, 24241, 32134, 20964, 20968, 38263, 25339, - 38287, 38323, 25389, 25369, 38268, 25346, 3961, 3960, 4033, 4034, 39611, - 34569, 34576, 34571, 34568, 39740, 39758, 38245, 38246, 22899, 39738, - 39734, 39735, 39739, 39654, 39652, 39653, 39655, 38285, 38340, 25380, - 39705, 3976, 39704, 3975, 25403, 4011, 8151, 38194, 34094, 8590, 4020, - 39747, 24589, 37421, 34800, 2568, 10711, 8608, 30732, 4026, 39749, 2795, - 2801, 2802, 32560, 38196, 20593, 39722, 4018, 33013, 32073, 3959, 3986, - 39695, 39754, 39719, 39670, 33990, 6225, 31937, 3864, 5361, 983, 30834, - 6585, 8816, 8815, 34715, 17564, 102, 19262, 31471, 41128, 38004, 38005, - 38010, 38007, 38009, 38008, 38006, 38003, 39607, 39682, 39726, 4006, - 39745, 17590, 22903, 27586, 17570, 11668, 25747, 21093, 32630, 38413, - 29460, 31766, 2566, 37042, 17864, 6099, 24463, 39336, 25277, 32724, - 32558, 6105, 2646, 31659, 39619, 39635, 39638, 39613, 39622, 39632, 3889, - 3905, 3908, 3883, 3892, 3902, 4019, 39685, 39666, 3917, 39727, 3938, - 3923, 39656, 20594, 31926, 16791, 3581, 3582, 28483, 28481, 28482, 39605, - 11673, 38210, 31967, 31968, 31969, 31970, 31971, 31972, 31973, 31974, - 4036, 31966, 31396, 31503, 39608, 10973, 10974, 10975, 10976, 10977, - 10978, 39649, 39651, 3868, 3870, 28355, 28356, 11013, 11016, 11015, - 11014, 39676, 3934, 19263, 981, 8824, 34709, 32719, 347, 17613, 17860, - 34710, 2581, 17610, 31040, 37398, 37397, 39581, 20444, 11414, 11415, - 20951, 25746, 25745, 25744, 39294, 20585, 27162, 27138, 27155, 25913, - 11136, 38212, 8807, 17778, 29270, 6235, 31205, 21094, 39323, 6588, 3977, - 32852, 32764, 31932, 32847, 34099, 3518, 34642, 39673, 39674, 3931, 3932, - 34095, 34802, 31942, 4013, 37420, 38124, 38123, 39667, 8825, 11055, - 30731, 31644, 6167, 20086, 6643, 6236, 29532, 368, 4027, 39752, 3957, - 39693, 11514, 19943, 24230, 34685, 17558, 4024, 32046, 32047, 2575, - 19869, 31478, 32212, 24353, 20974, 3880, 33018, 6620, 6227, 20549, 17861, - 17862, 25842, 28374, 38195, 17651, 17607, 17572, 32715, 34387, 33988, - 20629, 31490, 37162, 20991, 19845, 17780, 10073, 39677, 4014, 38252, - 4017, 25421, 39720, 39686, 37054, 37041, 226, 16913, 31955, 31947, 39327, - 39835, 25420, 31480, 38322, 39708, 3979, 6401, 19867, 28474, 19903, 2805, - 19859, 31042, 19950, 30715, 19905, 23392, 32857, 31039, 25748, 34713, - 17647, 17645, 19888, 17641, 3935, 39681, 34308, 34743, 6916, 30713, 3881, - 31041, 19907, 31656, 32856, 19858, 30714, 16790, 16785, 16783, 33982, - 16784, 19881, 38144, 33985, 37047, 30712, 19933, 33980, 3933, 39678, - 16786, 6905, 19932, 34097, 37692, 19866, 34307, 19926, 2794, 16789, - 19883, 8821, 32855, 29218, 25419, 38319, 25401, 38337, 4044, 39712, - 39675, 3920, 19885, 24586, 27159, 19949, 19916, 19917, 19877, 19878, - 19900, 19899, 10085, 19886, 19892, 19862, 32407, 17612, 32406, 27145, - 27148, 27139, 27140, 27146, 27149, 19896, 19909, 19895, 19908, 24578, - 24576, 27144, 27147, 11038, 11036, 11035, 11032, 11031, 11034, 11033, - 11039, 11037, 11030, 11049, 11046, 11045, 11042, 11041, 11044, 11043, - 11050, 11048, 11040, 11028, 11025, 11024, 11021, 11020, 11023, 11022, - 11029, 11027, 11019, 19945, 19948, 19904, 19874, 19922, 19910, 19929, - 11506, 19913, 37998, 19935, 10671, 19873, 3995, 37412, 37415, 3996, - 19860, 19861, 34703, 19872, 32228, 24343, 2658, 17663, 19901, 19940, - 29612, 10079, 29614, 6693, 39764, 4050, 4052, 4051, 19863, 19865, 19864, - 37048, 19934, 39601, 19946, 30726, 11347, 37395, 39751, 31484, 30722, - 30721, 24277, 32160, 30836, 32057, 34957, 39275, 26610, 25303, 26431, - 34670, 34671, 39665, 982, 16845, 25417, 38280, 24261, 32151, 17671, - 22891, 22890, 24208, 24207, 24257, 25325, 25308, 38231, 25443, 39657, - 39658, 39659, 39733, 39736, 26611, 26605, 26614, 26608, 26613, 26607, - 26612, 26606, 26615, 26609, 38381, 11496, 978, 8130, 32114, 25311, 25315, - 25305, 25309, 25320, 25307, 25312, 25319, 25310, 25321, 25324, 5027, - 4772, 4900, 4773, 4964, 4837, 4901, 4774, 4996, 4869, 4933, 4806, 4965, - 4838, 4902, 4775, 5012, 4885, 4949, 4822, 4981, 4854, 4918, 4791, 4997, - 4870, 4934, 4807, 4966, 4839, 4903, 4776, 5020, 4893, 4957, 4830, 4989, - 4862, 4926, 4799, 5005, 4878, 4942, 4815, 4974, 4847, 4911, 4784, 5013, - 4886, 4950, 4823, 4982, 4855, 4919, 4792, 4998, 4871, 4935, 4808, 4967, - 4840, 4904, 4777, 5024, 4897, 4961, 4834, 4993, 4866, 4930, 4803, 5009, - 4882, 4946, 4819, 4978, 4851, 4915, 4788, 5017, 4890, 4954, 4827, 4986, - 4859, 4923, 4796, 5002, 4875, 4939, 4812, 4971, 4844, 4908, 4781, 5021, - 4894, 4958, 4831, 4990, 4863, 4927, 4800, 5006, 4879, 4943, 4816, 4975, - 4848, 4912, 4785, 5014, 4887, 4951, 4824, 4983, 4856, 4920, 4793, 4999, - 4872, 4936, 4809, 4968, 4841, 4905, 4778, 5026, 4899, 4963, 4836, 4995, - 4868, 4932, 4805, 5011, 4884, 4948, 4821, 4980, 4853, 4917, 4790, 5019, - 4892, 4956, 4829, 4988, 4861, 4925, 4798, 5004, 4877, 4941, 4814, 4973, - 4846, 4910, 4783, 5023, 4896, 4960, 4833, 4992, 4865, 4929, 4802, 5008, - 4881, 4945, 4818, 4977, 4850, 4914, 4787, 5016, 4889, 4953, 4826, 4985, - 4858, 4922, 4795, 5001, 4874, 4938, 4811, 4970, 4843, 4907, 4780, 5025, - 4898, 4962, 4835, 4994, 4867, 4931, 4804, 5010, 4883, 4947, 4820, 4979, - 4852, 4916, 4789, 5018, 4891, 4955, 4828, 4987, 4860, 4924, 4797, 5003, - 4876, 4940, 4813, 4972, 4845, 4909, 4782, 5022, 4895, 4959, 4832, 4991, - 4864, 4928, 4801, 5007, 4880, 4944, 4817, 4976, 4849, 4913, 4786, 5015, - 4888, 4952, 4825, 4984, 4857, 4921, 4794, 5000, 4873, 4937, 4810, 4969, - 4842, 4906, 4779, 32332, 32331, 24444, 32277, 24268, 32333, 24446, 32279, - 11452, 38362, 38399, 11476, 24448, 32281, 24428, 32325, 32334, 32251, - 38364, 11456, 32264, 32263, 32327, 32329, 32328, 24393, 32271, 24447, - 32280, 24370, 32248, 24390, 32243, 29571, 29551, 29577, 29549, 34192, - 34205, 29576, 29548, 34189, 34204, 32351, 17556, 34190, 29546, 17557, - 32352, 29547, 29575, 39590, 2559, 2558, 2561, 2562, 32229, 24342, 37904, - 4462, 37906, 37905, 25399, 25363, 975, 8127, 32238, 24359, 33028, 32256, - 24375, 32247, 24266, 38402, 24220, 24219, 38219, 38218, 24221, 38220, - 24218, 38217, 24407, 32294, 38376, 11491, 24401, 32288, 38373, 11488, - 24406, 32293, 38375, 11490, 24400, 32287, 38372, 11487, 24403, 38371, - 32292, 11485, 24405, 24399, 32290, 32285, 24404, 24398, 32291, 32286, - 38370, 11486, 32126, 16930, 37696, 24363, 32240, 32239, 24544, 24366, - 18282, 34773, 24365, 34943, 24316, 32131, 38228, 11420, 38018, 41141, - 41142, 24308, 32197, 24310, 32199, 41136, 41132, 41137, 41133, 24289, - 32175, 24287, 32172, 24286, 32173, 24214, 32107, 24215, 32113, 11360, - 11385, 24223, 32117, 11335, 39308, 27033, 32112, 27034, 960, 5, 34324, - 34325, 38121, 32063, 961, 32064, 30111, 30110, 27032, 27031, 27026, - 27025, 27030, 27028, 27029, 27027, 32085, 16892, 16891, 16889, 16890, - 6632, 6920, 6907, 6911, 6908, 6633, 6625, 6634, 38216, 6915, 6638, 6853, - 6921, 6624, 6626, 34634, 34629, 34700, 34686, 34687, 38154, 37997, 37995, - 32555, 37994, 32189, 24294, 39272, 4475, 4476, 4043, 37703, 37704, 39690, - 3942, 24313, 32202, 24231, 32127, 20788, 37630, 20865, 11413, 34577, - 20790, 33048, 16931, 16932, 20631, 18166, 37386, 11433, 11434, 3921, - 3962, 39650, 3869, 16945, 16948, 16944, 16947, 16943, 16946, 32424, - 32058, 34151, 32059, 3857, 3856, 11367, 38014, 24330, 32215, 37705, - 27777, 28972, 28970, 28971, 28980, 28979, 28975, 28976, 38156, 38155, - 28974, 28180, 34798, 31923, 17583, 20946, 20938, 6925, 980, 24661, 24662, - 24663, 20939, 31925, 20943, 20940, 20944, 20942, 20945, 20941, 21091, - 22892, 41138, 41139, 41140, 31758, 31763, 31761, 31757, 31760, 31759, - 31762, 27770, 27771, 27773, 27772, 31754, 31755, 39325, 28473, 28472, - 32763, 34071, 28468, 28469, 6854, 28470, 6648, 31756, 27774, 28471, - 20961, 32234, 41134, 374, 20957, 38205, 38206, 20956, 20955, 38207, - 38203, 20954, 38202, 20953, 38204, 20958, 8143, 8149, 11368, 11369, 8144, - 25291, 25299, 11358, 11359, 38152, 38153, 34010, 34009, 25296, 25293, - 25301, 25292, 25300, 25290, 25294, 25289, 34061, 25298, 25297, 41135, - 41131, 16937, 20632, 38012, 38013, 37698, 37697, 33854, 8609, 16938, 365, - 1060, 16927, 31764, 16928, 11348, 38147, 37406, 16936, 16940, 24561, - 18301, 24562, 18302, 24553, 18288, 24556, 18291, 24554, 18289, 24555, - 18290, 24552, 18292, 24546, 18284, 24545, 18283, 24543, 18280, 24541, - 18278, 24540, 18277, 24539, 18281, 24542, 18279, 33995, 33993, 33996, - 33994, 11395, 11394, 11391, 11390, 33853, 33852, 33851, 33850, 11361, - 11363, 11362, 18296, 18285, 24550, 18299, 24551, 18300, 34069, 22900, - 34070, 22901, 16933, 31844, 34789, 31845, 34790, 31847, 34792, 31843, - 34788, 31846, 34791, 31842, 34787, 11364, 11373, 34784, 34956, 34783, - 34955, 34782, 34954, 34781, 34953, 34776, 34948, 34777, 34949, 34775, - 34947, 34778, 34950, 34455, 34542, 8138, 8140, 8139, 8141, 34771, 34942, - 34772, 34941, 34945, 34944, 16844, 31662, 37990, 17635, 29543, 33027, - 33033, 33030, 31485, 39274, 11382, 39273, 11380, 25302, 33034, 33032, - 33031, 11349, 11377, 11371, 32067, 11151, 39290, 39289, 11419, 31249, - 31248, 38017, 38020, 38011, 38024, 38023, 11393, 11392, 38021, 22889, - 11376, 39762, 28981, 29560, 29587, 34202, 34215, 24271, 24397, 38366, - 11458, 29557, 29584, 34199, 34212, 24273, 38223, 32260, 32261, 24379, - 24380, 34570, 34563, 34573, 34567, 10965, 10966, 10964, 10963, 11331, - 3948, 39691, 4041, 39763, 3982, 39710, 39688, 3939, 20560, 3943, 3965, - 39702, 3968, 39706, 4001, 4002, 39723, 3941, 39689, 4038, 39759, 24217, - 37399, 24216, 25313, 24436, 24435, 24437, 24438, 24373, 24383, 24382, - 24431, 24433, 24432, 24367, 39589, 16929, 32060, 24360, 32246, 32245, - 24462, 32341, 32061, 32236, 37695, 24362, 24361, 32237, 11472, 33025, - 33023, 39703, 4003, 39724, 3992, 39714, 19893, 19906, 19870, 19868, - 19871, 33997, 2656, 33998, 2655, 3698, 33024, 24413, 38385, 32310, 11461, - 24275, 38227, 29582, 29555, 34197, 34210, 24425, 38396, 32322, 11473, - 8135, 973, 24424, 38387, 32321, 11463, 41412, 41412, 29583, 29556, 34198, - 34211, 24415, 38395, 32312, 11471, 20581, 39303, 24414, 38386, 32311, - 11462, 24426, 38397, 32323, 11474, 24396, 38365, 32274, 11460, 970, 971, - 969, 972, 32051, 32052, 29455, 29456, 17642, 32275, 16935, 35055, 37410, - 37414, 37411, 37413, 3955, 4035, 3997, 3929, 11465, 11466, 38389, 38390, - 24418, 32315, 24417, 32314, 3872, 3873, 3874, 3875, 3876, 3878, 3877, - 3879, 32098, 32099, 32096, 32097, 32093, 32095, 32092, 32094, 38410, - 38215, 31057, 31056, 31058, 2800, 6923, 6637, 4008, 3919, 38122, 20559, - 4042, 3972, 3964, 3967, 3970, 29461, 37922, 4450, 24574, 32408, 39680, - 32409, 34527, 38198, 18828, 31770, 31769, 31768, 31767, 37989, 31869, - 2576, 20615, 31643, 29238, 39707, 3922, 38034, 10075, 19843, 41220, - 22725, 1055, 97, 39413, 31781, 24242, 32135, 34716, 34717, 24434, 38401, - 32330, 11478, 16950, 16949, 32853, 32550, 32548, 32549, 32547, 32551, - 32552, 16934, 38209, 32844, 11416, 31404, 32074, 20088, 18066, 18068, - 18102, 18076, 18072, 18103, 18110, 18073, 18109, 18082, 18078, 18077, - 18071, 18113, 18084, 18085, 18086, 18087, 18089, 18091, 18095, 18099, - 18112, 18074, 18111, 18088, 18090, 18092, 18101, 18070, 18094, 18105, - 18104, 18106, 18096, 18108, 18097, 18098, 18107, 18080, 18067, 18079, - 18075, 18081, 18093, 18100, 18083, 18069, 18114, 18116, 18150, 18124, - 18120, 18151, 18158, 18121, 18157, 18130, 18126, 18125, 18119, 18161, - 18132, 18133, 18134, 18135, 18137, 18139, 18143, 18147, 18160, 18122, - 18159, 18136, 18138, 18140, 18149, 18118, 18142, 18153, 18152, 18154, - 18144, 18156, 18145, 18146, 18155, 18128, 18115, 18127, 18123, 18129, - 18141, 18148, 18131, 18117, 23124, 23771, 23127, 23218, 23236, 23505, - 23997, 23067, 23690, 23113, 23750, 23382, 24164, 22945, 23146, 23286, - 23287, 24117, 23359, 24134, 24116, 23072, 23697, 24062, 23618, 24038, - 23852, 23430, 24189, 27898, 23262, 23386, 8617, 8711, 8667, 8761, 8631, - 8725, 8628, 8722, 8672, 8766, 8662, 8756, 8666, 8760, 8633, 8727, 8664, - 8758, 8670, 8764, 8636, 8730, 8641, 8735, 8673, 8767, 8674, 8768, 8637, - 8731, 8642, 8736, 8669, 8763, 8671, 8765, 8663, 8757, 8665, 8759, 8675, - 8769, 8639, 8733, 8635, 8729, 8668, 8762, 8658, 8752, 8625, 8719, 8653, - 8747, 8621, 8715, 8626, 8720, 8627, 8721, 8622, 8716, 8651, 8745, 8661, - 8755, 8623, 8717, 8649, 8743, 8652, 8746, 8616, 8710, 8624, 8718, 8644, - 8738, 8645, 8739, 8640, 8734, 8647, 8741, 8646, 8740, 8643, 8737, 8650, - 8744, 8648, 8742, 8656, 8750, 8654, 8748, 8655, 8749, 8657, 8751, 8771, - 8772, 8773, 8775, 8776, 8770, 8774, 8619, 8713, 8620, 8714, 8615, 8614, - 8613, 8618, 8712, 41412, 41412, 41412, 41412, 41412, 8709, 8706, 8707, - 8708, 8704, 8705, 8777, 17925, 17951, 17936, 17957, 17958, 17956, 17946, - 17947, 17959, 17940, 17949, 17952, 17954, 17960, 17942, 17945, 17950, - 17944, 17948, 17961, 17941, 17939, 17935, 17955, 17943, 17931, 17934, - 17938, 17933, 17932, 17953, 17937, 17926, 17930, 17928, 17963, 17927, - 17929, 41412, 17962, 41412, 41412, 41412, 41412, 41412, 17924, 41412, - 41412, 37645, 37665, 37666, 37646, 37648, 37635, 37674, 37661, 37664, - 37662, 37663, 37684, 37673, 37649, 37639, 37651, 37667, 37634, 37643, - 37668, 37672, 37650, 37640, 37679, 37644, 37685, 37659, 37633, 37641, - 37675, 37676, 37677, 37638, 37642, 37678, 37687, 37669, 37670, 37647, - 37637, 37632, 37652, 37654, 37653, 37655, 37656, 37671, 37657, 37680, - 37681, 37682, 37658, 37636, 37660, 37683, 37686, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 37688, 37689, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 37631, 17385, 17202, 17289, 17329, 17305, 16992, 17367, 17030, 17220, - 17211, 17112, 17445, 17060, 17045, 17376, 17336, 17021, 17236, 17249, - 17097, 17101, 17100, 17099, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 17319, 17325, 17323, 17320, 17322, 17321, 17324, - 41412, 17011, 17017, 17015, 17012, 17014, 17013, 17016, 41412, 17435, - 17441, 17439, 17436, 17438, 17437, 17440, 41412, 17004, 17010, 17008, - 17005, 17007, 17006, 17009, 41412, 17271, 17277, 17275, 17272, 17274, - 17273, 17276, 41412, 17180, 17186, 17184, 17181, 17183, 17182, 17185, - 41412, 17412, 17418, 17416, 17413, 17415, 17414, 17417, 41412, 17123, - 17129, 17127, 17124, 17126, 17125, 17128, 41412, 8197, 8235, 8232, 8199, - 8229, 8230, 8236, 8203, 8204, 8205, 8212, 8234, 8206, 8200, 8228, 8225, - 8227, 8231, 8215, 8214, 8233, 8201, 8237, 8211, 8198, 8224, 8220, 8222, - 8209, 8223, 8196, 8208, 32109, 32108, 24293, 32179, 24235, 32124, 31946, - 31945, 11334, 24296, 32187, 31954, 24276, 32159, 11675, 31247, 17634, - 32069, 20622, 11333, 11457, 38349, 11336, 11384, 20970, 31206, 20618, - 37701, 24256, 32149, 37700, 37699, 24325, 32193, 37931, 37935, 4455, - 4458, 24281, 32164, 24234, 32129, 38150, 30705, 34630, 17601, 32084, - 39306, 32344, 39823, 38126, 31944, 31956, 38137, 10662, 10663, 38127, - 37920, 38162, 37417, 34730, 39309, 39806, 6104, 11352, 32083, 11355, - 10669, 11372, 20971, 20972, 25335, 25336, 11370, 11330, 38022, 27135, - 31246, 31903, 8780, 8817, 8818, 37789, 27134, 27136, 24291, 32177, 24290, - 32176, 37912, 37916, 4441, 4445, 30112, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 8021, 7974, 8024, 8023, 8022, 8017, 7945, 8042, 8056, 8055, 7978, 8025, - 8038, 8037, 8007, 8006, 8005, 8004, 8034, 8043, 8033, 8032, 7993, 7992, - 7996, 8020, 41412, 7977, 8040, 8014, 7979, 8012, 7972, 8048, 8047, 7986, - 8016, 8015, 8026, 7976, 7980, 8001, 7943, 7985, 8036, 8035, 7948, 8031, - 7959, 8054, 8053, 8052, 8051, 8009, 8039, 8019, 7984, 8057, 7947, 7946, - 8008, 8013, 7990, 7989, 7988, 8044, 7975, 8050, 8049, 7963, 8027, 7995, - 7962, 7961, 7987, 7971, 8028, 8046, 8045, 7973, 7955, 8003, 8002, 7958, - 7956, 8011, 8010, 8018, 7949, 7965, 7957, 7967, 7953, 7983, 7982, 7981, - 7951, 7994, 7970, 7944, 7991, 7952, 7969, 7960, 8029, 8030, 7954, 8000, - 7950, 7998, 7966, 7999, 7968, 8041, 7997, 7964, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 21290, - 21272, 21206, 21326, 21314, 21258, 21358, 21273, 21286, 21269, 21221, - 21225, 21210, 21195, 21261, 21347, 21293, 21264, 21298, 21375, 21332, - 21303, 21255, 21360, 21204, 21315, 21191, 21295, 21166, 21284, 21220, - 21218, 21313, 21241, 21243, 21223, 21173, 21372, 21198, 21306, 21260, - 21342, 21265, 21193, 21331, 21282, 21304, 21373, 21291, 21356, 21216, - 21321, 21207, 21275, 21359, 21322, 21181, 21340, 21182, 21334, 21252, - 21249, 21212, 21250, 21183, 21301, 21312, 21205, 21168, 21343, 21288, - 21345, 21311, 21285, 21355, 21266, 21335, 21200, 21366, 21211, 21194, - 21240, 21189, 21333, 21365, 21232, 21190, 21227, 21209, 21248, 21327, - 21229, 21197, 21213, 21296, 21262, 21276, 21350, 21339, 21271, 21377, - 21230, 21177, 21323, 21208, 21368, 21344, 21203, 21226, 21328, 21164, - 21337, 21330, 21354, 21244, 21188, 21338, 21169, 21305, 21324, 21263, - 21289, 21319, 21238, 21294, 21167, 21297, 21217, 21184, 21277, 21278, - 21316, 21165, 21280, 21351, 21292, 21178, 21336, 21196, 21245, 21349, - 21259, 21174, 21364, 21192, 21367, 21317, 21257, 21329, 21361, 21185, - 21299, 21170, 21318, 21308, 21307, 21239, 21180, 21187, 21171, 21281, - 21363, 21199, 21371, 21202, 21362, 21242, 21274, 21247, 21283, 21325, - 21320, 21300, 21176, 21374, 21228, 21267, 21346, 21270, 21341, 21268, - 21370, 21235, 21219, 21253, 21236, 21256, 21179, 21348, 21251, 21231, - 21309, 21186, 21246, 21233, 21172, 21310, 21201, 21369, 21254, 21376, - 21279, 21175, 21224, 21237, 21353, 21215, 21302, 21287, 21222, 21352, - 21214, 21357, 21234, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 20655, - 20653, 20654, 20652, 20667, 20663, 20662, 20659, 20660, 20661, 20657, - 20656, 20664, 20658, 20668, 20666, 20752, 20651, 20750, 11140, 20990, - 20751, 20650, 20670, 24213, 32106, 24232, 32125, 24228, 32122, 24307, - 32196, 24222, 32116, 31783, 18059, 24304, 32191, 24309, 32198, 24312, - 32201, 24311, 32200, 39588, 32066, 11366, 25333, 31784, 19739, 19732, - 19729, 19735, 19734, 19737, 19736, 19740, 19738, 20748, 20747, 20669, - 20746, 19398, 19397, 39594, 39281, 39284, 39282, 39285, 39283, 6906, - 20744, 19733, 19731, 19730, 39280, 25992, 31401, 20749, 20745, 41412, - 20464, 20450, 20466, 20544, 20468, 20546, 20465, 20543, 20467, 20545, - 20505, 20495, 20507, 20497, 20509, 20499, 20506, 20496, 20508, 20498, - 20469, 20530, 20471, 20532, 20473, 20534, 20470, 20531, 20472, 20533, - 20525, 20490, 20527, 20492, 20463, 20529, 20494, 20526, 20491, 20528, - 20493, 20485, 20487, 20489, 20486, 20488, 20500, 20480, 20515, 20502, - 20474, 20517, 20504, 20483, 20519, 20501, 20481, 20516, 20503, 20482, - 20518, 20510, 20512, 20514, 20511, 20513, 20457, 20539, 20459, 20541, - 20458, 20540, 20520, 20522, 20524, 20521, 20523, 20453, 20535, 20537, - 20536, 20538, 20484, 20542, 20460, 20461, 41412, 41412, 8405, 8404, - 21616, 21615, 20548, 20547, 20449, 21613, 21543, 21472, 21545, 21606, - 21547, 21608, 21544, 21605, 21546, 21607, 21568, 21558, 21570, 21560, - 21572, 21562, 21569, 21559, 21571, 21561, 21548, 21593, 21550, 21595, - 21552, 21597, 21549, 21594, 21551, 21596, 21583, 21553, 21585, 21555, - 21530, 21587, 21557, 21584, 21554, 21586, 21556, 21510, 21512, 21514, - 21511, 21513, 21563, 21487, 21573, 21565, 21481, 21575, 21567, 21490, - 21577, 21564, 21488, 21574, 21566, 21489, 21576, 21505, 21491, 21508, - 21506, 21507, 21535, 21602, 21537, 21604, 21536, 21603, 21578, 21580, - 21582, 21579, 21581, 21531, 21598, 21600, 21599, 21601, 21509, 21592, - 21525, 21526, 21588, 21590, 21589, 21591, 21612, 21614, 21611, 21609, - 21610, 41412, 41412, 41412, 41412, 41412, 4422, 4430, 4429, 4427, 4426, - 4433, 4398, 4418, 4386, 4414, 4428, 4424, 4431, 4435, 4411, 4417, 4421, - 4432, 4410, 4416, 4420, 4366, 4402, 4378, 4383, 4367, 4384, 4369, 4409, - 4371, 4379, 4372, 4380, 4385, 4391, 4376, 4397, 4434, 4399, 4388, 4394, - 4405, 4401, 41412, 19651, 19695, 19652, 19657, 19658, 19660, 19687, - 19698, 19673, 19674, 19676, 19678, 19685, 19681, 19677, 19684, 19653, - 19663, 19697, 19664, 19688, 19700, 19645, 19640, 19694, 19639, 19650, - 19686, 19671, 19724, 19635, 19638, 19721, 19722, 19642, 19641, 19708, - 19707, 19725, 19704, 19705, 19726, 19713, 19727, 19703, 19702, 19706, - 19717, 19643, 19723, 19644, 19728, 19696, 19659, 19662, 19661, 19675, - 19682, 19679, 19680, 19683, 19654, 19656, 19655, 19649, 19670, 19668, - 19665, 19666, 19669, 19667, 19647, 19648, 19690, 19691, 19693, 19692, - 19689, 19672, 19701, 19710, 19712, 19711, 19646, 19699, 19709, 19714, - 19715, 19716, 19719, 19718, 19720, 19636, 19637, 41412, 20644, 20647, - 20646, 20642, 20640, 20636, 20643, 20638, 20634, 20637, 20645, 20641, - 20635, 20648, 20649, 20639, 4423, 4412, 4425, 4389, 4382, 4381, 4408, - 4404, 4396, 4373, 4392, 4377, 4395, 4400, 4368, 4370, 4375, 4407, 4403, - 4393, 4364, 4365, 4363, 4362, 4387, 4419, 4413, 4361, 4390, 4415, 4406, - 4374, 8088, 8091, 8092, 8090, 8078, 8064, 8070, 8059, 8069, 8082, 8071, - 8067, 8060, 8068, 8065, 8094, 8058, 8077, 8073, 8086, 8093, 8063, 8072, - 8081, 8080, 8087, 8085, 8074, 8076, 8089, 8084, 8079, 8061, 8066, 8075, - 8095, 8062, 8083, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 20665, 21528, 21540, 21541, 21529, 21539, 21515, 21517, 21519, - 21516, 21518, 21542, 21520, 21522, 21524, 21521, 21523, 31261, 31265, - 31277, 31271, 31263, 31269, 31273, 31279, 31254, 31252, 31259, 31275, - 31267, 31257, 31262, 31266, 31278, 31272, 31264, 31270, 31274, 31280, - 31255, 31253, 31260, 31276, 31268, 31258, 31256, 31318, 31317, 41412, - 31316, 31312, 31310, 31291, 31289, 31309, 31301, 31286, 31295, 31311, - 31294, 31288, 31314, 31313, 31293, 31285, 31308, 31306, 31315, 31303, - 31296, 31304, 31287, 31282, 31292, 31299, 31283, 31305, 31307, 31284, - 31297, 31281, 31290, 31298, 31302, 31300, 6725, 6713, 6735, 6714, 6879, - 6893, 6881, 6863, 6860, 6876, 6874, 6856, 31400, 6894, 6900, 6899, 6896, - 6895, 6898, 6897, 6902, 6901, 6880, 6882, 6888, 6887, 6884, 6883, 6673, - 6677, 6689, 6683, 6675, 6681, 6685, 6666, 6664, 6662, 6671, 6687, 6679, - 6669, 6674, 6678, 6690, 6684, 6676, 6682, 6686, 6667, 6665, 6663, 6672, - 6688, 6680, 6670, 6800, 6799, 6668, 22723, 6748, 6744, 6742, 6710, 6708, - 6740, 6731, 6705, 6723, 6743, 6721, 6707, 6746, 6745, 6719, 6703, 6734, - 6739, 6712, 6736, 6724, 6737, 6706, 6699, 6715, 6730, 6720, 6709, 6733, - 6704, 6741, 6696, 6747, 6727, 6700, 6698, 6711, 6701, 6716, 6717, 6729, - 6718, 6728, 6738, 6732, 6702, 6726, 6694, 6722, 6886, 6885, 6890, 6889, - 6862, 6864, 6870, 6869, 6866, 6865, 6868, 6867, 6872, 6871, 6859, 20735, - 20738, 20739, 20677, 20740, 20736, 20737, 20676, 20742, 20743, 20741, - 20709, 34415, 34381, 34383, 24660, 6794, 6796, 6798, 6795, 6797, 6757, - 6759, 6761, 6758, 6760, 6777, 6779, 6781, 6778, 6780, 6782, 6784, 6786, - 6783, 6785, 6767, 6769, 6771, 6768, 6770, 6752, 6754, 6756, 6753, 6755, - 6762, 6764, 6766, 6763, 6765, 6791, 6793, 6792, 6772, 6774, 6776, 6773, - 6775, 6787, 6789, 6788, 6790, 34379, 34340, 34342, 34341, 34343, 34418, - 34419, 34582, 34382, 34375, 34508, 34512, 34427, 34425, 34426, 34390, - 34391, 34395, 34394, 34441, 34393, 34428, 34431, 34429, 34430, 34396, - 34397, 34438, 34439, 34440, 34437, 34436, 34548, 34549, 34556, 34550, - 34551, 34366, 34370, 34371, 34561, 34501, 34502, 34403, 34515, 34516, - 34347, 34524, 34522, 34523, 34350, 34410, 34409, 34349, 34411, 34404, - 34521, 34519, 34405, 34520, 34518, 34352, 34525, 34351, 34408, 34526, - 34406, 34407, 34465, 34466, 34469, 34468, 34467, 34475, 34476, 34477, - 34472, 34473, 34474, 34580, 34579, 34581, 34543, 34544, 34546, 34545, - 34541, 34540, 34562, 20733, 20734, 20716, 20718, 20725, 20724, 20731, - 20729, 20720, 20727, 20719, 20722, 20715, 20717, 20726, 20723, 20732, - 20730, 20721, 20728, 20710, 20714, 20713, 20712, 20711, 34413, 34365, - 34345, 34348, 34513, 34529, 34367, 34369, 34368, 34423, 34376, 34380, - 34377, 34378, 34357, 34517, 34500, 34482, 34464, 34424, 34446, 34470, - 34400, 34354, 34443, 34530, 34503, 34483, 34484, 34497, 34447, 34416, - 34442, 34494, 34398, 34560, 34485, 34498, 34374, 34449, 34389, 34504, - 34486, 34479, 34358, 34432, 34481, 34360, 34463, 34435, 34480, 34359, - 34462, 34434, 34459, 34460, 34514, 34445, 34496, 34399, 34537, 34538, - 34539, 34534, 34505, 34487, 34499, 34535, 34506, 34488, 34490, 34451, - 34491, 34536, 34507, 34489, 34492, 34452, 34493, 34444, 34461, 34344, - 34353, 34363, 34364, 34361, 34356, 34372, 34401, 34402, 34412, 34417, - 34448, 34433, 34450, 34456, 34457, 34454, 34458, 34471, 34478, 34495, - 34531, 34532, 34528, 34533, 34557, 34558, 34578, 34346, 34338, 20708, - 20693, 20681, 20700, 20699, 20706, 20704, 20695, 20702, 20694, 20697, - 20692, 20680, 20701, 20698, 20707, 20705, 20696, 20703, 20682, 20690, - 20688, 20687, 20684, 20683, 20686, 20685, 20691, 20689, 20678, 20679, - 34392, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 20426, - 20429, 20390, 20440, 20437, 20385, 20423, 20402, 20419, 20436, 20414, - 20420, 20395, 20397, 20407, 20441, 20394, 20438, 20378, 20384, 20382, - 20401, 20421, 20415, 20403, 20400, 20408, 20399, 20424, 20427, 20406, - 20392, 20416, 20398, 20413, 20393, 20428, 20411, 20409, 20388, 20387, - 20405, 20383, 20386, 20396, 20412, 20410, 20430, 20417, 20425, 20422, - 20434, 20389, 20432, 20380, 20431, 20433, 20435, 20391, 20439, 20404, - 20418, 20379, 20381, 40345, 40352, 40344, 40351, 40349, 40350, 40347, - 40348, 41120, 41121, 41118, 41119, 41117, 41115, 41116, 41124, 41125, - 41122, 41123, 41127, 41126, 40992, 40012, 40013, 40006, 40011, 40009, - 40010, 40007, 40008, 40016, 40017, 40014, 40015, 39997, 39995, 39996, - 40020, 40021, 40018, 40019, 40005, 40003, 40004, 40001, 40002, 39994, - 40000, 39999, 39998, 40026, 40027, 40022, 40025, 40024, 40023, 40724, - 40725, 40719, 40723, 40722, 40720, 40721, 40728, 40729, 40726, 40727, - 40713, 40711, 40712, 40732, 40733, 40730, 40731, 40717, 40718, 40710, - 40716, 40715, 40714, 40738, 40739, 40734, 40737, 40736, 40735, 39980, - 39981, 39974, 39979, 39977, 39978, 39975, 39976, 39984, 39985, 39982, - 39983, 39965, 39963, 39964, 39988, 39989, 39986, 39987, 39973, 39971, - 39972, 39969, 39970, 39962, 39968, 39967, 39966, 39992, 39993, 39990, - 39991, 40527, 40528, 40522, 40526, 40525, 40523, 40524, 40531, 40532, - 40529, 40530, 40535, 40536, 40533, 40534, 40541, 40542, 40537, 40540, - 40539, 40538, 40547, 40548, 40543, 40546, 40545, 40544, 40270, 40271, - 40265, 40269, 40268, 40266, 40267, 40274, 40275, 40272, 40273, 40259, - 40257, 40258, 40278, 40279, 40276, 40277, 40263, 40264, 40256, 40262, - 40261, 40260, 40284, 40280, 40283, 40282, 40281, 40506, 40507, 40501, - 40505, 40504, 40502, 40503, 40510, 40511, 40508, 40509, 40494, 40495, - 40492, 40493, 40514, 40515, 40512, 40513, 40521, 40520, 40499, 40500, - 40491, 40498, 40497, 40496, 40518, 40519, 40516, 40517, 40151, 40152, - 40149, 40150, 40147, 40148, 40145, 40146, 40144, 40142, 40143, 40161, - 40162, 40157, 40160, 40159, 40158, 40155, 40156, 40153, 40154, 40970, - 40971, 40964, 40969, 40967, 40968, 40965, 40966, 40974, 40975, 40972, - 40973, 40978, 40979, 40976, 40977, 40963, 40962, 40984, 40985, 40980, - 40983, 40982, 40981, 40990, 40991, 40986, 40989, 40988, 40987, 40129, - 40130, 40124, 40128, 40127, 40125, 40126, 40136, 40137, 40134, 40135, - 40118, 40117, 40140, 40141, 40138, 40139, 40133, 40131, 40132, 40122, - 40123, 40116, 40121, 40120, 40119, 40949, 40950, 40944, 40948, 40947, - 40945, 40946, 40956, 40957, 40954, 40955, 40937, 40938, 40935, 40936, - 40960, 40961, 40958, 40959, 40953, 40951, 40952, 40942, 40943, 40934, - 40941, 40940, 40939, 40103, 40104, 40098, 40102, 40101, 40099, 40100, - 40110, 40111, 40108, 40109, 40092, 40090, 40091, 40114, 40115, 40112, - 40113, 40107, 40105, 40106, 40096, 40097, 40089, 40095, 40094, 40093, - 40553, 40554, 40549, 40552, 40551, 40550, 40560, 40561, 40558, 40559, - 40564, 40565, 40562, 40563, 40557, 40555, 40556, 40570, 40571, 40566, - 40569, 40568, 40567, 40300, 40301, 40294, 40299, 40297, 40298, 40295, - 40296, 40304, 40305, 40302, 40303, 40289, 40288, 40286, 40287, 40285, - 40293, 40291, 40292, 40290, 40698, 40699, 40693, 40697, 40696, 40694, - 40695, 40702, 40700, 40701, 40687, 40685, 40686, 40708, 40709, 40706, - 40707, 40705, 40703, 40704, 40691, 40692, 40684, 40690, 40689, 40688, - 40238, 40239, 40233, 40237, 40236, 40234, 40235, 40248, 40249, 40246, - 40247, 40227, 40225, 40226, 40245, 40243, 40244, 40242, 40240, 40241, - 40231, 40232, 40224, 40230, 40229, 40228, 40254, 40255, 40250, 40253, - 40252, 40251, 40453, 40454, 40447, 40452, 40450, 40451, 40448, 40449, - 40457, 40458, 40455, 40456, 40437, 40438, 40435, 40436, 40461, 40462, - 40459, 40460, 40446, 40444, 40445, 40442, 40443, 40434, 40441, 40440, - 40439, 40467, 40468, 40463, 40466, 40465, 40464, 40207, 40208, 40201, - 40206, 40204, 40205, 40202, 40203, 40211, 40212, 40209, 40210, 40194, - 40195, 40192, 40193, 40219, 40220, 40217, 40218, 40215, 40216, 40213, - 40214, 40199, 40200, 40191, 40198, 40197, 40196, 40420, 40421, 40415, - 40419, 40418, 40416, 40417, 40424, 40425, 40422, 40423, 40409, 40407, - 40408, 40432, 40433, 40430, 40431, 40428, 40429, 40426, 40427, 40413, - 40414, 40406, 40412, 40411, 40410, 40167, 40168, 40163, 40166, 40164, - 40165, 40181, 40182, 40179, 40180, 40172, 40173, 40170, 40171, 40189, - 40190, 40187, 40188, 40185, 40186, 40183, 40184, 40177, 40178, 40169, - 40176, 40175, 40174, 40490, 40489, 40483, 40484, 40481, 40482, 40472, - 40470, 40471, 40487, 40488, 40485, 40486, 40480, 40478, 40479, 40476, - 40477, 40469, 40475, 40474, 40473, 40319, 40320, 40313, 40318, 40316, - 40317, 40314, 40315, 40323, 40324, 40321, 40322, 40308, 40309, 40306, - 40307, 40327, 40328, 40325, 40326, 40312, 40310, 40311, 40580, 40578, - 40579, 40583, 40584, 40581, 40582, 40573, 40574, 40572, 40587, 40588, - 40585, 40586, 40577, 40575, 40576, 40223, 40222, 40221, 40338, 40339, - 40336, 40337, 40331, 40332, 40329, 40330, 40342, 40343, 40340, 40341, - 40335, 40333, 40334, 41004, 41005, 41002, 41003, 40995, 40993, 40994, - 41001, 40999, 41000, 40998, 40996, 40997, 41067, 41068, 41062, 41066, - 41065, 41063, 41064, 41103, 41104, 41101, 41102, 41056, 41054, 41055, - 41107, 41108, 41105, 41106, 41100, 41098, 41099, 41060, 41061, 41053, - 41059, 41058, 41057, 41113, 41114, 41109, 41112, 41111, 41110, 40073, - 40074, 40067, 40072, 40070, 40071, 40068, 40069, 40077, 40078, 40075, - 40076, 40058, 40056, 40057, 40081, 40082, 40079, 40080, 40066, 40064, - 40065, 40062, 40063, 40055, 40061, 40060, 40059, 40087, 40088, 40083, - 40086, 40085, 40084, 41081, 41082, 41075, 41080, 41078, 41079, 41076, - 41077, 41085, 41086, 41083, 41084, 41074, 41072, 41073, 41071, 41069, - 41070, 41091, 41087, 41090, 41089, 41088, 41096, 41097, 41092, 41095, - 41094, 41093, 40670, 40671, 40665, 40669, 40668, 40666, 40667, 40674, - 40675, 40672, 40673, 40658, 40657, 40664, 40663, 40683, 40682, 40662, - 40656, 40661, 40660, 40659, 40680, 40681, 40676, 40679, 40678, 40677, - 40915, 40916, 40910, 40914, 40913, 40911, 40912, 40922, 40923, 40920, - 40921, 40904, 40902, 40903, 40926, 40927, 40924, 40925, 40919, 40917, - 40918, 40908, 40909, 40901, 40907, 40906, 40905, 40932, 40933, 40928, - 40931, 40930, 40929, 40851, 40852, 40846, 40850, 40849, 40847, 40848, - 40858, 40859, 40856, 40857, 40862, 40863, 40860, 40861, 40855, 40853, - 40854, 40866, 40867, 40864, 40865, 40872, 40873, 40868, 40871, 40870, - 40869, 41037, 41038, 41035, 41036, 41029, 41027, 41028, 41045, 41046, - 41043, 41044, 41041, 41042, 41039, 41040, 41033, 41034, 41026, 41032, - 41031, 41030, 41051, 41052, 41047, 41050, 41049, 41048, 40039, 40040, - 40037, 40038, 40031, 40032, 40029, 40030, 40047, 40048, 40045, 40046, - 40043, 40044, 40041, 40042, 40036, 40028, 40035, 40034, 40033, 40053, - 40054, 40049, 40052, 40051, 40050, 40819, 40818, 40798, 40797, 40810, - 40811, 40808, 40809, 40806, 40807, 40804, 40805, 40802, 40803, 40796, - 40801, 40800, 40799, 40816, 40817, 40812, 40815, 40814, 40813, 40619, - 40620, 40617, 40618, 40616, 40614, 40615, 40623, 40624, 40621, 40622, - 40629, 40630, 40625, 40628, 40627, 40626, 40635, 40636, 40631, 40634, - 40633, 40632, 40885, 40886, 40883, 40884, 40877, 40875, 40876, 40893, - 40894, 40891, 40892, 40889, 40890, 40887, 40888, 40881, 40882, 40874, - 40880, 40879, 40878, 40899, 40900, 40895, 40898, 40897, 40896, 40834, - 40835, 40832, 40833, 40823, 40821, 40822, 40838, 40839, 40836, 40837, - 40831, 40829, 40830, 40827, 40828, 40820, 40826, 40825, 40824, 40844, - 40845, 40840, 40843, 40842, 40841, 40394, 40395, 40388, 40393, 40391, - 40392, 40389, 40390, 40381, 40382, 40379, 40380, 40398, 40399, 40396, - 40397, 40386, 40387, 40378, 40385, 40384, 40383, 40404, 40405, 40400, - 40403, 40402, 40401, 40756, 40757, 40750, 40755, 40753, 40754, 40751, - 40752, 40743, 40744, 40741, 40742, 40760, 40761, 40758, 40759, 40748, - 40749, 40740, 40747, 40746, 40745, 40766, 40767, 40762, 40765, 40764, - 40763, 40368, 40369, 40362, 40367, 40365, 40366, 40363, 40364, 40356, - 40354, 40355, 40372, 40373, 40370, 40371, 40360, 40361, 40353, 40359, - 40358, 40357, 40376, 40377, 40374, 40375, 40602, 40603, 40596, 40601, - 40599, 40600, 40597, 40598, 40591, 40590, 40606, 40607, 40604, 40605, - 40595, 40589, 40594, 40593, 40592, 40612, 40613, 40608, 40611, 40610, - 40609, 40650, 40651, 40644, 40649, 40647, 40648, 40645, 40646, 40640, - 40638, 40639, 40654, 40655, 40652, 40653, 40642, 40643, 40637, 40641, - 41012, 41013, 41006, 41011, 41009, 41010, 41007, 41008, 41025, 41024, - 41016, 41017, 41014, 41015, 41022, 41023, 41018, 41021, 41020, 41019, - 40784, 40785, 40778, 40783, 40781, 40782, 40779, 40780, 40771, 40772, - 40769, 40770, 40788, 40789, 40786, 40787, 40776, 40777, 40768, 40775, - 40774, 40773, 40794, 40795, 40790, 40793, 40792, 40791, 41412, 41412, - 41412, 39959, 39932, 39930, 39937, 39911, 39947, 39918, 39920, 39936, - 39923, 39934, 39907, 39935, 39953, 39941, 39922, 39948, 39921, 39954, - 39912, 39915, 39908, 39917, 39938, 39949, 39961, 39926, 39957, 39942, - 39925, 39952, 39950, 39946, 39951, 39958, 39929, 39939, 39928, 39919, - 39927, 39960, 39916, 39943, 39933, 39910, 39909, 39914, 39924, 39944, - 39955, 39945, 39913, 39956, 39940, 39931, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 25263, 25252, 25251, 25235, 25233, - 25232, 25246, 25250, 25249, 25265, 25244, 25243, 25234, 25231, 25230, - 25267, 25240, 25266, 25254, 25257, 25258, 25239, 25248, 25269, 25247, - 25264, 25268, 25253, 25256, 25245, 25259, 25260, 25241, 25242, 25270, - 25261, 25236, 25237, 25238, 25262, 25226, 25229, 25227, 25225, 25228, - 25224, 25271, 25272, 38679, 38680, 38516, 38665, 38666, 38639, 38442, - 38449, 38552, 38525, 38559, 38499, 38625, 38653, 38477, 38470, 38428, - 38421, 38543, 38646, 38435, 38578, 38463, 38456, 38491, 38484, 38618, - 38632, 38597, 38660, 38538, 38584, 38505, 38566, 38611, 38604, 38688, - 38689, 38520, 38521, 38674, 38675, 38641, 38444, 38451, 38554, 38531, - 38561, 38502, 38627, 38655, 38479, 38472, 38430, 38423, 38547, 38648, - 38437, 38580, 38465, 38458, 38493, 38486, 38620, 38634, 38599, 38662, - 38539, 38589, 38510, 38568, 38613, 38606, 38686, 38687, 38591, 38518, - 38519, 38672, 38673, 38640, 38443, 38450, 38553, 38529, 38530, 38560, - 38501, 38626, 38654, 38478, 38471, 38429, 38422, 38546, 38647, 38436, - 38579, 38464, 38457, 38492, 38485, 38619, 38633, 38598, 38661, 38535, - 38536, 38588, 38509, 38567, 38612, 38605, 38683, 38684, 38514, 38669, - 38670, 38637, 38440, 38447, 38550, 38528, 38557, 38497, 38623, 38651, - 38475, 38468, 38426, 38419, 38545, 38644, 38433, 38576, 38461, 38454, - 38489, 38482, 38616, 38630, 38595, 38658, 38534, 38587, 38508, 38564, - 38609, 38602, 38690, 38691, 38522, 38523, 38676, 38677, 38642, 38445, - 38452, 38555, 38532, 38562, 38503, 38628, 38656, 38480, 38473, 38431, - 38424, 38548, 38649, 38438, 38581, 38466, 38459, 38494, 38487, 38621, - 38635, 38600, 38663, 38540, 38590, 38511, 38569, 38614, 38607, 38682, - 38685, 38593, 38512, 38513, 38668, 38671, 38636, 38439, 38446, 38549, - 38527, 38556, 38495, 38496, 38622, 38650, 38474, 38467, 38425, 38418, - 38544, 38643, 38432, 38570, 38460, 38453, 38488, 38481, 38615, 38629, - 38594, 38657, 38533, 38586, 38507, 38563, 38608, 38601, 38678, 38681, - 38592, 38515, 38517, 38664, 38667, 38638, 38441, 38448, 38551, 38524, - 38526, 38558, 38498, 38500, 38624, 38652, 38476, 38469, 38427, 38420, - 38541, 38645, 38434, 38577, 38462, 38455, 38490, 38483, 38617, 38631, - 38596, 38659, 38537, 38583, 38585, 38504, 38506, 38565, 38610, 38603, - 38582, 38542, 38415, 38416, 38417, 38573, 38574, 38571, 38695, 38698, - 38701, 38700, 38704, 38696, 38703, 38694, 38692, 38699, 38702, 38693, - 38697, 38711, 38713, 38710, 38709, 38706, 38705, 38708, 38707, 38714, - 38712, 38575, 38572, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 10415, 10616, 10304, 10463, 10254, 10557, 10359, - 10518, 10300, 10459, 10380, 10543, 10288, 10447, 10247, 10544, 10408, - 10609, 10356, 10515, 10256, 10559, 10357, 10516, 10296, 10455, 10289, - 10448, 10353, 10512, 10410, 10611, 10255, 10558, 10399, 10577, 10396, - 10574, 10397, 10575, 10379, 10542, 10286, 10445, 10301, 10460, 10430, - 8251, 8243, 8194, 8244, 33999, 8218, 8207, 8221, 8217, 8226, 8219, 8216, - 8213, 8249, 8238, 10429, 10433, 10310, 10469, 10308, 10467, 10420, 10621, - 10298, 10457, 10306, 10465, 10260, 10585, 10268, 10594, 10264, 10589, - 10263, 10588, 10266, 10592, 10344, 10503, 10394, 10572, 10302, 10461, - 10297, 10456, 27910, 27947, 8202, 8210, 3462, 2824, 3465, 2826, 3461, - 3437, 3454, 3464, 2853, 3463, 2829, 3434, 3440, 3439, 2827, 2833, 3453, - 2852, 2846, 2832, 3449, 2840, 3444, 3450, 3443, 3447, 2822, 2818, 2850, - 2849, 2844, 3456, 3446, 3457, 3458, 2851, 2816, 3430, 2845, 2848, 3433, - 3459, 3431, 2813, 3442, 2831, 2838, 2855, 3436, 3441, 2817, 2841, 2842, - 2843, 3445, 3432, 2815, 2814, 3460, 2854, 2830, 3435, 2828, 2819, 2835, - 3438, 2834, 2837, 3455, 2825, 2839, 2836, 3452, 2823, 3451, 2847, 3448, - 2812, 2820, 2821, 2809, 2808, 3466, 3468, 2811, 2810, 3467, 3469, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 27907, 27903, 27906, - 27902, 27908, 27904, 27909, 27905, 27962, 27977, 28005, 27984, 27967, - 27961, 27976, 28004, 27983, 27966, 27963, 27978, 28006, 27988, 27968, - 27954, 27953, 27955, 27999, 28018, 28015, 28017, 28016, 27996, 28166, - 28167, 23034, 23638, 23035, 23639, 23074, 23700, 23301, 24063, 23300, - 24020, 22974, 23560, 22975, 23561, 23443, 23451, 22948, 23516, 22949, - 23517, 22950, 23518, 22946, 23514, 22947, 23515, 22951, 23519, 23245, - 23944, 23115, 23752, 23112, 23749, 23116, 23753, 22960, 23537, 23134, - 23776, 23167, 23851, 23168, 23853, 23214, 23891, 23219, 23896, 23217, - 23894, 23220, 23897, 23227, 23909, 23226, 23906, 23242, 23934, 23247, - 23947, 23342, 24113, 23351, 24125, 23346, 24120, 23295, 24014, 23296, - 24015, 23350, 24124, 23036, 23656, 23103, 23739, 22976, 23562, 28175, - 23598, 23797, 23811, 23834, 23946, 23428, 24058, 24110, 23096, 23728, - 23097, 23729, 23098, 23285, 24026, 23290, 24056, 23099, 23731, 23100, - 23732, 23101, 23733, 27982, 27951, 28028, 23268, 23970, 23288, 23781, - 23459, 23160, 23825, 22970, 23550, 23547, 23694, 22954, 23522, 23043, - 23663, 23347, 24121, 23348, 24122, 23349, 24123, 23051, 23674, 23119, - 23757, 23163, 23830, 23240, 23931, 23264, 23968, 23070, 23244, 23271, - 23122, 23267, 23450, 23289, 23292, 23106, 22977, 22961, 23539, 23212, - 23889, 23338, 24101, 23056, 23679, 23057, 23680, 23058, 23681, 23209, - 23880, 22943, 23511, 22968, 23265, 23388, 22981, 23564, 23261, 23962, - 23248, 23260, 23961, 23224, 23903, 22973, 23556, 22994, 23591, 22993, - 23588, 23149, 23810, 23270, 23988, 23138, 23786, 23139, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 27895, 27882, - 27885, 27894, 23243, 23935, 23398, 27877, 28107, 23433, 23396, 23397, - 23394, 23395, 23393, 34995, 34997, 35007, 34999, 34996, 34998, 35006, - 34987, 34986, 34983, 34982, 35005, 34981, 34980, 34985, 34984, 34975, - 34974, 34969, 34968, 34977, 34976, 34971, 34970, 34993, 34989, 34988, - 34979, 34978, 34992, 34973, 34991, 34972, 34994, 34990, 35009, 35011, - 35012, 35010, 35008, 35000, 35001, 35002, 35003, 35004, 41412, 41412, - 41412, 29568, 29567, 29570, 29565, 29566, 29569, 29562, 29561, 29564, - 29563, 41412, 41412, 41412, 41412, 41412, 41412, 31537, 31536, 31525, - 31526, 31513, 31515, 31547, 31528, 31535, 31534, 31518, 31529, 31539, - 31538, 31544, 31549, 31531, 31530, 31517, 31552, 31540, 31541, 31519, - 31554, 31551, 31548, 31520, 31521, 31546, 31510, 31555, 31557, 31542, - 31556, 31550, 31553, 31545, 31524, 31543, 31562, 31563, 31533, 31532, - 31516, 31527, 31511, 31523, 31522, 31512, 31561, 31564, 31514, 31560, - 31565, 31559, 31558, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 32682, 32684, 32631, 32632, 32652, 32653, 32648, 32649, 32643, - 32644, 32645, 32646, 32675, 32676, 32633, 32650, 32651, 32634, 32672, - 32671, 32668, 32667, 32656, 32666, 32665, 32670, 32669, 32658, 32640, - 32639, 32636, 32635, 32657, 32642, 32641, 32638, 32637, 32659, 32674, - 32673, 32664, 32663, 32678, 32680, 32679, 32655, 32647, 32660, 32661, - 32662, 32677, 32654, 32697, 32698, 32709, 32710, 32701, 32702, 32703, - 32704, 32705, 32706, 32711, 32712, 32699, 32707, 32708, 32700, 32683, - 32681, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 32686, - 32685, 32693, 32695, 32692, 32691, 32688, 32687, 32690, 32689, 32696, - 32694, 41412, 41412, 41412, 41412, 41412, 41412, 8269, 8271, 8268, 8267, - 8264, 8263, 8266, 8265, 8272, 8270, 8260, 8261, 8256, 8257, 8258, 8259, - 8255, 8262, 10903, 10897, 10910, 10899, 10898, 10896, 10911, 10800, - 10798, 10803, 10904, 10954, 10809, 10921, 21748, 21750, 21747, 21746, - 21743, 21742, 21745, 21744, 21751, 21749, 21712, 21711, 21722, 21708, - 21716, 21715, 21729, 21709, 21718, 21706, 21710, 21714, 21713, 21724, - 21721, 21719, 21725, 21728, 21723, 21727, 21717, 21707, 21726, 21720, - 21730, 21704, 21731, 21705, 21740, 21737, 21739, 21738, 21741, 21736, - 21734, 21735, 21732, 21733, 32024, 32021, 32013, 32029, 32020, 32015, - 32026, 32018, 32017, 32019, 32023, 32011, 32028, 32027, 32025, 32031, - 32030, 32022, 32016, 32012, 32014, 32010, 32032, 32039, 32041, 32034, - 32037, 32040, 32038, 32036, 32035, 32007, 32006, 32009, 32008, 32042, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 32033, 19386, 19389, 19390, 19387, 19344, 19345, 19353, 19347, - 19349, 19352, 19346, 19342, 19348, 19350, 19343, 19309, 19311, 19312, - 19325, 19332, 19339, 19374, 19291, 19298, 19372, 19376, 19322, 19395, - 19378, 41412, 41412, 41412, 21067, 21063, 21066, 21065, 21037, 21005, - 21004, 21006, 21046, 21025, 21011, 21012, 21044, 21038, 21045, 21007, - 21008, 21009, 21021, 21022, 21010, 21019, 21020, 21035, 21014, 21036, - 21013, 21033, 21034, 21000, 21001, 21016, 21031, 21032, 21002, 21003, - 21015, 21023, 21024, 21017, 21018, 21041, 21043, 21026, 21027, 21040, - 21042, 21029, 21030, 21028, 21039, 21064, 21070, 21072, 21073, 21074, - 21068, 21069, 21071, 21076, 21075, 20996, 20997, 20998, 21061, 20999, - 21047, 21050, 21059, 21052, 21057, 21055, 21053, 21051, 21048, 21049, - 21054, 21062, 41412, 21060, 21083, 21085, 21082, 21081, 21078, 21077, - 21080, 21079, 21086, 21084, 41412, 41412, 41412, 41412, 21056, 21058, - 28787, 28785, 28780, 28777, 28783, 28873, 28851, 28803, 28815, 28811, - 28810, 28813, 28812, 28805, 28804, 28802, 28915, 28917, 28914, 28913, - 28910, 28909, 28912, 28911, 28918, 28916, 28814, 28807, 28806, 28809, - 28808, 41412, 6347, 6365, 6367, 6364, 6348, 6366, 6356, 6355, 6352, 6351, - 6327, 6328, 6350, 6349, 6354, 6353, 6329, 6331, 6330, 6358, 6357, 6344, - 6343, 6332, 6333, 6342, 6338, 6337, 6336, 6341, 6340, 6334, 6335, 6339, - 6363, 6361, 6360, 6362, 6345, 6346, 6359, 6372, 6375, 6376, 6381, 6379, - 6378, 6377, 6373, 6374, 6380, 6315, 6313, 6312, 6314, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 6321, 6320, 6317, 6309, - 6319, 6325, 6316, 6323, 6326, 6324, 6322, 6318, 6311, 6310, 41412, 41412, - 6388, 6390, 6387, 6386, 6383, 6382, 6385, 6384, 6391, 6389, 41412, 41412, - 6368, 6370, 6369, 6371, 28757, 28750, 28749, 28754, 28753, 28747, 28746, - 28745, 28743, 28742, 28744, 28748, 28759, 28752, 28751, 28756, 28850, - 28760, 28761, 28758, 28847, 28848, 28849, 28888, 28890, 28889, 28732, - 28884, 28875, 28876, 28796, 28797, 35479, 35455, 35478, 35454, 35477, - 35453, 35492, 35468, 35486, 35462, 35481, 35457, 35480, 35456, 35497, - 35473, 35487, 35463, 35490, 35466, 35485, 35461, 35484, 35460, 35488, - 35464, 35489, 35465, 35483, 35459, 35482, 35458, 35491, 35467, 35495, - 35471, 35499, 35475, 35496, 35472, 35494, 35470, 35498, 35474, 35493, - 35469, 35500, 35476, 35501, 35513, 35521, 35518, 35517, 35523, 35524, - 35502, 35522, 35519, 35520, 35512, 35516, 35515, 35514, 35511, 35508, - 35509, 35510, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 35504, 35505, 35507, 35506, - 35503, 27214, 27215, 27173, 27190, 27201, 27200, 27177, 27176, 27189, - 27195, 27196, 27228, 27230, 27220, 27222, 27221, 27168, 27165, 27167, - 27217, 27218, 27232, 27233, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 17347, 17345, 17344, 17343, 17342, 17346, - 41412, 41412, 17041, 17039, 17038, 17037, 17036, 17040, 41412, 41412, - 17056, 17054, 17053, 17052, 17051, 17055, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 16997, 17003, 17001, 16998, 17000, - 16999, 17002, 41412, 16982, 16988, 16986, 16983, 16985, 16984, 16987, - 41412, 23530, 23506, 23536, 23531, 23627, 23790, 23980, 23779, 23770, - 23773, 23801, 23815, 23641, 23534, 23535, 23885, 23735, 24029, 24028, - 24030, 24031, 23990, 23427, 23933, 23589, 23913, 23590, 23977, 23978, - 23533, 24100, 24066, 24109, 24052, 24105, 23553, 23554, 23555, 24141, - 24138, 24139, 24140, 24152, 27864, 28088, 28097, 28098, 28155, 23971, - 23738, 23886, 24111, 23734, 18558, 23596, 24061, 24034, 28152, 28001, - 28025, 41412, 41412, 41412, 41412, 6570, 6571, 6572, 6573, 6574, 6575, - 6533, 6569, 6534, 6535, 6536, 6537, 6538, 6498, 6499, 6500, 6501, 6502, - 6503, 6539, 6540, 6541, 6542, 6543, 6544, 6545, 6546, 6547, 6548, 6549, - 6504, 6497, 6505, 6506, 6507, 6508, 6509, 6510, 6551, 6552, 6553, 6554, - 6555, 6556, 6512, 6511, 6513, 6514, 6515, 6516, 6517, 6491, 6530, 6492, - 6531, 6493, 6532, 6494, 6495, 6496, 6490, 6518, 6519, 6520, 6521, 6522, - 6523, 6524, 6525, 6526, 6527, 6528, 6529, 6557, 6558, 6559, 6560, 6561, - 6562, 6563, 27182, 27194, 27204, 27206, 27191, 27185, 27172, 27197, - 27184, 27187, 27199, 27210, 27212, 27208, 27213, 27202, 27193, 27211, - 27179, 27180, 27209, 27171, 27181, 27175, 27178, 27174, 27170, 27183, - 27205, 27207, 27192, 27186, 27198, 27188, 27203, 27224, 27227, 27219, - 27226, 27225, 27229, 27223, 27231, 27169, 27216, 27166, 41412, 41412, - 27240, 27242, 27239, 27238, 27235, 27234, 27237, 27236, 27243, 27241, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 19583, 19581, 19614, 19615, 19616, 19592, 19593, 19625, - 19627, 19560, 19558, 19557, 19561, 19567, 19568, 19570, 19569, 19574, - 19571, 19572, 19576, 19544, 19542, 41412, 41412, 41412, 41412, 19440, - 19441, 19509, 19510, 19529, 19523, 19524, 19527, 19526, 19525, 19484, - 19469, 19508, 19475, 19479, 19478, 19492, 19491, 19412, 19437, 19430, - 19515, 19428, 19435, 19465, 19458, 19464, 19519, 19460, 19463, 19462, - 19503, 19496, 19513, 19514, 19502, 19500, 19499, 19504, 19506, 19451, - 19450, 19536, 19537, 19401, 19400, 19516, 19455, 19453, 41412, 41412, - 41412, 41412, 7687, 7688, 7689, 7690, 7691, 7692, 7693, 7694, 7695, 7696, - 7697, 7698, 7699, 7700, 7701, 7702, 7703, 7704, 7705, 7706, 7707, 7708, - 7709, 7710, 7711, 7712, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, - 7721, 7722, 7723, 7724, 7725, 7726, 7727, 7728, 7729, 7730, 7731, 7732, - 7733, 7734, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7743, 7744, - 7745, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, - 7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, - 7769, 7770, 7771, 7772, 7773, 7774, 7775, 7776, 7777, 7778, 7779, 7780, - 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7788, 7789, 7790, 7791, 7792, - 7793, 7794, 7795, 7796, 7797, 7798, 7799, 7800, 7801, 7802, 7803, 7804, - 7805, 7806, 7807, 7808, 7809, 7810, 7811, 7812, 7813, 7814, 7815, 7816, - 7817, 7818, 7819, 7820, 7821, 7822, 7823, 7824, 7825, 7826, 7827, 7828, - 7829, 7830, 7831, 7832, 7833, 7834, 7835, 7836, 7837, 7838, 7839, 7840, - 7841, 7842, 7843, 7844, 7845, 7846, 7847, 7848, 7849, 7850, 7851, 7852, - 7853, 7854, 7855, 7856, 7857, 7858, 7859, 7860, 7861, 7862, 7863, 7864, - 7865, 7866, 7867, 7868, 7869, 7870, 7871, 7872, 7873, 7874, 7875, 7876, - 7877, 7878, 7879, 7880, 7881, 7882, 7883, 7884, 7885, 7886, 7887, 7888, - 7889, 7890, 7891, 7892, 7893, 7894, 7895, 7896, 7897, 7898, 7899, 7900, - 7901, 7902, 7903, 7904, 7905, 7906, 7907, 7908, 7909, 7910, 7911, 7912, - 7913, 7914, 7915, 7916, 7917, 7918, 7919, 7920, 7921, 7922, 7923, 7924, - 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936, - 7937, 7938, 7939, 7940, 7941, 7942, 7485, 7486, 7487, 7488, 7489, 7490, - 7491, 7492, 7493, 7494, 7495, 7496, 7497, 7498, 7499, 7500, 7501, 7502, - 7503, 7504, 7505, 7506, 7507, 7508, 7509, 7510, 7511, 7512, 7513, 7514, - 7515, 7516, 7517, 7518, 7519, 7520, 7521, 7522, 7523, 7524, 7525, 7526, - 7527, 7528, 7529, 7530, 7531, 7532, 7533, 7534, 7535, 7536, 7537, 7538, - 7539, 7540, 7541, 7542, 7543, 7544, 7545, 7546, 7547, 7548, 7549, 7550, - 7551, 7552, 7553, 7554, 7555, 7556, 7557, 7558, 7559, 7560, 7561, 7562, - 7563, 7564, 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7572, 7573, 7574, - 7575, 7576, 7577, 7578, 7579, 7580, 7471, 7472, 7473, 7474, 7475, 7476, - 7477, 7478, 7479, 7480, 7481, 7482, 7483, 7484, 41412, 41412, 7581, 7582, - 7583, 7584, 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7592, 7593, 7594, - 7595, 7596, 7597, 7598, 7599, 7600, 7601, 7602, 7603, 7604, 7605, 7606, - 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7617, 7618, - 7619, 7620, 7621, 7622, 7623, 7624, 7625, 7626, 7627, 7628, 7629, 7630, - 7631, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, - 7643, 7644, 7645, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7654, - 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7662, 7663, 7664, 7665, 7666, - 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, 7675, 7676, 7677, 7678, - 7679, 7680, 7681, 7682, 7683, 7684, 7685, 7686, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 24174, 24177, 24178, 24175, 24176, - 24180, 24181, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 2549, 2550, 2548, 2551, 2547, 41412, 41412, - 41412, 41412, 41412, 20049, 20076, 20054, 19985, 20041, 20044, 20046, - 20045, 20040, 20047, 20043, 20042, 19986, 20019, 20020, 20017, 20018, - 19983, 19984, 19982, 19990, 20032, 20030, 20007, 20039, 20012, 41412, - 20024, 20050, 19998, 19993, 20034, 41412, 20036, 41412, 20010, 20014, - 41412, 20000, 19996, 41412, 20028, 20005, 20022, 20016, 20026, 20038, - 19989, 19992, 19995, 20051, 1164, 1163, 1194, 1192, 1193, 1195, 1424, - 1422, 1423, 1425, 1189, 1187, 1188, 1190, 1555, 1553, 1554, 1556, 1534, - 1532, 1533, 1535, 1550, 1548, 1549, 1551, 1568, 1566, 1567, 1569, 1429, - 1427, 1428, 1430, 1230, 1228, 1229, 1231, 1401, 1399, 1400, 1402, 1511, - 1509, 1510, 1512, 1516, 1514, 1515, 1517, 1220, 1219, 1211, 1210, 1234, - 1233, 1223, 1222, 1330, 1329, 1459, 1458, 1353, 1351, 1352, 1354, 1264, - 1262, 1263, 1265, 1276, 1274, 1275, 1277, 1392, 1390, 1391, 1393, 1406, - 1405, 1463, 1461, 1462, 1464, 1306, 1305, 1301, 1299, 1300, 1302, 1310, - 1308, 1309, 1311, 1592, 1591, 1590, 1589, 2411, 2410, 2419, 2418, 2415, - 2414, 2413, 2412, 2423, 2422, 2409, 2417, 2416, 2425, 2421, 2420, 2424, - 1756, 1704, 1933, 1930, 1931, 1926, 1927, 1928, 1920, 1733, 1734, 1731, - 1732, 1956, 1645, 1649, 1396, 1394, 1395, 1397, 1561, 1560, 1614, 1613, - 1611, 1610, 1559, 1571, 1570, 1357, 1356, 1360, 1359, 1627, 1625, 1626, - 1628, 1562, 1563, 2100, 2099, 2102, 2101, 2121, 2120, 2129, 2128, 2119, - 2118, 2125, 2124, 2105, 2103, 2104, 2154, 2152, 2153, 1244, 1242, 1243, - 1245, 2111, 2109, 2115, 2098, 2123, 1675, 1666, 1671, 1678, 1673, 1684, - 2063, 2051, 2058, 2071, 2074, 2079, 2081, 2086, 2083, 2092, 1760, 1766, - 1743, 1738, 1799, 1795, 1801, 1970, 1963, 1975, 1983, 1940, 1944, 1697, - 1689, 1693, 1699, 2044, 2039, 2156, 1640, 1636, 1728, 1724, 1712, 1717, - 1708, 1715, 1710, 1719, 1905, 1901, 1903, 1907, 1774, 1776, 1784, 1782, - 1779, 1790, 1772, 1793, 1827, 1819, 1831, 1837, 1811, 1840, 1858, 1847, - 1852, 1862, 1841, 1863, 1879, 1869, 1891, 1884, 1887, 1894, 1753, 1749, - 1750, 1751, 2139, 2132, 2141, 2147, 2096, 2151, 2080, 1935, 1658, 1991, - 1994, 1998, 1992, 1995, 1997, 2127, 2126, 2113, 2117, 2097, 2122, 1682, - 1681, 1676, 1680, 1672, 1683, 2077, 2076, 2069, 2075, 2073, 2078, 2090, - 2089, 2084, 2088, 2082, 2091, 1709, 1718, 1902, 1906, 1773, 1777, 1788, - 1771, 1792, 1835, 1810, 1839, 1842, 1860, 1892, 1889, 1882, 1888, 1886, - 1893, 1657, 2149, 2136, 2145, 2135, 2095, 2150, 2110, 2108, 2112, 2114, - 2106, 1674, 1665, 1670, 1677, 1667, 2062, 2050, 2057, 2070, 2052, 2085, - 1759, 1765, 1742, 1737, 1798, 1800, 1969, 1962, 1974, 1982, 1939, 1947, - 1943, 1696, 1688, 1692, 1698, 2043, 2155, 1639, 1635, 1727, 1723, 1711, - 1716, 1707, 1714, 1904, 1900, 1775, 1783, 1781, 1778, 1789, 1826, 1818, - 1830, 1836, 1820, 1857, 1846, 1851, 1861, 1878, 1868, 1890, 1883, 1870, - 1752, 1748, 1754, 2138, 2131, 2140, 2146, 2133, 2116, 2107, 1679, 1668, - 2072, 2053, 2087, 2093, 1984, 1966, 2021, 2001, 1780, 1791, 1838, 1885, - 1871, 2148, 2134, 1999, 1993, 1996, 2042, 2046, 1642, 1644, 1726, 1730, - 1986, 1990, 2023, 2031, 1740, 1745, 1768, 1770, 1797, 1803, 1946, 1951, - 1695, 1703, 2012, 2007, 2026, 2020, 2029, 1988, 1949, 1701, 2041, 2045, - 1641, 1643, 1725, 1729, 1985, 1989, 2022, 2030, 1739, 1744, 1767, 1769, - 1796, 1802, 1945, 1950, 1694, 1702, 2010, 2005, 2024, 2018, 2028, 1987, - 1948, 1700, 2011, 2006, 2025, 2019, 1965, 2000, 2038, 1971, 1964, 1976, - 2013, 2008, 2027, 2040, 2157, 1659, 1660, 30832, 30833, 1923, 1914, 1918, - 1915, 1916, 1917, 1957, 1648, 1653, 1651, 1647, 1912, 1959, 1655, 2033, - 1925, 2060, 2049, 2048, 2047, 2055, 2065, 2067, 2066, 1762, 1761, 1736, - 1735, 1961, 1968, 1967, 1978, 1977, 1979, 1981, 1980, 1937, 1936, 1942, - 2003, 2002, 2009, 2015, 2014, 2017, 2016, 1686, 1691, 1690, 2035, 2034, - 2036, 2037, 1638, 1633, 1632, 1631, 1720, 1722, 1721, 1706, 1705, 1898, - 1896, 1816, 1817, 1814, 1821, 1822, 1829, 1828, 1833, 1832, 1843, 1844, - 1845, 1855, 1853, 1848, 1849, 1929, 1932, 1854, 1746, 1747, 1866, 1865, - 1876, 1875, 1874, 1881, 1880, 2143, 2142, 1669, 2061, 2059, 2056, 2054, - 2068, 2064, 1764, 1757, 1763, 1972, 1938, 2004, 1687, 1825, 1834, 2130, - 2137, 2144, 1859, 1899, 1867, 1897, 1815, 1634, 1787, 1872, 1850, 1823, - 1786, 1824, 1873, 1758, 1741, 1856, 1713, 1664, 1785, 1637, 1941, 1973, - 1877, 1924, 1919, 1922, 1921, 1958, 1646, 1794, 1953, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 1954, 1908, 1661, 1662, 1864, 1952, 1934, 1656, 2094, 1955, 1960, 1755, - 32353, 1685, 2032, 1663, 38715, 38826, 38894, 38905, 38916, 38927, 38938, - 38949, 38960, 38716, 38727, 38738, 38749, 38760, 38771, 38782, 31807, - 31812, 31813, 31806, 31837, 31808, 31839, 31815, 31829, 31811, 41412, - 41412, 41412, 41412, 41412, 41412, 8479, 8481, 8306, 8307, 8490, 8492, - 8192, 8480, 8482, 8555, 8556, 8491, 8493, 8193, 8246, 8247, 31838, 31809, - 31810, 31824, 31836, 31821, 31833, 31819, 31831, 31823, 31835, 31816, - 31825, 31817, 31826, 31820, 31832, 31818, 31830, 31814, 31827, 32848, - 39721, 31822, 31834, 10673, 6231, 39597, 11389, 10672, 6230, 39595, - 34023, 34032, 34067, 41412, 34057, 34024, 34068, 34030, 34031, 34034, - 34038, 34033, 34037, 34035, 34039, 34066, 34014, 34016, 34065, 34063, - 34036, 34062, 34029, 41412, 34056, 34025, 34064, 34022, 41412, 41412, - 41412, 41412, 1098, 2430, 1079, 2432, 1110, 41412, 1095, 1096, 1075, - 1076, 1107, 1108, 2335, 2336, 2405, 2406, 1295, 1159, 1158, 1149, 1148, - 1579, 1578, 1152, 1151, 1596, 1594, 1595, 1597, 1169, 1168, 1184, 1182, - 1183, 1185, 1521, 1520, 1530, 1528, 1529, 1523, 1544, 1542, 1543, 1545, - 1326, 1324, 1325, 1327, 1292, 1290, 1291, 1293, 1364, 1362, 1363, 1365, - 1208, 1207, 1538, 1537, 1456, 1455, 1622, 1621, 1485, 1483, 1484, 1486, - 1491, 1489, 1490, 1492, 1472, 1470, 1471, 1473, 1216, 1214, 1215, 1217, - 1504, 1502, 1503, 1505, 1618, 1616, 1617, 1619, 1127, 1125, 1126, 1128, - 1271, 1269, 1270, 1272, 1255, 1253, 1254, 1256, 1438, 1436, 1437, 1439, - 1340, 1338, 1339, 1341, 1376, 1374, 1375, 1377, 1385, 1383, 1384, 1386, - 1417, 1415, 1416, 1418, 1314, 1312, 1313, 1315, 1583, 1582, 1167, 1166, - 1607, 1605, 1606, 1608, 1809, 1808, 1805, 1804, 1807, 1806, 1813, 1812, - 41412, 41412, 41216, 41412, 17766, 17770, 17738, 17754, 17740, 17752, - 17751, 17681, 17744, 17753, 17741, 17676, 17769, 17774, 17748, 17761, - 17763, 17760, 17759, 17756, 17755, 17758, 17757, 17764, 17762, 17677, - 17747, 17683, 17765, 17768, 17771, 17675, 17684, 17685, 17686, 17687, - 17688, 17689, 17690, 17691, 17692, 17693, 17694, 17695, 17696, 17697, - 17698, 17699, 17700, 17701, 17702, 17703, 17704, 17705, 17706, 17707, - 17708, 17709, 17682, 17746, 17745, 17674, 17736, 17767, 17710, 17711, - 17712, 17713, 17714, 17715, 17716, 17717, 17718, 17719, 17720, 17721, - 17722, 17723, 17724, 17725, 17726, 17727, 17728, 17729, 17730, 17731, - 17732, 17733, 17734, 17735, 17680, 17776, 17743, 17773, 17679, 17742, - 19256, 19249, 19251, 19255, 19247, 19239, 19194, 19196, 19198, 19195, - 19197, 19190, 19192, 19191, 19193, 19248, 19240, 19242, 19244, 19241, - 19243, 19215, 19217, 19219, 19216, 19218, 19199, 19201, 19203, 19200, - 19202, 19230, 19232, 19234, 19231, 19233, 19205, 19207, 19209, 19206, - 19208, 19210, 19212, 19214, 19211, 19213, 19220, 19222, 19224, 19221, - 19223, 19235, 19237, 19236, 19225, 19227, 19229, 19226, 19228, 19238, - 19204, 19246, 19245, 19189, 19139, 19156, 19140, 19141, 19142, 19143, - 19177, 19158, 19147, 19152, 19151, 19150, 19154, 19148, 19149, 19153, - 19175, 19145, 19157, 19146, 19160, 19159, 19174, 19169, 19155, 19168, - 19138, 19176, 19144, 19183, 41412, 41412, 41412, 19184, 19185, 19163, - 19164, 19171, 19170, 41412, 41412, 19162, 19161, 19186, 19180, 19181, - 19187, 41412, 41412, 19166, 19188, 19179, 19178, 19182, 19167, 41412, - 41412, 19172, 19165, 19173, 41412, 41412, 41412, 17678, 17739, 17737, - 17750, 17775, 17749, 17772, 41412, 19253, 19250, 19254, 19252, 19259, - 19257, 19258, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 20948, 20950, 20949, 30114, 32045, 41412, 41412, 25137, - 25163, 25156, 25189, 25147, 25138, 25167, 25133, 25145, 25175, 25178, - 25172, 41412, 25161, 25188, 25192, 25171, 25186, 25193, 25200, 25203, - 25148, 25199, 25146, 25149, 25132, 25155, 25158, 25181, 25182, 25140, - 25197, 25162, 25143, 25179, 25141, 25198, 25157, 25165, 41412, 25190, - 25154, 25174, 25139, 25150, 25164, 25135, 25169, 25144, 25176, 25177, - 25134, 25160, 25136, 25187, 25180, 25194, 25168, 25170, 41412, 25142, - 25196, 41412, 25153, 25152, 25166, 25202, 25195, 25205, 25173, 25151, - 25183, 25191, 25159, 25184, 25185, 25201, 25204, 41412, 41412, 25215, - 25216, 25218, 25217, 25206, 25207, 25214, 25208, 25209, 25219, 25210, - 25211, 25212, 25213, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 25021, 25020, 25022, - 25009, 25010, 25011, 25012, 25013, 25014, 25015, 25017, 25016, 25019, - 25018, 25027, 25024, 25025, 25023, 25026, 25126, 25127, 25029, 25028, - 25030, 25129, 25128, 25032, 25033, 25034, 25031, 25035, 25038, 25037, - 25039, 25040, 25041, 25130, 25042, 25043, 25036, 25046, 25047, 25045, - 25044, 25048, 25049, 25050, 25051, 25052, 25053, 25056, 25057, 25058, - 25055, 25059, 25054, 25060, 25061, 25062, 25063, 25064, 25065, 25066, - 25067, 25068, 25069, 25071, 25070, 25072, 25073, 25075, 25076, 25077, - 25074, 25078, 25079, 25080, 25081, 25083, 25082, 25084, 25085, 25131, - 25086, 25087, 25089, 25090, 25091, 25088, 25092, 25093, 25094, 25095, - 25096, 25124, 25104, 25105, 25106, 25107, 25108, 25109, 25110, 25111, - 25112, 25113, 25114, 25115, 25116, 25117, 25118, 25119, 25120, 25121, - 25122, 25123, 25097, 25098, 25099, 25100, 25101, 25102, 25103, 25125, - 41412, 41412, 41412, 41412, 41412, 112, 113, 159, 41412, 41412, 41412, - 41412, 156, 151, 146, 126, 121, 139, 134, 114, 129, 154, 149, 144, 124, - 119, 140, 135, 115, 130, 157, 152, 147, 127, 122, 142, 137, 117, 132, - 158, 153, 148, 128, 123, 143, 138, 118, 133, 155, 150, 145, 125, 120, - 141, 136, 116, 131, 41412, 41412, 41412, 111, 107, 109, 110, 108, 103, - 104, 105, 106, 18323, 18320, 18324, 18310, 18305, 18311, 18314, 18306, - 18316, 18325, 18308, 18318, 18312, 18321, 18315, 18317, 18327, 18309, - 18319, 18313, 18322, 18326, 18307, 18328, 18340, 18349, 18339, 18335, - 18348, 18330, 18336, 18352, 18356, 18357, 18338, 18341, 18347, 18346, - 18354, 18355, 18337, 18344, 18350, 18345, 18334, 18353, 18342, 18329, - 18331, 18351, 18343, 18332, 18333, 18575, 18576, 18774, 18770, 18811, - 18776, 18506, 18580, 18773, 18769, 18512, 18511, 18572, 18554, 18570, - 18579, 18574, 18360, 18359, 18813, 18772, 18814, 18577, 18768, 18550, - 29540, 41412, 32397, 32400, 32395, 32398, 32369, 32399, 32367, 32370, - 32396, 32368, 32401, 32366, 2569, 41412, 41412, 41412, 18767, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 31590, 31591, 31602, 31571, - 31574, 31605, 31583, 31582, 31603, 31610, 31569, 31596, 31575, 31588, - 31589, 31598, 31587, 31568, 31572, 31579, 31577, 31599, 31576, 31567, - 31597, 31584, 31585, 31570, 31573, 31595, 31609, 31580, 31604, 31566, - 31592, 31611, 31593, 31594, 31586, 31608, 31607, 31581, 31600, 31601, - 31606, 31578, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 25459, 25461, 25457, 25458, 25466, 25465, 25468, 25476, - 25478, 25455, 25469, 25452, 25472, 25470, 25450, 25463, 25451, 25464, - 25475, 25471, 25453, 25473, 25474, 25454, 25456, 25460, 25462, 25467, - 25477, 41412, 41412, 41412, 6141, 6152, 6143, 6114, 6137, 6153, 6115, - 6142, 6159, 6157, 6117, 6158, 6144, 6132, 6127, 6128, 6126, 6112, 6135, - 6125, 6160, 6122, 6134, 6151, 6131, 6155, 6145, 6140, 6149, 6150, 6123, - 6136, 6147, 6148, 6129, 6130, 6124, 6156, 6113, 6133, 6138, 6154, 6118, - 6119, 6120, 6121, 6116, 6146, 6139, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 8703, 8701, 8699, 8698, 8695, 8694, 8697, 8696, 8702, 8700, 8693, 8692, - 8690, 8681, 8679, 8688, 8686, 8677, 8683, 8684, 8691, 8689, 8680, 8678, - 8687, 8685, 8676, 8682, 41412, 41412, 41412, 41412, 30395, 30389, 30375, - 30390, 30362, 30392, 30394, 30391, 30386, 30382, 30374, 30370, 30371, - 30372, 30364, 30396, 30385, 30378, 30376, 30366, 30363, 30387, 30380, - 30368, 30384, 30373, 30369, 30367, 30388, 30383, 30381, 30365, 30400, - 30398, 30399, 30397, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 30393, 30379, 30377, 18170, 18186, 18194, 18188, 18169, - 18179, 18173, 18172, 18181, 18190, 18195, 18191, 18189, 18177, 18193, - 18184, 18178, 18176, 18180, 18192, 18182, 18183, 18185, 18174, 18171, - 18187, 18175, 41412, 41412, 41412, 41412, 41412, 30467, 30466, 30463, - 30436, 30437, 30459, 30434, 30460, 30435, 30439, 30468, 30461, 30442, - 30443, 30450, 30444, 30462, 30447, 30449, 30470, 30433, 30446, 30445, - 30457, 30454, 30464, 30465, 30438, 30469, 30448, 30451, 30452, 30453, - 30456, 30441, 30458, 30455, 30440, 8508, 8506, 8504, 8505, 8507, 41412, - 41412, 41412, 41412, 41412, 38163, 38166, 38170, 38174, 38167, 38171, - 38189, 38185, 38172, 38182, 38184, 38173, 38179, 38175, 38190, 38168, - 38187, 38186, 38178, 38164, 38188, 38177, 38165, 38176, 38181, 38169, - 38183, 38191, 38192, 38180, 41412, 38193, 30476, 30518, 30519, 30499, - 30500, 30497, 30498, 30496, 30511, 30488, 30489, 30493, 30494, 30483, - 30486, 30487, 30492, 30515, 30480, 30512, 30501, 30502, 30505, 30506, - 30507, 30516, 30490, 30491, 30503, 30504, 30514, 30510, 30517, 30508, - 30509, 30513, 41412, 41412, 41412, 41412, 30477, 30478, 30479, 30495, - 30484, 30485, 30481, 30482, 30520, 30475, 30472, 30473, 30471, 30474, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 10727, 10726, 10722, 10723, 10724, 10725, 10733, 10732, - 10728, 10729, 10730, 10731, 10750, 10735, 10749, 10746, 10751, 10744, - 10741, 10737, 10742, 10740, 10743, 10748, 10747, 10717, 10745, 10716, - 10736, 10712, 10739, 10713, 10738, 10720, 10718, 10719, 10714, 10715, - 10734, 10721, 10767, 10766, 10762, 10763, 10764, 10765, 10773, 10772, - 10768, 10769, 10770, 10771, 10790, 10775, 10789, 10786, 10791, 10784, - 10781, 10777, 10782, 10780, 10783, 10788, 10787, 10757, 10785, 10756, - 10776, 10752, 10779, 10753, 10778, 10760, 10758, 10759, 10754, 10755, - 10774, 10761, 32992, 32998, 33009, 33006, 32996, 32995, 32994, 32973, - 33001, 32979, 33008, 33004, 33007, 33010, 32997, 33005, 32984, 33003, - 33000, 32978, 32983, 32985, 32982, 32977, 32971, 32968, 32990, 32999, - 32988, 32972, 32993, 33011, 32975, 32969, 32981, 33012, 32989, 32986, - 32987, 32970, 32966, 32991, 32967, 32976, 32965, 32974, 32980, 33002, - 30910, 30928, 30934, 30932, 30935, 30916, 30913, 30933, 30918, 30917, - 30914, 30912, 30930, 30929, 30920, 30915, 30923, 30919, 30924, 30925, - 30931, 30936, 30909, 30926, 30937, 30921, 30938, 30911, 30927, 30922, - 41412, 41412, 30945, 30947, 30944, 30943, 30940, 30939, 30942, 30941, - 30948, 30946, 41412, 41412, 41412, 41412, 41412, 41412, 30837, 30838, - 30839, 30840, 30865, 30858, 30844, 30841, 30847, 30857, 30856, 30871, - 30850, 30845, 30849, 30866, 30867, 30868, 30851, 30852, 30869, 30846, - 30862, 30861, 30855, 30843, 30854, 30842, 30853, 30859, 30872, 30870, - 30848, 30860, 30864, 30863, 41412, 41412, 41412, 41412, 30873, 30874, - 30875, 30876, 30901, 30894, 30880, 30877, 30883, 30893, 30892, 30907, - 30886, 30881, 30885, 30902, 30903, 30904, 30887, 30888, 30905, 30882, - 30898, 30897, 30891, 30879, 30890, 30878, 30889, 30895, 30908, 30906, - 30884, 30896, 30900, 30899, 41412, 41412, 41412, 41412, 16827, 16818, - 16807, 16806, 16809, 16798, 16808, 16805, 16804, 16819, 16795, 16794, - 16820, 16828, 16821, 16811, 16797, 16796, 16822, 16801, 16800, 16799, - 16829, 16823, 16824, 16803, 16802, 16813, 16812, 16815, 16814, 16830, - 16825, 16826, 16831, 16817, 16816, 16793, 16792, 16810, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 6173, 6222, 6189, 6185, 6187, - 6212, 6186, 6210, 6207, 6176, 6209, 6211, 6190, 6201, 6197, 6192, 6220, - 6184, 6175, 6193, 6196, 6198, 6223, 6214, 6172, 6178, 6179, 6181, 6215, - 6213, 6218, 6182, 6202, 6194, 6221, 6206, 6217, 6183, 6177, 6200, 6188, - 6219, 6204, 6216, 6205, 6203, 6191, 6180, 6174, 6208, 6199, 6195, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 6224, 39368, 39337, 39338, 39348, 39347, 39350, 39349, 39340, 39339, - 39357, 39365, 41412, 39356, 39355, 39341, 39342, 39358, 39366, 39344, - 39343, 39359, 39346, 39345, 39369, 39360, 39367, 39361, 41412, 39352, - 39351, 39354, 39353, 39370, 39362, 39363, 41412, 39371, 39364, 41412, - 39403, 39372, 39373, 39383, 39382, 39385, 39384, 39375, 39374, 39392, - 39400, 41412, 39391, 39390, 39376, 39377, 39393, 39401, 39379, 39378, - 39394, 39381, 39380, 39404, 39395, 39402, 39396, 41412, 39387, 39386, - 39389, 39388, 39405, 39397, 39398, 41412, 39406, 39399, 41412, 41412, - 41412, 37824, 37825, 37838, 37798, 37827, 37826, 37829, 37805, 37828, - 37821, 37820, 37839, 37795, 37801, 37794, 37800, 37808, 37807, 37842, - 37796, 37831, 37823, 37822, 37799, 37806, 37802, 37818, 37810, 37840, - 37817, 37816, 37815, 37812, 37811, 37833, 37832, 37843, 37841, 37835, - 37804, 37834, 37803, 37844, 37797, 37837, 37836, 37793, 37814, 37813, - 37830, 37809, 37819, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 24988, 24989, 24990, 24991, 24992, - 24993, 24994, 24995, 24996, 24927, 24928, 24929, 24930, 24931, 24940, - 24932, 24933, 24934, 24935, 24936, 24937, 24938, 24939, 24941, 24942, - 24943, 24944, 25008, 24945, 24946, 24947, 24948, 24949, 24950, 24951, - 24952, 24953, 24954, 24955, 24956, 24957, 24958, 24959, 24960, 24961, - 24962, 24963, 24964, 24965, 24966, 24967, 24968, 24969, 24970, 24971, - 24972, 24973, 24974, 24975, 24976, 24977, 24978, 24979, 24980, 24981, - 24982, 24983, 24984, 24985, 24986, 24987, 24668, 25004, 24997, 24669, - 24998, 24999, 25000, 25001, 24670, 25005, 25006, 25002, 25003, 25007, - 24674, 24675, 24676, 24677, 24678, 24679, 24680, 24681, 24671, 24672, - 24673, 24685, 24686, 24687, 24682, 24683, 24684, 24688, 24689, 24690, - 24691, 24692, 24693, 24696, 24697, 24698, 24699, 24700, 24701, 24702, - 24703, 24704, 24705, 24706, 24707, 24708, 24709, 24710, 24711, 24712, - 24713, 24714, 24715, 24716, 24717, 24718, 24719, 24720, 24721, 24722, - 24723, 24724, 24725, 24726, 24727, 24728, 24729, 24730, 24731, 24732, - 24733, 24734, 24735, 24736, 24737, 24738, 24739, 24740, 24741, 24742, - 24743, 24744, 24745, 24694, 24695, 24746, 24747, 24748, 24749, 24750, - 24751, 24752, 24753, 24754, 24755, 24756, 24757, 24758, 24759, 24760, - 24761, 24762, 24763, 24764, 24765, 24766, 24767, 24768, 24769, 24770, - 24771, 24772, 24773, 24774, 24775, 24776, 24777, 24778, 24810, 24811, - 24812, 24813, 24814, 24815, 24816, 24817, 24818, 24779, 24780, 24781, - 24782, 24783, 24784, 24785, 24786, 24787, 24788, 24789, 24790, 24791, - 24792, 24793, 24794, 24795, 24796, 24797, 24798, 24799, 24800, 24801, - 24802, 24803, 24804, 24805, 24806, 24807, 24808, 24809, 24825, 24826, - 24827, 24828, 24829, 24830, 24831, 24832, 24833, 24834, 24835, 24836, - 24837, 24838, 24839, 24840, 24841, 24842, 24843, 24844, 24819, 24820, - 24821, 24822, 24823, 24824, 24845, 24846, 24847, 24848, 24849, 24850, - 24851, 24852, 24887, 24888, 24889, 24890, 24891, 24892, 24893, 24894, - 24895, 24896, 24853, 24854, 24855, 24856, 24857, 24858, 24859, 24860, - 24861, 24862, 24863, 24864, 24865, 24866, 24867, 24868, 24869, 24870, - 24871, 24872, 24878, 24879, 24880, 24881, 24882, 24883, 24884, 24885, - 24886, 24873, 24874, 24875, 24876, 24877, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 24908, 24903, 24906, 24905, 24909, - 24904, 24902, 24907, 24901, 24897, 24900, 24899, 24898, 24915, 24913, - 24914, 24910, 24911, 24912, 24916, 24918, 24917, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 24919, 24920, 24921, - 24922, 24923, 24924, 24925, 24926, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 28048, - 28169, 28168, 28033, 28049, 28037, 41412, 28067, 28069, 28068, 28063, - 28062, 28060, 28061, 28122, 28055, 28079, 28119, 28043, 28083, 28044, - 28087, 28050, 28089, 28066, 28103, 28104, 28102, 28046, 28100, 28105, - 28106, 28147, 28148, 28111, 28047, 28056, 28162, 28144, 28145, 28118, - 28117, 28052, 28132, 28135, 28136, 28133, 28131, 28159, 41412, 28054, - 27974, 28021, 27868, 27952, 27981, 27865, 28023, 28124, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 10140, 10141, 10142, - 10143, 10144, 10134, 41412, 41412, 10135, 41412, 10090, 10091, 10092, - 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, 10102, - 10103, 10104, 10105, 10106, 10107, 10108, 10109, 10110, 10111, 10112, - 10113, 10114, 10115, 10116, 10117, 10118, 10119, 10120, 10121, 10122, - 10123, 10124, 10125, 10126, 10127, 10128, 10129, 10130, 10131, 10132, - 10133, 41412, 10138, 10139, 41412, 41412, 41412, 10136, 41412, 41412, - 10137, 20770, 20781, 20772, 20766, 20778, 20783, 20773, 20779, 20764, - 20777, 20780, 20767, 20785, 20782, 20774, 20771, 20784, 20775, 20768, - 20769, 20776, 20765, 41412, 20786, 20761, 20757, 20760, 20758, 20756, - 20762, 20763, 20759, 31218, 31229, 31220, 31214, 31226, 31231, 31221, - 31227, 31212, 31225, 31228, 31215, 31233, 31211, 31230, 31222, 31219, - 31232, 31223, 31216, 31217, 31224, 31213, 31210, 31234, 31241, 31236, - 31237, 31240, 31239, 31238, 31235, 28986, 29001, 28991, 29012, 29003, - 28997, 28993, 29009, 29014, 29004, 29010, 28995, 28989, 29008, 28990, - 29011, 28987, 28998, 28994, 29016, 28992, 29013, 29005, 29002, 29015, - 29006, 28999, 29000, 28988, 29007, 28996, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 29021, 29018, 29019, 29024, 29025, 29023, - 29020, 29017, 29022, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 19816, 19832, 19824, 19823, 19829, 19834, 19818, 19830, 19819, - 19828, 19831, 19821, 19836, 19833, 19825, 19817, 19835, 19826, 19822, - 41412, 19827, 19820, 41412, 41412, 41412, 41412, 41412, 19837, 19841, - 19840, 19839, 19838, 31614, 31633, 31629, 31616, 31617, 31625, 31626, - 31618, 31624, 31627, 31630, 31632, 31635, 31631, 31622, 31615, 31634, - 31620, 31619, 31628, 31621, 31623, 31640, 31639, 31636, 31641, 31637, - 31638, 41412, 41412, 41412, 31642, 25485, 25491, 25495, 25493, 25487, - 25503, 25496, 25504, 25497, 25481, 25498, 25489, 25499, 25501, 25484, - 25479, 25502, 25494, 25500, 25483, 25480, 25486, 25488, 25482, 25490, - 25492, 41412, 41412, 41412, 41412, 41412, 25505, 33150, 33151, 33152, - 33153, 33154, 33155, 33156, 33157, 33158, 33159, 33160, 33161, 33162, - 33163, 33164, 33165, 33166, 33167, 33168, 33143, 33144, 33145, 33146, - 33147, 33148, 33149, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 27580, 27581, 27582, 27583, 27579, 27578, 27554, 27555, 27576, - 27575, 27558, 27559, 27560, 27561, 27556, 27557, 27574, 27571, 27570, - 27562, 27563, 27564, 27572, 27577, 27565, 27566, 27567, 27568, 27569, - 27573, 27584, 27585, 27476, 27497, 27498, 27499, 27496, 27495, 27488, - 27492, 27491, 27481, 27482, 27494, 27490, 27486, 27485, 27483, 27477, - 27484, 27487, 27493, 27478, 27479, 27480, 27489, 41412, 41412, 41412, - 41412, 27464, 27469, 27501, 27500, 27550, 27542, 27536, 27513, 27507, - 27530, 27524, 27502, 27519, 27548, 27546, 27540, 27517, 27511, 27534, - 27528, 41412, 41412, 27551, 27543, 27537, 27514, 27508, 27531, 27525, - 27504, 27521, 27553, 27545, 27539, 27516, 27510, 27533, 27527, 27506, - 27523, 27549, 27547, 27541, 27518, 27512, 27535, 27529, 27503, 27520, - 27552, 27544, 27538, 27515, 27509, 27532, 27526, 27505, 27522, 27468, - 27474, 27473, 27467, 27466, 27471, 27470, 27465, 27475, 27472, 21831, - 21853, 21855, 21851, 41412, 21852, 21854, 41412, 41412, 41412, 41412, - 41412, 21856, 21847, 21850, 21849, 21797, 21795, 21819, 21818, 41412, - 21817, 21816, 21825, 41412, 21805, 21801, 21800, 21808, 21807, 21804, - 21803, 21802, 21810, 21809, 21806, 21821, 21820, 21815, 21814, 21827, - 21829, 21828, 21826, 21823, 21811, 21812, 21813, 21830, 21824, 21796, - 21798, 21799, 21822, 41412, 41412, 21845, 21846, 21848, 41412, 41412, - 41412, 41412, 21857, 21794, 21793, 21792, 21791, 21833, 21832, 21834, - 21835, 21858, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 21839, - 21844, 21837, 21836, 21843, 21841, 21840, 21838, 21842, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 30585, 30581, 30586, 30591, 30582, - 30589, 30575, 30583, 30587, 30579, 30574, 30570, 30588, 30571, 30573, - 30572, 30590, 30563, 30564, 30566, 30569, 30567, 30568, 30578, 30580, - 30565, 30584, 30577, 30576, 30593, 30592, 30594, 30406, 30424, 30405, - 30415, 30427, 30428, 30417, 30421, 30419, 30412, 30416, 30408, 30423, - 30407, 30429, 30418, 30420, 30401, 30402, 30425, 30404, 30426, 30403, - 30411, 30413, 30409, 30422, 30410, 30414, 30432, 30431, 30430, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 25786, 25790, 25789, 25794, 25793, 25791, 25815, 25818, 25834, - 25798, 25797, 25796, 25795, 25816, 25808, 25814, 25800, 25810, 25799, - 25812, 25792, 25807, 25821, 25817, 25804, 25788, 25787, 25820, 25819, - 25805, 25802, 25811, 25801, 25813, 25806, 25803, 25809, 25836, 25835, - 41412, 41412, 41412, 41412, 25822, 25826, 25825, 25824, 25823, 25833, - 25831, 25829, 25828, 25827, 25832, 25830, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 2587, 2588, 2594, 2590, 2593, 2589, - 2591, 2592, 2630, 2631, 2620, 2621, 2622, 2623, 2618, 2619, 2635, 2608, - 2607, 2606, 2597, 2595, 2596, 2632, 2634, 2617, 2615, 2627, 2626, 2616, - 2638, 2633, 2625, 2624, 2602, 2601, 2600, 2605, 2604, 2603, 2637, 2598, - 2613, 2614, 2640, 2639, 2636, 2612, 2629, 2610, 2628, 2609, 2611, 2599, - 41412, 41412, 41412, 2641, 37706, 34058, 22832, 22827, 22833, 22828, - 20912, 20923, 20914, 20908, 20920, 20925, 20915, 20921, 20906, 20919, - 20922, 20909, 20927, 20924, 20916, 20913, 20926, 20917, 20910, 20911, - 20918, 20907, 41412, 41412, 20932, 20929, 20930, 20935, 20931, 20928, - 20933, 20934, 20881, 20895, 20886, 20882, 20892, 20885, 20887, 20893, - 20879, 20891, 20894, 20883, 20884, 20896, 20888, 20897, 20889, 20890, - 20880, 41412, 41412, 41412, 41412, 41412, 20902, 20899, 20900, 20905, - 20901, 20898, 20903, 20904, 31875, 31889, 31880, 31876, 31886, 31879, - 31881, 31887, 31885, 31888, 31877, 31878, 31890, 31882, 31892, 31883, - 31884, 31891, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 31900, - 31901, 31873, 31874, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 31897, 31894, 31895, 31899, 31896, - 31893, 31898, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 30595, 30637, 30638, 30627, 30663, 30656, 30630, 30631, - 30665, 30608, 30648, 30596, 30641, 30610, 30650, 30598, 30642, 30609, - 30649, 30597, 30626, 30662, 30616, 30655, 30605, 30645, 30599, 30643, - 30632, 30666, 30611, 30651, 30600, 30621, 30624, 30612, 30601, 30639, - 30619, 30658, 30617, 30657, 30620, 30659, 30647, 30618, 30640, 30625, - 30633, 30628, 30623, 30661, 30613, 30652, 30629, 30664, 30634, 30667, - 30614, 30653, 30602, 30606, 30603, 30607, 30646, 30622, 30660, 30615, - 30654, 30604, 30644, 30635, 30636, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 30254, 30257, 30280, 30255, 30269, 30265, 30271, 30281, 30256, 30259, - 30302, 30282, 30283, 30272, 30273, 30284, 30303, 30304, 30285, 30286, - 30258, 30299, 30274, 30275, 30260, 30262, 30266, 30294, 30296, 30290, - 30292, 30295, 30287, 30261, 30288, 30297, 30267, 30268, 30276, 30263, - 30277, 30270, 30298, 30301, 30291, 30293, 30289, 30278, 30279, 30264, - 30300, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 30305, 30308, 30331, 30306, 30320, 30316, - 30322, 30332, 30307, 30310, 30353, 30333, 30334, 30323, 30324, 30335, - 30354, 30355, 30336, 30337, 30309, 30350, 30325, 30326, 30311, 30313, - 30317, 30345, 30347, 30341, 30343, 30346, 30338, 30312, 30339, 30348, - 30318, 30319, 30327, 30314, 30328, 30321, 30349, 30352, 30342, 30344, - 30340, 30329, 30330, 30315, 30351, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 30358, 30357, 30361, 30356, 30359, 30360, 19769, 19756, - 19764, 19748, 19747, 19761, 19757, 19760, 19745, 19758, 19742, 19741, - 19750, 19749, 19768, 19755, 19754, 19746, 19759, 19762, 19763, 19753, - 19766, 19743, 19767, 19744, 19751, 19752, 19765, 19776, 19778, 19780, - 19777, 19779, 19771, 19770, 19775, 19772, 19774, 19773, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 19787, 19789, 19786, 19785, - 19782, 19781, 19784, 19783, 19790, 19788, 41412, 41412, 41412, 41412, - 41412, 41412, 17854, 17856, 17853, 17852, 17849, 17848, 17851, 17850, - 17857, 17855, 17840, 17841, 17842, 17839, 17843, 17837, 17814, 17798, - 17806, 17804, 17797, 17803, 17809, 17811, 17805, 17801, 17799, 17812, - 17813, 17810, 17808, 17795, 17800, 17796, 17807, 17802, 17793, 17794, - 41412, 41412, 41412, 17838, 17792, 17790, 17789, 17791, 17845, 17844, - 17836, 17820, 17828, 17826, 17819, 17825, 17831, 17833, 17827, 17823, - 17821, 17834, 17835, 17832, 17830, 17817, 17822, 17818, 17829, 17824, - 17815, 17816, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 17846, 17847, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 32454, 32452, 32451, 32448, 32447, 32450, 32449, 32455, 32453, 32446, - 32445, 32443, 32434, 32432, 32441, 32439, 32430, 32436, 32437, 32444, - 32442, 32433, 32431, 32440, 32438, 32429, 32435, 32426, 32427, 32425, - 32428, 41412, 39869, 39903, 39883, 39882, 39888, 39887, 39865, 39864, - 39863, 39874, 39895, 39868, 39899, 39902, 39901, 39898, 39906, 39885, - 39884, 39886, 39867, 39889, 39900, 39870, 39894, 39905, 39890, 39891, - 39878, 39876, 39875, 39877, 39879, 39866, 39881, 39904, 39892, 39893, - 39872, 39873, 39896, 39871, 41412, 39861, 39860, 39862, 41412, 41412, - 39880, 39897, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 1201, 1497, 1332, - 2388, 1540, 1604, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 1065, 1654, 1652, 1650, 1909, 1910, 1911, 1913, 1895, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 1083, 2389, 1066, 2395, 2396, 2393, 30525, 30533, 30547, 30534, - 30538, 30544, 30535, 30550, 30539, 30545, 30543, 30546, 30537, 30552, - 30548, 30527, 30528, 30540, 30526, 30524, 30551, 30541, 30529, 30530, - 30536, 30542, 30549, 30531, 30532, 30559, 30557, 30554, 30562, 30561, - 30558, 30556, 30555, 30560, 30523, 30553, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 34118, 34132, 34120, 34129, 34136, 34124, - 34130, 34128, 34131, 34121, 34138, 34134, 34125, 34119, 34137, 34126, - 34123, 34127, 34135, 34133, 34122, 34117, 34112, 34110, 34113, 34111, - 34116, 34115, 34107, 34106, 34108, 34114, 34109, 34139, 34142, 34141, - 34140, 34145, 34146, 34143, 34147, 34144, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 30672, 30684, - 30682, 30687, 30676, 30681, 30680, 30683, 30674, 30689, 30685, 30677, - 30688, 30678, 30673, 30679, 30686, 30675, 30671, 30670, 30669, 30668, - 30693, 30690, 30691, 30692, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 6596, 6590, 6604, 6598, 6593, 6601, 6607, 6589, 6599, 6602, - 6600, 6603, 6594, 6609, 6605, 6591, 6597, 6608, 6595, 6592, 6606, 6614, - 6611, 6612, 6616, 6613, 6610, 6615, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 16854, 16865, 16856, 16850, 16862, - 16867, 16857, 16863, 16848, 16861, 16864, 16851, 16869, 16866, 16858, - 16855, 16868, 16859, 16852, 16853, 16860, 16849, 16870, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 4737, 4742, 4740, 4739, - 4741, 4664, 4665, 4683, 4684, 4681, 4682, 4676, 4677, 4678, 4679, 4710, - 4666, 4657, 4667, 4703, 4702, 4699, 4698, 4687, 4697, 4696, 4701, 4700, - 4689, 4673, 4672, 4669, 4668, 4688, 4675, 4674, 4671, 4670, 4690, 4705, - 4704, 4695, 4694, 4707, 4709, 4708, 4686, 4680, 4691, 4692, 4693, 4706, - 4685, 4658, 4663, 4662, 4747, 4746, 4756, 4757, 4750, 4751, 4752, 4753, - 4754, 4755, 4758, 4748, 4743, 4749, 4759, 4761, 4760, 4735, 4734, 4733, - 4736, 4732, 41412, 41412, 41412, 41412, 4728, 4726, 4723, 4714, 4716, - 4721, 4719, 4711, 4717, 4727, 4725, 4724, 4713, 4715, 4722, 4720, 4712, - 4718, 4729, 4730, 4768, 4770, 4767, 4766, 4763, 4762, 4765, 4764, 4771, - 4769, 4738, 4660, 4661, 4744, 4745, 4659, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 4731, 21141, 21143, 21145, 21101, - 21102, 21111, 21112, 21109, 21110, 21139, 21103, 21140, 21104, 21129, - 21128, 21125, 21124, 21113, 21123, 21122, 21127, 21126, 21115, 21106, - 21105, 21098, 21096, 21097, 21132, 21114, 21108, 21107, 21100, 21099, - 21116, 21131, 21130, 21121, 21120, 21136, 21138, 21133, 21135, 21137, - 21117, 21118, 21119, 21134, 21151, 21156, 21157, 21154, 21155, 21158, - 21152, 21159, 21153, 21144, 21142, 21162, 21163, 21160, 21146, 21147, - 21149, 21148, 21150, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 21161, 41412, 41412, 34170, 34171, 34160, 34161, - 34162, 34163, 34156, 34157, 34167, 34159, 34172, 34168, 34173, 34169, - 34164, 34166, 34165, 34158, 34174, 34153, 34175, 34177, 34176, 34154, - 34155, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 34184, 34186, - 34183, 34182, 34179, 34178, 34181, 34180, 34187, 34185, 41412, 41412, - 41412, 41412, 41412, 41412, 6276, 6278, 6277, 6272, 6274, 6275, 6273, - 6261, 6260, 6257, 6256, 6242, 6255, 6254, 6259, 6258, 6244, 6247, 6246, - 6239, 6238, 6243, 6249, 6248, 6241, 6240, 6245, 6265, 6264, 6253, 6252, - 6267, 6250, 6251, 6268, 6263, 6271, 6269, 6266, 6280, 6288, 6289, 6284, - 6285, 6286, 6282, 6290, 6283, 6291, 6308, 6307, 6292, 6306, 41412, 6301, - 6303, 6300, 6299, 6296, 6295, 6298, 6297, 6304, 6302, 6279, 6294, 6293, - 6305, 6262, 6281, 6287, 6270, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 25547, 25549, 25551, 25548, 25550, 25539, 25538, 25535, - 25534, 25533, 25532, 25537, 25536, 25518, 25527, 25526, 25521, 25520, - 25517, 25529, 25528, 25523, 25522, 25519, 25541, 25540, 25531, 25530, - 25544, 25525, 25543, 25546, 25545, 25542, 25524, 25554, 25555, 25553, - 25552, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 32928, 32931, 32935, 32874, 32875, 32893, 32894, 32891, 32892, 32886, - 32887, 32888, 32889, 32920, 32876, 32921, 32877, 32913, 32912, 32909, - 32908, 32897, 32907, 32906, 32911, 32910, 32899, 32883, 32882, 32879, - 32878, 32898, 32885, 32884, 32881, 32880, 32900, 32915, 32914, 32905, - 32904, 32917, 32919, 32918, 32896, 32895, 32890, 32901, 32902, 32903, - 32916, 32950, 32957, 32958, 32944, 32945, 32953, 32954, 32955, 32956, - 32959, 32951, 32940, 32952, 32934, 32930, 32932, 32933, 32962, 32860, - 32859, 32960, 32925, 32922, 32929, 32937, 32871, 32936, 32943, 32926, - 32867, 32869, 32866, 32865, 32862, 32861, 32864, 32863, 32870, 32868, - 32872, 32927, 32873, 32961, 32923, 32924, 41412, 33872, 33870, 33869, - 33866, 33865, 33868, 33867, 33873, 33871, 33884, 33883, 33882, 33878, - 33877, 33881, 33880, 33876, 33879, 33874, 33875, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 22537, 22538, - 22564, 22566, 22563, 22539, 22565, 22540, 22554, 22553, 22529, 22527, - 22528, 22547, 22552, 22551, 22536, 22535, 41412, 22549, 22542, 22541, - 22532, 22531, 22548, 22544, 22543, 22534, 22530, 22533, 22550, 22556, - 22555, 22526, 22524, 22525, 22558, 22562, 22560, 22546, 22561, 22523, - 22557, 22545, 22574, 22577, 22578, 22581, 22579, 22575, 22580, 22576, - 22571, 22570, 22569, 22567, 22521, 22520, 22582, 22572, 22519, 22583, - 22568, 22559, 22522, 22573, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 28461, 28463, 28464, 28462, - 28452, 28451, 28450, 41412, 28449, 41412, 28448, 28447, 28440, 28439, - 41412, 28434, 28442, 28441, 28430, 28428, 28429, 28433, 28444, 28443, - 28432, 28431, 28435, 28454, 28453, 28446, 41412, 28445, 28457, 28460, - 28438, 28456, 28459, 28458, 28455, 28437, 28436, 28465, 41412, 41412, - 41412, 41412, 41412, 41412, 22598, 22599, 22610, 22611, 22608, 22609, - 22629, 22600, 22630, 22601, 22619, 22618, 22589, 22587, 22588, 22612, - 22617, 22616, 22597, 22596, 22595, 22614, 22605, 22604, 22592, 22590, - 22602, 22591, 22613, 22607, 22606, 22594, 22593, 22615, 22621, 22620, - 22586, 22584, 22585, 22626, 22628, 22603, 22625, 22627, 22622, 22623, - 22624, 22633, 22634, 22639, 22640, 22637, 22638, 22641, 22635, 22642, - 22636, 22631, 22632, 41412, 41412, 41412, 41412, 41412, 22649, 22651, - 22648, 22647, 22644, 22643, 22646, 22645, 22652, 22650, 41412, 41412, - 41412, 41412, 41412, 41412, 18252, 18253, 18256, 18259, 41412, 18209, - 18210, 18223, 18224, 18221, 18222, 18204, 18206, 41412, 41412, 18247, - 18211, 41412, 41412, 18246, 18212, 18243, 18242, 18239, 18238, 18227, - 18237, 18236, 18241, 18240, 18229, 18218, 18217, 18214, 18213, 18228, - 18220, 18219, 18216, 18215, 18230, 41412, 18245, 18244, 18235, 18234, - 18249, 18251, 18250, 41412, 18226, 18225, 41412, 18208, 18231, 18232, - 18233, 18248, 41412, 8183, 18254, 18255, 18261, 18270, 18271, 18264, - 18265, 18266, 18267, 41412, 41412, 18273, 18262, 41412, 41412, 18272, - 18263, 18258, 41412, 41412, 18274, 41412, 41412, 41412, 41412, 41412, - 41412, 18260, 41412, 41412, 41412, 41412, 41412, 18257, 18203, 18202, - 18205, 18207, 18268, 18269, 41412, 41412, 8372, 8373, 8371, 8370, 8369, - 8368, 8367, 41412, 41412, 41412, 8378, 8375, 8376, 8374, 8377, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 38042, 38043, 38066, 38067, 38064, 38065, 38059, 38060, 38061, 38062, - 41412, 38088, 41412, 41412, 38044, 41412, 38087, 38045, 38084, 38083, - 38080, 38079, 38068, 38078, 38077, 38082, 38081, 38070, 38056, 38055, - 38047, 38046, 38069, 38058, 38057, 38049, 38048, 38071, 38086, 38085, - 38076, 38075, 38090, 38091, 38054, 38052, 38063, 38072, 38073, 38074, - 38089, 38051, 38053, 38050, 41412, 38093, 38104, 38113, 38114, 38107, - 38108, 38109, 38110, 38111, 38112, 41412, 38116, 41412, 41412, 38105, - 41412, 38115, 38106, 38037, 38098, 41412, 38094, 38101, 38100, 38095, - 38038, 38092, 38041, 38099, 38040, 38039, 41412, 38096, 38097, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 38103, 38102, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 29384, 29385, - 29398, 29399, 29396, 29397, 29380, 29381, 29382, 29383, 29424, 29386, - 29425, 29387, 29412, 29411, 29408, 29407, 29373, 29372, 29406, 29405, - 29410, 29409, 29375, 29374, 29393, 29392, 29389, 29388, 29377, 29395, - 29394, 29391, 29390, 29378, 29376, 29418, 29417, 29404, 29403, 29416, - 29415, 29423, 29420, 29419, 29414, 29413, 29422, 29400, 29401, 29402, - 29421, 29438, 29447, 29448, 29441, 29442, 29443, 29444, 29445, 29446, - 29449, 29439, 29450, 29440, 29433, 29426, 29429, 29434, 29427, 29428, - 29431, 29454, 29435, 29360, 29358, 29453, 29371, 29451, 29367, 29369, - 29366, 29365, 29362, 29361, 29364, 29363, 29370, 29368, 29359, 29437, - 41412, 29452, 29436, 29379, 29430, 29432, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 37708, 37709, 37710, 37728, - 37729, 37726, 37727, 37721, 37722, 37723, 37724, 37754, 37711, 37755, - 37712, 37746, 37745, 37742, 37741, 37730, 37740, 37739, 37744, 37743, - 37732, 37718, 37717, 37714, 37713, 37731, 37720, 37719, 37716, 37715, - 37733, 37748, 37747, 37738, 37737, 37751, 37753, 37752, 37750, 37725, - 37734, 37735, 37736, 37749, 37764, 37773, 37774, 37767, 37768, 37769, - 37770, 37771, 37772, 37775, 37762, 37765, 37776, 37763, 37766, 37756, - 37759, 37761, 37760, 37757, 37758, 37787, 37707, 37788, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 37783, 37785, 37782, 37781, - 37778, 37777, 37780, 37779, 37786, 37784, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 33052, 33054, 33075, 33076, 33073, 33074, 33068, 33069, - 33070, 33071, 33101, 33055, 33102, 33056, 33093, 33092, 33089, 33088, - 33077, 33087, 33086, 33091, 33090, 33079, 33062, 33061, 33065, 33064, - 33078, 33063, 33058, 33067, 33066, 33080, 33095, 33094, 33085, 33084, - 33098, 33100, 33099, 33097, 33072, 33081, 33082, 33083, 33096, 33130, - 33137, 33138, 33135, 33136, 33133, 33134, 41412, 41412, 33139, 33131, - 33140, 33132, 33123, 33125, 33127, 33126, 33124, 33122, 33142, 33141, - 33121, 33120, 33103, 33104, 33105, 33051, 33118, 33117, 33115, 33113, - 33114, 33106, 33107, 33116, 33119, 33111, 33112, 33110, 33109, 33108, - 33057, 33059, 33060, 33053, 33128, 33129, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 27815, 27816, 27834, 27835, 27832, 27833, 27827, 27828, 27829, 27830, - 27861, 27817, 27862, 27818, 27854, 27853, 27850, 27849, 27838, 27848, - 27847, 27852, 27851, 27840, 27824, 27823, 27820, 27819, 27839, 27826, - 27825, 27822, 27821, 27841, 27856, 27855, 27846, 27845, 27858, 27860, - 27859, 27837, 27831, 27842, 27843, 27844, 27857, 27836, 27790, 27799, - 27800, 27793, 27794, 27795, 27796, 27797, 27798, 27801, 27791, 27802, - 27792, 27786, 27789, 27788, 27785, 27804, 27803, 27863, 27787, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 27811, 27813, 27810, 27809, 27806, 27805, 27808, 27807, 27814, 27812, - 41412, 41412, 41412, 41412, 41412, 41412, 28344, 28339, 28184, 28345, - 28343, 28341, 28340, 28201, 28202, 28335, 28337, 28336, 28346, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 35581, 35583, - 35598, 35599, 35596, 35597, 35623, 35584, 35624, 35585, 35613, 35612, - 35609, 35608, 35600, 35607, 35606, 35611, 35610, 35602, 35593, 35592, - 35587, 35586, 35601, 35595, 35594, 35589, 35588, 35603, 35615, 35614, - 35605, 35604, 35620, 35622, 35591, 35619, 35621, 35616, 35617, 35618, - 35590, 35626, 35628, 35629, 35634, 35635, 35632, 35633, 35636, 35630, - 35637, 35631, 35627, 35625, 35582, 35580, 41412, 41412, 41412, 41412, - 41412, 41412, 35644, 35646, 35643, 35642, 35639, 35638, 35641, 35640, - 35647, 35645, 41412, 41412, 41412, 41412, 41412, 41412, 28953, 28955, - 28952, 28951, 28948, 28947, 28950, 28949, 28956, 28954, 28903, 28905, - 28902, 28901, 28898, 28897, 28900, 28899, 28906, 28904, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 191, 190, 178, 181, 175, 167, - 193, 192, 183, 195, 189, 184, 174, 196, 177, 197, 180, 194, 164, 171, - 170, 187, 166, 186, 182, 188, 165, 41412, 41412, 162, 163, 161, 203, 204, - 210, 211, 208, 209, 212, 207, 213, 205, 206, 200, 41412, 41412, 41412, - 41412, 222, 224, 221, 220, 217, 216, 219, 218, 225, 223, 215, 214, 198, - 199, 201, 202, 185, 173, 172, 169, 168, 179, 176, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 11159, 11160, 11175, 11176, 11173, 11174, 11201, 11161, - 11202, 11162, 11193, 11192, 11189, 11188, 11177, 11187, 11186, 11191, - 11190, 11179, 11170, 11169, 11164, 11163, 11178, 11172, 11171, 11166, - 11165, 11180, 11195, 11194, 11185, 11184, 11198, 11200, 11168, 11197, - 11199, 11181, 11182, 11183, 11196, 11167, 11205, 11210, 11211, 11208, - 11209, 11203, 11204, 11212, 11206, 11213, 11207, 11216, 11218, 11217, - 11215, 11214, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 39508, 39497, 39526, 39516, 39518, 39519, 39525, 39515, - 39501, 39510, 39498, 39528, 39524, 39503, 39517, 39514, 39502, 39511, - 39520, 39509, 39527, 39500, 39499, 39522, 39523, 39506, 39505, 39504, - 39507, 39512, 39513, 39521, 39540, 39529, 39558, 39548, 39550, 39551, - 39557, 39547, 39533, 39542, 39530, 39560, 39556, 39535, 39549, 39546, - 39534, 39543, 39552, 39541, 39559, 39532, 39531, 39554, 39555, 39538, - 39537, 39536, 39539, 39544, 39545, 39553, 39567, 39569, 39566, 39565, - 39562, 39561, 39564, 39563, 39570, 39568, 39579, 39578, 39577, 39573, - 39572, 39576, 39575, 39571, 39574, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 39580, 11075, 11076, - 11083, 11084, 11081, 11082, 11110, 41412, 41412, 11111, 41412, 41412, - 11101, 11100, 11099, 11098, 11087, 11097, 11096, 11105, 41412, 11089, - 11071, 41412, 11078, 11077, 11088, 11072, 11070, 11080, 11079, 11090, - 11103, 11102, 11095, 11094, 11106, 11074, 11073, 11107, 11086, 11108, - 11091, 11092, 11093, 11104, 11085, 11109, 11116, 11120, 11121, 11118, - 11119, 11122, 41412, 11117, 11123, 41412, 41412, 11115, 11113, 11112, - 11124, 11129, 11126, 11130, 11125, 11114, 11059, 11127, 11128, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 11066, 11068, - 11065, 11064, 11061, 11060, 11063, 11062, 11069, 11067, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 29075, 29076, - 29091, 29092, 29089, 29090, 29072, 29073, 41412, 41412, 29117, 29077, - 29118, 29078, 29111, 29110, 29107, 29106, 29095, 29105, 29104, 29109, - 29108, 29097, 29086, 29085, 29080, 29079, 29096, 29088, 29087, 29082, - 29081, 29098, 29113, 29112, 29103, 29102, 29115, 29116, 29084, 29094, - 29074, 29099, 29100, 29101, 29114, 29093, 29083, 29127, 29132, 29133, - 29130, 29131, 29125, 29126, 41412, 41412, 29134, 29128, 29135, 29129, - 29121, 29123, 29122, 29120, 29119, 29136, 29124, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41193, 41214, 41211, 41210, 41213, 41209, - 41208, 41206, 41207, 41212, 41205, 41161, 41160, 41180, 41179, 41162, - 41178, 41177, 41187, 41164, 41172, 41171, 41154, 41153, 41163, 41174, - 41173, 41158, 41157, 41165, 41182, 41181, 41176, 41175, 41189, 41170, - 41169, 41156, 41155, 41183, 41184, 41185, 41192, 41190, 41188, 41191, - 41166, 41167, 41168, 41186, 41159, 41152, 41202, 41199, 41200, 41201, - 41198, 41203, 41149, 41148, 41146, 41145, 41147, 41151, 41144, 41197, - 41195, 41194, 41196, 41150, 41143, 41204, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 34276, 34297, 34295, 34294, 34296, 34292, - 34293, 34290, 34291, 34289, 34288, 34298, 34243, 34242, 34262, 34261, - 34244, 34260, 34259, 34264, 34263, 34246, 34254, 34253, 34237, 34236, - 34245, 34256, 34255, 34240, 34238, 34247, 34266, 34265, 34258, 34257, - 34272, 34252, 34251, 34239, 34267, 34268, 34269, 34275, 34273, 34271, - 34274, 34248, 34249, 34250, 34270, 34241, 34281, 34283, 34220, 34219, - 34217, 34218, 34228, 34229, 34224, 34227, 34223, 34226, 34231, 34232, - 34230, 34222, 34221, 34225, 34284, 34282, 34299, 34285, 34280, 34279, - 34278, 34277, 34235, 34234, 34233, 34286, 34287, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 5719, 5720, 5717, 5718, 5715, 5716, 5725, 5726, 5723, 5724, 5721, 5722, - 5888, 5889, 5890, 5887, 31432, 31430, 31439, 31440, 31436, 31444, 31443, - 31425, 31438, 31437, 31429, 31442, 31435, 31428, 31434, 31433, 31426, - 31431, 31441, 31420, 31427, 31445, 31446, 31421, 31447, 31423, 31424, - 31422, 31416, 31413, 31417, 31415, 31411, 31414, 31418, 31412, 31419, - 31453, 31452, 31463, 31454, 31455, 31464, 31460, 31459, 31461, 31462, - 31456, 31410, 31457, 31458, 31449, 31448, 31408, 31450, 31451, 31409, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 10801, 10802, 10891, - 10892, 10893, 10894, 10901, 10900, 10902, 10906, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 32942, 32941, 32947, 32946, 32948, 32949, 32938, - 32939, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 34883, - 34902, 34909, 34906, 34896, 34893, 34888, 34910, 34878, 34895, 34905, - 34885, 34882, 34891, 34908, 34886, 34904, 34892, 34897, 34903, 34907, - 34880, 34879, 34884, 34900, 34894, 34890, 34889, 34898, 34881, 34899, - 34901, 34887, 34911, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 34918, 34920, 34917, - 34916, 34913, 34912, 34915, 34914, 34921, 34919, 41412, 41412, 41412, - 41412, 41412, 41412, 3761, 3762, 3775, 3776, 3773, 3774, 3757, 3758, - 3759, 41412, 3801, 3763, 3802, 3764, 3793, 3792, 3789, 3788, 3777, 3787, - 3786, 3791, 3790, 3779, 3770, 3769, 3766, 3765, 3778, 3772, 3771, 3768, - 3767, 3780, 3795, 3794, 3785, 3784, 3798, 3800, 3799, 3797, 3760, 3781, - 3782, 3783, 3796, 3829, 3834, 3835, 3832, 3833, 3826, 3827, 3828, 41412, - 3836, 3830, 3837, 3831, 3821, 3823, 3825, 3824, 3822, 3839, 3838, 3850, - 3851, 3852, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 3846, 3848, 3845, 3844, 3841, 3840, 3843, 3842, 3849, 3847, - 3820, 3818, 3815, 3806, 3808, 3813, 3811, 3803, 3809, 3819, 3817, 3816, - 3805, 3807, 3814, 3812, 3804, 3810, 3853, 41412, 41412, 41412, 25911, - 25912, 25857, 25856, 25866, 25851, 25855, 25854, 25868, 25852, 25848, - 25847, 25850, 25853, 25859, 25858, 25865, 25870, 25846, 25845, 25849, - 25872, 25862, 25863, 25864, 25873, 25871, 25869, 25860, 25861, 25867, - 25874, 41412, 41412, 25889, 25888, 25897, 25883, 25887, 25886, 25899, - 25884, 25880, 25879, 25882, 25885, 25891, 25890, 25896, 25901, 25878, - 25877, 25881, 25903, 25894, 25895, 41412, 25904, 25902, 25900, 25892, - 25893, 25898, 25905, 25906, 25908, 25910, 25907, 25909, 25876, 25875, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 25923, 25924, 25933, 25934, 25931, 25932, 25960, - 41412, 25925, 25961, 41412, 25926, 25939, 25938, 25952, 25951, 25940, - 25950, 25949, 25917, 25916, 25942, 25919, 25918, 25928, 25927, 25941, - 25922, 25920, 25930, 25929, 25943, 25954, 25953, 25948, 25947, 25956, - 25959, 25957, 25936, 25958, 25944, 25945, 25946, 25955, 25935, 25937, - 25915, 25921, 25970, 25975, 25976, 25973, 25974, 25969, 41412, 41412, - 41412, 25977, 41412, 25971, 25978, 41412, 25972, 25968, 25967, 25966, - 25964, 25965, 25979, 25963, 25962, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 25986, 25988, 25985, 25984, 25981, 25980, 25983, - 25982, 25989, 25987, 41412, 41412, 41412, 41412, 41412, 41412, 18927, - 18928, 18941, 18942, 18939, 18940, 41412, 18958, 18929, 41412, 18957, - 18930, 18964, 18963, 18946, 18945, 18960, 18954, 18953, 18938, 18937, - 18944, 18950, 18949, 18934, 18933, 18926, 18948, 18947, 18936, 18935, - 18943, 18952, 18951, 18932, 18931, 18925, 18956, 18955, 18959, 18961, - 18962, 18967, 18972, 18973, 18970, 18971, 41412, 18975, 18968, 41412, - 18974, 18969, 18966, 18965, 18976, 18987, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 18983, 18985, 18982, 18981, 18978, 18977, 18980, - 18979, 18986, 18984, 41412, 41412, 41412, 41412, 41412, 41412, 37877, - 37875, 37882, 37880, 37845, 37846, 37873, 37874, 37863, 37864, 37879, - 37859, 37862, 37847, 37850, 37851, 37860, 37861, 37848, 37849, 37852, - 37865, 37866, 37869, 37870, 37855, 37871, 37872, 37867, 37868, 37854, - 37885, 37856, 37878, 37883, 37853, 37881, 37876, 37884, 37857, 37858, - 37886, 37887, 37888, 41412, 41412, 41412, 41412, 37895, 37897, 37894, - 37893, 37890, 37889, 37892, 37891, 37898, 37896, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 25609, 25607, 25601, 25612, 25604, 25611, 25615, - 25606, 25603, 25605, 25608, 25602, 25617, 25613, 25610, 25616, 25614, - 25618, 25624, 25621, 25623, 25620, 25622, 25619, 25600, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 21676, 21680, 21678, 21679, 21617, - 21618, 21637, 21638, 21631, 21632, 21633, 21634, 21635, 21636, 21662, - 21619, 21663, 41412, 21653, 21652, 21651, 21650, 21639, 21649, 21648, - 21622, 21621, 21641, 21628, 21627, 21624, 21623, 21640, 21630, 21629, - 21626, 21625, 21642, 21655, 21654, 21647, 21646, 21658, 21661, 21659, - 21657, 21660, 21643, 21644, 21645, 21656, 21620, 21682, 21681, 21689, - 21690, 21687, 21688, 21684, 41412, 41412, 41412, 21685, 21683, 21686, - 21675, 21703, 21692, 21691, 21670, 21673, 21669, 21671, 21667, 21666, - 21674, 21665, 21668, 21672, 21664, 21699, 21701, 21698, 21697, 21694, - 21693, 21696, 21695, 21702, 21700, 21677, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 25255, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 35704, 35700, 35694, - 35703, 35696, 35705, 35709, 35711, 35706, 35701, 35702, 35707, 35695, - 35712, 35710, 35697, 35708, 35698, 35699, 35713, 35714, 35778, 35761, - 35759, 35768, 35767, 35763, 35769, 35765, 35764, 35771, 35772, 35773, - 35770, 35762, 35775, 35693, 35680, 35751, 35758, 36048, 36049, 35678, - 35653, 35779, 36047, 35715, 35780, 35766, 35774, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 35756, 8952, 8960, 8958, 8954, 8959, 8955, 8953, 8956, 8957, 9021, 8961, - 8970, 8969, 8963, 8962, 8974, 8964, 8965, 8973, 8967, 8968, 8975, 8976, - 8981, 8978, 8977, 8979, 8980, 8983, 8985, 8987, 8986, 8988, 8994, 8991, - 8992, 8996, 8989, 8990, 8995, 8993, 8998, 8997, 8999, 9001, 9002, 9006, - 9005, 9003, 9004, 9007, 9020, 9008, 9009, 9010, 9019, 9011, 9015, 9016, - 9014, 9012, 9013, 9018, 9017, 9022, 9023, 9034, 9025, 9029, 9030, 9031, - 9032, 9033, 9035, 9038, 9037, 9036, 9039, 9041, 9042, 9043, 9044, 9045, - 9046, 9047, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 9055, 9056, 9057, - 9058, 9073, 9059, 9060, 9070, 9064, 9061, 9062, 9063, 9071, 9068, 9072, - 9069, 9065, 9067, 9080, 9076, 9077, 9078, 9081, 9092, 9082, 9085, 9086, - 9088, 9089, 9090, 9093, 9096, 9094, 9095, 9097, 9098, 9100, 9101, 9130, - 9137, 9131, 9132, 9133, 9134, 9135, 9136, 9138, 9140, 9139, 9141, 9144, - 9145, 9148, 9142, 9143, 9149, 9194, 9193, 9195, 9150, 9153, 9154, 9155, - 9151, 9152, 9156, 9159, 9157, 9160, 9162, 9171, 9172, 9173, 9174, 9192, - 9175, 9176, 9189, 9190, 9188, 9177, 9178, 9179, 9180, 9181, 9182, 9183, - 9186, 9187, 9196, 9286, 9197, 9198, 9200, 9199, 9206, 9201, 9203, 9205, - 9209, 9208, 9210, 9211, 9218, 9212, 9213, 9217, 9221, 9222, 9219, 9220, - 9228, 9225, 9229, 9230, 9231, 9232, 9233, 9235, 9236, 9238, 9237, 9240, - 9239, 9242, 9241, 9243, 9244, 9246, 9247, 9251, 9253, 9257, 9258, 9271, - 9263, 9264, 9259, 9260, 9261, 9265, 9269, 9266, 9267, 9268, 9272, 9273, - 9275, 9276, 9277, 9278, 9279, 9280, 9290, 9281, 9282, 9285, 9284, 9283, - 9287, 9288, 9289, 9291, 9292, 9295, 9296, 9297, 9298, 9299, 9301, 9300, - 9317, 9308, 9309, 9302, 9303, 9305, 9306, 9304, 9307, 9316, 9310, 9315, - 9313, 9312, 9314, 9319, 9338, 9320, 9321, 9322, 9325, 9324, 9326, 9327, - 9329, 9330, 9331, 9339, 9332, 9333, 9334, 9337, 9336, 9335, 9340, 9341, - 9343, 9344, 9345, 9346, 9348, 9352, 9349, 9353, 9351, 9350, 9354, 9355, - 9356, 9357, 9361, 9360, 9358, 9359, 9362, 9363, 9365, 9384, 9386, 9366, - 9368, 9367, 9369, 9370, 9373, 9374, 9372, 9371, 9375, 9376, 9377, 9378, - 9381, 9379, 9380, 9382, 9383, 9387, 9388, 9385, 9389, 9390, 9391, 9392, - 9394, 9397, 9396, 9398, 9399, 9401, 9402, 9403, 9407, 9406, 9404, 9405, - 9408, 9412, 9411, 9410, 9413, 9414, 9416, 9417, 9421, 9418, 9419, 9424, - 9422, 9425, 9426, 9428, 9427, 9429, 9430, 9452, 9451, 9454, 9455, 9436, - 9437, 9434, 9435, 9433, 9431, 9439, 9438, 9440, 9442, 9448, 9449, 9446, - 9447, 9456, 9457, 9458, 9476, 9461, 9462, 9463, 9459, 9460, 9464, 9465, - 9466, 9467, 9468, 9470, 9471, 9472, 9473, 9474, 9499, 9477, 9480, 9478, - 9479, 9485, 9486, 9483, 9484, 9481, 9482, 9487, 9488, 9496, 9489, 9490, - 9497, 9494, 9495, 9498, 9491, 9492, 9493, 9500, 9501, 9502, 9503, 9504, - 9505, 9506, 9508, 9509, 9507, 9510, 9511, 9552, 9553, 9514, 9515, 9512, - 9513, 9518, 9519, 9517, 9523, 9520, 9522, 9521, 9527, 9528, 9526, 9524, - 9525, 9529, 9530, 9531, 9532, 9533, 9534, 9535, 9554, 9540, 9536, 9537, - 9538, 9539, 9541, 9543, 9542, 9544, 9545, 9547, 9546, 9548, 9550, 9549, - 9555, 9556, 9559, 9560, 9557, 9558, 9634, 9629, 9630, 9631, 9632, 9633, - 9635, 9638, 9636, 9637, 9639, 9681, 9640, 9670, 9671, 9647, 9649, 9666, - 9650, 9672, 9654, 9652, 9653, 9655, 9656, 9657, 9658, 9667, 9668, 9661, - 9662, 9664, 9673, 9641, 9642, 9646, 9644, 9682, 9674, 9676, 9675, 9677, - 9683, 9684, 9678, 9679, 9680, 9685, 9686, 9687, 9690, 9691, 9692, 9688, - 9689, 9693, 9694, 9696, 9698, 9699, 9717, 9715, 9716, 9719, 9718, 9700, - 9707, 9705, 9706, 9701, 9702, 9708, 9709, 9710, 9711, 9712, 9714, 9720, - 9729, 9721, 9723, 9724, 9722, 9725, 9727, 9726, 9728, 9731, 9733, 9732, - 9734, 9735, 9768, 9770, 9736, 9738, 9737, 9740, 9743, 9741, 9742, 9746, - 9750, 9753, 9752, 9755, 9758, 9756, 9757, 9761, 9763, 9769, 9771, 9772, - 9776, 9783, 9781, 9779, 9780, 9782, 9785, 9784, 9777, 9778, 9786, 9789, - 9795, 9790, 9793, 9788, 9787, 9796, 9794, 9791, 9792, 9797, 9798, 9799, - 9800, 9801, 9802, 9803, 9805, 9808, 9809, 9812, 9813, 9814, 9810, 9811, - 9806, 9807, 9815, 9816, 9817, 9818, 9819, 9820, 9822, 9823, 9824, 9825, - 9826, 9830, 9827, 9851, 9844, 9845, 9850, 9833, 9832, 9846, 9849, 9847, - 9836, 9835, 9838, 9840, 9841, 9842, 9843, 9839, 9852, 9828, 9853, 9854, - 9855, 9856, 9857, 9858, 9866, 9864, 9862, 9865, 9861, 9863, 9859, 9860, - 9867, 9869, 9870, 9871, 9878, 9873, 9874, 9882, 9883, 9879, 9881, 9880, - 9884, 9886, 9885, 9887, 9898, 9889, 9888, 9897, 9895, 9890, 9891, 9892, - 9894, 9893, 9896, 9902, 9899, 9901, 9900, 9903, 9904, 9905, 9906, 9909, - 9910, 9912, 9913, 9914, 9915, 9917, 9916, 9918, 9925, 9919, 9920, 9926, - 9921, 9922, 9923, 9924, 9927, 9931, 9928, 9929, 9930, 9932, 9933, 9934, - 9935, 9941, 9939, 9937, 9938, 9936, 9940, 9942, 9944, 9961, 9962, 9945, - 9950, 9952, 9946, 9949, 9947, 9948, 9953, 9959, 9960, 9954, 9957, 9958, - 9963, 9969, 9968, 9964, 9966, 9965, 10050, 10051, 9970, 9971, 9976, 9977, - 9974, 9975, 9978, 9972, 9973, 9979, 9982, 9983, 9985, 9986, 9987, 9991, - 9988, 9989, 9990, 9980, 9981, 9992, 9994, 9993, 9995, 9997, 9998, 9999, - 10005, 10004, 10000, 10001, 10002, 10037, 10006, 10007, 10008, 10009, - 10010, 10029, 10012, 10013, 10015, 10014, 10016, 10017, 10033, 10018, - 10020, 10019, 10032, 10022, 10030, 10034, 10025, 10024, 10031, 10026, - 10028, 10027, 10035, 10036, 10038, 10042, 10040, 10041, 10039, 10045, - 10044, 10043, 10049, 10046, 10047, 10048, 10052, 10054, 10053, 10057, - 10055, 10072, 10058, 10061, 10063, 10059, 10060, 10064, 10062, 10065, - 10067, 10069, 10070, 10071, 9475, 8971, 8982, 9000, 9066, 9075, 9091, - 9099, 9191, 9184, 9202, 9204, 9294, 9318, 9364, 9393, 9395, 9409, 9415, - 9450, 9423, 9453, 9432, 9441, 9445, 9516, 9645, 9648, 9663, 9695, 9713, - 9730, 9739, 9767, 9765, 9744, 9775, 9804, 9821, 9831, 9951, 9984, 9967, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 8936, 8931, 8868, 8854, 8915, 8911, 8843, 8888, 8935, 8876, - 8860, 8921, 8910, 8842, 8887, 8874, 8858, 8917, 8907, 8837, 8884, 8897, - 8941, 8933, 8870, 8856, 8919, 8909, 8839, 8886, 8898, 8942, 8934, 8871, - 8857, 8943, 8925, 8926, 8872, 8848, 8914, 8906, 8836, 8883, 8901, 8944, - 8927, 8928, 8873, 8849, 8912, 8913, 8896, 8939, 8922, 8923, 8863, 8853, - 8929, 8930, 8864, 8867, 8865, 8866, 8920, 8905, 8903, 8904, 8840, 8841, - 8879, 8881, 8882, 8880, 8937, 8932, 8869, 8855, 8916, 8895, 8938, 8924, - 8861, 8862, 8851, 8852, 8878, 8877, 8891, 8940, 8900, 8946, 8850, 8899, - 8945, 8892, 8893, 8889, 8890, 8894, 8902, 8844, 8847, 8846, 8845, 8875, - 8859, 8918, 8908, 8838, 8885, 41412, 8951, 8950, 8949, 8947, 8948, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 8972, 8966, 8984, 9024, 9026, 9027, 9028, 9040, 9079, 9074, 9084, 9083, - 9087, 9104, 9102, 9103, 9105, 9106, 9124, 9110, 9107, 9108, 9109, 9126, - 9127, 9125, 9114, 9113, 9111, 9112, 9117, 9115, 9116, 9118, 9119, 9120, - 9121, 9128, 9129, 9123, 9122, 9147, 9146, 9158, 9161, 9166, 9170, 9163, - 9167, 9168, 9164, 9165, 9169, 9185, 9207, 9214, 9215, 9216, 9223, 9224, - 9227, 9226, 9234, 9245, 9248, 9249, 9250, 9252, 9254, 9255, 9256, 9262, - 9270, 9274, 9293, 9311, 9323, 9328, 9342, 9347, 9400, 9420, 9443, 9444, - 9551, 9571, 9561, 9562, 9570, 9566, 9567, 9568, 9565, 9564, 9563, 9569, - 9573, 9572, 9579, 9580, 9574, 9575, 9576, 9581, 9577, 9578, 9582, 9583, - 9584, 9585, 9586, 9587, 9594, 9588, 9593, 9592, 9590, 9589, 9591, 9595, - 9596, 9601, 9602, 9597, 9598, 9599, 9600, 9628, 9624, 9603, 9611, 9612, - 9610, 9609, 9613, 9604, 9605, 9607, 9608, 9606, 9625, 9614, 9621, 9623, - 9618, 9619, 9622, 9617, 9620, 9616, 9615, 9626, 9627, 9643, 9669, 9651, - 9659, 9660, 9665, 9697, 9704, 9703, 9764, 9745, 9747, 9766, 9748, 9749, - 9751, 9754, 9759, 9760, 9762, 9829, 9848, 9834, 9837, 9868, 9872, 9875, - 9876, 9877, 9908, 9907, 9911, 9943, 9955, 9956, 9996, 10003, 10011, - 10023, 10021, 10056, 10066, 10068, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 10145, 10146, 10147, - 10148, 10149, 10150, 10151, 10152, 10155, 10156, 10153, 10154, 10157, - 10158, 10159, 10160, 10161, 10162, 10163, 10164, 10165, 10166, 10167, - 10168, 10169, 10170, 10171, 10172, 10173, 10174, 10175, 10176, 10177, - 10178, 10179, 10180, 10181, 10182, 10183, 10184, 10185, 10186, 10187, - 10188, 10189, 10190, 10191, 10211, 10212, 10213, 10214, 10215, 10216, - 10217, 10218, 10219, 10194, 10195, 10196, 10197, 10198, 10192, 10193, - 10199, 10200, 10201, 10220, 10221, 10222, 10223, 10224, 10225, 10226, - 10227, 10228, 10229, 10202, 10203, 10204, 10205, 10206, 10207, 10208, - 10209, 10210, 10230, 10231, 10232, 10233, 10234, 10235, 10236, 10237, - 10238, 10239, 10240, 10241, 10242, 10243, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 11681, - 11682, 11683, 11684, 11679, 11680, 11676, 11677, 11678, 11685, 11686, - 11687, 11692, 11693, 11694, 11695, 11688, 11689, 11696, 11697, 11690, - 11691, 11698, 11699, 11726, 11727, 11728, 11729, 11730, 11731, 11732, - 11733, 11734, 11735, 11716, 11717, 11714, 11715, 11718, 11719, 11720, - 11721, 11722, 11723, 11724, 11700, 11701, 11708, 11702, 11703, 11704, - 11705, 11709, 11706, 11707, 11710, 11711, 11712, 11713, 11736, 11737, - 11738, 11739, 11740, 11741, 11742, 11743, 11744, 11745, 11746, 11747, - 11748, 11749, 11750, 11751, 11752, 11753, 11754, 11755, 11725, 11795, - 11796, 11797, 11798, 11793, 11794, 11799, 11800, 11801, 11802, 11807, - 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, 11813, - 11814, 11815, 11816, 11817, 11818, 11819, 11820, 11821, 11822, 11823, - 11824, 11825, 11826, 11827, 11828, 11829, 11830, 11833, 11834, 11835, - 11836, 11837, 11838, 11839, 11831, 11832, 11840, 11913, 11914, 11915, - 11916, 11917, 11918, 11919, 11920, 11921, 11922, 11904, 11905, 11906, - 11907, 11908, 11909, 11910, 11902, 11903, 11911, 11912, 11845, 11841, - 11842, 11846, 11847, 11843, 11844, 11848, 11849, 11850, 11851, 11852, - 11857, 11858, 11859, 11860, 11861, 11862, 11853, 11854, 11863, 11855, - 11856, 11864, 11865, 11866, 11867, 11868, 11869, 11870, 11871, 11872, - 11873, 11874, 11879, 11875, 11876, 11880, 11877, 11878, 11881, 11882, - 11883, 11884, 11885, 11895, 11896, 11897, 11898, 11899, 11900, 11901, - 11886, 11887, 11888, 11889, 11890, 11891, 11892, 11893, 11894, 11927, - 11928, 11929, 11930, 11931, 11932, 11933, 11923, 11924, 11925, 11926, - 11959, 11960, 11961, 11962, 11963, 11964, 11955, 11956, 11957, 11958, - 11965, 11966, 11934, 11935, 11938, 11939, 11940, 11941, 11942, 11943, - 11944, 11936, 11937, 11945, 11948, 11949, 11950, 11951, 11946, 11947, - 11952, 11953, 11954, 11970, 11971, 11972, 11973, 11974, 11975, 11976, - 11977, 11978, 11979, 11982, 11983, 11984, 11980, 11981, 11985, 11986, - 11987, 11988, 11989, 11990, 12026, 12024, 12025, 12027, 12028, 12029, - 12030, 12031, 12032, 12033, 12034, 11997, 11991, 11992, 11998, 11999, - 12000, 12001, 12002, 11993, 11994, 11995, 11996, 12003, 12010, 12011, - 12012, 12013, 12014, 12004, 12005, 12006, 12007, 12008, 12009, 12015, - 12016, 12021, 12017, 12018, 12019, 12020, 12022, 12023, 12041, 12042, - 12043, 12044, 12045, 12039, 12040, 12036, 12037, 12038, 12046, 12047, - 12050, 12048, 12049, 12051, 12052, 12053, 12054, 12055, 12056, 12057, - 12058, 12083, 12084, 12087, 12088, 12089, 12090, 12091, 12085, 12086, - 12092, 12093, 12094, 12063, 12064, 12065, 12066, 12067, 12068, 12059, - 12060, 12061, 12062, 12069, 12070, 12075, 12076, 12077, 12071, 12072, - 12078, 12073, 12074, 12079, 12080, 12081, 12082, 12095, 12096, 12097, - 12098, 12099, 12102, 12103, 12104, 12105, 12106, 12100, 12101, 12107, - 12108, 12116, 12117, 12118, 12119, 12112, 12113, 12120, 12121, 12122, - 12114, 12115, 12123, 12124, 12125, 12126, 12127, 12128, 12129, 12130, - 12771, 12772, 12773, 12774, 12775, 12776, 12777, 12778, 12142, 12138, - 12139, 12143, 12144, 12145, 12140, 12141, 12146, 12147, 12149, 12150, - 12151, 12154, 12152, 12153, 12155, 12156, 12157, 12158, 12159, 12160, - 12170, 12171, 12178, 12161, 12162, 12163, 12164, 12165, 12166, 12167, - 12168, 12169, 12179, 12180, 12172, 12173, 12174, 12175, 12176, 12177, - 12181, 12182, 12189, 12190, 12183, 12184, 12191, 12185, 12186, 12192, - 12193, 12194, 12187, 12188, 12195, 12201, 12199, 12200, 12202, 12196, - 12197, 12198, 12203, 12204, 12205, 12206, 12207, 12208, 12209, 12210, - 12211, 12212, 12213, 12214, 12271, 12272, 12273, 12274, 12275, 12276, - 12277, 12278, 12279, 12234, 12235, 12236, 12237, 12238, 12239, 12240, - 12241, 12231, 12232, 12233, 12242, 12259, 12260, 12261, 12262, 12263, - 12257, 12258, 12264, 12265, 12266, 12267, 12251, 12252, 12253, 12243, - 12244, 12245, 12246, 12247, 12248, 12254, 12249, 12250, 12255, 12256, - 12268, 12269, 12270, 12282, 12283, 12284, 12285, 12280, 12281, 12286, - 12287, 12288, 12289, 12292, 12293, 12294, 12295, 12296, 12297, 12298, - 12290, 12291, 12299, 12300, 12301, 12319, 12320, 12321, 12322, 12323, - 12324, 12325, 12326, 12327, 12302, 12303, 12304, 12305, 12308, 12309, - 12310, 12311, 12312, 12313, 12306, 12307, 12314, 12317, 12318, 12315, - 12316, 12335, 12336, 12339, 12340, 12341, 12337, 12338, 12328, 12329, - 12330, 12331, 12332, 12333, 12334, 12342, 12343, 12344, 12345, 12346, - 12347, 12348, 12351, 12352, 12353, 12354, 12355, 12356, 12357, 12358, - 12349, 12350, 12359, 12360, 12367, 12368, 12369, 12361, 12362, 12363, - 12364, 12370, 12371, 12372, 12365, 12366, 12378, 12379, 12382, 12383, - 12380, 12381, 12384, 12385, 12373, 12374, 12375, 12376, 12377, 12386, - 12387, 12388, 12393, 12394, 12395, 12396, 12397, 12398, 12399, 12400, - 12401, 12402, 12389, 12390, 12391, 12392, 12404, 12405, 12408, 12406, - 12407, 12409, 12410, 12411, 12412, 12413, 12414, 12415, 12416, 12779, - 12780, 12781, 12782, 12783, 12784, 12785, 12422, 12420, 12421, 12417, - 12418, 12419, 12423, 12424, 12425, 12426, 12427, 12428, 12429, 12430, - 12433, 12434, 12435, 12436, 12437, 12431, 12432, 12438, 12439, 12440, - 12441, 12442, 12443, 12444, 12445, 12446, 12447, 12448, 12449, 12450, - 12455, 12451, 12452, 12456, 12457, 12458, 12453, 12454, 12459, 12460, - 12461, 12467, 12468, 12469, 12470, 12462, 12463, 12464, 12471, 12472, - 12465, 12466, 12473, 12474, 12478, 12479, 12480, 12481, 12482, 12483, - 12475, 12476, 12477, 12484, 12485, 12486, 12489, 12490, 12491, 12492, - 12493, 12487, 12488, 12494, 12495, 12496, 12497, 12498, 12499, 12500, - 12501, 12502, 12503, 12504, 12513, 12514, 12505, 12506, 12515, 12516, - 12517, 12507, 12508, 12509, 12510, 12511, 12512, 12522, 12518, 12519, - 12523, 12524, 12525, 12526, 12520, 12521, 12527, 12528, 12529, 12539, - 12540, 12541, 12542, 12543, 12544, 12545, 12546, 12547, 12548, 12534, - 12535, 12530, 12531, 12532, 12533, 12536, 12537, 12538, 12553, 12554, - 12555, 12556, 12557, 12550, 12551, 12552, 12558, 12559, 12560, 12587, - 12588, 12589, 12590, 12591, 12592, 12593, 12594, 12595, 12596, 12565, - 12566, 12567, 12561, 12562, 12568, 12569, 12570, 12571, 12572, 12563, - 12564, 12575, 12576, 12573, 12574, 12577, 12578, 12579, 12580, 12581, - 12582, 12583, 12584, 12585, 12586, 12600, 12601, 12602, 12603, 12604, - 12605, 12606, 12607, 12608, 12609, 12610, 12611, 12612, 12613, 12614, - 12615, 12597, 12598, 12599, 12616, 12617, 12626, 12618, 12619, 12620, - 12621, 12623, 12624, 12625, 12627, 12628, 12629, 12630, 12631, 12632, - 12633, 12634, 12635, 12636, 12637, 12638, 12639, 12640, 12641, 12642, - 12643, 12644, 12645, 12646, 12653, 12654, 12647, 12648, 12655, 12656, - 12657, 12658, 12649, 12650, 12651, 12652, 12659, 12660, 12661, 12662, - 12667, 12663, 12664, 12668, 12669, 12670, 12665, 12666, 12671, 12672, - 12673, 12674, 12680, 12681, 12676, 12677, 12682, 12683, 12684, 12685, - 12686, 12678, 12679, 12687, 12688, 12695, 12696, 12697, 12689, 12690, - 12698, 12699, 12691, 12692, 12693, 12694, 12700, 12703, 12704, 12705, - 12706, 12701, 12702, 12707, 12716, 12717, 12718, 12709, 12710, 12711, - 12719, 12712, 12713, 12720, 12714, 12715, 12721, 12722, 12723, 12724, - 12725, 12726, 12727, 12728, 12729, 12742, 12730, 12731, 12732, 12733, - 12734, 12735, 12736, 12737, 12738, 12739, 12740, 12741, 12743, 12744, - 12745, 12746, 12766, 12767, 12768, 12769, 12770, 12747, 12748, 12749, - 12750, 12751, 12752, 12753, 12754, 12755, 12756, 12757, 12758, 12759, - 12760, 12761, 12762, 12763, 12764, 12765, 11759, 11760, 11761, 11762, - 11763, 11764, 11756, 11757, 11758, 11765, 11766, 11770, 11771, 11772, - 11773, 11774, 11775, 11776, 11777, 11778, 11779, 11780, 11781, 11782, - 11783, 11784, 11785, 11786, 11787, 11788, 11789, 11767, 11768, 11769, - 12622, 12675, 12111, 12136, 12133, 12135, 12132, 12403, 11792, 11969, - 12137, 12134, 12131, 11791, 11968, 11790, 11967, 12230, 12035, 12109, - 12148, 12110, 12549, 12708, 12226, 12217, 12221, 12228, 12224, 12218, - 12223, 12220, 12227, 12216, 12222, 12229, 12225, 12219, 12215, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 12786, - 12787, 12788, 12789, 12790, 12791, 12792, 12793, 12794, 12795, 12796, - 12797, 12798, 12799, 12800, 12801, 12802, 12803, 12804, 12805, 12806, - 12807, 12808, 12809, 12810, 12811, 12812, 12813, 12814, 12815, 12816, - 12817, 12818, 12819, 12820, 12821, 12822, 12823, 12824, 12825, 12826, - 12827, 12828, 12829, 12830, 12831, 12832, 12833, 12834, 12835, 12836, - 12837, 12838, 12839, 12840, 12841, 12842, 12843, 12844, 12845, 12846, - 12847, 12848, 12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, - 12857, 12858, 12859, 12860, 12861, 12862, 12863, 12864, 12865, 12866, - 12867, 12868, 12869, 12870, 12871, 12872, 12873, 12874, 12875, 12876, - 12877, 12878, 12879, 12880, 12881, 12882, 12883, 12884, 12885, 12886, - 12887, 12888, 12889, 12890, 12891, 12892, 12893, 12894, 12895, 12896, - 12897, 12898, 12899, 12900, 12901, 12902, 12903, 12904, 12905, 12906, - 12907, 12908, 12909, 12910, 12911, 12912, 12913, 12914, 12915, 12916, - 12917, 12918, 12919, 12920, 12921, 12922, 12923, 12924, 12925, 12926, - 12927, 12928, 12929, 12930, 12931, 12932, 12933, 12934, 12935, 12936, - 12937, 12938, 12939, 12940, 12941, 12942, 12943, 12944, 12945, 12946, - 12947, 12948, 12949, 12950, 12951, 12952, 12953, 12954, 12955, 12956, - 12957, 12958, 12959, 12960, 12961, 12962, 12963, 12964, 12965, 12966, - 12967, 12968, 12969, 12970, 12971, 12972, 12973, 12974, 12975, 12976, - 12977, 12978, 12979, 12980, 12981, 12982, 12983, 12984, 12985, 12986, - 12987, 12988, 12989, 12990, 12991, 12992, 12993, 12994, 12995, 12996, - 12997, 12998, 12999, 13000, 13001, 13002, 13003, 13004, 13005, 13006, - 13007, 13008, 13009, 13010, 13011, 13012, 13013, 13014, 13015, 13016, - 13017, 13018, 13019, 13020, 13021, 13022, 13023, 13024, 13025, 13026, - 13027, 13028, 13029, 13030, 13031, 13032, 13033, 13034, 13035, 13036, - 13037, 13038, 13039, 13040, 13041, 13042, 13043, 13044, 13045, 13046, - 13047, 13048, 13049, 13050, 13051, 13052, 13053, 13054, 13055, 13056, - 13057, 13058, 13059, 13060, 13061, 13062, 13063, 13064, 13065, 13066, - 13067, 13068, 13069, 13070, 13071, 13072, 13073, 13074, 13075, 13076, - 13077, 13078, 13079, 13080, 13081, 13082, 13083, 13084, 13085, 13086, - 13087, 13088, 13089, 13090, 13091, 13092, 13093, 13094, 13095, 13096, - 13097, 13098, 13099, 13100, 13101, 13102, 13103, 13104, 13105, 13106, - 13107, 13108, 13109, 13110, 13111, 13112, 13113, 13114, 13115, 13116, - 13117, 13118, 13119, 13120, 13121, 13122, 13123, 13124, 13125, 13126, - 13127, 13128, 13129, 13130, 13131, 13132, 13133, 13134, 13135, 13136, - 13137, 13138, 13139, 13140, 13141, 13142, 13143, 13144, 13145, 13146, - 13147, 13148, 13149, 13150, 13151, 13152, 13153, 13154, 13155, 13156, - 13157, 13158, 13159, 13160, 13161, 13162, 13163, 13164, 13165, 13166, - 13167, 13168, 13169, 13170, 13171, 13172, 13173, 13174, 13175, 13176, - 13177, 13178, 13179, 13180, 13181, 13182, 13183, 13184, 13185, 13186, - 13187, 13188, 13189, 13190, 13191, 13192, 13193, 13194, 13195, 13196, - 13197, 13198, 13199, 13200, 13201, 13202, 13203, 13204, 13205, 13206, - 13207, 13208, 13209, 13210, 13211, 13212, 13213, 13214, 13215, 13216, - 13217, 13218, 13219, 13220, 13221, 13222, 13223, 13224, 13225, 13226, - 13227, 13228, 13229, 13230, 13231, 13232, 13233, 13234, 13235, 13236, - 13237, 13238, 13239, 13240, 13241, 13242, 13243, 13244, 13245, 13246, - 13247, 13248, 13249, 13250, 13251, 13252, 13253, 13254, 13255, 13256, - 13257, 13258, 13259, 13260, 13261, 13262, 13263, 13264, 13265, 13266, - 13267, 13268, 13269, 13270, 13271, 13272, 13273, 13274, 13275, 13276, - 13277, 13278, 13279, 13280, 13281, 13282, 13283, 13284, 13285, 13286, - 13287, 13288, 13289, 13290, 13291, 13292, 13293, 13294, 13295, 13296, - 13297, 13298, 13299, 13300, 13301, 13302, 13303, 13304, 13305, 13306, - 13307, 13308, 13309, 13310, 13311, 13312, 13313, 13314, 13315, 13316, - 13317, 13318, 13319, 13320, 13321, 13322, 13323, 13324, 13325, 13326, - 13327, 13328, 13329, 13330, 13331, 13332, 13333, 13334, 13335, 13336, - 13337, 13338, 13339, 13340, 13341, 13342, 13343, 13344, 13345, 13346, - 13347, 13348, 13349, 13350, 13351, 13352, 13353, 13354, 13355, 13356, - 13357, 13358, 13359, 13360, 13361, 13362, 13363, 13364, 13365, 13366, - 13367, 13368, 13369, 13370, 13371, 13372, 13373, 13374, 13375, 13376, - 13377, 13378, 13379, 13380, 13381, 13382, 13383, 13384, 13385, 13386, - 13387, 13388, 13389, 13390, 13391, 13392, 13393, 13394, 13395, 13396, - 13397, 13398, 13399, 13400, 13401, 13402, 13403, 13404, 13405, 13406, - 13407, 13408, 13409, 13410, 13411, 13412, 13413, 13414, 13415, 13416, - 13417, 13418, 13419, 13420, 13421, 13422, 13423, 13424, 13425, 13426, - 13427, 13428, 13429, 13430, 13431, 13432, 13433, 13434, 13435, 13436, - 13437, 13438, 13439, 13440, 13441, 13442, 13443, 13444, 13445, 13446, - 13447, 13448, 13449, 13450, 13451, 13452, 13453, 13454, 13455, 13456, - 13457, 13458, 13459, 13460, 13461, 13462, 13463, 13464, 13465, 13466, - 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475, 13476, - 13477, 13478, 13479, 13480, 13481, 13482, 13483, 13484, 13485, 13486, - 13487, 13488, 13489, 13490, 13491, 13492, 13493, 13494, 13495, 13496, - 13497, 13498, 13499, 13500, 13501, 13502, 13503, 13504, 13505, 13506, - 13507, 13508, 13509, 13510, 13511, 13512, 13513, 13514, 13515, 13516, - 13517, 13518, 13519, 13520, 13521, 13522, 13523, 13524, 13525, 13526, - 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13534, 13535, 13536, - 13537, 13538, 13539, 13540, 13541, 13542, 13543, 13544, 13545, 13546, - 13547, 13548, 13549, 13550, 13551, 13552, 13553, 13554, 13555, 13556, - 13557, 13558, 13559, 13560, 13561, 13562, 13563, 13564, 13565, 13566, - 13567, 13568, 13569, 13570, 13571, 13572, 13573, 13574, 13575, 13576, - 13577, 13578, 13579, 13580, 13581, 13582, 13583, 13584, 13585, 13586, - 13587, 13588, 13589, 13590, 13591, 13592, 13593, 13594, 13595, 13596, - 13597, 13598, 13599, 13600, 13601, 13602, 13603, 13604, 13605, 13606, - 13607, 13608, 13609, 13610, 13611, 13612, 13613, 13614, 13615, 13616, - 13617, 13618, 13619, 13620, 13621, 13622, 13623, 13624, 13625, 13626, - 13627, 13628, 13629, 13630, 13631, 13632, 13633, 13634, 13635, 13636, - 13637, 13638, 13639, 13640, 13641, 13642, 13643, 13644, 13645, 13646, - 13647, 13648, 13649, 13650, 13651, 13652, 13653, 13654, 13655, 13656, - 13657, 13658, 13659, 13660, 13661, 13662, 13663, 13664, 13665, 13666, - 13667, 13668, 13669, 13670, 13671, 13672, 13673, 13674, 13675, 13676, - 13677, 13678, 13679, 13680, 13681, 13682, 13683, 13684, 13685, 13686, - 13687, 13688, 13689, 13690, 13691, 13692, 13693, 13694, 13695, 13696, - 13697, 13698, 13699, 13700, 13701, 13702, 13703, 13704, 13705, 13706, - 13707, 13708, 13709, 13710, 13711, 13712, 13713, 13714, 13715, 13716, - 13717, 13718, 13719, 13720, 13721, 13722, 13723, 13724, 13725, 13726, - 13727, 13728, 13729, 13730, 13731, 13732, 13733, 13734, 13735, 13736, - 13737, 13738, 13739, 13740, 13741, 13742, 13743, 13744, 13745, 13746, - 13747, 13748, 13749, 13750, 13751, 13752, 13753, 13754, 13755, 13756, - 13757, 13758, 13759, 13760, 13761, 13762, 13763, 13764, 13765, 13766, - 13767, 13768, 13769, 13770, 13771, 13772, 13773, 13774, 13775, 13776, - 13777, 13778, 13779, 13780, 13781, 13782, 13783, 13784, 13785, 13786, - 13787, 13788, 13789, 13790, 13791, 13792, 13793, 13794, 13795, 13796, - 13797, 13798, 13799, 13800, 13801, 13802, 13803, 13804, 13805, 13806, - 13807, 13808, 13809, 13810, 13811, 13812, 13813, 13814, 13815, 13816, - 13817, 13818, 13819, 13820, 13821, 13822, 13823, 13824, 13825, 13826, - 13827, 13828, 13829, 13830, 13831, 13832, 13833, 13834, 13835, 13836, - 13837, 13838, 13839, 13840, 13841, 13842, 13843, 13844, 13845, 13846, - 13847, 13848, 13849, 13850, 13851, 13852, 13853, 13854, 13855, 13856, - 13857, 13858, 13859, 13860, 13861, 13862, 13863, 13864, 13865, 13866, - 13867, 13868, 13869, 13870, 13871, 13872, 13873, 13874, 13875, 13876, - 13877, 13878, 13879, 13880, 13881, 13882, 13883, 13884, 13885, 13886, - 13887, 13888, 13889, 13890, 13891, 13892, 13893, 13894, 13895, 13896, - 13897, 13898, 13899, 13900, 13901, 13902, 13903, 13904, 13905, 13906, - 13907, 13908, 13909, 13910, 13911, 13912, 13913, 13914, 13915, 13916, - 13917, 13918, 13919, 13920, 13921, 13922, 13923, 13924, 13925, 13926, - 13927, 13928, 13929, 13930, 13931, 13932, 13933, 13934, 13935, 13936, - 13937, 13938, 13939, 13940, 13941, 13942, 13943, 13944, 13945, 13946, - 13947, 13948, 13949, 13950, 13951, 13952, 13953, 13954, 13955, 13956, - 13957, 13958, 13959, 13960, 13961, 13962, 13963, 13964, 13965, 13966, - 13967, 13968, 13969, 13970, 13971, 13972, 13973, 13974, 13975, 13976, - 13977, 13978, 13979, 13980, 13981, 13982, 13983, 13984, 13985, 13986, - 13987, 13988, 13989, 13990, 13991, 13992, 13993, 13994, 13995, 13996, - 13997, 13998, 13999, 14000, 14001, 14002, 14003, 14004, 14005, 14006, - 14007, 14008, 14009, 14010, 14011, 14012, 14013, 14014, 14015, 14016, - 14017, 14018, 14019, 14020, 14021, 14022, 14023, 14024, 14025, 14026, - 14027, 14028, 14029, 14030, 14031, 14032, 14033, 14034, 14035, 14036, - 14037, 14038, 14039, 14040, 14041, 14042, 14043, 14044, 14045, 14046, - 14047, 14048, 14049, 14050, 14051, 14052, 14053, 14054, 14055, 14056, - 14057, 14058, 14059, 14060, 14061, 14062, 14063, 14064, 14065, 14066, - 14067, 14068, 14069, 14070, 14071, 14072, 14073, 14074, 14075, 14076, - 14077, 14078, 14079, 14080, 14081, 14082, 14083, 14084, 14085, 14086, - 14087, 14088, 14089, 14090, 14091, 14092, 14093, 14094, 14095, 14096, - 14097, 14098, 14099, 14100, 14101, 14102, 14103, 14104, 14105, 14106, - 14107, 14108, 14109, 14110, 14111, 14112, 14113, 14114, 14115, 14116, - 14117, 14118, 14119, 14120, 14121, 14122, 14123, 14124, 14125, 14126, - 14127, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 14136, - 14137, 14138, 14139, 14140, 14141, 14142, 14143, 14144, 14145, 14146, - 14147, 14148, 14149, 14150, 14151, 14152, 14153, 14154, 14155, 14156, - 14157, 14158, 14159, 14160, 14161, 14162, 14163, 14164, 14165, 14166, - 14167, 14168, 14169, 14170, 14171, 14172, 14173, 14174, 14175, 14176, - 14177, 14178, 14179, 14180, 14181, 14182, 14183, 14184, 14185, 14186, - 14187, 14188, 14189, 14190, 14191, 14192, 14193, 14194, 14195, 14196, - 14197, 14198, 14199, 14200, 14201, 14202, 14203, 14204, 14205, 14206, - 14207, 14208, 14209, 14210, 14211, 14212, 14213, 14214, 14215, 14216, - 14217, 14218, 14219, 14220, 14221, 14222, 14223, 14224, 14225, 14226, - 14227, 14228, 14229, 14230, 14231, 14232, 14233, 14234, 14235, 14236, - 14237, 14238, 14239, 14240, 14241, 14242, 14243, 14244, 14245, 14246, - 14247, 14248, 14249, 14250, 14251, 14252, 14253, 14254, 14255, 14256, - 14257, 14258, 14259, 14260, 14261, 14262, 14263, 14264, 14265, 14266, - 14267, 14268, 14269, 14270, 14271, 14272, 14273, 14274, 14275, 14276, - 14277, 14278, 14279, 14280, 14281, 14282, 14283, 14284, 14285, 14286, - 14287, 14288, 14289, 14290, 14291, 14292, 14293, 14294, 14295, 14296, - 14297, 14298, 14299, 14300, 14301, 14302, 14303, 14304, 14305, 14306, - 14307, 14308, 14309, 14310, 14311, 14312, 14313, 14314, 14315, 14316, - 14317, 14318, 14319, 14320, 14321, 14322, 14323, 14324, 14325, 14326, - 14327, 14328, 14329, 14330, 14331, 14332, 14333, 14334, 14335, 14336, - 14337, 14338, 14339, 14340, 14341, 14342, 14343, 14344, 14345, 14346, - 14347, 14348, 14349, 14350, 14351, 14352, 14353, 14354, 14355, 14356, - 14357, 14358, 14359, 14360, 14361, 14362, 14363, 14364, 14365, 14366, - 14367, 14368, 14369, 14370, 14371, 14372, 14373, 14374, 14375, 14376, - 14377, 14378, 14379, 14380, 14381, 14382, 14383, 14384, 14385, 14386, - 14387, 14388, 14389, 14390, 14391, 14392, 14393, 14394, 14395, 14396, - 14397, 14398, 14399, 14400, 14401, 14402, 14403, 14404, 14405, 14406, - 14407, 14408, 14409, 14410, 14411, 14412, 14413, 14414, 14415, 14416, - 14417, 14418, 14419, 14420, 14421, 14422, 14423, 14424, 14425, 14426, - 14427, 14428, 14429, 14430, 14431, 14432, 14433, 14434, 14435, 14436, - 14437, 14438, 14439, 14440, 14441, 14442, 14443, 14444, 14445, 14446, - 14447, 14448, 14449, 14450, 14451, 14452, 14453, 14454, 14455, 14456, - 14457, 14458, 14459, 14460, 14461, 14462, 14463, 14464, 14465, 14466, - 14467, 14468, 14469, 14470, 14471, 14472, 14473, 14474, 14475, 14476, - 14477, 14478, 14479, 14480, 14481, 14482, 14483, 14484, 14485, 14486, - 14487, 14488, 14489, 14490, 14491, 14492, 14493, 14494, 14495, 14496, - 14497, 14498, 14499, 14500, 14501, 14502, 14503, 14504, 14505, 14506, - 14507, 14508, 14509, 14510, 14511, 14512, 14513, 14514, 14515, 14516, - 14517, 14518, 14519, 14520, 14521, 14522, 14523, 14524, 14525, 14526, - 14527, 14528, 14529, 14530, 14531, 14532, 14533, 14534, 14535, 14536, - 14537, 14538, 14539, 14540, 14541, 14542, 14543, 14544, 14545, 14546, - 14547, 14548, 14549, 14550, 14551, 14552, 14553, 14554, 14555, 14556, - 14557, 14558, 14559, 14560, 14561, 14562, 14563, 14564, 14565, 14566, - 14567, 14568, 14569, 14570, 14571, 14572, 14573, 14574, 14575, 14576, - 14577, 14578, 14579, 14580, 14581, 14582, 14583, 14584, 14585, 14586, - 14587, 14588, 14589, 14590, 14591, 14592, 14593, 14594, 14595, 14596, - 14597, 14598, 14599, 14600, 14601, 14602, 14603, 14604, 14605, 14606, - 14607, 14608, 14609, 14610, 14611, 14612, 14613, 14614, 14615, 14616, - 14617, 14618, 14619, 14620, 14621, 14622, 14623, 14624, 14625, 14626, - 14627, 14628, 14629, 14630, 14631, 14632, 14633, 14634, 14635, 14636, - 14637, 14638, 14639, 14640, 14641, 14642, 14643, 14644, 14645, 14646, - 14647, 14648, 14649, 14650, 14651, 14652, 14653, 14654, 14655, 14656, - 14657, 14658, 14659, 14660, 14661, 14662, 14663, 14664, 14665, 14666, - 14667, 14668, 14669, 14670, 14671, 14672, 14673, 14674, 14675, 14676, - 14677, 14678, 14679, 14680, 14681, 14682, 14683, 14684, 14685, 14686, - 14687, 14688, 14689, 14690, 14691, 14692, 14693, 14694, 14695, 14696, - 14697, 14698, 14699, 14700, 14701, 14702, 14703, 14704, 14705, 14706, - 14707, 14708, 14709, 14710, 14711, 14712, 14713, 14714, 14715, 14716, - 14717, 14718, 14719, 14720, 14721, 14722, 14723, 14724, 14725, 14726, - 14727, 14728, 14729, 14730, 14731, 14732, 14733, 14734, 14735, 14736, - 14737, 14738, 14739, 14740, 14741, 14742, 14743, 14744, 14745, 14746, - 14747, 14748, 14749, 14750, 14751, 14752, 14753, 14754, 14755, 14756, - 14757, 14758, 14759, 14760, 14761, 14762, 14763, 14764, 14765, 14766, - 14767, 14768, 14769, 14770, 14771, 14772, 14773, 14774, 14775, 14776, - 14777, 14778, 14779, 14780, 14781, 14782, 14783, 14784, 14785, 14786, - 14787, 14788, 14789, 14790, 14791, 14792, 14793, 14794, 14795, 14796, - 14797, 14798, 14799, 14800, 14801, 14802, 14803, 14804, 14805, 14806, - 14807, 14808, 14809, 14810, 14811, 14812, 14813, 14814, 14815, 14816, - 14817, 14818, 14819, 14820, 14821, 14822, 14823, 14824, 14825, 14826, - 14827, 14828, 14829, 14830, 14831, 14832, 14833, 14834, 14835, 14836, - 14837, 14838, 14839, 14840, 14841, 14842, 14843, 14844, 14845, 14846, - 14847, 14848, 14849, 14850, 14851, 14852, 14853, 14854, 14855, 14856, - 14857, 14858, 14859, 14860, 14861, 14862, 14863, 14864, 14865, 14866, - 14867, 14868, 14869, 14870, 14871, 14872, 14873, 14874, 14875, 14876, - 14877, 14878, 14879, 14880, 14881, 14882, 14883, 14884, 14885, 14886, - 14887, 14888, 14889, 14890, 14891, 14892, 14893, 14894, 14895, 14896, - 14897, 14898, 14899, 14900, 14901, 14902, 14903, 14904, 14905, 14906, - 14907, 14908, 14909, 14910, 14911, 14912, 14913, 14914, 14915, 14916, - 14917, 14918, 14919, 14920, 14921, 14922, 14923, 14924, 14925, 14926, - 14927, 14928, 14929, 14930, 14931, 14932, 14933, 14934, 14935, 14936, - 14937, 14938, 14939, 14940, 14941, 14942, 14943, 14944, 14945, 14946, - 14947, 14948, 14949, 14950, 14951, 14952, 14953, 14954, 14955, 14956, - 14957, 14958, 14959, 14960, 14961, 14962, 14963, 14964, 14965, 14966, - 14967, 14968, 14969, 14970, 14971, 14972, 14973, 14974, 14975, 14976, - 14977, 14978, 14979, 14980, 14981, 14982, 14983, 14984, 14985, 14986, - 14987, 14988, 14989, 14990, 14991, 14992, 14993, 14994, 14995, 14996, - 14997, 14998, 14999, 15000, 15001, 15002, 15003, 15004, 15005, 15006, - 15007, 15008, 15009, 15010, 15011, 15012, 15013, 15014, 15015, 15016, - 15017, 15018, 15019, 15020, 15021, 15022, 15023, 15024, 15025, 15026, - 15027, 15028, 15029, 15030, 15031, 15032, 15033, 15034, 15035, 15036, - 15037, 15038, 15039, 15040, 15041, 15042, 15043, 15044, 15045, 15046, - 15047, 15048, 15049, 15050, 15051, 15052, 15053, 15054, 15055, 15056, - 15057, 15058, 15059, 15060, 15061, 15062, 15063, 15064, 15065, 15066, - 15067, 15068, 15069, 15070, 15071, 15072, 15073, 15074, 15075, 15076, - 15077, 15078, 15079, 15080, 15081, 15082, 15083, 15084, 15085, 15086, - 15087, 15088, 15089, 15090, 15091, 15092, 15093, 15094, 15095, 15096, - 15097, 15098, 15099, 15100, 15101, 15102, 15103, 15104, 15105, 15106, - 15107, 15108, 15109, 15110, 15111, 15112, 15113, 15114, 15115, 15116, - 15117, 15118, 15119, 15120, 15121, 15122, 15123, 15124, 15125, 15126, - 15127, 15128, 15129, 15130, 15131, 15132, 15133, 15134, 15135, 15136, - 15137, 15138, 15139, 15140, 15141, 15142, 15143, 15144, 15145, 15146, - 15147, 15148, 15149, 15150, 15151, 15152, 15153, 15154, 15155, 15156, - 15157, 15158, 15159, 15160, 15161, 15162, 15163, 15164, 15165, 15166, - 15167, 15168, 15169, 15170, 15171, 15172, 15173, 15174, 15175, 15176, - 15177, 15178, 15179, 15180, 15181, 15182, 15183, 15184, 15185, 15186, - 15187, 15188, 15189, 15190, 15191, 15192, 15193, 15194, 15195, 15196, - 15197, 15198, 15199, 15200, 15201, 15202, 15203, 15204, 15205, 15206, - 15207, 15208, 15209, 15210, 15211, 15212, 15213, 15214, 15215, 15216, - 15217, 15218, 15219, 15220, 15221, 15222, 15223, 15224, 15225, 15226, - 15227, 15228, 15229, 15230, 15231, 15232, 15233, 15234, 15235, 15236, - 15237, 15238, 15239, 15240, 15241, 15242, 15243, 15244, 15245, 15246, - 15247, 15248, 15249, 15250, 15251, 15252, 15253, 15254, 15255, 15256, - 15257, 15258, 15259, 15260, 15261, 15262, 15263, 15264, 15265, 15266, - 15267, 15268, 15269, 15270, 15271, 15272, 15273, 15274, 15275, 15276, - 15277, 15278, 15279, 15280, 15281, 15282, 15283, 15284, 15285, 15286, - 15287, 15288, 15289, 15290, 15291, 15292, 15293, 15294, 15295, 15296, - 15297, 15298, 15299, 15300, 15301, 15302, 15303, 15304, 15305, 15306, - 15307, 15308, 15309, 15310, 15311, 15312, 15313, 15314, 15315, 15316, - 15317, 15318, 15319, 15320, 15321, 15322, 15323, 15324, 15325, 15326, - 15327, 15328, 15329, 15330, 15331, 15332, 15333, 15334, 15335, 15336, - 15337, 15338, 15339, 15340, 15341, 15342, 15343, 15344, 15345, 15346, - 15347, 15348, 15349, 15350, 15351, 15352, 15353, 15354, 15355, 15356, - 15357, 15358, 15359, 15360, 15361, 15362, 15363, 15364, 15365, 15366, - 15367, 15368, 15369, 15370, 15371, 15372, 15373, 15374, 15375, 15376, - 15377, 15378, 15379, 15380, 15381, 15382, 15383, 15384, 15385, 15386, - 15387, 15388, 15389, 15390, 15391, 15392, 15393, 15394, 15395, 15396, - 15397, 15398, 15399, 15400, 15401, 15402, 15403, 15404, 15405, 15406, - 15407, 15408, 15409, 15410, 15411, 15412, 15413, 15414, 15415, 15416, - 15417, 15418, 15419, 15420, 15421, 15422, 15423, 15424, 15425, 15426, - 15427, 15428, 15429, 15430, 15431, 15432, 15433, 15434, 15435, 15436, - 15437, 15438, 15439, 15440, 15441, 15442, 15443, 15444, 15445, 15446, - 15447, 15448, 15449, 15450, 15451, 15452, 15453, 15454, 15455, 15456, - 15457, 15458, 15459, 15460, 15461, 15462, 15463, 15464, 15465, 15466, - 15467, 15468, 15469, 15470, 15471, 15472, 15473, 15474, 15475, 15476, - 15477, 15478, 15479, 15480, 15481, 15482, 15483, 15484, 15485, 15486, - 15487, 15488, 15489, 15490, 15491, 15492, 15493, 15494, 15495, 15496, - 15497, 15498, 15499, 15500, 15501, 15502, 15503, 15504, 15505, 15506, - 15507, 15508, 15509, 15510, 15511, 15512, 15513, 15514, 15515, 15516, - 15517, 15518, 15519, 15520, 15521, 15522, 15523, 15524, 15525, 15526, - 15527, 15528, 15529, 15530, 15531, 15532, 15533, 15534, 15535, 15536, - 15537, 15538, 15539, 15540, 15541, 15542, 15543, 15544, 15545, 15546, - 15547, 15548, 15549, 15550, 15551, 15552, 15553, 15554, 15555, 15556, - 15557, 15558, 15559, 15560, 15561, 15562, 15563, 15564, 15565, 15566, - 15567, 15568, 15569, 15570, 15571, 15572, 15573, 15574, 15575, 15576, - 15577, 15578, 15579, 15580, 15581, 15582, 15583, 15584, 15585, 15586, - 15587, 15588, 15589, 15590, 15591, 15592, 15593, 15594, 15595, 15596, - 15597, 15598, 15599, 15600, 15601, 15602, 15603, 15604, 15605, 15606, - 15607, 15608, 15609, 15610, 15611, 15612, 15613, 15614, 15615, 15616, - 15617, 15618, 15619, 15620, 15621, 15622, 15623, 15624, 15625, 15626, - 15627, 15628, 15629, 15630, 15631, 15632, 15633, 15634, 15635, 15636, - 15637, 15638, 15639, 15640, 15641, 15642, 15643, 15644, 15645, 15646, - 15647, 15648, 15649, 15650, 15651, 15652, 15653, 15654, 15655, 15656, - 15657, 15658, 15659, 15660, 15661, 15662, 15663, 15664, 15665, 15666, - 15667, 15668, 15669, 15670, 15671, 15672, 15673, 15674, 15675, 15676, - 15677, 15678, 15679, 15680, 15681, 15682, 15683, 15684, 15685, 15686, - 15687, 15688, 15689, 15690, 15691, 15692, 15693, 15694, 15695, 15696, - 15697, 15698, 15699, 15700, 15701, 15702, 15703, 15704, 15705, 15706, - 15707, 15708, 15709, 15710, 15711, 15712, 15713, 15714, 15715, 15716, - 15717, 15718, 15719, 15720, 15721, 15722, 15723, 15724, 15725, 15726, - 15727, 15728, 15729, 15730, 15731, 15732, 15733, 15734, 15735, 15736, - 15737, 15738, 15739, 15740, 15741, 15742, 15743, 15744, 15745, 15746, - 15747, 15748, 15749, 15750, 15751, 15752, 15753, 15754, 15755, 15756, - 15757, 15758, 15759, 15760, 15761, 16013, 16014, 16015, 16016, 16017, - 16018, 16019, 16020, 16021, 16022, 16023, 16024, 16025, 16026, 16027, - 16028, 16029, 16030, 16031, 16032, 16033, 16034, 16035, 16036, 16037, - 16038, 16039, 16040, 16041, 16042, 16043, 16044, 16045, 16046, 16047, - 16048, 16049, 16050, 16051, 16052, 16053, 16054, 16055, 16056, 16057, - 16058, 16059, 16060, 16061, 16062, 16063, 16064, 16065, 16066, 16067, - 16068, 16069, 16070, 16071, 16072, 16073, 16074, 16075, 16076, 16077, - 16078, 16079, 16080, 16081, 16082, 16083, 16084, 16085, 16086, 16087, - 16088, 16089, 16090, 16091, 16092, 16093, 16094, 16095, 16096, 16097, - 16098, 16099, 16100, 16101, 16102, 16103, 16104, 16105, 16106, 16107, - 16108, 16109, 16110, 16111, 16112, 16113, 16114, 16115, 16116, 16117, - 16118, 16119, 16120, 16121, 16122, 16123, 16124, 16125, 16126, 16127, - 16128, 16129, 16130, 16131, 16132, 16133, 16134, 16135, 16136, 16137, - 16138, 16139, 16140, 16141, 16142, 16143, 16144, 16145, 16146, 16147, - 16148, 16149, 16150, 16151, 16152, 16153, 16154, 16155, 16156, 16157, - 16158, 16159, 16160, 16161, 16162, 16163, 16164, 16165, 16166, 16167, - 16168, 16169, 16170, 16171, 16172, 16173, 16174, 16175, 16176, 16177, - 16178, 16179, 16180, 16181, 16182, 16183, 16184, 16185, 16186, 16187, - 16188, 16189, 16190, 16191, 16192, 16193, 16194, 16195, 16196, 16197, - 16198, 16199, 16200, 16201, 16202, 16203, 16204, 16205, 16206, 16207, - 16208, 16209, 16210, 16211, 16212, 16213, 16214, 16215, 16216, 16217, - 16218, 16219, 16220, 16221, 16222, 16223, 16224, 16225, 16226, 16227, - 16228, 16229, 16230, 16231, 16232, 16233, 16234, 16235, 16236, 16237, - 16238, 16239, 16240, 16241, 16242, 16243, 16244, 16245, 16246, 16247, - 16248, 16249, 16250, 16251, 16252, 16253, 16254, 16255, 16256, 16257, - 16258, 16259, 16260, 16261, 16262, 16263, 16264, 16265, 16266, 16267, - 16268, 16269, 16270, 16271, 16272, 16273, 16274, 16275, 16276, 16277, - 16278, 16279, 16280, 16281, 16282, 16283, 16284, 16285, 16286, 16287, - 16288, 16289, 16290, 16291, 16292, 16293, 16294, 16295, 16296, 16297, - 16298, 16299, 16300, 16301, 16302, 16303, 16304, 16305, 16306, 16307, - 16308, 16309, 16310, 16311, 16312, 16313, 16314, 16315, 16316, 16317, - 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, - 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, - 16338, 16339, 16340, 16341, 16342, 16343, 16344, 16345, 16346, 16347, - 16348, 16349, 16350, 16351, 16352, 16353, 16354, 16355, 16356, 16357, - 16358, 16359, 16360, 16361, 16362, 16363, 16364, 16365, 16366, 16367, - 16368, 16369, 16370, 16371, 16372, 16373, 16374, 16375, 16376, 16377, - 16378, 16379, 16380, 16381, 16382, 16383, 16384, 16385, 16386, 16387, - 16388, 16389, 16390, 16391, 16392, 16393, 16394, 16395, 16396, 16397, - 16398, 16399, 16400, 16401, 16402, 16403, 16404, 16405, 16406, 16407, - 16408, 16409, 16410, 16411, 16412, 16413, 16414, 16415, 16416, 16417, - 16418, 16419, 16420, 16421, 16422, 16423, 16424, 16425, 16426, 16427, - 16428, 16429, 16430, 16431, 16432, 16433, 16434, 16435, 16436, 16437, - 16438, 16439, 16440, 16441, 16442, 16443, 16444, 16445, 16446, 16447, - 16448, 16449, 16450, 16451, 16452, 16453, 16454, 16455, 16456, 16457, - 16458, 16459, 16460, 16461, 16462, 16463, 16464, 16465, 16466, 16467, - 16468, 16469, 16470, 16471, 16472, 16473, 16474, 16475, 16476, 16477, - 16478, 16479, 16480, 16481, 16482, 16483, 16484, 16485, 16486, 16487, - 16488, 16489, 16490, 16491, 16492, 16493, 16494, 16495, 16496, 16497, - 16498, 16499, 16500, 16501, 16502, 16503, 16504, 16505, 16506, 16507, - 16508, 16509, 16510, 16511, 16512, 16513, 16514, 16515, 16516, 16517, - 16518, 16519, 16520, 16521, 16522, 16523, 16524, 16525, 16526, 16527, - 16528, 16529, 16530, 16531, 16532, 16533, 16534, 16535, 16536, 16537, - 16538, 16539, 16540, 16541, 16542, 16543, 16544, 16545, 16546, 16547, - 16548, 16549, 16550, 16551, 16552, 16553, 16554, 16555, 16556, 16557, - 16558, 16559, 16560, 16561, 16562, 16563, 16564, 16565, 16566, 16567, - 16568, 16569, 16570, 16571, 16572, 16573, 16574, 16575, 16576, 16577, - 16578, 16579, 16580, 16581, 16582, 16583, 16584, 16585, 16586, 16587, - 16588, 16589, 16590, 16591, 16592, 16593, 16594, 16595, 16596, 16597, - 16598, 16599, 16600, 16601, 16602, 16603, 16604, 16605, 16606, 16607, - 16608, 16609, 16610, 16611, 16612, 16613, 16614, 16615, 16616, 16617, - 16618, 16619, 16620, 16621, 16622, 16623, 16624, 16625, 16626, 16627, - 16628, 16629, 16630, 16631, 16632, 16633, 16634, 16635, 16636, 16637, - 16638, 16639, 16640, 16641, 16642, 16643, 16644, 16645, 16646, 16647, - 16648, 16649, 16650, 16651, 16652, 16653, 16654, 16655, 16656, 16657, - 16658, 16659, 16660, 16661, 16662, 16663, 16664, 16665, 16666, 16667, - 16668, 16669, 16670, 16671, 16672, 16673, 16674, 16675, 16676, 16677, - 16678, 16679, 16680, 16681, 16682, 16683, 16684, 16685, 16686, 16687, - 16688, 16689, 16690, 16691, 16692, 16693, 16694, 16695, 16696, 16697, - 16698, 16699, 16700, 16701, 16702, 16703, 16704, 16705, 16706, 16707, - 16708, 16709, 16710, 16711, 16712, 16713, 16714, 16715, 16716, 16717, - 16718, 16719, 16720, 16721, 16722, 16723, 16724, 16725, 16726, 16727, - 16728, 16729, 16730, 16731, 16732, 16733, 16734, 16735, 16736, 16737, - 16738, 16739, 16740, 16741, 16742, 16743, 16744, 16745, 16746, 16747, - 16748, 16749, 16750, 16751, 16752, 16753, 16754, 16755, 16756, 16757, - 16758, 16759, 16760, 16761, 16762, 16763, 16764, 16765, 16766, 16767, - 16768, 16769, 16770, 16771, 16772, 16773, 16774, 16775, 16776, 16777, - 16778, 16779, 16780, 15773, 15774, 15775, 15776, 15777, 15778, 15779, - 15780, 15781, 15782, 15783, 15784, 15785, 15786, 15787, 15788, 15789, - 15790, 15791, 15792, 15793, 15794, 15795, 15796, 15797, 15798, 15799, - 15800, 15801, 15802, 15803, 15804, 15805, 15806, 15807, 15808, 15809, - 15810, 15811, 15812, 15813, 15814, 15815, 15816, 15817, 15818, 15819, - 15820, 15821, 15822, 15823, 15824, 15825, 15826, 15827, 15828, 15829, - 15830, 15831, 15832, 15833, 15834, 15835, 15836, 15837, 15838, 15839, - 15840, 15841, 15842, 15843, 15844, 15845, 15846, 15847, 15848, 15849, - 15850, 15851, 15852, 15853, 15854, 15855, 15856, 15857, 15858, 15859, - 15860, 15861, 15862, 15863, 15864, 15865, 15866, 15867, 15868, 15869, - 15870, 15871, 15872, 15873, 15874, 15875, 15876, 15877, 15878, 15879, - 15880, 15881, 15882, 15883, 15884, 15885, 15886, 15887, 15888, 15889, - 15890, 15891, 15892, 15893, 15894, 15895, 15896, 15897, 15898, 15899, - 15900, 15901, 15902, 15903, 15904, 15905, 15906, 15907, 15908, 15909, - 15910, 15911, 15912, 15913, 15914, 15915, 15916, 15917, 15918, 15919, - 15920, 15921, 15922, 15923, 15924, 15925, 15926, 15927, 15928, 15929, - 15930, 15931, 15932, 15933, 15934, 15935, 15936, 15937, 15938, 15939, - 15940, 15941, 15942, 15943, 15944, 15945, 15946, 15947, 15948, 15949, - 15950, 15951, 15952, 15953, 15954, 15955, 15956, 15957, 15958, 15959, - 15960, 15961, 15962, 15963, 15964, 15965, 15966, 15967, 15968, 15969, - 15970, 15971, 15972, 15973, 15974, 15975, 15976, 15977, 15978, 15979, - 15980, 15981, 15982, 15983, 15984, 15985, 15986, 15987, 15988, 15989, - 15990, 15991, 15992, 15993, 15994, 15995, 15996, 15997, 15998, 15999, - 16000, 16001, 16002, 16003, 16004, 16005, 16006, 16007, 16008, 16009, - 16010, 16011, 16012, 15762, 15763, 15764, 15765, 15766, 15767, 15768, - 15769, 15770, 15771, 15772, 41412, 41412, 41412, 41412, 41412, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 377, 378, 379, 380, 381, 382, 375, 376, 383, 384, - 385, 427, 428, 429, 430, 431, 432, 433, 434, 435, 425, 426, 393, 389, - 390, 394, 395, 396, 391, 392, 386, 387, 388, 397, 398, 399, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 404, 405, 406, 407, 408, 409, - 400, 401, 402, 403, 410, 411, 412, 466, 467, 468, 469, 470, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 417, - 418, 419, 420, 421, 422, 423, 413, 414, 415, 416, 424, 497, 498, 499, - 500, 501, 502, 503, 486, 487, 488, 489, 494, 495, 496, 504, 490, 491, - 492, 493, 505, 506, 507, 508, 509, 512, 513, 514, 515, 510, 511, 516, - 517, 518, 519, 522, 523, 524, 525, 526, 520, 521, 527, 528, 529, 530, - 533, 534, 535, 536, 537, 531, 532, 538, 539, 540, 541, 542, 543, 544, - 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, - 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, - 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, - 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, - 601, 609, 610, 602, 603, 604, 611, 612, 613, 614, 605, 606, 615, 607, - 608, 620, 621, 622, 623, 624, 616, 617, 618, 619, 625, 626, 627, 653, - 654, 655, 656, 657, 658, 659, 651, 652, 660, 661, 673, 674, 675, 676, - 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 664, 665, - 666, 667, 668, 669, 670, 662, 663, 671, 672, 703, 704, 705, 706, 707, - 708, 709, 710, 711, 712, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 640, 641, 632, 633, 634, 635, 628, 629, 636, 637, 638, 639, 630, 631, - 715, 716, 717, 718, 719, 720, 721, 722, 723, 713, 714, 807, 808, 809, - 810, 811, 812, 813, 814, 815, 816, 726, 727, 728, 729, 730, 731, 732, - 733, 734, 724, 725, 753, 754, 750, 751, 752, 755, 756, 757, 746, 747, - 748, 749, 758, 759, 760, 817, 818, 819, 820, 821, 822, 823, 824, 825, - 826, 737, 738, 739, 740, 741, 742, 743, 744, 745, 735, 736, 765, 766, - 767, 768, 761, 762, 769, 770, 771, 763, 764, 772, 798, 796, 797, 799, - 800, 801, 802, 803, 804, 805, 806, 779, 775, 776, 780, 773, 774, 781, - 782, 777, 778, 783, 784, 785, 787, 788, 789, 786, 790, 791, 792, 793, - 794, 795, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 827, 828, - 829, 830, 831, 832, 833, 834, 835, 836, 837, 868, 869, 870, 871, 872, - 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, - 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 838, 839, 842, - 843, 844, 845, 846, 847, 840, 841, 848, 849, 898, 899, 900, 901, 902, - 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, - 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 850, 851, 852, - 853, 854, 855, 856, 857, 929, 930, 931, 932, 933, 934, 935, 936, 937, - 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, - 952, 953, 954, 955, 956, 957, 928, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 19107, 19097, 19096, 19093, 19092, 19078, 19091, 19090, 19095, 19094, - 19100, 19085, 19084, 19081, 19080, 19105, 19087, 19086, 19083, 19082, - 19079, 19099, 19098, 19089, 19088, 19102, 19106, 19103, 19101, 19104, - 19110, 19117, 19118, 19113, 19114, 19119, 19120, 19111, 19115, 19116, - 19112, 19121, 19077, 19076, 19074, 19108, 19075, 19109, 19128, 19130, - 19127, 19126, 19123, 19122, 19125, 19124, 19131, 19129, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 2892, 2858, 2917, 2918, 2888, - 2925, 2936, 2907, 2924, 2919, 2920, 2871, 2937, 2894, 2873, 2878, 2885, - 2931, 2903, 2861, 2897, 2932, 2893, 2868, 2869, 2901, 2875, 2916, 2857, - 2915, 2884, 2908, 2939, 2856, 2902, 2933, 2887, 2886, 2882, 2859, 2914, - 2891, 2921, 2874, 2911, 2922, 2938, 2866, 2928, 2935, 2876, 2862, 2890, - 2864, 2883, 2926, 2867, 2941, 2943, 2863, 2929, 2879, 2923, 2900, 2927, - 2905, 2912, 2896, 2940, 2895, 2877, 2909, 2880, 2906, 2934, 2930, 2913, - 2898, 2870, 2904, 2860, 2899, 2942, 2865, 2910, 2889, 2881, 2976, 2993, - 2991, 2990, 2954, 2960, 2949, 2997, 2959, 2951, 2984, 2996, 2953, 2980, - 2981, 2944, 2986, 2994, 2988, 2989, 2966, 2963, 2979, 2947, 2945, 2946, - 2952, 2985, 3001, 2974, 2971, 2998, 2987, 2995, 2965, 2969, 2970, 2967, - 2992, 2962, 2968, 2978, 2983, 2964, 2999, 2961, 3000, 2948, 2958, 2957, - 2955, 2972, 2977, 2956, 2950, 2975, 3053, 3073, 3095, 3091, 3052, 3041, - 3054, 3002, 3030, 3004, 3074, 3070, 3027, 3075, 3045, 3024, 3007, 3003, - 3009, 3094, 3072, 3035, 3065, 3033, 3096, 3014, 3015, 3079, 3046, 3084, - 3061, 3088, 3083, 3048, 3090, 3039, 3021, 3071, 3049, 3017, 3032, 3037, - 3068, 3085, 3051, 3099, 3042, 3067, 3064, 3098, 3089, 3029, 3100, 3057, - 3016, 3087, 3062, 3059, 3011, 3047, 3023, 3034, 3019, 3013, 3058, 3056, - 3092, 3050, 3066, 3069, 3012, 3063, 3043, 3020, 3097, 3044, 3081, 3078, - 3031, 3022, 3026, 3008, 3028, 3010, 3025, 3093, 3060, 3038, 3036, 3082, - 3006, 3005, 3055, 3040, 3018, 3076, 3077, 3086, 3128, 3212, 3161, 3135, - 3162, 3121, 3160, 3166, 3148, 3175, 3211, 3157, 3191, 3158, 3105, 3204, - 3189, 3164, 3196, 3109, 3213, 3111, 3198, 3133, 3143, 3124, 3130, 3200, - 3217, 3159, 3106, 3154, 3206, 3104, 3156, 3101, 3144, 3138, 3116, 3145, - 3140, 3139, 3181, 3137, 3134, 3122, 3167, 3126, 3114, 3173, 3202, 3201, - 3214, 3107, 3188, 3205, 3153, 3132, 3168, 3108, 3184, 3179, 3174, 3119, - 3147, 3136, 3151, 3215, 3183, 3216, 3146, 3170, 3195, 3112, 3150, 3155, - 3207, 3129, 3113, 3169, 3203, 3125, 3149, 3117, 3152, 3165, 3163, 3103, - 3110, 3185, 3209, 3208, 3176, 3187, 3118, 3131, 3123, 3197, 3142, 3193, - 3190, 3115, 3178, 3194, 3171, 3180, 3177, 3192, 3182, 3141, 3120, 3186, - 3210, 3172, 3127, 3199, 3102, 3271, 3349, 3258, 3245, 3356, 3248, 3312, - 3338, 3328, 3298, 3274, 3323, 3343, 3284, 3238, 3359, 3331, 3276, 3313, - 3348, 3240, 3250, 3300, 3290, 3255, 3287, 3291, 3299, 3330, 3297, 3316, - 3339, 3279, 3262, 3232, 3286, 3294, 3256, 3249, 3277, 3273, 3340, 3332, - 3326, 3270, 3278, 3364, 3231, 3353, 3360, 3320, 3352, 3235, 3337, 3346, - 3354, 3357, 3244, 3322, 3342, 3229, 3292, 3333, 3261, 3259, 3305, 3309, - 3228, 3351, 3239, 3372, 3303, 3365, 3260, 3272, 3318, 3368, 3247, 3221, - 3227, 3289, 3237, 3254, 3285, 3233, 3223, 3301, 3314, 3362, 3275, 3304, - 3306, 3321, 3264, 3222, 3308, 3265, 3230, 3220, 3268, 3324, 3288, 3241, - 3319, 3302, 3361, 3280, 3310, 3219, 3226, 3295, 3373, 3350, 3375, 3374, - 3246, 3311, 3341, 3344, 3269, 3336, 3363, 3282, 3369, 3366, 3367, 3371, - 3370, 3236, 3315, 3296, 3325, 3358, 3225, 3355, 3252, 3263, 3329, 3327, - 3283, 3293, 3334, 3335, 3218, 3307, 3317, 3251, 3243, 3266, 3253, 3257, - 3345, 3242, 3267, 3347, 3224, 3234, 3380, 3429, 3382, 3427, 3407, 3420, - 3401, 3384, 3410, 3409, 3389, 3419, 3399, 3395, 3386, 3417, 3412, 3418, - 3415, 3378, 3377, 3397, 3396, 3394, 3422, 3414, 3423, 3398, 3403, 3400, - 3424, 3404, 3411, 3402, 3406, 3376, 3392, 3393, 3413, 3405, 3428, 3425, - 3385, 3383, 3381, 3387, 3408, 3390, 3391, 3388, 3421, 3379, 3416, 3426, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 28399, 28391, 28412, - 28389, 28413, 28400, 28415, 28395, 28386, 28403, 28401, 28409, 28385, - 28393, 28388, 28390, 28396, 28394, 28392, 28405, 28406, 28397, 28411, - 28414, 28410, 28387, 28408, 28407, 28402, 28404, 28398, 41412, 28424, - 28426, 28423, 28422, 28419, 28418, 28421, 28420, 28427, 28425, 41412, - 41412, 41412, 41412, 28417, 28416, 36122, 36119, 36120, 36121, 36074, - 36071, 36072, 36073, 36126, 36123, 36124, 36125, 36114, 36111, 36112, - 36113, 36118, 36115, 36116, 36117, 36110, 36107, 36108, 36109, 36070, - 36067, 36068, 36069, 36102, 36099, 36100, 36101, 36075, 36080, 36091, - 36092, 36103, 36106, 36104, 36105, 36098, 36095, 36096, 36097, 36086, - 36083, 36084, 36085, 36137, 36136, 36135, 36087, 36094, 36144, 36142, - 36139, 36089, 36138, 36140, 36082, 36090, 36079, 36081, 36078, 36129, - 36133, 36141, 36088, 36093, 36131, 36128, 36134, 36077, 36127, 36143, - 36076, 36132, 36130, 36145, 41412, 36152, 36154, 36151, 36150, 36147, - 36146, 36149, 36148, 36155, 36153, 41412, 41412, 41412, 41412, 41412, - 41412, 3490, 3495, 3511, 3513, 3503, 3501, 3493, 3487, 3494, 3507, 3502, - 3498, 3509, 3492, 3488, 3510, 3497, 3508, 3512, 3506, 3500, 3514, 3499, - 3515, 3504, 3505, 3496, 3491, 3489, 3516, 41412, 41412, 3483, 3485, 3486, - 3484, 3482, 3517, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 31177, 31178, 31183, 31184, 31171, 31172, 31187, 31188, - 31179, 31180, 31169, 31170, 31189, 31190, 31173, 31174, 31185, 31186, - 31191, 31192, 31181, 31182, 31175, 31176, 31193, 31194, 31167, 31168, - 31113, 31104, 31110, 31101, 31106, 31112, 31105, 31109, 31115, 31099, - 31111, 31097, 31102, 31100, 31108, 31103, 31107, 31116, 31114, 31098, - 31121, 31120, 31118, 31117, 31119, 31123, 31122, 31153, 31154, 31132, - 31152, 31150, 31158, 31160, 31159, 31161, 31151, 31143, 31156, 31141, - 31163, 31136, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 31201, 31203, 31200, 31199, 31196, 31195, 31198, 31197, - 31204, 31202, 41412, 31128, 31125, 31127, 31130, 31124, 31126, 31129, - 41412, 31155, 31162, 31140, 31148, 31164, 31139, 31146, 31157, 31145, - 31166, 31147, 31142, 31149, 31165, 31144, 31138, 31131, 31134, 31135, - 31137, 31133, 41412, 41412, 41412, 41412, 41412, 31085, 31092, 31084, - 31083, 31093, 31081, 31078, 31096, 31088, 31086, 31094, 31080, 31079, - 31089, 31095, 31091, 31087, 31082, 31090, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 22688, 22685, 22690, 22684, 22673, 22672, 22669, 22668, - 22661, 22667, 22666, 22671, 22670, 22662, 22658, 22657, 22654, 22653, - 22660, 22659, 22656, 22655, 22663, 22675, 22674, 22665, 22664, 22680, - 22683, 22681, 22679, 22682, 22677, 22676, 22678, 22691, 22697, 22694, - 22695, 22696, 22692, 22698, 22693, 22689, 22687, 22686, 22700, 22699, - 22707, 22709, 22706, 22705, 22702, 22701, 22704, 22703, 22710, 22708, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 27062, 27066, - 27069, 27070, 27040, 27072, 27048, 27063, 27067, 27058, 27057, 27059, - 27047, 27039, 27060, 27056, 27053, 27054, 27068, 27050, 27061, 27064, - 27046, 27044, 27071, 27055, 27052, 27042, 27065, 27051, 27041, 27049, - 27120, 27124, 27127, 27128, 27098, 27130, 27106, 27121, 27125, 27116, - 27115, 27117, 27105, 27097, 27118, 27114, 27111, 27112, 27126, 27108, - 27119, 27122, 27104, 27102, 27129, 27113, 27110, 27100, 27123, 27109, - 27099, 27107, 27084, 27078, 27076, 27074, 27081, 27080, 27083, 27082, - 27086, 27085, 27089, 27091, 27088, 27087, 27092, 27093, 27095, 27096, - 27090, 27094, 27079, 27077, 27075, 27073, 27133, 27131, 27132, 41412, - 41412, 41412, 41412, 41412, 3702, 3719, 3704, 3708, 3721, 3709, 3716, - 3726, 3705, 3717, 3722, 3715, 3711, 3710, 3712, 3723, 3724, 3706, 3707, - 3714, 3713, 3718, 3725, 3720, 3703, 41412, 41412, 3727, 3744, 3729, 3733, - 3746, 3734, 3741, 3751, 3730, 3742, 3747, 3740, 3736, 3735, 3737, 3748, - 3749, 3731, 3732, 3739, 3738, 3743, 3750, 3745, 3728, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 27681, 27607, 27669, 27680, 27685, 27684, 27604, 27686, - 27661, 27660, 27658, 27615, 27664, 27665, 27657, 27614, 27623, 27631, - 27667, 27603, 27628, 27627, 27622, 27621, 27620, 27619, 27645, 27613, - 27644, 27612, 27687, 27618, 27668, 27679, 27678, 27626, 27625, 27602, - 27683, 27689, 27617, 27616, 27654, 27610, 27630, 27629, 27653, 27609, - 27662, 27666, 27638, 27641, 27642, 27676, 27674, 27655, 27611, 27663, - 27643, 27677, 27675, 27673, 27671, 27601, 27672, 27670, 27688, 27605, - 27682, 27606, 27640, 27608, 27659, 27656, 27639, 41412, 41412, 41412, - 41412, 27693, 27624, 27692, 27691, 27690, 27698, 27704, 27703, 27699, - 27700, 27725, 27729, 27746, 27745, 27707, 27710, 27711, 27727, 27714, - 27715, 27716, 27717, 27718, 27721, 27723, 27724, 27720, 27731, 27732, - 27733, 27734, 27739, 27735, 27736, 27740, 27742, 27701, 27702, 27709, - 27744, 27708, 27743, 27705, 27713, 27706, 27730, 27747, 27748, 27737, - 27741, 27728, 27726, 27749, 27722, 27712, 27719, 27738, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 27697, 27695, 27696, 27694, 27646, - 27647, 27648, 27649, 27650, 27651, 27652, 27632, 27633, 27634, 27635, - 27636, 27637, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 37039, 30032, 30253, 30252, - 22331, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 39333, 39332, 6583, 6584, 39854, 39855, 39856, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 36156, 36157, - 36158, 36159, 36160, 36161, 36162, 36163, 36164, 36165, 36166, 36167, - 36168, 36169, 36170, 36171, 36172, 36173, 36174, 36175, 36176, 36177, - 36178, 36179, 36180, 36181, 36182, 36183, 36184, 36185, 36186, 36187, - 36188, 36189, 36190, 36191, 36192, 36193, 36194, 36195, 36196, 36197, - 36198, 36199, 36200, 36201, 36202, 36203, 36204, 36205, 36206, 36207, - 36208, 36209, 36210, 36211, 36212, 36213, 36214, 36215, 36216, 36217, - 36218, 36219, 36220, 36221, 36222, 36223, 36224, 36225, 36226, 36227, - 36228, 36229, 36230, 36231, 36232, 36233, 36234, 36235, 36236, 36237, - 36238, 36239, 36240, 36241, 36242, 36243, 36244, 36245, 36246, 36247, - 36248, 36249, 36250, 36251, 36252, 36253, 36254, 36255, 36256, 36257, - 36258, 36259, 36260, 36261, 36262, 36263, 36264, 36265, 36266, 36267, - 36268, 36269, 36270, 36271, 36272, 36273, 36274, 36275, 36276, 36277, - 36278, 36279, 36280, 36281, 36282, 36283, 36284, 36285, 36286, 36287, - 36288, 36289, 36290, 36291, 36292, 36293, 36294, 36295, 36296, 36297, - 36298, 36299, 36300, 36301, 36302, 36303, 36304, 36305, 36306, 36307, - 36308, 36309, 36310, 36311, 36312, 36313, 36314, 36315, 36316, 36317, - 36318, 36319, 36320, 36321, 36322, 36323, 36324, 36325, 36326, 36327, - 36328, 36329, 36330, 36331, 36332, 36333, 36334, 36335, 36336, 36337, - 36338, 36339, 36340, 36341, 36342, 36343, 36344, 36345, 36346, 36347, - 36348, 36349, 36350, 36351, 36352, 36353, 36354, 36355, 36356, 36357, - 36358, 36359, 36360, 36361, 36362, 36363, 36364, 36365, 36366, 36367, - 36368, 36369, 36370, 36371, 36372, 36373, 36374, 36375, 36376, 36377, - 36378, 36379, 36380, 36381, 36382, 36383, 36384, 36385, 36386, 36387, - 36388, 36389, 36390, 36391, 36392, 36393, 36394, 36395, 36396, 36397, - 36398, 36399, 36400, 36401, 36402, 36403, 36404, 36405, 36406, 36407, - 36408, 36409, 36410, 36411, 36412, 36413, 36414, 36415, 36416, 36417, - 36418, 36419, 36420, 36421, 36422, 36423, 36424, 36425, 36426, 36427, - 36428, 36429, 36430, 36431, 36432, 36433, 36434, 36435, 36436, 36437, - 36438, 36439, 36440, 36441, 36442, 36443, 36444, 36445, 36446, 36447, - 36448, 36449, 36450, 36451, 36452, 36453, 36454, 36455, 36456, 36457, - 36458, 36459, 36460, 36461, 36462, 36463, 36464, 36465, 36466, 36467, - 36468, 36469, 36470, 36471, 36472, 36473, 36474, 36475, 36476, 36477, - 36478, 36479, 36480, 36481, 36482, 36483, 36484, 36485, 36486, 36487, - 36488, 36489, 36490, 36491, 36492, 36493, 36494, 36495, 36496, 36497, - 36498, 36499, 36500, 36501, 36502, 36503, 36504, 36505, 36506, 36507, - 36508, 36509, 36510, 36511, 36512, 36513, 36514, 36515, 36516, 36517, - 36518, 36519, 36520, 36521, 36522, 36523, 36524, 36525, 36526, 36527, - 36528, 36529, 36530, 36531, 36532, 36533, 36534, 36535, 36536, 36537, - 36538, 36539, 36540, 36541, 36542, 36543, 36544, 36545, 36546, 36547, - 36548, 36549, 36550, 36551, 36552, 36553, 36554, 36555, 36556, 36557, - 36558, 36559, 36560, 36561, 36562, 36563, 36564, 36565, 36566, 36567, - 36568, 36569, 36570, 36571, 36572, 36573, 36574, 36575, 36576, 36577, - 36578, 36579, 36580, 36581, 36582, 36583, 36584, 36585, 36586, 36587, - 36588, 36589, 36590, 36591, 36592, 36593, 36594, 36595, 36596, 36597, - 36598, 36599, 36600, 36601, 36602, 36603, 36604, 36605, 36606, 36607, - 36608, 36609, 36610, 36611, 36612, 36613, 36614, 36615, 36616, 36617, - 36618, 36619, 36620, 36621, 36622, 36623, 36624, 36625, 36626, 36627, - 36628, 36629, 36630, 36631, 36632, 36633, 36634, 36635, 36636, 36637, - 36638, 36639, 36640, 36641, 36642, 36643, 36644, 36645, 36646, 36647, - 36648, 36649, 36650, 36651, 36652, 36653, 36654, 36655, 36656, 36657, - 36658, 36659, 36660, 36661, 36662, 36663, 36664, 36665, 36666, 36667, - 36668, 36669, 36670, 36671, 36672, 36673, 36674, 36675, 36676, 36677, - 36678, 36679, 36680, 36681, 36682, 36683, 36684, 36685, 36686, 36687, - 36688, 36689, 36690, 36691, 36692, 36693, 36694, 36695, 36696, 36697, - 36698, 36699, 36700, 36701, 36702, 36703, 36704, 36705, 36706, 36707, - 36708, 36709, 36710, 36711, 36712, 36713, 36714, 36715, 36716, 36717, - 36718, 36719, 36720, 36721, 36722, 36723, 36724, 36725, 36726, 36727, - 36728, 36729, 36730, 36731, 36732, 36733, 36734, 36735, 36736, 36737, - 36738, 36739, 36740, 36741, 36742, 36743, 36744, 36745, 36746, 36747, - 36748, 36749, 36750, 36751, 36752, 36753, 36754, 36755, 36756, 36757, - 36758, 36759, 36760, 36761, 36762, 36763, 36764, 36765, 36766, 36767, - 36768, 36769, 36770, 36771, 36772, 36773, 36774, 36775, 36776, 36777, - 36778, 36779, 36780, 36781, 36782, 36783, 36784, 36785, 36786, 36787, - 36788, 36789, 36790, 36791, 36792, 36793, 36794, 36795, 36796, 36797, - 36798, 36799, 36800, 36801, 36802, 36803, 36804, 36805, 36806, 36807, - 36808, 36809, 36810, 36811, 36812, 36813, 36814, 36815, 36816, 36817, - 36818, 36819, 36820, 36821, 36822, 36823, 36824, 36825, 36826, 36827, - 36828, 36829, 36830, 36831, 36832, 36833, 36834, 36835, 36836, 36837, - 36838, 36839, 36840, 36841, 36842, 36843, 36844, 36845, 36846, 36847, - 36848, 36849, 36850, 36851, 36852, 36853, 36854, 36855, 36856, 36857, - 36858, 36859, 36860, 36861, 36862, 36863, 36864, 36865, 36866, 36867, - 36868, 36869, 36870, 36871, 36872, 36873, 36874, 36875, 36876, 36877, - 36878, 36879, 36880, 36881, 36882, 36883, 36884, 36885, 36886, 36887, - 36888, 36889, 36890, 36891, 36892, 36893, 36894, 36895, 36896, 36897, - 36898, 36899, 36900, 36901, 36902, 36903, 36904, 36905, 36906, 36907, - 36908, 36909, 36910, 36911, 36912, 36913, 36914, 36915, 36916, 36917, - 36918, 36919, 36920, 36921, 36922, 36923, 21860, 21861, 21862, 21863, - 21864, 21865, 21866, 21867, 21868, 21869, 21870, 21871, 21872, 21873, - 21874, 21875, 21876, 21877, 21878, 21879, 21880, 21881, 21882, 21883, - 21884, 21885, 21886, 21887, 21888, 21889, 21890, 21891, 21892, 21893, - 21894, 21895, 21896, 21897, 21898, 21899, 21900, 21901, 21902, 21903, - 21904, 21905, 21906, 21907, 21908, 21909, 21910, 21911, 21912, 21913, - 21914, 21915, 21916, 21917, 21918, 21919, 21920, 21921, 21922, 21923, - 21924, 21925, 21926, 21927, 21928, 21929, 21930, 21931, 21932, 21933, - 21934, 21935, 21936, 21937, 21938, 21939, 21940, 21941, 21942, 21943, - 21944, 21945, 21946, 21947, 21948, 21949, 21950, 21951, 21952, 21953, - 21954, 21955, 21956, 21957, 21958, 21959, 21960, 21961, 21962, 21963, - 21964, 21965, 21966, 21967, 21968, 21969, 21970, 21971, 21972, 21973, - 21974, 21975, 21976, 21977, 21978, 21979, 21980, 21981, 21982, 21983, - 21984, 21985, 21986, 21987, 21988, 21989, 21990, 21991, 21992, 21993, - 21994, 21995, 21996, 21997, 21998, 21999, 22000, 22001, 22002, 22003, - 22004, 22005, 22006, 22007, 22008, 22009, 22010, 22011, 22012, 22013, - 22014, 22015, 22016, 22017, 22018, 22019, 22020, 22021, 22022, 22023, - 22024, 22025, 22026, 22027, 22028, 22029, 22030, 22031, 22032, 22033, - 22034, 22035, 22036, 22037, 22038, 22039, 22040, 22041, 22042, 22043, - 22044, 22045, 22046, 22047, 22048, 22049, 22050, 22051, 22052, 22053, - 22054, 22055, 22056, 22057, 22058, 22059, 22060, 22061, 22062, 22063, - 22064, 22065, 22066, 22067, 22068, 22069, 22070, 22071, 22072, 22073, - 22074, 22075, 22076, 22077, 22078, 22079, 22080, 22081, 22082, 22083, - 22084, 22085, 22086, 22087, 22088, 22089, 22090, 22091, 22092, 22093, - 22094, 22095, 22096, 22097, 22098, 22099, 22100, 22101, 22102, 22103, - 22104, 22105, 22106, 22107, 22108, 22109, 22110, 22111, 22112, 22113, - 22114, 22115, 22122, 22123, 22124, 22125, 22126, 22127, 22128, 22129, - 22130, 22131, 22132, 22133, 22134, 22135, 22136, 22137, 22138, 22139, - 22140, 22141, 22142, 22143, 22144, 22145, 22146, 22147, 22148, 22149, - 22150, 22151, 22152, 22153, 22154, 22155, 22156, 22157, 22158, 22159, - 22160, 22161, 22162, 22163, 22164, 22165, 22166, 22167, 22168, 22169, - 22170, 22171, 22172, 22173, 22174, 22175, 22176, 22177, 22178, 22179, - 22180, 22181, 22182, 22183, 22184, 22185, 22186, 22187, 22188, 22189, - 22190, 22191, 22192, 22193, 22194, 22195, 22196, 22197, 22198, 22199, - 22200, 22201, 22202, 22203, 22204, 22205, 22206, 22207, 22208, 22209, - 22210, 22211, 22212, 22213, 22214, 22215, 22216, 22217, 22218, 22219, - 22220, 22221, 22222, 22223, 22224, 22225, 22226, 22227, 22228, 22229, - 22230, 22231, 22232, 22233, 22234, 22235, 22236, 22237, 22238, 22239, - 22240, 22241, 22242, 22243, 22244, 22245, 22246, 22247, 22248, 22249, - 22250, 22251, 22252, 22253, 22254, 22255, 22256, 22257, 22258, 22259, - 22260, 22261, 22262, 22263, 22264, 22265, 22266, 22267, 22268, 22269, - 22270, 22271, 22272, 22273, 22274, 22275, 22276, 22277, 22278, 22279, - 22280, 22281, 22282, 22283, 22284, 22285, 22286, 22287, 22288, 22289, - 22290, 22291, 22292, 22293, 22294, 22295, 22296, 22297, 22298, 22299, - 22300, 22301, 22302, 22303, 22304, 22305, 22306, 22307, 22308, 22309, - 22310, 22311, 22312, 22313, 22314, 22315, 22316, 22317, 22318, 22319, - 22320, 22321, 22322, 22323, 22324, 22325, 22326, 22327, 22328, 22329, - 22116, 22117, 22118, 22119, 22120, 22121, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 22330, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 36924, 36925, 36926, 36927, - 36928, 36929, 36930, 36931, 36932, 36933, 36934, 36935, 36936, 36937, - 36938, 36939, 36940, 36941, 36942, 36943, 36944, 36945, 36946, 36947, - 36948, 36949, 36950, 36951, 36952, 36953, 36954, 36955, 36956, 36957, - 36958, 36959, 36960, 36961, 36962, 36963, 36964, 36965, 36966, 36967, - 36968, 36969, 36970, 36971, 36972, 36973, 36974, 36975, 36976, 36977, - 36978, 36979, 36980, 36981, 36982, 36983, 36984, 36985, 36986, 36987, - 36988, 36989, 36990, 36991, 36992, 36993, 36994, 36995, 36996, 36997, - 36998, 36999, 37000, 37001, 37002, 37003, 37004, 37005, 37006, 37007, - 37008, 37009, 37010, 37011, 37012, 37013, 37014, 37015, 37016, 37017, - 37018, 37019, 37020, 37021, 37022, 37023, 37024, 37025, 37026, 37027, - 37028, 37029, 37030, 37031, 37032, 37033, 37034, 37035, 37036, 37037, - 37038, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 21499, 21500, 21501, 21502, 41412, 21503, - 21504, 21492, 21493, 21494, 21495, 21496, 41412, 21497, 21498, 41412, - 21480, 20452, 20091, 20092, 20093, 20090, 20372, 20373, 20374, 20375, - 20364, 20365, 20366, 20367, 20368, 20359, 20360, 20361, 20362, 20363, - 20369, 20370, 20371, 20130, 20134, 20135, 20136, 20137, 20138, 20139, - 20140, 20141, 20131, 20132, 20133, 20146, 20147, 20148, 20149, 20150, - 20151, 20152, 20153, 20160, 20161, 20162, 20163, 20164, 20165, 20166, - 20154, 20155, 20156, 20157, 20158, 20159, 20143, 20144, 20145, 20142, - 20255, 20256, 20257, 20258, 20259, 20260, 20261, 20262, 20271, 20272, - 20273, 20274, 20275, 20276, 20263, 20264, 20265, 20266, 20267, 20268, - 20269, 20270, 20277, 20278, 20279, 20280, 20281, 20282, 20283, 20284, - 20285, 20286, 20287, 20288, 20317, 20318, 20319, 20320, 20310, 20311, - 20312, 20313, 20314, 20315, 20316, 20306, 20307, 20308, 20309, 20305, - 20289, 20290, 20291, 20292, 20293, 20294, 20295, 20296, 20297, 20299, - 20300, 20301, 20302, 20303, 20304, 20298, 20209, 20210, 20211, 20212, - 20213, 20214, 20215, 20216, 20217, 20202, 20203, 20204, 20205, 20206, - 20207, 20208, 20201, 20223, 20224, 20225, 20195, 20196, 20197, 20198, - 20199, 20200, 20194, 20218, 20219, 20220, 20221, 20222, 20102, 20105, - 20106, 20107, 20108, 20109, 20110, 20111, 20112, 20103, 20104, 20123, - 20124, 20125, 20126, 20127, 20128, 20129, 20113, 20114, 20115, 20116, - 20117, 20118, 20119, 20120, 20121, 20122, 20094, 20095, 20096, 20097, - 20098, 20099, 20100, 20101, 20176, 20177, 20178, 20179, 20180, 20181, - 20182, 20183, 20184, 20185, 20186, 20187, 20188, 20189, 20190, 20191, - 20192, 20193, 20168, 20169, 20167, 20170, 20171, 20172, 20173, 20174, - 20175, 20343, 20344, 20345, 20346, 20347, 20342, 20354, 20355, 20356, - 20357, 20348, 20349, 20350, 20351, 20352, 20353, 20247, 20248, 20249, - 20250, 20240, 20241, 20242, 20243, 20244, 20245, 20246, 20234, 20235, - 20236, 20237, 20238, 20239, 20251, 20252, 20253, 20254, 20228, 20229, - 20230, 20231, 20232, 20233, 20321, 20322, 20323, 20324, 20325, 20326, - 20327, 20328, 20329, 20330, 20338, 20339, 20340, 20341, 20331, 20332, - 20333, 20334, 20335, 20336, 20337, 20226, 20227, 20451, 21478, 21477, - 21479, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 20462, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 20455, 20454, 20456, 41412, - 41412, 21527, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 21533, 21532, 21534, 21538, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 29636, 29637, - 29638, 29639, 29640, 29641, 29642, 29643, 29644, 29645, 29646, 29647, - 29648, 29649, 29650, 29651, 29652, 29653, 29654, 29655, 29656, 29657, - 29658, 29659, 29660, 29661, 29662, 29663, 29664, 29665, 29666, 29667, - 29668, 29669, 29670, 29671, 29672, 29673, 29674, 29675, 29676, 29677, - 29678, 29679, 29680, 29681, 29682, 29683, 29684, 29685, 29686, 29687, - 29688, 29689, 29690, 29691, 29692, 29693, 29694, 29695, 29696, 29697, - 29698, 29699, 29700, 29701, 29702, 29703, 29704, 29705, 29706, 29707, - 29708, 29709, 29710, 29711, 29712, 29713, 29714, 29715, 29716, 29717, - 29718, 29719, 29720, 29721, 29722, 29723, 29724, 29725, 29726, 29727, - 29728, 29729, 29730, 29731, 29732, 29733, 29734, 29735, 29736, 29737, - 29738, 29739, 29740, 29741, 29742, 29743, 29744, 29745, 29746, 29747, - 29748, 29749, 29750, 29751, 29752, 29753, 29754, 29755, 29756, 29757, - 29758, 29759, 29760, 29761, 29762, 29763, 29764, 29765, 29766, 29767, - 29768, 29769, 29770, 29771, 29772, 29773, 29774, 29775, 29776, 29777, - 29778, 29779, 29780, 29781, 29782, 29783, 29784, 29785, 29786, 29787, - 29788, 29789, 29790, 29791, 29792, 29793, 29794, 29795, 29796, 29797, - 29798, 29799, 29800, 29801, 29802, 29803, 29804, 29805, 29806, 29807, - 29808, 29809, 29810, 29811, 29812, 29813, 29814, 29815, 29816, 29817, - 29818, 29819, 29820, 29821, 29822, 29823, 29824, 29825, 29826, 29827, - 29828, 29829, 29830, 29831, 29832, 29833, 29834, 29835, 29836, 29837, - 29838, 29839, 29840, 29841, 29842, 29843, 29844, 29845, 29846, 29847, - 29848, 29849, 29850, 29851, 29852, 29853, 29854, 29855, 29856, 29857, - 29858, 29859, 29860, 29861, 29862, 29863, 29864, 29865, 29866, 29867, - 29868, 29869, 29870, 29871, 29872, 29873, 29874, 29875, 29876, 29877, - 29878, 29879, 29880, 29881, 29882, 29883, 29884, 29885, 29886, 29887, - 29888, 29889, 29890, 29891, 29892, 29893, 29894, 29895, 29896, 29897, - 29898, 29899, 29900, 29901, 29902, 29903, 29904, 29905, 29906, 29907, - 29908, 29909, 29910, 29911, 29912, 29913, 29914, 29915, 29916, 29917, - 29918, 29919, 29920, 29921, 29922, 29923, 29924, 29925, 29926, 29927, - 29928, 29929, 29930, 29931, 29932, 29933, 29934, 29935, 29936, 29937, - 29938, 29939, 29940, 29941, 29942, 29943, 29944, 29945, 29946, 29947, - 29948, 29949, 29950, 29951, 29952, 29953, 29954, 29955, 29956, 29957, - 29958, 29959, 29960, 29961, 29962, 29963, 29964, 29965, 29966, 29967, - 29968, 29969, 29970, 29971, 29972, 29973, 29974, 29975, 29976, 29977, - 29978, 29979, 29980, 29981, 29982, 29983, 29984, 29985, 29986, 29987, - 29988, 29989, 29990, 29991, 29992, 29993, 29994, 29995, 29996, 29997, - 29998, 29999, 30000, 30001, 30002, 30003, 30004, 30005, 30006, 30007, - 30008, 30009, 30010, 30011, 30012, 30013, 30014, 30015, 30016, 30017, - 30018, 30019, 30020, 30021, 30022, 30023, 30024, 30025, 30026, 30027, - 30028, 30029, 30030, 30031, 41412, 41412, 41412, 41412, 11649, 11647, - 11596, 11629, 11556, 11569, 11573, 11654, 11550, 11637, 11558, 11600, - 11599, 11551, 11557, 11571, 11603, 11632, 11625, 11552, 11572, 11626, - 11650, 11576, 11604, 11577, 11582, 11560, 11605, 11578, 11583, 11563, - 11606, 11580, 11585, 11561, 11562, 11614, 11615, 11581, 11586, 11567, - 11618, 11579, 11584, 11564, 11607, 11568, 11565, 11566, 11612, 11613, - 11610, 11611, 11631, 11630, 11639, 11645, 11642, 11617, 11616, 11570, - 11559, 11608, 11609, 11548, 11623, 11593, 11591, 11549, 11651, 11553, - 11652, 11628, 11636, 11554, 11620, 11601, 11619, 11574, 11653, 11633, - 11555, 11648, 11634, 11575, 11602, 11635, 11627, 11592, 11595, 11594, - 11644, 11640, 11646, 11643, 11641, 11590, 11589, 11588, 11587, 11598, - 11597, 11621, 11624, 11622, 11638, 41412, 41412, 41412, 41412, 41412, - 11533, 11546, 11545, 11540, 11547, 11527, 11520, 11519, 11516, 11518, - 11521, 11522, 11517, 41412, 41412, 41412, 11529, 11525, 11528, 11523, - 11532, 11531, 11524, 11530, 11526, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 11534, 11538, 11541, 11536, 11544, 11543, 11537, 11542, - 11539, 11535, 41412, 41412, 11658, 11655, 11656, 11657, 33036, 33035, - 33037, 33038, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 38247, 32227, 24339, 32224, 11423, 25347, - 32195, 25405, 967, 20587, 39302, 24297, 27756, 32180, 24332, 32217, - 30107, 31773, 31965, 20583, 39276, 25287, 25286, 25285, 25284, 25282, - 25283, 4587, 4588, 4596, 4610, 4480, 4479, 32766, 32774, 32767, 32778, - 32771, 32775, 32768, 32780, 32773, 32777, 32770, 32779, 32772, 32776, - 32769, 38286, 38254, 38256, 38341, 38303, 38299, 38335, 38305, 25431, - 25378, 25398, 25433, 25381, 25423, 25425, 25404, 34309, 34310, 30835, - 10972, 10708, 10707, 34321, 34322, 24345, 32204, 17621, 17622, 352, 351, - 358, 357, 360, 359, 355, 356, 353, 354, 24335, 38239, 32220, 11429, - 37913, 37909, 37917, 4442, 4440, 4446, 24328, 38234, 32214, 11425, 28480, - 24338, 38242, 32223, 11432, 16787, 16788, 3944, 3947, 3946, 3945, 3978, - 24351, 38232, 32210, 11435, 24352, 38233, 32211, 11436, 24341, 38236, - 32226, 11427, 34554, 34555, 34553, 34552, 34746, 34748, 34747, 34745, - 39286, 20566, 39699, 39700, 38159, 34386, 34385, 34384, 34339, 20962, - 24211, 20963, 39291, 20564, 24346, 32205, 24347, 32206, 17606, 24337, - 38241, 32222, 11431, 20586, 39301, 39279, 24340, 32225, 24334, 32219, - 24336, 32221, 24245, 32138, 38295, 38331, 38294, 38330, 25367, 25387, - 25366, 25386, 25364, 25384, 25365, 25385, 38298, 38334, 25377, 25397, - 38296, 38332, 25376, 25396, 38289, 38325, 25371, 25391, 38292, 38328, - 25374, 25394, 38293, 38329, 25375, 25395, 38288, 38324, 25370, 25390, - 38290, 38326, 25372, 25392, 38291, 38327, 25373, 25393, 38297, 38333, - 25368, 25388, 31013, 31014, 31015, 31016, 31017, 31018, 31019, 31020, - 31021, 31022, 31023, 31024, 31025, 31026, 31027, 31028, 31029, 31030, - 31031, 31032, 31033, 31034, 31035, 31036, 31037, 31038, 31049, 31051, - 31048, 31047, 31044, 31043, 31046, 31045, 31052, 31050, 34090, 17623, - 29621, 41412, 41412, 41412, 4239, 4183, 4054, 4269, 4140, 4081, 4240, - 4121, 4184, 4230, 4156, 4215, 4097, 4112, 4200, 4066, 4273, 4141, 4171, - 4082, 4241, 4122, 4185, 4055, 4236, 4164, 4223, 4105, 4262, 4118, 4208, - 4074, 4149, 4177, 4090, 4248, 4130, 4193, 4060, 4231, 4157, 4216, 4098, - 4255, 4113, 4201, 4067, 4274, 4142, 4172, 4083, 4242, 4123, 4186, 4168, - 4227, 4109, 4266, 4137, 4212, 4078, 4281, 4153, 4180, 4094, 4252, 4134, - 4197, 4063, 4161, 4220, 4102, 4259, 4205, 4071, 4278, 4146, 4087, 4245, - 4127, 4190, 4237, 4165, 4224, 4106, 4263, 4119, 4209, 4075, 4270, 4150, - 4178, 4091, 4249, 4131, 4194, 4061, 4232, 4158, 4217, 4099, 4256, 4114, - 4202, 4068, 4275, 4143, 4173, 4084, 4243, 4124, 4187, 4056, 4170, 4229, - 4111, 4268, 4139, 4214, 4080, 4283, 4155, 4182, 4096, 4254, 4136, 4199, - 4065, 4235, 4163, 4222, 4104, 4261, 4117, 4207, 4073, 4280, 4148, 4176, - 4089, 4247, 4129, 4192, 4059, 4167, 4226, 4108, 4265, 4211, 4077, 4272, - 4152, 4093, 4251, 4133, 4196, 4233, 4160, 4219, 4101, 4258, 4115, 4204, - 4070, 4277, 4145, 4174, 4086, 4244, 4126, 4189, 4057, 4169, 4228, 4110, - 4267, 4138, 4213, 4079, 4282, 4154, 4181, 4095, 4253, 4135, 4198, 4064, - 4234, 4162, 4221, 4103, 4260, 4116, 4206, 4072, 4279, 4147, 4175, 4088, - 4246, 4128, 4191, 4058, 4238, 4166, 4225, 4107, 4264, 4120, 4210, 4076, - 4271, 4151, 4179, 4092, 4250, 4132, 4195, 4062, 4159, 4218, 4100, 4257, - 4203, 4069, 4276, 4144, 4085, 4125, 4188, 37921, 4449, 37918, 4447, - 37919, 4448, 37914, 4443, 37915, 4444, 37908, 4436, 4437, 4438, 4439, - 28364, 37910, 37911, 11426, 24329, 34060, 38237, 11428, 17492, 17493, - 17494, 32133, 25338, 17495, 38261, 25340, 19942, 39761, 37932, 17779, - 4481, 4478, 24249, 32142, 24248, 32141, 20563, 24246, 32139, 20562, - 25341, 38264, 39292, 4606, 4604, 4605, 4603, 22883, 22882, 22887, 22881, - 22859, 22838, 22839, 22879, 22845, 22863, 22886, 22861, 22884, 22885, - 22867, 22864, 22844, 22843, 22846, 22862, 22847, 22835, 22856, 22880, - 22836, 22837, 22834, 22860, 22865, 22851, 22842, 22866, 22868, 22841, - 22858, 22850, 22848, 22849, 22840, 22888, 22857, 22852, 22855, 22853, - 22854, 22876, 22874, 22875, 22878, 22873, 22870, 22877, 22872, 22871, - 22869, 32781, 32813, 32782, 32829, 32798, 32814, 32783, 32837, 32806, - 32822, 32791, 32830, 32799, 32815, 32784, 32841, 32810, 32826, 32795, - 32834, 32803, 32819, 32788, 32838, 32807, 32823, 32792, 32831, 32800, - 32816, 32785, 32843, 32812, 32828, 32797, 32836, 32805, 32821, 32790, - 32840, 32809, 32825, 32794, 32833, 32802, 32818, 32787, 32842, 32811, - 32827, 32796, 32835, 32804, 32820, 32789, 32839, 32808, 32824, 32793, - 32832, 32801, 32817, 32786, 38281, 38253, 38255, 38320, 38302, 38300, - 38301, 38304, 25430, 25428, 25429, 25432, 25383, 25422, 25424, 25418, - 32143, 32183, 24300, 24250, 25343, 25438, 38344, 38266, 24251, 24301, - 32184, 32144, 38267, 38345, 25439, 25344, 20588, 21790, 30522, 3984, - 41412, 41412, 41412, 41412, 41412, 41412, 17659, 31062, 37993, 1057, - 6577, 34742, 20085, 20984, 17611, 27599, 31398, 39328, 16781, 20983, - 17487, 31902, 37387, 27244, 17637, 2574, 3597, 369, 24565, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 17878, 17875, 17867, 17873, 17879, 17865, 17871, - 17868, 17874, 17870, 17866, 17876, 17872, 17877, 17869, 17880, 27156, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41228, 41233, 41267, 41230, 41235, - 41263, 41257, 41251, 41274, 41253, 41247, 41271, 41229, 41234, 41268, - 41231, 41236, 41264, 41258, 41252, 41275, 41254, 41248, 41272, 41269, - 41255, 41262, 41249, 41250, 41273, 41256, 41232, 41278, 41243, 41260, - 41270, 41281, 41280, 41246, 41279, 41240, 41239, 41277, 41261, 41259, - 41238, 41412, 41412, 41283, 41284, 41285, 41276, 41226, 41241, 41244, - 41245, 41223, 41224, 41242, 41265, 41266, 41227, 41282, 41225, 41237, - 41222, 41404, 41405, 41402, 41403, 41406, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41302, 41303, 41319, 41291, 41300, - 41399, 41354, 41355, 41322, 41323, 41356, 41286, 41320, 41400, 41298, - 41295, 41297, 41296, 41294, 41396, 41395, 41398, 41397, 41392, 41391, - 41394, 41393, 41292, 41326, 41288, 41299, 41287, 41324, 41337, 41338, - 41336, 41335, 41289, 41333, 41334, 41332, 41330, 41331, 41329, 41328, - 41339, 41341, 41342, 41340, 41304, 41327, 41293, 41301, 41401, 41343, - 41348, 41345, 41349, 41346, 41351, 41352, 41347, 41344, 41350, 41325, - 41353, 41386, 41383, 41374, 41384, 41385, 41375, 41363, 41362, 41390, - 41360, 41359, 41357, 41361, 41358, 41377, 41382, 41376, 41380, 41381, - 41378, 41379, 41306, 41310, 41309, 41308, 41307, 41389, 41387, 41388, - 41313, 41318, 41317, 41316, 41315, 41314, 41364, 41373, 41366, 41371, - 41365, 41369, 41370, 41367, 41368, 41372, 41305, 41312, 41290, 41311, - 41321, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 5296, 5168, 5289, 5271, 5272, 5340, 5341, 5221, 5318, 5278, 5352, - 5353, 5244, 5123, 5174, 5321, 5222, 5126, 5127, 5316, 5328, 5267, 5204, - 5295, 5147, 5344, 5216, 5230, 5226, 5319, 5281, 5310, 5274, 5343, 5129, - 5131, 5231, 5297, 5282, 5339, 5121, 5299, 5313, 5315, 5269, 5323, 5251, - 5169, 5331, 5322, 5241, 5122, 5181, 5212, 5333, 5219, 5287, 5291, 5234, - 5145, 5298, 5276, 5279, 5218, 5356, 5286, 5235, 5334, 5311, 5210, 5217, - 5268, 5273, 5285, 5237, 5284, 5242, 5288, 5225, 5229, 5355, 5128, 5124, - 5354, 5243, 5177, 5148, 5266, 5342, 5283, 5292, 5275, 5120, 5252, 5280, - 5277, 5173, 5245, 5119, 5335, 5176, 5314, 5317, 5146, 5175, 5300, 5357, - 5337, 5293, 5332, 5336, 5290, 5338, 5294, 5207, 5133, 5172, 5270, 5325, - 5326, 5324, 5327, 5220, 5170, 5345, 5346, 5309, 5233, 5166, 5238, 5239, - 5240, 5130, 5132, 5165, 5330, 5320, 5236, 5246, 5250, 5249, 5248, 5247, - 5206, 5203, 5202, 5160, 5162, 5163, 5161, 5329, 5134, 5214, 5153, 5117, - 5111, 5112, 5115, 5116, 5114, 5113, 5118, 5259, 5254, 5255, 5253, 5264, - 5263, 5262, 5261, 5265, 5257, 5215, 5125, 5180, 5179, 5178, 5260, 5258, - 5256, 5208, 5209, 5171, 5213, 5211, 5182, 5189, 5185, 5193, 5188, 5197, - 5187, 5186, 5183, 5184, 5191, 5192, 5199, 5196, 5194, 5143, 5144, 5142, - 5190, 5198, 5351, 5156, 5154, 5157, 5159, 5158, 5155, 5347, 5349, 5348, - 5350, 5200, 5201, 5150, 5149, 5151, 5152, 5305, 5308, 5306, 5307, 5301, - 5304, 5302, 5303, 5164, 5167, 5312, 5141, 5135, 5140, 5138, 5137, 5136, - 5139, 5223, 5227, 5224, 5228, 5232, 5205, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 28669, 28546, 28562, 28654, - 28541, 28666, 28604, 28655, 28653, 28542, 28538, 28665, 28532, 28650, - 28651, 28652, 28557, 28558, 28495, 28496, 28491, 28490, 28621, 28692, - 28689, 28564, 28563, 28670, 28671, 28565, 28574, 28575, 28576, 28535, - 28567, 28568, 28569, 28548, 28549, 41412, 41412, 28612, 28545, 28547, - 28573, 28572, 28617, 28616, 28668, 28667, 28644, 28645, 28531, 28537, - 28633, 28634, 28648, 28649, 28613, 28715, 28587, 28647, 28556, 28673, - 28691, 28675, 28620, 28713, 28636, 28536, 28676, 28677, 28700, 28701, - 28704, 28705, 28702, 28703, 28696, 28697, 28698, 28699, 28610, 28611, - 28706, 28707, 28635, 28711, 28618, 28615, 28499, 28500, 28494, 28714, - 28586, 28646, 28555, 28672, 28690, 28674, 28619, 28520, 28521, 28524, - 28525, 28526, 28559, 28560, 28561, 28503, 28510, 28511, 28512, 28513, - 28514, 28488, 28553, 28489, 28554, 28487, 28551, 28486, 28550, 28501, - 28519, 28527, 28518, 28504, 28505, 28502, 28529, 28584, 28583, 28508, - 28530, 28515, 28522, 28528, 28507, 28523, 28656, 28679, 28718, 28643, - 28606, 28566, 28534, 28543, 28580, 28579, 28695, 28708, 28717, 28709, - 28710, 28622, 28625, 28626, 28627, 28628, 28629, 28630, 28631, 28632, - 28623, 28624, 28588, 28614, 28552, 28544, 28506, 28509, 28516, 28517, - 28638, 28637, 28585, 28578, 28577, 28716, 28539, 28540, 28605, 28601, - 28492, 28659, 28661, 28607, 28609, 28662, 28664, 28570, 28571, 28603, - 28602, 28493, 28660, 28608, 28663, 28687, 28686, 28688, 28685, 28681, - 28682, 28683, 28684, 28533, 28581, 28582, 28678, 28712, 28640, 28498, - 28657, 28497, 28693, 28641, 28642, 28658, 28694, 28639, 28589, 28592, - 28596, 28599, 28598, 28597, 28593, 28594, 28590, 28591, 28595, 28680, - 28600, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 18793, 18781, 18804, 18805, 18787, 18806, 18807, 18808, - 18809, 18794, 18795, 18796, 18797, 18798, 18799, 18800, 18801, 18802, - 18803, 18782, 18783, 18784, 18785, 18786, 18788, 18789, 18790, 18791, - 18792, 18513, 18521, 18534, 18542, 18548, 18549, 18514, 18515, 18516, - 18517, 18518, 18519, 18520, 18522, 18523, 18524, 18525, 18526, 18527, - 18528, 18529, 18530, 18531, 18532, 18533, 18535, 18536, 18537, 18538, - 18539, 18540, 18541, 18543, 18544, 18545, 18546, 18547, 8387, 8386, 8388, - 18573, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 21770, 21771, 21768, 21766, 21757, 21756, 21763, - 21761, 21752, 21759, 21769, 21754, 21767, 21765, 21758, 21755, 21764, - 21762, 21753, 21760, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 27020, 27021, 27018, 27016, 27007, - 27006, 27013, 27011, 27002, 27009, 27019, 27004, 27017, 27015, 27008, - 27005, 27014, 27012, 27003, 27010, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 28357, 11017, 11018, - 11012, 11011, 11010, 37181, 37201, 37222, 37170, 37215, 37179, 37165, - 37224, 37169, 37183, 37189, 37212, 37213, 37227, 37233, 37180, 37211, - 37241, 37199, 37166, 37229, 37231, 37198, 37244, 37178, 37193, 37190, - 37171, 37185, 37168, 37226, 37219, 37173, 37216, 37205, 37239, 37228, - 37202, 37230, 37218, 37232, 37207, 37195, 37238, 37208, 37194, 37225, - 37234, 37204, 37240, 37177, 37221, 37197, 37243, 37187, 37172, 37209, - 37206, 37220, 37164, 37192, 37191, 37242, 37236, 37214, 37184, 37182, - 37188, 37196, 37235, 37237, 37210, 37176, 37174, 37203, 37167, 37175, - 37223, 37186, 37217, 37200, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 8801, 8799, 8798, 8795, 8794, 8797, 8796, 8802, - 8800, 8792, 8790, 8789, 8786, 8785, 8788, 8787, 8793, 8791, 20675, 20674, - 20673, 20672, 20671, 35650, 35649, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 26000, 26002, 26030, 25993, 26006, 26038, 26009, 26039, 26011, 26040, - 26013, 26015, 26032, 26034, 26017, 26020, 26041, 26024, 26026, 25996, - 26028, 26042, 26043, 26036, 26044, 26004, 26048, 26050, 26083, 26045, - 26054, 26057, 26059, 26091, 26061, 26092, 26063, 26065, 26085, 26087, - 26067, 26070, 26093, 26074, 26076, 26078, 26081, 26094, 26095, 26089, - 26096, 26052, 26488, 26490, 26520, 26494, 26496, 26528, 26499, 26529, - 26501, 26530, 26503, 26505, 26522, 26524, 26507, 26510, 26531, 26514, - 26516, 26484, 26518, 26532, 26533, 26526, 26534, 26492, 26436, 26438, - 26471, 26432, 26442, 26445, 26447, 41412, 26449, 26479, 26451, 26453, - 26473, 26475, 26455, 26458, 26480, 26462, 26464, 26466, 26469, 26481, - 26482, 26477, 26483, 26440, 26153, 26155, 26185, 26159, 26161, 26193, - 26164, 26194, 26166, 26195, 26168, 26170, 26187, 26189, 26172, 26175, - 26196, 26179, 26181, 26149, 26183, 26197, 26198, 26191, 26199, 26157, - 26207, 26209, 26244, 26213, 26215, 26218, 26220, 26252, 26222, 26253, - 26224, 26226, 26246, 26248, 26228, 26231, 26254, 26235, 26237, 26239, - 26242, 26255, 26256, 26250, 26257, 26211, 26960, 41412, 26961, 26962, - 41412, 41412, 26963, 41412, 41412, 26964, 26965, 41412, 41412, 26966, - 26967, 26968, 26969, 41412, 26970, 26971, 26972, 26973, 26974, 26975, - 26976, 26977, 26978, 26979, 26980, 26981, 41412, 26982, 41412, 26983, - 26984, 26985, 26986, 26987, 26988, 26989, 41412, 26990, 26991, 26992, - 26993, 26994, 26995, 26996, 26997, 26998, 26999, 27000, 26097, 26098, - 26099, 26100, 26101, 26102, 26103, 26104, 26105, 26106, 26107, 26108, - 26109, 26110, 26111, 26112, 26113, 26114, 26115, 26116, 26117, 26118, - 26119, 26120, 26121, 26122, 26123, 26124, 26125, 26126, 26127, 26128, - 26129, 26130, 26131, 26132, 26133, 26134, 26135, 26136, 26137, 26138, - 26139, 26140, 26141, 26142, 26143, 26144, 26145, 26146, 26147, 26148, - 26384, 26385, 41412, 26386, 26387, 26388, 26389, 41412, 41412, 26390, - 26391, 26392, 26393, 26394, 26395, 26396, 26397, 41412, 26398, 26399, - 26400, 26401, 26402, 26403, 26404, 41412, 26405, 26406, 26407, 26408, - 26409, 26410, 26411, 26412, 26413, 26414, 26415, 26416, 26417, 26418, - 26419, 26420, 26421, 26422, 26423, 26424, 26425, 26426, 26427, 26428, - 26429, 26430, 26329, 26330, 41412, 26331, 26332, 26333, 26334, 41412, - 26335, 26336, 26337, 26338, 26339, 41412, 26340, 41412, 41412, 41412, - 26341, 26342, 26343, 26344, 26345, 26346, 26347, 41412, 26348, 26349, - 26350, 26351, 26352, 26353, 26354, 26355, 26356, 26357, 26358, 26359, - 26360, 26361, 26362, 26363, 26364, 26365, 26366, 26367, 26368, 26369, - 26370, 26371, 26372, 26373, 26267, 26268, 26269, 26270, 26271, 26272, - 26273, 26274, 26275, 26276, 26277, 26278, 26279, 26280, 26281, 26282, - 26283, 26284, 26285, 26286, 26287, 26288, 26289, 26290, 26291, 26292, - 26293, 26294, 26295, 26296, 26297, 26298, 26299, 26300, 26301, 26302, - 26303, 26304, 26305, 26306, 26307, 26308, 26309, 26310, 26311, 26312, - 26313, 26314, 26315, 26316, 26317, 26318, 26898, 26899, 26900, 26901, - 26902, 26903, 26904, 26905, 26906, 26907, 26908, 26909, 26910, 26911, - 26912, 26913, 26914, 26915, 26916, 26917, 26918, 26919, 26920, 26921, - 26922, 26923, 26924, 26925, 26926, 26927, 26928, 26929, 26930, 26931, - 26932, 26933, 26934, 26935, 26936, 26937, 26938, 26939, 26940, 26941, - 26942, 26943, 26944, 26945, 26946, 26947, 26948, 26949, 26730, 26732, - 26762, 26736, 26738, 26770, 26741, 26771, 26743, 26772, 26745, 26747, - 26764, 26766, 26749, 26752, 26773, 26756, 26758, 26726, 26760, 26774, - 26775, 26768, 26776, 26734, 26784, 26786, 26821, 26790, 26792, 26795, - 26797, 26829, 26799, 26830, 26801, 26803, 26823, 26825, 26805, 26808, - 26831, 26812, 26814, 26816, 26819, 26832, 26833, 26827, 26834, 26788, - 26846, 26847, 26848, 26849, 26850, 26851, 26852, 26853, 26854, 26855, - 26856, 26857, 26858, 26859, 26860, 26861, 26862, 26863, 26864, 26865, - 26866, 26867, 26868, 26869, 26870, 26871, 26872, 26873, 26874, 26875, - 26876, 26877, 26878, 26879, 26880, 26881, 26882, 26883, 26884, 26885, - 26886, 26887, 26888, 26889, 26890, 26891, 26892, 26893, 26894, 26895, - 26896, 26897, 26620, 26622, 26652, 26626, 26628, 26660, 26631, 26661, - 26633, 26662, 26635, 26637, 26654, 26656, 26639, 26642, 26663, 26646, - 26648, 26616, 26650, 26664, 26665, 26658, 26666, 26624, 26674, 26676, - 26711, 26680, 26682, 26685, 26687, 26719, 26689, 26720, 26691, 26693, - 26713, 26715, 26695, 26698, 26721, 26702, 26704, 26706, 26709, 26722, - 26723, 26717, 26724, 26678, 26543, 26544, 26545, 26546, 26547, 26548, - 26549, 26550, 26551, 26552, 26553, 26554, 26555, 26556, 26557, 26558, - 26559, 26560, 26561, 26562, 26563, 26564, 26565, 26566, 26567, 26568, - 26569, 26570, 26571, 26572, 26573, 26574, 26575, 26576, 26577, 26578, - 26579, 26580, 26581, 26582, 26583, 26584, 26585, 26586, 26587, 26588, - 26589, 26590, 26591, 26592, 26593, 26594, 26433, 26434, 41412, 41412, - 26001, 26003, 26010, 25995, 26007, 26005, 26008, 25997, 26012, 26014, - 26016, 26033, 26035, 26037, 26018, 26023, 26025, 25998, 26027, 25999, - 26029, 26021, 26031, 26022, 26019, 26261, 26049, 26051, 26060, 26047, - 26055, 26053, 26056, 26079, 26062, 26064, 26066, 26086, 26088, 26090, - 26068, 26073, 26075, 26058, 26077, 26080, 26082, 26071, 26084, 26072, - 26069, 26263, 26259, 26266, 26260, 26262, 26265, 26264, 26489, 26491, - 26500, 26495, 26497, 26493, 26498, 26485, 26502, 26504, 26506, 26523, - 26525, 26527, 26508, 26513, 26515, 26486, 26517, 26487, 26519, 26511, - 26521, 26512, 26509, 26537, 26437, 26439, 26448, 26435, 26443, 26441, - 26444, 26467, 26450, 26452, 26454, 26474, 26476, 26478, 26456, 26461, - 26463, 26446, 26465, 26468, 26470, 26459, 26472, 26460, 26457, 26539, - 26535, 26542, 26536, 26538, 26541, 26540, 26154, 26156, 26165, 26160, - 26162, 26158, 26163, 26150, 26167, 26169, 26171, 26188, 26190, 26192, - 26173, 26178, 26180, 26151, 26182, 26152, 26184, 26176, 26186, 26177, - 26174, 26202, 26208, 26210, 26221, 26214, 26216, 26212, 26217, 26240, - 26223, 26225, 26227, 26247, 26249, 26251, 26229, 26234, 26236, 26219, - 26238, 26241, 26243, 26232, 26245, 26233, 26230, 26204, 26200, 26258, - 26201, 26203, 26206, 26205, 26731, 26733, 26742, 26737, 26739, 26735, - 26740, 26727, 26744, 26746, 26748, 26765, 26767, 26769, 26750, 26755, - 26757, 26728, 26759, 26729, 26761, 26753, 26763, 26754, 26751, 26779, - 26785, 26787, 26798, 26791, 26793, 26789, 26794, 26817, 26800, 26802, - 26804, 26824, 26826, 26828, 26806, 26811, 26813, 26796, 26815, 26818, - 26820, 26809, 26822, 26810, 26807, 26781, 26777, 26835, 26778, 26780, - 26783, 26782, 26621, 26623, 26632, 26627, 26629, 26625, 26630, 26617, - 26634, 26636, 26638, 26655, 26657, 26659, 26640, 26645, 26647, 26618, - 26649, 26619, 26651, 26643, 26653, 26644, 26641, 26669, 26675, 26677, - 26688, 26681, 26683, 26679, 26684, 26707, 26690, 26692, 26694, 26714, - 26716, 26718, 26696, 26701, 26703, 26686, 26705, 26708, 26710, 26699, - 26712, 26700, 26697, 26671, 26667, 26725, 26668, 26670, 26673, 26672, - 25994, 26046, 41412, 41412, 26325, 26327, 26324, 26323, 26320, 26319, - 26322, 26321, 26328, 26326, 26380, 26382, 26379, 26378, 26375, 26374, - 26377, 26376, 26383, 26381, 26956, 26958, 26955, 26954, 26951, 26950, - 26953, 26952, 26959, 26957, 26842, 26844, 26841, 26840, 26837, 26836, - 26839, 26838, 26845, 26843, 26601, 26603, 26600, 26599, 26596, 26595, - 26598, 26597, 26604, 26602, 33315, 33271, 33296, 33512, 33467, 33253, - 33316, 33280, 33429, 33381, 33357, 33318, 33321, 33278, 33322, 33272, - 33323, 33345, 33340, 33378, 33319, 33325, 33334, 33335, 33326, 33332, - 33336, 33274, 33408, 33317, 33346, 33275, 33355, 33324, 33354, 33341, - 33380, 33379, 33320, 33339, 33349, 33350, 33353, 33352, 33420, 33328, - 33329, 33330, 33402, 33370, 33333, 33337, 33331, 33327, 33401, 33362, - 33400, 33399, 33359, 33358, 33361, 33351, 33348, 33347, 33397, 33396, - 33398, 33369, 33445, 33449, 33448, 33446, 33447, 33290, 33436, 33466, - 33438, 33451, 33443, 33452, 33444, 33453, 33442, 33300, 33301, 33465, - 33506, 33439, 33440, 33441, 33437, 33463, 33450, 33461, 33454, 33462, - 33460, 33458, 33455, 33456, 33457, 33459, 33287, 33293, 33291, 33292, - 33496, 33495, 33303, 33295, 33306, 33309, 33304, 33307, 33305, 33308, - 33313, 33310, 33270, 33505, 33511, 33508, 33510, 33484, 33486, 33464, - 33494, 33487, 33491, 33485, 33493, 33492, 33490, 33252, 33342, 33277, - 33469, 33255, 33478, 33344, 33343, 33470, 33383, 33386, 33385, 33384, - 33393, 33433, 33282, 33507, 33264, 33389, 33392, 33387, 33388, 33481, - 33391, 33480, 33263, 33262, 33390, 33281, 33479, 33261, 33356, 33276, - 33471, 33488, 33254, 33338, 33273, 33409, 33489, 33265, 33417, 33413, - 33415, 33286, 33509, 33266, 33410, 33412, 33411, 33416, 33414, 33504, - 33382, 33279, 33311, 33498, 33499, 33497, 33299, 33477, 33257, 33256, - 33406, 33482, 33404, 33285, 33394, 33405, 33503, 33403, 33407, 33395, - 33283, 33312, 33302, 33483, 33268, 33269, 33267, 33284, 33288, 33289, - 33501, 33502, 33500, 33468, 33371, 33473, 33374, 33375, 33376, 33373, - 33377, 33372, 33366, 33367, 33368, 33365, 33363, 33294, 33364, 33360, - 33297, 33298, 33475, 33476, 33472, 33474, 33259, 33260, 33258, 33418, - 33423, 33426, 33427, 33428, 33434, 33419, 33421, 33422, 33430, 33425, - 33431, 33432, 33424, 33314, 33435, 33826, 33825, 33824, 33846, 33845, - 33844, 33801, 33800, 33799, 33185, 33184, 33183, 33787, 33786, 33785, - 33797, 33798, 33793, 33796, 33792, 33795, 33794, 33242, 33245, 33241, - 33244, 33243, 33791, 33661, 33662, 33663, 33664, 33659, 33660, 33665, - 33705, 33610, 33723, 33722, 33720, 33721, 33724, 33699, 33702, 33700, - 33701, 33698, 33729, 33728, 33726, 33727, 33675, 33674, 33673, 33679, - 33678, 33677, 33676, 33697, 33696, 33695, 33672, 33671, 33670, 33745, - 33744, 33743, 33719, 33718, 33717, 33842, 33841, 33840, 33839, 33838, - 33837, 33843, 33836, 33835, 33834, 33579, 33578, 33576, 33577, 33583, - 33582, 33580, 33581, 33571, 33570, 33568, 33569, 33575, 33574, 33572, - 33573, 33633, 33632, 33630, 33631, 33634, 33648, 33651, 33649, 33650, - 33607, 33638, 33637, 33636, 33635, 33593, 33606, 33605, 33604, 33594, - 33592, 33591, 33590, 33657, 33656, 33655, 33654, 33653, 33652, 33829, - 33828, 33827, 33832, 33831, 33830, 33833, 33692, 33691, 33689, 33690, - 33683, 33682, 33680, 33681, 33688, 33687, 33710, 33709, 33706, 33711, - 33716, 33713, 33712, 33732, 33731, 33730, 33735, 33734, 33733, 33686, - 33694, 33693, 33782, 33779, 33778, 33725, 33684, 33707, 33714, 33739, - 33783, 33780, 33776, 33685, 33708, 33715, 33740, 33784, 33781, 33777, - 33738, 33737, 33736, 33597, 33596, 33614, 33612, 33613, 33611, 33623, - 33621, 33622, 33620, 33640, 33639, 33771, 33768, 33774, 33599, 33598, - 33615, 33616, 33618, 33617, 33627, 33625, 33626, 33624, 33642, 33641, - 33772, 33769, 33775, 33603, 33602, 33600, 33601, 33595, 33619, 33628, - 33643, 33644, 33645, 33770, 33767, 33773, 33629, 33669, 33667, 33668, - 33666, 33589, 33587, 33585, 33588, 33586, 33584, 33742, 33741, 33647, - 33646, 33704, 33703, 33609, 33608, 33201, 33200, 33196, 33199, 33203, - 33202, 33197, 33198, 33195, 33204, 33514, 33521, 33519, 33518, 33516, - 33517, 33515, 33520, 33234, 33232, 33233, 33210, 33209, 33208, 33193, - 33191, 33192, 33194, 33249, 33248, 33247, 33228, 33229, 33225, 33206, - 33205, 33224, 33226, 33223, 33227, 33207, 33222, 33220, 33221, 33217, - 33219, 33218, 33211, 33213, 33212, 33215, 33214, 33216, 33188, 33187, - 33186, 33811, 33810, 33812, 33231, 33748, 33747, 33749, 33750, 33178, - 33180, 33177, 33179, 33182, 33181, 33543, 33541, 33542, 33548, 33550, - 33549, 33545, 33547, 33546, 33562, 33561, 33560, 33554, 33555, 33556, - 33557, 33558, 33559, 33551, 33553, 33552, 33563, 33564, 33565, 33532, - 33530, 33531, 33544, 33567, 33566, 33819, 33818, 33816, 33817, 33815, - 33820, 33814, 33813, 33803, 33808, 33806, 33807, 33804, 33805, 33809, - 33746, 33658, 33751, 33513, 33230, 33789, 33788, 33251, 33246, 33790, - 33822, 33821, 33823, 33847, 33522, 33523, 33524, 33525, 33526, 33527, - 33528, 33529, 33240, 33540, 33539, 33534, 33537, 33536, 33533, 33535, - 33538, 33190, 33250, 33802, 33189, 33848, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 33235, 33236, 33237, 33238, 33239, 41412, 33759, 33760, 33761, - 33762, 33763, 33764, 33765, 33766, 33752, 33753, 33754, 33755, 33756, - 33757, 33758, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 23665, 23940, 23431, 23945, 23418, 23789, 24051, 23942, - 24037, 24006, 23411, 23644, 23645, 24041, 23405, 23458, 23432, 23782, - 23581, 23762, 23642, 24035, 23921, 24010, 23653, 23582, 23726, 23879, - 24011, 23548, 23957, 41412, 41412, 41412, 41412, 41412, 41412, 23572, - 23775, 23821, 23926, 23965, 24001, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 8342, 8344, 8354, - 8348, 8330, 8355, 8362, 41412, 8361, 8335, 8332, 8331, 8329, 8366, 8350, - 8349, 8351, 8365, 8352, 8353, 8337, 8340, 8364, 8346, 8363, 41412, 41412, - 8338, 8341, 8345, 8339, 8357, 8356, 8358, 41412, 8360, 8336, 41412, 8359, - 8334, 8343, 8333, 8347, 41412, 41412, 41412, 41412, 41412, 27944, 27913, - 27941, 27939, 27915, 27937, 27934, 27935, 27936, 27943, 27920, 27921, - 27945, 27924, 27922, 27917, 27930, 27946, 27919, 27942, 27929, 27938, - 27928, 27931, 27916, 27933, 27914, 27927, 27911, 27940, 27912, 27925, - 27923, 10652, 10630, 10650, 10637, 10633, 10647, 10644, 10645, 10646, - 10651, 10635, 10653, 10649, 10636, 10654, 10634, 10639, 10643, 10648, - 10642, 10640, 10641, 10638, 10629, 10632, 10631, 27918, 27932, 27926, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 8250, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 30063, 30047, 30038, 30049, - 30054, 30046, 30051, 30042, 30068, 30072, 30074, 30077, 30041, 30036, - 30071, 30061, 30045, 30044, 30075, 30037, 30048, 30069, 30057, 30073, - 30076, 30043, 30065, 30050, 30040, 30060, 30039, 30055, 30062, 30064, - 30070, 30056, 30052, 30053, 30078, 30079, 30058, 30059, 30066, 30067, - 30080, 41412, 41412, 41412, 30089, 30093, 30092, 30095, 30094, 30091, - 30090, 30086, 30083, 30082, 30085, 30084, 30087, 30088, 41412, 41412, - 30103, 30105, 30102, 30101, 30098, 30097, 30100, 30099, 30106, 30104, - 41412, 41412, 41412, 41412, 30081, 30096, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 37973, 37956, 37976, 37966, - 37970, 37967, 37972, 37958, 37957, 37975, 37963, 37978, 37977, 37969, - 37968, 37974, 37971, 37959, 37951, 37960, 37952, 37980, 37961, 37953, - 37962, 37954, 37979, 37965, 37955, 37964, 37981, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 39435, 39434, 39466, 39467, 39468, 39470, - 39459, 39462, 39448, 39451, 39463, 39455, 39452, 39469, 39465, 39464, - 39472, 39477, 39476, 39475, 39461, 39440, 39439, 39474, 39473, 39460, - 39471, 39443, 39445, 39449, 39456, 39447, 39454, 39453, 39442, 39437, - 39438, 39446, 39441, 39444, 39436, 39450, 39457, 39458, 39481, 39482, - 39479, 39480, 39489, 39491, 39488, 39487, 39484, 39483, 39486, 39485, - 39492, 39490, 41412, 41412, 41412, 41412, 41412, 39478, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 29044, 29047, 29046, 29048, - 29045, 29027, 29031, 29029, 29028, 29030, 29039, 29042, 29040, 29043, - 29041, 29049, 29050, 29051, 29052, 29053, 29032, 29034, 29037, 29038, - 29033, 29036, 29035, 29057, 29054, 29058, 29056, 29055, 29065, 29067, - 29064, 29063, 29060, 29059, 29062, 29061, 29068, 29066, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 30226, 30229, 30228, 30227, 30230, 30231, 30208, 30210, - 30209, 30211, 30212, 30213, 30220, 30221, 30225, 30222, 30223, 30224, - 30232, 30236, 30233, 30235, 30234, 30237, 30214, 30219, 30218, 30216, - 30215, 30217, 30240, 30238, 30239, 30248, 30250, 30247, 30246, 30243, - 30242, 30245, 30244, 30251, 30249, 41412, 41412, 41412, 41412, 30241, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 35536, 35545, 35534, 35543, 35567, 35552, 35565, 35542, - 35551, 35537, 35546, 35566, 35541, 35550, 35559, 35553, 35564, 35540, - 35549, 35558, 35538, 35547, 35568, 35571, 35533, 35570, 35539, 35548, - 35569, 35535, 35544, 41412, 35526, 35560, 35555, 35576, 35554, 35527, - 35574, 35562, 35572, 35561, 35556, 35557, 35563, 35525, 35575, 35573, - 35530, 35529, 35528, 35532, 35531, 35577, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 35578, 35579, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 17141, 17147, 17145, 17142, 17144, 17143, 17146, 41412, 17096, 17140, - 17138, 17137, 41412, 17084, 17083, 41412, 17095, 17094, 17093, 17080, - 17079, 17092, 17091, 17090, 17089, 17088, 17087, 17082, 17081, 17086, - 17085, 41412, 27254, 27255, 27256, 27322, 27343, 27331, 27295, 27431, - 27257, 27258, 27262, 27381, 27366, 27371, 27294, 27449, 27398, 27320, - 27300, 27392, 27261, 27259, 27260, 27307, 27351, 27404, 27444, 27267, - 27263, 27271, 27408, 27346, 27356, 27383, 27272, 27269, 27268, 27421, - 27359, 27419, 27397, 27388, 27386, 27387, 27450, 27429, 27266, 27281, - 27273, 27420, 27365, 27390, 27325, 27451, 27277, 27278, 27279, 27335, - 27327, 27311, 27412, 27363, 27264, 27270, 27265, 27338, 27435, 27436, - 27274, 27275, 27276, 27349, 27304, 27354, 27321, 27282, 27280, 27283, - 27407, 27364, 27413, 27315, 27427, 27284, 27288, 27292, 27361, 27333, - 27401, 27382, 27285, 27289, 27290, 27332, 27324, 27389, 27342, 27452, - 27353, 27291, 27286, 27287, 27369, 27422, 27430, 27299, 27442, 27293, - 27352, 27302, 27399, 27339, 27377, 27309, 27391, 27341, 27308, 27448, - 27297, 27344, 27301, 27340, 27368, 27395, 27406, 27376, 27411, 27378, - 27337, 27357, 27438, 27405, 27372, 27415, 27445, 27418, 27416, 27441, - 27312, 27428, 27318, 27347, 27303, 27334, 27310, 27358, 27314, 27394, - 27313, 27373, 27298, 27439, 27329, 27424, 27425, 27443, 27414, 27355, - 27393, 27385, 27348, 27323, 27296, 27362, 27370, 27409, 27375, 27305, - 27400, 27345, 27360, 27326, 27328, 27434, 27374, 27380, 27379, 27446, - 27367, 27316, 27317, 27403, 27447, 27396, 27384, 27437, 27440, 27410, - 27432, 27336, 27402, 27330, 27417, 27306, 27433, 27350, 27319, 41412, - 41412, 27460, 27458, 27457, 27454, 27453, 27456, 27455, 27461, 27459, - 27249, 27248, 27252, 27250, 27247, 27251, 27253, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 27, 9, 24, 14, - 29, 21, 34, 28, 37, 39, 35, 40, 41, 10, 30, 32, 18, 15, 31, 42, 13, 25, - 36, 23, 12, 20, 33, 19, 38, 17, 11, 26, 16, 22, 62, 44, 59, 49, 64, 56, - 69, 63, 72, 74, 70, 75, 76, 45, 65, 67, 53, 50, 66, 77, 48, 60, 71, 58, - 47, 55, 68, 54, 73, 52, 46, 61, 51, 57, 85, 86, 79, 84, 43, 78, 83, 82, - 41412, 41412, 41412, 41412, 93, 95, 92, 91, 88, 87, 90, 89, 96, 94, - 41412, 41412, 41412, 41412, 80, 81, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 20858, 20844, - 20839, 20819, 20814, 20832, 20827, 20807, 20822, 20847, 20842, 20837, - 20817, 20812, 20833, 20828, 20808, 20823, 20859, 20845, 20840, 20820, - 20815, 20835, 20830, 20810, 20825, 20860, 20846, 20841, 20821, 20816, - 20836, 20831, 20811, 20826, 20848, 20843, 20838, 20818, 20813, 20834, - 20829, 20809, 20824, 20805, 20806, 20796, 20803, 20804, 20856, 20854, - 20853, 20850, 20849, 20852, 20851, 20857, 20855, 20862, 20798, 20797, - 20799, 20861, 20802, 20801, 20800, 20795, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 31008, 31003, 30998, 30978, 30973, 30991, 30986, 30966, - 30981, 31006, 31001, 30996, 30976, 30971, 30992, 30987, 30967, 30982, - 31009, 31004, 30999, 30979, 30974, 30994, 30989, 30969, 30984, 31010, - 31005, 31000, 30980, 30975, 30995, 30990, 30970, 30985, 31007, 31002, - 30997, 30977, 30972, 30993, 30988, 30968, 30983, 30965, 30958, 30960, - 30950, 30952, 30953, 30955, 30962, 30961, 30956, 30951, 30954, 30959, - 30957, 30964, 30963, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 2288, 2296, 2294, 2192, - 41412, 2304, 2292, 2300, 2284, 2299, 2291, 2240, 2295, 2302, 2267, 2289, + 1007, 1006, 1043, 1003, 1008, 1005, 24130, 26234, 27165, 3595, 33417, + 15927, 7591, 10042, 11885, 7573, 33865, 11907, 367, 15078, 6691, 6913, + 5038, 32324, 22878, 15614, 24848, 24849, 25529, 25530, 10037, 28228, + 1013, 9667, 25976, 23978, 25978, 7143, 18843, 18844, 18842, 26281, 26282, + 26280, 18805, 18812, 18804, 26295, 26302, 26294, 18747, 18745, 18746, + 9066, 26245, 26243, 26244, 15938, 15556, 32406, 32445, 28923, 28921, + 32061, 4460, 4461, 26063, 18846, 26318, 15565, 15566, 15567, 15568, 9689, + 9687, 9691, 9680, 9684, 9692, 9681, 9685, 9690, 9679, 9683, 9678, 9682, + 9688, 9686, 28512, 26174, 12509, 33412, 22117, 22109, 22116, 22110, + 22114, 22115, 22113, 22112, 22111, 10658, 12772, 32049, 4464, 32031, + 4463, 32062, 4467, 33874, 3701, 28864, 12596, 8, 11827, 9668, 3987, 3949, + 4030, 3926, 3988, 3950, 3990, 230, 28862, 31826, 15589, 3966, 3969, 3971, + 3963, 10365, 4009, 3871, 25924, 25921, 25922, 25923, 24237, 29165, 29173, + 29174, 29154, 29152, 29155, 29166, 29137, 29138, 29159, 29161, 29160, + 29158, 29139, 29171, 29172, 29141, 29150, 29149, 29148, 29147, 29163, + 29177, 29153, 29140, 29151, 29175, 29156, 29157, 29168, 29167, 29169, + 29178, 29142, 4053, 24835, 29164, 29145, 29176, 29144, 29143, 29146, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 24249, 24244, 24247, 24248, 24241, 24242, 24240, 24239, + 24246, 24243, 24245, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 6657, 6654, 6653, 6650, 6649, 6652, 6651, + 6658, 6656, 6878, 6858, 6903, 6891, 6873, 6861, 6877, 6875, 6857, 6904, + 6892, 25461, 25459, 25458, 25455, 25454, 25457, 25456, 25462, 25460, + 25453, 25444, 25452, 25450, 25445, 25446, 25448, 25449, 25443, 25447, + 25451, 9977, 9989, 9986, 9971, 9968, 9983, 9980, 9995, 9974, 24151, + 24144, 24152, 24150, 24145, 24146, 24147, 24149, 24143, 24154, 24153, + 25489, 25490, 25491, 25492, 25493, 25494, 25495, 25496, 25497, 25498, + 25499, 25500, 25501, 25502, 25503, 25504, 25505, 25506, 25507, 25508, + 25509, 25510, 25511, 25512, 25513, 25514, 6801, 6802, 6803, 6804, 6805, + 6806, 6807, 6808, 6809, 6810, 6811, 6812, 6813, 6814, 6815, 6816, 6817, + 6818, 6819, 6820, 6821, 6822, 6823, 6824, 6825, 6826, 6827, 6828, 6829, + 6830, 6831, 6832, 6833, 6834, 6835, 6836, 6837, 6838, 6839, 6840, 6841, + 6842, 6843, 6844, 6845, 6846, 6847, 6848, 6849, 6850, 6851, 6852, 6655, + 23671, 23669, 23667, 23672, 23673, 23675, 23676, 23670, 23674, 23668, + 10331, 10329, 10328, 10325, 10324, 10327, 10326, 10332, 10330, 10323, + 23666, 4586, 4532, 4602, 4518, 4595, 4531, 4594, 4530, 4593, 4529, 4592, + 4528, 4583, 4502, 4496, 4525, 4582, 4500, 4494, 4524, 4601, 4630, 4624, + 4517, 4600, 4628, 4622, 4515, 4609, 4646, 4623, 4495, 4643, 4501, 4629, + 4521, 4608, 4645, 4621, 4493, 4642, 4499, 4627, 4520, 4581, 4536, 4614, + 4504, 4498, 4617, 4539, 4523, 4599, 4535, 4613, 4631, 4625, 4616, 4538, + 4516, 4607, 4537, 4615, 4644, 4620, 4497, 4641, 4541, 4619, 4534, 4612, + 4503, 4626, 4618, 4540, 4519, 4585, 4527, 4584, 4526, 4492, 4488, 4509, + 4506, 4484, 4508, 4505, 4483, 4636, 4633, 4487, 4635, 4632, 4486, 4648, + 4639, 4491, 4647, 4638, 4490, 4510, 4507, 4482, 4637, 4634, 4485, 4649, + 4640, 4489, 4543, 4542, 4544, 4545, 4574, 4568, 4578, 4590, 4597, 4611, + 4580, 4511, 4513, 4533, 4522, 4591, 4598, 4512, 4514, 32383, 19955, + 19954, 19957, 19865, 19947, 19960, 19956, 12663, 18799, 18822, 18835, + 18763, 18823, 18778, 18779, 26260, 19099, 21671, 9654, 32431, 26277, + 26045, 26046, 26037, 26038, 26039, 26040, 26041, 26042, 26043, 26044, + 4007, 33852, 33861, 33855, 28690, 28699, 28689, 28696, 28698, 28688, + 4004, 33849, 4000, 33837, 4037, 33884, 3981, 33833, 4032, 33881, 4031, + 33880, 3989, 33841, 3994, 33840, 3993, 33839, 3928, 33796, 3927, 33795, + 3954, 33822, 3953, 33821, 3952, 33820, 3918, 33785, 33786, 12588, 19962, + 33771, 10314, 6630, 5101, 3867, 6622, 6631, 6623, 6628, 6627, 6629, + 18761, 26258, 15955, 15959, 32387, 19859, 32411, 32447, 19909, 19889, + 32392, 19866, 3961, 3960, 4033, 4034, 33735, 28693, 28700, 28695, 28692, + 33864, 33882, 32369, 32370, 17419, 33862, 33858, 33859, 33863, 33778, + 33776, 33777, 33779, 32409, 32464, 19900, 33829, 3976, 33828, 3975, + 19923, 4011, 7137, 32318, 28218, 7576, 4020, 33871, 19109, 31545, 28924, + 2568, 9697, 7594, 24856, 4026, 33873, 2795, 2801, 2802, 26684, 32320, + 15584, 33846, 4018, 27137, 26197, 3959, 3986, 33819, 33878, 33843, 33794, + 28114, 6225, 26061, 3864, 5361, 983, 24958, 6585, 7802, 7801, 28839, + 12555, 102, 14253, 25595, 35252, 32128, 32129, 32134, 32131, 32133, + 32132, 32130, 32127, 33731, 33806, 33850, 4006, 33869, 12581, 17423, + 22106, 12561, 10654, 20267, 16084, 26754, 32537, 23980, 25890, 2566, + 31166, 12855, 6099, 18983, 33460, 19797, 26848, 26682, 6105, 2646, 25783, + 33743, 33759, 33762, 33737, 33746, 33756, 3889, 3905, 3908, 3883, 3892, + 3902, 4019, 33809, 33790, 3917, 33851, 3938, 3923, 33780, 15585, 26050, + 11782, 3581, 3582, 23003, 23001, 23002, 33729, 10659, 32334, 26091, + 26092, 26093, 26094, 26095, 26096, 26097, 26098, 4036, 26090, 25520, + 25627, 33732, 9959, 9960, 9961, 9962, 9963, 9964, 33773, 33775, 3868, + 3870, 22875, 22876, 9999, 10002, 10001, 10000, 33800, 3934, 14254, 981, + 7810, 28833, 26843, 347, 12604, 12851, 28834, 2581, 12601, 25164, 31522, + 31521, 33705, 15435, 10400, 10401, 15942, 20266, 20265, 20264, 33418, + 15576, 21682, 21658, 21675, 20433, 10122, 32336, 7793, 12769, 23790, + 6235, 25329, 16085, 33447, 6588, 3977, 26976, 26888, 26056, 26971, 28223, + 3518, 28766, 33797, 33798, 3931, 3932, 28219, 28926, 26066, 4013, 31544, + 32248, 32247, 33791, 7811, 10041, 24855, 25768, 6167, 15077, 6643, 6236, + 24052, 368, 4027, 33876, 3957, 33817, 10500, 14934, 18750, 28809, 12549, + 4024, 26170, 26171, 2575, 14860, 25602, 26336, 18873, 15965, 3880, 27142, + 6620, 6227, 15540, 12852, 12853, 20362, 22894, 32319, 12642, 12598, + 12563, 26839, 28511, 28112, 15620, 25614, 31286, 15982, 14836, 12771, + 9059, 33801, 4014, 32376, 4017, 19941, 33844, 33810, 31178, 31165, 226, + 11904, 26079, 26071, 33451, 33959, 19940, 25604, 32446, 33832, 3979, + 6401, 14858, 22994, 14894, 2805, 14850, 25166, 14941, 24839, 14896, + 17912, 26981, 25163, 20268, 28837, 12638, 12636, 14879, 12632, 3935, + 33805, 28432, 28867, 6916, 24837, 3881, 25165, 14898, 25780, 26980, + 14849, 24838, 11781, 11776, 11774, 28106, 11775, 14872, 32268, 28109, + 31171, 24836, 14924, 28104, 3933, 33802, 11777, 6905, 14923, 28221, + 31816, 14857, 28431, 14917, 2794, 11780, 14874, 7807, 26979, 23738, + 19939, 32443, 19921, 32461, 4044, 33836, 33799, 3920, 14876, 19106, + 21679, 14940, 14907, 14908, 14868, 14869, 14891, 14890, 9071, 14877, + 14883, 14853, 26531, 12603, 26530, 21665, 21668, 21659, 21660, 21666, + 21669, 14887, 14900, 14886, 14899, 19098, 19096, 21664, 21667, 10024, + 10022, 10021, 10018, 10017, 10020, 10019, 10025, 10023, 10016, 10035, + 10032, 10031, 10028, 10027, 10030, 10029, 10036, 10034, 10026, 10014, + 10011, 10010, 10007, 10006, 10009, 10008, 10015, 10013, 10005, 14936, + 14939, 14895, 14865, 14913, 14901, 14920, 10492, 14904, 32122, 14926, + 9657, 14864, 3995, 31536, 31539, 3996, 14851, 14852, 28827, 14863, 26352, + 18863, 2658, 12654, 14892, 14931, 24132, 9065, 24134, 6693, 33888, 4050, + 4052, 4051, 14854, 14856, 14855, 31172, 14925, 33725, 14937, 24850, + 10333, 31519, 33875, 25608, 24846, 24845, 18797, 26284, 24960, 26181, + 29081, 33399, 21130, 19823, 20951, 28794, 28795, 33789, 982, 11836, + 19937, 32404, 18781, 26275, 12662, 17411, 17410, 18728, 18727, 18777, + 19845, 19828, 32355, 19963, 33781, 33782, 33783, 33857, 33860, 21131, + 21125, 21134, 21128, 21133, 21127, 21132, 21126, 21135, 21129, 32505, + 10482, 978, 7116, 26238, 19831, 19835, 19825, 19829, 19840, 19827, 19832, + 19839, 19830, 19841, 19844, 5027, 4772, 4900, 4773, 4964, 4837, 4901, + 4774, 4996, 4869, 4933, 4806, 4965, 4838, 4902, 4775, 5012, 4885, 4949, + 4822, 4981, 4854, 4918, 4791, 4997, 4870, 4934, 4807, 4966, 4839, 4903, + 4776, 5020, 4893, 4957, 4830, 4989, 4862, 4926, 4799, 5005, 4878, 4942, + 4815, 4974, 4847, 4911, 4784, 5013, 4886, 4950, 4823, 4982, 4855, 4919, + 4792, 4998, 4871, 4935, 4808, 4967, 4840, 4904, 4777, 5024, 4897, 4961, + 4834, 4993, 4866, 4930, 4803, 5009, 4882, 4946, 4819, 4978, 4851, 4915, + 4788, 5017, 4890, 4954, 4827, 4986, 4859, 4923, 4796, 5002, 4875, 4939, + 4812, 4971, 4844, 4908, 4781, 5021, 4894, 4958, 4831, 4990, 4863, 4927, + 4800, 5006, 4879, 4943, 4816, 4975, 4848, 4912, 4785, 5014, 4887, 4951, + 4824, 4983, 4856, 4920, 4793, 4999, 4872, 4936, 4809, 4968, 4841, 4905, + 4778, 5026, 4899, 4963, 4836, 4995, 4868, 4932, 4805, 5011, 4884, 4948, + 4821, 4980, 4853, 4917, 4790, 5019, 4892, 4956, 4829, 4988, 4861, 4925, + 4798, 5004, 4877, 4941, 4814, 4973, 4846, 4910, 4783, 5023, 4896, 4960, + 4833, 4992, 4865, 4929, 4802, 5008, 4881, 4945, 4818, 4977, 4850, 4914, + 4787, 5016, 4889, 4953, 4826, 4985, 4858, 4922, 4795, 5001, 4874, 4938, + 4811, 4970, 4843, 4907, 4780, 5025, 4898, 4962, 4835, 4994, 4867, 4931, + 4804, 5010, 4883, 4947, 4820, 4979, 4852, 4916, 4789, 5018, 4891, 4955, + 4828, 4987, 4860, 4924, 4797, 5003, 4876, 4940, 4813, 4972, 4845, 4909, + 4782, 5022, 4895, 4959, 4832, 4991, 4864, 4928, 4801, 5007, 4880, 4944, + 4817, 4976, 4849, 4913, 4786, 5015, 4888, 4952, 4825, 4984, 4857, 4921, + 4794, 5000, 4873, 4937, 4810, 4969, 4842, 4906, 4779, 26456, 26455, + 18964, 26401, 18788, 26457, 18966, 26403, 10438, 32486, 32523, 10462, + 18968, 26405, 18948, 26449, 26458, 26375, 32488, 10442, 26388, 26387, + 26451, 26453, 26452, 18913, 26395, 18967, 26404, 18890, 26372, 18910, + 26367, 24091, 24071, 24097, 24069, 28316, 28329, 24096, 24068, 28313, + 28328, 26475, 12547, 28314, 24066, 12548, 26476, 24067, 24095, 33714, + 2559, 2558, 2561, 2562, 26353, 18862, 32028, 4462, 32030, 32029, 19919, + 19883, 975, 7113, 26362, 18879, 27152, 26380, 18895, 26371, 18786, 32526, + 18740, 18739, 32343, 32342, 18741, 32344, 18738, 32341, 18927, 26418, + 32500, 10477, 18921, 26412, 32497, 10474, 18926, 26417, 32499, 10476, + 18920, 26411, 32496, 10473, 18923, 32495, 26416, 10471, 18925, 18919, + 26414, 26409, 18924, 18918, 26415, 26410, 32494, 10472, 26250, 11921, + 31820, 18883, 26364, 26363, 19064, 18886, 13273, 28897, 18885, 29067, + 18836, 26255, 32352, 10406, 32142, 35265, 35266, 18828, 26321, 18830, + 26323, 35260, 35256, 35261, 35257, 18809, 26299, 18807, 26296, 18806, + 26297, 18734, 26231, 18735, 26237, 10346, 10371, 18743, 26241, 10321, + 33432, 21553, 26236, 21554, 960, 5, 28448, 28449, 32245, 26187, 961, + 26188, 24235, 24234, 21552, 21551, 21546, 21545, 21550, 21548, 21549, + 21547, 26209, 11883, 11882, 11880, 11881, 6632, 6920, 6907, 6911, 6908, + 6633, 6625, 6634, 32340, 6915, 6638, 6853, 6921, 6624, 6626, 28758, + 28753, 28824, 28810, 28811, 32278, 32121, 32119, 26679, 32118, 26313, + 18814, 33396, 4475, 4476, 4043, 31827, 31828, 33814, 3942, 18833, 26326, + 18751, 26251, 15779, 31754, 15856, 10399, 28701, 15781, 27172, 11922, + 11923, 15622, 13157, 31510, 10419, 10420, 3921, 3962, 33774, 3869, 11936, + 11939, 11935, 11938, 11934, 11937, 26548, 26182, 28275, 26183, 3857, + 3856, 10353, 32138, 18850, 26339, 31829, 22297, 23492, 23490, 23491, + 23500, 23499, 23495, 23496, 32280, 32279, 23494, 22700, 28922, 26047, + 12574, 15937, 15929, 6925, 980, 19181, 19182, 19183, 15930, 26049, 15934, + 15931, 15935, 15933, 15936, 15932, 16082, 17412, 35262, 35263, 35264, + 25882, 25887, 25885, 25881, 25884, 25883, 25886, 22290, 22291, 22293, + 22292, 25878, 25879, 33449, 22993, 22992, 26887, 28195, 22988, 22989, + 6854, 22990, 6648, 25880, 22294, 22991, 15952, 26358, 35258, 374, 15948, + 32329, 32330, 15947, 15946, 32331, 32327, 15945, 32326, 15944, 32328, + 15949, 7129, 7135, 10354, 10355, 7130, 19811, 19819, 10344, 10345, 32276, + 32277, 28134, 28133, 19816, 19813, 19821, 19812, 19820, 19810, 19814, + 19809, 28185, 19818, 19817, 35259, 35255, 11928, 15623, 32136, 32137, + 31822, 31821, 27978, 7595, 11929, 365, 1060, 11918, 25888, 11919, 10334, + 32271, 31530, 11927, 11931, 19081, 13292, 19082, 13293, 19073, 13279, + 19076, 13282, 19074, 13280, 19075, 13281, 19072, 13283, 19066, 13275, + 19065, 13274, 19063, 13271, 19061, 13269, 19060, 13268, 19059, 13272, + 19062, 13270, 28119, 28117, 28120, 28118, 10381, 10380, 10377, 10376, + 27977, 27976, 27975, 27974, 10347, 10349, 10348, 13287, 13276, 19070, + 13290, 19071, 13291, 28193, 17420, 28194, 17421, 11924, 25968, 28913, + 25969, 28914, 25971, 28916, 25967, 28912, 25970, 28915, 25966, 28911, + 10350, 10359, 28908, 29080, 28907, 29079, 28906, 29078, 28905, 29077, + 28900, 29072, 28901, 29073, 28899, 29071, 28902, 29074, 28579, 28666, + 7124, 7126, 7125, 7127, 28895, 29066, 28896, 29065, 29069, 29068, 11835, + 25786, 32114, 12626, 24063, 27151, 27157, 27154, 25609, 33398, 10368, + 33397, 10366, 19822, 27158, 27156, 27155, 10335, 10363, 10357, 26191, + 10137, 33414, 33413, 10405, 25373, 25372, 32141, 32144, 32135, 32148, + 32147, 10379, 10378, 32145, 17409, 10362, 33886, 23501, 24080, 24107, + 28326, 28339, 18791, 18917, 32490, 10444, 24077, 24104, 28323, 28336, + 18793, 32347, 26384, 26385, 18899, 18900, 28694, 28687, 28697, 28691, + 9951, 9952, 9950, 9949, 10317, 3948, 33815, 4041, 33887, 3982, 33834, + 33812, 3939, 15551, 3943, 3965, 33826, 3968, 33830, 4001, 4002, 33847, + 3941, 33813, 4038, 33883, 18737, 31523, 18736, 19833, 18956, 18955, + 18957, 18958, 18893, 18903, 18902, 18951, 18953, 18952, 18887, 33713, + 11920, 26184, 18880, 26370, 26369, 18982, 26465, 26185, 26360, 31819, + 18882, 18881, 26361, 10458, 27149, 27147, 33827, 4003, 33848, 3992, + 33838, 14884, 14897, 14861, 14859, 14862, 28121, 2656, 28122, 2655, 3698, + 27148, 18933, 32509, 26434, 10447, 18795, 32351, 24102, 24075, 28321, + 28334, 18945, 32520, 26446, 10459, 7121, 973, 18944, 32511, 26445, 10449, + 35536, 35536, 24103, 24076, 28322, 28335, 18935, 32519, 26436, 10457, + 15572, 33427, 18934, 32510, 26435, 10448, 18946, 32521, 26447, 10460, + 18916, 32489, 26398, 10446, 970, 971, 969, 972, 26175, 26176, 23975, + 23976, 12633, 26399, 11926, 29179, 31534, 31538, 31535, 31537, 3955, + 4035, 3997, 3929, 10451, 10452, 32513, 32514, 18938, 26439, 18937, 26438, + 3872, 3873, 3874, 3875, 3876, 3878, 3877, 3879, 26222, 26223, 26220, + 26221, 26217, 26219, 26216, 26218, 32534, 32339, 25181, 25180, 25182, + 2800, 6923, 6637, 4008, 3919, 32246, 15550, 4042, 3972, 3964, 3967, 3970, + 23981, 32046, 4450, 19094, 26532, 33804, 26533, 28651, 32322, 13819, + 25894, 25893, 25892, 25891, 32113, 25993, 2576, 15606, 25767, 23758, + 33831, 3922, 32158, 9061, 14834, 35344, 17245, 1055, 97, 33537, 25905, + 18762, 26259, 28840, 28841, 18954, 32525, 26454, 10464, 11941, 11940, + 26977, 26674, 26672, 26673, 26671, 26675, 26676, 11925, 32333, 26968, + 10402, 25528, 26198, 15079, 13057, 13059, 13093, 13067, 13063, 13094, + 13101, 13064, 13100, 13073, 13069, 13068, 13062, 13104, 13075, 13076, + 13077, 13078, 13080, 13082, 13086, 13090, 13103, 13065, 13102, 13079, + 13081, 13083, 13092, 13061, 13085, 13096, 13095, 13097, 13087, 13099, + 13088, 13089, 13098, 13071, 13058, 13070, 13066, 13072, 13084, 13091, + 13074, 13060, 13105, 13107, 13141, 13115, 13111, 13142, 13149, 13112, + 13148, 13121, 13117, 13116, 13110, 13152, 13123, 13124, 13125, 13126, + 13128, 13130, 13134, 13138, 13151, 13113, 13150, 13127, 13129, 13131, + 13140, 13109, 13133, 13144, 13143, 13145, 13135, 13147, 13136, 13137, + 13146, 13119, 13106, 13118, 13114, 13120, 13132, 13139, 13122, 13108, + 17644, 18291, 17647, 17738, 17756, 18025, 18517, 17587, 18210, 17633, + 18270, 17902, 18684, 17465, 17666, 17806, 17807, 18637, 17879, 18654, + 18636, 17592, 18217, 18582, 18138, 18558, 18372, 17950, 18709, 22418, + 17782, 17906, 7603, 7697, 7653, 7747, 7617, 7711, 7614, 7708, 7658, 7752, + 7648, 7742, 7652, 7746, 7619, 7713, 7650, 7744, 7656, 7750, 7622, 7716, + 7627, 7721, 7659, 7753, 7660, 7754, 7623, 7717, 7628, 7722, 7655, 7749, + 7657, 7751, 7649, 7743, 7651, 7745, 7661, 7755, 7625, 7719, 7621, 7715, + 7654, 7748, 7644, 7738, 7611, 7705, 7639, 7733, 7607, 7701, 7612, 7706, + 7613, 7707, 7608, 7702, 7637, 7731, 7647, 7741, 7609, 7703, 7635, 7729, + 7638, 7732, 7602, 7696, 7610, 7704, 7630, 7724, 7631, 7725, 7626, 7720, + 7633, 7727, 7632, 7726, 7629, 7723, 7636, 7730, 7634, 7728, 7642, 7736, + 7640, 7734, 7641, 7735, 7643, 7737, 7757, 7758, 7759, 7761, 7762, 7756, + 7760, 7605, 7699, 7606, 7700, 7601, 7600, 7599, 7604, 7698, 35536, 35536, + 35536, 35536, 35536, 7695, 7692, 7693, 7694, 7690, 7691, 7763, 12916, + 12942, 12927, 12948, 12949, 12947, 12937, 12938, 12950, 12931, 12940, + 12943, 12945, 12951, 12933, 12936, 12941, 12935, 12939, 12952, 12932, + 12930, 12926, 12946, 12934, 12922, 12925, 12929, 12924, 12923, 12944, + 12928, 12917, 12921, 12919, 12954, 12918, 12920, 35536, 12953, 35536, + 35536, 35536, 35536, 35536, 12915, 35536, 35536, 31769, 31789, 31790, + 31770, 31772, 31759, 31798, 31785, 31788, 31786, 31787, 31808, 31797, + 31773, 31763, 31775, 31791, 31758, 31767, 31792, 31796, 31774, 31764, + 31803, 31768, 31809, 31783, 31757, 31765, 31799, 31800, 31801, 31762, + 31766, 31802, 31811, 31793, 31794, 31771, 31761, 31756, 31776, 31778, + 31777, 31779, 31780, 31795, 31781, 31804, 31805, 31806, 31782, 31760, + 31784, 31807, 31810, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 31812, 31813, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 31755, 12376, 12193, 12280, + 12320, 12296, 11983, 12358, 12021, 12211, 12202, 12103, 12436, 12051, + 12036, 12367, 12327, 12012, 12227, 12240, 12088, 12092, 12091, 12090, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 12310, + 12316, 12314, 12311, 12313, 12312, 12315, 35536, 12002, 12008, 12006, + 12003, 12005, 12004, 12007, 35536, 12426, 12432, 12430, 12427, 12429, + 12428, 12431, 35536, 11995, 12001, 11999, 11996, 11998, 11997, 12000, + 35536, 12262, 12268, 12266, 12263, 12265, 12264, 12267, 35536, 12171, + 12177, 12175, 12172, 12174, 12173, 12176, 35536, 12403, 12409, 12407, + 12404, 12406, 12405, 12408, 35536, 12114, 12120, 12118, 12115, 12117, + 12116, 12119, 35536, 7183, 7221, 7218, 7185, 7215, 7216, 7222, 7189, + 7190, 7191, 7198, 7220, 7192, 7186, 7214, 7211, 7213, 7217, 7201, 7200, + 7219, 7187, 7223, 7197, 7184, 7210, 7206, 7208, 7195, 7209, 7182, 7194, + 26233, 26232, 18813, 26303, 18755, 26248, 26070, 26069, 10320, 18816, + 26311, 26078, 18796, 26283, 10661, 25371, 12625, 26193, 15613, 10319, + 10443, 32473, 10322, 10370, 15961, 25330, 15609, 31825, 18776, 26273, + 31824, 31823, 18845, 26317, 32055, 32059, 4455, 4458, 18801, 26288, + 18754, 26253, 32274, 24829, 28754, 12592, 26208, 33430, 26468, 33947, + 32250, 26068, 26080, 32261, 9648, 9649, 32251, 32044, 32286, 31541, + 28854, 33433, 33930, 6104, 10338, 26207, 10341, 9655, 10358, 15962, + 15963, 19855, 19856, 10356, 10316, 32146, 21655, 25370, 26027, 7766, + 7803, 7804, 31913, 21654, 21656, 18811, 26301, 18810, 26300, 32036, + 32040, 4441, 4445, 24236, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 7007, 6960, 7010, + 7009, 7008, 7003, 6931, 7028, 7042, 7041, 6964, 7011, 7024, 7023, 6993, + 6992, 6991, 6990, 7020, 7029, 7019, 7018, 6979, 6978, 6982, 7006, 35536, + 6963, 7026, 7000, 6965, 6998, 6958, 7034, 7033, 6972, 7002, 7001, 7012, + 6962, 6966, 6987, 6929, 6971, 7022, 7021, 6934, 7017, 6945, 7040, 7039, + 7038, 7037, 6995, 7025, 7005, 6970, 7043, 6933, 6932, 6994, 6999, 6976, + 6975, 6974, 7030, 6961, 7036, 7035, 6949, 7013, 6981, 6948, 6947, 6973, + 6957, 7014, 7032, 7031, 6959, 6941, 6989, 6988, 6944, 6942, 6997, 6996, + 7004, 6935, 6951, 6943, 6953, 6939, 6969, 6968, 6967, 6937, 6980, 6956, + 6930, 6977, 6938, 6955, 6946, 7015, 7016, 6940, 6986, 6936, 6984, 6952, + 6985, 6954, 7027, 6983, 6950, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 16281, 16263, 16197, 16317, + 16305, 16249, 16349, 16264, 16277, 16260, 16212, 16216, 16201, 16186, + 16252, 16338, 16284, 16255, 16289, 16366, 16323, 16294, 16246, 16351, + 16195, 16306, 16182, 16286, 16157, 16275, 16211, 16209, 16304, 16232, + 16234, 16214, 16164, 16363, 16189, 16297, 16251, 16333, 16256, 16184, + 16322, 16273, 16295, 16364, 16282, 16347, 16207, 16312, 16198, 16266, + 16350, 16313, 16172, 16331, 16173, 16325, 16243, 16240, 16203, 16241, + 16174, 16292, 16303, 16196, 16159, 16334, 16279, 16336, 16302, 16276, + 16346, 16257, 16326, 16191, 16357, 16202, 16185, 16231, 16180, 16324, + 16356, 16223, 16181, 16218, 16200, 16239, 16318, 16220, 16188, 16204, + 16287, 16253, 16267, 16341, 16330, 16262, 16368, 16221, 16168, 16314, + 16199, 16359, 16335, 16194, 16217, 16319, 16155, 16328, 16321, 16345, + 16235, 16179, 16329, 16160, 16296, 16315, 16254, 16280, 16310, 16229, + 16285, 16158, 16288, 16208, 16175, 16268, 16269, 16307, 16156, 16271, + 16342, 16283, 16169, 16327, 16187, 16236, 16340, 16250, 16165, 16355, + 16183, 16358, 16308, 16248, 16320, 16352, 16176, 16290, 16161, 16309, + 16299, 16298, 16230, 16171, 16178, 16162, 16272, 16354, 16190, 16362, + 16193, 16353, 16233, 16265, 16238, 16274, 16316, 16311, 16291, 16167, + 16365, 16219, 16258, 16337, 16261, 16332, 16259, 16361, 16226, 16210, + 16244, 16227, 16247, 16170, 16339, 16242, 16222, 16300, 16177, 16237, + 16224, 16163, 16301, 16192, 16360, 16245, 16367, 16270, 16166, 16215, + 16228, 16344, 16206, 16293, 16278, 16213, 16343, 16205, 16348, 16225, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 15646, 15644, 15645, 15643, + 15658, 15654, 15653, 15650, 15651, 15652, 15648, 15647, 15655, 15649, + 15659, 15657, 15743, 15642, 15741, 10126, 15981, 15742, 15641, 15661, + 18733, 26230, 18752, 26249, 18748, 26246, 18827, 26320, 18742, 26240, + 25907, 13050, 18824, 26315, 18829, 26322, 18832, 26325, 18831, 26324, + 33712, 26190, 10352, 19853, 25908, 14730, 14723, 14720, 14726, 14725, + 14728, 14727, 14731, 14729, 15739, 15738, 15660, 15737, 14389, 14388, + 33718, 33405, 33408, 33406, 33409, 33407, 6906, 15735, 14724, 14722, + 14721, 33404, 20512, 25525, 15740, 15736, 35536, 15455, 15441, 15457, + 15535, 15459, 15537, 15456, 15534, 15458, 15536, 15496, 15486, 15498, + 15488, 15500, 15490, 15497, 15487, 15499, 15489, 15460, 15521, 15462, + 15523, 15464, 15525, 15461, 15522, 15463, 15524, 15516, 15481, 15518, + 15483, 15454, 15520, 15485, 15517, 15482, 15519, 15484, 15476, 15478, + 15480, 15477, 15479, 15491, 15471, 15506, 15493, 15465, 15508, 15495, + 15474, 15510, 15492, 15472, 15507, 15494, 15473, 15509, 15501, 15503, + 15505, 15502, 15504, 15448, 15530, 15450, 15532, 15449, 15531, 15511, + 15513, 15515, 15512, 15514, 15444, 15526, 15528, 15527, 15529, 15475, + 15533, 15451, 15452, 35536, 35536, 7391, 7390, 16607, 16606, 15539, + 15538, 15440, 16604, 16534, 16463, 16536, 16597, 16538, 16599, 16535, + 16596, 16537, 16598, 16559, 16549, 16561, 16551, 16563, 16553, 16560, + 16550, 16562, 16552, 16539, 16584, 16541, 16586, 16543, 16588, 16540, + 16585, 16542, 16587, 16574, 16544, 16576, 16546, 16521, 16578, 16548, + 16575, 16545, 16577, 16547, 16501, 16503, 16505, 16502, 16504, 16554, + 16478, 16564, 16556, 16472, 16566, 16558, 16481, 16568, 16555, 16479, + 16565, 16557, 16480, 16567, 16496, 16482, 16499, 16497, 16498, 16526, + 16593, 16528, 16595, 16527, 16594, 16569, 16571, 16573, 16570, 16572, + 16522, 16589, 16591, 16590, 16592, 16500, 16583, 16516, 16517, 16579, + 16581, 16580, 16582, 16603, 16605, 16602, 16600, 16601, 35536, 35536, + 35536, 35536, 35536, 4422, 4430, 4429, 4427, 4426, 4433, 4398, 4418, + 4386, 4414, 4428, 4424, 4431, 4435, 4411, 4417, 4421, 4432, 4410, 4416, + 4420, 4366, 4402, 4378, 4383, 4367, 4384, 4369, 4409, 4371, 4379, 4372, + 4380, 4385, 4391, 4376, 4397, 4434, 4399, 4388, 4394, 4405, 4401, 35536, + 14642, 14686, 14643, 14648, 14649, 14651, 14678, 14689, 14664, 14665, + 14667, 14669, 14676, 14672, 14668, 14675, 14644, 14654, 14688, 14655, + 14679, 14691, 14636, 14631, 14685, 14630, 14641, 14677, 14662, 14715, + 14626, 14629, 14712, 14713, 14633, 14632, 14699, 14698, 14716, 14695, + 14696, 14717, 14704, 14718, 14694, 14693, 14697, 14708, 14634, 14714, + 14635, 14719, 14687, 14650, 14653, 14652, 14666, 14673, 14670, 14671, + 14674, 14645, 14647, 14646, 14640, 14661, 14659, 14656, 14657, 14660, + 14658, 14638, 14639, 14681, 14682, 14684, 14683, 14680, 14663, 14692, + 14701, 14703, 14702, 14637, 14690, 14700, 14705, 14706, 14707, 14710, + 14709, 14711, 14627, 14628, 35536, 15635, 15638, 15637, 15633, 15631, + 15627, 15634, 15629, 15625, 15628, 15636, 15632, 15626, 15639, 15640, + 15630, 4423, 4412, 4425, 4389, 4382, 4381, 4408, 4404, 4396, 4373, 4392, + 4377, 4395, 4400, 4368, 4370, 4375, 4407, 4403, 4393, 4364, 4365, 4363, + 4362, 4387, 4419, 4413, 4361, 4390, 4415, 4406, 4374, 7074, 7077, 7078, + 7076, 7064, 7050, 7056, 7045, 7055, 7068, 7057, 7053, 7046, 7054, 7051, + 7080, 7044, 7063, 7059, 7072, 7079, 7049, 7058, 7067, 7066, 7073, 7071, + 7060, 7062, 7075, 7070, 7065, 7047, 7052, 7061, 7081, 7048, 7069, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 15656, 16519, + 16531, 16532, 16520, 16530, 16506, 16508, 16510, 16507, 16509, 16533, + 16511, 16513, 16515, 16512, 16514, 25385, 25389, 25401, 25395, 25387, + 25393, 25397, 25403, 25378, 25376, 25383, 25399, 25391, 25381, 25386, + 25390, 25402, 25396, 25388, 25394, 25398, 25404, 25379, 25377, 25384, + 25400, 25392, 25382, 25380, 25442, 25441, 35536, 25440, 25436, 25434, + 25415, 25413, 25433, 25425, 25410, 25419, 25435, 25418, 25412, 25438, + 25437, 25417, 25409, 25432, 25430, 25439, 25427, 25420, 25428, 25411, + 25406, 25416, 25423, 25407, 25429, 25431, 25408, 25421, 25405, 25414, + 25422, 25426, 25424, 6725, 6713, 6735, 6714, 6879, 6893, 6881, 6863, + 6860, 6876, 6874, 6856, 25524, 6894, 6900, 6899, 6896, 6895, 6898, 6897, + 6902, 6901, 6880, 6882, 6888, 6887, 6884, 6883, 6673, 6677, 6689, 6683, + 6675, 6681, 6685, 6666, 6664, 6662, 6671, 6687, 6679, 6669, 6674, 6678, + 6690, 6684, 6676, 6682, 6686, 6667, 6665, 6663, 6672, 6688, 6680, 6670, + 6800, 6799, 6668, 17243, 6748, 6744, 6742, 6710, 6708, 6740, 6731, 6705, + 6723, 6743, 6721, 6707, 6746, 6745, 6719, 6703, 6734, 6739, 6712, 6736, + 6724, 6737, 6706, 6699, 6715, 6730, 6720, 6709, 6733, 6704, 6741, 6696, + 6747, 6727, 6700, 6698, 6711, 6701, 6716, 6717, 6729, 6718, 6728, 6738, + 6732, 6702, 6726, 6694, 6722, 6886, 6885, 6890, 6889, 6862, 6864, 6870, + 6869, 6866, 6865, 6868, 6867, 6872, 6871, 6859, 15726, 15729, 15730, + 15668, 15731, 15727, 15728, 15667, 15733, 15734, 15732, 15700, 28539, + 28505, 28507, 19180, 6794, 6796, 6798, 6795, 6797, 6757, 6759, 6761, + 6758, 6760, 6777, 6779, 6781, 6778, 6780, 6782, 6784, 6786, 6783, 6785, + 6767, 6769, 6771, 6768, 6770, 6752, 6754, 6756, 6753, 6755, 6762, 6764, + 6766, 6763, 6765, 6791, 6793, 6792, 6772, 6774, 6776, 6773, 6775, 6787, + 6789, 6788, 6790, 28503, 28464, 28466, 28465, 28467, 28542, 28543, 28706, + 28506, 28499, 28632, 28636, 28551, 28549, 28550, 28514, 28515, 28519, + 28518, 28565, 28517, 28552, 28555, 28553, 28554, 28520, 28521, 28562, + 28563, 28564, 28561, 28560, 28672, 28673, 28680, 28674, 28675, 28490, + 28494, 28495, 28685, 28625, 28626, 28527, 28639, 28640, 28471, 28648, + 28646, 28647, 28474, 28534, 28533, 28473, 28535, 28528, 28645, 28643, + 28529, 28644, 28642, 28476, 28649, 28475, 28532, 28650, 28530, 28531, + 28589, 28590, 28593, 28592, 28591, 28599, 28600, 28601, 28596, 28597, + 28598, 28704, 28703, 28705, 28667, 28668, 28670, 28669, 28665, 28664, + 28686, 15724, 15725, 15707, 15709, 15716, 15715, 15722, 15720, 15711, + 15718, 15710, 15713, 15706, 15708, 15717, 15714, 15723, 15721, 15712, + 15719, 15701, 15705, 15704, 15703, 15702, 28537, 28489, 28469, 28472, + 28637, 28653, 28491, 28493, 28492, 28547, 28500, 28504, 28501, 28502, + 28481, 28641, 28624, 28606, 28588, 28548, 28570, 28594, 28524, 28478, + 28567, 28654, 28627, 28607, 28608, 28621, 28571, 28540, 28566, 28618, + 28522, 28684, 28609, 28622, 28498, 28573, 28513, 28628, 28610, 28603, + 28482, 28556, 28605, 28484, 28587, 28559, 28604, 28483, 28586, 28558, + 28583, 28584, 28638, 28569, 28620, 28523, 28661, 28662, 28663, 28658, + 28629, 28611, 28623, 28659, 28630, 28612, 28614, 28575, 28615, 28660, + 28631, 28613, 28616, 28576, 28617, 28568, 28585, 28468, 28477, 28487, + 28488, 28485, 28480, 28496, 28525, 28526, 28536, 28541, 28572, 28557, + 28574, 28580, 28581, 28578, 28582, 28595, 28602, 28619, 28655, 28656, + 28652, 28657, 28681, 28682, 28702, 28470, 28462, 15699, 15684, 15672, + 15691, 15690, 15697, 15695, 15686, 15693, 15685, 15688, 15683, 15671, + 15692, 15689, 15698, 15696, 15687, 15694, 15673, 15681, 15679, 15678, + 15675, 15674, 15677, 15676, 15682, 15680, 15669, 15670, 28516, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 15417, 15420, 15381, + 15431, 15428, 15376, 15414, 15393, 15410, 15427, 15405, 15411, 15386, + 15388, 15398, 15432, 15385, 15429, 15369, 15375, 15373, 15392, 15412, + 15406, 15394, 15391, 15399, 15390, 15415, 15418, 15397, 15383, 15407, + 15389, 15404, 15384, 15419, 15402, 15400, 15379, 15378, 15396, 15374, + 15377, 15387, 15403, 15401, 15421, 15408, 15416, 15413, 15425, 15380, + 15423, 15371, 15422, 15424, 15426, 15382, 15430, 15395, 15409, 15370, + 15372, 34469, 34476, 34468, 34475, 34473, 34474, 34471, 34472, 35244, + 35245, 35242, 35243, 35241, 35239, 35240, 35248, 35249, 35246, 35247, + 35251, 35250, 35116, 34136, 34137, 34130, 34135, 34133, 34134, 34131, + 34132, 34140, 34141, 34138, 34139, 34121, 34119, 34120, 34144, 34145, + 34142, 34143, 34129, 34127, 34128, 34125, 34126, 34118, 34124, 34123, + 34122, 34150, 34151, 34146, 34149, 34148, 34147, 34848, 34849, 34843, + 34847, 34846, 34844, 34845, 34852, 34853, 34850, 34851, 34837, 34835, + 34836, 34856, 34857, 34854, 34855, 34841, 34842, 34834, 34840, 34839, + 34838, 34862, 34863, 34858, 34861, 34860, 34859, 34104, 34105, 34098, + 34103, 34101, 34102, 34099, 34100, 34108, 34109, 34106, 34107, 34089, + 34087, 34088, 34112, 34113, 34110, 34111, 34097, 34095, 34096, 34093, + 34094, 34086, 34092, 34091, 34090, 34116, 34117, 34114, 34115, 34651, + 34652, 34646, 34650, 34649, 34647, 34648, 34655, 34656, 34653, 34654, + 34659, 34660, 34657, 34658, 34665, 34666, 34661, 34664, 34663, 34662, + 34671, 34672, 34667, 34670, 34669, 34668, 34394, 34395, 34389, 34393, + 34392, 34390, 34391, 34398, 34399, 34396, 34397, 34383, 34381, 34382, + 34402, 34403, 34400, 34401, 34387, 34388, 34380, 34386, 34385, 34384, + 34408, 34404, 34407, 34406, 34405, 34630, 34631, 34625, 34629, 34628, + 34626, 34627, 34634, 34635, 34632, 34633, 34618, 34619, 34616, 34617, + 34638, 34639, 34636, 34637, 34645, 34644, 34623, 34624, 34615, 34622, + 34621, 34620, 34642, 34643, 34640, 34641, 34275, 34276, 34273, 34274, + 34271, 34272, 34269, 34270, 34268, 34266, 34267, 34285, 34286, 34281, + 34284, 34283, 34282, 34279, 34280, 34277, 34278, 35094, 35095, 35088, + 35093, 35091, 35092, 35089, 35090, 35098, 35099, 35096, 35097, 35102, + 35103, 35100, 35101, 35087, 35086, 35108, 35109, 35104, 35107, 35106, + 35105, 35114, 35115, 35110, 35113, 35112, 35111, 34253, 34254, 34248, + 34252, 34251, 34249, 34250, 34260, 34261, 34258, 34259, 34242, 34241, + 34264, 34265, 34262, 34263, 34257, 34255, 34256, 34246, 34247, 34240, + 34245, 34244, 34243, 35073, 35074, 35068, 35072, 35071, 35069, 35070, + 35080, 35081, 35078, 35079, 35061, 35062, 35059, 35060, 35084, 35085, + 35082, 35083, 35077, 35075, 35076, 35066, 35067, 35058, 35065, 35064, + 35063, 34227, 34228, 34222, 34226, 34225, 34223, 34224, 34234, 34235, + 34232, 34233, 34216, 34214, 34215, 34238, 34239, 34236, 34237, 34231, + 34229, 34230, 34220, 34221, 34213, 34219, 34218, 34217, 34677, 34678, + 34673, 34676, 34675, 34674, 34684, 34685, 34682, 34683, 34688, 34689, + 34686, 34687, 34681, 34679, 34680, 34694, 34695, 34690, 34693, 34692, + 34691, 34424, 34425, 34418, 34423, 34421, 34422, 34419, 34420, 34428, + 34429, 34426, 34427, 34413, 34412, 34410, 34411, 34409, 34417, 34415, + 34416, 34414, 34822, 34823, 34817, 34821, 34820, 34818, 34819, 34826, + 34824, 34825, 34811, 34809, 34810, 34832, 34833, 34830, 34831, 34829, + 34827, 34828, 34815, 34816, 34808, 34814, 34813, 34812, 34362, 34363, + 34357, 34361, 34360, 34358, 34359, 34372, 34373, 34370, 34371, 34351, + 34349, 34350, 34369, 34367, 34368, 34366, 34364, 34365, 34355, 34356, + 34348, 34354, 34353, 34352, 34378, 34379, 34374, 34377, 34376, 34375, + 34577, 34578, 34571, 34576, 34574, 34575, 34572, 34573, 34581, 34582, + 34579, 34580, 34561, 34562, 34559, 34560, 34585, 34586, 34583, 34584, + 34570, 34568, 34569, 34566, 34567, 34558, 34565, 34564, 34563, 34591, + 34592, 34587, 34590, 34589, 34588, 34331, 34332, 34325, 34330, 34328, + 34329, 34326, 34327, 34335, 34336, 34333, 34334, 34318, 34319, 34316, + 34317, 34343, 34344, 34341, 34342, 34339, 34340, 34337, 34338, 34323, + 34324, 34315, 34322, 34321, 34320, 34544, 34545, 34539, 34543, 34542, + 34540, 34541, 34548, 34549, 34546, 34547, 34533, 34531, 34532, 34556, + 34557, 34554, 34555, 34552, 34553, 34550, 34551, 34537, 34538, 34530, + 34536, 34535, 34534, 34291, 34292, 34287, 34290, 34288, 34289, 34305, + 34306, 34303, 34304, 34296, 34297, 34294, 34295, 34313, 34314, 34311, + 34312, 34309, 34310, 34307, 34308, 34301, 34302, 34293, 34300, 34299, + 34298, 34614, 34613, 34607, 34608, 34605, 34606, 34596, 34594, 34595, + 34611, 34612, 34609, 34610, 34604, 34602, 34603, 34600, 34601, 34593, + 34599, 34598, 34597, 34443, 34444, 34437, 34442, 34440, 34441, 34438, + 34439, 34447, 34448, 34445, 34446, 34432, 34433, 34430, 34431, 34451, + 34452, 34449, 34450, 34436, 34434, 34435, 34704, 34702, 34703, 34707, + 34708, 34705, 34706, 34697, 34698, 34696, 34711, 34712, 34709, 34710, + 34701, 34699, 34700, 34347, 34346, 34345, 34462, 34463, 34460, 34461, + 34455, 34456, 34453, 34454, 34466, 34467, 34464, 34465, 34459, 34457, + 34458, 35128, 35129, 35126, 35127, 35119, 35117, 35118, 35125, 35123, + 35124, 35122, 35120, 35121, 35191, 35192, 35186, 35190, 35189, 35187, + 35188, 35227, 35228, 35225, 35226, 35180, 35178, 35179, 35231, 35232, + 35229, 35230, 35224, 35222, 35223, 35184, 35185, 35177, 35183, 35182, + 35181, 35237, 35238, 35233, 35236, 35235, 35234, 34197, 34198, 34191, + 34196, 34194, 34195, 34192, 34193, 34201, 34202, 34199, 34200, 34182, + 34180, 34181, 34205, 34206, 34203, 34204, 34190, 34188, 34189, 34186, + 34187, 34179, 34185, 34184, 34183, 34211, 34212, 34207, 34210, 34209, + 34208, 35205, 35206, 35199, 35204, 35202, 35203, 35200, 35201, 35209, + 35210, 35207, 35208, 35198, 35196, 35197, 35195, 35193, 35194, 35215, + 35211, 35214, 35213, 35212, 35220, 35221, 35216, 35219, 35218, 35217, + 34794, 34795, 34789, 34793, 34792, 34790, 34791, 34798, 34799, 34796, + 34797, 34782, 34781, 34788, 34787, 34807, 34806, 34786, 34780, 34785, + 34784, 34783, 34804, 34805, 34800, 34803, 34802, 34801, 35039, 35040, + 35034, 35038, 35037, 35035, 35036, 35046, 35047, 35044, 35045, 35028, + 35026, 35027, 35050, 35051, 35048, 35049, 35043, 35041, 35042, 35032, + 35033, 35025, 35031, 35030, 35029, 35056, 35057, 35052, 35055, 35054, + 35053, 34975, 34976, 34970, 34974, 34973, 34971, 34972, 34982, 34983, + 34980, 34981, 34986, 34987, 34984, 34985, 34979, 34977, 34978, 34990, + 34991, 34988, 34989, 34996, 34997, 34992, 34995, 34994, 34993, 35161, + 35162, 35159, 35160, 35153, 35151, 35152, 35169, 35170, 35167, 35168, + 35165, 35166, 35163, 35164, 35157, 35158, 35150, 35156, 35155, 35154, + 35175, 35176, 35171, 35174, 35173, 35172, 34163, 34164, 34161, 34162, + 34155, 34156, 34153, 34154, 34171, 34172, 34169, 34170, 34167, 34168, + 34165, 34166, 34160, 34152, 34159, 34158, 34157, 34177, 34178, 34173, + 34176, 34175, 34174, 34943, 34942, 34922, 34921, 34934, 34935, 34932, + 34933, 34930, 34931, 34928, 34929, 34926, 34927, 34920, 34925, 34924, + 34923, 34940, 34941, 34936, 34939, 34938, 34937, 34743, 34744, 34741, + 34742, 34740, 34738, 34739, 34747, 34748, 34745, 34746, 34753, 34754, + 34749, 34752, 34751, 34750, 34759, 34760, 34755, 34758, 34757, 34756, + 35009, 35010, 35007, 35008, 35001, 34999, 35000, 35017, 35018, 35015, + 35016, 35013, 35014, 35011, 35012, 35005, 35006, 34998, 35004, 35003, + 35002, 35023, 35024, 35019, 35022, 35021, 35020, 34958, 34959, 34956, + 34957, 34947, 34945, 34946, 34962, 34963, 34960, 34961, 34955, 34953, + 34954, 34951, 34952, 34944, 34950, 34949, 34948, 34968, 34969, 34964, + 34967, 34966, 34965, 34518, 34519, 34512, 34517, 34515, 34516, 34513, + 34514, 34505, 34506, 34503, 34504, 34522, 34523, 34520, 34521, 34510, + 34511, 34502, 34509, 34508, 34507, 34528, 34529, 34524, 34527, 34526, + 34525, 34880, 34881, 34874, 34879, 34877, 34878, 34875, 34876, 34867, + 34868, 34865, 34866, 34884, 34885, 34882, 34883, 34872, 34873, 34864, + 34871, 34870, 34869, 34890, 34891, 34886, 34889, 34888, 34887, 34492, + 34493, 34486, 34491, 34489, 34490, 34487, 34488, 34480, 34478, 34479, + 34496, 34497, 34494, 34495, 34484, 34485, 34477, 34483, 34482, 34481, + 34500, 34501, 34498, 34499, 34726, 34727, 34720, 34725, 34723, 34724, + 34721, 34722, 34715, 34714, 34730, 34731, 34728, 34729, 34719, 34713, + 34718, 34717, 34716, 34736, 34737, 34732, 34735, 34734, 34733, 34774, + 34775, 34768, 34773, 34771, 34772, 34769, 34770, 34764, 34762, 34763, + 34778, 34779, 34776, 34777, 34766, 34767, 34761, 34765, 35136, 35137, + 35130, 35135, 35133, 35134, 35131, 35132, 35149, 35148, 35140, 35141, + 35138, 35139, 35146, 35147, 35142, 35145, 35144, 35143, 34908, 34909, + 34902, 34907, 34905, 34906, 34903, 34904, 34895, 34896, 34893, 34894, + 34912, 34913, 34910, 34911, 34900, 34901, 34892, 34899, 34898, 34897, + 34918, 34919, 34914, 34917, 34916, 34915, 35536, 35536, 35536, 34083, + 34056, 34054, 34061, 34035, 34071, 34042, 34044, 34060, 34047, 34058, + 34031, 34059, 34077, 34065, 34046, 34072, 34045, 34078, 34036, 34039, + 34032, 34041, 34062, 34073, 34085, 34050, 34081, 34066, 34049, 34076, + 34074, 34070, 34075, 34082, 34053, 34063, 34052, 34043, 34051, 34084, + 34040, 34067, 34057, 34034, 34033, 34038, 34048, 34068, 34079, 34069, + 34037, 34080, 34064, 34055, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 19783, 19772, 19771, 19755, 19753, 19752, 19766, + 19770, 19769, 19785, 19764, 19763, 19754, 19751, 19750, 19787, 19760, + 19786, 19774, 19777, 19778, 19759, 19768, 19789, 19767, 19784, 19788, + 19773, 19776, 19765, 19779, 19780, 19761, 19762, 19790, 19781, 19756, + 19757, 19758, 19782, 19746, 19749, 19747, 19745, 19748, 19744, 19791, + 19792, 32803, 32804, 32640, 32789, 32790, 32763, 32566, 32573, 32676, + 32649, 32683, 32623, 32749, 32777, 32601, 32594, 32552, 32545, 32667, + 32770, 32559, 32702, 32587, 32580, 32615, 32608, 32742, 32756, 32721, + 32784, 32662, 32708, 32629, 32690, 32735, 32728, 32812, 32813, 32644, + 32645, 32798, 32799, 32765, 32568, 32575, 32678, 32655, 32685, 32626, + 32751, 32779, 32603, 32596, 32554, 32547, 32671, 32772, 32561, 32704, + 32589, 32582, 32617, 32610, 32744, 32758, 32723, 32786, 32663, 32713, + 32634, 32692, 32737, 32730, 32810, 32811, 32715, 32642, 32643, 32796, + 32797, 32764, 32567, 32574, 32677, 32653, 32654, 32684, 32625, 32750, + 32778, 32602, 32595, 32553, 32546, 32670, 32771, 32560, 32703, 32588, + 32581, 32616, 32609, 32743, 32757, 32722, 32785, 32659, 32660, 32712, + 32633, 32691, 32736, 32729, 32807, 32808, 32638, 32793, 32794, 32761, + 32564, 32571, 32674, 32652, 32681, 32621, 32747, 32775, 32599, 32592, + 32550, 32543, 32669, 32768, 32557, 32700, 32585, 32578, 32613, 32606, + 32740, 32754, 32719, 32782, 32658, 32711, 32632, 32688, 32733, 32726, + 32814, 32815, 32646, 32647, 32800, 32801, 32766, 32569, 32576, 32679, + 32656, 32686, 32627, 32752, 32780, 32604, 32597, 32555, 32548, 32672, + 32773, 32562, 32705, 32590, 32583, 32618, 32611, 32745, 32759, 32724, + 32787, 32664, 32714, 32635, 32693, 32738, 32731, 32806, 32809, 32717, + 32636, 32637, 32792, 32795, 32760, 32563, 32570, 32673, 32651, 32680, + 32619, 32620, 32746, 32774, 32598, 32591, 32549, 32542, 32668, 32767, + 32556, 32694, 32584, 32577, 32612, 32605, 32739, 32753, 32718, 32781, + 32657, 32710, 32631, 32687, 32732, 32725, 32802, 32805, 32716, 32639, + 32641, 32788, 32791, 32762, 32565, 32572, 32675, 32648, 32650, 32682, + 32622, 32624, 32748, 32776, 32600, 32593, 32551, 32544, 32665, 32769, + 32558, 32701, 32586, 32579, 32614, 32607, 32741, 32755, 32720, 32783, + 32661, 32707, 32709, 32628, 32630, 32689, 32734, 32727, 32706, 32666, + 32539, 32540, 32541, 32697, 32698, 32695, 32819, 32822, 32825, 32824, + 32828, 32820, 32827, 32818, 32816, 32823, 32826, 32817, 32821, 32835, + 32837, 32834, 32833, 32830, 32829, 32832, 32831, 32838, 32836, 32699, + 32696, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 9401, 9602, 9290, 9449, 9240, 9543, 9345, 9504, 9286, 9445, 9366, + 9529, 9274, 9433, 9233, 9530, 9394, 9595, 9342, 9501, 9242, 9545, 9343, + 9502, 9282, 9441, 9275, 9434, 9339, 9498, 9396, 9597, 9241, 9544, 9385, + 9563, 9382, 9560, 9383, 9561, 9365, 9528, 9272, 9431, 9287, 9446, 9416, + 7237, 7229, 7180, 7230, 28123, 7204, 7193, 7207, 7203, 7212, 7205, 7202, + 7199, 7235, 7224, 9415, 9419, 9296, 9455, 9294, 9453, 9406, 9607, 9284, + 9443, 9292, 9451, 9246, 9571, 9254, 9580, 9250, 9575, 9249, 9574, 9252, + 9578, 9330, 9489, 9380, 9558, 9288, 9447, 9283, 9442, 22430, 22467, 7188, + 7196, 3462, 2824, 3465, 2826, 3461, 3437, 3454, 3464, 2853, 3463, 2829, + 3434, 3440, 3439, 2827, 2833, 3453, 2852, 2846, 2832, 3449, 2840, 3444, + 3450, 3443, 3447, 2822, 2818, 2850, 2849, 2844, 3456, 3446, 3457, 3458, + 2851, 2816, 3430, 2845, 2848, 3433, 3459, 3431, 2813, 3442, 2831, 2838, + 2855, 3436, 3441, 2817, 2841, 2842, 2843, 3445, 3432, 2815, 2814, 3460, + 2854, 2830, 3435, 2828, 2819, 2835, 3438, 2834, 2837, 3455, 2825, 2839, + 2836, 3452, 2823, 3451, 2847, 3448, 2812, 2820, 2821, 2809, 2808, 3466, + 3468, 2811, 2810, 3467, 3469, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 22427, 22423, 22426, 22422, 22428, 22424, 22429, 22425, + 22482, 22497, 22525, 22504, 22487, 22481, 22496, 22524, 22503, 22486, + 22483, 22498, 22526, 22508, 22488, 22474, 22473, 22475, 22519, 22538, + 22535, 22537, 22536, 22516, 22686, 22687, 17554, 18158, 17555, 18159, + 17594, 18220, 17821, 18583, 17820, 18540, 17494, 18080, 17495, 18081, + 17963, 17971, 17468, 18036, 17469, 18037, 17470, 18038, 17466, 18034, + 17467, 18035, 17471, 18039, 17765, 18464, 17635, 18272, 17632, 18269, + 17636, 18273, 17480, 18057, 17654, 18296, 17687, 18371, 17688, 18373, + 17734, 18411, 17739, 18416, 17737, 18414, 17740, 18417, 17747, 18429, + 17746, 18426, 17762, 18454, 17767, 18467, 17862, 18633, 17871, 18645, + 17866, 18640, 17815, 18534, 17816, 18535, 17870, 18644, 17556, 18176, + 17623, 18259, 17496, 18082, 22695, 18118, 18317, 18331, 18354, 18466, + 17948, 18578, 18630, 17616, 18248, 17617, 18249, 17618, 17805, 18546, + 17810, 18576, 17619, 18251, 17620, 18252, 17621, 18253, 22502, 22471, + 22548, 17788, 18490, 17808, 18301, 17979, 17680, 18345, 17490, 18070, + 18067, 18214, 17474, 18042, 17563, 18183, 17867, 18641, 17868, 18642, + 17869, 18643, 17571, 18194, 17639, 18277, 17683, 18350, 17760, 18451, + 17784, 18488, 17590, 17764, 17791, 17642, 17787, 17970, 17809, 17812, + 17626, 17497, 17481, 18059, 17732, 18409, 17858, 18621, 17576, 18199, + 17577, 18200, 17578, 18201, 17729, 18400, 17463, 18031, 17488, 17785, + 17908, 17501, 18084, 17781, 18482, 17768, 17780, 18481, 17744, 18423, + 17493, 18076, 17514, 18111, 17513, 18108, 17669, 18330, 17790, 18508, + 17658, 18306, 17659, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 22415, 22402, 22405, 22414, 17763, 18455, 17918, + 22397, 22627, 17953, 17916, 17917, 17914, 17915, 17913, 29119, 29121, + 29131, 29123, 29120, 29122, 29130, 29111, 29110, 29107, 29106, 29129, + 29105, 29104, 29109, 29108, 29099, 29098, 29093, 29092, 29101, 29100, + 29095, 29094, 29117, 29113, 29112, 29103, 29102, 29116, 29097, 29115, + 29096, 29118, 29114, 29133, 29135, 29136, 29134, 29132, 29124, 29125, + 29126, 29127, 29128, 35536, 35536, 35536, 24088, 24087, 24090, 24085, + 24086, 24089, 24082, 24081, 24084, 24083, 35536, 35536, 35536, 35536, + 35536, 35536, 25661, 25660, 25649, 25650, 25637, 25639, 25671, 25652, + 25659, 25658, 25642, 25653, 25663, 25662, 25668, 25673, 25655, 25654, + 25641, 25676, 25664, 25665, 25643, 25678, 25675, 25672, 25644, 25645, + 25670, 25634, 25679, 25681, 25666, 25680, 25674, 25677, 25669, 25648, + 25667, 25686, 25687, 25657, 25656, 25640, 25651, 25635, 25647, 25646, + 25636, 25685, 25688, 25638, 25684, 25689, 25683, 25682, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 26806, 26808, 26755, 26756, + 26776, 26777, 26772, 26773, 26767, 26768, 26769, 26770, 26799, 26800, + 26757, 26774, 26775, 26758, 26796, 26795, 26792, 26791, 26780, 26790, + 26789, 26794, 26793, 26782, 26764, 26763, 26760, 26759, 26781, 26766, + 26765, 26762, 26761, 26783, 26798, 26797, 26788, 26787, 26802, 26804, + 26803, 26779, 26771, 26784, 26785, 26786, 26801, 26778, 26821, 26822, + 26833, 26834, 26825, 26826, 26827, 26828, 26829, 26830, 26835, 26836, + 26823, 26831, 26832, 26824, 26807, 26805, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 26810, 26809, 26817, 26819, 26816, 26815, + 26812, 26811, 26814, 26813, 26820, 26818, 35536, 35536, 35536, 35536, + 35536, 35536, 7255, 7257, 7254, 7253, 7250, 7249, 7252, 7251, 7258, 7256, + 7246, 7247, 7242, 7243, 7244, 7245, 7241, 7248, 9889, 9883, 9896, 9885, + 9884, 9882, 9897, 9786, 9784, 9789, 9890, 9940, 9795, 9907, 16739, 16741, + 16738, 16737, 16734, 16733, 16736, 16735, 16742, 16740, 16703, 16702, + 16713, 16699, 16707, 16706, 16720, 16700, 16709, 16697, 16701, 16705, + 16704, 16715, 16712, 16710, 16716, 16719, 16714, 16718, 16708, 16698, + 16717, 16711, 16721, 16695, 16722, 16696, 16731, 16728, 16730, 16729, + 16732, 16727, 16725, 16726, 16723, 16724, 26148, 26145, 26137, 26153, + 26144, 26139, 26150, 26142, 26141, 26143, 26147, 26135, 26152, 26151, + 26149, 26155, 26154, 26146, 26140, 26136, 26138, 26134, 26156, 26163, + 26165, 26158, 26161, 26164, 26162, 26160, 26159, 26131, 26130, 26133, + 26132, 26166, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 26157, 14377, 14380, 14381, 14378, 14335, 14336, + 14344, 14338, 14340, 14343, 14337, 14333, 14339, 14341, 14334, 14300, + 14302, 14303, 14316, 14323, 14330, 14365, 14282, 14289, 14363, 14367, + 14313, 14386, 14369, 35536, 35536, 35536, 16058, 16054, 16057, 16056, + 16028, 15996, 15995, 15997, 16037, 16016, 16002, 16003, 16035, 16029, + 16036, 15998, 15999, 16000, 16012, 16013, 16001, 16010, 16011, 16026, + 16005, 16027, 16004, 16024, 16025, 15991, 15992, 16007, 16022, 16023, + 15993, 15994, 16006, 16014, 16015, 16008, 16009, 16032, 16034, 16017, + 16018, 16031, 16033, 16020, 16021, 16019, 16030, 16055, 16061, 16063, + 16064, 16065, 16059, 16060, 16062, 16067, 16066, 15987, 15988, 15989, + 16052, 15990, 16038, 16041, 16050, 16043, 16048, 16046, 16044, 16042, + 16039, 16040, 16045, 16053, 35536, 16051, 16074, 16076, 16073, 16072, + 16069, 16068, 16071, 16070, 16077, 16075, 35536, 35536, 35536, 35536, + 16047, 16049, 23307, 23305, 23300, 23297, 23303, 23393, 23371, 23323, + 23335, 23331, 23330, 23333, 23332, 23325, 23324, 23322, 23435, 23437, + 23434, 23433, 23430, 23429, 23432, 23431, 23438, 23436, 23334, 23327, + 23326, 23329, 23328, 35536, 6347, 6365, 6367, 6364, 6348, 6366, 6356, + 6355, 6352, 6351, 6327, 6328, 6350, 6349, 6354, 6353, 6329, 6331, 6330, + 6358, 6357, 6344, 6343, 6332, 6333, 6342, 6338, 6337, 6336, 6341, 6340, + 6334, 6335, 6339, 6363, 6361, 6360, 6362, 6345, 6346, 6359, 6372, 6375, + 6376, 6381, 6379, 6378, 6377, 6373, 6374, 6380, 6315, 6313, 6312, 6314, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 6321, + 6320, 6317, 6309, 6319, 6325, 6316, 6323, 6326, 6324, 6322, 6318, 6311, + 6310, 35536, 35536, 6388, 6390, 6387, 6386, 6383, 6382, 6385, 6384, 6391, + 6389, 35536, 35536, 6368, 6370, 6369, 6371, 23277, 23270, 23269, 23274, + 23273, 23267, 23266, 23265, 23263, 23262, 23264, 23268, 23279, 23272, + 23271, 23276, 23370, 23280, 23281, 23278, 23367, 23368, 23369, 23408, + 23410, 23409, 23252, 23404, 23395, 23396, 23316, 23317, 29603, 29579, + 29602, 29578, 29601, 29577, 29616, 29592, 29610, 29586, 29605, 29581, + 29604, 29580, 29621, 29597, 29611, 29587, 29614, 29590, 29609, 29585, + 29608, 29584, 29612, 29588, 29613, 29589, 29607, 29583, 29606, 29582, + 29615, 29591, 29619, 29595, 29623, 29599, 29620, 29596, 29618, 29594, + 29622, 29598, 29617, 29593, 29624, 29600, 29625, 29637, 29645, 29642, + 29641, 29647, 29648, 29626, 29646, 29643, 29644, 29636, 29640, 29639, + 29638, 29635, 29632, 29633, 29634, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 29628, + 29629, 29631, 29630, 29627, 21734, 21735, 21693, 21710, 21721, 21720, + 21697, 21696, 21709, 21715, 21716, 21748, 21750, 21740, 21742, 21741, + 21688, 21685, 21687, 21737, 21738, 21752, 21753, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 12338, 12336, 12335, + 12334, 12333, 12337, 35536, 35536, 12032, 12030, 12029, 12028, 12027, + 12031, 35536, 35536, 12047, 12045, 12044, 12043, 12042, 12046, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 11988, 11994, + 11992, 11989, 11991, 11990, 11993, 35536, 11973, 11979, 11977, 11974, + 11976, 11975, 11978, 35536, 18050, 18026, 18056, 18051, 18147, 18310, + 18500, 18299, 18290, 18293, 18321, 18335, 18161, 18054, 18055, 18405, + 18255, 18549, 18548, 18550, 18551, 18510, 17947, 18453, 18109, 18433, + 18110, 18497, 18498, 18053, 18620, 18586, 18629, 18572, 18625, 18073, + 18074, 18075, 18661, 18658, 18659, 18660, 18672, 22384, 22608, 22617, + 22618, 22675, 18491, 18258, 18406, 18631, 18254, 13549, 18116, 18581, + 18554, 22672, 22521, 22545, 35536, 35536, 35536, 35536, 6570, 6571, 6572, + 6573, 6574, 6575, 6533, 6569, 6534, 6535, 6536, 6537, 6538, 6498, 6499, + 6500, 6501, 6502, 6503, 6539, 6540, 6541, 6542, 6543, 6544, 6545, 6546, + 6547, 6548, 6549, 6504, 6497, 6505, 6506, 6507, 6508, 6509, 6510, 6551, + 6552, 6553, 6554, 6555, 6556, 6512, 6511, 6513, 6514, 6515, 6516, 6517, + 6491, 6530, 6492, 6531, 6493, 6532, 6494, 6495, 6496, 6490, 6518, 6519, + 6520, 6521, 6522, 6523, 6524, 6525, 6526, 6527, 6528, 6529, 6557, 6558, + 6559, 6560, 6561, 6562, 6563, 21702, 21714, 21724, 21726, 21711, 21705, + 21692, 21717, 21704, 21707, 21719, 21730, 21732, 21728, 21733, 21722, + 21713, 21731, 21699, 21700, 21729, 21691, 21701, 21695, 21698, 21694, + 21690, 21703, 21725, 21727, 21712, 21706, 21718, 21708, 21723, 21744, + 21747, 21739, 21746, 21745, 21749, 21743, 21751, 21689, 21736, 21686, + 35536, 35536, 21760, 21762, 21759, 21758, 21755, 21754, 21757, 21756, + 21763, 21761, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 14574, 14572, 14605, 14606, 14607, 14583, + 14584, 14616, 14618, 14551, 14549, 14548, 14552, 14558, 14559, 14561, + 14560, 14565, 14562, 14563, 14567, 14535, 14533, 35536, 35536, 35536, + 35536, 14431, 14432, 14500, 14501, 14520, 14514, 14515, 14518, 14517, + 14516, 14475, 14460, 14499, 14466, 14470, 14469, 14483, 14482, 14403, + 14428, 14421, 14506, 14419, 14426, 14456, 14449, 14455, 14510, 14451, + 14454, 14453, 14494, 14487, 14504, 14505, 14493, 14491, 14490, 14495, + 14497, 14442, 14441, 14527, 14528, 14392, 14391, 14507, 14446, 14444, + 35536, 35536, 35536, 35536, 18694, 18697, 18698, 18695, 18696, 18700, + 18701, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 2549, 2550, 2548, 2551, 2547, 35536, 35536, 35536, + 35536, 35536, 15040, 15067, 15045, 14976, 15032, 15035, 15037, 15036, + 15031, 15038, 15034, 15033, 14977, 15010, 15011, 15008, 15009, 14974, + 14975, 14973, 14981, 15023, 15021, 14998, 15030, 15003, 35536, 15015, + 15041, 14989, 14984, 15025, 35536, 15027, 35536, 15001, 15005, 35536, + 14991, 14987, 35536, 15019, 14996, 15013, 15007, 15017, 15029, 14980, + 14983, 14986, 15042, 1164, 1163, 1194, 1192, 1193, 1195, 1424, 1422, + 1423, 1425, 1189, 1187, 1188, 1190, 1555, 1553, 1554, 1556, 1534, 1532, + 1533, 1535, 1550, 1548, 1549, 1551, 1568, 1566, 1567, 1569, 1429, 1427, + 1428, 1430, 1230, 1228, 1229, 1231, 1401, 1399, 1400, 1402, 1511, 1509, + 1510, 1512, 1516, 1514, 1515, 1517, 1220, 1219, 1211, 1210, 1234, 1233, + 1223, 1222, 1330, 1329, 1459, 1458, 1353, 1351, 1352, 1354, 1264, 1262, + 1263, 1265, 1276, 1274, 1275, 1277, 1392, 1390, 1391, 1393, 1406, 1405, + 1463, 1461, 1462, 1464, 1306, 1305, 1301, 1299, 1300, 1302, 1310, 1308, + 1309, 1311, 1592, 1591, 1590, 1589, 2411, 2410, 2419, 2418, 2415, 2414, + 2413, 2412, 2423, 2422, 2409, 2417, 2416, 2425, 2421, 2420, 2424, 1756, + 1704, 1933, 1930, 1931, 1926, 1927, 1928, 1920, 1733, 1734, 1731, 1732, + 1956, 1645, 1649, 1396, 1394, 1395, 1397, 1561, 1560, 1614, 1613, 1611, + 1610, 1559, 1571, 1570, 1357, 1356, 1360, 1359, 1627, 1625, 1626, 1628, + 1562, 1563, 2100, 2099, 2102, 2101, 2121, 2120, 2129, 2128, 2119, 2118, + 2125, 2124, 2105, 2103, 2104, 2154, 2152, 2153, 1244, 1242, 1243, 1245, + 2111, 2109, 2115, 2098, 2123, 1675, 1666, 1671, 1678, 1673, 1684, 2063, + 2051, 2058, 2071, 2074, 2079, 2081, 2086, 2083, 2092, 1760, 1766, 1743, + 1738, 1799, 1795, 1801, 1970, 1963, 1975, 1983, 1940, 1944, 1697, 1689, + 1693, 1699, 2044, 2039, 2156, 1640, 1636, 1728, 1724, 1712, 1717, 1708, + 1715, 1710, 1719, 1905, 1901, 1903, 1907, 1774, 1776, 1784, 1782, 1779, + 1790, 1772, 1793, 1827, 1819, 1831, 1837, 1811, 1840, 1858, 1847, 1852, + 1862, 1841, 1863, 1879, 1869, 1891, 1884, 1887, 1894, 1753, 1749, 1750, + 1751, 2139, 2132, 2141, 2147, 2096, 2151, 2080, 1935, 1658, 1991, 1994, + 1998, 1992, 1995, 1997, 2127, 2126, 2113, 2117, 2097, 2122, 1682, 1681, + 1676, 1680, 1672, 1683, 2077, 2076, 2069, 2075, 2073, 2078, 2090, 2089, + 2084, 2088, 2082, 2091, 1709, 1718, 1902, 1906, 1773, 1777, 1788, 1771, + 1792, 1835, 1810, 1839, 1842, 1860, 1892, 1889, 1882, 1888, 1886, 1893, + 1657, 2149, 2136, 2145, 2135, 2095, 2150, 2110, 2108, 2112, 2114, 2106, + 1674, 1665, 1670, 1677, 1667, 2062, 2050, 2057, 2070, 2052, 2085, 1759, + 1765, 1742, 1737, 1798, 1800, 1969, 1962, 1974, 1982, 1939, 1947, 1943, + 1696, 1688, 1692, 1698, 2043, 2155, 1639, 1635, 1727, 1723, 1711, 1716, + 1707, 1714, 1904, 1900, 1775, 1783, 1781, 1778, 1789, 1826, 1818, 1830, + 1836, 1820, 1857, 1846, 1851, 1861, 1878, 1868, 1890, 1883, 1870, 1752, + 1748, 1754, 2138, 2131, 2140, 2146, 2133, 2116, 2107, 1679, 1668, 2072, + 2053, 2087, 2093, 1984, 1966, 2021, 2001, 1780, 1791, 1838, 1885, 1871, + 2148, 2134, 1999, 1993, 1996, 2042, 2046, 1642, 1644, 1726, 1730, 1986, + 1990, 2023, 2031, 1740, 1745, 1768, 1770, 1797, 1803, 1946, 1951, 1695, + 1703, 2012, 2007, 2026, 2020, 2029, 1988, 1949, 1701, 2041, 2045, 1641, + 1643, 1725, 1729, 1985, 1989, 2022, 2030, 1739, 1744, 1767, 1769, 1796, + 1802, 1945, 1950, 1694, 1702, 2010, 2005, 2024, 2018, 2028, 1987, 1948, + 1700, 2011, 2006, 2025, 2019, 1965, 2000, 2038, 1971, 1964, 1976, 2013, + 2008, 2027, 2040, 2157, 1659, 1660, 24956, 24957, 1923, 1914, 1918, 1915, + 1916, 1917, 1957, 1648, 1653, 1651, 1647, 1912, 1959, 1655, 2033, 1925, + 2060, 2049, 2048, 2047, 2055, 2065, 2067, 2066, 1762, 1761, 1736, 1735, + 1961, 1968, 1967, 1978, 1977, 1979, 1981, 1980, 1937, 1936, 1942, 2003, + 2002, 2009, 2015, 2014, 2017, 2016, 1686, 1691, 1690, 2035, 2034, 2036, + 2037, 1638, 1633, 1632, 1631, 1720, 1722, 1721, 1706, 1705, 1898, 1896, + 1816, 1817, 1814, 1821, 1822, 1829, 1828, 1833, 1832, 1843, 1844, 1845, + 1855, 1853, 1848, 1849, 1929, 1932, 1854, 1746, 1747, 1866, 1865, 1876, + 1875, 1874, 1881, 1880, 2143, 2142, 1669, 2061, 2059, 2056, 2054, 2068, + 2064, 1764, 1757, 1763, 1972, 1938, 2004, 1687, 1825, 1834, 2130, 2137, + 2144, 1859, 1899, 1867, 1897, 1815, 1634, 1787, 1872, 1850, 1823, 1786, + 1824, 1873, 1758, 1741, 1856, 1713, 1664, 1785, 1637, 1941, 1973, 1877, + 1924, 1919, 1922, 1921, 1958, 1646, 1794, 1953, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 1954, + 1908, 1661, 1662, 1864, 1952, 1934, 1656, 2094, 1955, 1960, 1755, 26477, + 1685, 2032, 1663, 32839, 32950, 33018, 33029, 33040, 33051, 33062, 33073, + 33084, 32840, 32851, 32862, 32873, 32884, 32895, 32906, 25931, 25936, + 25937, 25930, 25961, 25932, 25963, 25939, 25953, 25935, 35536, 35536, + 35536, 35536, 35536, 35536, 7465, 7467, 7292, 7293, 7476, 7478, 7178, + 7466, 7468, 7541, 7542, 7477, 7479, 7179, 7232, 7233, 25962, 25933, + 25934, 25948, 25960, 25945, 25957, 25943, 25955, 25947, 25959, 25940, + 25949, 25941, 25950, 25944, 25956, 25942, 25954, 25938, 25951, 26972, + 33845, 25946, 25958, 9659, 6231, 33721, 10375, 9658, 6230, 33719, 28147, + 28156, 28191, 35536, 28181, 28148, 28192, 28154, 28155, 28158, 28162, + 28157, 28161, 28159, 28163, 28190, 28138, 28140, 28189, 28187, 28160, + 28186, 28153, 35536, 28180, 28149, 28188, 28146, 35536, 35536, 35536, + 35536, 1098, 2430, 1079, 2432, 1110, 35536, 1095, 1096, 1075, 1076, 1107, + 1108, 2335, 2336, 2405, 2406, 1295, 1159, 1158, 1149, 1148, 1579, 1578, + 1152, 1151, 1596, 1594, 1595, 1597, 1169, 1168, 1184, 1182, 1183, 1185, + 1521, 1520, 1530, 1528, 1529, 1523, 1544, 1542, 1543, 1545, 1326, 1324, + 1325, 1327, 1292, 1290, 1291, 1293, 1364, 1362, 1363, 1365, 1208, 1207, + 1538, 1537, 1456, 1455, 1622, 1621, 1485, 1483, 1484, 1486, 1491, 1489, + 1490, 1492, 1472, 1470, 1471, 1473, 1216, 1214, 1215, 1217, 1504, 1502, + 1503, 1505, 1618, 1616, 1617, 1619, 1127, 1125, 1126, 1128, 1271, 1269, + 1270, 1272, 1255, 1253, 1254, 1256, 1438, 1436, 1437, 1439, 1340, 1338, + 1339, 1341, 1376, 1374, 1375, 1377, 1385, 1383, 1384, 1386, 1417, 1415, + 1416, 1418, 1314, 1312, 1313, 1315, 1583, 1582, 1167, 1166, 1607, 1605, + 1606, 1608, 1809, 1808, 1805, 1804, 1807, 1806, 1813, 1812, 35536, 35536, + 35340, 35536, 12757, 12761, 12729, 12745, 12731, 12743, 12742, 12672, + 12735, 12744, 12732, 12667, 12760, 12765, 12739, 12752, 12754, 12751, + 12750, 12747, 12746, 12749, 12748, 12755, 12753, 12668, 12738, 12674, + 12756, 12759, 12762, 12666, 12675, 12676, 12677, 12678, 12679, 12680, + 12681, 12682, 12683, 12684, 12685, 12686, 12687, 12688, 12689, 12690, + 12691, 12692, 12693, 12694, 12695, 12696, 12697, 12698, 12699, 12700, + 12673, 12737, 12736, 12665, 12727, 12758, 12701, 12702, 12703, 12704, + 12705, 12706, 12707, 12708, 12709, 12710, 12711, 12712, 12713, 12714, + 12715, 12716, 12717, 12718, 12719, 12720, 12721, 12722, 12723, 12724, + 12725, 12726, 12671, 12767, 12734, 12764, 12670, 12733, 14247, 14240, + 14242, 14246, 14238, 14230, 14185, 14187, 14189, 14186, 14188, 14181, + 14183, 14182, 14184, 14239, 14231, 14233, 14235, 14232, 14234, 14206, + 14208, 14210, 14207, 14209, 14190, 14192, 14194, 14191, 14193, 14221, + 14223, 14225, 14222, 14224, 14196, 14198, 14200, 14197, 14199, 14201, + 14203, 14205, 14202, 14204, 14211, 14213, 14215, 14212, 14214, 14226, + 14228, 14227, 14216, 14218, 14220, 14217, 14219, 14229, 14195, 14237, + 14236, 14180, 14130, 14147, 14131, 14132, 14133, 14134, 14168, 14149, + 14138, 14143, 14142, 14141, 14145, 14139, 14140, 14144, 14166, 14136, + 14148, 14137, 14151, 14150, 14165, 14160, 14146, 14159, 14129, 14167, + 14135, 14174, 35536, 35536, 35536, 14175, 14176, 14154, 14155, 14162, + 14161, 35536, 35536, 14153, 14152, 14177, 14171, 14172, 14178, 35536, + 35536, 14157, 14179, 14170, 14169, 14173, 14158, 35536, 35536, 14163, + 14156, 14164, 35536, 35536, 35536, 12669, 12730, 12728, 12741, 12766, + 12740, 12763, 35536, 14244, 14241, 14245, 14243, 14250, 14248, 14249, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 15939, 15941, 15940, 24238, 26169, 35536, 35536, 19657, 19683, 19676, + 19709, 19667, 19658, 19687, 19653, 19665, 19695, 19698, 19692, 35536, + 19681, 19708, 19712, 19691, 19706, 19713, 19720, 19723, 19668, 19719, + 19666, 19669, 19652, 19675, 19678, 19701, 19702, 19660, 19717, 19682, + 19663, 19699, 19661, 19718, 19677, 19685, 35536, 19710, 19674, 19694, + 19659, 19670, 19684, 19655, 19689, 19664, 19696, 19697, 19654, 19680, + 19656, 19707, 19700, 19714, 19688, 19690, 35536, 19662, 19716, 35536, + 19673, 19672, 19686, 19722, 19715, 19725, 19693, 19671, 19703, 19711, + 19679, 19704, 19705, 19721, 19724, 35536, 35536, 19735, 19736, 19738, + 19737, 19726, 19727, 19734, 19728, 19729, 19739, 19730, 19731, 19732, + 19733, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 19541, 19540, 19542, 19529, 19530, + 19531, 19532, 19533, 19534, 19535, 19537, 19536, 19539, 19538, 19547, + 19544, 19545, 19543, 19546, 19646, 19647, 19549, 19548, 19550, 19649, + 19648, 19552, 19553, 19554, 19551, 19555, 19558, 19557, 19559, 19560, + 19561, 19650, 19562, 19563, 19556, 19566, 19567, 19565, 19564, 19568, + 19569, 19570, 19571, 19572, 19573, 19576, 19577, 19578, 19575, 19579, + 19574, 19580, 19581, 19582, 19583, 19584, 19585, 19586, 19587, 19588, + 19589, 19591, 19590, 19592, 19593, 19595, 19596, 19597, 19594, 19598, + 19599, 19600, 19601, 19603, 19602, 19604, 19605, 19651, 19606, 19607, + 19609, 19610, 19611, 19608, 19612, 19613, 19614, 19615, 19616, 19644, + 19624, 19625, 19626, 19627, 19628, 19629, 19630, 19631, 19632, 19633, + 19634, 19635, 19636, 19637, 19638, 19639, 19640, 19641, 19642, 19643, + 19617, 19618, 19619, 19620, 19621, 19622, 19623, 19645, 35536, 35536, + 35536, 35536, 35536, 112, 113, 159, 35536, 35536, 35536, 35536, 156, 151, + 146, 126, 121, 139, 134, 114, 129, 154, 149, 144, 124, 119, 140, 135, + 115, 130, 157, 152, 147, 127, 122, 142, 137, 117, 132, 158, 153, 148, + 128, 123, 143, 138, 118, 133, 155, 150, 145, 125, 120, 141, 136, 116, + 131, 35536, 35536, 35536, 111, 107, 109, 110, 108, 103, 104, 105, 106, + 13314, 13311, 13315, 13301, 13296, 13302, 13305, 13297, 13307, 13316, + 13299, 13309, 13303, 13312, 13306, 13308, 13318, 13300, 13310, 13304, + 13313, 13317, 13298, 13319, 13331, 13340, 13330, 13326, 13339, 13321, + 13327, 13343, 13347, 13348, 13329, 13332, 13338, 13337, 13345, 13346, + 13328, 13335, 13341, 13336, 13325, 13344, 13333, 13320, 13322, 13342, + 13334, 13323, 13324, 13566, 13567, 13765, 13761, 13802, 13767, 13497, + 13571, 13764, 13760, 13503, 13502, 13563, 13545, 13561, 13570, 13565, + 13351, 13350, 13804, 13763, 13805, 13568, 13759, 13541, 24060, 35536, + 26521, 26524, 26519, 26522, 26493, 26523, 26491, 26494, 26520, 26492, + 26525, 26490, 2569, 35536, 35536, 35536, 13758, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 25714, 25715, 25726, 25695, 25698, 25729, + 25707, 25706, 25727, 25734, 25693, 25720, 25699, 25712, 25713, 25722, + 25711, 25692, 25696, 25703, 25701, 25723, 25700, 25691, 25721, 25708, + 25709, 25694, 25697, 25719, 25733, 25704, 25728, 25690, 25716, 25735, + 25717, 25718, 25710, 25732, 25731, 25705, 25724, 25725, 25730, 25702, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 19979, 19981, 19977, 19978, 19986, 19985, 19988, 19996, 19998, 19975, + 19989, 19972, 19992, 19990, 19970, 19983, 19971, 19984, 19995, 19991, + 19973, 19993, 19994, 19974, 19976, 19980, 19982, 19987, 19997, 35536, + 35536, 35536, 6141, 6152, 6143, 6114, 6137, 6153, 6115, 6142, 6159, 6157, + 6117, 6158, 6144, 6132, 6127, 6128, 6126, 6112, 6135, 6125, 6160, 6122, + 6134, 6151, 6131, 6155, 6145, 6140, 6149, 6150, 6123, 6136, 6147, 6148, + 6129, 6130, 6124, 6156, 6113, 6133, 6138, 6154, 6118, 6119, 6120, 6121, + 6116, 6146, 6139, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 7689, 7687, 7685, 7684, + 7681, 7680, 7683, 7682, 7688, 7686, 7679, 7678, 7676, 7667, 7665, 7674, + 7672, 7663, 7669, 7670, 7677, 7675, 7666, 7664, 7673, 7671, 7662, 7668, + 35536, 35536, 35536, 35536, 24519, 24513, 24499, 24514, 24486, 24516, + 24518, 24515, 24510, 24506, 24498, 24494, 24495, 24496, 24488, 24520, + 24509, 24502, 24500, 24490, 24487, 24511, 24504, 24492, 24508, 24497, + 24493, 24491, 24512, 24507, 24505, 24489, 24524, 24522, 24523, 24521, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 24517, + 24503, 24501, 13161, 13177, 13185, 13179, 13160, 13170, 13164, 13163, + 13172, 13181, 13186, 13182, 13180, 13168, 13184, 13175, 13169, 13167, + 13171, 13183, 13173, 13174, 13176, 13165, 13162, 13178, 13166, 35536, + 35536, 35536, 35536, 35536, 24591, 24590, 24587, 24560, 24561, 24583, + 24558, 24584, 24559, 24563, 24592, 24585, 24566, 24567, 24574, 24568, + 24586, 24571, 24573, 24594, 24557, 24570, 24569, 24581, 24578, 24588, + 24589, 24562, 24593, 24572, 24575, 24576, 24577, 24580, 24565, 24582, + 24579, 24564, 7494, 7492, 7490, 7491, 7493, 35536, 35536, 35536, 35536, + 35536, 32287, 32290, 32294, 32298, 32291, 32295, 32313, 32309, 32296, + 32306, 32308, 32297, 32303, 32299, 32314, 32292, 32311, 32310, 32302, + 32288, 32312, 32301, 32289, 32300, 32305, 32293, 32307, 32315, 32316, + 32304, 35536, 32317, 24600, 24642, 24643, 24623, 24624, 24621, 24622, + 24620, 24635, 24612, 24613, 24617, 24618, 24607, 24610, 24611, 24616, + 24639, 24604, 24636, 24625, 24626, 24629, 24630, 24631, 24640, 24614, + 24615, 24627, 24628, 24638, 24634, 24641, 24632, 24633, 24637, 35536, + 35536, 35536, 35536, 24601, 24602, 24603, 24619, 24608, 24609, 24605, + 24606, 24644, 24599, 24596, 24597, 24595, 24598, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 9713, + 9712, 9708, 9709, 9710, 9711, 9719, 9718, 9714, 9715, 9716, 9717, 9736, + 9721, 9735, 9732, 9737, 9730, 9727, 9723, 9728, 9726, 9729, 9734, 9733, + 9703, 9731, 9702, 9722, 9698, 9725, 9699, 9724, 9706, 9704, 9705, 9700, + 9701, 9720, 9707, 9753, 9752, 9748, 9749, 9750, 9751, 9759, 9758, 9754, + 9755, 9756, 9757, 9776, 9761, 9775, 9772, 9777, 9770, 9767, 9763, 9768, + 9766, 9769, 9774, 9773, 9743, 9771, 9742, 9762, 9738, 9765, 9739, 9764, + 9746, 9744, 9745, 9740, 9741, 9760, 9747, 27116, 27122, 27133, 27130, + 27120, 27119, 27118, 27097, 27125, 27103, 27132, 27128, 27131, 27134, + 27121, 27129, 27108, 27127, 27124, 27102, 27107, 27109, 27106, 27101, + 27095, 27092, 27114, 27123, 27112, 27096, 27117, 27135, 27099, 27093, + 27105, 27136, 27113, 27110, 27111, 27094, 27090, 27115, 27091, 27100, + 27089, 27098, 27104, 27126, 25034, 25052, 25058, 25056, 25059, 25040, + 25037, 25057, 25042, 25041, 25038, 25036, 25054, 25053, 25044, 25039, + 25047, 25043, 25048, 25049, 25055, 25060, 25033, 25050, 25061, 25045, + 25062, 25035, 25051, 25046, 35536, 35536, 25069, 25071, 25068, 25067, + 25064, 25063, 25066, 25065, 25072, 25070, 35536, 35536, 35536, 35536, + 35536, 35536, 24961, 24962, 24963, 24964, 24989, 24982, 24968, 24965, + 24971, 24981, 24980, 24995, 24974, 24969, 24973, 24990, 24991, 24992, + 24975, 24976, 24993, 24970, 24986, 24985, 24979, 24967, 24978, 24966, + 24977, 24983, 24996, 24994, 24972, 24984, 24988, 24987, 35536, 35536, + 35536, 35536, 24997, 24998, 24999, 25000, 25025, 25018, 25004, 25001, + 25007, 25017, 25016, 25031, 25010, 25005, 25009, 25026, 25027, 25028, + 25011, 25012, 25029, 25006, 25022, 25021, 25015, 25003, 25014, 25002, + 25013, 25019, 25032, 25030, 25008, 25020, 25024, 25023, 35536, 35536, + 35536, 35536, 11818, 11809, 11798, 11797, 11800, 11789, 11799, 11796, + 11795, 11810, 11786, 11785, 11811, 11819, 11812, 11802, 11788, 11787, + 11813, 11792, 11791, 11790, 11820, 11814, 11815, 11794, 11793, 11804, + 11803, 11806, 11805, 11821, 11816, 11817, 11822, 11808, 11807, 11784, + 11783, 11801, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 6173, 6222, 6189, 6185, 6187, 6212, 6186, 6210, 6207, 6176, 6209, 6211, + 6190, 6201, 6197, 6192, 6220, 6184, 6175, 6193, 6196, 6198, 6223, 6214, + 6172, 6178, 6179, 6181, 6215, 6213, 6218, 6182, 6202, 6194, 6221, 6206, + 6217, 6183, 6177, 6200, 6188, 6219, 6204, 6216, 6205, 6203, 6191, 6180, + 6174, 6208, 6199, 6195, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 6224, 33492, 33461, 33462, 33472, 33471, + 33474, 33473, 33464, 33463, 33481, 33489, 35536, 33480, 33479, 33465, + 33466, 33482, 33490, 33468, 33467, 33483, 33470, 33469, 33493, 33484, + 33491, 33485, 35536, 33476, 33475, 33478, 33477, 33494, 33486, 33487, + 35536, 33495, 33488, 35536, 33527, 33496, 33497, 33507, 33506, 33509, + 33508, 33499, 33498, 33516, 33524, 35536, 33515, 33514, 33500, 33501, + 33517, 33525, 33503, 33502, 33518, 33505, 33504, 33528, 33519, 33526, + 33520, 35536, 33511, 33510, 33513, 33512, 33529, 33521, 33522, 35536, + 33530, 33523, 35536, 35536, 35536, 31948, 31949, 31962, 31922, 31951, + 31950, 31953, 31929, 31952, 31945, 31944, 31963, 31919, 31925, 31918, + 31924, 31932, 31931, 31966, 31920, 31955, 31947, 31946, 31923, 31930, + 31926, 31942, 31934, 31964, 31941, 31940, 31939, 31936, 31935, 31957, + 31956, 31967, 31965, 31959, 31928, 31958, 31927, 31968, 31921, 31961, + 31960, 31917, 31938, 31937, 31954, 31933, 31943, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 19508, + 19509, 19510, 19511, 19512, 19513, 19514, 19515, 19516, 19447, 19448, + 19449, 19450, 19451, 19460, 19452, 19453, 19454, 19455, 19456, 19457, + 19458, 19459, 19461, 19462, 19463, 19464, 19528, 19465, 19466, 19467, + 19468, 19469, 19470, 19471, 19472, 19473, 19474, 19475, 19476, 19477, + 19478, 19479, 19480, 19481, 19482, 19483, 19484, 19485, 19486, 19487, + 19488, 19489, 19490, 19491, 19492, 19493, 19494, 19495, 19496, 19497, + 19498, 19499, 19500, 19501, 19502, 19503, 19504, 19505, 19506, 19507, + 19188, 19524, 19517, 19189, 19518, 19519, 19520, 19521, 19190, 19525, + 19526, 19522, 19523, 19527, 19194, 19195, 19196, 19197, 19198, 19199, + 19200, 19201, 19191, 19192, 19193, 19205, 19206, 19207, 19202, 19203, + 19204, 19208, 19209, 19210, 19211, 19212, 19213, 19216, 19217, 19218, + 19219, 19220, 19221, 19222, 19223, 19224, 19225, 19226, 19227, 19228, + 19229, 19230, 19231, 19232, 19233, 19234, 19235, 19236, 19237, 19238, + 19239, 19240, 19241, 19242, 19243, 19244, 19245, 19246, 19247, 19248, + 19249, 19250, 19251, 19252, 19253, 19254, 19255, 19256, 19257, 19258, + 19259, 19260, 19261, 19262, 19263, 19264, 19265, 19214, 19215, 19266, + 19267, 19268, 19269, 19270, 19271, 19272, 19273, 19274, 19275, 19276, + 19277, 19278, 19279, 19280, 19281, 19282, 19283, 19284, 19285, 19286, + 19287, 19288, 19289, 19290, 19291, 19292, 19293, 19294, 19295, 19296, + 19297, 19298, 19330, 19331, 19332, 19333, 19334, 19335, 19336, 19337, + 19338, 19299, 19300, 19301, 19302, 19303, 19304, 19305, 19306, 19307, + 19308, 19309, 19310, 19311, 19312, 19313, 19314, 19315, 19316, 19317, + 19318, 19319, 19320, 19321, 19322, 19323, 19324, 19325, 19326, 19327, + 19328, 19329, 19345, 19346, 19347, 19348, 19349, 19350, 19351, 19352, + 19353, 19354, 19355, 19356, 19357, 19358, 19359, 19360, 19361, 19362, + 19363, 19364, 19339, 19340, 19341, 19342, 19343, 19344, 19365, 19366, + 19367, 19368, 19369, 19370, 19371, 19372, 19407, 19408, 19409, 19410, + 19411, 19412, 19413, 19414, 19415, 19416, 19373, 19374, 19375, 19376, + 19377, 19378, 19379, 19380, 19381, 19382, 19383, 19384, 19385, 19386, + 19387, 19388, 19389, 19390, 19391, 19392, 19398, 19399, 19400, 19401, + 19402, 19403, 19404, 19405, 19406, 19393, 19394, 19395, 19396, 19397, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 19428, + 19423, 19426, 19425, 19429, 19424, 19422, 19427, 19421, 19417, 19420, + 19419, 19418, 19435, 19433, 19434, 19430, 19431, 19432, 19436, 19438, + 19437, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 19439, 19440, 19441, 19442, 19443, 19444, 19445, 19446, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 22568, 22689, 22688, 22553, 22569, 22557, 35536, + 22587, 22589, 22588, 22583, 22582, 22580, 22581, 22642, 22575, 22599, + 22639, 22563, 22603, 22564, 22607, 22570, 22609, 22586, 22623, 22624, + 22622, 22566, 22620, 22625, 22626, 22667, 22668, 22631, 22567, 22576, + 22682, 22664, 22665, 22638, 22637, 22572, 22652, 22655, 22656, 22653, + 22651, 22679, 35536, 22574, 22494, 22541, 22388, 22472, 22501, 22385, + 22543, 22644, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 9126, 9127, 9128, 9129, 9130, 9120, 35536, 35536, 9121, 35536, + 9076, 9077, 9078, 9079, 9080, 9081, 9082, 9083, 9084, 9085, 9086, 9087, + 9088, 9089, 9090, 9091, 9092, 9093, 9094, 9095, 9096, 9097, 9098, 9099, + 9100, 9101, 9102, 9103, 9104, 9105, 9106, 9107, 9108, 9109, 9110, 9111, + 9112, 9113, 9114, 9115, 9116, 9117, 9118, 9119, 35536, 9124, 9125, 35536, + 35536, 35536, 9122, 35536, 35536, 9123, 15761, 15772, 15763, 15757, + 15769, 15774, 15764, 15770, 15755, 15768, 15771, 15758, 15776, 15773, + 15765, 15762, 15775, 15766, 15759, 15760, 15767, 15756, 35536, 15777, + 15752, 15748, 15751, 15749, 15747, 15753, 15754, 15750, 25342, 25353, + 25344, 25338, 25350, 25355, 25345, 25351, 25336, 25349, 25352, 25339, + 25357, 25335, 25354, 25346, 25343, 25356, 25347, 25340, 25341, 25348, + 25337, 25334, 25358, 25365, 25360, 25361, 25364, 25363, 25362, 25359, + 23506, 23521, 23511, 23532, 23523, 23517, 23513, 23529, 23534, 23524, + 23530, 23515, 23509, 23528, 23510, 23531, 23507, 23518, 23514, 23536, + 23512, 23533, 23525, 23522, 23535, 23526, 23519, 23520, 23508, 23527, + 23516, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 23541, + 23538, 23539, 23544, 23545, 23543, 23540, 23537, 23542, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 14807, 14823, 14815, 14814, + 14820, 14825, 14809, 14821, 14810, 14819, 14822, 14812, 14827, 14824, + 14816, 14808, 14826, 14817, 14813, 35536, 14818, 14811, 35536, 35536, + 35536, 35536, 35536, 14828, 14832, 14831, 14830, 14829, 25738, 25757, + 25753, 25740, 25741, 25749, 25750, 25742, 25748, 25751, 25754, 25756, + 25759, 25755, 25746, 25739, 25758, 25744, 25743, 25752, 25745, 25747, + 25764, 25763, 25760, 25765, 25761, 25762, 35536, 35536, 35536, 25766, + 20005, 20011, 20015, 20013, 20007, 20023, 20016, 20024, 20017, 20001, + 20018, 20009, 20019, 20021, 20004, 19999, 20022, 20014, 20020, 20003, + 20000, 20006, 20008, 20002, 20010, 20012, 35536, 35536, 35536, 35536, + 35536, 20025, 27274, 27275, 27276, 27277, 27278, 27279, 27280, 27281, + 27282, 27283, 27284, 27285, 27286, 27287, 27288, 27289, 27290, 27291, + 27292, 27267, 27268, 27269, 27270, 27271, 27272, 27273, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 22100, 22101, 22102, 22103, + 22099, 22098, 22074, 22075, 22096, 22095, 22078, 22079, 22080, 22081, + 22076, 22077, 22094, 22091, 22090, 22082, 22083, 22084, 22092, 22097, + 22085, 22086, 22087, 22088, 22089, 22093, 22104, 22105, 21996, 22017, + 22018, 22019, 22016, 22015, 22008, 22012, 22011, 22001, 22002, 22014, + 22010, 22006, 22005, 22003, 21997, 22004, 22007, 22013, 21998, 21999, + 22000, 22009, 35536, 35536, 35536, 35536, 21984, 21989, 22021, 22020, + 22070, 22062, 22056, 22033, 22027, 22050, 22044, 22022, 22039, 22068, + 22066, 22060, 22037, 22031, 22054, 22048, 35536, 35536, 22071, 22063, + 22057, 22034, 22028, 22051, 22045, 22024, 22041, 22073, 22065, 22059, + 22036, 22030, 22053, 22047, 22026, 22043, 22069, 22067, 22061, 22038, + 22032, 22055, 22049, 22023, 22040, 22072, 22064, 22058, 22035, 22029, + 22052, 22046, 22025, 22042, 21988, 21994, 21993, 21987, 21986, 21991, + 21990, 21985, 21995, 21992, 16822, 16844, 16846, 16842, 35536, 16843, + 16845, 35536, 35536, 35536, 35536, 35536, 16847, 16838, 16841, 16840, + 16788, 16786, 16810, 16809, 35536, 16808, 16807, 16816, 35536, 16796, + 16792, 16791, 16799, 16798, 16795, 16794, 16793, 16801, 16800, 16797, + 16812, 16811, 16806, 16805, 16818, 16820, 16819, 16817, 16814, 16802, + 16803, 16804, 16821, 16815, 16787, 16789, 16790, 16813, 35536, 35536, + 16836, 16837, 16839, 35536, 35536, 35536, 35536, 16848, 16785, 16784, + 16783, 16782, 16824, 16823, 16825, 16826, 16849, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 16830, 16835, 16828, 16827, 16834, 16832, + 16831, 16829, 16833, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 24709, 24705, 24710, 24715, 24706, 24713, 24699, 24707, 24711, 24703, + 24698, 24694, 24712, 24695, 24697, 24696, 24714, 24687, 24688, 24690, + 24693, 24691, 24692, 24702, 24704, 24689, 24708, 24701, 24700, 24717, + 24716, 24718, 24530, 24548, 24529, 24539, 24551, 24552, 24541, 24545, + 24543, 24536, 24540, 24532, 24547, 24531, 24553, 24542, 24544, 24525, + 24526, 24549, 24528, 24550, 24527, 24535, 24537, 24533, 24546, 24534, + 24538, 24556, 24555, 24554, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 20306, 20310, 20309, 20314, + 20313, 20311, 20335, 20338, 20354, 20318, 20317, 20316, 20315, 20336, + 20328, 20334, 20320, 20330, 20319, 20332, 20312, 20327, 20341, 20337, + 20324, 20308, 20307, 20340, 20339, 20325, 20322, 20331, 20321, 20333, + 20326, 20323, 20329, 20356, 20355, 35536, 35536, 35536, 35536, 20342, + 20346, 20345, 20344, 20343, 20353, 20351, 20349, 20348, 20347, 20352, + 20350, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 2587, 2588, 2594, 2590, 2593, 2589, 2591, 2592, 2630, 2631, 2620, 2621, + 2622, 2623, 2618, 2619, 2635, 2608, 2607, 2606, 2597, 2595, 2596, 2632, + 2634, 2617, 2615, 2627, 2626, 2616, 2638, 2633, 2625, 2624, 2602, 2601, + 2600, 2605, 2604, 2603, 2637, 2598, 2613, 2614, 2640, 2639, 2636, 2612, + 2629, 2610, 2628, 2609, 2611, 2599, 35536, 35536, 35536, 2641, 31830, + 28182, 17352, 17347, 17353, 17348, 15903, 15914, 15905, 15899, 15911, + 15916, 15906, 15912, 15897, 15910, 15913, 15900, 15918, 15915, 15907, + 15904, 15917, 15908, 15901, 15902, 15909, 15898, 35536, 35536, 15923, + 15920, 15921, 15926, 15922, 15919, 15924, 15925, 15872, 15886, 15877, + 15873, 15883, 15876, 15878, 15884, 15870, 15882, 15885, 15874, 15875, + 15887, 15879, 15888, 15880, 15881, 15871, 35536, 35536, 35536, 35536, + 35536, 15893, 15890, 15891, 15896, 15892, 15889, 15894, 15895, 25999, + 26013, 26004, 26000, 26010, 26003, 26005, 26011, 26009, 26012, 26001, + 26002, 26014, 26006, 26016, 26007, 26008, 26015, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 26024, 26025, 25997, 25998, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 26021, 26018, 26019, 26023, 26020, 26017, 26022, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 24719, 24761, 24762, + 24751, 24787, 24780, 24754, 24755, 24789, 24732, 24772, 24720, 24765, + 24734, 24774, 24722, 24766, 24733, 24773, 24721, 24750, 24786, 24740, + 24779, 24729, 24769, 24723, 24767, 24756, 24790, 24735, 24775, 24724, + 24745, 24748, 24736, 24725, 24763, 24743, 24782, 24741, 24781, 24744, + 24783, 24771, 24742, 24764, 24749, 24757, 24752, 24747, 24785, 24737, + 24776, 24753, 24788, 24758, 24791, 24738, 24777, 24726, 24730, 24727, + 24731, 24770, 24746, 24784, 24739, 24778, 24728, 24768, 24759, 24760, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 24378, 24381, 24404, 24379, 24393, + 24389, 24395, 24405, 24380, 24383, 24426, 24406, 24407, 24396, 24397, + 24408, 24427, 24428, 24409, 24410, 24382, 24423, 24398, 24399, 24384, + 24386, 24390, 24418, 24420, 24414, 24416, 24419, 24411, 24385, 24412, + 24421, 24391, 24392, 24400, 24387, 24401, 24394, 24422, 24425, 24415, + 24417, 24413, 24402, 24403, 24388, 24424, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 24429, + 24432, 24455, 24430, 24444, 24440, 24446, 24456, 24431, 24434, 24477, + 24457, 24458, 24447, 24448, 24459, 24478, 24479, 24460, 24461, 24433, + 24474, 24449, 24450, 24435, 24437, 24441, 24469, 24471, 24465, 24467, + 24470, 24462, 24436, 24463, 24472, 24442, 24443, 24451, 24438, 24452, + 24445, 24473, 24476, 24466, 24468, 24464, 24453, 24454, 24439, 24475, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 24482, 24481, 24485, + 24480, 24483, 24484, 14760, 14747, 14755, 14739, 14738, 14752, 14748, + 14751, 14736, 14749, 14733, 14732, 14741, 14740, 14759, 14746, 14745, + 14737, 14750, 14753, 14754, 14744, 14757, 14734, 14758, 14735, 14742, + 14743, 14756, 14767, 14769, 14771, 14768, 14770, 14762, 14761, 14766, + 14763, 14765, 14764, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 14778, 14780, 14777, 14776, 14773, 14772, 14775, 14774, 14781, + 14779, 35536, 35536, 35536, 35536, 35536, 35536, 12845, 12847, 12844, + 12843, 12840, 12839, 12842, 12841, 12848, 12846, 12831, 12832, 12833, + 12830, 12834, 12828, 12805, 12789, 12797, 12795, 12788, 12794, 12800, + 12802, 12796, 12792, 12790, 12803, 12804, 12801, 12799, 12786, 12791, + 12787, 12798, 12793, 12784, 12785, 35536, 35536, 35536, 12829, 12783, + 12781, 12780, 12782, 12836, 12835, 12827, 12811, 12819, 12817, 12810, + 12816, 12822, 12824, 12818, 12814, 12812, 12825, 12826, 12823, 12821, + 12808, 12813, 12809, 12820, 12815, 12806, 12807, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 12837, 12838, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 26578, 26576, 26575, 26572, 26571, + 26574, 26573, 26579, 26577, 26570, 26569, 26567, 26558, 26556, 26565, + 26563, 26554, 26560, 26561, 26568, 26566, 26557, 26555, 26564, 26562, + 26553, 26559, 26550, 26551, 26549, 26552, 35536, 33993, 34027, 34007, + 34006, 34012, 34011, 33989, 33988, 33987, 33998, 34019, 33992, 34023, + 34026, 34025, 34022, 34030, 34009, 34008, 34010, 33991, 34013, 34024, + 33994, 34018, 34029, 34014, 34015, 34002, 34000, 33999, 34001, 34003, + 33990, 34005, 34028, 34016, 34017, 33996, 33997, 34020, 33995, 35536, + 33985, 33984, 33986, 35536, 35536, 34004, 34021, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 1201, 1497, 1332, 2388, 1540, 1604, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 1065, 1654, 1652, 1650, 1909, + 1910, 1911, 1913, 1895, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 1083, 2389, 1066, 2395, 2396, + 2393, 24649, 24657, 24671, 24658, 24662, 24668, 24659, 24674, 24663, + 24669, 24667, 24670, 24661, 24676, 24672, 24651, 24652, 24664, 24650, + 24648, 24675, 24665, 24653, 24654, 24660, 24666, 24673, 24655, 24656, + 24683, 24681, 24678, 24686, 24685, 24682, 24680, 24679, 24684, 24647, + 24677, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 28242, + 28256, 28244, 28253, 28260, 28248, 28254, 28252, 28255, 28245, 28262, + 28258, 28249, 28243, 28261, 28250, 28247, 28251, 28259, 28257, 28246, + 28241, 28236, 28234, 28237, 28235, 28240, 28239, 28231, 28230, 28232, + 28238, 28233, 28263, 28266, 28265, 28264, 28269, 28270, 28267, 28271, + 28268, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 24796, 24808, 24806, 24811, 24800, 24805, 24804, + 24807, 24798, 24813, 24809, 24801, 24812, 24802, 24797, 24803, 24810, + 24799, 24795, 24794, 24793, 24792, 24817, 24814, 24815, 24816, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 6596, 6590, 6604, 6598, + 6593, 6601, 6607, 6589, 6599, 6602, 6600, 6603, 6594, 6609, 6605, 6591, + 6597, 6608, 6595, 6592, 6606, 6614, 6611, 6612, 6616, 6613, 6610, 6615, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 11845, 11856, 11847, 11841, 11853, 11858, 11848, 11854, 11839, 11852, + 11855, 11842, 11860, 11857, 11849, 11846, 11859, 11850, 11843, 11844, + 11851, 11840, 11861, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 4737, 4742, 4740, 4739, 4741, 4664, 4665, 4683, 4684, 4681, + 4682, 4676, 4677, 4678, 4679, 4710, 4666, 4657, 4667, 4703, 4702, 4699, + 4698, 4687, 4697, 4696, 4701, 4700, 4689, 4673, 4672, 4669, 4668, 4688, + 4675, 4674, 4671, 4670, 4690, 4705, 4704, 4695, 4694, 4707, 4709, 4708, + 4686, 4680, 4691, 4692, 4693, 4706, 4685, 4658, 4663, 4662, 4747, 4746, + 4756, 4757, 4750, 4751, 4752, 4753, 4754, 4755, 4758, 4748, 4743, 4749, + 4759, 4761, 4760, 4735, 4734, 4733, 4736, 4732, 35536, 35536, 35536, + 35536, 4728, 4726, 4723, 4714, 4716, 4721, 4719, 4711, 4717, 4727, 4725, + 4724, 4713, 4715, 4722, 4720, 4712, 4718, 4729, 4730, 4768, 4770, 4767, + 4766, 4763, 4762, 4765, 4764, 4771, 4769, 4738, 4660, 4661, 4744, 4745, + 4659, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 4731, 16132, 16134, 16136, 16092, 16093, 16102, 16103, 16100, 16101, + 16130, 16094, 16131, 16095, 16120, 16119, 16116, 16115, 16104, 16114, + 16113, 16118, 16117, 16106, 16097, 16096, 16089, 16087, 16088, 16123, + 16105, 16099, 16098, 16091, 16090, 16107, 16122, 16121, 16112, 16111, + 16127, 16129, 16124, 16126, 16128, 16108, 16109, 16110, 16125, 16142, + 16147, 16148, 16145, 16146, 16149, 16143, 16150, 16144, 16135, 16133, + 16153, 16154, 16151, 16137, 16138, 16140, 16139, 16141, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 16152, 35536, + 35536, 28294, 28295, 28284, 28285, 28286, 28287, 28280, 28281, 28291, + 28283, 28296, 28292, 28297, 28293, 28288, 28290, 28289, 28282, 28298, + 28277, 28299, 28301, 28300, 28278, 28279, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 28308, 28310, 28307, 28306, 28303, 28302, 28305, + 28304, 28311, 28309, 35536, 35536, 35536, 35536, 35536, 35536, 6276, + 6278, 6277, 6272, 6274, 6275, 6273, 6261, 6260, 6257, 6256, 6242, 6255, + 6254, 6259, 6258, 6244, 6247, 6246, 6239, 6238, 6243, 6249, 6248, 6241, + 6240, 6245, 6265, 6264, 6253, 6252, 6267, 6250, 6251, 6268, 6263, 6271, + 6269, 6266, 6280, 6288, 6289, 6284, 6285, 6286, 6282, 6290, 6283, 6291, + 6308, 6307, 6292, 6306, 35536, 6301, 6303, 6300, 6299, 6296, 6295, 6298, + 6297, 6304, 6302, 6279, 6294, 6293, 6305, 6262, 6281, 6287, 6270, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 20067, 20069, 20071, + 20068, 20070, 20059, 20058, 20055, 20054, 20053, 20052, 20057, 20056, + 20038, 20047, 20046, 20041, 20040, 20037, 20049, 20048, 20043, 20042, + 20039, 20061, 20060, 20051, 20050, 20064, 20045, 20063, 20066, 20065, + 20062, 20044, 20074, 20075, 20073, 20072, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 27052, 27055, 27059, 26998, 26999, + 27017, 27018, 27015, 27016, 27010, 27011, 27012, 27013, 27044, 27000, + 27045, 27001, 27037, 27036, 27033, 27032, 27021, 27031, 27030, 27035, + 27034, 27023, 27007, 27006, 27003, 27002, 27022, 27009, 27008, 27005, + 27004, 27024, 27039, 27038, 27029, 27028, 27041, 27043, 27042, 27020, + 27019, 27014, 27025, 27026, 27027, 27040, 27074, 27081, 27082, 27068, + 27069, 27077, 27078, 27079, 27080, 27083, 27075, 27064, 27076, 27058, + 27054, 27056, 27057, 27086, 26984, 26983, 27084, 27049, 27046, 27053, + 27061, 26995, 27060, 27067, 27050, 26991, 26993, 26990, 26989, 26986, + 26985, 26988, 26987, 26994, 26992, 26996, 27051, 26997, 27085, 27047, + 27048, 35536, 27996, 27994, 27993, 27990, 27989, 27992, 27991, 27997, + 27995, 28008, 28007, 28006, 28002, 28001, 28005, 28004, 28000, 28003, + 27998, 27999, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 17056, 17057, 17083, 17085, 17082, 17058, 17084, + 17059, 17073, 17072, 17048, 17046, 17047, 17066, 17071, 17070, 17055, + 17054, 35536, 17068, 17061, 17060, 17051, 17050, 17067, 17063, 17062, + 17053, 17049, 17052, 17069, 17075, 17074, 17045, 17043, 17044, 17077, + 17081, 17079, 17065, 17080, 17042, 17076, 17064, 17093, 17096, 17097, + 17100, 17098, 17094, 17099, 17095, 17090, 17089, 17088, 17086, 17040, + 17039, 17101, 17091, 17038, 17102, 17087, 17078, 17041, 17092, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 22981, 22983, 22984, 22982, 22972, 22971, 22970, 35536, 22969, + 35536, 22968, 22967, 22960, 22959, 35536, 22954, 22962, 22961, 22950, + 22948, 22949, 22953, 22964, 22963, 22952, 22951, 22955, 22974, 22973, + 22966, 35536, 22965, 22977, 22980, 22958, 22976, 22979, 22978, 22975, + 22957, 22956, 22985, 35536, 35536, 35536, 35536, 35536, 35536, 17117, + 17118, 17129, 17130, 17127, 17128, 17148, 17119, 17149, 17120, 17138, + 17137, 17108, 17106, 17107, 17131, 17136, 17135, 17116, 17115, 17114, + 17133, 17124, 17123, 17111, 17109, 17121, 17110, 17132, 17126, 17125, + 17113, 17112, 17134, 17140, 17139, 17105, 17103, 17104, 17145, 17147, + 17122, 17144, 17146, 17141, 17142, 17143, 17152, 17153, 17158, 17159, + 17156, 17157, 17160, 17154, 17161, 17155, 17150, 17151, 35536, 35536, + 35536, 35536, 35536, 17168, 17170, 17167, 17166, 17163, 17162, 17165, + 17164, 17171, 17169, 35536, 35536, 35536, 35536, 35536, 35536, 13243, + 13244, 13247, 13250, 35536, 13200, 13201, 13214, 13215, 13212, 13213, + 13195, 13197, 35536, 35536, 13238, 13202, 35536, 35536, 13237, 13203, + 13234, 13233, 13230, 13229, 13218, 13228, 13227, 13232, 13231, 13220, + 13209, 13208, 13205, 13204, 13219, 13211, 13210, 13207, 13206, 13221, + 35536, 13236, 13235, 13226, 13225, 13240, 13242, 13241, 35536, 13217, + 13216, 35536, 13199, 13222, 13223, 13224, 13239, 35536, 7169, 13245, + 13246, 13252, 13261, 13262, 13255, 13256, 13257, 13258, 35536, 35536, + 13264, 13253, 35536, 35536, 13263, 13254, 13249, 35536, 35536, 13265, + 35536, 35536, 35536, 35536, 35536, 35536, 13251, 35536, 35536, 35536, + 35536, 35536, 13248, 13194, 13193, 13196, 13198, 13259, 13260, 35536, + 35536, 7358, 7359, 7357, 7356, 7355, 7354, 7353, 35536, 35536, 35536, + 7364, 7361, 7362, 7360, 7363, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 32166, 32167, 32190, 32191, 32188, + 32189, 32183, 32184, 32185, 32186, 35536, 32212, 35536, 35536, 32168, + 35536, 32211, 32169, 32208, 32207, 32204, 32203, 32192, 32202, 32201, + 32206, 32205, 32194, 32180, 32179, 32171, 32170, 32193, 32182, 32181, + 32173, 32172, 32195, 32210, 32209, 32200, 32199, 32214, 32215, 32178, + 32176, 32187, 32196, 32197, 32198, 32213, 32175, 32177, 32174, 35536, + 32217, 32228, 32237, 32238, 32231, 32232, 32233, 32234, 32235, 32236, + 35536, 32240, 35536, 35536, 32229, 35536, 32239, 32230, 32161, 32222, + 35536, 32218, 32225, 32224, 32219, 32162, 32216, 32165, 32223, 32164, + 32163, 35536, 32220, 32221, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 32227, 32226, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 23904, 23905, 23918, 23919, 23916, 23917, 23900, + 23901, 23902, 23903, 23944, 23906, 23945, 23907, 23932, 23931, 23928, + 23927, 23893, 23892, 23926, 23925, 23930, 23929, 23895, 23894, 23913, + 23912, 23909, 23908, 23897, 23915, 23914, 23911, 23910, 23898, 23896, + 23938, 23937, 23924, 23923, 23936, 23935, 23943, 23940, 23939, 23934, + 23933, 23942, 23920, 23921, 23922, 23941, 23958, 23967, 23968, 23961, + 23962, 23963, 23964, 23965, 23966, 23969, 23959, 23970, 23960, 23953, + 23946, 23949, 23954, 23947, 23948, 23951, 23974, 23955, 23880, 23878, + 23973, 23891, 23971, 23887, 23889, 23886, 23885, 23882, 23881, 23884, + 23883, 23890, 23888, 23879, 23957, 35536, 23972, 23956, 23899, 23950, + 23952, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 31832, 31833, 31834, 31852, 31853, 31850, 31851, 31845, 31846, + 31847, 31848, 31878, 31835, 31879, 31836, 31870, 31869, 31866, 31865, + 31854, 31864, 31863, 31868, 31867, 31856, 31842, 31841, 31838, 31837, + 31855, 31844, 31843, 31840, 31839, 31857, 31872, 31871, 31862, 31861, + 31875, 31877, 31876, 31874, 31849, 31858, 31859, 31860, 31873, 31888, + 31897, 31898, 31891, 31892, 31893, 31894, 31895, 31896, 31899, 31886, + 31889, 31900, 31887, 31890, 31880, 31883, 31885, 31884, 31881, 31882, + 31911, 31831, 31912, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 31907, 31909, 31906, 31905, 31902, 31901, 31904, 31903, 31910, + 31908, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 27176, 27178, 27199, + 27200, 27197, 27198, 27192, 27193, 27194, 27195, 27225, 27179, 27226, + 27180, 27217, 27216, 27213, 27212, 27201, 27211, 27210, 27215, 27214, + 27203, 27186, 27185, 27189, 27188, 27202, 27187, 27182, 27191, 27190, + 27204, 27219, 27218, 27209, 27208, 27222, 27224, 27223, 27221, 27196, + 27205, 27206, 27207, 27220, 27254, 27261, 27262, 27259, 27260, 27257, + 27258, 35536, 35536, 27263, 27255, 27264, 27256, 27247, 27249, 27251, + 27250, 27248, 27246, 27266, 27265, 27245, 27244, 27227, 27228, 27229, + 27175, 27242, 27241, 27239, 27237, 27238, 27230, 27231, 27240, 27243, + 27235, 27236, 27234, 27233, 27232, 27181, 27183, 27184, 27177, 27252, + 27253, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 22335, 22336, 22354, 22355, 22352, + 22353, 22347, 22348, 22349, 22350, 22381, 22337, 22382, 22338, 22374, + 22373, 22370, 22369, 22358, 22368, 22367, 22372, 22371, 22360, 22344, + 22343, 22340, 22339, 22359, 22346, 22345, 22342, 22341, 22361, 22376, + 22375, 22366, 22365, 22378, 22380, 22379, 22357, 22351, 22362, 22363, + 22364, 22377, 22356, 22310, 22319, 22320, 22313, 22314, 22315, 22316, + 22317, 22318, 22321, 22311, 22322, 22312, 22306, 22309, 22308, 22305, + 22324, 22323, 22383, 22307, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 22331, 22333, 22330, 22329, 22326, + 22325, 22328, 22327, 22334, 22332, 35536, 35536, 35536, 35536, 35536, + 35536, 22864, 22859, 22704, 22865, 22863, 22861, 22860, 22721, 22722, + 22855, 22857, 22856, 22866, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 29705, 29707, 29722, 29723, 29720, 29721, 29747, + 29708, 29748, 29709, 29737, 29736, 29733, 29732, 29724, 29731, 29730, + 29735, 29734, 29726, 29717, 29716, 29711, 29710, 29725, 29719, 29718, + 29713, 29712, 29727, 29739, 29738, 29729, 29728, 29744, 29746, 29715, + 29743, 29745, 29740, 29741, 29742, 29714, 29750, 29752, 29753, 29758, + 29759, 29756, 29757, 29760, 29754, 29761, 29755, 29751, 29749, 29706, + 29704, 35536, 35536, 35536, 35536, 35536, 35536, 29768, 29770, 29767, + 29766, 29763, 29762, 29765, 29764, 29771, 29769, 35536, 35536, 35536, + 35536, 35536, 35536, 23473, 23475, 23472, 23471, 23468, 23467, 23470, + 23469, 23476, 23474, 23423, 23425, 23422, 23421, 23418, 23417, 23420, + 23419, 23426, 23424, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 191, 190, 178, 181, 175, 167, 193, 192, 183, 195, 189, 184, 174, + 196, 177, 197, 180, 194, 164, 171, 170, 187, 166, 186, 182, 188, 165, + 35536, 35536, 162, 163, 161, 203, 204, 210, 211, 208, 209, 212, 207, 213, + 205, 206, 200, 35536, 35536, 35536, 35536, 222, 224, 221, 220, 217, 216, + 219, 218, 225, 223, 215, 214, 198, 199, 201, 202, 185, 173, 172, 169, + 168, 179, 176, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 10145, 10146, 10161, + 10162, 10159, 10160, 10187, 10147, 10188, 10148, 10179, 10178, 10175, + 10174, 10163, 10173, 10172, 10177, 10176, 10165, 10156, 10155, 10150, + 10149, 10164, 10158, 10157, 10152, 10151, 10166, 10181, 10180, 10171, + 10170, 10184, 10186, 10154, 10183, 10185, 10167, 10168, 10169, 10182, + 10153, 10191, 10196, 10197, 10194, 10195, 10189, 10190, 10198, 10192, + 10199, 10193, 10202, 10204, 10203, 10201, 10200, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 33632, 33621, 33650, + 33640, 33642, 33643, 33649, 33639, 33625, 33634, 33622, 33652, 33648, + 33627, 33641, 33638, 33626, 33635, 33644, 33633, 33651, 33624, 33623, + 33646, 33647, 33630, 33629, 33628, 33631, 33636, 33637, 33645, 33664, + 33653, 33682, 33672, 33674, 33675, 33681, 33671, 33657, 33666, 33654, + 33684, 33680, 33659, 33673, 33670, 33658, 33667, 33676, 33665, 33683, + 33656, 33655, 33678, 33679, 33662, 33661, 33660, 33663, 33668, 33669, + 33677, 33691, 33693, 33690, 33689, 33686, 33685, 33688, 33687, 33694, + 33692, 33703, 33702, 33701, 33697, 33696, 33700, 33699, 33695, 33698, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 33704, 10061, 10062, 10069, 10070, 10067, 10068, 10096, + 35536, 35536, 10097, 35536, 35536, 10087, 10086, 10085, 10084, 10073, + 10083, 10082, 10091, 35536, 10075, 10057, 35536, 10064, 10063, 10074, + 10058, 10056, 10066, 10065, 10076, 10089, 10088, 10081, 10080, 10092, + 10060, 10059, 10093, 10072, 10094, 10077, 10078, 10079, 10090, 10071, + 10095, 10102, 10106, 10107, 10104, 10105, 10108, 35536, 10103, 10109, + 35536, 35536, 10101, 10099, 10098, 10110, 10115, 10112, 10116, 10111, + 10100, 10045, 10113, 10114, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 10052, 10054, 10051, 10050, 10047, 10046, 10049, + 10048, 10055, 10053, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 23595, 23596, 23611, 23612, 23609, 23610, 23592, + 23593, 35536, 35536, 23637, 23597, 23638, 23598, 23631, 23630, 23627, + 23626, 23615, 23625, 23624, 23629, 23628, 23617, 23606, 23605, 23600, + 23599, 23616, 23608, 23607, 23602, 23601, 23618, 23633, 23632, 23623, + 23622, 23635, 23636, 23604, 23614, 23594, 23619, 23620, 23621, 23634, + 23613, 23603, 23647, 23652, 23653, 23650, 23651, 23645, 23646, 35536, + 35536, 23654, 23648, 23655, 23649, 23641, 23643, 23642, 23640, 23639, + 23656, 23644, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35317, + 35338, 35335, 35334, 35337, 35333, 35332, 35330, 35331, 35336, 35329, + 35285, 35284, 35304, 35303, 35286, 35302, 35301, 35311, 35288, 35296, + 35295, 35278, 35277, 35287, 35298, 35297, 35282, 35281, 35289, 35306, + 35305, 35300, 35299, 35313, 35294, 35293, 35280, 35279, 35307, 35308, + 35309, 35316, 35314, 35312, 35315, 35290, 35291, 35292, 35310, 35283, + 35276, 35326, 35323, 35324, 35325, 35322, 35327, 35273, 35272, 35270, + 35269, 35271, 35275, 35268, 35321, 35319, 35318, 35320, 35274, 35267, + 35328, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 28400, + 28421, 28419, 28418, 28420, 28416, 28417, 28414, 28415, 28413, 28412, + 28422, 28367, 28366, 28386, 28385, 28368, 28384, 28383, 28388, 28387, + 28370, 28378, 28377, 28361, 28360, 28369, 28380, 28379, 28364, 28362, + 28371, 28390, 28389, 28382, 28381, 28396, 28376, 28375, 28363, 28391, + 28392, 28393, 28399, 28397, 28395, 28398, 28372, 28373, 28374, 28394, + 28365, 28405, 28407, 28344, 28343, 28341, 28342, 28352, 28353, 28348, + 28351, 28347, 28350, 28355, 28356, 28354, 28346, 28345, 28349, 28408, + 28406, 28423, 28409, 28404, 28403, 28402, 28401, 28359, 28358, 28357, + 28410, 28411, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 5719, 5720, 5717, 5718, 5715, 5716, + 5725, 5726, 5723, 5724, 5721, 5722, 5888, 5889, 5890, 5887, 25556, 25554, + 25563, 25564, 25560, 25568, 25567, 25549, 25562, 25561, 25553, 25566, + 25559, 25552, 25558, 25557, 25550, 25555, 25565, 25544, 25551, 25569, + 25570, 25545, 25571, 25547, 25548, 25546, 25540, 25537, 25541, 25539, + 25535, 25538, 25542, 25536, 25543, 25577, 25576, 25587, 25578, 25579, + 25588, 25584, 25583, 25585, 25586, 25580, 25534, 25581, 25582, 25573, + 25572, 25532, 25574, 25575, 25533, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 9787, 9788, 9877, 9878, 9879, 9880, 9887, 9886, 9888, 9892, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 27066, 27065, 27071, 27070, + 27072, 27073, 27062, 27063, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 29007, 29026, 29033, 29030, 29020, 29017, 29012, 29034, + 29002, 29019, 29029, 29009, 29006, 29015, 29032, 29010, 29028, 29016, + 29021, 29027, 29031, 29004, 29003, 29008, 29024, 29018, 29014, 29013, + 29022, 29005, 29023, 29025, 29011, 29035, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 29042, 29044, 29041, 29040, 29037, 29036, 29039, 29038, 29045, 29043, + 35536, 35536, 35536, 35536, 35536, 35536, 3761, 3762, 3775, 3776, 3773, + 3774, 3757, 3758, 3759, 35536, 3801, 3763, 3802, 3764, 3793, 3792, 3789, + 3788, 3777, 3787, 3786, 3791, 3790, 3779, 3770, 3769, 3766, 3765, 3778, + 3772, 3771, 3768, 3767, 3780, 3795, 3794, 3785, 3784, 3798, 3800, 3799, + 3797, 3760, 3781, 3782, 3783, 3796, 3829, 3834, 3835, 3832, 3833, 3826, + 3827, 3828, 35536, 3836, 3830, 3837, 3831, 3821, 3823, 3825, 3824, 3822, + 3839, 3838, 3850, 3851, 3852, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 3846, 3848, 3845, 3844, 3841, 3840, 3843, + 3842, 3849, 3847, 3820, 3818, 3815, 3806, 3808, 3813, 3811, 3803, 3809, + 3819, 3817, 3816, 3805, 3807, 3814, 3812, 3804, 3810, 3853, 35536, 35536, + 35536, 20431, 20432, 20377, 20376, 20386, 20371, 20375, 20374, 20388, + 20372, 20368, 20367, 20370, 20373, 20379, 20378, 20385, 20390, 20366, + 20365, 20369, 20392, 20382, 20383, 20384, 20393, 20391, 20389, 20380, + 20381, 20387, 20394, 35536, 35536, 20409, 20408, 20417, 20403, 20407, + 20406, 20419, 20404, 20400, 20399, 20402, 20405, 20411, 20410, 20416, + 20421, 20398, 20397, 20401, 20423, 20414, 20415, 35536, 20424, 20422, + 20420, 20412, 20413, 20418, 20425, 20426, 20428, 20430, 20427, 20429, + 20396, 20395, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 20443, 20444, 20453, 20454, 20451, + 20452, 20480, 35536, 20445, 20481, 35536, 20446, 20459, 20458, 20472, + 20471, 20460, 20470, 20469, 20437, 20436, 20462, 20439, 20438, 20448, + 20447, 20461, 20442, 20440, 20450, 20449, 20463, 20474, 20473, 20468, + 20467, 20476, 20479, 20477, 20456, 20478, 20464, 20465, 20466, 20475, + 20455, 20457, 20435, 20441, 20490, 20495, 20496, 20493, 20494, 20489, + 35536, 35536, 35536, 20497, 35536, 20491, 20498, 35536, 20492, 20488, + 20487, 20486, 20484, 20485, 20499, 20483, 20482, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 20506, 20508, 20505, 20504, 20501, + 20500, 20503, 20502, 20509, 20507, 35536, 35536, 35536, 35536, 35536, + 35536, 13918, 13919, 13932, 13933, 13930, 13931, 35536, 13949, 13920, + 35536, 13948, 13921, 13955, 13954, 13937, 13936, 13951, 13945, 13944, + 13929, 13928, 13935, 13941, 13940, 13925, 13924, 13917, 13939, 13938, + 13927, 13926, 13934, 13943, 13942, 13923, 13922, 13916, 13947, 13946, + 13950, 13952, 13953, 13958, 13963, 13964, 13961, 13962, 35536, 13966, + 13959, 35536, 13965, 13960, 13957, 13956, 13967, 13978, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 13974, 13976, 13973, 13972, 13969, + 13968, 13971, 13970, 13977, 13975, 35536, 35536, 35536, 35536, 35536, + 35536, 32001, 31999, 32006, 32004, 31969, 31970, 31997, 31998, 31987, + 31988, 32003, 31983, 31986, 31971, 31974, 31975, 31984, 31985, 31972, + 31973, 31976, 31989, 31990, 31993, 31994, 31979, 31995, 31996, 31991, + 31992, 31978, 32009, 31980, 32002, 32007, 31977, 32005, 32000, 32008, + 31981, 31982, 32010, 32011, 32012, 35536, 35536, 35536, 35536, 32019, + 32021, 32018, 32017, 32014, 32013, 32016, 32015, 32022, 32020, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 20129, 20127, 20121, 20132, 20124, + 20131, 20135, 20126, 20123, 20125, 20128, 20122, 20137, 20133, 20130, + 20136, 20134, 20138, 20144, 20141, 20143, 20140, 20142, 20139, 20120, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 16667, 16671, 16669, + 16670, 16608, 16609, 16628, 16629, 16622, 16623, 16624, 16625, 16626, + 16627, 16653, 16610, 16654, 35536, 16644, 16643, 16642, 16641, 16630, + 16640, 16639, 16613, 16612, 16632, 16619, 16618, 16615, 16614, 16631, + 16621, 16620, 16617, 16616, 16633, 16646, 16645, 16638, 16637, 16649, + 16652, 16650, 16648, 16651, 16634, 16635, 16636, 16647, 16611, 16673, + 16672, 16680, 16681, 16678, 16679, 16675, 35536, 35536, 35536, 16676, + 16674, 16677, 16666, 16694, 16683, 16682, 16661, 16664, 16660, 16662, + 16658, 16657, 16665, 16656, 16659, 16663, 16655, 16690, 16692, 16689, + 16688, 16685, 16684, 16687, 16686, 16693, 16691, 16668, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 19775, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 29828, + 29824, 29818, 29827, 29820, 29829, 29833, 29835, 29830, 29825, 29826, + 29831, 29819, 29836, 29834, 29821, 29832, 29822, 29823, 29837, 29838, + 29902, 29885, 29883, 29892, 29891, 29887, 29893, 29889, 29888, 29895, + 29896, 29897, 29894, 29886, 29899, 29817, 29804, 29875, 29882, 30172, + 30173, 29802, 29777, 29903, 30171, 29839, 29904, 29890, 29898, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 29880, 7938, 7946, 7944, 7940, 7945, 7941, 7939, 7942, + 7943, 8007, 7947, 7956, 7955, 7949, 7948, 7960, 7950, 7951, 7959, 7953, + 7954, 7961, 7962, 7967, 7964, 7963, 7965, 7966, 7969, 7971, 7973, 7972, + 7974, 7980, 7977, 7978, 7982, 7975, 7976, 7981, 7979, 7984, 7983, 7985, + 7987, 7988, 7992, 7991, 7989, 7990, 7993, 8006, 7994, 7995, 7996, 8005, + 7997, 8001, 8002, 8000, 7998, 7999, 8004, 8003, 8008, 8009, 8020, 8011, + 8015, 8016, 8017, 8018, 8019, 8021, 8024, 8023, 8022, 8025, 8027, 8028, + 8029, 8030, 8031, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8040, + 8041, 8042, 8043, 8044, 8059, 8045, 8046, 8056, 8050, 8047, 8048, 8049, + 8057, 8054, 8058, 8055, 8051, 8053, 8066, 8062, 8063, 8064, 8067, 8078, + 8068, 8071, 8072, 8074, 8075, 8076, 8079, 8082, 8080, 8081, 8083, 8084, + 8086, 8087, 8116, 8123, 8117, 8118, 8119, 8120, 8121, 8122, 8124, 8126, + 8125, 8127, 8130, 8131, 8134, 8128, 8129, 8135, 8180, 8179, 8181, 8136, + 8139, 8140, 8141, 8137, 8138, 8142, 8145, 8143, 8146, 8148, 8157, 8158, + 8159, 8160, 8178, 8161, 8162, 8175, 8176, 8174, 8163, 8164, 8165, 8166, + 8167, 8168, 8169, 8172, 8173, 8182, 8272, 8183, 8184, 8186, 8185, 8192, + 8187, 8189, 8191, 8195, 8194, 8196, 8197, 8204, 8198, 8199, 8203, 8207, + 8208, 8205, 8206, 8214, 8211, 8215, 8216, 8217, 8218, 8219, 8221, 8222, + 8224, 8223, 8226, 8225, 8228, 8227, 8229, 8230, 8232, 8233, 8237, 8239, + 8243, 8244, 8257, 8249, 8250, 8245, 8246, 8247, 8251, 8255, 8252, 8253, + 8254, 8258, 8259, 8261, 8262, 8263, 8264, 8265, 8266, 8276, 8267, 8268, + 8271, 8270, 8269, 8273, 8274, 8275, 8277, 8278, 8281, 8282, 8283, 8284, + 8285, 8287, 8286, 8303, 8294, 8295, 8288, 8289, 8291, 8292, 8290, 8293, + 8302, 8296, 8301, 8299, 8298, 8300, 8305, 8324, 8306, 8307, 8308, 8311, + 8310, 8312, 8313, 8315, 8316, 8317, 8325, 8318, 8319, 8320, 8323, 8322, + 8321, 8326, 8327, 8329, 8330, 8331, 8332, 8334, 8338, 8335, 8339, 8337, + 8336, 8340, 8341, 8342, 8343, 8347, 8346, 8344, 8345, 8348, 8349, 8351, + 8370, 8372, 8352, 8354, 8353, 8355, 8356, 8359, 8360, 8358, 8357, 8361, + 8362, 8363, 8364, 8367, 8365, 8366, 8368, 8369, 8373, 8374, 8371, 8375, + 8376, 8377, 8378, 8380, 8383, 8382, 8384, 8385, 8387, 8388, 8389, 8393, + 8392, 8390, 8391, 8394, 8398, 8397, 8396, 8399, 8400, 8402, 8403, 8407, + 8404, 8405, 8410, 8408, 8411, 8412, 8414, 8413, 8415, 8416, 8438, 8437, + 8440, 8441, 8422, 8423, 8420, 8421, 8419, 8417, 8425, 8424, 8426, 8428, + 8434, 8435, 8432, 8433, 8442, 8443, 8444, 8462, 8447, 8448, 8449, 8445, + 8446, 8450, 8451, 8452, 8453, 8454, 8456, 8457, 8458, 8459, 8460, 8485, + 8463, 8466, 8464, 8465, 8471, 8472, 8469, 8470, 8467, 8468, 8473, 8474, + 8482, 8475, 8476, 8483, 8480, 8481, 8484, 8477, 8478, 8479, 8486, 8487, + 8488, 8489, 8490, 8491, 8492, 8494, 8495, 8493, 8496, 8497, 8538, 8539, + 8500, 8501, 8498, 8499, 8504, 8505, 8503, 8509, 8506, 8508, 8507, 8513, + 8514, 8512, 8510, 8511, 8515, 8516, 8517, 8518, 8519, 8520, 8521, 8540, + 8526, 8522, 8523, 8524, 8525, 8527, 8529, 8528, 8530, 8531, 8533, 8532, + 8534, 8536, 8535, 8541, 8542, 8545, 8546, 8543, 8544, 8620, 8615, 8616, + 8617, 8618, 8619, 8621, 8624, 8622, 8623, 8625, 8667, 8626, 8656, 8657, + 8633, 8635, 8652, 8636, 8658, 8640, 8638, 8639, 8641, 8642, 8643, 8644, + 8653, 8654, 8647, 8648, 8650, 8659, 8627, 8628, 8632, 8630, 8668, 8660, + 8662, 8661, 8663, 8669, 8670, 8664, 8665, 8666, 8671, 8672, 8673, 8676, + 8677, 8678, 8674, 8675, 8679, 8680, 8682, 8684, 8685, 8703, 8701, 8702, + 8705, 8704, 8686, 8693, 8691, 8692, 8687, 8688, 8694, 8695, 8696, 8697, + 8698, 8700, 8706, 8715, 8707, 8709, 8710, 8708, 8711, 8713, 8712, 8714, + 8717, 8719, 8718, 8720, 8721, 8754, 8756, 8722, 8724, 8723, 8726, 8729, + 8727, 8728, 8732, 8736, 8739, 8738, 8741, 8744, 8742, 8743, 8747, 8749, + 8755, 8757, 8758, 8762, 8769, 8767, 8765, 8766, 8768, 8771, 8770, 8763, + 8764, 8772, 8775, 8781, 8776, 8779, 8774, 8773, 8782, 8780, 8777, 8778, + 8783, 8784, 8785, 8786, 8787, 8788, 8789, 8791, 8794, 8795, 8798, 8799, + 8800, 8796, 8797, 8792, 8793, 8801, 8802, 8803, 8804, 8805, 8806, 8808, + 8809, 8810, 8811, 8812, 8816, 8813, 8837, 8830, 8831, 8836, 8819, 8818, + 8832, 8835, 8833, 8822, 8821, 8824, 8826, 8827, 8828, 8829, 8825, 8838, + 8814, 8839, 8840, 8841, 8842, 8843, 8844, 8852, 8850, 8848, 8851, 8847, + 8849, 8845, 8846, 8853, 8855, 8856, 8857, 8864, 8859, 8860, 8868, 8869, + 8865, 8867, 8866, 8870, 8872, 8871, 8873, 8884, 8875, 8874, 8883, 8881, + 8876, 8877, 8878, 8880, 8879, 8882, 8888, 8885, 8887, 8886, 8889, 8890, + 8891, 8892, 8895, 8896, 8898, 8899, 8900, 8901, 8903, 8902, 8904, 8911, + 8905, 8906, 8912, 8907, 8908, 8909, 8910, 8913, 8917, 8914, 8915, 8916, + 8918, 8919, 8920, 8921, 8927, 8925, 8923, 8924, 8922, 8926, 8928, 8930, + 8947, 8948, 8931, 8936, 8938, 8932, 8935, 8933, 8934, 8939, 8945, 8946, + 8940, 8943, 8944, 8949, 8955, 8954, 8950, 8952, 8951, 9036, 9037, 8956, + 8957, 8962, 8963, 8960, 8961, 8964, 8958, 8959, 8965, 8968, 8969, 8971, + 8972, 8973, 8977, 8974, 8975, 8976, 8966, 8967, 8978, 8980, 8979, 8981, + 8983, 8984, 8985, 8991, 8990, 8986, 8987, 8988, 9023, 8992, 8993, 8994, + 8995, 8996, 9015, 8998, 8999, 9001, 9000, 9002, 9003, 9019, 9004, 9006, + 9005, 9018, 9008, 9016, 9020, 9011, 9010, 9017, 9012, 9014, 9013, 9021, + 9022, 9024, 9028, 9026, 9027, 9025, 9031, 9030, 9029, 9035, 9032, 9033, + 9034, 9038, 9040, 9039, 9043, 9041, 9058, 9044, 9047, 9049, 9045, 9046, + 9050, 9048, 9051, 9053, 9055, 9056, 9057, 8461, 7957, 7968, 7986, 8052, + 8061, 8077, 8085, 8177, 8170, 8188, 8190, 8280, 8304, 8350, 8379, 8381, + 8395, 8401, 8436, 8409, 8439, 8418, 8427, 8431, 8502, 8631, 8634, 8649, + 8681, 8699, 8716, 8725, 8753, 8751, 8730, 8761, 8790, 8807, 8817, 8937, + 8970, 8953, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 7922, 7917, 7854, 7840, 7901, 7897, 7829, + 7874, 7921, 7862, 7846, 7907, 7896, 7828, 7873, 7860, 7844, 7903, 7893, + 7823, 7870, 7883, 7927, 7919, 7856, 7842, 7905, 7895, 7825, 7872, 7884, + 7928, 7920, 7857, 7843, 7929, 7911, 7912, 7858, 7834, 7900, 7892, 7822, + 7869, 7887, 7930, 7913, 7914, 7859, 7835, 7898, 7899, 7882, 7925, 7908, + 7909, 7849, 7839, 7915, 7916, 7850, 7853, 7851, 7852, 7906, 7891, 7889, + 7890, 7826, 7827, 7865, 7867, 7868, 7866, 7923, 7918, 7855, 7841, 7902, + 7881, 7924, 7910, 7847, 7848, 7837, 7838, 7864, 7863, 7877, 7926, 7886, + 7932, 7836, 7885, 7931, 7878, 7879, 7875, 7876, 7880, 7888, 7830, 7833, + 7832, 7831, 7861, 7845, 7904, 7894, 7824, 7871, 35536, 7937, 7936, 7935, + 7933, 7934, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 7958, 7952, 7970, 8010, 8012, 8013, 8014, 8026, + 8065, 8060, 8070, 8069, 8073, 8090, 8088, 8089, 8091, 8092, 8110, 8096, + 8093, 8094, 8095, 8112, 8113, 8111, 8100, 8099, 8097, 8098, 8103, 8101, + 8102, 8104, 8105, 8106, 8107, 8114, 8115, 8109, 8108, 8133, 8132, 8144, + 8147, 8152, 8156, 8149, 8153, 8154, 8150, 8151, 8155, 8171, 8193, 8200, + 8201, 8202, 8209, 8210, 8213, 8212, 8220, 8231, 8234, 8235, 8236, 8238, + 8240, 8241, 8242, 8248, 8256, 8260, 8279, 8297, 8309, 8314, 8328, 8333, + 8386, 8406, 8429, 8430, 8537, 8557, 8547, 8548, 8556, 8552, 8553, 8554, + 8551, 8550, 8549, 8555, 8559, 8558, 8565, 8566, 8560, 8561, 8562, 8567, + 8563, 8564, 8568, 8569, 8570, 8571, 8572, 8573, 8580, 8574, 8579, 8578, + 8576, 8575, 8577, 8581, 8582, 8587, 8588, 8583, 8584, 8585, 8586, 8614, + 8610, 8589, 8597, 8598, 8596, 8595, 8599, 8590, 8591, 8593, 8594, 8592, + 8611, 8600, 8607, 8609, 8604, 8605, 8608, 8603, 8606, 8602, 8601, 8612, + 8613, 8629, 8655, 8637, 8645, 8646, 8651, 8683, 8690, 8689, 8750, 8731, + 8733, 8752, 8734, 8735, 8737, 8740, 8745, 8746, 8748, 8815, 8834, 8820, + 8823, 8854, 8858, 8861, 8862, 8863, 8894, 8893, 8897, 8929, 8941, 8942, + 8982, 8989, 8997, 9009, 9007, 9042, 9052, 9054, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 9131, + 9132, 9133, 9134, 9135, 9136, 9137, 9138, 9141, 9142, 9139, 9140, 9143, + 9144, 9145, 9146, 9147, 9148, 9149, 9150, 9151, 9152, 9153, 9154, 9155, + 9156, 9157, 9158, 9159, 9160, 9161, 9162, 9163, 9164, 9165, 9166, 9167, + 9168, 9169, 9170, 9171, 9172, 9173, 9174, 9175, 9176, 9177, 9197, 9198, + 9199, 9200, 9201, 9202, 9203, 9204, 9205, 9180, 9181, 9182, 9183, 9184, + 9178, 9179, 9185, 9186, 9187, 9206, 9207, 9208, 9209, 9210, 9211, 9212, + 9213, 9214, 9215, 9188, 9189, 9190, 9191, 9192, 9193, 9194, 9195, 9196, + 9216, 9217, 9218, 9219, 9220, 9221, 9222, 9223, 9224, 9225, 9226, 9227, + 9228, 9229, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 10667, 10668, 10669, 10670, 10665, + 10666, 10662, 10663, 10664, 10671, 10672, 10673, 10678, 10679, 10680, + 10681, 10674, 10675, 10682, 10683, 10676, 10677, 10684, 10685, 10712, + 10713, 10714, 10715, 10716, 10717, 10718, 10719, 10720, 10721, 10702, + 10703, 10700, 10701, 10704, 10705, 10706, 10707, 10708, 10709, 10710, + 10686, 10687, 10694, 10688, 10689, 10690, 10691, 10695, 10692, 10693, + 10696, 10697, 10698, 10699, 10722, 10723, 10724, 10725, 10726, 10727, + 10728, 10729, 10730, 10731, 10732, 10733, 10734, 10735, 10736, 10737, + 10738, 10739, 10740, 10741, 10711, 10781, 10782, 10783, 10784, 10779, + 10780, 10785, 10786, 10787, 10788, 10793, 10789, 10790, 10791, 10792, + 10794, 10795, 10796, 10797, 10798, 10799, 10800, 10801, 10802, 10803, + 10804, 10805, 10806, 10807, 10808, 10809, 10810, 10811, 10812, 10813, + 10814, 10815, 10816, 10819, 10820, 10821, 10822, 10823, 10824, 10825, + 10817, 10818, 10826, 10899, 10900, 10901, 10902, 10903, 10904, 10905, + 10906, 10907, 10908, 10890, 10891, 10892, 10893, 10894, 10895, 10896, + 10888, 10889, 10897, 10898, 10831, 10827, 10828, 10832, 10833, 10829, + 10830, 10834, 10835, 10836, 10837, 10838, 10843, 10844, 10845, 10846, + 10847, 10848, 10839, 10840, 10849, 10841, 10842, 10850, 10851, 10852, + 10853, 10854, 10855, 10856, 10857, 10858, 10859, 10860, 10865, 10861, + 10862, 10866, 10863, 10864, 10867, 10868, 10869, 10870, 10871, 10881, + 10882, 10883, 10884, 10885, 10886, 10887, 10872, 10873, 10874, 10875, + 10876, 10877, 10878, 10879, 10880, 10913, 10914, 10915, 10916, 10917, + 10918, 10919, 10909, 10910, 10911, 10912, 10945, 10946, 10947, 10948, + 10949, 10950, 10941, 10942, 10943, 10944, 10951, 10952, 10920, 10921, + 10924, 10925, 10926, 10927, 10928, 10929, 10930, 10922, 10923, 10931, + 10934, 10935, 10936, 10937, 10932, 10933, 10938, 10939, 10940, 10956, + 10957, 10958, 10959, 10960, 10961, 10962, 10963, 10964, 10965, 10968, + 10969, 10970, 10966, 10967, 10971, 10972, 10973, 10974, 10975, 10976, + 11012, 11010, 11011, 11013, 11014, 11015, 11016, 11017, 11018, 11019, + 11020, 10983, 10977, 10978, 10984, 10985, 10986, 10987, 10988, 10979, + 10980, 10981, 10982, 10989, 10996, 10997, 10998, 10999, 11000, 10990, + 10991, 10992, 10993, 10994, 10995, 11001, 11002, 11007, 11003, 11004, + 11005, 11006, 11008, 11009, 11027, 11028, 11029, 11030, 11031, 11025, + 11026, 11022, 11023, 11024, 11032, 11033, 11036, 11034, 11035, 11037, + 11038, 11039, 11040, 11041, 11042, 11043, 11044, 11069, 11070, 11073, + 11074, 11075, 11076, 11077, 11071, 11072, 11078, 11079, 11080, 11049, + 11050, 11051, 11052, 11053, 11054, 11045, 11046, 11047, 11048, 11055, + 11056, 11061, 11062, 11063, 11057, 11058, 11064, 11059, 11060, 11065, + 11066, 11067, 11068, 11081, 11082, 11083, 11084, 11085, 11088, 11089, + 11090, 11091, 11092, 11086, 11087, 11093, 11094, 11102, 11103, 11104, + 11105, 11098, 11099, 11106, 11107, 11108, 11100, 11101, 11109, 11110, + 11111, 11112, 11113, 11114, 11115, 11116, 11757, 11758, 11759, 11760, + 11761, 11762, 11763, 11764, 11128, 11124, 11125, 11129, 11130, 11131, + 11126, 11127, 11132, 11133, 11135, 11136, 11137, 11140, 11138, 11139, + 11141, 11142, 11143, 11144, 11145, 11146, 11156, 11157, 11164, 11147, + 11148, 11149, 11150, 11151, 11152, 11153, 11154, 11155, 11165, 11166, + 11158, 11159, 11160, 11161, 11162, 11163, 11167, 11168, 11175, 11176, + 11169, 11170, 11177, 11171, 11172, 11178, 11179, 11180, 11173, 11174, + 11181, 11187, 11185, 11186, 11188, 11182, 11183, 11184, 11189, 11190, + 11191, 11192, 11193, 11194, 11195, 11196, 11197, 11198, 11199, 11200, + 11257, 11258, 11259, 11260, 11261, 11262, 11263, 11264, 11265, 11220, + 11221, 11222, 11223, 11224, 11225, 11226, 11227, 11217, 11218, 11219, + 11228, 11245, 11246, 11247, 11248, 11249, 11243, 11244, 11250, 11251, + 11252, 11253, 11237, 11238, 11239, 11229, 11230, 11231, 11232, 11233, + 11234, 11240, 11235, 11236, 11241, 11242, 11254, 11255, 11256, 11268, + 11269, 11270, 11271, 11266, 11267, 11272, 11273, 11274, 11275, 11278, + 11279, 11280, 11281, 11282, 11283, 11284, 11276, 11277, 11285, 11286, + 11287, 11305, 11306, 11307, 11308, 11309, 11310, 11311, 11312, 11313, + 11288, 11289, 11290, 11291, 11294, 11295, 11296, 11297, 11298, 11299, + 11292, 11293, 11300, 11303, 11304, 11301, 11302, 11321, 11322, 11325, + 11326, 11327, 11323, 11324, 11314, 11315, 11316, 11317, 11318, 11319, + 11320, 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11337, 11338, + 11339, 11340, 11341, 11342, 11343, 11344, 11335, 11336, 11345, 11346, + 11353, 11354, 11355, 11347, 11348, 11349, 11350, 11356, 11357, 11358, + 11351, 11352, 11364, 11365, 11368, 11369, 11366, 11367, 11370, 11371, + 11359, 11360, 11361, 11362, 11363, 11372, 11373, 11374, 11379, 11380, + 11381, 11382, 11383, 11384, 11385, 11386, 11387, 11388, 11375, 11376, + 11377, 11378, 11390, 11391, 11394, 11392, 11393, 11395, 11396, 11397, + 11398, 11399, 11400, 11401, 11402, 11765, 11766, 11767, 11768, 11769, + 11770, 11771, 11408, 11406, 11407, 11403, 11404, 11405, 11409, 11410, + 11411, 11412, 11413, 11414, 11415, 11416, 11419, 11420, 11421, 11422, + 11423, 11417, 11418, 11424, 11425, 11426, 11427, 11428, 11429, 11430, + 11431, 11432, 11433, 11434, 11435, 11436, 11441, 11437, 11438, 11442, + 11443, 11444, 11439, 11440, 11445, 11446, 11447, 11453, 11454, 11455, + 11456, 11448, 11449, 11450, 11457, 11458, 11451, 11452, 11459, 11460, + 11464, 11465, 11466, 11467, 11468, 11469, 11461, 11462, 11463, 11470, + 11471, 11472, 11475, 11476, 11477, 11478, 11479, 11473, 11474, 11480, + 11481, 11482, 11483, 11484, 11485, 11486, 11487, 11488, 11489, 11490, + 11499, 11500, 11491, 11492, 11501, 11502, 11503, 11493, 11494, 11495, + 11496, 11497, 11498, 11508, 11504, 11505, 11509, 11510, 11511, 11512, + 11506, 11507, 11513, 11514, 11515, 11525, 11526, 11527, 11528, 11529, + 11530, 11531, 11532, 11533, 11534, 11520, 11521, 11516, 11517, 11518, + 11519, 11522, 11523, 11524, 11539, 11540, 11541, 11542, 11543, 11536, + 11537, 11538, 11544, 11545, 11546, 11573, 11574, 11575, 11576, 11577, + 11578, 11579, 11580, 11581, 11582, 11551, 11552, 11553, 11547, 11548, + 11554, 11555, 11556, 11557, 11558, 11549, 11550, 11561, 11562, 11559, + 11560, 11563, 11564, 11565, 11566, 11567, 11568, 11569, 11570, 11571, + 11572, 11586, 11587, 11588, 11589, 11590, 11591, 11592, 11593, 11594, + 11595, 11596, 11597, 11598, 11599, 11600, 11601, 11583, 11584, 11585, + 11602, 11603, 11612, 11604, 11605, 11606, 11607, 11609, 11610, 11611, + 11613, 11614, 11615, 11616, 11617, 11618, 11619, 11620, 11621, 11622, + 11623, 11624, 11625, 11626, 11627, 11628, 11629, 11630, 11631, 11632, + 11639, 11640, 11633, 11634, 11641, 11642, 11643, 11644, 11635, 11636, + 11637, 11638, 11645, 11646, 11647, 11648, 11653, 11649, 11650, 11654, + 11655, 11656, 11651, 11652, 11657, 11658, 11659, 11660, 11666, 11667, + 11662, 11663, 11668, 11669, 11670, 11671, 11672, 11664, 11665, 11673, + 11674, 11681, 11682, 11683, 11675, 11676, 11684, 11685, 11677, 11678, + 11679, 11680, 11686, 11689, 11690, 11691, 11692, 11687, 11688, 11693, + 11702, 11703, 11704, 11695, 11696, 11697, 11705, 11698, 11699, 11706, + 11700, 11701, 11707, 11708, 11709, 11710, 11711, 11712, 11713, 11714, + 11715, 11728, 11716, 11717, 11718, 11719, 11720, 11721, 11722, 11723, + 11724, 11725, 11726, 11727, 11729, 11730, 11731, 11732, 11752, 11753, + 11754, 11755, 11756, 11733, 11734, 11735, 11736, 11737, 11738, 11739, + 11740, 11741, 11742, 11743, 11744, 11745, 11746, 11747, 11748, 11749, + 11750, 11751, 10745, 10746, 10747, 10748, 10749, 10750, 10742, 10743, + 10744, 10751, 10752, 10756, 10757, 10758, 10759, 10760, 10761, 10762, + 10763, 10764, 10765, 10766, 10767, 10768, 10769, 10770, 10771, 10772, + 10773, 10774, 10775, 10753, 10754, 10755, 11608, 11661, 11097, 11122, + 11119, 11121, 11118, 11389, 10778, 10955, 11123, 11120, 11117, 10777, + 10954, 10776, 10953, 11216, 11021, 11095, 11134, 11096, 11535, 11694, + 11212, 11203, 11207, 11214, 11210, 11204, 11209, 11206, 11213, 11202, + 11208, 11215, 11211, 11205, 11201, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 447, 448, 449, 450, 451, 452, 453, + 454, 455, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 377, + 378, 379, 380, 381, 382, 375, 376, 383, 384, 385, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 425, 426, 393, 389, 390, 394, 395, 396, 391, + 392, 386, 387, 388, 397, 398, 399, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 404, 405, 406, 407, 408, 409, 400, 401, 402, 403, 410, + 411, 412, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 417, 418, 419, 420, 421, 422, + 423, 413, 414, 415, 416, 424, 497, 498, 499, 500, 501, 502, 503, 486, + 487, 488, 489, 494, 495, 496, 504, 490, 491, 492, 493, 505, 506, 507, + 508, 509, 512, 513, 514, 515, 510, 511, 516, 517, 518, 519, 522, 523, + 524, 525, 526, 520, 521, 527, 528, 529, 530, 533, 534, 535, 536, 537, + 531, 532, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, + 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, + 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 609, 610, 602, 603, + 604, 611, 612, 613, 614, 605, 606, 615, 607, 608, 620, 621, 622, 623, + 624, 616, 617, 618, 619, 625, 626, 627, 653, 654, 655, 656, 657, 658, + 659, 651, 652, 660, 661, 673, 674, 675, 676, 677, 678, 679, 680, 681, + 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 664, 665, 666, 667, 668, 669, 670, + 662, 663, 671, 672, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 640, 641, 632, 633, 634, + 635, 628, 629, 636, 637, 638, 639, 630, 631, 715, 716, 717, 718, 719, + 720, 721, 722, 723, 713, 714, 807, 808, 809, 810, 811, 812, 813, 814, + 815, 816, 726, 727, 728, 729, 730, 731, 732, 733, 734, 724, 725, 753, + 754, 750, 751, 752, 755, 756, 757, 746, 747, 748, 749, 758, 759, 760, + 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 737, 738, 739, 740, + 741, 742, 743, 744, 745, 735, 736, 765, 766, 767, 768, 761, 762, 769, + 770, 771, 763, 764, 772, 798, 796, 797, 799, 800, 801, 802, 803, 804, + 805, 806, 779, 775, 776, 780, 773, 774, 781, 782, 777, 778, 783, 784, + 785, 787, 788, 789, 786, 790, 791, 792, 793, 794, 795, 858, 859, 860, + 861, 862, 863, 864, 865, 866, 867, 827, 828, 829, 830, 831, 832, 833, + 834, 835, 836, 837, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, + 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, + 892, 893, 894, 895, 896, 897, 838, 839, 842, 843, 844, 845, 846, 847, + 840, 841, 848, 849, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, + 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, + 922, 923, 924, 925, 926, 927, 850, 851, 852, 853, 854, 855, 856, 857, + 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, + 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, + 957, 928, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 14098, 14088, 14087, 14084, + 14083, 14069, 14082, 14081, 14086, 14085, 14091, 14076, 14075, 14072, + 14071, 14096, 14078, 14077, 14074, 14073, 14070, 14090, 14089, 14080, + 14079, 14093, 14097, 14094, 14092, 14095, 14101, 14108, 14109, 14104, + 14105, 14110, 14111, 14102, 14106, 14107, 14103, 14112, 14068, 14067, + 14065, 14099, 14066, 14100, 14119, 14121, 14118, 14117, 14114, 14113, + 14116, 14115, 14122, 14120, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 2892, 2858, 2917, 2918, 2888, 2925, 2936, 2907, 2924, 2919, + 2920, 2871, 2937, 2894, 2873, 2878, 2885, 2931, 2903, 2861, 2897, 2932, + 2893, 2868, 2869, 2901, 2875, 2916, 2857, 2915, 2884, 2908, 2939, 2856, + 2902, 2933, 2887, 2886, 2882, 2859, 2914, 2891, 2921, 2874, 2911, 2922, + 2938, 2866, 2928, 2935, 2876, 2862, 2890, 2864, 2883, 2926, 2867, 2941, + 2943, 2863, 2929, 2879, 2923, 2900, 2927, 2905, 2912, 2896, 2940, 2895, + 2877, 2909, 2880, 2906, 2934, 2930, 2913, 2898, 2870, 2904, 2860, 2899, + 2942, 2865, 2910, 2889, 2881, 2976, 2993, 2991, 2990, 2954, 2960, 2949, + 2997, 2959, 2951, 2984, 2996, 2953, 2980, 2981, 2944, 2986, 2994, 2988, + 2989, 2966, 2963, 2979, 2947, 2945, 2946, 2952, 2985, 3001, 2974, 2971, + 2998, 2987, 2995, 2965, 2969, 2970, 2967, 2992, 2962, 2968, 2978, 2983, + 2964, 2999, 2961, 3000, 2948, 2958, 2957, 2955, 2972, 2977, 2956, 2950, + 2975, 3053, 3073, 3095, 3091, 3052, 3041, 3054, 3002, 3030, 3004, 3074, + 3070, 3027, 3075, 3045, 3024, 3007, 3003, 3009, 3094, 3072, 3035, 3065, + 3033, 3096, 3014, 3015, 3079, 3046, 3084, 3061, 3088, 3083, 3048, 3090, + 3039, 3021, 3071, 3049, 3017, 3032, 3037, 3068, 3085, 3051, 3099, 3042, + 3067, 3064, 3098, 3089, 3029, 3100, 3057, 3016, 3087, 3062, 3059, 3011, + 3047, 3023, 3034, 3019, 3013, 3058, 3056, 3092, 3050, 3066, 3069, 3012, + 3063, 3043, 3020, 3097, 3044, 3081, 3078, 3031, 3022, 3026, 3008, 3028, + 3010, 3025, 3093, 3060, 3038, 3036, 3082, 3006, 3005, 3055, 3040, 3018, + 3076, 3077, 3086, 3128, 3212, 3161, 3135, 3162, 3121, 3160, 3166, 3148, + 3175, 3211, 3157, 3191, 3158, 3105, 3204, 3189, 3164, 3196, 3109, 3213, + 3111, 3198, 3133, 3143, 3124, 3130, 3200, 3217, 3159, 3106, 3154, 3206, + 3104, 3156, 3101, 3144, 3138, 3116, 3145, 3140, 3139, 3181, 3137, 3134, + 3122, 3167, 3126, 3114, 3173, 3202, 3201, 3214, 3107, 3188, 3205, 3153, + 3132, 3168, 3108, 3184, 3179, 3174, 3119, 3147, 3136, 3151, 3215, 3183, + 3216, 3146, 3170, 3195, 3112, 3150, 3155, 3207, 3129, 3113, 3169, 3203, + 3125, 3149, 3117, 3152, 3165, 3163, 3103, 3110, 3185, 3209, 3208, 3176, + 3187, 3118, 3131, 3123, 3197, 3142, 3193, 3190, 3115, 3178, 3194, 3171, + 3180, 3177, 3192, 3182, 3141, 3120, 3186, 3210, 3172, 3127, 3199, 3102, + 3271, 3349, 3258, 3245, 3356, 3248, 3312, 3338, 3328, 3298, 3274, 3323, + 3343, 3284, 3238, 3359, 3331, 3276, 3313, 3348, 3240, 3250, 3300, 3290, + 3255, 3287, 3291, 3299, 3330, 3297, 3316, 3339, 3279, 3262, 3232, 3286, + 3294, 3256, 3249, 3277, 3273, 3340, 3332, 3326, 3270, 3278, 3364, 3231, + 3353, 3360, 3320, 3352, 3235, 3337, 3346, 3354, 3357, 3244, 3322, 3342, + 3229, 3292, 3333, 3261, 3259, 3305, 3309, 3228, 3351, 3239, 3372, 3303, + 3365, 3260, 3272, 3318, 3368, 3247, 3221, 3227, 3289, 3237, 3254, 3285, + 3233, 3223, 3301, 3314, 3362, 3275, 3304, 3306, 3321, 3264, 3222, 3308, + 3265, 3230, 3220, 3268, 3324, 3288, 3241, 3319, 3302, 3361, 3280, 3310, + 3219, 3226, 3295, 3373, 3350, 3375, 3374, 3246, 3311, 3341, 3344, 3269, + 3336, 3363, 3282, 3369, 3366, 3367, 3371, 3370, 3236, 3315, 3296, 3325, + 3358, 3225, 3355, 3252, 3263, 3329, 3327, 3283, 3293, 3334, 3335, 3218, + 3307, 3317, 3251, 3243, 3266, 3253, 3257, 3345, 3242, 3267, 3347, 3224, + 3234, 3380, 3429, 3382, 3427, 3407, 3420, 3401, 3384, 3410, 3409, 3389, + 3419, 3399, 3395, 3386, 3417, 3412, 3418, 3415, 3378, 3377, 3397, 3396, + 3394, 3422, 3414, 3423, 3398, 3403, 3400, 3424, 3404, 3411, 3402, 3406, + 3376, 3392, 3393, 3413, 3405, 3428, 3425, 3385, 3383, 3381, 3387, 3408, + 3390, 3391, 3388, 3421, 3379, 3416, 3426, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 22919, 22911, 22932, 22909, 22933, 22920, 22935, + 22915, 22906, 22923, 22921, 22929, 22905, 22913, 22908, 22910, 22916, + 22914, 22912, 22925, 22926, 22917, 22931, 22934, 22930, 22907, 22928, + 22927, 22922, 22924, 22918, 35536, 22944, 22946, 22943, 22942, 22939, + 22938, 22941, 22940, 22947, 22945, 35536, 35536, 35536, 35536, 22937, + 22936, 30246, 30243, 30244, 30245, 30198, 30195, 30196, 30197, 30250, + 30247, 30248, 30249, 30238, 30235, 30236, 30237, 30242, 30239, 30240, + 30241, 30234, 30231, 30232, 30233, 30194, 30191, 30192, 30193, 30226, + 30223, 30224, 30225, 30199, 30204, 30215, 30216, 30227, 30230, 30228, + 30229, 30222, 30219, 30220, 30221, 30210, 30207, 30208, 30209, 30261, + 30260, 30259, 30211, 30218, 30268, 30266, 30263, 30213, 30262, 30264, + 30206, 30214, 30203, 30205, 30202, 30253, 30257, 30265, 30212, 30217, + 30255, 30252, 30258, 30201, 30251, 30267, 30200, 30256, 30254, 30269, + 35536, 30276, 30278, 30275, 30274, 30271, 30270, 30273, 30272, 30279, + 30277, 35536, 35536, 35536, 35536, 35536, 35536, 3490, 3495, 3511, 3513, + 3503, 3501, 3493, 3487, 3494, 3507, 3502, 3498, 3509, 3492, 3488, 3510, + 3497, 3508, 3512, 3506, 3500, 3514, 3499, 3515, 3504, 3505, 3496, 3491, + 3489, 3516, 35536, 35536, 3483, 3485, 3486, 3484, 3482, 3517, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 25301, + 25302, 25307, 25308, 25295, 25296, 25311, 25312, 25303, 25304, 25293, + 25294, 25313, 25314, 25297, 25298, 25309, 25310, 25315, 25316, 25305, + 25306, 25299, 25300, 25317, 25318, 25291, 25292, 25237, 25228, 25234, + 25225, 25230, 25236, 25229, 25233, 25239, 25223, 25235, 25221, 25226, + 25224, 25232, 25227, 25231, 25240, 25238, 25222, 25245, 25244, 25242, + 25241, 25243, 25247, 25246, 25277, 25278, 25256, 25276, 25274, 25282, + 25284, 25283, 25285, 25275, 25267, 25280, 25265, 25287, 25260, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 25325, + 25327, 25324, 25323, 25320, 25319, 25322, 25321, 25328, 25326, 35536, + 25252, 25249, 25251, 25254, 25248, 25250, 25253, 35536, 25279, 25286, + 25264, 25272, 25288, 25263, 25270, 25281, 25269, 25290, 25271, 25266, + 25273, 25289, 25268, 25262, 25255, 25258, 25259, 25261, 25257, 35536, + 35536, 35536, 35536, 35536, 25209, 25216, 25208, 25207, 25217, 25205, + 25202, 25220, 25212, 25210, 25218, 25204, 25203, 25213, 25219, 25215, + 25211, 25206, 25214, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 17208, + 17205, 17210, 17204, 17193, 17192, 17189, 17188, 17181, 17187, 17186, + 17191, 17190, 17182, 17178, 17177, 17174, 17173, 17180, 17179, 17176, + 17175, 17183, 17195, 17194, 17185, 17184, 17200, 17203, 17201, 17199, + 17202, 17197, 17196, 17198, 17211, 17217, 17214, 17215, 17216, 17212, + 17218, 17213, 17209, 17207, 17206, 17220, 17219, 17227, 17229, 17226, + 17225, 17222, 17221, 17224, 17223, 17230, 17228, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 21582, 21586, 21589, 21590, 21560, + 21592, 21568, 21583, 21587, 21578, 21577, 21579, 21567, 21559, 21580, + 21576, 21573, 21574, 21588, 21570, 21581, 21584, 21566, 21564, 21591, + 21575, 21572, 21562, 21585, 21571, 21561, 21569, 21640, 21644, 21647, + 21648, 21618, 21650, 21626, 21641, 21645, 21636, 21635, 21637, 21625, + 21617, 21638, 21634, 21631, 21632, 21646, 21628, 21639, 21642, 21624, + 21622, 21649, 21633, 21630, 21620, 21643, 21629, 21619, 21627, 21604, + 21598, 21596, 21594, 21601, 21600, 21603, 21602, 21606, 21605, 21609, + 21611, 21608, 21607, 21612, 21613, 21615, 21616, 21610, 21614, 21599, + 21597, 21595, 21593, 21653, 21651, 21652, 35536, 35536, 35536, 35536, + 35536, 3702, 3719, 3704, 3708, 3721, 3709, 3716, 3726, 3705, 3717, 3722, + 3715, 3711, 3710, 3712, 3723, 3724, 3706, 3707, 3714, 3713, 3718, 3725, + 3720, 3703, 35536, 35536, 3727, 3744, 3729, 3733, 3746, 3734, 3741, 3751, + 3730, 3742, 3747, 3740, 3736, 3735, 3737, 3748, 3749, 3731, 3732, 3739, + 3738, 3743, 3750, 3745, 3728, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 22201, 22127, + 22189, 22200, 22205, 22204, 22124, 22206, 22181, 22180, 22178, 22135, + 22184, 22185, 22177, 22134, 22143, 22151, 22187, 22123, 22148, 22147, + 22142, 22141, 22140, 22139, 22165, 22133, 22164, 22132, 22207, 22138, + 22188, 22199, 22198, 22146, 22145, 22122, 22203, 22209, 22137, 22136, + 22174, 22130, 22150, 22149, 22173, 22129, 22182, 22186, 22158, 22161, + 22162, 22196, 22194, 22175, 22131, 22183, 22163, 22197, 22195, 22193, + 22191, 22121, 22192, 22190, 22208, 22125, 22202, 22126, 22160, 22128, + 22179, 22176, 22159, 35536, 35536, 35536, 35536, 22213, 22144, 22212, + 22211, 22210, 22218, 22224, 22223, 22219, 22220, 22245, 22249, 22266, + 22265, 22227, 22230, 22231, 22247, 22234, 22235, 22236, 22237, 22238, + 22241, 22243, 22244, 22240, 22251, 22252, 22253, 22254, 22259, 22255, + 22256, 22260, 22262, 22221, 22222, 22229, 22264, 22228, 22263, 22225, + 22233, 22226, 22250, 22267, 22268, 22257, 22261, 22248, 22246, 22269, + 22242, 22232, 22239, 22258, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 22217, 22215, 22216, 22214, 22166, 22167, 22168, 22169, 22170, + 22171, 22172, 22152, 22153, 22154, 22155, 22156, 22157, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 31163, 24157, 24377, 24376, 17172, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 33457, 33456, + 6583, 6584, 33978, 33979, 33980, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 30280, 30281, 30282, 30283, 30284, 30285, + 30286, 30287, 30288, 30289, 30290, 30291, 30292, 30293, 30294, 30295, + 30296, 30297, 30298, 30299, 30300, 30301, 30302, 30303, 30304, 30305, + 30306, 30307, 30308, 30309, 30310, 30311, 30312, 30313, 30314, 30315, + 30316, 30317, 30318, 30319, 30320, 30321, 30322, 30323, 30324, 30325, + 30326, 30327, 30328, 30329, 30330, 30331, 30332, 30333, 30334, 30335, + 30336, 30337, 30338, 30339, 30340, 30341, 30342, 30343, 30344, 30345, + 30346, 30347, 30348, 30349, 30350, 30351, 30352, 30353, 30354, 30355, + 30356, 30357, 30358, 30359, 30360, 30361, 30362, 30363, 30364, 30365, + 30366, 30367, 30368, 30369, 30370, 30371, 30372, 30373, 30374, 30375, + 30376, 30377, 30378, 30379, 30380, 30381, 30382, 30383, 30384, 30385, + 30386, 30387, 30388, 30389, 30390, 30391, 30392, 30393, 30394, 30395, + 30396, 30397, 30398, 30399, 30400, 30401, 30402, 30403, 30404, 30405, + 30406, 30407, 30408, 30409, 30410, 30411, 30412, 30413, 30414, 30415, + 30416, 30417, 30418, 30419, 30420, 30421, 30422, 30423, 30424, 30425, + 30426, 30427, 30428, 30429, 30430, 30431, 30432, 30433, 30434, 30435, + 30436, 30437, 30438, 30439, 30440, 30441, 30442, 30443, 30444, 30445, + 30446, 30447, 30448, 30449, 30450, 30451, 30452, 30453, 30454, 30455, + 30456, 30457, 30458, 30459, 30460, 30461, 30462, 30463, 30464, 30465, + 30466, 30467, 30468, 30469, 30470, 30471, 30472, 30473, 30474, 30475, + 30476, 30477, 30478, 30479, 30480, 30481, 30482, 30483, 30484, 30485, + 30486, 30487, 30488, 30489, 30490, 30491, 30492, 30493, 30494, 30495, + 30496, 30497, 30498, 30499, 30500, 30501, 30502, 30503, 30504, 30505, + 30506, 30507, 30508, 30509, 30510, 30511, 30512, 30513, 30514, 30515, + 30516, 30517, 30518, 30519, 30520, 30521, 30522, 30523, 30524, 30525, + 30526, 30527, 30528, 30529, 30530, 30531, 30532, 30533, 30534, 30535, + 30536, 30537, 30538, 30539, 30540, 30541, 30542, 30543, 30544, 30545, + 30546, 30547, 30548, 30549, 30550, 30551, 30552, 30553, 30554, 30555, + 30556, 30557, 30558, 30559, 30560, 30561, 30562, 30563, 30564, 30565, + 30566, 30567, 30568, 30569, 30570, 30571, 30572, 30573, 30574, 30575, + 30576, 30577, 30578, 30579, 30580, 30581, 30582, 30583, 30584, 30585, + 30586, 30587, 30588, 30589, 30590, 30591, 30592, 30593, 30594, 30595, + 30596, 30597, 30598, 30599, 30600, 30601, 30602, 30603, 30604, 30605, + 30606, 30607, 30608, 30609, 30610, 30611, 30612, 30613, 30614, 30615, + 30616, 30617, 30618, 30619, 30620, 30621, 30622, 30623, 30624, 30625, + 30626, 30627, 30628, 30629, 30630, 30631, 30632, 30633, 30634, 30635, + 30636, 30637, 30638, 30639, 30640, 30641, 30642, 30643, 30644, 30645, + 30646, 30647, 30648, 30649, 30650, 30651, 30652, 30653, 30654, 30655, + 30656, 30657, 30658, 30659, 30660, 30661, 30662, 30663, 30664, 30665, + 30666, 30667, 30668, 30669, 30670, 30671, 30672, 30673, 30674, 30675, + 30676, 30677, 30678, 30679, 30680, 30681, 30682, 30683, 30684, 30685, + 30686, 30687, 30688, 30689, 30690, 30691, 30692, 30693, 30694, 30695, + 30696, 30697, 30698, 30699, 30700, 30701, 30702, 30703, 30704, 30705, + 30706, 30707, 30708, 30709, 30710, 30711, 30712, 30713, 30714, 30715, + 30716, 30717, 30718, 30719, 30720, 30721, 30722, 30723, 30724, 30725, + 30726, 30727, 30728, 30729, 30730, 30731, 30732, 30733, 30734, 30735, + 30736, 30737, 30738, 30739, 30740, 30741, 30742, 30743, 30744, 30745, + 30746, 30747, 30748, 30749, 30750, 30751, 30752, 30753, 30754, 30755, + 30756, 30757, 30758, 30759, 30760, 30761, 30762, 30763, 30764, 30765, + 30766, 30767, 30768, 30769, 30770, 30771, 30772, 30773, 30774, 30775, + 30776, 30777, 30778, 30779, 30780, 30781, 30782, 30783, 30784, 30785, + 30786, 30787, 30788, 30789, 30790, 30791, 30792, 30793, 30794, 30795, + 30796, 30797, 30798, 30799, 30800, 30801, 30802, 30803, 30804, 30805, + 30806, 30807, 30808, 30809, 30810, 30811, 30812, 30813, 30814, 30815, + 30816, 30817, 30818, 30819, 30820, 30821, 30822, 30823, 30824, 30825, + 30826, 30827, 30828, 30829, 30830, 30831, 30832, 30833, 30834, 30835, + 30836, 30837, 30838, 30839, 30840, 30841, 30842, 30843, 30844, 30845, + 30846, 30847, 30848, 30849, 30850, 30851, 30852, 30853, 30854, 30855, + 30856, 30857, 30858, 30859, 30860, 30861, 30862, 30863, 30864, 30865, + 30866, 30867, 30868, 30869, 30870, 30871, 30872, 30873, 30874, 30875, + 30876, 30877, 30878, 30879, 30880, 30881, 30882, 30883, 30884, 30885, + 30886, 30887, 30888, 30889, 30890, 30891, 30892, 30893, 30894, 30895, + 30896, 30897, 30898, 30899, 30900, 30901, 30902, 30903, 30904, 30905, + 30906, 30907, 30908, 30909, 30910, 30911, 30912, 30913, 30914, 30915, + 30916, 30917, 30918, 30919, 30920, 30921, 30922, 30923, 30924, 30925, + 30926, 30927, 30928, 30929, 30930, 30931, 30932, 30933, 30934, 30935, + 30936, 30937, 30938, 30939, 30940, 30941, 30942, 30943, 30944, 30945, + 30946, 30947, 30948, 30949, 30950, 30951, 30952, 30953, 30954, 30955, + 30956, 30957, 30958, 30959, 30960, 30961, 30962, 30963, 30964, 30965, + 30966, 30967, 30968, 30969, 30970, 30971, 30972, 30973, 30974, 30975, + 30976, 30977, 30978, 30979, 30980, 30981, 30982, 30983, 30984, 30985, + 30986, 30987, 30988, 30989, 30990, 30991, 30992, 30993, 30994, 30995, + 30996, 30997, 30998, 30999, 31000, 31001, 31002, 31003, 31004, 31005, + 31006, 31007, 31008, 31009, 31010, 31011, 31012, 31013, 31014, 31015, + 31016, 31017, 31018, 31019, 31020, 31021, 31022, 31023, 31024, 31025, + 31026, 31027, 31028, 31029, 31030, 31031, 31032, 31033, 31034, 31035, + 31036, 31037, 31038, 31039, 31040, 31041, 31042, 31043, 31044, 31045, + 31046, 31047, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 31048, 31049, 31050, 31051, 31052, 31053, 31054, 31055, 31056, 31057, + 31058, 31059, 31060, 31061, 31062, 31063, 31064, 31065, 31066, 31067, + 31068, 31069, 31070, 31071, 31072, 31073, 31074, 31075, 31076, 31077, + 31078, 31079, 31080, 31081, 31082, 31083, 31084, 31085, 31086, 31087, + 31088, 31089, 31090, 31091, 31092, 31093, 31094, 31095, 31096, 31097, + 31098, 31099, 31100, 31101, 31102, 31103, 31104, 31105, 31106, 31107, + 31108, 31109, 31110, 31111, 31112, 31113, 31114, 31115, 31116, 31117, + 31118, 31119, 31120, 31121, 31122, 31123, 31124, 31125, 31126, 31127, + 31128, 31129, 31130, 31131, 31132, 31133, 31134, 31135, 31136, 31137, + 31138, 31139, 31140, 31141, 31142, 31143, 31144, 31145, 31146, 31147, + 31148, 31149, 31150, 31151, 31152, 31153, 31154, 31155, 31156, 31157, + 31158, 31159, 31160, 31161, 31162, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 16490, 16491, + 16492, 16493, 35536, 16494, 16495, 16483, 16484, 16485, 16486, 16487, + 35536, 16488, 16489, 35536, 16471, 15443, 15082, 15083, 15084, 15081, + 15363, 15364, 15365, 15366, 15355, 15356, 15357, 15358, 15359, 15350, + 15351, 15352, 15353, 15354, 15360, 15361, 15362, 15121, 15125, 15126, + 15127, 15128, 15129, 15130, 15131, 15132, 15122, 15123, 15124, 15137, + 15138, 15139, 15140, 15141, 15142, 15143, 15144, 15151, 15152, 15153, + 15154, 15155, 15156, 15157, 15145, 15146, 15147, 15148, 15149, 15150, + 15134, 15135, 15136, 15133, 15246, 15247, 15248, 15249, 15250, 15251, + 15252, 15253, 15262, 15263, 15264, 15265, 15266, 15267, 15254, 15255, + 15256, 15257, 15258, 15259, 15260, 15261, 15268, 15269, 15270, 15271, + 15272, 15273, 15274, 15275, 15276, 15277, 15278, 15279, 15308, 15309, + 15310, 15311, 15301, 15302, 15303, 15304, 15305, 15306, 15307, 15297, + 15298, 15299, 15300, 15296, 15280, 15281, 15282, 15283, 15284, 15285, + 15286, 15287, 15288, 15290, 15291, 15292, 15293, 15294, 15295, 15289, + 15200, 15201, 15202, 15203, 15204, 15205, 15206, 15207, 15208, 15193, + 15194, 15195, 15196, 15197, 15198, 15199, 15192, 15214, 15215, 15216, + 15186, 15187, 15188, 15189, 15190, 15191, 15185, 15209, 15210, 15211, + 15212, 15213, 15093, 15096, 15097, 15098, 15099, 15100, 15101, 15102, + 15103, 15094, 15095, 15114, 15115, 15116, 15117, 15118, 15119, 15120, + 15104, 15105, 15106, 15107, 15108, 15109, 15110, 15111, 15112, 15113, + 15085, 15086, 15087, 15088, 15089, 15090, 15091, 15092, 15167, 15168, + 15169, 15170, 15171, 15172, 15173, 15174, 15175, 15176, 15177, 15178, + 15179, 15180, 15181, 15182, 15183, 15184, 15159, 15160, 15158, 15161, + 15162, 15163, 15164, 15165, 15166, 15334, 15335, 15336, 15337, 15338, + 15333, 15345, 15346, 15347, 15348, 15339, 15340, 15341, 15342, 15343, + 15344, 15238, 15239, 15240, 15241, 15231, 15232, 15233, 15234, 15235, + 15236, 15237, 15225, 15226, 15227, 15228, 15229, 15230, 15242, 15243, + 15244, 15245, 15219, 15220, 15221, 15222, 15223, 15224, 15312, 15313, + 15314, 15315, 15316, 15317, 15318, 15319, 15320, 15321, 15329, 15330, + 15331, 15332, 15322, 15323, 15324, 15325, 15326, 15327, 15328, 15217, + 15218, 15442, 16469, 16468, 16470, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 15453, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 15446, 15445, 15447, 35536, 35536, 16518, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 16524, 16523, 16525, 16529, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 10635, 10633, 10582, 10615, + 10542, 10555, 10559, 10640, 10536, 10623, 10544, 10586, 10585, 10537, + 10543, 10557, 10589, 10618, 10611, 10538, 10558, 10612, 10636, 10562, + 10590, 10563, 10568, 10546, 10591, 10564, 10569, 10549, 10592, 10566, + 10571, 10547, 10548, 10600, 10601, 10567, 10572, 10553, 10604, 10565, + 10570, 10550, 10593, 10554, 10551, 10552, 10598, 10599, 10596, 10597, + 10617, 10616, 10625, 10631, 10628, 10603, 10602, 10556, 10545, 10594, + 10595, 10534, 10609, 10579, 10577, 10535, 10637, 10539, 10638, 10614, + 10622, 10540, 10606, 10587, 10605, 10560, 10639, 10619, 10541, 10634, + 10620, 10561, 10588, 10621, 10613, 10578, 10581, 10580, 10630, 10626, + 10632, 10629, 10627, 10576, 10575, 10574, 10573, 10584, 10583, 10607, + 10610, 10608, 10624, 35536, 35536, 35536, 35536, 35536, 10519, 10532, + 10531, 10526, 10533, 10513, 10506, 10505, 10502, 10504, 10507, 10508, + 10503, 35536, 35536, 35536, 10515, 10511, 10514, 10509, 10518, 10517, + 10510, 10516, 10512, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 10520, 10524, 10527, 10522, 10530, 10529, 10523, 10528, 10525, 10521, + 35536, 35536, 10644, 10641, 10642, 10643, 27160, 27159, 27161, 27162, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 32371, 26351, 18859, 26348, 10409, 19867, 26319, 19925, + 967, 15578, 33426, 18817, 22276, 26304, 18852, 26341, 24231, 25897, + 26089, 15574, 33400, 19807, 19806, 19805, 19804, 19802, 19803, 4587, + 4588, 4596, 4610, 4480, 4479, 26890, 26898, 26891, 26902, 26895, 26899, + 26892, 26904, 26897, 26901, 26894, 26903, 26896, 26900, 26893, 32410, + 32378, 32380, 32465, 32427, 32423, 32459, 32429, 19951, 19898, 19918, + 19953, 19901, 19943, 19945, 19924, 28433, 28434, 24959, 9958, 9694, 9693, + 28445, 28446, 18865, 26328, 12612, 12613, 352, 351, 358, 357, 360, 359, + 355, 356, 353, 354, 18855, 32363, 26344, 10415, 32037, 32033, 32041, + 4442, 4440, 4446, 18848, 32358, 26338, 10411, 23000, 18858, 32366, 26347, + 10418, 11778, 11779, 3944, 3947, 3946, 3945, 3978, 18871, 32356, 26334, + 10421, 18872, 32357, 26335, 10422, 18861, 32360, 26350, 10413, 28678, + 28679, 28677, 28676, 28870, 28872, 28871, 28869, 33410, 15557, 33823, + 33824, 32283, 28510, 28509, 28508, 28463, 15953, 18731, 15954, 33415, + 15555, 18866, 26329, 18867, 26330, 12597, 18857, 32365, 26346, 10417, + 15577, 33425, 33403, 18860, 26349, 18854, 26343, 18856, 26345, 18765, + 26262, 32419, 32455, 32418, 32454, 19887, 19907, 19886, 19906, 19884, + 19904, 19885, 19905, 32422, 32458, 19897, 19917, 32420, 32456, 19896, + 19916, 32413, 32449, 19891, 19911, 32416, 32452, 19894, 19914, 32417, + 32453, 19895, 19915, 32412, 32448, 19890, 19910, 32414, 32450, 19892, + 19912, 32415, 32451, 19893, 19913, 32421, 32457, 19888, 19908, 25137, + 25138, 25139, 25140, 25141, 25142, 25143, 25144, 25145, 25146, 25147, + 25148, 25149, 25150, 25151, 25152, 25153, 25154, 25155, 25156, 25157, + 25158, 25159, 25160, 25161, 25162, 25173, 25175, 25172, 25171, 25168, + 25167, 25170, 25169, 25176, 25174, 28214, 12614, 24141, 35536, 35536, + 35536, 4239, 4183, 4054, 4269, 4140, 4081, 4240, 4121, 4184, 4230, 4156, + 4215, 4097, 4112, 4200, 4066, 4273, 4141, 4171, 4082, 4241, 4122, 4185, + 4055, 4236, 4164, 4223, 4105, 4262, 4118, 4208, 4074, 4149, 4177, 4090, + 4248, 4130, 4193, 4060, 4231, 4157, 4216, 4098, 4255, 4113, 4201, 4067, + 4274, 4142, 4172, 4083, 4242, 4123, 4186, 4168, 4227, 4109, 4266, 4137, + 4212, 4078, 4281, 4153, 4180, 4094, 4252, 4134, 4197, 4063, 4161, 4220, + 4102, 4259, 4205, 4071, 4278, 4146, 4087, 4245, 4127, 4190, 4237, 4165, + 4224, 4106, 4263, 4119, 4209, 4075, 4270, 4150, 4178, 4091, 4249, 4131, + 4194, 4061, 4232, 4158, 4217, 4099, 4256, 4114, 4202, 4068, 4275, 4143, + 4173, 4084, 4243, 4124, 4187, 4056, 4170, 4229, 4111, 4268, 4139, 4214, + 4080, 4283, 4155, 4182, 4096, 4254, 4136, 4199, 4065, 4235, 4163, 4222, + 4104, 4261, 4117, 4207, 4073, 4280, 4148, 4176, 4089, 4247, 4129, 4192, + 4059, 4167, 4226, 4108, 4265, 4211, 4077, 4272, 4152, 4093, 4251, 4133, + 4196, 4233, 4160, 4219, 4101, 4258, 4115, 4204, 4070, 4277, 4145, 4174, + 4086, 4244, 4126, 4189, 4057, 4169, 4228, 4110, 4267, 4138, 4213, 4079, + 4282, 4154, 4181, 4095, 4253, 4135, 4198, 4064, 4234, 4162, 4221, 4103, + 4260, 4116, 4206, 4072, 4279, 4147, 4175, 4088, 4246, 4128, 4191, 4058, + 4238, 4166, 4225, 4107, 4264, 4120, 4210, 4076, 4271, 4151, 4179, 4092, + 4250, 4132, 4195, 4062, 4159, 4218, 4100, 4257, 4203, 4069, 4276, 4144, + 4085, 4125, 4188, 32045, 4449, 32042, 4447, 32043, 4448, 32038, 4443, + 32039, 4444, 32032, 4436, 4437, 4438, 4439, 22884, 32034, 32035, 10412, + 18849, 28184, 32361, 10414, 12483, 12484, 12485, 26257, 19858, 12486, + 32385, 19860, 14933, 33885, 32056, 12770, 4481, 4478, 18769, 26266, + 18768, 26265, 15554, 18766, 26263, 15553, 19861, 32388, 33416, 4606, + 4604, 4605, 4603, 17403, 17402, 17407, 17401, 17379, 17358, 17359, 17399, + 17365, 17383, 17406, 17381, 17404, 17405, 17387, 17384, 17364, 17363, + 17366, 17382, 17367, 17355, 17376, 17400, 17356, 17357, 17354, 17380, + 17385, 17371, 17362, 17386, 17388, 17361, 17378, 17370, 17368, 17369, + 17360, 17408, 17377, 17372, 17375, 17373, 17374, 17396, 17394, 17395, + 17398, 17393, 17390, 17397, 17392, 17391, 17389, 26905, 26937, 26906, + 26953, 26922, 26938, 26907, 26961, 26930, 26946, 26915, 26954, 26923, + 26939, 26908, 26965, 26934, 26950, 26919, 26958, 26927, 26943, 26912, + 26962, 26931, 26947, 26916, 26955, 26924, 26940, 26909, 26967, 26936, + 26952, 26921, 26960, 26929, 26945, 26914, 26964, 26933, 26949, 26918, + 26957, 26926, 26942, 26911, 26966, 26935, 26951, 26920, 26959, 26928, + 26944, 26913, 26963, 26932, 26948, 26917, 26956, 26925, 26941, 26910, + 32405, 32377, 32379, 32444, 32426, 32424, 32425, 32428, 19950, 19948, + 19949, 19952, 19903, 19942, 19944, 19938, 26267, 26307, 18820, 18770, + 19863, 19958, 32468, 32390, 18771, 18821, 26308, 26268, 32391, 32469, + 19959, 19864, 15579, 16781, 24646, 3984, 35536, 35536, 35536, 35536, + 35536, 35536, 12650, 25186, 32117, 1057, 6577, 28866, 15076, 15975, + 12602, 22119, 25522, 33452, 11772, 15974, 12478, 26026, 31511, 21764, + 12628, 2574, 3597, 369, 19085, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 12869, + 12866, 12858, 12864, 12870, 12856, 12862, 12859, 12865, 12861, 12857, + 12867, 12863, 12868, 12860, 12871, 21676, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35352, 35357, 35391, 35354, 35359, 35387, 35381, 35375, 35398, + 35377, 35371, 35395, 35353, 35358, 35392, 35355, 35360, 35388, 35382, + 35376, 35399, 35378, 35372, 35396, 35393, 35379, 35386, 35373, 35374, + 35397, 35380, 35356, 35402, 35367, 35384, 35394, 35405, 35404, 35370, + 35403, 35364, 35363, 35401, 35385, 35383, 35362, 35536, 35536, 35407, + 35408, 35409, 35400, 35350, 35365, 35368, 35369, 35347, 35348, 35366, + 35389, 35390, 35351, 35406, 35349, 35361, 35346, 35528, 35529, 35526, + 35527, 35530, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35426, 35427, 35443, 35415, 35424, 35523, 35478, 35479, 35446, + 35447, 35480, 35410, 35444, 35524, 35422, 35419, 35421, 35420, 35418, + 35520, 35519, 35522, 35521, 35516, 35515, 35518, 35517, 35416, 35450, + 35412, 35423, 35411, 35448, 35461, 35462, 35460, 35459, 35413, 35457, + 35458, 35456, 35454, 35455, 35453, 35452, 35463, 35465, 35466, 35464, + 35428, 35451, 35417, 35425, 35525, 35467, 35472, 35469, 35473, 35470, + 35475, 35476, 35471, 35468, 35474, 35449, 35477, 35510, 35507, 35498, + 35508, 35509, 35499, 35487, 35486, 35514, 35484, 35483, 35481, 35485, + 35482, 35501, 35506, 35500, 35504, 35505, 35502, 35503, 35430, 35434, + 35433, 35432, 35431, 35513, 35511, 35512, 35437, 35442, 35441, 35440, + 35439, 35438, 35488, 35497, 35490, 35495, 35489, 35493, 35494, 35491, + 35492, 35496, 35429, 35436, 35414, 35435, 35445, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 5296, 5168, 5289, 5271, + 5272, 5340, 5341, 5221, 5318, 5278, 5352, 5353, 5244, 5123, 5174, 5321, + 5222, 5126, 5127, 5316, 5328, 5267, 5204, 5295, 5147, 5344, 5216, 5230, + 5226, 5319, 5281, 5310, 5274, 5343, 5129, 5131, 5231, 5297, 5282, 5339, + 5121, 5299, 5313, 5315, 5269, 5323, 5251, 5169, 5331, 5322, 5241, 5122, + 5181, 5212, 5333, 5219, 5287, 5291, 5234, 5145, 5298, 5276, 5279, 5218, + 5356, 5286, 5235, 5334, 5311, 5210, 5217, 5268, 5273, 5285, 5237, 5284, + 5242, 5288, 5225, 5229, 5355, 5128, 5124, 5354, 5243, 5177, 5148, 5266, + 5342, 5283, 5292, 5275, 5120, 5252, 5280, 5277, 5173, 5245, 5119, 5335, + 5176, 5314, 5317, 5146, 5175, 5300, 5357, 5337, 5293, 5332, 5336, 5290, + 5338, 5294, 5207, 5133, 5172, 5270, 5325, 5326, 5324, 5327, 5220, 5170, + 5345, 5346, 5309, 5233, 5166, 5238, 5239, 5240, 5130, 5132, 5165, 5330, + 5320, 5236, 5246, 5250, 5249, 5248, 5247, 5206, 5203, 5202, 5160, 5162, + 5163, 5161, 5329, 5134, 5214, 5153, 5117, 5111, 5112, 5115, 5116, 5114, + 5113, 5118, 5259, 5254, 5255, 5253, 5264, 5263, 5262, 5261, 5265, 5257, + 5215, 5125, 5180, 5179, 5178, 5260, 5258, 5256, 5208, 5209, 5171, 5213, + 5211, 5182, 5189, 5185, 5193, 5188, 5197, 5187, 5186, 5183, 5184, 5191, + 5192, 5199, 5196, 5194, 5143, 5144, 5142, 5190, 5198, 5351, 5156, 5154, + 5157, 5159, 5158, 5155, 5347, 5349, 5348, 5350, 5200, 5201, 5150, 5149, + 5151, 5152, 5305, 5308, 5306, 5307, 5301, 5304, 5302, 5303, 5164, 5167, + 5312, 5141, 5135, 5140, 5138, 5137, 5136, 5139, 5223, 5227, 5224, 5228, + 5232, 5205, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 23189, 23066, 23082, 23174, 23061, 23186, 23124, 23175, + 23173, 23062, 23058, 23185, 23052, 23170, 23171, 23172, 23077, 23078, + 23015, 23016, 23011, 23010, 23141, 23212, 23209, 23084, 23083, 23190, + 23191, 23085, 23094, 23095, 23096, 23055, 23087, 23088, 23089, 23068, + 23069, 35536, 35536, 23132, 23065, 23067, 23093, 23092, 23137, 23136, + 23188, 23187, 23164, 23165, 23051, 23057, 23153, 23154, 23168, 23169, + 23133, 23235, 23107, 23167, 23076, 23193, 23211, 23195, 23140, 23233, + 23156, 23056, 23196, 23197, 23220, 23221, 23224, 23225, 23222, 23223, + 23216, 23217, 23218, 23219, 23130, 23131, 23226, 23227, 23155, 23231, + 23138, 23135, 23019, 23020, 23014, 23234, 23106, 23166, 23075, 23192, + 23210, 23194, 23139, 23040, 23041, 23044, 23045, 23046, 23079, 23080, + 23081, 23023, 23030, 23031, 23032, 23033, 23034, 23008, 23073, 23009, + 23074, 23007, 23071, 23006, 23070, 23021, 23039, 23047, 23038, 23024, + 23025, 23022, 23049, 23104, 23103, 23028, 23050, 23035, 23042, 23048, + 23027, 23043, 23176, 23199, 23238, 23163, 23126, 23086, 23054, 23063, + 23100, 23099, 23215, 23228, 23237, 23229, 23230, 23142, 23145, 23146, + 23147, 23148, 23149, 23150, 23151, 23152, 23143, 23144, 23108, 23134, + 23072, 23064, 23026, 23029, 23036, 23037, 23158, 23157, 23105, 23098, + 23097, 23236, 23059, 23060, 23125, 23121, 23012, 23179, 23181, 23127, + 23129, 23182, 23184, 23090, 23091, 23123, 23122, 23013, 23180, 23128, + 23183, 23207, 23206, 23208, 23205, 23201, 23202, 23203, 23204, 23053, + 23101, 23102, 23198, 23232, 23160, 23018, 23177, 23017, 23213, 23161, + 23162, 23178, 23214, 23159, 23109, 23112, 23116, 23119, 23118, 23117, + 23113, 23114, 23110, 23111, 23115, 23200, 23120, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 13784, 13772, + 13795, 13796, 13778, 13797, 13798, 13799, 13800, 13785, 13786, 13787, + 13788, 13789, 13790, 13791, 13792, 13793, 13794, 13773, 13774, 13775, + 13776, 13777, 13779, 13780, 13781, 13782, 13783, 13504, 13512, 13525, + 13533, 13539, 13540, 13505, 13506, 13507, 13508, 13509, 13510, 13511, + 13513, 13514, 13515, 13516, 13517, 13518, 13519, 13520, 13521, 13522, + 13523, 13524, 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13534, + 13535, 13536, 13537, 13538, 7373, 7372, 7374, 13564, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 16761, + 16762, 16759, 16757, 16748, 16747, 16754, 16752, 16743, 16750, 16760, + 16745, 16758, 16756, 16749, 16746, 16755, 16753, 16744, 16751, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 21540, 21541, 21538, 21536, 21527, 21526, 21533, 21531, 21522, + 21529, 21539, 21524, 21537, 21535, 21528, 21525, 21534, 21532, 21523, + 21530, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 22877, 10003, 10004, 9998, 9997, 9996, 31305, 31325, + 31346, 31294, 31339, 31303, 31289, 31348, 31293, 31307, 31313, 31336, + 31337, 31351, 31357, 31304, 31335, 31365, 31323, 31290, 31353, 31355, + 31322, 31368, 31302, 31317, 31314, 31295, 31309, 31292, 31350, 31343, + 31297, 31340, 31329, 31363, 31352, 31326, 31354, 31342, 31356, 31331, + 31319, 31362, 31332, 31318, 31349, 31358, 31328, 31364, 31301, 31345, + 31321, 31367, 31311, 31296, 31333, 31330, 31344, 31288, 31316, 31315, + 31366, 31360, 31338, 31308, 31306, 31312, 31320, 31359, 31361, 31334, + 31300, 31298, 31327, 31291, 31299, 31347, 31310, 31341, 31324, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 7787, 7785, 7784, + 7781, 7780, 7783, 7782, 7788, 7786, 7778, 7776, 7775, 7772, 7771, 7774, + 7773, 7779, 7777, 15666, 15665, 15664, 15663, 15662, 29774, 29773, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 20520, 20522, 20550, 20513, 20526, 20558, + 20529, 20559, 20531, 20560, 20533, 20535, 20552, 20554, 20537, 20540, + 20561, 20544, 20546, 20516, 20548, 20562, 20563, 20556, 20564, 20524, + 20568, 20570, 20603, 20565, 20574, 20577, 20579, 20611, 20581, 20612, + 20583, 20585, 20605, 20607, 20587, 20590, 20613, 20594, 20596, 20598, + 20601, 20614, 20615, 20609, 20616, 20572, 21008, 21010, 21040, 21014, + 21016, 21048, 21019, 21049, 21021, 21050, 21023, 21025, 21042, 21044, + 21027, 21030, 21051, 21034, 21036, 21004, 21038, 21052, 21053, 21046, + 21054, 21012, 20956, 20958, 20991, 20952, 20962, 20965, 20967, 35536, + 20969, 20999, 20971, 20973, 20993, 20995, 20975, 20978, 21000, 20982, + 20984, 20986, 20989, 21001, 21002, 20997, 21003, 20960, 20673, 20675, + 20705, 20679, 20681, 20713, 20684, 20714, 20686, 20715, 20688, 20690, + 20707, 20709, 20692, 20695, 20716, 20699, 20701, 20669, 20703, 20717, + 20718, 20711, 20719, 20677, 20727, 20729, 20764, 20733, 20735, 20738, + 20740, 20772, 20742, 20773, 20744, 20746, 20766, 20768, 20748, 20751, + 20774, 20755, 20757, 20759, 20762, 20775, 20776, 20770, 20777, 20731, + 21480, 35536, 21481, 21482, 35536, 35536, 21483, 35536, 35536, 21484, + 21485, 35536, 35536, 21486, 21487, 21488, 21489, 35536, 21490, 21491, + 21492, 21493, 21494, 21495, 21496, 21497, 21498, 21499, 21500, 21501, + 35536, 21502, 35536, 21503, 21504, 21505, 21506, 21507, 21508, 21509, + 35536, 21510, 21511, 21512, 21513, 21514, 21515, 21516, 21517, 21518, + 21519, 21520, 20617, 20618, 20619, 20620, 20621, 20622, 20623, 20624, + 20625, 20626, 20627, 20628, 20629, 20630, 20631, 20632, 20633, 20634, + 20635, 20636, 20637, 20638, 20639, 20640, 20641, 20642, 20643, 20644, + 20645, 20646, 20647, 20648, 20649, 20650, 20651, 20652, 20653, 20654, + 20655, 20656, 20657, 20658, 20659, 20660, 20661, 20662, 20663, 20664, + 20665, 20666, 20667, 20668, 20904, 20905, 35536, 20906, 20907, 20908, + 20909, 35536, 35536, 20910, 20911, 20912, 20913, 20914, 20915, 20916, + 20917, 35536, 20918, 20919, 20920, 20921, 20922, 20923, 20924, 35536, + 20925, 20926, 20927, 20928, 20929, 20930, 20931, 20932, 20933, 20934, + 20935, 20936, 20937, 20938, 20939, 20940, 20941, 20942, 20943, 20944, + 20945, 20946, 20947, 20948, 20949, 20950, 20849, 20850, 35536, 20851, + 20852, 20853, 20854, 35536, 20855, 20856, 20857, 20858, 20859, 35536, + 20860, 35536, 35536, 35536, 20861, 20862, 20863, 20864, 20865, 20866, + 20867, 35536, 20868, 20869, 20870, 20871, 20872, 20873, 20874, 20875, + 20876, 20877, 20878, 20879, 20880, 20881, 20882, 20883, 20884, 20885, + 20886, 20887, 20888, 20889, 20890, 20891, 20892, 20893, 20787, 20788, + 20789, 20790, 20791, 20792, 20793, 20794, 20795, 20796, 20797, 20798, + 20799, 20800, 20801, 20802, 20803, 20804, 20805, 20806, 20807, 20808, + 20809, 20810, 20811, 20812, 20813, 20814, 20815, 20816, 20817, 20818, + 20819, 20820, 20821, 20822, 20823, 20824, 20825, 20826, 20827, 20828, + 20829, 20830, 20831, 20832, 20833, 20834, 20835, 20836, 20837, 20838, + 21418, 21419, 21420, 21421, 21422, 21423, 21424, 21425, 21426, 21427, + 21428, 21429, 21430, 21431, 21432, 21433, 21434, 21435, 21436, 21437, + 21438, 21439, 21440, 21441, 21442, 21443, 21444, 21445, 21446, 21447, + 21448, 21449, 21450, 21451, 21452, 21453, 21454, 21455, 21456, 21457, + 21458, 21459, 21460, 21461, 21462, 21463, 21464, 21465, 21466, 21467, + 21468, 21469, 21250, 21252, 21282, 21256, 21258, 21290, 21261, 21291, + 21263, 21292, 21265, 21267, 21284, 21286, 21269, 21272, 21293, 21276, + 21278, 21246, 21280, 21294, 21295, 21288, 21296, 21254, 21304, 21306, + 21341, 21310, 21312, 21315, 21317, 21349, 21319, 21350, 21321, 21323, + 21343, 21345, 21325, 21328, 21351, 21332, 21334, 21336, 21339, 21352, + 21353, 21347, 21354, 21308, 21366, 21367, 21368, 21369, 21370, 21371, + 21372, 21373, 21374, 21375, 21376, 21377, 21378, 21379, 21380, 21381, + 21382, 21383, 21384, 21385, 21386, 21387, 21388, 21389, 21390, 21391, + 21392, 21393, 21394, 21395, 21396, 21397, 21398, 21399, 21400, 21401, + 21402, 21403, 21404, 21405, 21406, 21407, 21408, 21409, 21410, 21411, + 21412, 21413, 21414, 21415, 21416, 21417, 21140, 21142, 21172, 21146, + 21148, 21180, 21151, 21181, 21153, 21182, 21155, 21157, 21174, 21176, + 21159, 21162, 21183, 21166, 21168, 21136, 21170, 21184, 21185, 21178, + 21186, 21144, 21194, 21196, 21231, 21200, 21202, 21205, 21207, 21239, + 21209, 21240, 21211, 21213, 21233, 21235, 21215, 21218, 21241, 21222, + 21224, 21226, 21229, 21242, 21243, 21237, 21244, 21198, 21063, 21064, + 21065, 21066, 21067, 21068, 21069, 21070, 21071, 21072, 21073, 21074, + 21075, 21076, 21077, 21078, 21079, 21080, 21081, 21082, 21083, 21084, + 21085, 21086, 21087, 21088, 21089, 21090, 21091, 21092, 21093, 21094, + 21095, 21096, 21097, 21098, 21099, 21100, 21101, 21102, 21103, 21104, + 21105, 21106, 21107, 21108, 21109, 21110, 21111, 21112, 21113, 21114, + 20953, 20954, 35536, 35536, 20521, 20523, 20530, 20515, 20527, 20525, + 20528, 20517, 20532, 20534, 20536, 20553, 20555, 20557, 20538, 20543, + 20545, 20518, 20547, 20519, 20549, 20541, 20551, 20542, 20539, 20781, + 20569, 20571, 20580, 20567, 20575, 20573, 20576, 20599, 20582, 20584, + 20586, 20606, 20608, 20610, 20588, 20593, 20595, 20578, 20597, 20600, + 20602, 20591, 20604, 20592, 20589, 20783, 20779, 20786, 20780, 20782, + 20785, 20784, 21009, 21011, 21020, 21015, 21017, 21013, 21018, 21005, + 21022, 21024, 21026, 21043, 21045, 21047, 21028, 21033, 21035, 21006, + 21037, 21007, 21039, 21031, 21041, 21032, 21029, 21057, 20957, 20959, + 20968, 20955, 20963, 20961, 20964, 20987, 20970, 20972, 20974, 20994, + 20996, 20998, 20976, 20981, 20983, 20966, 20985, 20988, 20990, 20979, + 20992, 20980, 20977, 21059, 21055, 21062, 21056, 21058, 21061, 21060, + 20674, 20676, 20685, 20680, 20682, 20678, 20683, 20670, 20687, 20689, + 20691, 20708, 20710, 20712, 20693, 20698, 20700, 20671, 20702, 20672, + 20704, 20696, 20706, 20697, 20694, 20722, 20728, 20730, 20741, 20734, + 20736, 20732, 20737, 20760, 20743, 20745, 20747, 20767, 20769, 20771, + 20749, 20754, 20756, 20739, 20758, 20761, 20763, 20752, 20765, 20753, + 20750, 20724, 20720, 20778, 20721, 20723, 20726, 20725, 21251, 21253, + 21262, 21257, 21259, 21255, 21260, 21247, 21264, 21266, 21268, 21285, + 21287, 21289, 21270, 21275, 21277, 21248, 21279, 21249, 21281, 21273, + 21283, 21274, 21271, 21299, 21305, 21307, 21318, 21311, 21313, 21309, + 21314, 21337, 21320, 21322, 21324, 21344, 21346, 21348, 21326, 21331, + 21333, 21316, 21335, 21338, 21340, 21329, 21342, 21330, 21327, 21301, + 21297, 21355, 21298, 21300, 21303, 21302, 21141, 21143, 21152, 21147, + 21149, 21145, 21150, 21137, 21154, 21156, 21158, 21175, 21177, 21179, + 21160, 21165, 21167, 21138, 21169, 21139, 21171, 21163, 21173, 21164, + 21161, 21189, 21195, 21197, 21208, 21201, 21203, 21199, 21204, 21227, + 21210, 21212, 21214, 21234, 21236, 21238, 21216, 21221, 21223, 21206, + 21225, 21228, 21230, 21219, 21232, 21220, 21217, 21191, 21187, 21245, + 21188, 21190, 21193, 21192, 20514, 20566, 35536, 35536, 20845, 20847, + 20844, 20843, 20840, 20839, 20842, 20841, 20848, 20846, 20900, 20902, + 20899, 20898, 20895, 20894, 20897, 20896, 20903, 20901, 21476, 21478, + 21475, 21474, 21471, 21470, 21473, 21472, 21479, 21477, 21362, 21364, + 21361, 21360, 21357, 21356, 21359, 21358, 21365, 21363, 21121, 21123, + 21120, 21119, 21116, 21115, 21118, 21117, 21124, 21122, 27439, 27395, + 27420, 27636, 27591, 27377, 27440, 27404, 27553, 27505, 27481, 27442, + 27445, 27402, 27446, 27396, 27447, 27469, 27464, 27502, 27443, 27449, + 27458, 27459, 27450, 27456, 27460, 27398, 27532, 27441, 27470, 27399, + 27479, 27448, 27478, 27465, 27504, 27503, 27444, 27463, 27473, 27474, + 27477, 27476, 27544, 27452, 27453, 27454, 27526, 27494, 27457, 27461, + 27455, 27451, 27525, 27486, 27524, 27523, 27483, 27482, 27485, 27475, + 27472, 27471, 27521, 27520, 27522, 27493, 27569, 27573, 27572, 27570, + 27571, 27414, 27560, 27590, 27562, 27575, 27567, 27576, 27568, 27577, + 27566, 27424, 27425, 27589, 27630, 27563, 27564, 27565, 27561, 27587, + 27574, 27585, 27578, 27586, 27584, 27582, 27579, 27580, 27581, 27583, + 27411, 27417, 27415, 27416, 27620, 27619, 27427, 27419, 27430, 27433, + 27428, 27431, 27429, 27432, 27437, 27434, 27394, 27629, 27635, 27632, + 27634, 27608, 27610, 27588, 27618, 27611, 27615, 27609, 27617, 27616, + 27614, 27376, 27466, 27401, 27593, 27379, 27602, 27468, 27467, 27594, + 27507, 27510, 27509, 27508, 27517, 27557, 27406, 27631, 27388, 27513, + 27516, 27511, 27512, 27605, 27515, 27604, 27387, 27386, 27514, 27405, + 27603, 27385, 27480, 27400, 27595, 27612, 27378, 27462, 27397, 27533, + 27613, 27389, 27541, 27537, 27539, 27410, 27633, 27390, 27534, 27536, + 27535, 27540, 27538, 27628, 27506, 27403, 27435, 27622, 27623, 27621, + 27423, 27601, 27381, 27380, 27530, 27606, 27528, 27409, 27518, 27529, + 27627, 27527, 27531, 27519, 27407, 27436, 27426, 27607, 27392, 27393, + 27391, 27408, 27412, 27413, 27625, 27626, 27624, 27592, 27495, 27597, + 27498, 27499, 27500, 27497, 27501, 27496, 27490, 27491, 27492, 27489, + 27487, 27418, 27488, 27484, 27421, 27422, 27599, 27600, 27596, 27598, + 27383, 27384, 27382, 27542, 27547, 27550, 27551, 27552, 27558, 27543, + 27545, 27546, 27554, 27549, 27555, 27556, 27548, 27438, 27559, 27950, + 27949, 27948, 27970, 27969, 27968, 27925, 27924, 27923, 27309, 27308, + 27307, 27911, 27910, 27909, 27921, 27922, 27917, 27920, 27916, 27919, + 27918, 27366, 27369, 27365, 27368, 27367, 27915, 27785, 27786, 27787, + 27788, 27783, 27784, 27789, 27829, 27734, 27847, 27846, 27844, 27845, + 27848, 27823, 27826, 27824, 27825, 27822, 27853, 27852, 27850, 27851, + 27799, 27798, 27797, 27803, 27802, 27801, 27800, 27821, 27820, 27819, + 27796, 27795, 27794, 27869, 27868, 27867, 27843, 27842, 27841, 27966, + 27965, 27964, 27963, 27962, 27961, 27967, 27960, 27959, 27958, 27703, + 27702, 27700, 27701, 27707, 27706, 27704, 27705, 27695, 27694, 27692, + 27693, 27699, 27698, 27696, 27697, 27757, 27756, 27754, 27755, 27758, + 27772, 27775, 27773, 27774, 27731, 27762, 27761, 27760, 27759, 27717, + 27730, 27729, 27728, 27718, 27716, 27715, 27714, 27781, 27780, 27779, + 27778, 27777, 27776, 27953, 27952, 27951, 27956, 27955, 27954, 27957, + 27816, 27815, 27813, 27814, 27807, 27806, 27804, 27805, 27812, 27811, + 27834, 27833, 27830, 27835, 27840, 27837, 27836, 27856, 27855, 27854, + 27859, 27858, 27857, 27810, 27818, 27817, 27906, 27903, 27902, 27849, + 27808, 27831, 27838, 27863, 27907, 27904, 27900, 27809, 27832, 27839, + 27864, 27908, 27905, 27901, 27862, 27861, 27860, 27721, 27720, 27738, + 27736, 27737, 27735, 27747, 27745, 27746, 27744, 27764, 27763, 27895, + 27892, 27898, 27723, 27722, 27739, 27740, 27742, 27741, 27751, 27749, + 27750, 27748, 27766, 27765, 27896, 27893, 27899, 27727, 27726, 27724, + 27725, 27719, 27743, 27752, 27767, 27768, 27769, 27894, 27891, 27897, + 27753, 27793, 27791, 27792, 27790, 27713, 27711, 27709, 27712, 27710, + 27708, 27866, 27865, 27771, 27770, 27828, 27827, 27733, 27732, 27325, + 27324, 27320, 27323, 27327, 27326, 27321, 27322, 27319, 27328, 27638, + 27645, 27643, 27642, 27640, 27641, 27639, 27644, 27358, 27356, 27357, + 27334, 27333, 27332, 27317, 27315, 27316, 27318, 27373, 27372, 27371, + 27352, 27353, 27349, 27330, 27329, 27348, 27350, 27347, 27351, 27331, + 27346, 27344, 27345, 27341, 27343, 27342, 27335, 27337, 27336, 27339, + 27338, 27340, 27312, 27311, 27310, 27935, 27934, 27936, 27355, 27872, + 27871, 27873, 27874, 27302, 27304, 27301, 27303, 27306, 27305, 27667, + 27665, 27666, 27672, 27674, 27673, 27669, 27671, 27670, 27686, 27685, + 27684, 27678, 27679, 27680, 27681, 27682, 27683, 27675, 27677, 27676, + 27687, 27688, 27689, 27656, 27654, 27655, 27668, 27691, 27690, 27943, + 27942, 27940, 27941, 27939, 27944, 27938, 27937, 27927, 27932, 27930, + 27931, 27928, 27929, 27933, 27870, 27782, 27875, 27637, 27354, 27913, + 27912, 27375, 27370, 27914, 27946, 27945, 27947, 27971, 27646, 27647, + 27648, 27649, 27650, 27651, 27652, 27653, 27364, 27664, 27663, 27658, + 27661, 27660, 27657, 27659, 27662, 27314, 27374, 27926, 27313, 27972, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 27359, 27360, 27361, 27362, 27363, + 35536, 27883, 27884, 27885, 27886, 27887, 27888, 27889, 27890, 27876, + 27877, 27878, 27879, 27880, 27881, 27882, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 18185, 18460, 17951, 18465, + 17938, 18309, 18571, 18462, 18557, 18526, 17931, 18164, 18165, 18561, + 17925, 17978, 17952, 18302, 18101, 18282, 18162, 18555, 18441, 18530, + 18173, 18102, 18246, 18399, 18531, 18068, 18477, 35536, 35536, 35536, + 35536, 35536, 35536, 18092, 18295, 18341, 18446, 18485, 18521, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 7328, 7330, 7340, 7334, 7316, 7341, 7348, 35536, 7347, + 7321, 7318, 7317, 7315, 7352, 7336, 7335, 7337, 7351, 7338, 7339, 7323, + 7326, 7350, 7332, 7349, 35536, 35536, 7324, 7327, 7331, 7325, 7343, 7342, + 7344, 35536, 7346, 7322, 35536, 7345, 7320, 7329, 7319, 7333, 35536, + 35536, 35536, 35536, 35536, 22464, 22433, 22461, 22459, 22435, 22457, + 22454, 22455, 22456, 22463, 22440, 22441, 22465, 22444, 22442, 22437, + 22450, 22466, 22439, 22462, 22449, 22458, 22448, 22451, 22436, 22453, + 22434, 22447, 22431, 22460, 22432, 22445, 22443, 9638, 9616, 9636, 9623, + 9619, 9633, 9630, 9631, 9632, 9637, 9621, 9639, 9635, 9622, 9640, 9620, + 9625, 9629, 9634, 9628, 9626, 9627, 9624, 9615, 9618, 9617, 22438, 22452, + 22446, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 7236, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 24187, 24171, 24162, + 24173, 24178, 24170, 24175, 24166, 24192, 24196, 24198, 24201, 24165, + 24160, 24195, 24185, 24169, 24168, 24199, 24161, 24172, 24193, 24181, + 24197, 24200, 24167, 24189, 24174, 24164, 24184, 24163, 24179, 24186, + 24188, 24194, 24180, 24176, 24177, 24202, 24203, 24182, 24183, 24190, + 24191, 24204, 35536, 35536, 35536, 24213, 24217, 24216, 24219, 24218, + 24215, 24214, 24210, 24207, 24206, 24209, 24208, 24211, 24212, 35536, + 35536, 24227, 24229, 24226, 24225, 24222, 24221, 24224, 24223, 24230, + 24228, 35536, 35536, 35536, 35536, 24205, 24220, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 32097, 32080, 32100, + 32090, 32094, 32091, 32096, 32082, 32081, 32099, 32087, 32102, 32101, + 32093, 32092, 32098, 32095, 32083, 32075, 32084, 32076, 32104, 32085, + 32077, 32086, 32078, 32103, 32089, 32079, 32088, 32105, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 33559, 33558, 33590, 33591, 33592, + 33594, 33583, 33586, 33572, 33575, 33587, 33579, 33576, 33593, 33589, + 33588, 33596, 33601, 33600, 33599, 33585, 33564, 33563, 33598, 33597, + 33584, 33595, 33567, 33569, 33573, 33580, 33571, 33578, 33577, 33566, + 33561, 33562, 33570, 33565, 33568, 33560, 33574, 33581, 33582, 33605, + 33606, 33603, 33604, 33613, 33615, 33612, 33611, 33608, 33607, 33610, + 33609, 33616, 33614, 35536, 35536, 35536, 35536, 35536, 33602, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 23564, 23567, 23566, + 23568, 23565, 23547, 23551, 23549, 23548, 23550, 23559, 23562, 23560, + 23563, 23561, 23569, 23570, 23571, 23572, 23573, 23552, 23554, 23557, + 23558, 23553, 23556, 23555, 23577, 23574, 23578, 23576, 23575, 23585, + 23587, 23584, 23583, 23580, 23579, 23582, 23581, 23588, 23586, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 24350, 24353, 24352, 24351, 24354, 24355, 24332, + 24334, 24333, 24335, 24336, 24337, 24344, 24345, 24349, 24346, 24347, + 24348, 24356, 24360, 24357, 24359, 24358, 24361, 24338, 24343, 24342, + 24340, 24339, 24341, 24364, 24362, 24363, 24372, 24374, 24371, 24370, + 24367, 24366, 24369, 24368, 24375, 24373, 35536, 35536, 35536, 35536, + 24365, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 29660, 29669, 29658, 29667, 29691, 29676, 29689, + 29666, 29675, 29661, 29670, 29690, 29665, 29674, 29683, 29677, 29688, + 29664, 29673, 29682, 29662, 29671, 29692, 29695, 29657, 29694, 29663, + 29672, 29693, 29659, 29668, 35536, 29650, 29684, 29679, 29700, 29678, + 29651, 29698, 29686, 29696, 29685, 29680, 29681, 29687, 29649, 29699, + 29697, 29654, 29653, 29652, 29656, 29655, 29701, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 29702, 29703, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 12132, 12138, 12136, 12133, 12135, 12134, 12137, 35536, 12087, + 12131, 12129, 12128, 35536, 12075, 12074, 35536, 12086, 12085, 12084, + 12071, 12070, 12083, 12082, 12081, 12080, 12079, 12078, 12073, 12072, + 12077, 12076, 35536, 21774, 21775, 21776, 21842, 21863, 21851, 21815, + 21951, 21777, 21778, 21782, 21901, 21886, 21891, 21814, 21969, 21918, + 21840, 21820, 21912, 21781, 21779, 21780, 21827, 21871, 21924, 21964, + 21787, 21783, 21791, 21928, 21866, 21876, 21903, 21792, 21789, 21788, + 21941, 21879, 21939, 21917, 21908, 21906, 21907, 21970, 21949, 21786, + 21801, 21793, 21940, 21885, 21910, 21845, 21971, 21797, 21798, 21799, + 21855, 21847, 21831, 21932, 21883, 21784, 21790, 21785, 21858, 21955, + 21956, 21794, 21795, 21796, 21869, 21824, 21874, 21841, 21802, 21800, + 21803, 21927, 21884, 21933, 21835, 21947, 21804, 21808, 21812, 21881, + 21853, 21921, 21902, 21805, 21809, 21810, 21852, 21844, 21909, 21862, + 21972, 21873, 21811, 21806, 21807, 21889, 21942, 21950, 21819, 21962, + 21813, 21872, 21822, 21919, 21859, 21897, 21829, 21911, 21861, 21828, + 21968, 21817, 21864, 21821, 21860, 21888, 21915, 21926, 21896, 21931, + 21898, 21857, 21877, 21958, 21925, 21892, 21935, 21965, 21938, 21936, + 21961, 21832, 21948, 21838, 21867, 21823, 21854, 21830, 21878, 21834, + 21914, 21833, 21893, 21818, 21959, 21849, 21944, 21945, 21963, 21934, + 21875, 21913, 21905, 21868, 21843, 21816, 21882, 21890, 21929, 21895, + 21825, 21920, 21865, 21880, 21846, 21848, 21954, 21894, 21900, 21899, + 21966, 21887, 21836, 21837, 21923, 21967, 21916, 21904, 21957, 21960, + 21930, 21952, 21856, 21922, 21850, 21937, 21826, 21953, 21870, 21839, + 35536, 35536, 21980, 21978, 21977, 21974, 21973, 21976, 21975, 21981, + 21979, 21769, 21768, 21772, 21770, 21767, 21771, 21773, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 27, 9, 24, + 14, 29, 21, 34, 28, 37, 39, 35, 40, 41, 10, 30, 32, 18, 15, 31, 42, 13, + 25, 36, 23, 12, 20, 33, 19, 38, 17, 11, 26, 16, 22, 62, 44, 59, 49, 64, + 56, 69, 63, 72, 74, 70, 75, 76, 45, 65, 67, 53, 50, 66, 77, 48, 60, 71, + 58, 47, 55, 68, 54, 73, 52, 46, 61, 51, 57, 85, 86, 79, 84, 43, 78, 83, + 82, 35536, 35536, 35536, 35536, 93, 95, 92, 91, 88, 87, 90, 89, 96, 94, + 35536, 35536, 35536, 35536, 80, 81, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 15849, 15835, + 15830, 15810, 15805, 15823, 15818, 15798, 15813, 15838, 15833, 15828, + 15808, 15803, 15824, 15819, 15799, 15814, 15850, 15836, 15831, 15811, + 15806, 15826, 15821, 15801, 15816, 15851, 15837, 15832, 15812, 15807, + 15827, 15822, 15802, 15817, 15839, 15834, 15829, 15809, 15804, 15825, + 15820, 15800, 15815, 15796, 15797, 15787, 15794, 15795, 15847, 15845, + 15844, 15841, 15840, 15843, 15842, 15848, 15846, 15853, 15789, 15788, + 15790, 15852, 15793, 15792, 15791, 15786, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 25132, 25127, 25122, 25102, 25097, 25115, 25110, 25090, + 25105, 25130, 25125, 25120, 25100, 25095, 25116, 25111, 25091, 25106, + 25133, 25128, 25123, 25103, 25098, 25118, 25113, 25093, 25108, 25134, + 25129, 25124, 25104, 25099, 25119, 25114, 25094, 25109, 25131, 25126, + 25121, 25101, 25096, 25117, 25112, 25092, 25107, 25089, 25082, 25084, + 25074, 25076, 25077, 25079, 25086, 25085, 25080, 25075, 25078, 25083, + 25081, 25088, 25087, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 2288, 2296, 2294, 2192, + 35536, 2304, 2292, 2300, 2284, 2299, 2291, 2240, 2295, 2302, 2267, 2289, 2297, 2268, 2303, 2298, 2266, 2287, 2286, 2290, 2285, 2191, 2293, 2301, - 2162, 2164, 2163, 2165, 41412, 2204, 2202, 41412, 2199, 41412, 41412, - 2198, 41412, 2206, 2201, 2209, 2203, 2208, 2196, 2211, 2205, 2197, 2210, - 41412, 2195, 2194, 2193, 2200, 41412, 2212, 41412, 2207, 41412, 41412, - 41412, 41412, 41412, 41412, 2276, 41412, 41412, 41412, 41412, 2278, - 41412, 2277, 41412, 2281, 41412, 2280, 2273, 2283, 41412, 2274, 2282, - 41412, 2272, 41412, 41412, 2275, 41412, 2271, 41412, 2279, 41412, 2269, - 41412, 2270, 41412, 2258, 2256, 41412, 2253, 41412, 41412, 2252, 2247, - 2260, 2255, 41412, 2257, 2263, 2250, 2265, 2259, 2251, 2264, 41412, 2249, - 2248, 2246, 2254, 41412, 2245, 2261, 2262, 2243, 41412, 2244, 41412, - 2217, 2229, 2227, 2237, 2220, 2239, 2225, 2219, 2223, 2232, 41412, 2235, + 2162, 2164, 2163, 2165, 35536, 2204, 2202, 35536, 2199, 35536, 35536, + 2198, 35536, 2206, 2201, 2209, 2203, 2208, 2196, 2211, 2205, 2197, 2210, + 35536, 2195, 2194, 2193, 2200, 35536, 2212, 35536, 2207, 35536, 35536, + 35536, 35536, 35536, 35536, 2276, 35536, 35536, 35536, 35536, 2278, + 35536, 2277, 35536, 2281, 35536, 2280, 2273, 2283, 35536, 2274, 2282, + 35536, 2272, 35536, 35536, 2275, 35536, 2271, 35536, 2279, 35536, 2269, + 35536, 2270, 35536, 2258, 2256, 35536, 2253, 35536, 35536, 2252, 2247, + 2260, 2255, 35536, 2257, 2263, 2250, 2265, 2259, 2251, 2264, 35536, 2249, + 2248, 2246, 2254, 35536, 2245, 2261, 2262, 2243, 35536, 2244, 35536, + 2217, 2229, 2227, 2237, 2220, 2239, 2225, 2219, 2223, 2232, 35536, 2235, 2228, 2234, 2214, 2218, 2230, 2215, 2238, 2231, 2213, 2224, 2222, 2216, - 2221, 2236, 2226, 2233, 41412, 41412, 41412, 41412, 41412, 2178, 2176, - 2187, 41412, 2190, 2174, 2182, 2172, 2181, 41412, 2185, 2177, 2184, 2167, + 2221, 2236, 2226, 2233, 35536, 35536, 35536, 35536, 35536, 2178, 2176, + 2187, 35536, 2190, 2174, 2182, 2172, 2181, 35536, 2185, 2177, 2184, 2167, 2189, 2179, 2168, 2188, 2180, 2166, 2173, 2171, 2169, 2170, 2186, 2175, - 2183, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 2241, 2242, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 25561, - 25577, 25592, 25568, 25596, 25595, 25593, 25573, 25590, 25587, 25566, - 25563, 25582, 25579, 25559, 25570, 25574, 25591, 25588, 25567, 25564, - 25583, 25580, 25560, 25571, 25572, 25589, 25586, 25565, 25562, 25581, - 25578, 25558, 25569, 25576, 25575, 25556, 25599, 25585, 25584, 25597, - 25594, 25598, 25557, 41412, 41412, 41412, 41412, 11271, 11222, 11223, - 11224, 11225, 11226, 11227, 11228, 11229, 11230, 11231, 11232, 11233, - 11234, 11235, 11236, 11237, 11238, 11239, 11240, 11241, 11242, 11243, - 11244, 11245, 11246, 11247, 11248, 11249, 11250, 11251, 11252, 11253, - 11254, 11255, 11256, 11257, 11258, 11259, 11260, 11261, 11262, 11263, - 11264, 11265, 11266, 11267, 11268, 11269, 11270, 11321, 11272, 11273, - 11274, 11275, 11276, 11277, 11278, 11279, 11280, 11281, 11282, 11283, - 11284, 11285, 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293, - 11294, 11295, 11296, 11297, 11298, 11299, 11300, 11301, 11302, 11303, - 11304, 11305, 11306, 11307, 11308, 11309, 11310, 11311, 11312, 11313, - 11314, 11315, 11316, 11317, 11318, 11319, 11320, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 31671, - 31741, 31716, 31712, 31675, 31680, 31700, 31696, 31692, 31745, 31708, - 31749, 31684, 31704, 31688, 41412, 41412, 31742, 31717, 31713, 31676, - 31681, 31701, 31697, 31693, 31746, 31709, 31750, 31685, 31705, 31689, - 31672, 41412, 31743, 31718, 31714, 31677, 31682, 31702, 31698, 31694, - 31747, 31710, 31751, 31686, 31706, 31690, 31670, 41412, 31740, 31715, - 31711, 31674, 31679, 31699, 31695, 31691, 31744, 31707, 31748, 31683, - 31703, 31687, 31673, 31678, 31722, 31719, 31733, 31734, 31735, 31736, - 31737, 31738, 31739, 31723, 31724, 31725, 31726, 31727, 31728, 31729, - 31730, 31731, 31732, 31720, 31721, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 11006, 11005, 10990, 11002, 10999, - 10984, 10981, 10996, 10993, 11008, 10987, 11047, 11026, 6918, 6635, 6659, - 31339, 31340, 31341, 31342, 31343, 31344, 31345, 31346, 31347, 31348, - 31349, 31350, 31351, 31352, 31353, 31354, 31355, 31356, 31357, 31358, - 31359, 31360, 31361, 31362, 31363, 31364, 37949, 6749, 6750, 6646, 6917, - 8778, 34644, 34645, 34646, 34647, 34648, 34649, 34650, 34651, 34652, - 34653, 34654, 34655, 34656, 34657, 34658, 34659, 34660, 34661, 34662, - 34663, 34664, 34665, 34666, 34667, 34668, 34669, 34638, 34674, 34689, - 34690, 34679, 34701, 29157, 29158, 29159, 29160, 29161, 29162, 29163, - 29164, 29165, 29166, 29167, 29168, 29169, 29170, 29171, 29172, 29173, - 29174, 29175, 29176, 29177, 29178, 29179, 29180, 29181, 29182, 31950, - 31951, 31952, 6645, 6644, 6692, 29188, 29189, 29190, 29191, 29192, 29193, - 29194, 29195, 29196, 29197, 29198, 29199, 29200, 29201, 29202, 29203, - 29204, 29205, 29206, 29207, 29208, 29209, 29210, 29211, 29212, 29213, - 8822, 29220, 29223, 29224, 29219, 29221, 34373, 34627, 34626, 34633, - 34702, 34675, 34676, 34678, 34688, 34696, 34699, 34691, 34681, 34693, - 34631, 34695, 34632, 34682, 34692, 34684, 34677, 34643, 34637, 34636, - 34635, 34672, 34683, 34697, 34698, 25991, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 31980, 31981, 31982, 31983, 31984, 31985, 31986, 31987, - 31988, 31989, 31990, 31991, 31992, 31993, 31994, 31995, 31996, 31997, - 31998, 31999, 32000, 32001, 32002, 32003, 32004, 32005, 34414, 34639, - 34641, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 34605, 34600, 34592, 34640, 34586, 34598, - 34621, 34597, 34585, 34610, 34618, 34609, 34590, 34601, 34602, 34608, - 34589, 34619, 34616, 34623, 34599, 34594, 34613, 34603, 34606, 34583, - 34584, 34625, 34596, 34587, 34591, 34607, 34622, 34604, 34617, 34620, - 34593, 34614, 34612, 34611, 34615, 34588, 34595, 34624, 41412, 41412, - 41412, 41412, 37946, 37940, 37941, 37943, 37947, 37944, 37948, 37942, - 37945, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 6697, 6695, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 32416, 32417, 32414, 32418, 32413, 32415, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 10657, 17627, 8142, 29467, 34877, 34876, - 6928, 34922, 31943, 5033, 39583, 39408, 27764, 11671, 11669, 11670, - 18163, 29272, 39495, 17592, 39496, 17670, 39494, 22905, 39493, 8812, - 29271, 17591, 22904, 17669, 34801, 18164, 33020, 37385, 3930, 39742, - 39746, 39743, 39744, 8155, 8154, 8153, 8152, 17626, 39809, 20595, 37043, - 5109, 6579, 32750, 17519, 10683, 31207, 6226, 20592, 38117, 6576, 32404, - 20552, 34923, 4344, 11665, 11666, 20377, 17646, 25843, 17559, 24202, - 28479, 37899, 2586, 18276, 27246, 39586, 36066, 24568, 3475, 31655, - 31977, 18816, 31475, 31472, 6578, 34741, 19266, 34006, 27036, 31791, - 32100, 32101, 8612, 10084, 34729, 34305, 5031, 17660, 32420, 10666, - 31065, 34963, 17668, 17598, 34102, 32964, 20626, 11417, 8611, 6618, 6101, - 25446, 10087, 20558, 33039, 3699, 31789, 8610, 17632, 37045, 32717, - 39811, 8159, 38030, 3589, 8101, 2650, 17633, 4468, 31779, 32091, 39831, - 3860, 20987, 6619, 17565, 17588, 17587, 2793, 31397, 8591, 36065, 8823, - 31654, 20992, 6163, 39808, 28362, 32722, 18201, 19847, 4470, 27763, - 32044, 28485, 34750, 24567, 8603, 3579, 3580, 17581, 98, 6161, 17571, - 32362, 17596, 27753, 28384, 6621, 19846, 2565, 37924, 6926, 37792, 8097, - 31504, 39330, 11052, 34012, 3859, 17859, 4473, 17615, 28720, 28466, - 32716, 18832, 28484, 38035, 39335, 28719, 32545, 37160, 33987, 3481, - 6580, 34096, 32546, 34961, 34336, 38032, 20590, 372, 32423, 34966, 39604, - 18200, 31933, 31934, 8814, 39409, 17602, 20628, 35154, 34093, 5367, 3585, - 5108, 20602, 6927, 10710, 8098, 10792, 10793, 29138, 34727, 20601, 20600, - 31061, 20989, 17484, 20603, 3470, 2583, 20596, 25330, 8606, 32721, 10709, - 17555, 20985, 20988, 17483, 39711, 3983, 39592, 39591, 32405, 3999, - 22727, 2661, 4477, 370, 16877, 16878, 16879, 16880, 16881, 31958, 28379, - 31068, 39584, 8805, 37690, 24464, 31960, 6168, 11507, 8826, 39765, 34091, - 34089, 20589, 31963, 18168, 33045, 28360, 32403, 6587, 11158, 31646, - 4655, 16846, 30127, 34330, 5046, 966, 20557, 22729, 17595, 38031, 4345, - 38142, 19815, 2649, 17664, 3861, 31476, 22724, 31801, 11509, 2659, 11220, - 28381, 8806, 37691, 31961, 6169, 11508, 34335, 20591, 28361, 11219, - 31648, 17667, 19264, 39830, 3584, 31244, 31647, 31465, 6586, 17516, - 17514, 11664, 29620, 28382, 37900, 39753, 39668, 39694, 39718, 17599, - 39593, 31064, 37418, 37419, 8096, 30718, 8828, 39821, 17515, 29462, - 35151, 21089, 11515, 22719, 3865, 39819, 31906, 19270, 31796, 25837, - 2580, 20448, 39820, 39818, 17631, 5104, 5103, 4653, 18063, 25750, 39816, - 17563, 25756, 38157, 38158, 31776, 39817, 5034, 31489, 25753, 25754, - 30697, 30695, 2648, 8594, 31858, 20995, 20994, 19132, 2651, 17503, 350, - 20755, 33989, 20871, 18831, 10665, 25223, 29069, 17551, 19137, 3479, - 35149, 31651, 22716, 25329, 32342, 17863, 22711, 4469, 8804, 39602, 3586, - 5040, 38151, 34306, 18829, 19849, 4347, 18818, 39858, 31905, 19848, - 32087, 19850, 10968, 16834, 964, 4652, 34001, 8164, 34331, 11511, 10670, - 31649, 17609, 11138, 34319, 37393, 39679, 20612, 28182, 10082, 19879, - 8811, 3472, 3474, 3473, 3471, 28181, 6397, 32746, 31499, 5035, 27766, - 17616, 30729, 11662, 17577, 30716, 31072, 31074, 5364, 37046, 6106, 6396, - 6398, 3477, 8102, 31908, 32411, 31467, 34739, 38000, 4358, 24566, 29618, - 29619, 8148, 30710, 18817, 4346, 30733, 4359, 29140, 32743, 27600, 37051, - 31075, 17562, 32629, 31909, 6403, 31012, 20982, 31466, 17517, 20787, - 16915, 8145, 8146, 30720, 30719, 31785, 31782, 29457, 27780, 27781, - 39326, 27782, 29537, 968, 5365, 5366, 39329, 37058, 31936, 39331, 17580, - 31780, 31872, 38145, 8132, 8133, 8129, 977, 25331, 20443, 34314, 34313, - 34315, 34316, 3578, 16832, 24333, 32218, 25281, 8147, 21774, 25278, - 30723, 3592, 3594, 4357, 25221, 31938, 2653, 16910, 30699, 34152, 37939, - 29536, 21789, 20874, 20875, 20878, 20877, 20876, 17584, 16833, 39834, - 19260, 30033, 20604, 31660, 27752, 37057, 8833, 33983, 20993, 38002, - 4010, 39729, 22895, 22822, 22830, 22823, 34018, 34017, 38240, 11430, - 38244, 11424, 25400, 38336, 6642, 8820, 8819, 29611, 29613, 35038, 39692, - 19894, 6234, 31066, 11502, 21772, 28368, 35059, 27462, 4471, 8113, 8123, - 8125, 8109, 8107, 8117, 8115, 8105, 8111, 8119, 8103, 8121, 8114, 8124, - 8126, 8110, 8108, 8118, 8116, 8106, 8112, 8120, 8104, 8122, 32165, 32166, - 32167, 5099, 5100, 32350, 4356, 6100, 25840, 4012, 29535, 20556, 25751, - 34004, 10667, 34326, 34327, 21090, 25755, 24254, 37052, 32146, 39748, - 4025, 37056, 8099, 2654, 34711, 16914, 17625, 31479, 25220, 3980, 25362, - 25348, 25360, 25361, 25382, 24314, 38133, 31948, 32072, 32080, 32081, - 32086, 32082, 31949, 39669, 33174, 33173, 33170, 33169, 3958, 3985, - 33176, 33175, 33172, 33171, 4028, 3924, 3937, 10794, 21776, 37409, 31855, - 31802, 3940, 39683, 34103, 37040, 39814, 30707, 38146, 37405, 37984, - 30521, 19813, 32727, 31856, 17561, 30730, 11144, 11145, 11146, 17656, - 17658, 17657, 3936, 17629, 30717, 6107, 6108, 17578, 16882, 16883, 16884, - 29615, 29616, 29617, 16893, 16886, 16887, 11143, 31071, 31076, 39598, - 34329, 34328, 10795, 27767, 27022, 31055, 8131, 6098, 20789, 10684, 8586, - 30694, 32361, 31073, 34737, 10664, 25222, 34317, 37401, 37400, 37402, - 37403, 24282, 32168, 38161, 37407, 24299, 32182, 24212, 32104, 28365, - 24591, 24590, 2798, 2804, 2799, 2803, 2796, 24588, 2797, 39825, 28378, - 37983, 34724, 33986, 28383, 18821, 18824, 17541, 34077, 34079, 34078, - 34080, 34076, 34075, 39812, 34081, 17521, 32043, 34074, 34084, 34087, - 29269, 17496, 38197, 17524, 31477, 8592, 8593, 22712, 17552, 22713, - 22714, 17538, 17539, 17540, 11054, 39826, 965, 31794, 8832, 31501, 17546, - 11053, 17666, 962, 17567, 39600, 34003, 37791, 18826, 25445, 17529, - 20611, 17531, 17522, 2573, 17617, 34002, 11139, 17549, 17526, 18825, - 6170, 34073, 34072, 6171, 22715, 31793, 8831, 39599, 34008, 34007, 38348, - 17545, 17534, 17528, 31498, 32751, 19852, 34312, 19812, 31496, 31495, - 31491, 31493, 29580, 34208, 29553, 34195, 38131, 38140, 38130, 38139, - 29579, 34207, 29552, 34194, 19930, 19923, 19927, 19920, 29581, 34209, - 29554, 34196, 19931, 19924, 19928, 19921, 20554, 20555, 34148, 34149, - 24457, 38382, 32305, 11497, 32737, 19925, 24570, 19902, 19857, 34964, - 32623, 32624, 32625, 19947, 32626, 19914, 39316, 39313, 6399, 32053, - 32360, 20089, 34728, 31941, 20446, 20447, 37991, 27598, 24577, 34725, - 37987, 37988, 5102, 30704, 38028, 5105, 27768, 373, 17585, 31774, 30703, - 37044, 30702, 2582, 30700, 31976, 10689, 2564, 37985, 28359, 28375, - 34962, 28376, 160, 33019, 32419, 34318, 20582, 39307, 8595, 31775, 37999, - 11503, 29533, 34088, 29538, 31907, 11501, 31787, 29542, 3855, 29531, - 3854, 28377, 31508, 29534, 6582, 27463, 39822, 32048, 2652, 37982, 39582, - 33044, 3576, 3577, 31407, 10086, 2665, 24255, 37996, 31870, 6751, 4654, - 18064, 8803, 34000, 33022, 3596, 3756, 31665, 30126, 33021, 34752, 31077, - 20550, 20614, 16847, 22731, 41412, 41412, 41412, 39815, 31669, 39606, - 32343, 19261, 33015, 30159, 28373, 31940, 28370, 38238, 38235, 38243, - 34015, 29588, 227, 228, 41412, 41412, 41412, 32628, 30701, 10979, 31403, - 32725, 28371, 6103, 34005, 17620, 33992, 2584, 31645, 32363, 41412, - 41412, 41412, 297, 245, 345, 344, 341, 239, 237, 238, 235, 236, 334, 336, - 337, 323, 290, 252, 283, 284, 285, 267, 311, 288, 338, 339, 309, 310, - 272, 325, 278, 279, 261, 302, 258, 280, 321, 259, 260, 257, 312, 319, - 340, 331, 281, 240, 320, 313, 318, 335, 300, 301, 299, 303, 304, 305, - 232, 233, 286, 314, 242, 306, 307, 243, 248, 328, 329, 298, 249, 250, - 251, 234, 346, 324, 330, 273, 342, 291, 256, 333, 255, 327, 254, 332, - 315, 282, 326, 343, 276, 244, 293, 253, 292, 241, 316, 317, 322, 296, - 270, 268, 269, 295, 294, 262, 263, 264, 265, 266, 231, 246, 247, 308, - 277, 289, 271, 287, 275, 274, 25327, 30128, 25448, 39324, 2577, 20616, - 31399, 19842, 25625, 18198, 31927, 30736, 3951, 4029, 3991, 3925, 4015, - 27137, 4353, 19944, 39317, 17500, 39648, 32412, 4023, 4016, 24585, 27163, - 4354, 19941, 39318, 17501, 39730, 39732, 34559, 4021, 4039, 3973, 39663, - 39664, 10967, 4022, 4040, 3974, 39701, 37390, 24587, 27164, 4355, 39322, - 39319, 17502, 37388, 24580, 27154, 4349, 19915, 39314, 17497, 24573, - 27143, 4352, 19890, 39312, 17499, 24581, 27153, 4350, 19919, 39315, - 17498, 24571, 27161, 4351, 19884, 39311, 24583, 27158, 37408, 27157, - 24575, 27142, 17648, 27141, 32054, 24572, 19889, 27152, 19918, 33981, - 27160, 19882, 39310, 19880, 24582, 19937, 19936, 6912, 29183, 6922, - 29184, 29465, 41412, 41412, 41412, 41412, 41412, 41412, 22829, 22897, - 22825, 22893, 22820, 22896, 22824, 22831, 22898, 22826, 22894, 22821, - 41412, 41412, 41412, 41412, 19887, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 24377, 38358, 32258, 11448, 24384, 38355, 32265, 11445, 24371, 38354, - 32255, 11444, 41412, 41412, 41412, 41412, 24376, 38357, 32257, 11447, - 24386, 38359, 32267, 11449, 19898, 19939, 19912, 19876, 19897, 19938, - 19911, 19875, 24421, 38392, 32318, 11468, 24420, 38391, 32317, 11467, - 24419, 38388, 32316, 11464, 24423, 38394, 32320, 11470, 24422, 38393, - 32319, 11469, 24451, 38369, 32284, 11484, 24459, 38384, 32307, 11499, - 24461, 38380, 32340, 11495, 24411, 38378, 32298, 11493, 24412, 38379, - 32299, 11494, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 24460, 38383, 32308, 11498, 29586, 29559, 34201, 34214, 24274, 38225, - 41412, 41412, 41412, 41412, 41412, 41412, 39768, 39783, 39773, 39778, - 39793, 39788, 39798, 39803, 39770, 39785, 39775, 39780, 39795, 39790, - 39800, 39805, 39769, 39784, 39774, 39779, 39794, 39789, 39799, 39804, - 39766, 39781, 39771, 39776, 39791, 39786, 39796, 39801, 39767, 39782, - 39772, 39777, 39792, 39787, 39797, 39802, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 24427, 38398, 32324, 11475, 24441, 38408, - 32339, 11480, 24385, 38356, 32266, 11446, 19853, 19856, 19855, 19854, - 24395, 32273, 24430, 32309, 24452, 32304, 24456, 32300, 24394, 32272, - 24450, 32283, 39610, 39609, 41412, 41412, 2560, 2557, 32253, 11459, - 29214, 29215, 29222, 29216, 29578, 29550, 34193, 34206, 41412, 41412, - 41412, 41412, 24391, 32244, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 25318, 25322, - 25323, 33029, 25314, 33026, 25316, 25317, 25306, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 6640, 6641, 6639, 24239, 24237, - 24238, 24240, 24236, 11437, 11439, 11438, 11440, 31652, 39684, 5042, - 31653, 41221, 28183, 17542, 29463, 37391, 17525, 32421, 20613, 33849, - 5363, 31957, 24348, 32207, 19271, 19267, 20986, 17523, 8156, 29139, - 32365, 11512, 25506, 17550, 34092, 17533, 18823, 18822, 17544, 32846, - 34082, 17530, 33042, 31803, 5030, 31242, 32854, 31857, 25752, 28369, - 33047, 31486, 21092, 17573, 27783, 39833, 39585, 19269, 11134, 39807, - 11513, 8100, 38143, 34334, 18167, 32354, 17594, 32749, 37392, 4650, - 25914, 10081, 22728, 34105, 17624, 8827, 2642, 10088, 2660, 31788, 6166, - 2663, 18819, 32858, 34751, 16782, 18162, 31473, 22717, 31243, 11659, - 17636, 35648, 6617, 4472, 10074, 8160, 5041, 31663, 31853, 10089, 32627, - 6102, 24203, 25841, 28363, 2664, 34083, 39857, 34085, 17535, 17548, - 31054, 17662, 29466, 11058, 17553, 17537, 32718, 22726, 18197, 20551, - 17603, 8834, 25275, 32723, 38119, 38211, 11674, 11660, 3519, 32963, - 31067, 17653, 5107, 10962, 18196, 25276, 32089, 33046, 34704, 18065, - 41215, 20442, 32713, 35152, 8813, 21378, 25512, 31470, 20553, 31402, - 31935, 25444, 28367, 27755, 2662, 34965, 25749, 11504, 34013, 31011, - 30735, 33991, 17608, 31060, 3587, 3866, 32745, 18833, 31871, 16873, - 16874, 16876, 16875, 4656, 24569, 17630, 37901, 34958, 34959, 32556, - 11667, 28372, 25838, 27037, 27038, 6402, 10076, 32559, 3755, 17858, - 30709, 17560, 39433, 5106, 27001, 20627, 5044, 38027, 34726, 22721, - 10961, 17527, 101, 6581, 30696, 3583, 31494, 31488, 31497, 31487, 25516, - 17566, 38971, 27587, 16871, 18060, 41407, 5028, 30734, 3858, 32720, - 18165, 8809, 34100, 31978, 17589, 21095, 37163, 31507, 11661, 8589, 2645, - 17586, 37903, 5037, 25515, 25447, 25326, 34333, 2806, 32557, 37050, 5043, - 3480, 32364, 3478, 34337, 31964, 29141, 29246, 29257, 29260, 29249, - 29239, 29254, 39623, 3893, 29240, 39620, 39636, 39639, 39614, 39628, - 39633, 3890, 3906, 3909, 3884, 3898, 3903, 29247, 29258, 29261, 29250, - 29245, 29255, 39624, 3894, 29241, 39642, 39645, 39646, 39641, 39643, - 39644, 3912, 3915, 3916, 3911, 3913, 3914, 29264, 29267, 29268, 29263, - 29265, 29266, 39625, 3895, 29242, 39621, 39637, 39640, 39615, 39626, - 39634, 3891, 3907, 3910, 3885, 3896, 3904, 29248, 29259, 29262, 29251, - 29243, 29256, 39627, 3897, 29244, 39616, 3886, 29252, 39617, 3887, 29253, - 39630, 39631, 39629, 3900, 3901, 3899, 39618, 39612, 3888, 3882, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 39849, 39852, 39848, - 39850, 39847, 39846, 39851, 39842, 39845, 39841, 39843, 39840, 39839, - 39844, 41412, 41412, 2807, 30708, 5036, 33040, 37394, 24584, 18820, - 31657, 11510, 99, 34731, 39838, 8830, 41412, 41412, 41412, 41129, 22720, - 31251, 4360, 25514, 31658, 29236, 25844, 17618, 19814, 38029, 41412, - 41412, 41412, 37992, 33043, 32349, 6237, 31962, 2647, 11137, 3476, 27762, - 1, 25304, 8808, 6164, 32726, 22730, 20606, 27778, 39810, 31771, 32851, - 22722, 5110, 28380, 37902, 19844, 31666, 32359, 27779, 20633, 25332, - 19265, 17628, 19134, 21859, 17619, 39827, 3590, 8158, 31790, 39829, - 17568, 25328, 8782, 16885, 29237, 20624, 21088, 39813, 24201, 18199, 958, - 25449, 31509, 31805, 31804, 31492, 17582, 41412, 19136, 41412, 41412, - 41412, 41412, 30737, 28366, 11322, 4348, 3593, 30698, 17604, 36064, - 17652, 37049, 31792, 3588, 21087, 18062, 31474, 32402, 41412, 41412, - 34332, 27245, 32561, 17532, 17536, 17547, 11332, 3863, 5045, 33014, - 17543, 11057, 41412, 41412, 41412, 41412, 17576, 19268, 32297, 24410, - 31208, 31209, 20794, 19851, 24455, 32303, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 4284, 4314, 4285, 4329, 4300, 4318, 4286, 4337, + 2183, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 2241, 2242, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 20081, + 20097, 20112, 20088, 20116, 20115, 20113, 20093, 20110, 20107, 20086, + 20083, 20102, 20099, 20079, 20090, 20094, 20111, 20108, 20087, 20084, + 20103, 20100, 20080, 20091, 20092, 20109, 20106, 20085, 20082, 20101, + 20098, 20078, 20089, 20096, 20095, 20076, 20119, 20105, 20104, 20117, + 20114, 20118, 20077, 35536, 35536, 35536, 35536, 10257, 10208, 10209, + 10210, 10211, 10212, 10213, 10214, 10215, 10216, 10217, 10218, 10219, + 10220, 10221, 10222, 10223, 10224, 10225, 10226, 10227, 10228, 10229, + 10230, 10231, 10232, 10233, 10234, 10235, 10236, 10237, 10238, 10239, + 10240, 10241, 10242, 10243, 10244, 10245, 10246, 10247, 10248, 10249, + 10250, 10251, 10252, 10253, 10254, 10255, 10256, 10307, 10258, 10259, + 10260, 10261, 10262, 10263, 10264, 10265, 10266, 10267, 10268, 10269, + 10270, 10271, 10272, 10273, 10274, 10275, 10276, 10277, 10278, 10279, + 10280, 10281, 10282, 10283, 10284, 10285, 10286, 10287, 10288, 10289, + 10290, 10291, 10292, 10293, 10294, 10295, 10296, 10297, 10298, 10299, + 10300, 10301, 10302, 10303, 10304, 10305, 10306, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 25795, + 25865, 25840, 25836, 25799, 25804, 25824, 25820, 25816, 25869, 25832, + 25873, 25808, 25828, 25812, 35536, 35536, 25866, 25841, 25837, 25800, + 25805, 25825, 25821, 25817, 25870, 25833, 25874, 25809, 25829, 25813, + 25796, 35536, 25867, 25842, 25838, 25801, 25806, 25826, 25822, 25818, + 25871, 25834, 25875, 25810, 25830, 25814, 25794, 35536, 25864, 25839, + 25835, 25798, 25803, 25823, 25819, 25815, 25868, 25831, 25872, 25807, + 25827, 25811, 25797, 25802, 25846, 25843, 25857, 25858, 25859, 25860, + 25861, 25862, 25863, 25847, 25848, 25849, 25850, 25851, 25852, 25853, + 25854, 25855, 25856, 25844, 25845, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 9992, 9991, 9976, 9988, 9985, 9970, + 9967, 9982, 9979, 9994, 9973, 10033, 10012, 6918, 6635, 6659, 25463, + 25464, 25465, 25466, 25467, 25468, 25469, 25470, 25471, 25472, 25473, + 25474, 25475, 25476, 25477, 25478, 25479, 25480, 25481, 25482, 25483, + 25484, 25485, 25486, 25487, 25488, 32073, 6749, 6750, 6646, 6917, 7764, + 28768, 28769, 28770, 28771, 28772, 28773, 28774, 28775, 28776, 28777, + 28778, 28779, 28780, 28781, 28782, 28783, 28784, 28785, 28786, 28787, + 28788, 28789, 28790, 28791, 28792, 28793, 28762, 28798, 28813, 28814, + 28803, 28825, 23677, 23678, 23679, 23680, 23681, 23682, 23683, 23684, + 23685, 23686, 23687, 23688, 23689, 23690, 23691, 23692, 23693, 23694, + 23695, 23696, 23697, 23698, 23699, 23700, 23701, 23702, 26074, 26075, + 26076, 6645, 6644, 6692, 23708, 23709, 23710, 23711, 23712, 23713, 23714, + 23715, 23716, 23717, 23718, 23719, 23720, 23721, 23722, 23723, 23724, + 23725, 23726, 23727, 23728, 23729, 23730, 23731, 23732, 23733, 7808, + 23740, 23743, 23744, 23739, 23741, 28497, 28751, 28750, 28757, 28826, + 28799, 28800, 28802, 28812, 28820, 28823, 28815, 28805, 28817, 28755, + 28819, 28756, 28806, 28816, 28808, 28801, 28767, 28761, 28760, 28759, + 28796, 28807, 28821, 28822, 20511, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 26104, 26105, 26106, 26107, 26108, 26109, 26110, 26111, 26112, + 26113, 26114, 26115, 26116, 26117, 26118, 26119, 26120, 26121, 26122, + 26123, 26124, 26125, 26126, 26127, 26128, 26129, 28538, 28763, 28765, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 28729, 28724, 28716, 28764, 28710, 28722, 28745, + 28721, 28709, 28734, 28742, 28733, 28714, 28725, 28726, 28732, 28713, + 28743, 28740, 28747, 28723, 28718, 28737, 28727, 28730, 28707, 28708, + 28749, 28720, 28711, 28715, 28731, 28746, 28728, 28741, 28744, 28717, + 28738, 28736, 28735, 28739, 28712, 28719, 28748, 35536, 35536, 35536, + 35536, 32070, 32064, 32065, 32067, 32071, 32068, 32072, 32066, 32069, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 6697, 6695, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 26540, 26541, 26538, 26542, 26537, 26539, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 9643, 12618, 7128, 23987, 29001, 29000, 6928, 29046, + 26067, 5033, 33707, 33532, 22284, 10657, 10655, 10656, 13154, 23792, + 33619, 12583, 33620, 12661, 33618, 17425, 33617, 7798, 23791, 12582, + 17424, 12660, 28925, 13155, 27144, 31509, 3930, 33866, 33870, 33867, + 33868, 7141, 7140, 7139, 7138, 12617, 33933, 15586, 31167, 5109, 6579, + 26874, 12510, 9669, 25331, 6226, 15583, 32241, 6576, 26528, 15543, 29047, + 4344, 10651, 10652, 15368, 12637, 20363, 12550, 18722, 22999, 32023, + 2586, 13267, 21766, 33710, 30190, 19088, 3475, 25779, 26101, 13807, + 25599, 25596, 6578, 28865, 14257, 28130, 21556, 25915, 26224, 26225, + 7598, 9070, 28853, 28429, 5031, 12651, 26544, 9652, 25189, 29087, 12659, + 12589, 28226, 27088, 15617, 10403, 7597, 6618, 6101, 19966, 9073, 15549, + 27163, 3699, 25913, 7596, 12623, 31169, 26841, 33935, 7145, 32154, 3589, + 7087, 2650, 12624, 4468, 25903, 26215, 33955, 3860, 15978, 6619, 12556, + 12579, 12578, 2793, 25521, 7577, 30189, 7809, 25778, 15983, 6163, 33932, + 22882, 26846, 13192, 14838, 4470, 22283, 26168, 23005, 28874, 19087, + 7589, 3579, 3580, 12572, 98, 6161, 12562, 26486, 12587, 22273, 22904, + 6621, 14837, 2565, 32048, 6926, 31916, 7083, 25628, 33454, 10038, 28136, + 3859, 12850, 4473, 12606, 23240, 22986, 26840, 13823, 23004, 32159, + 33459, 23239, 26669, 31284, 28111, 3481, 6580, 28220, 26670, 29085, + 28460, 32156, 15581, 372, 26547, 29090, 33728, 13191, 26057, 26058, 7800, + 33533, 12593, 15619, 29278, 28217, 5367, 3585, 5108, 15593, 6927, 9696, + 7084, 9778, 9779, 23658, 28851, 15592, 15591, 25185, 15980, 12475, 15594, + 3470, 2583, 15587, 19850, 7592, 26845, 9695, 12546, 15976, 15979, 12474, + 33835, 3983, 33716, 33715, 26529, 3999, 17247, 2661, 4477, 370, 11868, + 11869, 11870, 11871, 11872, 26082, 22899, 25192, 33708, 7791, 31814, + 18984, 26084, 6168, 10493, 7812, 33889, 28215, 28213, 15580, 26087, + 13159, 27169, 22880, 26527, 6587, 10144, 25770, 4655, 11837, 24251, + 28454, 5046, 966, 15548, 17249, 12586, 32155, 4345, 32266, 14806, 2649, + 12655, 3861, 25600, 17244, 25925, 10495, 2659, 10206, 22901, 7792, 31815, + 26085, 6169, 10494, 28459, 15582, 22881, 10205, 25772, 12658, 14255, + 33954, 3584, 25368, 25771, 25589, 6586, 12507, 12505, 10650, 24140, + 22902, 32024, 33877, 33792, 33818, 33842, 12590, 33717, 25188, 31542, + 31543, 7082, 24842, 7814, 33945, 12506, 23982, 29275, 16080, 10501, + 17239, 3865, 33943, 26030, 14261, 25920, 20357, 2580, 15439, 33944, + 33942, 12622, 5104, 5103, 4653, 13054, 20270, 33940, 12554, 20276, 32281, + 32282, 25900, 33941, 5034, 25613, 20273, 20274, 24821, 24819, 2648, 7580, + 25982, 15986, 15985, 14123, 2651, 12494, 350, 15746, 28113, 15862, 13822, + 9651, 19743, 23589, 12542, 14128, 3479, 29273, 25775, 17236, 19849, + 26466, 12854, 17231, 4469, 7790, 33726, 3586, 5040, 32275, 28430, 13820, + 14840, 4347, 13809, 33982, 26029, 14839, 26211, 14841, 9954, 11825, 964, + 4652, 28125, 7150, 28455, 10497, 9656, 25773, 12600, 10124, 28443, 31517, + 33803, 15603, 22702, 9068, 14870, 7797, 3472, 3474, 3473, 3471, 22701, + 6397, 26870, 25623, 5035, 22286, 12607, 24853, 10648, 12568, 24840, + 25196, 25198, 5364, 31170, 6106, 6396, 6398, 3477, 7088, 26032, 26535, + 25591, 28863, 32124, 4358, 19086, 24138, 24139, 7134, 24834, 13808, 4346, + 24857, 4359, 23660, 26867, 22120, 31175, 25199, 12553, 26753, 26033, + 6403, 25136, 15973, 25590, 12508, 15778, 11906, 7131, 7132, 24844, 24843, + 25909, 25906, 23977, 22300, 22301, 33450, 22302, 24057, 968, 5365, 5366, + 33453, 31182, 26060, 33455, 12571, 25904, 25996, 32269, 7118, 7119, 7115, + 977, 19851, 15434, 28438, 28437, 28439, 28440, 3578, 11823, 18853, 26342, + 19801, 7133, 16765, 19798, 24847, 3592, 3594, 4357, 19741, 26062, 2653, + 11901, 24823, 28276, 32063, 24056, 16780, 15865, 15866, 15869, 15868, + 15867, 12575, 11824, 33958, 14251, 24156, 15595, 25784, 22272, 31181, + 7819, 28107, 15984, 32126, 4010, 33853, 17415, 17342, 17350, 17343, + 28142, 28141, 32364, 10416, 32368, 10410, 19920, 32460, 6642, 7806, 7805, + 24131, 24133, 29162, 33816, 14885, 6234, 25190, 10488, 16763, 22888, + 29183, 21982, 4471, 7099, 7109, 7111, 7095, 7093, 7103, 7101, 7091, 7097, + 7105, 7089, 7107, 7100, 7110, 7112, 7096, 7094, 7104, 7102, 7092, 7098, + 7106, 7090, 7108, 26289, 26290, 26291, 5099, 5100, 26474, 4356, 6100, + 20360, 4012, 24055, 15547, 20271, 28128, 9653, 28450, 28451, 16081, + 20275, 18774, 31176, 26270, 33872, 4025, 31180, 7085, 2654, 28835, 11905, + 12616, 25603, 19740, 3980, 19882, 19868, 19880, 19881, 19902, 18834, + 32257, 26072, 26196, 26204, 26205, 26210, 26206, 26073, 33793, 27298, + 27297, 27294, 27293, 3958, 3985, 27300, 27299, 27296, 27295, 4028, 3924, + 3937, 9780, 16767, 31533, 25979, 25926, 3940, 33807, 28227, 31164, 33938, + 24831, 32270, 31529, 32108, 24645, 14804, 26851, 25980, 12552, 24854, + 10130, 10131, 10132, 12647, 12649, 12648, 3936, 12620, 24841, 6107, 6108, + 12569, 11873, 11874, 11875, 24135, 24136, 24137, 11884, 11877, 11878, + 10129, 25195, 25200, 33722, 28453, 28452, 9781, 22287, 21542, 25179, + 7117, 6098, 15780, 9670, 7572, 24818, 26485, 25197, 28861, 9650, 19742, + 28441, 31525, 31524, 31526, 31527, 18802, 26292, 32285, 31531, 18819, + 26306, 18732, 26228, 22885, 19111, 19110, 2798, 2804, 2799, 2803, 2796, + 19108, 2797, 33949, 22898, 32107, 28848, 28110, 22903, 13812, 13815, + 12532, 28201, 28203, 28202, 28204, 28200, 28199, 33936, 28205, 12512, + 26167, 28198, 28208, 28211, 23789, 12487, 32321, 12515, 25601, 7578, + 7579, 17232, 12543, 17233, 17234, 12529, 12530, 12531, 10040, 33950, 965, + 25918, 7818, 25625, 12537, 10039, 12657, 962, 12558, 33724, 28127, 31915, + 13817, 19965, 12520, 15602, 12522, 12513, 2573, 12608, 28126, 10125, + 12540, 12517, 13816, 6170, 28197, 28196, 6171, 17235, 25917, 7817, 33723, + 28132, 28131, 32472, 12536, 12525, 12519, 25622, 26875, 14843, 28436, + 14803, 25620, 25619, 25615, 25617, 24100, 28332, 24073, 28319, 32255, + 32264, 32254, 32263, 24099, 28331, 24072, 28318, 14921, 14914, 14918, + 14911, 24101, 28333, 24074, 28320, 14922, 14915, 14919, 14912, 15545, + 15546, 28272, 28273, 18977, 32506, 26429, 10483, 26861, 14916, 19090, + 14893, 14848, 29088, 26747, 26748, 26749, 14938, 26750, 14905, 33440, + 33437, 6399, 26177, 26484, 15080, 28852, 26065, 15437, 15438, 32115, + 22118, 19097, 28849, 32111, 32112, 5102, 24828, 32152, 5105, 22288, 373, + 12576, 25898, 24827, 31168, 24826, 2582, 24824, 26100, 9675, 2564, 32109, + 22879, 22895, 29086, 22896, 160, 27143, 26543, 28442, 15573, 33431, 7581, + 25899, 32123, 10489, 24053, 28212, 24058, 26031, 10487, 25911, 24062, + 3855, 24051, 3854, 22897, 25632, 24054, 6582, 21983, 33946, 26172, 2652, + 32106, 33706, 27168, 3576, 3577, 25531, 9072, 2665, 18775, 32120, 25994, + 6751, 4654, 13055, 7789, 28124, 27146, 3596, 3756, 25789, 24250, 27145, + 28876, 25201, 15541, 15605, 11838, 17251, 35536, 35536, 35536, 33939, + 25793, 33730, 26467, 14252, 27139, 24283, 22893, 26064, 22890, 32362, + 32359, 32367, 28139, 24108, 227, 228, 35536, 35536, 35536, 26752, 24825, + 9965, 25527, 26849, 22891, 6103, 28129, 12611, 28116, 2584, 25769, 26487, + 35536, 35536, 35536, 297, 245, 345, 344, 341, 239, 237, 238, 235, 236, + 334, 336, 337, 323, 290, 252, 283, 284, 285, 267, 311, 288, 338, 339, + 309, 310, 272, 325, 278, 279, 261, 302, 258, 280, 321, 259, 260, 257, + 312, 319, 340, 331, 281, 240, 320, 313, 318, 335, 300, 301, 299, 303, + 304, 305, 232, 233, 286, 314, 242, 306, 307, 243, 248, 328, 329, 298, + 249, 250, 251, 234, 346, 324, 330, 273, 342, 291, 256, 333, 255, 327, + 254, 332, 315, 282, 326, 343, 276, 244, 293, 253, 292, 241, 316, 317, + 322, 296, 270, 268, 269, 295, 294, 262, 263, 264, 265, 266, 231, 246, + 247, 308, 277, 289, 271, 287, 275, 274, 19847, 24252, 19968, 33448, 2577, + 15607, 25523, 14833, 20145, 13189, 26051, 24860, 3951, 4029, 3991, 3925, + 4015, 21657, 4353, 14935, 33441, 12491, 33772, 26536, 4023, 4016, 19105, + 21683, 4354, 14932, 33442, 12492, 33854, 33856, 28683, 4021, 4039, 3973, + 33787, 33788, 9953, 4022, 4040, 3974, 33825, 31514, 19107, 21684, 4355, + 33446, 33443, 12493, 31512, 19100, 21674, 4349, 14906, 33438, 12488, + 19093, 21663, 4352, 14881, 33436, 12490, 19101, 21673, 4350, 14910, + 33439, 12489, 19091, 21681, 4351, 14875, 33435, 19103, 21678, 31532, + 21677, 19095, 21662, 12639, 21661, 26178, 19092, 14880, 21672, 14909, + 28105, 21680, 14873, 33434, 14871, 19102, 14928, 14927, 6912, 23703, + 6922, 23704, 23985, 35536, 35536, 35536, 35536, 35536, 35536, 17349, + 17417, 17345, 17413, 17340, 17416, 17344, 17351, 17418, 17346, 17414, + 17341, 35536, 35536, 35536, 35536, 14878, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 18897, 32482, 26382, 10434, 18904, 32479, 26389, 10431, 18891, + 32478, 26379, 10430, 35536, 35536, 35536, 35536, 18896, 32481, 26381, + 10433, 18906, 32483, 26391, 10435, 14889, 14930, 14903, 14867, 14888, + 14929, 14902, 14866, 18941, 32516, 26442, 10454, 18940, 32515, 26441, + 10453, 18939, 32512, 26440, 10450, 18943, 32518, 26444, 10456, 18942, + 32517, 26443, 10455, 18971, 32493, 26408, 10470, 18979, 32508, 26431, + 10485, 18981, 32504, 26464, 10481, 18931, 32502, 26422, 10479, 18932, + 32503, 26423, 10480, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 18980, 32507, 26432, 10484, 24106, 24079, 28325, 28338, 18794, + 32349, 35536, 35536, 35536, 35536, 35536, 35536, 33892, 33907, 33897, + 33902, 33917, 33912, 33922, 33927, 33894, 33909, 33899, 33904, 33919, + 33914, 33924, 33929, 33893, 33908, 33898, 33903, 33918, 33913, 33923, + 33928, 33890, 33905, 33895, 33900, 33915, 33910, 33920, 33925, 33891, + 33906, 33896, 33901, 33916, 33911, 33921, 33926, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 18947, 32522, 26448, 10461, 18961, + 32532, 26463, 10466, 18905, 32480, 26390, 10432, 14844, 14847, 14846, + 14845, 18915, 26397, 18950, 26433, 18972, 26428, 18976, 26424, 18914, + 26396, 18970, 26407, 33734, 33733, 35536, 35536, 2560, 2557, 26377, + 10445, 23734, 23735, 23742, 23736, 24098, 24070, 28317, 28330, 35536, + 35536, 35536, 35536, 18911, 26368, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 19838, + 19842, 19843, 27153, 19834, 27150, 19836, 19837, 19826, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 6640, 6641, 6639, 18759, + 18757, 18758, 18760, 18756, 10423, 10425, 10424, 10426, 25776, 33808, + 5042, 25777, 35345, 22703, 12533, 23983, 31515, 12516, 26545, 15604, + 27973, 5363, 26081, 18868, 26331, 14262, 14258, 15977, 12514, 7142, + 23659, 26489, 10498, 20026, 12541, 28216, 12524, 13814, 13813, 12535, + 26970, 28206, 12521, 27166, 25927, 5030, 25366, 26978, 25981, 20272, + 22889, 27171, 25610, 16083, 12564, 22303, 33957, 33709, 14260, 10120, + 33931, 10499, 7086, 32267, 28458, 13158, 26478, 12585, 26873, 31516, + 4650, 20434, 9067, 17248, 28229, 12615, 7813, 2642, 9074, 2660, 25912, + 6166, 2663, 13810, 26982, 28875, 11773, 13153, 25597, 17237, 25367, + 10645, 12627, 29772, 6617, 4472, 9060, 7146, 5041, 25787, 25977, 9075, + 26751, 6102, 18723, 20361, 22883, 2664, 28207, 33981, 28209, 12526, + 12539, 25178, 12653, 23986, 10044, 12544, 12528, 26842, 17246, 13188, + 15542, 12594, 7820, 19795, 26847, 32243, 32335, 10660, 10646, 3519, + 27087, 25191, 12644, 5107, 9948, 13187, 19796, 26213, 27170, 28828, + 13056, 35339, 15433, 26837, 29276, 7799, 16369, 20032, 25594, 15544, + 25526, 26059, 19964, 22887, 22275, 2662, 29089, 20269, 10490, 28137, + 25135, 24859, 28115, 12599, 25184, 3587, 3866, 26869, 13824, 25995, + 11864, 11865, 11867, 11866, 4656, 19089, 12621, 32025, 29082, 29083, + 26680, 10653, 22892, 20358, 21557, 21558, 6402, 9062, 26683, 3755, 12849, + 24833, 12551, 33557, 5106, 21521, 15618, 5044, 32151, 28850, 17241, 9947, + 12518, 101, 6581, 24820, 3583, 25618, 25612, 25621, 25611, 20036, 12557, + 33095, 22107, 11862, 13051, 35531, 5028, 24858, 3858, 26844, 13156, 7795, + 28224, 26102, 12580, 16086, 31287, 25631, 10647, 7575, 2645, 12577, + 32027, 5037, 20035, 19967, 19846, 28457, 2806, 26681, 31174, 5043, 3480, + 26488, 3478, 28461, 26088, 23661, 23766, 23777, 23780, 23769, 23759, + 23774, 33747, 3893, 23760, 33744, 33760, 33763, 33738, 33752, 33757, + 3890, 3906, 3909, 3884, 3898, 3903, 23767, 23778, 23781, 23770, 23765, + 23775, 33748, 3894, 23761, 33766, 33769, 33770, 33765, 33767, 33768, + 3912, 3915, 3916, 3911, 3913, 3914, 23784, 23787, 23788, 23783, 23785, + 23786, 33749, 3895, 23762, 33745, 33761, 33764, 33739, 33750, 33758, + 3891, 3907, 3910, 3885, 3896, 3904, 23768, 23779, 23782, 23771, 23763, + 23776, 33751, 3897, 23764, 33740, 3886, 23772, 33741, 3887, 23773, 33754, + 33755, 33753, 3900, 3901, 3899, 33742, 33736, 3888, 3882, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 33973, 33976, 33972, 33974, + 33971, 33970, 33975, 33966, 33969, 33965, 33967, 33964, 33963, 33968, + 35536, 35536, 2807, 24832, 5036, 27164, 31518, 19104, 13811, 25781, + 10496, 99, 28855, 33962, 7816, 35536, 35536, 35536, 35253, 17240, 25375, + 4360, 20034, 25782, 23756, 20364, 12609, 14805, 32153, 35536, 35536, + 35536, 32116, 27167, 26473, 6237, 26086, 2647, 10123, 3476, 22282, 1, + 19824, 7794, 6164, 26850, 17250, 15597, 22298, 33934, 25895, 26975, + 17242, 5110, 22900, 32026, 14835, 25790, 26483, 22299, 15624, 19852, + 14256, 12619, 14125, 16850, 12610, 33951, 3590, 7144, 25914, 33953, + 12559, 19848, 7768, 11876, 23757, 15615, 16079, 33937, 18721, 13190, 958, + 19969, 25633, 25929, 25928, 25616, 12573, 35536, 14127, 35536, 35536, + 35536, 35536, 24861, 22886, 10308, 4348, 3593, 24822, 12595, 30188, + 12643, 31173, 25916, 3588, 16078, 13053, 25598, 26526, 35536, 35536, + 28456, 21765, 26685, 12523, 12527, 12538, 10318, 3863, 5045, 27138, + 12534, 10043, 35536, 35536, 35536, 35536, 12567, 14259, 26421, 18930, + 25332, 25333, 15785, 14842, 18975, 26427, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 4284, 4314, 4285, 4329, 4300, 4318, 4286, 4337, 4307, 4315, 4293, 4330, 4301, 4319, 4287, 4341, 4311, 4326, 4297, 4334, 4323, 4290, 4338, 4308, 4316, 4294, 4331, 4302, 4320, 4288, 4343, 4313, 4328, 4299, 4336, 4306, 4325, 4292, 4340, 4310, 4296, 4333, 4304, 4322, 4289, 4342, 4312, 4327, 4298, 4335, 4305, 4324, 4291, 4339, 4309, 4317, - 4295, 4332, 4303, 4321, 25349, 25350, 25357, 25359, 25354, 25415, 25416, - 25412, 25414, 25410, 25413, 25406, 25409, 25407, 25411, 25408, 25353, - 25356, 25351, 25355, 25352, 25358, 38308, 38309, 38316, 38318, 38313, - 38278, 38279, 38275, 38277, 38273, 38276, 38269, 38272, 38270, 38274, - 38271, 38312, 38315, 38310, 38314, 38311, 38317, 38251, 24204, 38248, - 24209, 24295, 38347, 32190, 25441, 39295, 39296, 39297, 39298, 39299, - 39300, 20568, 20569, 20570, 20571, 20572, 20573, 24205, 24210, 32103, - 32102, 38250, 20567, 38306, 38343, 38258, 38346, 38342, 32152, 32186, - 32130, 32185, 32162, 24253, 32145, 38265, 25342, 20969, 38260, 38262, - 41412, 24252, 6400, 20965, 19891, 38283, 38338, 38249, 24206, 38284, - 38339, 25402, 25379, 4556, 4560, 4548, 4554, 4557, 4562, 4549, 4551, - 4559, 4561, 4563, 4558, 4552, 4553, 4579, 4589, 2563, 20966, 24247, - 32140, 20967, 24364, 32241, 11454, 38351, 24244, 32137, 39407, 32154, - 29186, 29185, 29187, 39687, 24298, 27757, 32181, 29217, 34732, 34733, - 34735, 34736, 34734, 39755, 39660, 31953, 4005, 24305, 24260, 4555, 4576, + 4295, 4332, 4303, 4321, 19869, 19870, 19877, 19879, 19874, 19935, 19936, + 19932, 19934, 19930, 19933, 19926, 19929, 19927, 19931, 19928, 19873, + 19876, 19871, 19875, 19872, 19878, 32432, 32433, 32440, 32442, 32437, + 32402, 32403, 32399, 32401, 32397, 32400, 32393, 32396, 32394, 32398, + 32395, 32436, 32439, 32434, 32438, 32435, 32441, 32375, 18724, 32372, + 18729, 18815, 32471, 26314, 19961, 33419, 33420, 33421, 33422, 33423, + 33424, 15559, 15560, 15561, 15562, 15563, 15564, 18725, 18730, 26227, + 26226, 32374, 15558, 32430, 32467, 32382, 32470, 32466, 26276, 26310, + 26254, 26309, 26286, 18773, 26269, 32389, 19862, 15960, 32384, 32386, + 35536, 18772, 6400, 15956, 14882, 32407, 32462, 32373, 18726, 32408, + 32463, 19922, 19899, 4556, 4560, 4548, 4554, 4557, 4562, 4549, 4551, + 4559, 4561, 4563, 4558, 4552, 4553, 4579, 4589, 2563, 15957, 18767, + 26264, 15958, 18884, 26365, 10440, 32475, 18764, 26261, 33531, 26278, + 23706, 23705, 23707, 33811, 18818, 22277, 26305, 23737, 28856, 28857, + 28859, 28860, 28858, 33879, 33784, 26077, 4005, 18825, 18780, 4555, 4576, 4571, 4550, 4566, 4565, 4573, 4564, 4569, 4575, 4546, 4570, 4567, 4577, - 4547, 4572, 37927, 32148, 4466, 24319, 38257, 25426, 27758, 27759, 37926, - 32147, 4465, 24318, 37936, 4452, 4459, 37928, 32759, 32761, 32758, 32757, - 32754, 32753, 32756, 32755, 32762, 32760, 229, 41412, 41412, 41412, - 41412, 41412, 6959, 6960, 6961, 6962, 6963, 6964, 6965, 6966, 6967, 6968, - 6969, 6970, 6971, 6972, 6973, 6974, 6975, 6976, 6977, 6978, 6979, 6980, - 6981, 6982, 6983, 6984, 6985, 6986, 6987, 6988, 6989, 6990, 6991, 6992, - 6993, 6994, 6995, 6996, 6997, 6998, 6999, 7000, 7001, 7002, 7003, 7004, - 7005, 7006, 7007, 7008, 7009, 7010, 7011, 7012, 7013, 7014, 7015, 7016, - 7017, 7018, 7019, 7020, 7021, 7022, 7023, 7024, 7025, 7026, 7027, 7028, - 7029, 7030, 7031, 7032, 7033, 7034, 7035, 7036, 7037, 7038, 7039, 7040, - 7041, 7042, 7043, 7044, 7045, 7046, 7047, 7048, 7049, 7050, 7051, 7052, - 7053, 7054, 7055, 7056, 7057, 7058, 7059, 7060, 7061, 7062, 7063, 7064, - 7065, 7066, 7067, 7068, 7069, 7070, 7071, 7072, 7073, 7074, 7075, 7076, - 7077, 7078, 7079, 7080, 7081, 7082, 7083, 7084, 7085, 7086, 7087, 7088, - 7089, 7090, 7091, 7092, 7093, 7094, 7095, 7096, 7097, 7098, 7099, 7100, - 7101, 7102, 7103, 7104, 7105, 7106, 7107, 7108, 7109, 7110, 7111, 7112, - 7113, 7114, 7115, 7116, 7117, 7118, 7119, 7120, 7121, 7122, 7123, 7124, - 7125, 7126, 7127, 7128, 7129, 7130, 7131, 7132, 7133, 7134, 7135, 7136, - 7137, 7138, 7139, 7140, 7141, 7142, 7143, 7144, 7145, 7146, 7147, 7148, - 7149, 7150, 7151, 7152, 7153, 7154, 7155, 7156, 7157, 7158, 7159, 7160, - 7161, 7162, 7163, 7164, 7165, 7166, 7167, 7168, 7169, 7170, 7171, 7172, - 7173, 7174, 7175, 7176, 7177, 7178, 7179, 7180, 7181, 7182, 7183, 7184, - 7185, 7186, 7187, 7188, 7189, 7190, 7191, 7192, 7193, 7194, 7195, 7196, - 7197, 7198, 7199, 7200, 7201, 7202, 7203, 7204, 7205, 7206, 7207, 7208, - 7209, 7210, 7211, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, 7220, - 7221, 7222, 7223, 7224, 7225, 7226, 7227, 7228, 7229, 7230, 7231, 7232, - 7233, 7234, 7235, 7236, 7237, 7238, 7239, 7240, 7241, 7242, 7243, 7244, - 7245, 7246, 7247, 7248, 7249, 7250, 7251, 7252, 7253, 7254, 7255, 7256, - 7257, 7258, 7259, 7260, 7261, 7262, 7263, 7264, 7265, 7266, 7267, 7268, - 7269, 7270, 7271, 7272, 7273, 7274, 7275, 7276, 7277, 7278, 7279, 7280, - 7281, 7282, 7283, 7284, 7285, 7286, 7287, 7288, 7289, 7290, 7291, 7292, - 7293, 7294, 7295, 7296, 7297, 7298, 7299, 7300, 7301, 7302, 7303, 7304, - 7305, 7306, 7307, 7308, 7309, 7310, 7311, 7312, 7313, 7314, 7315, 7316, - 7317, 7318, 7319, 7320, 7321, 7322, 7323, 7324, 7325, 7326, 7327, 7328, - 7329, 7330, 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, 7340, - 7341, 7342, 7343, 7344, 7345, 7346, 7347, 7348, 7349, 7350, 7351, 7352, - 7353, 7354, 7355, 7356, 7357, 7358, 7359, 7360, 7361, 7362, 7363, 7364, - 7365, 7366, 7367, 7368, 7369, 7370, 7371, 7372, 7373, 7374, 7375, 7376, - 7377, 7378, 7379, 7380, 7381, 7382, 7383, 7384, 7385, 7386, 7387, 7388, - 7389, 7390, 7391, 7392, 7393, 7394, 7395, 7396, 7397, 7398, 7399, 7400, - 7401, 7402, 7403, 7404, 7405, 7406, 7407, 7408, 7409, 7410, 7411, 7412, - 7413, 7414, 7415, 7416, 7417, 7418, 7419, 7420, 7421, 7422, 7423, 7424, - 7425, 7426, 7427, 7428, 7429, 7430, 7431, 7432, 7433, 7434, 7435, 7436, - 7437, 7438, 7439, 7440, 7441, 7442, 7443, 7444, 7445, 7446, 7447, 7448, - 7449, 7450, 7451, 7452, 7453, 7454, 7455, 7456, 7457, 7458, 7459, 7460, - 7461, 7462, 7463, 7464, 7465, 7466, 7467, 7468, 7469, 7470, 6943, 6944, - 6945, 6946, 6947, 6948, 6949, 6950, 6951, 6952, 6953, 6954, 6955, 6956, - 6957, 6958, 6929, 6930, 6931, 6932, 6933, 6934, 6935, 6936, 6937, 6938, - 6939, 6940, 6941, 6942, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 22732, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 35245, 35174, 35237, 35246, 35162, 35235, 35156, 35155, 35232, - 35240, 35157, 35236, 35160, 35177, 35248, 35244, 35169, 35171, 35168, - 35167, 35164, 35163, 35166, 35165, 35172, 35170, 35161, 35243, 35230, - 35173, 35176, 35238, 35159, 35178, 35179, 35180, 35181, 35182, 35183, - 35184, 35185, 35186, 35187, 35188, 35189, 35190, 35191, 35192, 35193, - 35194, 35195, 35196, 35197, 35198, 35199, 35200, 35201, 35202, 35203, - 35233, 35242, 35241, 35158, 35234, 35175, 35204, 35205, 35206, 35207, - 35208, 35209, 35210, 35211, 35212, 35213, 35214, 35215, 35216, 35217, - 35218, 35219, 35220, 35221, 35222, 35223, 35224, 35225, 35226, 35227, - 35228, 35229, 35231, 35249, 35239, 35247, 6097, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 38793, 38804, 38815, 38827, 38838, - 38849, 38860, 38871, 38882, 38890, 38891, 38892, 38893, 38895, 38896, - 38897, 38898, 38899, 38900, 38901, 38902, 38903, 38904, 38906, 38907, - 38908, 38909, 38910, 38911, 38912, 38913, 38914, 38915, 38917, 38918, - 38919, 38920, 38921, 38922, 38923, 38924, 38925, 38926, 38928, 38929, - 38930, 38931, 38932, 38933, 38934, 38935, 38936, 38937, 38939, 38940, - 38941, 38942, 38943, 38944, 38945, 38946, 38947, 38948, 38950, 38951, - 38952, 38953, 38954, 38955, 38956, 38957, 38958, 38959, 38961, 38962, - 38963, 38964, 38965, 38966, 38967, 38968, 38969, 38970, 38717, 38718, - 38719, 38720, 38721, 38722, 38723, 38724, 38725, 38726, 38728, 38729, - 38730, 38731, 38732, 38733, 38734, 38735, 38736, 38737, 38739, 38740, - 38741, 38742, 38743, 38744, 38745, 38746, 38747, 38748, 38750, 38751, - 38752, 38753, 38754, 38755, 38756, 38757, 38758, 38759, 38761, 38762, - 38763, 38764, 38765, 38766, 38767, 38768, 38769, 38770, 38772, 38773, - 38774, 38775, 38776, 38777, 38778, 38779, 38780, 38781, 38783, 38784, - 38785, 38786, 38787, 38788, 38789, 38790, 38791, 38792, 38794, 38795, - 38796, 38797, 38798, 38799, 38800, 38801, 38802, 38803, 38805, 38806, - 38807, 38808, 38809, 38810, 38811, 38812, 38813, 38814, 38816, 38817, - 38818, 38819, 38820, 38821, 38822, 38823, 38824, 38825, 38828, 38829, - 38830, 38831, 38832, 38833, 38834, 38835, 38836, 38837, 38839, 38840, - 38841, 38842, 38843, 38844, 38845, 38846, 38847, 38848, 38850, 38851, - 38852, 38853, 38854, 38855, 38856, 38857, 38858, 38859, 38861, 38862, - 38863, 38864, 38865, 38866, 38867, 38868, 38869, 38870, 38872, 38873, - 38874, 38875, 38876, 38877, 38878, 38879, 38880, 38881, 38883, 38884, - 38885, 38886, 38887, 38888, 38889, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 30035, 30034, 34722, 34301, 34723, 34754, 16908, 17482, 16906, - 16919, 16912, 16911, 3, 2, 349, 3591, 2657, 5360, 6392, 20578, 20608, - 35153, 24664, 29357, 16909, 25513, 30109, 16917, 24666, 39304, 39411, - 17638, 17788, 6165, 8810, 33016, 25280, 34098, 33017, 25279, 33050, - 10675, 11663, 10960, 10676, 10959, 10677, 10958, 10678, 10956, 10679, - 29225, 29143, 35058, 35057, 16907, 17481, 6095, 5368, 16905, 16918, - 16872, 34785, 34755, 16954, 16953, 20866, 17579, 17786, 20867, 18827, - 19133, 20868, 31975, 32554, 20869, 38208, 38414, 34303, 10691, 10688, - 31070, 31069, 20445, 20607, 5029, 5359, 29530, 29145, 20793, 20792, - 29459, 29464, 34719, 34707, 16904, 16957, 6394, 20580, 20610, 6393, - 20579, 20609, 24667, 39305, 39412, 31393, 31392, 31772, 31394, 31395, - 31752, 32055, 32062, 32090, 33862, 33863, 34705, 33861, 33864, 34706, - 10957, 10680, 31861, 31862, 31910, 31860, 31863, 31911, 32849, 34753, - 6096, 10660, 27588, 28969, 34718, 34721, 34304, 16903, 16901, 17520, - 34720, 34302, 33856, 35150, 33855, 32744, 8604, 10659, 34744, 34708, - 30727, 30949, 31859, 31912, 1056, 1063, 29144, 33049, 23060, 23683, - 10658, 2354, 363, 35136, 21392, 22735, 22736, 22778, 22744, 37497, 19533, - 19534, 19511, 19532, 17782, 17783, 17784, 28967, 17785, 34810, 41410, - 41409, 41411, 25509, 32357, 25507, 32355, 31468, 25510, 32358, 30108, - 28968, 39836, 25508, 32356, 17787, 31469, 39603, 27750, 27751, 24416, - 32313, 40346, 28755, 38972, 39083, 39151, 39162, 39173, 39184, 39195, - 39206, 39217, 38973, 38984, 38995, 39006, 39017, 39028, 39039, 31828, - 5358, 4651, 41408, 9774, 9773, 9469, 2872, 2982, 2973, 3080, 3281, 27045, - 27043, 27103, 27101, 20358, 5195, 27423, 27426, 39050, 39061, 39072, - 39084, 39095, 39106, 39117, 39128, 39139, 39147, 39148, 39149, 39150, - 39152, 39153, 39154, 39155, 39156, 39157, 39158, 39159, 39160, 39161, - 39163, 39164, 39165, 39166, 39167, 39168, 39169, 39170, 39171, 39172, - 39174, 39175, 39176, 39177, 39178, 39179, 39180, 39181, 39182, 39183, - 39185, 39186, 39187, 39188, 39189, 39190, 39191, 39192, 39193, 39194, - 39196, 39197, 39198, 39199, 39200, 39201, 39202, 39203, 39204, 39205, - 39207, 39208, 39209, 39210, 39211, 39212, 39213, 39214, 39215, 39216, - 39218, 39219, 39220, 39221, 39222, 39223, 39224, 39225, 39226, 39227, - 38974, 38975, 38976, 38977, 38978, 38979, 38980, 38981, 38982, 38983, - 38985, 38986, 38987, 38988, 38989, 38990, 38991, 38992, 38993, 38994, - 38996, 38997, 38998, 38999, 39000, 39001, 39002, 39003, 39004, 39005, - 39007, 39008, 39009, 39010, 39011, 39012, 39013, 39014, 39015, 39016, - 39018, 39019, 39020, 39021, 39022, 39023, 39024, 39025, 39026, 39027, - 39029, 39030, 39031, 39032, 39033, 39034, 39035, 39036, 39037, 39038, - 39040, 39041, 39042, 39043, 39044, 39045, 39046, 39047, 39048, 39049, - 39051, 39052, 39053, 39054, 39055, 39056, 39057, 39058, 39059, 39060, - 39062, 39063, 39064, 39065, 39066, 39067, 39068, 39069, 39070, 39071, - 39073, 39074, 39075, 39076, 39077, 39078, 39079, 39080, 39081, 39082, - 39085, 39086, 39087, 39088, 39089, 39090, 39091, 39092, 39093, 39094, - 39096, 39097, 39098, 39099, 39100, 39101, 39102, 39103, 39104, 39105, - 39107, 39108, 39109, 39110, 39111, 39112, 39113, 39114, 39115, 39116, - 39118, 39119, 39120, 39121, 39122, 39123, 39124, 39125, 39126, 39127, - 39129, 39130, 39131, 39132, 39133, 39134, 39135, 39136, 39137, 39138, - 39140, 39141, 39142, 39143, 39144, 39145, 39146, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 21777, 21778, - 21785, 21787, 21784, 21783, 21780, 21779, 21782, 21781, 21788, 21786, - 22923, 23489, 23084, 23714, 23324, 24088, 23019, 23624, 23020, 23625, - 23021, 23626, 23195, 23865, 23196, 23866, 23197, 23867, 23263, 23964, - 23003, 23607, 22999, 23603, 23709, 23833, 22933, 23499, 22934, 23500, - 23024, 23630, 23025, 23631, 23009, 23613, 23010, 23614, 23708, 23710, - 23089, 23716, 23090, 23717, 23107, 23744, 23137, 23784, 23145, 23806, - 23235, 23924, 23328, 24092, 23329, 24093, 23325, 24089, 23326, 24090, - 23508, 23882, 23883, 24043, 24044, 23973, 23974, 23698, 23699, 2324, - 2327, 2325, 2329, 2331, 2328, 2330, 2326, 2332, 10889, 10884, 10883, - 10890, 10885, 10886, 10888, 10887, 3664, 3663, 3665, 19041, 19040, 19039, - 19038, 19043, 19042, 30801, 30800, 3609, 35654, 35662, 35671, 35663, - 35665, 35660, 35664, 35659, 35675, 35674, 35677, 35669, 35656, 35676, - 35658, 35657, 35670, 35661, 35673, 35667, 35668, 35666, 35672, 35655, - 35793, 35800, 35801, 35796, 35797, 35802, 35803, 35794, 35798, 35799, - 35795, 35859, 35866, 35867, 35862, 35863, 35868, 35869, 35860, 35864, - 35865, 35861, 35970, 35977, 35978, 35973, 35974, 35979, 35980, 35971, - 35975, 35976, 35972, 35870, 35877, 35878, 35873, 35874, 35879, 35880, - 35871, 35875, 35876, 35872, 35948, 35955, 35956, 35951, 35952, 35957, - 35958, 35949, 35953, 35954, 35950, 35848, 35855, 35856, 35851, 35852, - 35857, 35858, 35849, 35853, 35854, 35850, 35959, 35966, 35967, 35962, - 35963, 35968, 35969, 35960, 35964, 35965, 35961, 35881, 35888, 35889, - 35884, 35885, 35890, 35891, 35882, 35886, 35887, 35883, 36014, 36021, - 36022, 36017, 36018, 36023, 36024, 36015, 36019, 36020, 36016, 36003, - 36010, 36011, 36006, 36007, 36012, 36013, 36004, 36008, 36009, 36005, - 36036, 36043, 36044, 36039, 36040, 36045, 36046, 36037, 36041, 36042, - 36038, 35903, 35910, 35911, 35906, 35907, 35912, 35913, 35904, 35908, - 35909, 35905, 35826, 35833, 35834, 35829, 35830, 35835, 35836, 35827, - 35831, 35832, 35828, 36025, 36032, 36033, 36028, 36029, 36034, 36035, - 36026, 36030, 36031, 36027, 35804, 35811, 35812, 35807, 35808, 35813, - 35814, 35805, 35809, 35810, 35806, 35815, 35822, 35823, 35818, 35819, - 35824, 35825, 35816, 35820, 35821, 35817, 35892, 35899, 35900, 35895, - 35896, 35901, 35902, 35893, 35897, 35898, 35894, 35837, 35844, 35845, - 35840, 35841, 35846, 35847, 35838, 35842, 35843, 35839, 35992, 35999, - 36000, 35995, 35996, 36001, 36002, 35993, 35997, 35998, 35994, 35914, - 35922, 35923, 35917, 35918, 35924, 35925, 35915, 35919, 35920, 35916, - 35926, 35933, 35934, 35929, 35930, 35935, 35936, 35927, 35931, 35932, - 35928, 35937, 35944, 35945, 35940, 35941, 35946, 35947, 35938, 35942, - 35943, 35939, 35981, 35988, 35989, 35984, 35985, 35990, 35991, 35982, - 35986, 35987, 35983, 35781, 35782, 35789, 35790, 35785, 35786, 35791, - 35792, 35783, 35787, 35788, 35784, 35921, 33887, 33885, 33886, 17964, - 22342, 22340, 22343, 22341, 22332, 22338, 22336, 22339, 22337, 22333, - 22353, 22349, 22354, 22350, 22334, 22351, 22347, 22352, 22348, 22335, - 22364, 22344, 22346, 22345, 22360, 22363, 22361, 22356, 22362, 22357, - 22358, 22359, 22365, 22355, 22504, 22381, 22382, 22383, 22380, 22499, - 22491, 20475, 20477, 20479, 20476, 20478, 21482, 21484, 21486, 21483, - 21485, 21475, 21474, 21473, 21476, 27960, 27965, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, - 41412, 41412, 41412, 41412, 41412, 41412, 41412, 41412, + 4547, 4572, 32051, 26272, 4466, 18839, 32381, 19946, 22278, 22279, 32050, + 26271, 4465, 18838, 32060, 4452, 4459, 32052, 26883, 26885, 26882, 26881, + 26878, 26877, 26880, 26879, 26886, 26884, 229, 35536, 35536, 35536, + 35536, 35536, 35536, 17252, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 29369, 29298, 29361, 29370, 29286, 29359, + 29280, 29279, 29356, 29364, 29281, 29360, 29284, 29301, 29372, 29368, + 29293, 29295, 29292, 29291, 29288, 29287, 29290, 29289, 29296, 29294, + 29285, 29367, 29354, 29297, 29300, 29362, 29283, 29302, 29303, 29304, + 29305, 29306, 29307, 29308, 29309, 29310, 29311, 29312, 29313, 29314, + 29315, 29316, 29317, 29318, 29319, 29320, 29321, 29322, 29323, 29324, + 29325, 29326, 29327, 29357, 29366, 29365, 29282, 29358, 29299, 29328, + 29329, 29330, 29331, 29332, 29333, 29334, 29335, 29336, 29337, 29338, + 29339, 29340, 29341, 29342, 29343, 29344, 29345, 29346, 29347, 29348, + 29349, 29350, 29351, 29352, 29353, 29355, 29373, 29363, 29371, 6097, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 32917, 32928, + 32939, 32951, 32962, 32973, 32984, 32995, 33006, 33014, 33015, 33016, + 33017, 33019, 33020, 33021, 33022, 33023, 33024, 33025, 33026, 33027, + 33028, 33030, 33031, 33032, 33033, 33034, 33035, 33036, 33037, 33038, + 33039, 33041, 33042, 33043, 33044, 33045, 33046, 33047, 33048, 33049, + 33050, 33052, 33053, 33054, 33055, 33056, 33057, 33058, 33059, 33060, + 33061, 33063, 33064, 33065, 33066, 33067, 33068, 33069, 33070, 33071, + 33072, 33074, 33075, 33076, 33077, 33078, 33079, 33080, 33081, 33082, + 33083, 33085, 33086, 33087, 33088, 33089, 33090, 33091, 33092, 33093, + 33094, 32841, 32842, 32843, 32844, 32845, 32846, 32847, 32848, 32849, + 32850, 32852, 32853, 32854, 32855, 32856, 32857, 32858, 32859, 32860, + 32861, 32863, 32864, 32865, 32866, 32867, 32868, 32869, 32870, 32871, + 32872, 32874, 32875, 32876, 32877, 32878, 32879, 32880, 32881, 32882, + 32883, 32885, 32886, 32887, 32888, 32889, 32890, 32891, 32892, 32893, + 32894, 32896, 32897, 32898, 32899, 32900, 32901, 32902, 32903, 32904, + 32905, 32907, 32908, 32909, 32910, 32911, 32912, 32913, 32914, 32915, + 32916, 32918, 32919, 32920, 32921, 32922, 32923, 32924, 32925, 32926, + 32927, 32929, 32930, 32931, 32932, 32933, 32934, 32935, 32936, 32937, + 32938, 32940, 32941, 32942, 32943, 32944, 32945, 32946, 32947, 32948, + 32949, 32952, 32953, 32954, 32955, 32956, 32957, 32958, 32959, 32960, + 32961, 32963, 32964, 32965, 32966, 32967, 32968, 32969, 32970, 32971, + 32972, 32974, 32975, 32976, 32977, 32978, 32979, 32980, 32981, 32982, + 32983, 32985, 32986, 32987, 32988, 32989, 32990, 32991, 32992, 32993, + 32994, 32996, 32997, 32998, 32999, 33000, 33001, 33002, 33003, 33004, + 33005, 33007, 33008, 33009, 33010, 33011, 33012, 33013, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 24159, 24158, 28846, 28425, 28847, 28878, + 11899, 12473, 11897, 11910, 11903, 11902, 3, 2, 349, 3591, 2657, 5360, + 6392, 15569, 15599, 29277, 19184, 23877, 11900, 20033, 24233, 11908, + 19186, 33428, 33535, 12629, 12779, 6165, 7796, 27140, 19800, 28222, + 27141, 19799, 27174, 9661, 10649, 9946, 9662, 9945, 9663, 9944, 9664, + 9942, 9665, 23745, 23663, 29182, 29181, 11898, 12472, 6095, 5368, 11896, + 11909, 11863, 28909, 28879, 11945, 11944, 15857, 12570, 12777, 15858, + 13818, 14124, 15859, 26099, 26678, 15860, 32332, 32538, 28427, 9677, + 9674, 25194, 25193, 15436, 15598, 5029, 5359, 24050, 23665, 15784, 15783, + 23979, 23984, 28843, 28831, 11895, 11948, 6394, 15571, 15601, 6393, + 15570, 15600, 19187, 33429, 33536, 25517, 25516, 25896, 25518, 25519, + 25876, 26179, 26186, 26214, 27986, 27987, 28829, 27985, 27988, 28830, + 9943, 9666, 25985, 25986, 26034, 25984, 25987, 26035, 26973, 28877, 6096, + 9646, 22108, 23489, 28842, 28845, 28428, 11894, 11892, 12511, 28844, + 28426, 27980, 29274, 27979, 26868, 7590, 9645, 28868, 28832, 24851, + 25073, 25983, 26036, 1056, 1063, 23664, 27173, 17580, 18203, 9644, 2354, + 363, 29260, 16383, 17255, 17256, 17298, 17264, 31621, 14524, 14525, + 14502, 14523, 12773, 12774, 12775, 23487, 12776, 28934, 35534, 35533, + 35535, 20029, 26481, 20027, 26479, 25592, 20030, 26482, 24232, 23488, + 33960, 20028, 26480, 12778, 25593, 33727, 22270, 22271, 18936, 26437, + 34470, 23275, 33096, 33207, 33275, 33286, 33297, 33308, 33319, 33330, + 33341, 33097, 33108, 33119, 33130, 33141, 33152, 33163, 25952, 5358, + 4651, 35532, 8760, 8759, 8455, 2872, 2982, 2973, 3080, 3281, 21565, + 21563, 21623, 21621, 15349, 5195, 21943, 21946, 33174, 33185, 33196, + 33208, 33219, 33230, 33241, 33252, 33263, 33271, 33272, 33273, 33274, + 33276, 33277, 33278, 33279, 33280, 33281, 33282, 33283, 33284, 33285, + 33287, 33288, 33289, 33290, 33291, 33292, 33293, 33294, 33295, 33296, + 33298, 33299, 33300, 33301, 33302, 33303, 33304, 33305, 33306, 33307, + 33309, 33310, 33311, 33312, 33313, 33314, 33315, 33316, 33317, 33318, + 33320, 33321, 33322, 33323, 33324, 33325, 33326, 33327, 33328, 33329, + 33331, 33332, 33333, 33334, 33335, 33336, 33337, 33338, 33339, 33340, + 33342, 33343, 33344, 33345, 33346, 33347, 33348, 33349, 33350, 33351, + 33098, 33099, 33100, 33101, 33102, 33103, 33104, 33105, 33106, 33107, + 33109, 33110, 33111, 33112, 33113, 33114, 33115, 33116, 33117, 33118, + 33120, 33121, 33122, 33123, 33124, 33125, 33126, 33127, 33128, 33129, + 33131, 33132, 33133, 33134, 33135, 33136, 33137, 33138, 33139, 33140, + 33142, 33143, 33144, 33145, 33146, 33147, 33148, 33149, 33150, 33151, + 33153, 33154, 33155, 33156, 33157, 33158, 33159, 33160, 33161, 33162, + 33164, 33165, 33166, 33167, 33168, 33169, 33170, 33171, 33172, 33173, + 33175, 33176, 33177, 33178, 33179, 33180, 33181, 33182, 33183, 33184, + 33186, 33187, 33188, 33189, 33190, 33191, 33192, 33193, 33194, 33195, + 33197, 33198, 33199, 33200, 33201, 33202, 33203, 33204, 33205, 33206, + 33209, 33210, 33211, 33212, 33213, 33214, 33215, 33216, 33217, 33218, + 33220, 33221, 33222, 33223, 33224, 33225, 33226, 33227, 33228, 33229, + 33231, 33232, 33233, 33234, 33235, 33236, 33237, 33238, 33239, 33240, + 33242, 33243, 33244, 33245, 33246, 33247, 33248, 33249, 33250, 33251, + 33253, 33254, 33255, 33256, 33257, 33258, 33259, 33260, 33261, 33262, + 33264, 33265, 33266, 33267, 33268, 33269, 33270, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 16768, 16769, + 16776, 16778, 16775, 16774, 16771, 16770, 16773, 16772, 16779, 16777, + 17443, 18009, 17604, 18234, 17844, 18608, 17539, 18144, 17540, 18145, + 17541, 18146, 17715, 18385, 17716, 18386, 17717, 18387, 17783, 18484, + 17523, 18127, 17519, 18123, 18229, 18353, 17453, 18019, 17454, 18020, + 17544, 18150, 17545, 18151, 17529, 18133, 17530, 18134, 18228, 18230, + 17609, 18236, 17610, 18237, 17627, 18264, 17657, 18304, 17665, 18326, + 17755, 18444, 17848, 18612, 17849, 18613, 17845, 18609, 17846, 18610, + 18028, 18402, 18403, 18563, 18564, 18493, 18494, 18218, 18219, 2324, + 2327, 2325, 2329, 2331, 2328, 2330, 2326, 2332, 9875, 9870, 9869, 9876, + 9871, 9872, 9874, 9873, 3664, 3663, 3665, 14032, 14031, 14030, 14029, + 14034, 14033, 24925, 24924, 3609, 29778, 29786, 29795, 29787, 29789, + 29784, 29788, 29783, 29799, 29798, 29801, 29793, 29780, 29800, 29782, + 29781, 29794, 29785, 29797, 29791, 29792, 29790, 29796, 29779, 29917, + 29924, 29925, 29920, 29921, 29926, 29927, 29918, 29922, 29923, 29919, + 29983, 29990, 29991, 29986, 29987, 29992, 29993, 29984, 29988, 29989, + 29985, 30094, 30101, 30102, 30097, 30098, 30103, 30104, 30095, 30099, + 30100, 30096, 29994, 30001, 30002, 29997, 29998, 30003, 30004, 29995, + 29999, 30000, 29996, 30072, 30079, 30080, 30075, 30076, 30081, 30082, + 30073, 30077, 30078, 30074, 29972, 29979, 29980, 29975, 29976, 29981, + 29982, 29973, 29977, 29978, 29974, 30083, 30090, 30091, 30086, 30087, + 30092, 30093, 30084, 30088, 30089, 30085, 30005, 30012, 30013, 30008, + 30009, 30014, 30015, 30006, 30010, 30011, 30007, 30138, 30145, 30146, + 30141, 30142, 30147, 30148, 30139, 30143, 30144, 30140, 30127, 30134, + 30135, 30130, 30131, 30136, 30137, 30128, 30132, 30133, 30129, 30160, + 30167, 30168, 30163, 30164, 30169, 30170, 30161, 30165, 30166, 30162, + 30027, 30034, 30035, 30030, 30031, 30036, 30037, 30028, 30032, 30033, + 30029, 29950, 29957, 29958, 29953, 29954, 29959, 29960, 29951, 29955, + 29956, 29952, 30149, 30156, 30157, 30152, 30153, 30158, 30159, 30150, + 30154, 30155, 30151, 29928, 29935, 29936, 29931, 29932, 29937, 29938, + 29929, 29933, 29934, 29930, 29939, 29946, 29947, 29942, 29943, 29948, + 29949, 29940, 29944, 29945, 29941, 30016, 30023, 30024, 30019, 30020, + 30025, 30026, 30017, 30021, 30022, 30018, 29961, 29968, 29969, 29964, + 29965, 29970, 29971, 29962, 29966, 29967, 29963, 30116, 30123, 30124, + 30119, 30120, 30125, 30126, 30117, 30121, 30122, 30118, 30038, 30046, + 30047, 30041, 30042, 30048, 30049, 30039, 30043, 30044, 30040, 30050, + 30057, 30058, 30053, 30054, 30059, 30060, 30051, 30055, 30056, 30052, + 30061, 30068, 30069, 30064, 30065, 30070, 30071, 30062, 30066, 30067, + 30063, 30105, 30112, 30113, 30108, 30109, 30114, 30115, 30106, 30110, + 30111, 30107, 29905, 29906, 29913, 29914, 29909, 29910, 29915, 29916, + 29907, 29911, 29912, 29908, 30045, 28011, 28009, 28010, 12955, 16861, + 16859, 16862, 16860, 16851, 16857, 16855, 16858, 16856, 16852, 16872, + 16868, 16873, 16869, 16853, 16870, 16866, 16871, 16867, 16854, 16883, + 16863, 16865, 16864, 16879, 16882, 16880, 16875, 16881, 16876, 16877, + 16878, 16884, 16874, 17023, 16900, 16901, 16902, 16899, 17018, 17010, + 15466, 15468, 15470, 15467, 15469, 16473, 16475, 16477, 16474, 16476, + 16466, 16465, 16464, 16467, 22480, 22485, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, 35536, + 35536, 35536, 35536, 35536, 35536, 35536, 35536, }; @@ -19695,14 +18472,21 @@ static const derived_name_range derived_name_ranges[] = { {0x3400, 0x4DBF, 1}, {0x4E00, 0x9FFF, 1}, {0xAC00, 0xD7A3, 0}, + {0xF900, 0xFA6D, 3}, + {0xFA70, 0xFAD9, 3}, + {0x13460, 0x143FA, 4}, {0x17000, 0x187FF, 2}, + {0x18B00, 0x18CD5, 5}, + {0x18CFF, 0x18CFF, 5}, {0x18D00, 0x18D1E, 2}, + {0x1B170, 0x1B2FB, 6}, {0x20000, 0x2A6DF, 1}, {0x2A700, 0x2B73F, 1}, {0x2B740, 0x2B81D, 1}, {0x2B820, 0x2CEAD, 1}, {0x2CEB0, 0x2EBE0, 1}, {0x2EBF0, 0x2EE5D, 1}, + {0x2F800, 0x2FA1D, 3}, {0x30000, 0x3134A, 1}, {0x31350, 0x323AF, 1}, {0x323B0, 0x33479, 1}, @@ -19711,4 +18495,8 @@ static const char * const derived_name_prefixes[] = { "HANGUL SYLLABLE ", "CJK UNIFIED IDEOGRAPH-", "TANGUT IDEOGRAPH-", + "CJK COMPATIBILITY IDEOGRAPH-", + "EGYPTIAN HIEROGLYPH-", + "KHITAN SMALL SCRIPT CHARACTER-", + "NUSHU CHARACTER-", }; diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 37d7e096769833..11f626ca0aba7a 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -764,11 +764,11 @@ def makeunicodename(unicode, trace): fprint('static const derived_name_range derived_name_ranges[] = {') for name_range in unicode.derived_name_ranges: - fprint(' {0x%s, 0x%s, %d},' % name_range) + fprint(' {0x%s, 0x%s, %d},' % tuple(name_range)) fprint('};') fprint('static const char * const derived_name_prefixes[] = {') - for _, prefix in derived_name_range_names: + for prefix in unicode.derived_name_prefixes: fprint(' "%s",' % prefix) fprint('};') @@ -997,6 +997,10 @@ def __init__(self, version, ideograph_check=True): table[char] = from_row(s) self.derived_name_ranges = [] + self.derived_name_prefixes = { + prefix: i + for i, (_, prefix) in enumerate(derived_name_range_names) + } # expand first-last ranges field = None @@ -1017,8 +1021,24 @@ def __init__(self, version, ideograph_check=True): break s.name = "" field = None + else: + codepoint = s.codepoint + if s.name.endswith(codepoint): + prefix = s.name[:-len(codepoint)] + j = self.derived_name_prefixes.get(prefix) + if j is None: + j = len(self.derived_name_prefixes) + self.derived_name_prefixes[prefix] = j + if (self.derived_name_ranges + and self.derived_name_ranges[-1][2] == j + and int(self.derived_name_ranges[-1][1], 16) == i - 1): + self.derived_name_ranges[-1][1] = codepoint + else: + self.derived_name_ranges.append( + [codepoint, codepoint, j]) + s.name = "" elif field: - table[i] = from_row(('%X' % i,) + field[1:]) + table[i] = from_row(('%04X' % i,) + field[1:]) # public attributes self.filename = UNICODE_DATA % '' From 9e8fa2d4d1ec263bdc6945237b0e0517f07a3474 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 Feb 2026 13:13:32 +0200 Subject: [PATCH 141/498] gh-144386: Update equivalent code for "with", "async with" and "async for" (GH-144472) They use special method lookup for special methods. --- Doc/reference/compound_stmts.rst | 34 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 861c221502ed4d..0cf0a41bfb400c 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -544,9 +544,9 @@ The following code:: is semantically equivalent to:: manager = (EXPRESSION) - enter = type(manager).__enter__ - exit = type(manager).__exit__ - value = enter(manager) + enter = manager.__enter__ + exit = manager.__exit__ + value = enter() hit_except = False try: @@ -554,11 +554,14 @@ is semantically equivalent to:: SUITE except: hit_except = True - if not exit(manager, *sys.exc_info()): + if not exit(*sys.exc_info()): raise finally: if not hit_except: - exit(manager, None, None, None) + exit(None, None, None) + +except that implicit :ref:`special method lookup ` is used +for :meth:`~object.__enter__` and :meth:`~object.__exit__`. With more than one item, the context managers are processed as if multiple :keyword:`with` statements were nested:: @@ -1679,13 +1682,12 @@ The following code:: Is semantically equivalent to:: - iter = (ITER) - iter = type(iter).__aiter__(iter) + iter = (ITER).__aiter__() running = True while running: try: - TARGET = await type(iter).__anext__(iter) + TARGET = await iter.__anext__() except StopAsyncIteration: running = False else: @@ -1693,7 +1695,8 @@ Is semantically equivalent to:: else: SUITE2 -See also :meth:`~object.__aiter__` and :meth:`~object.__anext__` for details. +except that implicit :ref:`special method lookup ` is used +for :meth:`~object.__aiter__` and :meth:`~object.__anext__`. It is a :exc:`SyntaxError` to use an ``async for`` statement outside the body of a coroutine function. @@ -1719,9 +1722,9 @@ The following code:: is semantically equivalent to:: manager = (EXPRESSION) - aenter = type(manager).__aenter__ - aexit = type(manager).__aexit__ - value = await aenter(manager) + aenter = manager.__aenter__ + aexit = manager.__aexit__ + value = await aenter() hit_except = False try: @@ -1729,13 +1732,14 @@ is semantically equivalent to:: SUITE except: hit_except = True - if not await aexit(manager, *sys.exc_info()): + if not await aexit(*sys.exc_info()): raise finally: if not hit_except: - await aexit(manager, None, None, None) + await aexit(None, None, None) -See also :meth:`~object.__aenter__` and :meth:`~object.__aexit__` for details. +except that implicit :ref:`special method lookup ` is used +for :meth:`~object.__aenter__` and :meth:`~object.__aexit__`. It is a :exc:`SyntaxError` to use an ``async with`` statement outside the body of a coroutine function. From 7ac0868708f342b8990404174a4d200105a4f728 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 Feb 2026 13:20:31 +0200 Subject: [PATCH 142/498] gh-135573: Make pickled lists, sets and dicts a tiny bit smaller (GH-144162) Ensure that APPENDS and SETITEMS are never used for a batch of size 1. Ensure that ADDITEMS and SETITEMS are never used for a batch of size 0. This harmonizes the C implementation with the Python implementation which already guarantees this and makes a pickle a tiny bit smaller with a tiny chance (about 0.1%). Saves 1 byte for list and dict with size 1001, 2001, ... Saves 2 bytes for set and dict with size 1000, 2000, ... --- Modules/_pickle.c | 79 +++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/Modules/_pickle.c b/Modules/_pickle.c index a897e45f00fab6..24d3443dd8abfe 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -3066,11 +3066,6 @@ batch_list(PickleState *state, PicklerObject *self, PyObject *iter, PyObject *or assert(iter != NULL); - /* XXX: I think this function could be made faster by avoiding the - iterator interface and fetching objects directly from list using - PyList_GET_ITEM. - */ - if (self->proto == 0) { /* APPENDS isn't available; do one at a time. */ for (;; total++) { @@ -3192,24 +3187,24 @@ batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj) assert(obj != NULL); assert(self->proto > 0); assert(PyList_CheckExact(obj)); - - if (PyList_GET_SIZE(obj) == 1) { - item = PyList_GET_ITEM(obj, 0); - Py_INCREF(item); - int err = save(state, self, item, 0); - Py_DECREF(item); - if (err < 0) { - _PyErr_FormatNote("when serializing %T item 0", obj); - return -1; - } - if (_Pickler_Write(self, &append_op, 1) < 0) - return -1; - return 0; - } + assert(PyList_GET_SIZE(obj)); /* Write in batches of BATCHSIZE. */ total = 0; do { + if (PyList_GET_SIZE(obj) - total == 1) { + item = PyList_GET_ITEM(obj, total); + Py_INCREF(item); + int err = save(state, self, item, 0); + Py_DECREF(item); + if (err < 0) { + _PyErr_FormatNote("when serializing %T item %zd", obj, total); + return -1; + } + if (_Pickler_Write(self, &append_op, 1) < 0) + return -1; + return 0; + } this_batch = 0; if (_Pickler_Write(self, &mark_op, 1) < 0) return -1; @@ -3470,28 +3465,29 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) assert(self->proto > 0); dict_size = PyDict_GET_SIZE(obj); - - /* Special-case len(d) == 1 to save space. */ - if (dict_size == 1) { - PyDict_Next(obj, &ppos, &key, &value); - Py_INCREF(key); - Py_INCREF(value); - if (save(state, self, key, 0) < 0) { - goto error; - } - if (save(state, self, value, 0) < 0) { - _PyErr_FormatNote("when serializing %T item %R", obj, key); - goto error; - } - Py_CLEAR(key); - Py_CLEAR(value); - if (_Pickler_Write(self, &setitem_op, 1) < 0) - return -1; - return 0; - } + assert(dict_size); /* Write in batches of BATCHSIZE. */ + Py_ssize_t total = 0; do { + if (dict_size - total == 1) { + PyDict_Next(obj, &ppos, &key, &value); + Py_INCREF(key); + Py_INCREF(value); + if (save(state, self, key, 0) < 0) { + goto error; + } + if (save(state, self, value, 0) < 0) { + _PyErr_FormatNote("when serializing %T item %R", obj, key); + goto error; + } + Py_CLEAR(key); + Py_CLEAR(value); + if (_Pickler_Write(self, &setitem_op, 1) < 0) + return -1; + return 0; + } + i = 0; if (_Pickler_Write(self, &mark_op, 1) < 0) return -1; @@ -3507,6 +3503,7 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) } Py_CLEAR(key); Py_CLEAR(value); + total++; if (++i == BATCHSIZE) break; } @@ -3519,7 +3516,7 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) return -1; } - } while (i == BATCHSIZE); + } while (total < dict_size); return 0; error: Py_XDECREF(key); @@ -3637,6 +3634,7 @@ save_set(PickleState *state, PicklerObject *self, PyObject *obj) return 0; /* nothing to do */ /* Write in batches of BATCHSIZE. */ + Py_ssize_t total = 0; do { i = 0; if (_Pickler_Write(self, &mark_op, 1) < 0) @@ -3651,6 +3649,7 @@ save_set(PickleState *state, PicklerObject *self, PyObject *obj) _PyErr_FormatNote("when serializing %T element", obj); break; } + total++; if (++i == BATCHSIZE) break; } @@ -3666,7 +3665,7 @@ save_set(PickleState *state, PicklerObject *self, PyObject *obj) "set changed size during iteration"); return -1; } - } while (i == BATCHSIZE); + } while (total < set_size); return 0; } From dd64e4260e0d114f8259f15bc86fb17c5b08c80b Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 18 Feb 2026 12:30:26 +0100 Subject: [PATCH 143/498] gh-141510: Implement copy and deepcopy for frozendict (#144905) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Victor Stinner --- Lib/copy.py | 7 ++++++- Lib/test/test_copy.py | 13 +++++++++++++ .../2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst diff --git a/Lib/copy.py b/Lib/copy.py index 4c024ab5311d2d..33dabb3395a7c0 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -101,7 +101,7 @@ def copy(x): _copy_atomic_types = frozenset({types.NoneType, int, float, bool, complex, str, tuple, - bytes, frozenset, type, range, slice, property, + bytes, frozendict, frozenset, type, range, slice, property, types.BuiltinFunctionType, types.EllipsisType, types.NotImplementedType, types.FunctionType, types.CodeType, weakref.ref, super}) @@ -203,6 +203,11 @@ def _deepcopy_dict(x, memo, deepcopy=deepcopy): return y d[dict] = _deepcopy_dict +def _deepcopy_frozendict(x, memo, deepcopy=deepcopy): + y = _deepcopy_dict(x, memo, deepcopy) + return frozendict(y) +d[frozendict] = _deepcopy_frozendict + def _deepcopy_method(x, memo): # Copy instance methods return type(x)(x.__func__, deepcopy(x.__self__, memo)) d[types.MethodType] = _deepcopy_method diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index cfef24727e8c82..858e5e089d5aba 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -133,6 +133,12 @@ def test_copy_dict(self): self.assertEqual(y, x) self.assertIsNot(y, x) + def test_copy_frozendict(self): + x = frozendict(x=1, y=2) + self.assertIs(copy.copy(x), x) + x = frozendict() + self.assertIs(copy.copy(x), x) + def test_copy_set(self): x = {1, 2, 3} y = copy.copy(x) @@ -419,6 +425,13 @@ def test_deepcopy_dict(self): self.assertIsNot(x, y) self.assertIsNot(x["foo"], y["foo"]) + def test_deepcopy_frozendict(self): + x = frozendict({"foo": [1, 2], "bar": 3}) + y = copy.deepcopy(x) + self.assertEqual(y, x) + self.assertIsNot(x, y) + self.assertIsNot(x["foo"], y["foo"]) + @support.skip_emscripten_stack_overflow() @support.skip_wasi_stack_overflow() def test_deepcopy_reflexive_dict(self): diff --git a/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst b/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst new file mode 100644 index 00000000000000..5b604124c6d7cc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst @@ -0,0 +1,2 @@ +The :mod:`copy` module now supports the :class:`frozendict` type. Patch by +Pieter Eendebak based on work by Victor Stinner. From 3f50432e31c8e0d2e3ea8cbc2e472f7ee80e327a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 Feb 2026 14:54:48 +0200 Subject: [PATCH 144/498] =?UTF-8?q?gh-140652:=20Fix=20a=20crash=20in=20=5F?= =?UTF-8?q?interpchannels.list=5Fall()=20after=20closing=20a=20channel=20(?= =?UTF-8?q?=D0=9F=D0=A0-143743)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lib/test/test__interpchannels.py | 32 +++++++++++++++++++ Lib/test/test_interpreters/test_channels.py | 6 ++++ ...-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst | 1 + Modules/_interpchannelsmodule.c | 16 ++++++---- 4 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst diff --git a/Lib/test/test__interpchannels.py b/Lib/test/test__interpchannels.py index d7cf77368ef9f2..2b0aba42896c06 100644 --- a/Lib/test/test__interpchannels.py +++ b/Lib/test/test__interpchannels.py @@ -382,6 +382,38 @@ def test_sequential_ids(self): self.assertEqual(id3, int(id2) + 1) self.assertEqual(set(after) - set(before), {id1, id2, id3}) + def test_channel_list_all_closed(self): + id1 = _channels.create() + id2 = _channels.create() + id3 = _channels.create() + before = _channels.list_all() + expected = [info for info in before if info[0] != id2] + _channels.close(id2, force=True) + after = _channels.list_all() + self.assertEqual(set(after), set(expected)) + self.assertEqual(len(after), len(before) - 1) + + def test_channel_list_all_destroyed(self): + id1 = _channels.create() + id2 = _channels.create() + id3 = _channels.create() + before = _channels.list_all() + expected = [info for info in before if info[0] != id2] + _channels.destroy(id2) + after = _channels.list_all() + self.assertEqual(set(after), set(expected)) + self.assertEqual(len(after), len(before) - 1) + + def test_channel_list_all_released(self): + id1 = _channels.create() + id2 = _channels.create() + id3 = _channels.create() + before = _channels.list_all() + _channels.release(id2, send=True, recv=True) + after = _channels.list_all() + self.assertEqual(set(after), set(before)) + self.assertEqual(len(after), len(before)) + def test_ids_global(self): id1 = _interpreters.create() out = _run_output(id1, dedent(""" diff --git a/Lib/test/test_interpreters/test_channels.py b/Lib/test/test_interpreters/test_channels.py index 52827357078b85..5437792b5a7014 100644 --- a/Lib/test/test_interpreters/test_channels.py +++ b/Lib/test/test_interpreters/test_channels.py @@ -47,6 +47,12 @@ def test_list_all(self): after = set(channels.list_all()) self.assertEqual(after, created) + def test_list_all_closed(self): + created = [channels.create() for _ in range(3)] + rch, sch = created.pop(1) + rch.close() + self.assertEqual(set(channels.list_all()), set(created)) + def test_shareable(self): interp = interpreters.create() rch, sch = channels.create() diff --git a/Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst b/Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst new file mode 100644 index 00000000000000..bed126f02f8714 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst @@ -0,0 +1 @@ +Fix a crash in :func:`!_interpchannels.list_all` after closing a channel. diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index ef9cf01ecbec5e..2933332ad465d4 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -1644,14 +1644,16 @@ _channels_list_all(_channels *channels, int64_t *count) if (ids == NULL) { goto done; } - _channelref *ref = channels->head; - for (int64_t i=0; ref != NULL; ref = ref->next, i++) { - ids[i] = (struct channel_id_and_info){ - .id = ref->cid, - .defaults = ref->chan->defaults, - }; + int64_t i = 0; + for (_channelref *ref = channels->head; ref != NULL; ref = ref->next) { + if (ref->chan != NULL) { + ids[i++] = (struct channel_id_and_info){ + .id = ref->cid, + .defaults = ref->chan->defaults, + }; + } } - *count = channels->numopen; + *count = i; cids = ids; done: From 112d8ac9724a53c5459a4f957941f5a3c97abf5d Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 18 Feb 2026 14:13:21 +0100 Subject: [PATCH 145/498] gh-141984: Reword and reorganize the first part of Atoms docs (GH-144117) Co-authored-by: Blaise Pabon Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/faq/programming.rst | 2 + Doc/library/stdtypes.rst | 12 +- Doc/library/token.rst | 3 +- Doc/reference/expressions.rst | 201 ++++++++++++++++++++++++++-------- 4 files changed, 167 insertions(+), 51 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 138a5ca7a7516f..7a6f88d90a9ea5 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1852,6 +1852,8 @@ to the object: 13891296 +.. _faq-identity-with-is: + When can I rely on identity tests with the *is* operator? --------------------------------------------------------- diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index a8f693f4879025..b9b81a7d469d0d 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -265,9 +265,17 @@ The constructors :func:`int`, :func:`float`, and pair: operator; % (percent) pair: operator; ** +.. _stdtypes-mixed-arithmetic: + Python fully supports mixed arithmetic: when a binary arithmetic operator has -operands of different numeric types, the operand with the "narrower" type is -widened to that of the other, where integer is narrower than floating point. +operands of different built-in numeric types, the operand with the "narrower" +type is widened to that of the other: + +* If both arguments are complex numbers, no conversion is performed; +* if either argument is a complex or a floating-point number, the other is + converted to a floating-point number; +* otherwise, both must be integers and no conversion is necessary. + Arithmetic with complex and real operands is defined by the usual mathematical formula, for example:: diff --git a/Doc/library/token.rst b/Doc/library/token.rst index c228006d4c1e1d..fb826f5465bd80 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -50,8 +50,7 @@ The token constants are: .. data:: NAME - Token value that indicates an :ref:`identifier `. - Note that keywords are also initially tokenized as ``NAME`` tokens. + Token value that indicates an :ref:`identifier or keyword `. .. data:: NUMBER diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 54384a8cf3fb90..68dcfc00bbd99c 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -9,9 +9,11 @@ Expressions This chapter explains the meaning of the elements of expressions in Python. -**Syntax Notes:** In this and the following chapters, extended BNF notation will -be used to describe syntax, not lexical analysis. When (one alternative of) a -syntax rule has the form +**Syntax Notes:** In this and the following chapters, +:ref:`grammar notation ` will be used to describe syntax, +not lexical analysis. + +When (one alternative of) a syntax rule has the form: .. productionlist:: python-grammar name: othername @@ -29,17 +31,13 @@ Arithmetic conversions When a description of an arithmetic operator below uses the phrase "the numeric arguments are converted to a common real type", this means that the operator -implementation for built-in types works as follows: - -* If both arguments are complex numbers, no conversion is performed; - -* if either argument is a complex or a floating-point number, the other is converted to a floating-point number; - -* otherwise, both must be integers and no conversion is necessary. +implementation for built-in numeric types works as described in the +:ref:`Numeric Types ` section of the standard +library documentation. -Some additional rules apply for certain operators (e.g., a string as a left -argument to the '%' operator). Extensions must define their own conversion -behavior. +Some additional rules apply for certain operators and non-numeric operands +(for example, a string as a left argument to the ``%`` operator). +Extensions must define their own conversion behavior. .. _atoms: @@ -49,15 +47,57 @@ Atoms .. index:: atom -Atoms are the most basic elements of expressions. The simplest atoms are -identifiers or literals. Forms enclosed in parentheses, brackets or braces are -also categorized syntactically as atoms. The syntax for atoms is: +Atoms are the most basic elements of expressions. +The simplest atoms are :ref:`names ` or literals. +Forms enclosed in parentheses, brackets or braces are also categorized +syntactically as atoms. -.. productionlist:: python-grammar - atom: `identifier` | `literal` | `enclosure` - enclosure: `parenth_form` | `list_display` | `dict_display` | `set_display` - : | `generator_expression` | `yield_atom` +Formally, the syntax for atoms is: + +.. grammar-snippet:: + :group: python-grammar + + atom: + | 'True' + | 'False' + | 'None' + | '...' + | `identifier` + | `literal` + | `enclosure` + enclosure: + | `parenth_form` + | `list_display` + | `dict_display` + | `set_display` + | `generator_expression` + | `yield_atom` + + +.. _atom-singletons: + +Built-in constants +------------------ + +The keywords ``True``, ``False``, and ``None`` name +:ref:`built-in constants `. +The token ``...`` names the :py:data:`Ellipsis` constant. +Evaluation of these atoms yields the corresponding value. + +.. note:: + + Several more built-in constants are available as global variables, + but only the ones mentioned here are :ref:`keywords `. + In particular, these names cannot be reassigned or used as attributes: + + .. code-block:: pycon + + >>> False = 123 + File "", line 1 + False = 123 + ^^^^^ + SyntaxError: cannot assign to False .. _atom-identifiers: @@ -131,51 +171,104 @@ Literals .. index:: single: literal -Python supports string and bytes literals and various numeric literals: +A :dfn:`literal` is a textual representation of a value. +Python supports numeric, string and bytes literals. +:ref:`Format strings ` and :ref:`template strings ` +are treated as string literals. + +Numeric literals consist of a single :token:`NUMBER ` +token, which names an integer, floating-point number, or an imaginary number. +See the :ref:`numbers` section in Lexical analysis documentation for details. + +String and bytes literals may consist of several tokens. +See section :ref:`string-concatenation` for details. + +Note that negative and complex numbers, like ``-3`` or ``3+4.2j``, +are syntactically not literals, but :ref:`unary ` or +:ref:`binary ` arithmetic operations involving the ``-`` or ``+`` +operator. + +Evaluation of a literal yields an object of the given type +(:class:`int`, :class:`float`, :class:`complex`, :class:`str`, +:class:`bytes`, or :class:`~string.templatelib.Template`) with the given value. +The value may be approximated in the case of floating-point +and imaginary literals. + +The formal grammar for literals is: .. grammar-snippet:: :group: python-grammar literal: `strings` | `NUMBER` -Evaluation of a literal yields an object of the given type (string, bytes, -integer, floating-point number, complex number) with the given value. The value -may be approximated in the case of floating-point and imaginary (complex) -literals. -See section :ref:`literals` for details. -See section :ref:`string-concatenation` for details on ``strings``. - .. index:: triple: immutable; data; type pair: immutable; object +Literals and object identity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + All literals correspond to immutable data types, and hence the object's identity is less important than its value. Multiple evaluations of literals with the same value (either the same occurrence in the program text or a different occurrence) may obtain the same object or a different object with the same value. +.. admonition:: CPython implementation detail + + For example, in CPython, *small* integers with the same value evaluate + to the same object:: + + >>> x = 7 + >>> y = 7 + >>> x is y + True + + However, large integers evaluate to different objects:: + + >>> x = 123456789 + >>> y = 123456789 + >>> x is y + False + + This behavior may change in future versions of CPython. + In particular, the boundary between "small" and "large" integers has + already changed in the past. + + CPython will emit a :py:exc:`SyntaxWarning` when you compare literals + using ``is``:: + + >>> x = 7 + >>> x is 7 + :1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? + True + + See :ref:`faq-identity-with-is` for more information. + +:ref:`Template strings ` are immutable but may reference mutable +objects as :class:`~string.templatelib.Interpolation` values. +For the purposes of this section, two t-strings have the "same value" if +both their structure and the *identity* of the values match. + +.. impl-detail:: + + Currently, each evaluation of a template string results in + a different object. + .. _string-concatenation: String literal concatenation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Multiple adjacent string or bytes literals (delimited by whitespace), possibly +Multiple adjacent string or bytes literals, possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation:: >>> "hello" 'world' "helloworld" -Formally: - -.. grammar-snippet:: - :group: python-grammar - - strings: ( `STRING` | `fstring`)+ | `tstring`+ - This feature is defined at the syntactical level, so it only works with literals. To concatenate string expressions at run time, the '+' operator may be used:: @@ -208,6 +301,13 @@ string literals:: >>> t"Hello" t"{name}!" Template(strings=('Hello', '!'), interpolations=(...)) +Formally: + +.. grammar-snippet:: + :group: python-grammar + + strings: (`STRING` | `fstring`)+ | `tstring`+ + .. _parenthesized: @@ -1390,8 +1490,9 @@ for the operands): ``-1**2`` results in ``-1``. The power operator has the same semantics as the built-in :func:`pow` function, when called with two arguments: it yields its left argument raised to the power -of its right argument. The numeric arguments are first converted to a common -type, and the result is of that type. +of its right argument. +Numeric arguments are first :ref:`converted to a common type `, +and the result is of that type. For int operands, the result has the same type as the operands unless the second argument is negative; in that case, all arguments are converted to float and a @@ -1477,9 +1578,10 @@ operators and one for additive operators: The ``*`` (multiplication) operator yields the product of its arguments. The arguments must either both be numbers, or one argument must be an integer and -the other must be a sequence. In the former case, the numbers are converted to a -common real type and then multiplied together. In the latter case, sequence -repetition is performed; a negative repetition factor yields an empty sequence. +the other must be a sequence. In the former case, the numbers are +:ref:`converted to a common real type ` and then +multiplied together. In the latter case, sequence repetition is performed; +a negative repetition factor yields an empty sequence. This operation can be customized using the special :meth:`~object.__mul__` and :meth:`~object.__rmul__` methods. @@ -1507,7 +1609,8 @@ This operation can be customized using the special :meth:`~object.__matmul__` an pair: operator; // The ``/`` (division) and ``//`` (floor division) operators yield the quotient of -their arguments. The numeric arguments are first converted to a common type. +their arguments. The numeric arguments are first +:ref:`converted to a common type `. Division of integers yields a float, while floor division of integers results in an integer; the result is that of mathematical division with the 'floor' function applied to the result. Division by zero raises the :exc:`ZeroDivisionError` @@ -1523,8 +1626,9 @@ The floor division operation can be customized using the special pair: operator; % (percent) The ``%`` (modulo) operator yields the remainder from the division of the first -argument by the second. The numeric arguments are first converted to a common -type. A zero right argument raises the :exc:`ZeroDivisionError` exception. The +argument by the second. The numeric arguments are first +:ref:`converted to a common type `. +A zero right argument raises the :exc:`ZeroDivisionError` exception. The arguments may be floating-point numbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals ``4*0.7 + 0.34``.) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of @@ -1555,7 +1659,9 @@ floating-point number using the :func:`abs` function if appropriate. The ``+`` (addition) operator yields the sum of its arguments. The arguments must either both be numbers or both be sequences of the same type. In the -former case, the numbers are converted to a common real type and then added together. +former case, the numbers are +:ref:`converted to a common real type ` and then +added together. In the latter case, the sequences are concatenated. This operation can be customized using the special :meth:`~object.__add__` and @@ -1570,8 +1676,9 @@ This operation can be customized using the special :meth:`~object.__add__` and single: operator; - (minus) single: - (minus); binary operator -The ``-`` (subtraction) operator yields the difference of its arguments. The -numeric arguments are first converted to a common real type. +The ``-`` (subtraction) operator yields the difference of its arguments. +The numeric arguments are first +:ref:`converted to a common real type `. This operation can be customized using the special :meth:`~object.__sub__` and :meth:`~object.__rsub__` methods. From 1636630390883a5de0da26bef11da2bbf081badf Mon Sep 17 00:00:00 2001 From: Ruslan Gilfanov Date: Wed, 18 Feb 2026 18:17:08 +0500 Subject: [PATCH 146/498] gh-124748: Fix handling kwargs in `WeakKeyDictionary.update()` (#124783) --- Lib/test/test_weakref.py | 5 +++++ Lib/weakref.py | 6 ++++-- .../Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 47f6b46061ac30..b187643e84521c 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -1815,6 +1815,11 @@ def test_weak_valued_union_operators(self): def test_weak_keyed_dict_update(self): self.check_update(weakref.WeakKeyDictionary, {C(): 1, C(): 2, C(): 3}) + d = weakref.WeakKeyDictionary() + msg = ("Keyword arguments are not supported: " + "cannot create weak reference to 'str' object") + with self.assertRaisesRegex(TypeError, msg): + d.update(k='v') def test_weak_keyed_delitem(self): d = weakref.WeakKeyDictionary() diff --git a/Lib/weakref.py b/Lib/weakref.py index 94e4278143c987..af7244553c908c 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -408,14 +408,16 @@ def setdefault(self, key, default=None): return self.data.setdefault(ref(key, self._remove),default) def update(self, dict=None, /, **kwargs): + if kwargs: + msg = ("Keyword arguments are not supported: " + "cannot create weak reference to 'str' object") + raise TypeError(msg) d = self.data if dict is not None: if not hasattr(dict, "items"): dict = type({})(dict) for key, value in dict.items(): d[ref(key, self._remove)] = value - if len(kwargs): - self.update(kwargs) def __ior__(self, other): self.update(other) diff --git a/Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst b/Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst new file mode 100644 index 00000000000000..5067db357fc577 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst @@ -0,0 +1,2 @@ +Improve :exc:`TypeError` error message when :meth:`!weakref.WeakKeyDictionary.update` +is used with keyword-only parameters. From c6a142f9472f2d3e2c360b72a19450f9dd087657 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 18 Feb 2026 13:22:34 +0000 Subject: [PATCH 147/498] Datetime: Tidy up docs (GH-144720) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/CODEOWNERS | 1 + Doc/library/datetime-inheritance.dot | 31 ++++++ Doc/library/datetime-inheritance.svg | 84 +++++++++++++++ Doc/library/datetime.rst | 156 ++++++++++++++++----------- 4 files changed, 209 insertions(+), 63 deletions(-) create mode 100644 Doc/library/datetime-inheritance.dot create mode 100644 Doc/library/datetime-inheritance.svg diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b53c3cc1f465ff..dcebcbb434643f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -424,6 +424,7 @@ Lib/test/test_dataclasses/ @ericvsmith # Dates and times Doc/**/*time.rst @pganssle @abalkin +Doc/library/datetime-* @pganssle Doc/library/zoneinfo.rst @pganssle Include/datetime.h @pganssle @abalkin Include/internal/pycore_time.h @pganssle @abalkin diff --git a/Doc/library/datetime-inheritance.dot b/Doc/library/datetime-inheritance.dot new file mode 100644 index 00000000000000..3c6b9b4beb7ab1 --- /dev/null +++ b/Doc/library/datetime-inheritance.dot @@ -0,0 +1,31 @@ +// Used to generate datetime-inheritance.svg with Graphviz +// (https://graphviz.org/) for the datetime documentation. + +digraph { + comment="Generated with datetime-inheritance.dot" + graph [ + bgcolor="transparent" + fontnames="svg" + layout="dot" + ranksep=0.5 + nodesep=0.5 + splines=line + ] + node [ + fontname="Courier" + fontsize=14.0 + shape=box + style=rounded + margin="0.15,0.07" + ] + edge [ + arrowhead=none + ] + + object -> tzinfo + object -> timedelta + object -> time + object -> date + tzinfo -> timezone + date -> datetime +} diff --git a/Doc/library/datetime-inheritance.svg b/Doc/library/datetime-inheritance.svg new file mode 100644 index 00000000000000..e6b1cf877a574f --- /dev/null +++ b/Doc/library/datetime-inheritance.svg @@ -0,0 +1,84 @@ + + + + + + +datetime class hierarchy + + +object + +object + + + +tzinfo + +tzinfo + + + +object->tzinfo + + + + +timedelta + +timedelta + + + +object->timedelta + + + + +time + +time + + + +object->time + + + + +date + +date + + + +object->date + + + + +timezone + +timezone + + + +tzinfo->timezone + + + + +datetime + +datetime + + + +date->datetime + + + + diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 39a7a1530a95cc..b806a49e1be903 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -12,8 +12,6 @@ -------------- -.. XXX what order should the types be discussed in? - The :mod:`!datetime` module supplies classes for manipulating dates and times. While date and time arithmetic is supported, the focus of the implementation is @@ -38,13 +36,14 @@ on efficient attribute extraction for output formatting and manipulation. Third-party library with expanded time zone and parsing support. Package :pypi:`DateType` - Third-party library that introduces distinct static types to e.g. allow - :term:`static type checkers ` + Third-party library that introduces distinct static types to for example, + allow :term:`static type checkers ` to differentiate between naive and aware datetimes. + .. _datetime-naive-aware: -Aware and Naive Objects +Aware and naive objects ----------------------- Date and time objects may be categorized as "aware" or "naive" depending on @@ -77,6 +76,7 @@ detail is up to the application. The rules for time adjustment across the world are more political than rational, change frequently, and there is no standard suitable for every application aside from UTC. + Constants --------- @@ -93,13 +93,15 @@ The :mod:`!datetime` module exports the following constants: The largest year number allowed in a :class:`date` or :class:`.datetime` object. :const:`MAXYEAR` is 9999. + .. data:: UTC Alias for the UTC time zone singleton :attr:`datetime.timezone.utc`. .. versionadded:: 3.11 -Available Types + +Available types --------------- .. class:: date @@ -142,6 +144,7 @@ Available Types time adjustment (for example, to account for time zone and/or daylight saving time). + .. class:: timezone :noindex: @@ -150,19 +153,19 @@ Available Types .. versionadded:: 3.2 + Objects of these types are immutable. -Subclass relationships:: +Subclass relationships: + +.. figure:: datetime-inheritance.svg + :class: invert-in-dark-mode + :align: center + :alt: timedelta, tzinfo, time, and date inherit from object; timezone inherits + from tzinfo; and datetime inherits from date. - object - timedelta - tzinfo - timezone - time - date - datetime -Common Properties +Common properties ^^^^^^^^^^^^^^^^^ The :class:`date`, :class:`.datetime`, :class:`.time`, and :class:`timezone` types @@ -173,7 +176,8 @@ share these common features: dictionary keys. - Objects of these types support efficient pickling via the :mod:`pickle` module. -Determining if an Object is Aware or Naive + +Determining if an object is aware or naive ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Objects of the :class:`date` type are always naive. @@ -197,10 +201,11 @@ Otherwise, ``t`` is naive. The distinction between aware and naive doesn't apply to :class:`timedelta` objects. + .. _datetime-timedelta: -:class:`timedelta` Objects --------------------------- +:class:`!timedelta` objects +--------------------------- A :class:`timedelta` object represents a duration, the difference between two :class:`.datetime` or :class:`date` instances. @@ -296,6 +301,7 @@ Class attributes: The smallest possible difference between non-equal :class:`timedelta` objects, ``timedelta(microseconds=1)``. + Note that, because of normalization, ``timedelta.max`` is greater than ``-timedelta.min``. ``-timedelta.max`` is not representable as a :class:`timedelta` object. @@ -326,6 +332,7 @@ Instance attributes (read-only): >>> duration.total_seconds() 11235813.0 + .. attribute:: timedelta.microseconds Between 0 and 999,999 inclusive. @@ -333,8 +340,6 @@ Instance attributes (read-only): Supported operations: -.. XXX this table is too wide! - +--------------------------------+-----------------------------------------------+ | Operation | Result | +================================+===============================================+ @@ -396,7 +401,6 @@ Supported operations: | | call with canonical attribute values. | +--------------------------------+-----------------------------------------------+ - Notes: (1) @@ -447,15 +451,16 @@ Instance methods: Return the total number of seconds contained in the duration. Equivalent to ``td / timedelta(seconds=1)``. For interval units other than seconds, use the - division form directly (e.g. ``td / timedelta(microseconds=1)``). + division form directly (for example, ``td / timedelta(microseconds=1)``). Note that for very large time intervals (greater than 270 years on most platforms) this method will lose microsecond accuracy. .. versionadded:: 3.2 -Examples of usage: :class:`timedelta` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Examples of usage: :class:`!timedelta` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ An additional example of normalization:: @@ -485,10 +490,11 @@ Examples of :class:`timedelta` arithmetic:: >>> three_years, three_years.days // 365 (datetime.timedelta(days=1095), 3) + .. _datetime-date: -:class:`date` Objects ---------------------- +:class:`!date` objects +---------------------- A :class:`date` object represents a date (year, month and day) in an idealized calendar, the current Gregorian calendar indefinitely extended in both @@ -517,9 +523,10 @@ Other constructors, all class methods: This is equivalent to ``date.fromtimestamp(time.time())``. + .. classmethod:: date.fromtimestamp(timestamp) - Return the local date corresponding to the POSIX timestamp, such as is + Return the local date corresponding to the POSIX *timestamp*, such as is returned by :func:`time.time`. This may raise :exc:`OverflowError`, if the timestamp is out @@ -541,7 +548,7 @@ Other constructors, all class methods: .. classmethod:: date.fromordinal(ordinal) - Return the date corresponding to the proleptic Gregorian ordinal, where + Return the date corresponding to the proleptic Gregorian *ordinal*, where January 1 of year 1 has ordinal 1. :exc:`ValueError` is raised unless ``1 <= ordinal <= @@ -574,13 +581,15 @@ Other constructors, all class methods: .. versionchanged:: 3.11 Previously, this method only supported the format ``YYYY-MM-DD``. + .. classmethod:: date.fromisocalendar(year, week, day) Return a :class:`date` corresponding to the ISO calendar date specified by - year, week and day. This is the inverse of the function :meth:`date.isocalendar`. + *year*, *week* and *day*. This is the inverse of the function :meth:`date.isocalendar`. .. versionadded:: 3.8 + .. classmethod:: date.strptime(date_string, format) Return a :class:`.date` corresponding to *date_string*, parsed according to @@ -791,6 +800,7 @@ Instance methods: .. versionchanged:: 3.9 Result changed from a tuple to a :term:`named tuple`. + .. method:: date.isoformat() Return a string representing the date in ISO 8601 format, ``YYYY-MM-DD``:: @@ -799,6 +809,7 @@ Instance methods: >>> date(2002, 12, 4).isoformat() '2002-12-04' + .. method:: date.__str__() For a date ``d``, ``str(d)`` is equivalent to ``d.isoformat()``. @@ -835,8 +846,9 @@ Instance methods: literals ` and when using :meth:`str.format`. See also :ref:`strftime-strptime-behavior` and :meth:`date.isoformat`. -Examples of Usage: :class:`date` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Examples of usage: :class:`!date` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Example of counting days to an event:: @@ -878,7 +890,7 @@ More examples of working with :class:`date`: >>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month") 'The day is 11, the month is March.' - >>> # Methods for to extracting 'components' under different calendars + >>> # Methods for extracting 'components' under different calendars >>> t = d.timetuple() >>> for i in t: # doctest: +SKIP ... print(i) @@ -905,7 +917,7 @@ More examples of working with :class:`date`: .. _datetime-datetime: -:class:`.datetime` Objects +:class:`!datetime` objects -------------------------- A :class:`.datetime` object is a single object containing all the information @@ -937,6 +949,7 @@ Constructor: .. versionchanged:: 3.6 Added the *fold* parameter. + Other constructors, all class methods: .. classmethod:: datetime.today() @@ -952,6 +965,7 @@ Other constructors, all class methods: This method is functionally equivalent to :meth:`now`, but without a ``tz`` parameter. + .. classmethod:: datetime.now(tz=None) Return the current local date and time. @@ -972,6 +986,7 @@ Other constructors, all class methods: Subsequent calls to :meth:`!datetime.now` may return the same instant depending on the precision of the underlying clock. + .. classmethod:: datetime.utcnow() Return the current UTC date and time, with :attr:`.tzinfo` ``None``. @@ -1063,13 +1078,13 @@ Other constructors, all class methods: :c:func:`gmtime` function. Raise :exc:`OSError` instead of :exc:`ValueError` on :c:func:`gmtime` failure. + .. versionchanged:: 3.15 + Accepts any real number as *timestamp*, not only integer or float. + .. deprecated:: 3.12 Use :meth:`datetime.fromtimestamp` with :const:`UTC` instead. - .. versionchanged:: 3.15 - Accepts any real number as *timestamp*, not only integer or float. - .. classmethod:: datetime.fromordinal(ordinal) @@ -1142,12 +1157,13 @@ Other constructors, all class methods: .. classmethod:: datetime.fromisocalendar(year, week, day) Return a :class:`.datetime` corresponding to the ISO calendar date specified - by year, week and day. The non-date components of the datetime are populated + by *year*, *week* and *day*. The non-date components of the datetime are populated with their normal default values. This is the inverse of the function :meth:`datetime.isocalendar`. .. versionadded:: 3.8 + .. classmethod:: datetime.strptime(date_string, format) Return a :class:`.datetime` corresponding to *date_string*, parsed according to @@ -1255,6 +1271,7 @@ Instance attributes (read-only): .. versionadded:: 3.6 + Supported operations: +---------------------------------------+--------------------------------+ @@ -1345,6 +1362,7 @@ Supported operations: The default behavior can be changed by overriding the special comparison methods in subclasses. + Instance methods: .. method:: datetime.date() @@ -1500,11 +1518,13 @@ Instance methods: ``datetime.replace(tzinfo=timezone.utc)`` to make it aware, at which point you can use :meth:`.datetime.timetuple`. + .. method:: datetime.toordinal() Return the proleptic Gregorian ordinal of the date. The same as ``self.date().toordinal()``. + .. method:: datetime.timestamp() Return POSIX timestamp corresponding to the :class:`.datetime` @@ -1523,16 +1543,6 @@ Instance methods: (dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds() - .. versionadded:: 3.3 - - .. versionchanged:: 3.6 - The :meth:`timestamp` method uses the :attr:`.fold` attribute to - disambiguate the times during a repeated interval. - - .. versionchanged:: 3.6 - This method no longer relies on the platform C :c:func:`mktime` - function to perform conversions. - .. note:: There is no method to obtain the POSIX timestamp directly from a @@ -1547,6 +1557,17 @@ Instance methods: timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1) + .. versionadded:: 3.3 + + .. versionchanged:: 3.6 + The :meth:`timestamp` method uses the :attr:`.fold` attribute to + disambiguate the times during a repeated interval. + + .. versionchanged:: 3.6 + This method no longer relies on the platform C :c:func:`mktime` + function to perform conversions. + + .. method:: datetime.weekday() Return the day of the week as an integer, where Monday is 0 and Sunday is 6. @@ -1675,7 +1696,7 @@ Instance methods: See also :ref:`strftime-strptime-behavior` and :meth:`datetime.isoformat`. -Examples of Usage: :class:`.datetime` +Examples of usage: :class:`!datetime` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Examples of working with :class:`.datetime` objects: @@ -1801,9 +1822,10 @@ Usage of ``KabulTz`` from above:: >>> dt2 == dt3 True + .. _datetime-time: -:class:`.time` Objects +:class:`!time` objects ---------------------- A :class:`.time` object represents a (local) time of day, independent of any particular @@ -1824,6 +1846,7 @@ day, and subject to adjustment via a :class:`tzinfo` object. If an argument outside those ranges is given, :exc:`ValueError` is raised. All default to 0 except *tzinfo*, which defaults to ``None``. + Class attributes: @@ -1882,6 +1905,7 @@ Instance attributes (read-only): .. versionadded:: 3.6 + :class:`.time` objects support equality and order comparisons, where ``a`` is considered less than ``b`` when ``a`` precedes ``b`` in time. @@ -1904,8 +1928,8 @@ In Boolean contexts, a :class:`.time` object is always considered to be true. .. versionchanged:: 3.5 Before Python 3.5, a :class:`.time` object was considered to be false if it represented midnight in UTC. This behavior was considered obscure and - error-prone and has been removed in Python 3.5. See :issue:`13936` for full - details. + error-prone and has been removed in Python 3.5. See :issue:`13936` for more + information. Other constructors: @@ -1950,6 +1974,7 @@ Other constructors: Previously, this method only supported formats that could be emitted by :meth:`time.isoformat`. + .. classmethod:: time.strptime(date_string, format) Return a :class:`.time` corresponding to *date_string*, parsed according to @@ -2066,13 +2091,15 @@ Instance methods: .. versionchanged:: 3.7 The DST offset is not restricted to a whole number of minutes. + .. method:: time.tzname() If :attr:`.tzinfo` is ``None``, returns ``None``, else returns ``self.tzinfo.tzname(None)``, or raises an exception if the latter doesn't return ``None`` or a string object. -Examples of Usage: :class:`.time` + +Examples of usage: :class:`!time` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Examples of working with a :class:`.time` object:: @@ -2105,12 +2132,12 @@ Examples of working with a :class:`.time` object:: .. _datetime-tzinfo: -:class:`tzinfo` Objects ------------------------ +:class:`!tzinfo` objects +------------------------ .. class:: tzinfo() - This is an abstract base class, meaning that this class should not be + This is an :term:`abstract base class`, meaning that this class should not be instantiated directly. Define a subclass of :class:`tzinfo` to capture information about a particular time zone. @@ -2381,8 +2408,8 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). .. _datetime-timezone: -:class:`timezone` Objects -------------------------- +:class:`!timezone` objects +-------------------------- The :class:`timezone` class is a subclass of :class:`tzinfo`, each instance of which represents a time zone defined by a fixed offset from @@ -2420,6 +2447,7 @@ where historical changes have been made to civil time. .. versionchanged:: 3.7 The UTC offset is not restricted to a whole number of minutes. + .. method:: timezone.tzname(dt) Return the fixed value specified when the :class:`timezone` instance @@ -2440,11 +2468,13 @@ where historical changes have been made to civil time. Always returns ``None``. + .. method:: timezone.fromutc(dt) Return ``dt + offset``. The *dt* argument must be an aware :class:`.datetime` instance, with ``tzinfo`` set to ``self``. + Class attributes: .. attribute:: timezone.utc @@ -2457,8 +2487,8 @@ Class attributes: .. _strftime-strptime-behavior: -:meth:`~.datetime.strftime` and :meth:`~.datetime.strptime` Behavior --------------------------------------------------------------------- +:meth:`!strftime` and :meth:`!strptime` behavior +------------------------------------------------ :class:`date`, :class:`.datetime`, and :class:`.time` objects all support a ``strftime(format)`` method, to create a string representing the time under the @@ -2484,8 +2514,8 @@ versus :meth:`~.datetime.strptime`: .. _format-codes: -:meth:`~.datetime.strftime` and :meth:`~.datetime.strptime` Format Codes -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:meth:`!strftime` and :meth:`!strptime` format codes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These methods accept format codes that can be used to parse and format dates:: @@ -2678,7 +2708,8 @@ differences between platforms in handling of unsupported format specifiers. .. versionadded:: 3.15 ``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`. -Technical Detail + +Technical detail ^^^^^^^^^^^^^^^^ Broadly speaking, ``d.strftime(fmt)`` acts like the :mod:`time` module's @@ -2701,7 +2732,6 @@ in the format string will be pulled from the default value. the default year of 1900 is *not* a leap year. Always add a default leap year to partial date strings before parsing. - .. testsetup:: # doctest seems to turn the warning into an error which makes it From f705486745e5907190f1ace76fd08f492be09e68 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Feb 2026 15:25:47 +0100 Subject: [PATCH 148/498] gh-141510: Add frozendict fast-path to the set type (#144912) --- Lib/test/test_set.py | 13 ++++++++++++- Objects/setobject.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 554716aed1e98b..9bfd4bc7d63669 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -188,7 +188,10 @@ def test_symmetric_difference(self): self.assertEqual(type(i), self.basetype) self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru()) self.assertRaises(TypeError, self.s.symmetric_difference, [[]]) - for C in set, frozenset, dict.fromkeys, str, list, tuple: + constructors = (set, frozenset, + dict.fromkeys, frozendict.fromkeys, + str, list, tuple) + for C in constructors: self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd')) self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg')) self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a')) @@ -1591,6 +1594,14 @@ def setUp(self): #------------------------------------------------------------------------------ +class TestOnlySetsFrozenDict(TestOnlySetsInBinaryOps, unittest.TestCase): + def setUp(self): + self.set = set((1, 2, 3)) + self.other = frozendict({1:2, 3:4}) + self.otherIsIterable = True + +#------------------------------------------------------------------------------ + class TestOnlySetsOperator(TestOnlySetsInBinaryOps, unittest.TestCase): def setUp(self): self.set = set((1, 2, 3)) diff --git a/Objects/setobject.c b/Objects/setobject.c index f8713bf3d1a432..ae6c1d1248d2fc 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1186,10 +1186,14 @@ set_iter(PyObject *so) static int set_update_dict_lock_held(PySetObject *so, PyObject *other) { - assert(PyDict_CheckExact(other)); + assert(PyAnyDict_CheckExact(other)); _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so); - _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other); +#ifdef Py_DEBUG + if (!PyFrozenDict_CheckExact(other)) { + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other); + } +#endif /* Do one big resize at the start, rather than * incrementally resizing as we insert new keys. Expect @@ -1245,7 +1249,7 @@ set_update_lock_held(PySetObject *so, PyObject *other) if (PyAnySet_Check(other)) { return set_merge_lock_held(so, other); } - else if (PyDict_CheckExact(other)) { + else if (PyAnyDict_CheckExact(other)) { return set_update_dict_lock_held(so, other); } return set_update_iterable_lock_held(so, other); @@ -1270,6 +1274,9 @@ set_update_local(PySetObject *so, PyObject *other) Py_END_CRITICAL_SECTION(); return rv; } + else if (PyFrozenDict_CheckExact(other)) { + return set_update_dict_lock_held(so, other); + } return set_update_iterable_lock_held(so, other); } @@ -1293,6 +1300,13 @@ set_update_internal(PySetObject *so, PyObject *other) Py_END_CRITICAL_SECTION2(); return rv; } + else if (PyFrozenDict_CheckExact(other)) { + int rv; + Py_BEGIN_CRITICAL_SECTION(so); + rv = set_update_dict_lock_held(so, other); + Py_END_CRITICAL_SECTION(); + return rv; + } else { int rv; Py_BEGIN_CRITICAL_SECTION(so); @@ -2033,7 +2047,7 @@ set_difference(PySetObject *so, PyObject *other) if (PyAnySet_Check(other)) { other_size = PySet_GET_SIZE(other); } - else if (PyDict_CheckExact(other)) { + else if (PyAnyDict_CheckExact(other)) { other_size = PyDict_GET_SIZE(other); } else { @@ -2050,7 +2064,7 @@ set_difference(PySetObject *so, PyObject *other) if (result == NULL) return NULL; - if (PyDict_CheckExact(other)) { + if (PyAnyDict_CheckExact(other)) { while (set_next(so, &pos, &entry)) { key = entry->key; hash = entry->hash; @@ -2172,7 +2186,11 @@ static int set_symmetric_difference_update_dict(PySetObject *so, PyObject *other) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so); - _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other); +#ifdef Py_DEBUG + if (!PyFrozenDict_CheckExact(other)) { + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other); + } +#endif Py_ssize_t pos = 0; PyObject *key, *value; @@ -2246,6 +2264,11 @@ set_symmetric_difference_update_impl(PySetObject *so, PyObject *other) rv = set_symmetric_difference_update_dict(so, other); Py_END_CRITICAL_SECTION2(); } + else if (PyFrozenDict_CheckExact(other)) { + Py_BEGIN_CRITICAL_SECTION(so); + rv = set_symmetric_difference_update_dict(so, other); + Py_END_CRITICAL_SECTION(); + } else if (PyAnySet_Check(other)) { Py_BEGIN_CRITICAL_SECTION2(so, other); rv = set_symmetric_difference_update_set(so, (PySetObject *)other); From 1ddb41268997938d5f416e1ac98ae39cc3e81535 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Feb 2026 15:47:49 +0100 Subject: [PATCH 149/498] gh-141510: Add can_modify_dict() in dictobject.c (#144955) can_modify_dict() is stricter than ASSERT_DICT_LOCKED() for frozendict. It uses PyUnstable_Object_IsUniquelyReferenced() which matters for free-threaded builds. Replace anydict_setitem_take2() with setitem_take2_lock_held(). It's no longer useful to have two functions. --- Objects/dictobject.c | 102 +++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 0959e2c78a3289..68602caf61401a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -282,6 +282,24 @@ load_keys_nentries(PyDictObject *mp) #endif +#ifndef NDEBUG +// Check if it's possible to modify a dictionary. +// Usage: assert(can_modify_dict(mp)). +static inline int +can_modify_dict(PyDictObject *mp) +{ + if (PyFrozenDict_Check(mp)) { + // No locking required to modify a newly created frozendict + // since it's only accessible from the current thread. + return PyUnstable_Object_IsUniquelyReferenced(_PyObject_CAST(mp)); + } + else { + ASSERT_DICT_LOCKED(mp); + return 1; + } +} +#endif + #define _PyAnyDict_CAST(op) \ (assert(PyAnyDict_Check(op)), _Py_CAST(PyDictObject*, op)) @@ -1867,8 +1885,9 @@ insert_split_key(PyDictKeysObject *keys, PyObject *key, Py_hash_t hash) static void insert_split_value(PyDictObject *mp, PyObject *key, PyObject *value, Py_ssize_t ix) { + assert(can_modify_dict(mp)); assert(PyUnicode_CheckExact(key)); - ASSERT_DICT_LOCKED(mp); + PyObject *old_value = mp->ma_values->values[ix]; if (old_value == NULL) { _PyDict_NotifyEvent(PyDict_EVENT_ADDED, mp, key, value); @@ -1896,11 +1915,11 @@ static int insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { + assert(can_modify_dict(mp)); + PyObject *old_value = NULL; Py_ssize_t ix; - ASSERT_DICT_LOCKED(mp); - if (_PyDict_HasSplitTable(mp) && PyUnicode_CheckExact(key)) { ix = insert_split_key(mp->ma_keys, key, hash); if (ix != DKIX_EMPTY) { @@ -1967,8 +1986,8 @@ static int insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { + assert(can_modify_dict(mp)); assert(mp->ma_keys == Py_EMPTY_KEYS); - ASSERT_DICT_LOCKED(mp); int unicode = PyUnicode_CheckExact(key); PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE, unicode); @@ -2069,11 +2088,11 @@ static int dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) { + assert(can_modify_dict(mp)); + PyDictKeysObject *oldkeys, *newkeys; PyDictValues *oldvalues; - ASSERT_DICT_LOCKED(mp); - if (log2_newsize >= SIZEOF_SIZE_T*8) { PyErr_NoMemory(); return -1; @@ -2671,11 +2690,13 @@ _PyDict_LoadBuiltinsFromGlobals(PyObject *globals) /* Consumes references to key and value */ static int -anydict_setitem_take2(PyDictObject *mp, PyObject *key, PyObject *value) +setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) { + assert(PyAnyDict_Check(mp)); + assert(can_modify_dict(mp)); assert(key); assert(value); - assert(PyAnyDict_Check(mp)); + Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { dict_unhashable_type(key); @@ -2691,14 +2712,6 @@ anydict_setitem_take2(PyDictObject *mp, PyObject *key, PyObject *value) return insertdict(mp, key, hash, value); } -/* Consumes references to key and value */ -static int -setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) -{ - ASSERT_DICT_LOCKED(mp); - return anydict_setitem_take2(mp, key, value); -} - int _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) { @@ -2800,9 +2813,9 @@ static void delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, PyObject *old_value) { - PyObject *old_key; + assert(can_modify_dict(mp)); - ASSERT_DICT_LOCKED(mp); + PyObject *old_key; Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); @@ -2856,19 +2869,17 @@ int _PyDict_DelItem_KnownHash_LockHeld(PyObject *op, PyObject *key, Py_hash_t hash) { Py_ssize_t ix; - PyDictObject *mp; PyObject *old_value; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return -1; } - - ASSERT_DICT_LOCKED(op); + PyDictObject *mp = (PyDictObject *)op; + assert(can_modify_dict(mp)); assert(key); assert(hash != -1); - mp = (PyDictObject *)op; ix = _Py_dict_lookup(mp, key, hash, &old_value); if (ix == DKIX_ERROR) return -1; @@ -2897,19 +2908,18 @@ delitemif_lock_held(PyObject *op, PyObject *key, int (*predicate)(PyObject *value, void *arg), void *arg) { + PyDictObject *mp = _PyAnyDict_CAST(op); + assert(can_modify_dict(mp)); + Py_ssize_t ix; - PyDictObject *mp; Py_hash_t hash; PyObject *old_value; int res; - ASSERT_DICT_LOCKED(op); - assert(key); hash = PyObject_Hash(key); if (hash == -1) return -1; - mp = (PyDictObject *)op; ix = _Py_dict_lookup(mp, key, hash, &old_value); if (ix == DKIX_ERROR) { return -1; @@ -2951,16 +2961,16 @@ _PyDict_DelItemIf(PyObject *op, PyObject *key, static void clear_lock_held(PyObject *op) { - PyDictObject *mp; + if (!PyDict_Check(op)) { + return; + } + PyDictObject *mp = (PyDictObject *)op; + assert(can_modify_dict(mp)); + PyDictKeysObject *oldkeys; PyDictValues *oldvalues; Py_ssize_t i, n; - ASSERT_DICT_LOCKED(op); - - if (!PyDict_Check(op)) - return; - mp = ((PyDictObject *)op); oldkeys = mp->ma_keys; oldvalues = mp->ma_values; if (oldkeys == Py_EMPTY_KEYS) { @@ -3106,8 +3116,7 @@ _PyDict_Pop_KnownHash(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **result) { assert(PyDict_Check(mp)); - - ASSERT_DICT_LOCKED(mp); + assert(can_modify_dict(mp)); if (mp->ma_used == 0) { if (result) { @@ -3149,8 +3158,6 @@ _PyDict_Pop_KnownHash(PyDictObject *mp, PyObject *key, Py_hash_t hash, static int pop_lock_held(PyObject *op, PyObject *key, PyObject **result) { - ASSERT_DICT_LOCKED(op); - if (!PyDict_Check(op)) { if (result) { *result = NULL; @@ -3159,6 +3166,7 @@ pop_lock_held(PyObject *op, PyObject *key, PyObject **result) return -1; } PyDictObject *dict = (PyDictObject *)op; + assert(can_modify_dict(dict)); if (dict->ma_used == 0) { if (result) { @@ -3361,9 +3369,9 @@ dict_iter_exit:; } else if (PyFrozenDict_CheckExact(d)) { while ((key = PyIter_Next(it)) != NULL) { - // anydict_setitem_take2 consumes a reference to key - status = anydict_setitem_take2((PyDictObject *)d, - key, Py_NewRef(value)); + // setitem_take2_lock_held consumes a reference to key + status = setitem_take2_lock_held((PyDictObject *)d, + key, Py_NewRef(value)); if (status < 0) { assert(PyErr_Occurred()); goto Fail; @@ -3933,7 +3941,7 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) static int dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override) { - ASSERT_DICT_LOCKED(mp); + assert(can_modify_dict(mp)); ASSERT_DICT_LOCKED(other); if (other == mp || other->ma_used == 0) @@ -4474,8 +4482,6 @@ dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_valu Py_hash_t hash; Py_ssize_t ix; - ASSERT_DICT_LOCKED(d); - if (!PyDict_Check(d)) { PyErr_BadInternalCall(); if (result) { @@ -4483,6 +4489,7 @@ dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_valu } return -1; } + assert(can_modify_dict((PyDictObject*)d)); hash = _PyObject_HashFast(key); if (hash == -1) { @@ -4657,11 +4664,11 @@ static PyObject * dict_popitem_impl(PyDictObject *self) /*[clinic end generated code: output=e65fcb04420d230d input=ef28b4da5f0f762e]*/ { + assert(can_modify_dict(self)); + Py_ssize_t i, j; PyObject *res; - ASSERT_DICT_LOCKED(self); - /* Allocate the result tuple before checking the size. Believe it * or not, this allocation could trigger a garbage collection which * could empty the dict, so if we checked the size first and that @@ -4799,11 +4806,12 @@ _PyDict_SizeOf_LockHeld(PyDictObject *mp) } void -_PyDict_ClearKeysVersionLockHeld(PyObject *mp) +_PyDict_ClearKeysVersionLockHeld(PyObject *op) { - ASSERT_DICT_LOCKED(mp); + PyDictObject *mp = _PyAnyDict_CAST(op); + assert(can_modify_dict(mp)); - FT_ATOMIC_STORE_UINT32_RELAXED(((PyDictObject *)mp)->ma_keys->dk_version, 0); + FT_ATOMIC_STORE_UINT32_RELAXED(mp->ma_keys->dk_version, 0); } Py_ssize_t From c582ff3c2508a8b1164ed861e4f304ba6a782546 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Feb 2026 16:56:09 +0100 Subject: [PATCH 150/498] gh-141510: Fix frozendict.fromkeys() for subclasses (#144952) Copy the frozendict if needed. --- Lib/test/test_dict.py | 28 ++++++++++++++++++++++++++++ Objects/dictobject.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 21f8bb11071c90..1a8ae1cd42356e 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1787,6 +1787,34 @@ def test_hash(self): with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"): hash(fd) + def test_fromkeys(self): + self.assertEqual(frozendict.fromkeys('abc'), + frozendict(a=None, b=None, c=None)) + + # Subclass which overrides the constructor + created = frozendict(x=1) + class FrozenDictSubclass(frozendict): + def __new__(self): + return created + + fd = FrozenDictSubclass.fromkeys("abc") + self.assertEqual(fd, frozendict(x=1, a=None, b=None, c=None)) + self.assertEqual(type(fd), FrozenDictSubclass) + self.assertEqual(created, frozendict(x=1)) + + fd = FrozenDictSubclass.fromkeys(frozendict(y=2)) + self.assertEqual(fd, frozendict(x=1, y=None)) + self.assertEqual(type(fd), FrozenDictSubclass) + self.assertEqual(created, frozendict(x=1)) + + # Subclass which doesn't override the constructor + class FrozenDictSubclass2(frozendict): + pass + + fd = FrozenDictSubclass2.fromkeys("abc") + self.assertEqual(fd, frozendict(a=None, b=None, c=None)) + self.assertEqual(type(fd), FrozenDictSubclass2) + if __name__ == "__main__": unittest.main() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 68602caf61401a..8d3c34f87e2afe 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -138,6 +138,7 @@ As a consequence of this, split keys have a maximum size of 16. // Forward declarations static PyObject* frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static int dict_merge(PyObject *a, PyObject *b, int override); /*[clinic input] @@ -294,6 +295,8 @@ can_modify_dict(PyDictObject *mp) return PyUnstable_Object_IsUniquelyReferenced(_PyObject_CAST(mp)); } else { + // Locking is only required if the dictionary is not + // uniquely referenced. ASSERT_DICT_LOCKED(mp); return 1; } @@ -3238,6 +3241,8 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value) static PyDictObject * dict_dict_fromkeys(PyDictObject *mp, PyObject *iterable, PyObject *value) { + assert(can_modify_dict(mp)); + PyObject *oldvalue; Py_ssize_t pos = 0; PyObject *key; @@ -3263,6 +3268,8 @@ dict_dict_fromkeys(PyDictObject *mp, PyObject *iterable, PyObject *value) static PyDictObject * dict_set_fromkeys(PyDictObject *mp, PyObject *iterable, PyObject *value) { + assert(can_modify_dict(mp)); + Py_ssize_t pos = 0; PyObject *key; Py_hash_t hash; @@ -3294,9 +3301,31 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) int status; d = _PyObject_CallNoArgs(cls); - if (d == NULL) + if (d == NULL) { return NULL; + } + // If cls is a frozendict subclass with overridden constructor, + // copy the frozendict. + PyTypeObject *cls_type = _PyType_CAST(cls); + if (PyFrozenDict_Check(d) + && PyObject_IsSubclass(cls, (PyObject*)&PyFrozenDict_Type) + && cls_type->tp_new != frozendict_new) + { + // Subclass-friendly copy + PyObject *copy = frozendict_new(cls_type, NULL, NULL); + if (copy == NULL) { + Py_DECREF(d); + return NULL; + } + if (dict_merge(copy, d, 1) < 0) { + Py_DECREF(d); + Py_DECREF(copy); + return NULL; + } + Py_SETREF(d, copy); + } + assert(!PyFrozenDict_Check(d) || can_modify_dict((PyDictObject*)d)); if (PyDict_CheckExact(d)) { if (PyDict_CheckExact(iterable)) { @@ -3367,7 +3396,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) dict_iter_exit:; Py_END_CRITICAL_SECTION(); } - else if (PyFrozenDict_CheckExact(d)) { + else if (PyFrozenDict_Check(d)) { while ((key = PyIter_Next(it)) != NULL) { // setitem_take2_lock_held consumes a reference to key status = setitem_take2_lock_held((PyDictObject *)d, @@ -8002,6 +8031,8 @@ frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (d == NULL) { return NULL; } + assert(can_modify_dict(_PyAnyDict_CAST(d))); + PyFrozenDictObject *self = _PyFrozenDictObject_CAST(d); self->ma_hash = -1; From 83f4fffe3d78ba368c0d4864c42c7c9c9223f7d1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Feb 2026 16:57:48 +0100 Subject: [PATCH 151/498] gh-144763: Don't detach the GIL in tracemalloc (#144779) tracemalloc no longer detaches the GIL to acquire its internal lock. Co-authored-by: Kumar Aditya --- ...-02-13-11-14-18.gh-issue-144763.cDwnEE.rst | 2 ++ Python/tracemalloc.c | 24 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst b/Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst new file mode 100644 index 00000000000000..14eb4f49c8ad3c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst @@ -0,0 +1,2 @@ +Fix a race condition in :mod:`tracemalloc`: it no longer detaches the attached +thread state to acquire its internal lock. Patch by Victor Stinner. diff --git a/Python/tracemalloc.c b/Python/tracemalloc.c index cdd96925d1f27a..0afc84e021817c 100644 --- a/Python/tracemalloc.c +++ b/Python/tracemalloc.c @@ -36,7 +36,7 @@ static int _PyTraceMalloc_TraceRef(PyObject *op, PyRefTracerEvent event, the GIL held from PyMem_RawFree(). It cannot acquire the lock because it would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ #define tables_lock _PyRuntime.tracemalloc.tables_lock -#define TABLES_LOCK() PyMutex_Lock(&tables_lock) +#define TABLES_LOCK() PyMutex_LockFlags(&tables_lock, _Py_LOCK_DONT_DETACH) #define TABLES_UNLOCK() PyMutex_Unlock(&tables_lock) @@ -224,13 +224,20 @@ tracemalloc_get_frame(_PyInterpreterFrame *pyframe, frame_t *frame) assert(PyStackRef_CodeCheck(pyframe->f_executable)); frame->filename = &_Py_STR(anon_unknown); - int lineno = PyUnstable_InterpreterFrame_GetLine(pyframe); + int lineno = -1; + PyCodeObject *code = _PyFrame_GetCode(pyframe); + // PyUnstable_InterpreterFrame_GetLine() cannot but used, since it uses + // a critical section which can trigger a deadlock. + int lasti = _PyFrame_SafeGetLasti(pyframe); + if (lasti >= 0) { + lineno = _PyCode_SafeAddr2Line(code, lasti); + } if (lineno < 0) { lineno = 0; } frame->lineno = (unsigned int)lineno; - PyObject *filename = _PyFrame_GetCode(pyframe)->co_filename; + PyObject *filename = code->co_filename; if (filename == NULL) { #ifdef TRACE_DEBUG tracemalloc_error("failed to get the filename of the code object"); @@ -863,7 +870,8 @@ _PyTraceMalloc_Stop(void) TABLES_LOCK(); if (!tracemalloc_config.tracing) { - goto done; + TABLES_UNLOCK(); + return; } /* stop tracing Python memory allocations */ @@ -880,10 +888,12 @@ _PyTraceMalloc_Stop(void) raw_free(tracemalloc_traceback); tracemalloc_traceback = NULL; - (void)PyRefTracer_SetTracer(NULL, NULL); - -done: TABLES_UNLOCK(); + + // Call it after TABLES_UNLOCK() since it calls _PyEval_StopTheWorldAll() + // which would lead to a deadlock with TABLES_LOCK() which doesn't detach + // the thread state. + (void)PyRefTracer_SetTracer(NULL, NULL); } From a18e0fa4c045e9ffc9d566b173c72fa3f6fc2252 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 Feb 2026 18:02:12 +0200 Subject: [PATCH 152/498] gh-135573: Add tests for pickle opcodes with wrong types (GH-144950) Ensure that APPENDS and ADDITEMS raise error for wrong collection even with empty items. --- Lib/test/pickletester.py | 23 +++++++++++++++++++++++ Modules/_pickle.c | 6 ------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index c4460c2e44d578..3d4ed8a2b6ee40 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -1484,6 +1484,29 @@ def __hash__(self): # bad hashable dict key self.check_unpickling_error(CustomError, base + b'}c__main__\nBadKey1\n)\x81Nsb.') + def test_bad_types(self): + # APPEND + self.assertEqual(self.loads(b']Na.'), [None]) + self.check_unpickling_error(AttributeError, b'NNa.') # non-list + # APPENDS + self.assertEqual(self.loads(b'](Ne.'), [None]) + self.check_unpickling_error(AttributeError, b'N(Ne.') # non-list + self.check_unpickling_error(AttributeError, b'N(e.') + # SETITEM + self.assertEqual(self.loads(b'}NNs.'), {None: None}) + self.check_unpickling_error(TypeError, b'NNNs.') # non-dict + self.check_unpickling_error(TypeError, b'}]Ns.') # non-hashable key + # SETITEMS + self.assertEqual(self.loads(b'}(NNu.'), {None: None}) + self.check_unpickling_error(TypeError, b'N(NNu.') # non-dict + self.assertEqual(self.loads(b'N(u.'), None) # no validation for empty items + self.check_unpickling_error(TypeError, b'}(]Nu.') # non-hashable key + # ADDITEMS + self.assertEqual(self.loads(b'\x8f(N\x90.'), {None}) + self.check_unpickling_error(AttributeError, b'N(N\x90.') # non-set + self.check_unpickling_error(AttributeError, b'N(\x90.') + self.check_unpickling_error(TypeError, b'\x8f(]\x90.') # non-hashable element + def test_bad_stack(self): badpickles = [ b'.', # STOP diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 24d3443dd8abfe..65facaa6db2036 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -6663,8 +6663,6 @@ do_append(PickleState *state, UnpicklerObject *self, Py_ssize_t x) len = Py_SIZE(self->stack); if (x > len || x <= self->stack->fence) return Pdata_stack_underflow(state, self->stack); - if (len == x) /* nothing to do */ - return 0; list = self->stack->data[x - 1]; @@ -6754,8 +6752,6 @@ do_setitems(PickleState *st, UnpicklerObject *self, Py_ssize_t x) len = Py_SIZE(self->stack); if (x > len || x <= self->stack->fence) return Pdata_stack_underflow(st, self->stack); - if (len == x) /* nothing to do */ - return 0; if ((len - x) % 2 != 0) { /* Corrupt or hostile pickle -- we never write one like this. */ PyErr_SetString(st->UnpicklingError, @@ -6807,8 +6803,6 @@ load_additems(PickleState *state, UnpicklerObject *self) len = Py_SIZE(self->stack); if (mark > len || mark <= self->stack->fence) return Pdata_stack_underflow(state, self->stack); - if (len == mark) /* nothing to do */ - return 0; set = self->stack->data[mark - 1]; From 3e2f5c133f37f13f627404f3cbd54a5fc163887a Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 19 Feb 2026 01:10:53 +0900 Subject: [PATCH 153/498] gh-141510: Update specializer to support frozendict (gh-144949) --- Include/internal/pycore_interp_structs.h | 2 +- Lib/test/test_opcache.py | 42 +++++++++++++++++++ ...-02-18-21-44-39.gh-issue-141510.7LST2O.rst | 1 + Modules/_testinternalcapi/test_cases.c.h | 10 ++--- Python/bytecodes.c | 8 ++-- Python/executor_cases.c.h | 20 ++++----- Python/generated_cases.c.h | 10 ++--- Python/specialize.c | 4 +- 8 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 3ebc8967c3dc7f..1e69c64bcd1fc0 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -496,7 +496,7 @@ struct _py_func_state { /* For now we hard-code this to a value for which we are confident all the static builtin types will fit (for all builds). */ -#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 200 +#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 201 #define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10 #define _Py_MAX_MANAGED_STATIC_TYPES \ (_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES + _Py_MAX_MANAGED_STATIC_EXT_TYPES) diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 343711ce3a9cef..1f5b0596107704 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1548,6 +1548,27 @@ def contains_op_dict(): self.assert_specialized(contains_op_dict, "CONTAINS_OP_DICT") self.assert_no_opcode(contains_op_dict, "CONTAINS_OP") + def contains_op_frozen_dict(): + for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): + a, b = 1, frozendict({1: 2, 2: 5}) + self.assertTrue(a in b) + self.assertFalse(3 in b) + + contains_op_frozen_dict() + self.assert_specialized(contains_op_frozen_dict, "CONTAINS_OP_DICT") + self.assert_no_opcode(contains_op_frozen_dict, "CONTAINS_OP") + + def contains_op_frozen_dict_subclass(): + class MyFrozenDict(frozendict): + pass + for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): + a, b = 1, MyFrozenDict({1: 2, 2: 5}) + self.assertTrue(a in b) + self.assertFalse(3 in b) + + contains_op_frozen_dict_subclass() + self.assert_no_opcode(contains_op_frozen_dict_subclass, "CONTAINS_OP_DICT") + def contains_op_set(): for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): a, b = 1, {1, 2} @@ -1808,6 +1829,27 @@ def binary_subscr_dict(): self.assert_specialized(binary_subscr_dict, "BINARY_OP_SUBSCR_DICT") self.assert_no_opcode(binary_subscr_dict, "BINARY_OP") + def binary_subscr_frozen_dict(): + for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): + a = frozendict({1: 2, 2: 3}) + self.assertEqual(a[1], 2) + self.assertEqual(a[2], 3) + + binary_subscr_frozen_dict() + self.assert_specialized(binary_subscr_frozen_dict, "BINARY_OP_SUBSCR_DICT") + self.assert_no_opcode(binary_subscr_frozen_dict, "BINARY_OP") + + def binary_subscr_frozen_dict_subclass(): + class MyFrozenDict(frozendict): + pass + for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): + a = MyFrozenDict({1: 2, 2: 3}) + self.assertEqual(a[1], 2) + self.assertEqual(a[2], 3) + + binary_subscr_frozen_dict_subclass() + self.assert_no_opcode(binary_subscr_frozen_dict_subclass, "BINARY_OP_SUBSCR_DICT") + def binary_subscr_str_int(): for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): a = "foobar" diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst new file mode 100644 index 00000000000000..87d6a2a6df96a1 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst @@ -0,0 +1 @@ +Update specializer to support frozendict. Patch by Donghee Na. diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index ddd8fcdc231bf1..a9cd0574a596a1 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -642,7 +642,7 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UPDATE_MISS_STATS(BINARY_OP); assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); @@ -655,7 +655,7 @@ dict_st = nos; PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st); - assert(PyDict_CheckExact(dict)); + assert(PyAnyDict_CheckExact(dict)); STAT_INC(BINARY_OP, hit); PyObject *res_o; _PyFrame_SetStackPointer(frame, stack_pointer); @@ -5139,7 +5139,7 @@ { tos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UPDATE_MISS_STATS(CONTAINS_OP); assert(_PyOpcode_Deopt[opcode] == (CONTAINS_OP)); JUMP_TO_PREDICTED(CONTAINS_OP); @@ -5152,7 +5152,7 @@ left = stack_pointer[-2]; PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); - assert(PyDict_CheckExact(right_o)); + assert(PyAnyDict_CheckExact(right_o)); STAT_INC(CONTAINS_OP, hit); _PyFrame_SetStackPointer(frame, stack_pointer); int res = PyDict_Contains(right_o, left_o); @@ -11482,7 +11482,7 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); JUMP_TO_PREDICTED(STORE_SUBSCR); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index b461f9b5bea8a6..63a4222264985a 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1058,12 +1058,12 @@ dummy_func( op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) { PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - EXIT_IF(!PyDict_CheckExact(o)); + EXIT_IF(!PyAnyDict_CheckExact(o)); } op(_GUARD_TOS_DICT, (tos -- tos)) { PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - EXIT_IF(!PyDict_CheckExact(o)); + EXIT_IF(!PyAnyDict_CheckExact(o)); } macro(BINARY_OP_SUBSCR_DICT) = @@ -1073,7 +1073,7 @@ dummy_func( PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st); - assert(PyDict_CheckExact(dict)); + assert(PyAnyDict_CheckExact(dict)); STAT_INC(BINARY_OP, hit); PyObject *res_o; int rc = PyDict_GetItemRef(dict, sub, &res_o); @@ -2940,7 +2940,7 @@ dummy_func( PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); - assert(PyDict_CheckExact(right_o)); + assert(PyAnyDict_CheckExact(right_o)); STAT_INC(CONTAINS_OP, hit); int res = PyDict_Contains(right_o, left_o); if (res < 0) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9dead4eecc7826..1b3de80e4443b1 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5920,7 +5920,7 @@ _PyStackRef nos; nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); JUMP_TO_JUMP_TARGET(); @@ -5941,7 +5941,7 @@ _PyStackRef _stack_item_0 = _tos_cache0; nos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = _stack_item_0; SET_CURRENT_CACHED_VALUES(1); @@ -5964,7 +5964,7 @@ _PyStackRef _stack_item_1 = _tos_cache1; nos = _stack_item_0; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; _tos_cache0 = nos; @@ -5987,7 +5987,7 @@ _PyStackRef _stack_item_2 = _tos_cache2; nos = _stack_item_1; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = _stack_item_2; _tos_cache1 = nos; @@ -6009,7 +6009,7 @@ _PyStackRef tos; tos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); JUMP_TO_JUMP_TARGET(); @@ -6029,7 +6029,7 @@ _PyStackRef _stack_item_0 = _tos_cache0; tos = _stack_item_0; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = tos; SET_CURRENT_CACHED_VALUES(1); @@ -6049,7 +6049,7 @@ _PyStackRef _stack_item_1 = _tos_cache1; tos = _stack_item_1; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = tos; _tos_cache0 = _stack_item_0; @@ -6072,7 +6072,7 @@ _PyStackRef _stack_item_2 = _tos_cache2; tos = _stack_item_2; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = tos; _tos_cache1 = _stack_item_1; @@ -6102,7 +6102,7 @@ dict_st = _stack_item_0; PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st); - assert(PyDict_CheckExact(dict)); + assert(PyAnyDict_CheckExact(dict)); STAT_INC(BINARY_OP, hit); PyObject *res_o; stack_pointer[0] = dict_st; @@ -10393,7 +10393,7 @@ left = _stack_item_0; PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); - assert(PyDict_CheckExact(right_o)); + assert(PyAnyDict_CheckExact(right_o)); STAT_INC(CONTAINS_OP, hit); stack_pointer[0] = left; stack_pointer[1] = right; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 37fa6d679190dd..829a6988954e5f 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -642,7 +642,7 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UPDATE_MISS_STATS(BINARY_OP); assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); @@ -655,7 +655,7 @@ dict_st = nos; PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st); - assert(PyDict_CheckExact(dict)); + assert(PyAnyDict_CheckExact(dict)); STAT_INC(BINARY_OP, hit); PyObject *res_o; _PyFrame_SetStackPointer(frame, stack_pointer); @@ -5139,7 +5139,7 @@ { tos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UPDATE_MISS_STATS(CONTAINS_OP); assert(_PyOpcode_Deopt[opcode] == (CONTAINS_OP)); JUMP_TO_PREDICTED(CONTAINS_OP); @@ -5152,7 +5152,7 @@ left = stack_pointer[-2]; PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); - assert(PyDict_CheckExact(right_o)); + assert(PyAnyDict_CheckExact(right_o)); STAT_INC(CONTAINS_OP, hit); _PyFrame_SetStackPointer(frame, stack_pointer); int res = PyDict_Contains(right_o, left_o); @@ -11479,7 +11479,7 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyDict_CheckExact(o)) { + if (!PyAnyDict_CheckExact(o)) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); JUMP_TO_PREDICTED(STORE_SUBSCR); diff --git a/Python/specialize.c b/Python/specialize.c index 5ba016f83ea077..4d3ba4acbbf038 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2287,7 +2287,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in } } } - if (PyDict_CheckExact(lhs)) { + if (PyAnyDict_CheckExact(lhs)) { specialize(instr, BINARY_OP_SUBSCR_DICT); return; } @@ -2767,7 +2767,7 @@ _Py_Specialize_ContainsOp(_PyStackRef value_st, _Py_CODEUNIT *instr) assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[CONTAINS_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP); - if (PyDict_CheckExact(value)) { + if (PyAnyDict_CheckExact(value)) { specialize(instr, CONTAINS_OP_DICT); return; } From 16ccdbc50a3034f9c0e5ea6845356281b2ad04bd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Feb 2026 18:03:04 +0100 Subject: [PATCH 154/498] gh-141510: Fix frozendict.fromkeys() for dict subclasses (#144962) Copy also the dictionary if a dict subclass returns a frozendict. --- Lib/test/test_dict.py | 10 ++++++++++ Objects/dictobject.c | 16 ++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 1a8ae1cd42356e..71f72cb2557670 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1815,6 +1815,16 @@ class FrozenDictSubclass2(frozendict): self.assertEqual(fd, frozendict(a=None, b=None, c=None)) self.assertEqual(type(fd), FrozenDictSubclass2) + # Dict subclass which overrides the constructor + class DictSubclass(dict): + def __new__(self): + return created + + fd = DictSubclass.fromkeys("abc") + self.assertEqual(fd, frozendict(x=1, a=None, b=None, c=None)) + self.assertEqual(type(fd), DictSubclass) + self.assertEqual(created, frozendict(x=1)) + if __name__ == "__main__": unittest.main() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 8d3c34f87e2afe..af3fcca7455470 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -138,6 +138,7 @@ As a consequence of this, split keys have a maximum size of 16. // Forward declarations static PyObject* frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static PyObject* dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static int dict_merge(PyObject *a, PyObject *b, int override); @@ -3305,15 +3306,18 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) return NULL; } - // If cls is a frozendict subclass with overridden constructor, + // If cls is a dict or frozendict subclass with overridden constructor, // copy the frozendict. PyTypeObject *cls_type = _PyType_CAST(cls); - if (PyFrozenDict_Check(d) - && PyObject_IsSubclass(cls, (PyObject*)&PyFrozenDict_Type) - && cls_type->tp_new != frozendict_new) - { + if (PyFrozenDict_Check(d) && cls_type->tp_new != frozendict_new) { // Subclass-friendly copy - PyObject *copy = frozendict_new(cls_type, NULL, NULL); + PyObject *copy; + if (PyObject_IsSubclass(cls, (PyObject*)&PyFrozenDict_Type)) { + copy = frozendict_new(cls_type, NULL, NULL); + } + else { + copy = dict_new(cls_type, NULL, NULL); + } if (copy == NULL) { Py_DECREF(d); return NULL; From 0bbdb4e897ae909af39cd93f7a25de89b724ab47 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Feb 2026 21:23:49 +0100 Subject: [PATCH 155/498] gh-141510: Replace MappingProxyType with frozendict (#144904) --- Lib/dataclasses.py | 4 ++-- Lib/email/headerregistry.py | 4 +--- Lib/test/support/hashlib_helper.py | 5 ++--- Lib/test/test_dataclasses/__init__.py | 2 +- Lib/test/test_hmac.py | 5 ++--- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 730ced7299865e..482a4c61039184 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -191,8 +191,8 @@ class _KW_ONLY_TYPE: KW_ONLY = _KW_ONLY_TYPE() # Since most per-field metadata will be unused, create an empty -# read-only proxy that can be shared among all fields. -_EMPTY_METADATA = types.MappingProxyType({}) +# read-only dictionary that can be shared among all fields. +_EMPTY_METADATA = frozendict() # Markers for the various kinds of fields and pseudo-fields. class _FIELD_BASE: diff --git a/Lib/email/headerregistry.py b/Lib/email/headerregistry.py index 0e8698efc0b966..48cd85a65ba9f6 100644 --- a/Lib/email/headerregistry.py +++ b/Lib/email/headerregistry.py @@ -3,8 +3,6 @@ This module provides an implementation of the HeaderRegistry API. The implementation is designed to flexibly follow RFC5322 rules. """ -from types import MappingProxyType - from email import utils from email import errors from email import _header_value_parser as parser @@ -462,7 +460,7 @@ def init(self, *args, **kw): @property def params(self): - return MappingProxyType(self._params) + return frozendict(self._params) class ContentTypeHeader(ParameterizedMIMEHeader): diff --git a/Lib/test/support/hashlib_helper.py b/Lib/test/support/hashlib_helper.py index 49077d7cb4d757..818f99d0023dae 100644 --- a/Lib/test/support/hashlib_helper.py +++ b/Lib/test/support/hashlib_helper.py @@ -6,7 +6,6 @@ import unittest import unittest.mock from test.support import import_helper -from types import MappingProxyType def _parse_fullname(fullname, *, strict=False): @@ -351,7 +350,7 @@ def __init__( ) -_HASHINFO_DATABASE = MappingProxyType({ +_HASHINFO_DATABASE = frozendict({ _HashId.md5: _HashInfo( _HashId.md5, "_md5.MD5Type", @@ -500,7 +499,7 @@ def _iter_hash_func_info(excluded): # keyed hash function. However, as it's exposed by HACL*, we test it. _HMACINFO_DATABASE[_HashId.blake2s] = _HashInfoItem('_hmac.compute_blake2s_32') _HMACINFO_DATABASE[_HashId.blake2b] = _HashInfoItem('_hmac.compute_blake2b_32') -_HMACINFO_DATABASE = MappingProxyType(_HMACINFO_DATABASE) +_HMACINFO_DATABASE = frozendict(_HMACINFO_DATABASE) assert _HMACINFO_DATABASE.keys() == CANONICAL_DIGEST_NAMES diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index 3b335429b98500..8b5e0cf7806ba9 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -71,7 +71,7 @@ def test_field_repr(self): expected_output = "Field(name='id',type=None," \ f"default=1,default_factory={MISSING!r}," \ "init=True,repr=False,hash=None," \ - "compare=True,metadata=mappingproxy({})," \ + "compare=True,metadata=frozendict()," \ f"kw_only={MISSING!r}," \ "doc='Docstring'," \ "_field_type=None)" diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py index 17888a9f286c8f..de4d200374bcea 100644 --- a/Lib/test/test_hmac.py +++ b/Lib/test/test_hmac.py @@ -21,7 +21,6 @@ import hmac import hashlib import random -import types import unittest import warnings from _operator import _compare_digest as operator_compare_digest @@ -303,7 +302,7 @@ def assert_hmac_new_by_name( def check_hmac_new( self, key, msg, hexdigest, hashname, digest_size, block_size, - hmac_new_func, hmac_new_kwds=types.MappingProxyType({}), + hmac_new_func, hmac_new_kwds=frozendict(), ): """Check that HMAC(key, msg) == digest. @@ -349,7 +348,7 @@ def assert_hmac_hexdigest_by_name( def check_hmac_hexdigest( self, key, msg, hexdigest, digest_size, - hmac_digest_func, hmac_digest_kwds=types.MappingProxyType({}), + hmac_digest_func, hmac_digest_kwds=frozendict(), ): """Check and return a HMAC digest computed by hmac_digest_func(). From 7ebe9243950e9038dbbd9ddf46d4601ad6212260 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Wed, 18 Feb 2026 19:49:09 -0500 Subject: [PATCH 156/498] gh-144969: Document that the free threading GC can change ob_tid (#144972) --- Include/internal/pycore_critical_section.h | 9 +++++++++ InternalDocs/garbage_collector.md | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_critical_section.h b/Include/internal/pycore_critical_section.h index 60b6fc4a72e88f..2a2846b1296b90 100644 --- a/Include/internal/pycore_critical_section.h +++ b/Include/internal/pycore_critical_section.h @@ -50,6 +50,15 @@ extern "C" { // Asserts that the mutex for the given object is locked. The mutex must // be held by the top-most critical section otherwise there's the // possibility that the mutex would be swalled out in some code paths. +// +// NOTE: We use Py_REFCNT(op) != 1 instead of +// !PyUnstable_Object_IsUniquelyReferenced(op) because the free threading +// GC can change an object's ob_tid (it overwrites ob_tid and later +// restores it from the mimalloc segment). This means +// PyUnstable_Object_IsUniquelyReferenced() may spuriously return false +// after a GC collection, even though the thread may still have exclusive +// access to the object. The refcount check is a looser but still catches +// most misuses. #ifdef Py_DEBUG # define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op) \ diff --git a/InternalDocs/garbage_collector.md b/InternalDocs/garbage_collector.md index a7d872f3ec4392..94e6fb05b68d6f 100644 --- a/InternalDocs/garbage_collector.md +++ b/InternalDocs/garbage_collector.md @@ -153,7 +153,11 @@ pointer-sized (that is, eight bytes on a 64-bit platform). The garbage collector also temporarily repurposes the `ob_tid` (thread ID) and `ob_ref_local` (local reference count) fields for other purposes during -collections. +collections. The `ob_tid` field is later restored from the containing +mimalloc segment data structure. In some cases, such as when the original +allocating thread exits, this can result in a different `ob_tid` value. +Code should not rely on `ob_tid` being stable across operations that may +trigger garbage collection. C APIs From e84a2cc83c273329553377e99c9520d3f1225eda Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 19 Feb 2026 11:44:50 +0800 Subject: [PATCH 157/498] gh-144888: Don't invalidate executors during function deallocation (#144974) --- Objects/funcobject.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Objects/funcobject.c b/Objects/funcobject.c index ee0c46a95b9708..8099b82f4835fb 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -1126,10 +1126,6 @@ func_dealloc(PyObject *self) if (_PyObject_ResurrectEnd(self)) { return; } -#if _Py_TIER2 - _Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), self, 1); - _PyJit_Tracer_InvalidateDependency(_PyThreadState_GET(), self); -#endif _PyObject_GC_UNTRACK(op); FT_CLEAR_WEAKREFS(self, op->func_weakreflist); (void)func_clear((PyObject*)op); From 20caf1c08440684b618d2166022ae82b2db3b696 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 19 Feb 2026 11:45:30 +0000 Subject: [PATCH 158/498] Remove unused :platform: in module's docs (GH-144988) It has not been outputted since Sphinx 1.1. --- Doc/library/curses.rst | 3 ++- Doc/library/dbm.rst | 7 ++++--- Doc/library/dialog.rst | 3 --- Doc/library/fcntl.rst | 1 - Doc/library/grp.rst | 1 - Doc/library/msvcrt.rst | 1 - Doc/library/posix.rst | 1 - Doc/library/pty.rst | 1 - Doc/library/pwd.rst | 1 - Doc/library/readline.rst | 3 ++- Doc/library/resource.rst | 1 - Doc/library/syslog.rst | 1 - Doc/library/termios.rst | 1 - Doc/library/tkinter.colorchooser.rst | 1 - Doc/library/tkinter.dnd.rst | 1 - Doc/library/tkinter.font.rst | 1 - Doc/library/tkinter.messagebox.rst | 1 - Doc/library/tkinter.scrolledtext.rst | 1 - Doc/library/tty.rst | 1 - Doc/library/winreg.rst | 1 - Doc/library/winsound.rst | 1 - 21 files changed, 8 insertions(+), 25 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 84efc6654e87c6..2dc638b3d4014b 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -4,7 +4,6 @@ .. module:: curses :synopsis: An interface to the curses library, providing portable terminal handling. - :platform: Unix .. sectionauthor:: Moshe Zadka .. sectionauthor:: Eric Raymond @@ -25,6 +24,8 @@ Linux and the BSD variants of Unix. .. include:: ../includes/optional-module.rst +.. availability:: Unix. + .. note:: Whenever the documentation mentions a *character* it can be specified diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 2481d77f5fbfba..646981e8692cc5 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -161,7 +161,6 @@ The individual submodules are described in the following sections. ---------------------------------------------- .. module:: dbm.sqlite3 - :platform: All :synopsis: SQLite backend for dbm .. versionadded:: 3.13 @@ -224,7 +223,6 @@ or any other SQLite browser, including the SQLite CLI. ---------------------------------------- .. module:: dbm.gnu - :platform: Unix :synopsis: GNU database manager **Source code:** :source:`Lib/dbm/gnu.py` @@ -242,6 +240,8 @@ functionality like crash tolerance. .. include:: ../includes/wasm-mobile-notavail.rst +.. availability:: Unix. + .. exception:: error Raised on :mod:`!dbm.gnu`-specific errors, such as I/O errors. :exc:`KeyError` is @@ -347,7 +347,6 @@ functionality like crash tolerance. ----------------------------------------- .. module:: dbm.ndbm - :platform: Unix :synopsis: The New Database Manager **Source code:** :source:`Lib/dbm/ndbm.py` @@ -373,6 +372,8 @@ This module can be used with the "classic" NDBM interface or the .. include:: ../includes/wasm-mobile-notavail.rst +.. availability:: Unix. + .. exception:: error Raised on :mod:`!dbm.ndbm`-specific errors, such as I/O errors. :exc:`KeyError` is raised diff --git a/Doc/library/dialog.rst b/Doc/library/dialog.rst index 6fee23e942183d..5d522556235a02 100644 --- a/Doc/library/dialog.rst +++ b/Doc/library/dialog.rst @@ -5,7 +5,6 @@ Tkinter Dialogs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: tkinter.simpledialog - :platform: Tk :synopsis: Simple dialog windows **Source code:** :source:`Lib/tkinter/simpledialog.py` @@ -43,7 +42,6 @@ functions for creating simple modal dialogs to get a value from the user. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: tkinter.filedialog - :platform: Tk :synopsis: Dialog classes for file selection **Source code:** :source:`Lib/tkinter/filedialog.py` @@ -208,7 +206,6 @@ These do not emulate the native look-and-feel of the platform. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. module:: tkinter.commondialog - :platform: Tk :synopsis: Tkinter base class for dialogs **Source code:** :source:`Lib/tkinter/commondialog.py` diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 2c9e883f56904f..6e69d24a0e4586 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -2,7 +2,6 @@ ========================================================== .. module:: fcntl - :platform: Unix :synopsis: The fcntl() and ioctl() system calls. .. sectionauthor:: Jaap Vermeulen diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index d1c7f22a209780..f436970e791ace 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -2,7 +2,6 @@ ================================== .. module:: grp - :platform: Unix :synopsis: The group database (getgrnam() and friends). -------------- diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 80f3ae4ee3f5c1..ee6798f969a1b6 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -2,7 +2,6 @@ =========================================================== .. module:: msvcrt - :platform: Windows :synopsis: Miscellaneous useful routines from the MS VC++ runtime. .. sectionauthor:: Fred L. Drake, Jr. diff --git a/Doc/library/posix.rst b/Doc/library/posix.rst index c52661ae112541..1f1ca03dfd6222 100644 --- a/Doc/library/posix.rst +++ b/Doc/library/posix.rst @@ -2,7 +2,6 @@ ==================================================== .. module:: posix - :platform: Unix :synopsis: The most common POSIX system calls (normally used via module os). -------------- diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 397cf0ea7cece4..f0314ea5af8118 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -2,7 +2,6 @@ ========================================= .. module:: pty - :platform: Unix :synopsis: Pseudo-Terminal Handling for Unix. .. moduleauthor:: Steen Lumholt diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst index e1ff32912132f7..7691fed2c7cb83 100644 --- a/Doc/library/pwd.rst +++ b/Doc/library/pwd.rst @@ -2,7 +2,6 @@ ===================================== .. module:: pwd - :platform: Unix :synopsis: The password database (getpwnam() and friends). -------------- diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 1bdfb6ce0ed426..59f5b54a042ea3 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -2,7 +2,6 @@ =========================================== .. module:: readline - :platform: Unix :synopsis: GNU readline support for Python. .. sectionauthor:: Skip Montanaro @@ -28,6 +27,8 @@ Readline library in general. .. include:: ../includes/optional-module.rst +.. availability:: Unix. + .. note:: The underlying Readline library API may be implemented by diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index b176a28fdfe35b..94bfbeab967693 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -2,7 +2,6 @@ =============================================== .. module:: resource - :platform: Unix :synopsis: An interface to provide resource usage information on the current process. .. moduleauthor:: Jeremy Hylton diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 548898a37bc6ea..b6bf01240951eb 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -2,7 +2,6 @@ =============================================== .. module:: syslog - :platform: Unix :synopsis: An interface to the Unix syslog library routines. -------------- diff --git a/Doc/library/termios.rst b/Doc/library/termios.rst index e3ce596d18486f..537dfcedd8cf5a 100644 --- a/Doc/library/termios.rst +++ b/Doc/library/termios.rst @@ -2,7 +2,6 @@ =========================================== .. module:: termios - :platform: Unix :synopsis: POSIX style tty control. .. index:: diff --git a/Doc/library/tkinter.colorchooser.rst b/Doc/library/tkinter.colorchooser.rst index a8468a4807357f..73f8f76a21044b 100644 --- a/Doc/library/tkinter.colorchooser.rst +++ b/Doc/library/tkinter.colorchooser.rst @@ -2,7 +2,6 @@ ====================================================== .. module:: tkinter.colorchooser - :platform: Tk :synopsis: Color choosing dialog **Source code:** :source:`Lib/tkinter/colorchooser.py` diff --git a/Doc/library/tkinter.dnd.rst b/Doc/library/tkinter.dnd.rst index 8c179d9793a855..48d16ccb204b9d 100644 --- a/Doc/library/tkinter.dnd.rst +++ b/Doc/library/tkinter.dnd.rst @@ -2,7 +2,6 @@ ============================================= .. module:: tkinter.dnd - :platform: Tk :synopsis: Tkinter drag-and-drop interface **Source code:** :source:`Lib/tkinter/dnd.py` diff --git a/Doc/library/tkinter.font.rst b/Doc/library/tkinter.font.rst index 9d7b3e0fc227c1..9eecb803c3aedc 100644 --- a/Doc/library/tkinter.font.rst +++ b/Doc/library/tkinter.font.rst @@ -2,7 +2,6 @@ ============================================= .. module:: tkinter.font - :platform: Tk :synopsis: Tkinter font-wrapping class **Source code:** :source:`Lib/tkinter/font.py` diff --git a/Doc/library/tkinter.messagebox.rst b/Doc/library/tkinter.messagebox.rst index 4503913d6889b8..2a69d282638529 100644 --- a/Doc/library/tkinter.messagebox.rst +++ b/Doc/library/tkinter.messagebox.rst @@ -2,7 +2,6 @@ ====================================================== .. module:: tkinter.messagebox - :platform: Tk :synopsis: Various types of alert dialogs **Source code:** :source:`Lib/tkinter/messagebox.py` diff --git a/Doc/library/tkinter.scrolledtext.rst b/Doc/library/tkinter.scrolledtext.rst index d2543c524b2532..6c3c74afd47d82 100644 --- a/Doc/library/tkinter.scrolledtext.rst +++ b/Doc/library/tkinter.scrolledtext.rst @@ -2,7 +2,6 @@ ===================================================== .. module:: tkinter.scrolledtext - :platform: Tk :synopsis: Text widget with a vertical scroll bar. .. sectionauthor:: Fred L. Drake, Jr. diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index b2fe1bac9b0b2f..fe46be8b3211a2 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -2,7 +2,6 @@ ========================================== .. module:: tty - :platform: Unix :synopsis: Utility functions that perform common terminal control operations. .. moduleauthor:: Steen Lumholt diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 99137db4496c55..12f9252af9356e 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -2,7 +2,6 @@ ========================================== .. module:: winreg - :platform: Windows :synopsis: Routines and objects for manipulating the Windows registry. .. sectionauthor:: Mark Hammond diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst index 8efe4b1ee643e7..730b1bac658002 100644 --- a/Doc/library/winsound.rst +++ b/Doc/library/winsound.rst @@ -2,7 +2,6 @@ ======================================================== .. module:: winsound - :platform: Windows :synopsis: Access to the sound-playing machinery for Windows. .. moduleauthor:: Toby Dickenson From 3f37b94c7377a971a063aaf13387b940cb4cac01 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 19 Feb 2026 11:52:57 +0000 Subject: [PATCH 159/498] GH-144651: Optimize the new uops added when recording values during tracing. (GH-144948) * Handle dependencies in the optimizer, not the tracer * Strengthen some checks to avoid relying on optimizer for correctness --- Include/internal/pycore_optimizer.h | 26 +++--- Include/internal/pycore_optimizer_types.h | 6 +- Include/internal/pycore_uop_ids.h | 10 +-- Include/internal/pycore_uop_metadata.h | 32 +++---- Lib/test/test_capi/test_opt.py | 1 + Modules/_testinternalcapi/test_cases.c.h | 3 +- Objects/codeobject.c | 1 - Objects/frameobject.c | 1 - Objects/funcobject.c | 2 +- Python/bytecodes.c | 16 ++-- Python/executor_cases.c.h | 54 ++++-------- Python/generated_cases.c.h | 3 +- Python/instrumentation.c | 7 +- Python/optimizer.c | 57 +++--------- Python/optimizer_analysis.c | 25 +++--- Python/optimizer_bytecodes.c | 100 ++++++++++++++-------- Python/optimizer_cases.c.h | 85 ++++++++++-------- Python/optimizer_symbols.c | 90 +++++++++++++------ 18 files changed, 277 insertions(+), 242 deletions(-) diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 79a2d60eb788ea..d9f7f59de1798e 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -22,6 +22,10 @@ typedef struct _PyJitUopBuffer { _PyUOpInstruction *end; } _PyJitUopBuffer; +typedef struct _JitOptRefBuffer { + JitOptRef *used; + JitOptRef *end; +} _JitOptRefBuffer; typedef struct _JitOptContext { char done; @@ -37,10 +41,15 @@ typedef struct _JitOptContext { // Arena for the symbolic types. ty_arena t_arena; - JitOptRef *n_consumed; - JitOptRef *limit; - JitOptRef locals_and_stack[MAX_ABSTRACT_INTERP_SIZE]; + /* To do -- We could make this more space efficient + * by using a single array and growing the stack and + * locals toward each other. */ + _JitOptRefBuffer locals; + _JitOptRefBuffer stack; + JitOptRef locals_array[ABSTRACT_INTERP_LOCALS_SIZE]; + JitOptRef stack_array[ABSTRACT_INTERP_STACK_SIZE]; _PyJitUopBuffer out_buffer; + _PyBloomFilter *dependencies; } JitOptContext; @@ -83,13 +92,11 @@ typedef struct _PyJitTracerInitialState { } _PyJitTracerInitialState; typedef struct _PyJitTracerPreviousState { - bool dependencies_still_valid; int instr_oparg; int instr_stacklevel; _Py_CODEUNIT *instr; PyCodeObject *instr_code; // Strong struct _PyInterpreterFrame *instr_frame; - _PyBloomFilter dependencies; PyObject *recorded_value; // Strong, may be NULL } _PyJitTracerPreviousState; @@ -303,25 +310,24 @@ extern void _Py_uop_sym_set_recorded_type(JitOptContext *ctx, JitOptRef sym, PyT extern void _Py_uop_sym_set_recorded_gen_func(JitOptContext *ctx, JitOptRef ref, PyFunctionObject *value); extern PyCodeObject *_Py_uop_sym_get_probable_func_code(JitOptRef sym); extern PyObject *_Py_uop_sym_get_probable_value(JitOptRef sym); +extern JitOptRef *_Py_uop_sym_set_stack_depth(JitOptContext *ctx, int stack_depth, JitOptRef *current_sp); -extern void _Py_uop_abstractcontext_init(JitOptContext *ctx); +extern void _Py_uop_abstractcontext_init(JitOptContext *ctx, _PyBloomFilter *dependencies); extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx); extern _Py_UOpsAbstractFrame *_Py_uop_frame_new( JitOptContext *ctx, PyCodeObject *co, - int curr_stackentries, JitOptRef *args, int arg_len); extern _Py_UOpsAbstractFrame *_Py_uop_frame_new_from_symbol( JitOptContext *ctx, JitOptRef callable, - int curr_stackentries, JitOptRef *args, int arg_len); -extern int _Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co, int curr_stackentries); +extern int _Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co); PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored); @@ -357,8 +363,6 @@ PyAPI_FUNC(void) _PyJit_FinalizeTracing(PyThreadState *tstate, int err); void _PyPrintExecutor(_PyExecutorObject *executor, const _PyUOpInstruction *marker); void _PyJit_TracerFree(_PyThreadStateImpl *_tstate); -void _PyJit_Tracer_InvalidateDependency(PyThreadState *old_tstate, void *obj); - #ifdef _Py_TIER2 typedef void (*_Py_RecordFuncPtr)(_PyInterpreterFrame *frame, _PyStackRef *stackpointer, int oparg, PyObject **recorded_value); PyAPI_DATA(const _Py_RecordFuncPtr) _PyOpcode_RecordFunctions[]; diff --git a/Include/internal/pycore_optimizer_types.h b/Include/internal/pycore_optimizer_types.h index 57c0c828c2aabd..2958db5b787975 100644 --- a/Include/internal/pycore_optimizer_types.h +++ b/Include/internal/pycore_optimizer_types.h @@ -11,8 +11,9 @@ extern "C" { #include #include "pycore_uop.h" // UOP_MAX_TRACE_LENGTH -// Holds locals, stack, locals, stack ... (in that order) -#define MAX_ABSTRACT_INTERP_SIZE 512 +#define ABSTRACT_INTERP_STACK_SIZE 256 +#define ABSTRACT_INTERP_LOCALS_SIZE 512 + #define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * 5) @@ -138,6 +139,7 @@ typedef struct _Py_UOpsAbstractFrame { // Max stacklen int stack_len; int locals_len; + bool caller; // We have made a call from this frame during the trace PyFunctionObject *func; PyCodeObject *code; diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 94b05b736ed277..ebf21b12633c78 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -147,7 +147,7 @@ extern "C" { #define _GUARD_CALLABLE_STR_1 402 #define _GUARD_CALLABLE_TUPLE_1 403 #define _GUARD_CALLABLE_TYPE_1 404 -#define _GUARD_CODE 405 +#define _GUARD_CODE_VERSION 405 #define _GUARD_DORV_NO_DICT 406 #define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 407 #define _GUARD_GLOBALS_VERSION 408 @@ -658,10 +658,10 @@ extern "C" { #define _GUARD_CALLABLE_TYPE_1_r13 855 #define _GUARD_CALLABLE_TYPE_1_r23 856 #define _GUARD_CALLABLE_TYPE_1_r33 857 -#define _GUARD_CODE_r00 858 -#define _GUARD_CODE_r11 859 -#define _GUARD_CODE_r22 860 -#define _GUARD_CODE_r33 861 +#define _GUARD_CODE_VERSION_r00 858 +#define _GUARD_CODE_VERSION_r11 859 +#define _GUARD_CODE_VERSION_r22 860 +#define _GUARD_CODE_VERSION_r33 861 #define _GUARD_DORV_NO_DICT_r01 862 #define _GUARD_DORV_NO_DICT_r11 863 #define _GUARD_DORV_NO_DICT_r22 864 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 5a47eae7a9abb1..7921d229f11db3 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -370,7 +370,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_TIER2_RESUME_CHECK] = HAS_PERIODIC_FLAG, [_COLD_EXIT] = HAS_SYNC_SP_FLAG, [_COLD_DYNAMIC_EXIT] = HAS_SYNC_SP_FLAG, - [_GUARD_CODE] = HAS_EXIT_FLAG, + [_GUARD_CODE_VERSION] = HAS_EXIT_FLAG, [_GUARD_IP__PUSH_FRAME] = HAS_EXIT_FLAG, [_GUARD_IP_YIELD_VALUE] = HAS_EXIT_FLAG, [_GUARD_IP_RETURN_VALUE] = HAS_EXIT_FLAG, @@ -3404,13 +3404,13 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, }, }, - [_GUARD_CODE] = { + [_GUARD_CODE_VERSION] = { .best = { 0, 1, 2, 3 }, .entries = { - { 0, 0, _GUARD_CODE_r00 }, - { 1, 1, _GUARD_CODE_r11 }, - { 2, 2, _GUARD_CODE_r22 }, - { 3, 3, _GUARD_CODE_r33 }, + { 0, 0, _GUARD_CODE_VERSION_r00 }, + { 1, 1, _GUARD_CODE_VERSION_r11 }, + { 2, 2, _GUARD_CODE_VERSION_r22 }, + { 3, 3, _GUARD_CODE_VERSION_r33 }, }, }, [_GUARD_IP__PUSH_FRAME] = { @@ -4221,10 +4221,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_TIER2_RESUME_CHECK_r33] = _TIER2_RESUME_CHECK, [_COLD_EXIT_r00] = _COLD_EXIT, [_COLD_DYNAMIC_EXIT_r00] = _COLD_DYNAMIC_EXIT, - [_GUARD_CODE_r00] = _GUARD_CODE, - [_GUARD_CODE_r11] = _GUARD_CODE, - [_GUARD_CODE_r22] = _GUARD_CODE, - [_GUARD_CODE_r33] = _GUARD_CODE, + [_GUARD_CODE_VERSION_r00] = _GUARD_CODE_VERSION, + [_GUARD_CODE_VERSION_r11] = _GUARD_CODE_VERSION, + [_GUARD_CODE_VERSION_r22] = _GUARD_CODE_VERSION, + [_GUARD_CODE_VERSION_r33] = _GUARD_CODE_VERSION, [_GUARD_IP__PUSH_FRAME_r00] = _GUARD_IP__PUSH_FRAME, [_GUARD_IP__PUSH_FRAME_r11] = _GUARD_IP__PUSH_FRAME, [_GUARD_IP__PUSH_FRAME_r22] = _GUARD_IP__PUSH_FRAME, @@ -4655,11 +4655,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_CALLABLE_TYPE_1_r13] = "_GUARD_CALLABLE_TYPE_1_r13", [_GUARD_CALLABLE_TYPE_1_r23] = "_GUARD_CALLABLE_TYPE_1_r23", [_GUARD_CALLABLE_TYPE_1_r33] = "_GUARD_CALLABLE_TYPE_1_r33", - [_GUARD_CODE] = "_GUARD_CODE", - [_GUARD_CODE_r00] = "_GUARD_CODE_r00", - [_GUARD_CODE_r11] = "_GUARD_CODE_r11", - [_GUARD_CODE_r22] = "_GUARD_CODE_r22", - [_GUARD_CODE_r33] = "_GUARD_CODE_r33", + [_GUARD_CODE_VERSION] = "_GUARD_CODE_VERSION", + [_GUARD_CODE_VERSION_r00] = "_GUARD_CODE_VERSION_r00", + [_GUARD_CODE_VERSION_r11] = "_GUARD_CODE_VERSION_r11", + [_GUARD_CODE_VERSION_r22] = "_GUARD_CODE_VERSION_r22", + [_GUARD_CODE_VERSION_r33] = "_GUARD_CODE_VERSION_r33", [_GUARD_DORV_NO_DICT] = "_GUARD_DORV_NO_DICT", [_GUARD_DORV_NO_DICT_r01] = "_GUARD_DORV_NO_DICT_r01", [_GUARD_DORV_NO_DICT_r11] = "_GUARD_DORV_NO_DICT_r11", @@ -6070,7 +6070,7 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _COLD_DYNAMIC_EXIT: return 0; - case _GUARD_CODE: + case _GUARD_CODE_VERSION: return 0; case _GUARD_IP__PUSH_FRAME: return 0; diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 2cad53d9c0728b..7ac71fbfab1fe0 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -110,6 +110,7 @@ def f{n}(): for exe in executors[:i]: self.assertTrue(exe.is_valid()) + @unittest.skipIf(os.getenv("PYTHON_UOPS_OPTIMIZE") == "0", "Needs uop optimizer to run.") def test_uop_optimizer_invalidation(self): # Generate a new function at each call ns = {} diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index a9cd0574a596a1..fde6db4933f74a 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -5675,7 +5675,8 @@ assert(executor->vm_data.code == code); assert(executor->vm_data.valid); assert(tstate->current_executor == NULL); - if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(code->_co_instrumentation_version); + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) != iversion) { opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index ed3cc41480ab5c..776444a0cc2086 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -2433,7 +2433,6 @@ code_dealloc(PyObject *self) PyMem_Free(co_extra); } #ifdef _Py_TIER2 - _PyJit_Tracer_InvalidateDependency(tstate, self); if (co->co_executors != NULL) { clear_executors(co); } diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 9d774a71edb797..9a7abfc0ec26ab 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -262,7 +262,6 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value) #if _Py_TIER2 _Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), co, 1); - _PyJit_Tracer_InvalidateDependency(_PyThreadState_GET(), co); #endif _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 8099b82f4835fb..efe27a2b70c4de 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -12,7 +12,7 @@ #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_stats.h" #include "pycore_weakref.h" // FT_CLEAR_WEAKREFS() -#include "pycore_optimizer.h" // _PyJit_Tracer_InvalidateDependency +#include "pycore_optimizer.h" // _Py_Executors_InvalidateDependency static const char * func_event_name(PyFunction_WatchEvent event) { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 63a4222264985a..01eaf4a59b645a 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3125,10 +3125,10 @@ dummy_func( assert(executor->vm_data.code == code); assert(executor->vm_data.valid); assert(tstate->current_executor == NULL); - /* If the eval breaker is set then stay in tier 1. - * This avoids any potentially infinite loops - * involving _RESUME_CHECK */ - if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + /* If the eval breaker is set, or instrumentation is needed, then stay in tier 1. + * This avoids any potentially infinite loops involving _RESUME_CHECK */ + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(code->_co_instrumentation_version); + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) != iversion) { opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; @@ -5616,9 +5616,9 @@ dummy_func( HANDLE_PENDING_AND_DEOPT_IF(_Py_emscripten_signal_clock == 0); _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - HANDLE_PENDING_AND_DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); - assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); + HANDLE_PENDING_AND_DEOPT_IF(eval_breaker != iversion); } tier2 op(_COLD_EXIT, ( -- )) { @@ -5668,9 +5668,9 @@ dummy_func( Py_UNREACHABLE(); } - tier2 op(_GUARD_CODE, (version/2 -- )) { + tier2 op(_GUARD_CODE_VERSION, (version/2 -- )) { PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); - EXIT_IF(code == Py_None); + assert(PyCode_Check(code)); EXIT_IF(((PyCodeObject *)code)->co_version != version); } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 1b3de80e4443b1..8b36d1abf2e916 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -20034,13 +20034,13 @@ } _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - if (eval_breaker & _PY_EVAL_EVENTS_MASK) { + if (eval_breaker != iversion) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); JUMP_TO_JUMP_TARGET(); } - assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); SET_CURRENT_CACHED_VALUES(0); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); break; @@ -20059,14 +20059,14 @@ } _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - if (eval_breaker & _PY_EVAL_EVENTS_MASK) { + if (eval_breaker != iversion) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = _stack_item_0; SET_CURRENT_CACHED_VALUES(1); JUMP_TO_JUMP_TARGET(); } - assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); _tos_cache0 = _stack_item_0; SET_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); @@ -20088,15 +20088,15 @@ } _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - if (eval_breaker & _PY_EVAL_EVENTS_MASK) { + if (eval_breaker != iversion) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; _tos_cache0 = _stack_item_0; SET_CURRENT_CACHED_VALUES(2); JUMP_TO_JUMP_TARGET(); } - assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); _tos_cache1 = _stack_item_1; _tos_cache0 = _stack_item_0; SET_CURRENT_CACHED_VALUES(2); @@ -20121,8 +20121,9 @@ } _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - if (eval_breaker & _PY_EVAL_EVENTS_MASK) { + if (eval_breaker != iversion) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = _stack_item_2; _tos_cache1 = _stack_item_1; @@ -20130,7 +20131,6 @@ SET_CURRENT_CACHED_VALUES(3); JUMP_TO_JUMP_TARGET(); } - assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); _tos_cache2 = _stack_item_2; _tos_cache1 = _stack_item_1; _tos_cache0 = _stack_item_0; @@ -20184,16 +20184,12 @@ GOTO_TIER_ONE(target); } - case _GUARD_CODE_r00: { + case _GUARD_CODE_VERSION_r00: { CHECK_CURRENT_CACHED_VALUES(0); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); - if (code == Py_None) { - UOP_STAT_INC(uopcode, miss); - SET_CURRENT_CACHED_VALUES(0); - JUMP_TO_JUMP_TARGET(); - } + assert(PyCode_Check(code)); if (((PyCodeObject *)code)->co_version != version) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); @@ -20204,18 +20200,13 @@ break; } - case _GUARD_CODE_r11: { + case _GUARD_CODE_VERSION_r11: { CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef _stack_item_0 = _tos_cache0; uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); - if (code == Py_None) { - UOP_STAT_INC(uopcode, miss); - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(1); - JUMP_TO_JUMP_TARGET(); - } + assert(PyCode_Check(code)); if (((PyCodeObject *)code)->co_version != version) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = _stack_item_0; @@ -20228,20 +20219,14 @@ break; } - case _GUARD_CODE_r22: { + case _GUARD_CODE_VERSION_r22: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef _stack_item_0 = _tos_cache0; _PyStackRef _stack_item_1 = _tos_cache1; uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); - if (code == Py_None) { - UOP_STAT_INC(uopcode, miss); - _tos_cache1 = _stack_item_1; - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(2); - JUMP_TO_JUMP_TARGET(); - } + assert(PyCode_Check(code)); if (((PyCodeObject *)code)->co_version != version) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; @@ -20256,7 +20241,7 @@ break; } - case _GUARD_CODE_r33: { + case _GUARD_CODE_VERSION_r33: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef _stack_item_0 = _tos_cache0; @@ -20264,14 +20249,7 @@ _PyStackRef _stack_item_2 = _tos_cache2; uint32_t version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *code = PyStackRef_AsPyObjectBorrow(frame->f_executable); - if (code == Py_None) { - UOP_STAT_INC(uopcode, miss); - _tos_cache2 = _stack_item_2; - _tos_cache1 = _stack_item_1; - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(3); - JUMP_TO_JUMP_TARGET(); - } + assert(PyCode_Check(code)); if (((PyCodeObject *)code)->co_version != version) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = _stack_item_2; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 829a6988954e5f..bc9ae7e0ab3be3 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5675,7 +5675,8 @@ assert(executor->vm_data.code == code); assert(executor->vm_data.valid); assert(tstate->current_executor == NULL); - if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + uintptr_t iversion = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(code->_co_instrumentation_version); + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) != iversion) { opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 28bbe1d82a3b88..b074d23277878b 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1785,7 +1785,6 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp) _PyCode_Clear_Executors(code); } _Py_Executors_InvalidateDependency(interp, code, 1); - _PyJit_Tracer_InvalidateDependency(PyThreadState_GET(), code); #endif int code_len = (int)Py_SIZE(code); /* Exit early to avoid creating instrumentation @@ -2115,6 +2114,9 @@ int _PyMonitoring_ClearToolId(int tool_id) // Set the new global version so all the code objects can refresh the // instrumentation. set_global_version(_PyThreadState_GET(), version); +#ifdef _Py_TIER2 + _Py_Executors_InvalidateAll(interp, 1); +#endif int res = instrument_all_executing_code_objects(interp); _PyEval_StartTheWorld(interp); return res; @@ -2457,6 +2459,9 @@ monitoring_restart_events_impl(PyObject *module) } interp->last_restart_version = restart_version; set_global_version(tstate, new_version); +#ifdef _Py_TIER2 + _Py_Executors_InvalidateAll(interp, 1); +#endif int res = instrument_all_executing_code_objects(interp); _PyEval_StartTheWorld(interp); diff --git a/Python/optimizer.c b/Python/optimizer.c index 466729b158d345..f075e28d71e0f8 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -160,11 +160,6 @@ _PyOptimizer_Optimize( interp->compiling = false; return 0; } - // One of our dependencies while tracing was invalidated. Not worth compiling. - if (!_tstate->jit_tracer_state->prev_state.dependencies_still_valid) { - interp->compiling = false; - return 0; - } _PyExecutorObject *executor; int err = uop_optimize(frame, tstate, &executor, progress_needed); if (err <= 0) { @@ -615,7 +610,6 @@ _PyJit_translate_single_bytecode_to_trace( _PyJitTracerState *tracer = _tstate->jit_tracer_state; PyCodeObject *old_code = tracer->prev_state.instr_code; bool progress_needed = (tracer->initial_state.chain_depth % MAX_CHAIN_DEPTH) == 0; - _PyBloomFilter *dependencies = &tracer->prev_state.dependencies; _PyJitUopBuffer *trace = &tracer->code_buffer; _Py_CODEUNIT *this_instr = tracer->prev_state.instr; @@ -701,10 +695,6 @@ _PyJit_translate_single_bytecode_to_trace( } #endif - if (!tracer->prev_state.dependencies_still_valid) { - goto done; - } - // This happens when a recursive call happens that we can't trace. Such as Python -> C -> Python calls // If we haven't guarded the IP, then it's untraceable. if (frame != tracer->prev_state.instr_frame && !needs_guard_ip) { @@ -784,11 +774,6 @@ _PyJit_translate_single_bytecode_to_trace( ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)target_instr, target); } - // Can be NULL for the entry frame. - if (old_code != NULL) { - _Py_BloomFilter_Add(dependencies, old_code); - } - switch (opcode) { case POP_JUMP_IF_NONE: case POP_JUMP_IF_NOT_NONE: @@ -925,15 +910,6 @@ _PyJit_translate_single_bytecode_to_trace( expansion->uops[i].offset); Py_FatalError("garbled expansion"); } - if (uop == _PUSH_FRAME || uop == _RETURN_VALUE || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { - PyCodeObject *new_code = (PyCodeObject *)PyStackRef_AsPyObjectBorrow(frame->f_executable); - if (new_code != NULL && !Py_IsNone((PyObject*)new_code)) { - _Py_BloomFilter_Add(dependencies, new_code); - } - ADD_TO_TRACE(uop, oparg, operand, target); - uop_buffer_last(trace)->operand1 = PyStackRef_IsNone(frame->f_executable) ? 2 : ((int)(frame->stackpointer - _PyFrame_Stackbase(frame))); - break; - } if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) { assert(i + 1 == nuops); _Py_CODEUNIT *next = target_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; @@ -964,7 +940,10 @@ _PyJit_translate_single_bytecode_to_trace( ADD_TO_TRACE(_RECORD_CODE, 0, (uintptr_t)code, 0); ADD_TO_TRACE(guard_ip, 0, (uintptr_t)next_instr, 0); if (PyCode_Check(code)) { - ADD_TO_TRACE(_GUARD_CODE, 0, ((PyCodeObject *)code)->co_version, 0); + /* Record stack depth, in operand1 */ + int stack_depth = (int)(frame->stackpointer - _PyFrame_Stackbase(frame)); + uop_buffer_last(trace)->operand1 = stack_depth; + ADD_TO_TRACE(_GUARD_CODE_VERSION, 0, ((PyCodeObject *)code)->co_version, 0); } } // Loop back to the start @@ -1046,7 +1025,6 @@ _PyJit_TryInitializeTracing( tracer->initial_state.exit = exit; tracer->initial_state.stack_depth = (int)(stack_pointer - _PyFrame_Stackbase(frame)); tracer->initial_state.chain_depth = chain_depth; - tracer->prev_state.dependencies_still_valid = true; tracer->prev_state.instr_code = (PyCodeObject *)Py_NewRef(_PyFrame_GetCode(frame)); tracer->prev_state.instr = curr_instr; tracer->prev_state.instr_frame = frame; @@ -1064,7 +1042,6 @@ _PyJit_TryInitializeTracing( if (_PyOpcode_Caches[_PyOpcode_Deopt[close_loop_instr->op.code]]) { close_loop_instr[1].counter = trigger_backoff_counter(); } - _Py_BloomFilter_Init(&tracer->prev_state.dependencies); tracer->is_tracing = true; return 1; } @@ -1216,7 +1193,7 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length) base_opcode == _GUARD_IP_RETURN_VALUE || base_opcode == _GUARD_IP_YIELD_VALUE || base_opcode == _GUARD_IP_RETURN_GENERATOR || - base_opcode == _GUARD_CODE + base_opcode == _GUARD_CODE_VERSION ) { base_exit_op = _DYNAMIC_EXIT; } @@ -1498,7 +1475,6 @@ uop_optimize( { _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; assert(_tstate->jit_tracer_state != NULL); - _PyBloomFilter *dependencies = &_tstate->jit_tracer_state->prev_state.dependencies; _PyUOpInstruction *buffer = _tstate->jit_tracer_state->code_buffer.start; OPT_STAT_INC(attempts); bool is_noopt = !tstate->interp->opt_config.uops_optimize_enabled; @@ -1510,11 +1486,15 @@ uop_optimize( assert(length > 0); assert(length < UOP_MAX_TRACE_LENGTH); OPT_STAT_INC(traces_created); + + _PyBloomFilter dependencies; + _Py_BloomFilter_Init(&dependencies); if (!is_noopt) { _PyUOpInstruction *output = &_tstate->jit_tracer_state->uop_array[UOP_MAX_TRACE_LENGTH]; length = _Py_uop_analyze_and_optimize( _tstate, buffer, length, curr_stackentries, - output, dependencies); + output, &dependencies); + if (length <= 0) { return length; } @@ -1546,7 +1526,7 @@ uop_optimize( length = prepare_for_execution(buffer, length); assert(length <= UOP_MAX_TRACE_LENGTH); _PyExecutorObject *executor = make_executor_from_uops( - _tstate, buffer, length, dependencies); + _tstate, buffer, length, &dependencies); if (executor == NULL) { return -1; } @@ -1861,21 +1841,6 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is _Py_Executors_InvalidateAll(interp, is_invalidation); } -void -_PyJit_Tracer_InvalidateDependency(PyThreadState *tstate, void *obj) -{ - _PyBloomFilter obj_filter; - _Py_BloomFilter_Init(&obj_filter); - _Py_BloomFilter_Add(&obj_filter, obj); - _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; - if (_tstate->jit_tracer_state == NULL) { - return; - } - if (bloom_filter_may_contain(&_tstate->jit_tracer_state->prev_state.dependencies, &obj_filter)) - { - _tstate->jit_tracer_state->prev_state.dependencies_still_valid = false; - } -} /* Invalidate all executors */ void _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index c6a513ad220b63..45dd42c96064bc 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -55,23 +55,21 @@ static void dump_abstract_stack(_Py_UOpsAbstractFrame *frame, JitOptRef *stack_pointer) { - JitOptRef *stack_base = frame->stack; - JitOptRef *locals_base = frame->locals; printf(" locals=["); - for (JitOptRef *ptr = locals_base; ptr < stack_base; ptr++) { - if (ptr != locals_base) { + for (int i = 0 ; i < frame->locals_len; i++) { + if (i > 0) { printf(", "); } - _PyUOpSymPrint(*ptr); + _PyUOpSymPrint(frame->locals[i]); } printf("]\n"); - if (stack_pointer < stack_base) { - printf(" stack=%d\n", (int)(stack_pointer - stack_base)); + if (stack_pointer < frame->stack) { + printf(" stack=%d\n", (int)(stack_pointer - frame->stack)); } else { printf(" stack=["); - for (JitOptRef *ptr = stack_base; ptr < stack_pointer; ptr++) { - if (ptr != stack_base) { + for (JitOptRef *ptr = frame->stack; ptr < stack_pointer; ptr++) { + if (ptr != frame->stack) { printf(", "); } _PyUOpSymPrint(*ptr); @@ -291,6 +289,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr, #define sym_set_recorded_gen_func(SYM, VAL) _Py_uop_sym_set_recorded_gen_func(ctx, SYM, VAL) #define sym_get_probable_func_code _Py_uop_sym_get_probable_func_code #define sym_get_probable_value _Py_uop_sym_get_probable_value +#define sym_set_stack_depth(DEPTH, SP) _Py_uop_sym_set_stack_depth(ctx, DEPTH, SP) /* Comparison oparg masks */ #define COMPARE_LT_MASK 2 @@ -473,14 +472,15 @@ optimize_uops( interp->type_watchers[TYPE_WATCHER_ID] = type_watcher_callback; } - _Py_uop_abstractcontext_init(ctx); - _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, (PyCodeObject *)func->func_code, curr_stacklen, NULL, 0); + _Py_uop_abstractcontext_init(ctx, dependencies); + _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, (PyCodeObject *)func->func_code, NULL, 0); if (frame == NULL) { return 0; } frame->func = func; ctx->curr_frame_depth++; ctx->frame = frame; + _Py_uop_sym_set_stack_depth(ctx, curr_stacklen, frame->stack_pointer); _PyUOpInstruction *this_instr = NULL; JitOptRef *stack_pointer = ctx->frame->stack_pointer; @@ -718,8 +718,7 @@ _Py_uop_analyze_and_optimize( OPT_STAT_INC(optimizer_attempts); length = optimize_uops( - tstate, buffer, length, curr_stacklen, - output, dependencies); + tstate, buffer, length, curr_stacklen, output, dependencies); if (length == 0) { return length; diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 2b35628ad99999..228bd51a28bb69 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -46,6 +46,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; #define sym_set_recorded_gen_func(SYM, VAL) _Py_uop_sym_set_recorded_gen_func(ctx, SYM, VAL) #define sym_get_probable_func_code _Py_uop_sym_get_probable_func_code #define sym_get_probable_value _Py_uop_sym_get_probable_value +#define sym_set_stack_depth(DEPTH, SP) _Py_uop_sym_set_stack_depth(ctx, DEPTH, SP) extern int optimize_to_bool( @@ -362,7 +363,7 @@ dummy_func(void) { } op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) { - _Py_UOpsAbstractFrame *f = frame_new_from_symbol(ctx, getitem, 0, NULL, 0); + _Py_UOpsAbstractFrame *f = frame_new_from_symbol(ctx, getitem, NULL, 0); if (f == NULL) { break; } @@ -833,7 +834,7 @@ dummy_func(void) { // + 1 for _SAVE_RETURN_OFFSET // FIX ME -- This needs a version check and function watcher PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; - _Py_UOpsAbstractFrame *f = frame_new(ctx, co, 0, NULL, 0); + _Py_UOpsAbstractFrame *f = frame_new(ctx, co, NULL, 0); if (f == NULL) { break; } @@ -894,9 +895,9 @@ dummy_func(void) { } if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, args, argcount)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, args, argcount)); } else { - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, NULL, 0)); } } @@ -907,15 +908,15 @@ dummy_func(void) { } op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) { - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, NULL, 0)); } op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) { - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, NULL, 0)); } op(_PY_FRAME_EX, (func_st, null, callargs_st, kwargs_st -- ex_frame)) { - ex_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, func_st, 0, NULL, 0)); + ex_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, func_st, NULL, 0)); } op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) { @@ -927,18 +928,18 @@ dummy_func(void) { op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) { ctx->frame->stack_pointer = stack_pointer - oparg - 2; - _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, 0, NULL, 0); + _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, NULL, 0); if (shim == NULL) { break; } /* Push self onto stack of shim */ - shim->stack[0] = self; + shim->stack_pointer[0] = self; shim->stack_pointer++; assert((int)(shim->stack_pointer - shim->stack) == 1); ctx->frame = shim; ctx->curr_frame_depth++; assert((this_instr + 1)->opcode == _PUSH_FRAME); - init_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, init, 0, args-1, oparg+1)); + init_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, init, args-1, oparg+1)); } op(_RETURN_VALUE, (retval -- res)) { @@ -954,15 +955,7 @@ dummy_func(void) { ctx->done = true; break; } - int returning_stacklevel = (int)this_instr->operand1; - if (ctx->curr_frame_depth >= 2) { - PyCodeObject *expected_code = ctx->frames[ctx->curr_frame_depth - 2].code; - if (expected_code == returning_code) { - assert(this_instr[2].opcode == _GUARD_IP_RETURN_VALUE); - REPLACE_OP((this_instr + 2), _NOP, 0, 0); - } - } - if (frame_pop(ctx, returning_code, returning_stacklevel)) { + if (frame_pop(ctx, returning_code)) { break; } stack_pointer = ctx->frame->stack_pointer; @@ -976,14 +969,12 @@ dummy_func(void) { ctx->frame->stack_pointer = stack_pointer; assert(this_instr[1].opcode == _RECORD_CODE); PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; - assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; } - _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = (int)this_instr->operand1; - if (frame_pop(ctx, returning_code, returning_stacklevel)) { + assert(PyCode_Check(returning_code)); + if (frame_pop(ctx, returning_code)) { break; } stack_pointer = ctx->frame->stack_pointer; @@ -998,14 +989,12 @@ dummy_func(void) { ctx->frame->stack_pointer = stack_pointer; assert(this_instr[1].opcode == _RECORD_CODE); PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; - assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; } - _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = (int)this_instr->operand1; - if (frame_pop(ctx, returning_code, returning_stacklevel)) { + assert(PyCode_Check(returning_code)); + if (frame_pop(ctx, returning_code)) { break; } stack_pointer = ctx->frame->stack_pointer; @@ -1025,22 +1014,24 @@ dummy_func(void) { } op(_FOR_ITER_GEN_FRAME, (iter, unused -- iter, unused, gen_frame)) { - _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, iter, 1, NULL, 0); + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, iter, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; } - new_frame->stack[0] = sym_new_const(ctx, Py_None); + new_frame->stack_pointer[0] = sym_new_const(ctx, Py_None); + new_frame->stack_pointer++; gen_frame = PyJitRef_WrapInvalid(new_frame); } op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) { - _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, 1, NULL, 0); + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; } - new_frame->stack[0] = PyJitRef_StripReferenceInfo(v); + new_frame->stack_pointer[0] = PyJitRef_StripReferenceInfo(v); + new_frame->stack_pointer++; gen_frame = PyJitRef_WrapInvalid(new_frame); } @@ -1062,14 +1053,10 @@ dummy_func(void) { if (!CURRENT_FRAME_IS_INIT_SHIM()) { ctx->frame->stack_pointer = stack_pointer; } + ctx->frame->caller = true; ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame); ctx->curr_frame_depth++; stack_pointer = ctx->frame->stack_pointer; - // Fixed calls don't need IP guards. - if ((this_instr-1)->opcode == _CREATE_INIT_FRAME) { - assert((this_instr+1)->opcode == _GUARD_IP__PUSH_FRAME); - REPLACE_OP(this_instr+1, _NOP, 0, 0); - } assert(ctx->frame->locals != NULL); } @@ -1653,6 +1640,47 @@ dummy_func(void) { sym_set_recorded_gen_func(nos, func); } + op(_GUARD_IP__PUSH_FRAME, (ip/4 --)) { + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + // TO DO + // Normal function calls to known functions + // do not need an IP guard. + } + + op(_GUARD_CODE_VERSION, (version/2 -- )) { + PyCodeObject *co = get_current_code_object(ctx); + if (co->co_version == version) { + _Py_BloomFilter_Add(dependencies, co); + REPLACE_OP(this_instr, _NOP, 0, 0); + } + else { + ctx->done = true; + } + } + + op(_GUARD_IP_YIELD_VALUE, (ip/4 --)) { + if (ctx->frame->caller) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + } + + op(_GUARD_IP_RETURN_VALUE, (ip/4 --)) { + if (ctx->frame->caller) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + } + + op(_GUARD_IP_RETURN_GENERATOR, (ip/4 --)) { + if (ctx->frame->caller) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + } + + + // END BYTECODES // } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 7faa699a058249..a93e85329297cd 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1162,7 +1162,7 @@ getitem = stack_pointer[-1]; sub = stack_pointer[-2]; container = stack_pointer[-3]; - _Py_UOpsAbstractFrame *f = frame_new_from_symbol(ctx, getitem, 0, NULL, 0); + _Py_UOpsAbstractFrame *f = frame_new_from_symbol(ctx, getitem, NULL, 0); if (f == NULL) { break; } @@ -1272,15 +1272,7 @@ ctx->done = true; break; } - int returning_stacklevel = (int)this_instr->operand1; - if (ctx->curr_frame_depth >= 2) { - PyCodeObject *expected_code = ctx->frames[ctx->curr_frame_depth - 2].code; - if (expected_code == returning_code) { - assert(this_instr[2].opcode == _GUARD_IP_RETURN_VALUE); - REPLACE_OP((this_instr + 2), _NOP, 0, 0); - } - } - if (frame_pop(ctx, returning_code, returning_stacklevel)) { + if (frame_pop(ctx, returning_code)) { break; } stack_pointer = ctx->frame->stack_pointer; @@ -1324,12 +1316,13 @@ JitOptRef gen_frame; v = stack_pointer[-1]; receiver = stack_pointer[-2]; - _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, 1, NULL, 0); + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, receiver, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; } - new_frame->stack[0] = PyJitRef_StripReferenceInfo(v); + new_frame->stack_pointer[0] = PyJitRef_StripReferenceInfo(v); + new_frame->stack_pointer++; gen_frame = PyJitRef_WrapInvalid(new_frame); stack_pointer[-1] = gen_frame; break; @@ -1346,14 +1339,12 @@ ctx->frame->stack_pointer = stack_pointer; assert(this_instr[1].opcode == _RECORD_CODE); PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; - assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; } - _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = (int)this_instr->operand1; - if (frame_pop(ctx, returning_code, returning_stacklevel)) { + assert(PyCode_Check(returning_code)); + if (frame_pop(ctx, returning_code)) { break; } stack_pointer = ctx->frame->stack_pointer; @@ -2011,7 +2002,7 @@ owner = stack_pointer[-1]; PyObject *fget = (PyObject *)this_instr->operand0; PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; - _Py_UOpsAbstractFrame *f = frame_new(ctx, co, 0, NULL, 0); + _Py_UOpsAbstractFrame *f = frame_new(ctx, co, NULL, 0); if (f == NULL) { break; } @@ -2711,12 +2702,13 @@ JitOptRef iter; JitOptRef gen_frame; iter = stack_pointer[-2]; - _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, iter, 1, NULL, 0); + _Py_UOpsAbstractFrame *new_frame = frame_new_from_symbol(ctx, iter, NULL, 0); if (new_frame == NULL) { ctx->done = true; break; } - new_frame->stack[0] = sym_new_const(ctx, Py_None); + new_frame->stack_pointer[0] = sym_new_const(ctx, Py_None); + new_frame->stack_pointer++; gen_frame = PyJitRef_WrapInvalid(new_frame); CHECK_STACK_BOUNDS(1); stack_pointer[0] = gen_frame; @@ -2897,7 +2889,7 @@ JitOptRef callable; JitOptRef new_frame; callable = stack_pointer[-2 - oparg]; - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, NULL, 0)); CHECK_STACK_BOUNDS(-1 - oparg); stack_pointer[-2 - oparg] = new_frame; stack_pointer += -1 - oparg; @@ -3033,9 +3025,9 @@ argcount++; } if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, args, argcount)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, args, argcount)); } else { - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, NULL, 0)); } CHECK_STACK_BOUNDS(-1 - oparg); stack_pointer[-2 - oparg] = new_frame; @@ -3053,13 +3045,10 @@ if (!CURRENT_FRAME_IS_INIT_SHIM()) { ctx->frame->stack_pointer = stack_pointer; } + ctx->frame->caller = true; ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame); ctx->curr_frame_depth++; stack_pointer = ctx->frame->stack_pointer; - if ((this_instr-1)->opcode == _CREATE_INIT_FRAME) { - assert((this_instr+1)->opcode == _GUARD_IP__PUSH_FRAME); - REPLACE_OP(this_instr+1, _NOP, 0, 0); - } assert(ctx->frame->locals != NULL); break; } @@ -3213,17 +3202,17 @@ self = stack_pointer[-1 - oparg]; init = stack_pointer[-2 - oparg]; ctx->frame->stack_pointer = stack_pointer - oparg - 2; - _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, 0, NULL, 0); + _Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, NULL, 0); if (shim == NULL) { break; } - shim->stack[0] = self; + shim->stack_pointer[0] = self; shim->stack_pointer++; assert((int)(shim->stack_pointer - shim->stack) == 1); ctx->frame = shim; ctx->curr_frame_depth++; assert((this_instr + 1)->opcode == _PUSH_FRAME); - init_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, init, 0, args-1, oparg+1)); + init_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, init, args-1, oparg+1)); CHECK_STACK_BOUNDS(-1 - oparg); stack_pointer[-2 - oparg] = init_frame; stack_pointer += -1 - oparg; @@ -3500,7 +3489,7 @@ JitOptRef callable; JitOptRef new_frame; callable = stack_pointer[-3 - oparg]; - new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, 0, NULL, 0)); + new_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, callable, NULL, 0)); CHECK_STACK_BOUNDS(-2 - oparg); stack_pointer[-3 - oparg] = new_frame; stack_pointer += -2 - oparg; @@ -3548,7 +3537,7 @@ JitOptRef func_st; JitOptRef ex_frame; func_st = stack_pointer[-4]; - ex_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, func_st, 0, NULL, 0)); + ex_frame = PyJitRef_WrapInvalid(frame_new_from_symbol(ctx, func_st, NULL, 0)); CHECK_STACK_BOUNDS(-3); stack_pointer[-4] = ex_frame; stack_pointer += -3; @@ -3592,14 +3581,12 @@ ctx->frame->stack_pointer = stack_pointer; assert(this_instr[1].opcode == _RECORD_CODE); PyCodeObject *returning_code = (PyCodeObject *)this_instr[1].operand0; - assert(PyCode_Check(returning_code)); if (returning_code == NULL) { ctx->done = true; break; } - _Py_BloomFilter_Add(dependencies, returning_code); - int returning_stacklevel = (int)this_instr->operand1; - if (frame_pop(ctx, returning_code, returning_stacklevel)) { + assert(PyCode_Check(returning_code)); + if (frame_pop(ctx, returning_code)) { break; } stack_pointer = ctx->frame->stack_pointer; @@ -4157,23 +4144,49 @@ break; } - case _GUARD_CODE: { + case _GUARD_CODE_VERSION: { + uint32_t version = (uint32_t)this_instr->operand0; + PyCodeObject *co = get_current_code_object(ctx); + if (co->co_version == version) { + _Py_BloomFilter_Add(dependencies, co); + REPLACE_OP(this_instr, _NOP, 0, 0); + } + else { + ctx->done = true; + } break; } case _GUARD_IP__PUSH_FRAME: { + PyObject *ip = (PyObject *)this_instr->operand0; + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); break; } case _GUARD_IP_YIELD_VALUE: { + PyObject *ip = (PyObject *)this_instr->operand0; + if (ctx->frame->caller) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); break; } case _GUARD_IP_RETURN_VALUE: { + PyObject *ip = (PyObject *)this_instr->operand0; + if (ctx->frame->caller) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); break; } case _GUARD_IP_RETURN_GENERATOR: { + PyObject *ip = (PyObject *)this_instr->operand0; + if (ctx->frame->caller) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); break; } diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c index 635ce622c3c589..dcbe093fd6d74c 100644 --- a/Python/optimizer_symbols.c +++ b/Python/optimizer_symbols.c @@ -1284,7 +1284,6 @@ _Py_UOpsAbstractFrame * _Py_uop_frame_new_from_symbol( JitOptContext *ctx, JitOptRef callable, - int curr_stackentries, JitOptRef *args, int arg_len) { @@ -1293,7 +1292,7 @@ _Py_uop_frame_new_from_symbol( ctx->done = true; return NULL; } - _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, co, curr_stackentries, args, arg_len); + _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, co, args, arg_len); if (frame == NULL) { return NULL; } @@ -1311,7 +1310,6 @@ _Py_UOpsAbstractFrame * _Py_uop_frame_new( JitOptContext *ctx, PyCodeObject *co, - int curr_stackentries, JitOptRef *args, int arg_len) { @@ -1324,17 +1322,21 @@ _Py_uop_frame_new( } _Py_UOpsAbstractFrame *frame = &ctx->frames[ctx->curr_frame_depth]; frame->code = co; - frame->stack_len = co->co_stacksize; + + frame->locals = ctx->locals.used; + ctx->locals.used += co->co_nlocalsplus; frame->locals_len = co->co_nlocalsplus; - frame->locals = ctx->n_consumed; - frame->stack = frame->locals + co->co_nlocalsplus; - frame->stack_pointer = frame->stack + curr_stackentries; + frame->stack = ctx->stack.used; + ctx->stack.used += co->co_stacksize; + frame->stack_len = co->co_stacksize; + + frame->stack_pointer = frame->stack; frame->globals_checked_version = 0; frame->globals_watched = false; frame->func = NULL; - ctx->n_consumed = ctx->n_consumed + (co->co_nlocalsplus + co->co_stacksize); - if (ctx->n_consumed >= ctx->limit) { + frame->caller = false; + if (ctx->locals.used > ctx->locals.end || ctx->stack.used > ctx->stack.end) { ctx->done = true; ctx->out_of_space = true; return NULL; @@ -1354,16 +1356,45 @@ _Py_uop_frame_new( frame->locals[i] = local; } - // Initialize the stack as well - for (int i = 0; i < curr_stackentries; i++) { - JitOptRef stackvar = _Py_uop_sym_new_unknown(ctx); - frame->stack[i] = stackvar; - } + /* Most optimizations rely on code objects being immutable (including sys._getframe modifications), + * and up to date for instrumentation. */ + _Py_BloomFilter_Add(ctx->dependencies, co); assert(frame->locals != NULL); return frame; } +JitOptRef * +_Py_uop_sym_set_stack_depth(JitOptContext *ctx, int stack_depth, JitOptRef *current_sp) { + _Py_UOpsAbstractFrame *frame = ctx->frame; + assert(frame->stack != NULL); + JitOptRef *new_stack_pointer = frame->stack + stack_depth; + if (current_sp > new_stack_pointer) { + ctx->done = true; + ctx->contradiction = true; + return NULL; + } + if (new_stack_pointer > ctx->stack.end) { + ctx->done = true; + ctx->out_of_space = true; + return NULL; + } + int delta = (int)(new_stack_pointer - current_sp); + assert(delta >= 0); + if (delta) { + /* Shift existing stack elements up */ + for (JitOptRef *p = current_sp-1; p >= frame->stack; p--) { + p[delta] = *p; + } + /* Fill rest of stack with unknowns */ + for (int i = 0; i < delta; i++) { + frame->stack[i] = _Py_uop_sym_new_unknown(ctx); + } + } + return frame->stack_pointer = new_stack_pointer; +} + + void _Py_uop_abstractcontext_fini(JitOptContext *ctx) { @@ -1380,15 +1411,24 @@ _Py_uop_abstractcontext_fini(JitOptContext *ctx) } } +// Leave a bit of space to push values before checking that there is space for a new frame +#define STACK_HEADROOM 2 + void -_Py_uop_abstractcontext_init(JitOptContext *ctx) +_Py_uop_abstractcontext_init(JitOptContext *ctx, _PyBloomFilter *dependencies) { static_assert(sizeof(JitOptSymbol) <= 3 * sizeof(uint64_t), "JitOptSymbol has grown"); - ctx->limit = ctx->locals_and_stack + MAX_ABSTRACT_INTERP_SIZE; - ctx->n_consumed = ctx->locals_and_stack; + + ctx->stack.used = ctx->stack_array; + ctx->stack.end = &ctx->stack_array[ABSTRACT_INTERP_STACK_SIZE-STACK_HEADROOM]; + ctx->locals.used = ctx->locals_array; + ctx->locals.end = &ctx->locals_array[ABSTRACT_INTERP_LOCALS_SIZE-STACK_HEADROOM]; #ifdef Py_DEBUG // Aids debugging a little. There should never be NULL in the abstract interpreter. - for (int i = 0 ; i < MAX_ABSTRACT_INTERP_SIZE; i++) { - ctx->locals_and_stack[i] = PyJitRef_NULL; + for (int i = 0 ; i < ABSTRACT_INTERP_STACK_SIZE; i++) { + ctx->stack_array[i] = PyJitRef_NULL; + } + for (int i = 0 ; i < ABSTRACT_INTERP_LOCALS_SIZE; i++) { + ctx->locals_array[i] = PyJitRef_NULL; } #endif @@ -1406,13 +1446,15 @@ _Py_uop_abstractcontext_init(JitOptContext *ctx) ctx->out_of_space = false; ctx->contradiction = false; ctx->builtins_watched = false; + ctx->dependencies = dependencies; } int -_Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co, int curr_stackentries) +_Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co) { _Py_UOpsAbstractFrame *frame = ctx->frame; - ctx->n_consumed = frame->locals; + ctx->stack.used = frame->stack; + ctx->locals.used = frame->locals; ctx->curr_frame_depth--; @@ -1436,9 +1478,7 @@ _Py_uop_frame_pop(JitOptContext *ctx, PyCodeObject *co, int curr_stackentries) // Else: trace stack underflow. // This handles swapping out frames. - assert(curr_stackentries >= 1); - // -1 to stackentries as we push to the stack our return value after this. - _Py_UOpsAbstractFrame *new_frame = _Py_uop_frame_new(ctx, co, curr_stackentries - 1, NULL, 0); + _Py_UOpsAbstractFrame *new_frame = _Py_uop_frame_new(ctx, co, NULL, 0); if (new_frame == NULL) { ctx->done = true; return 1; @@ -1474,7 +1514,7 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) { JitOptContext context; JitOptContext *ctx = &context; - _Py_uop_abstractcontext_init(ctx); + _Py_uop_abstractcontext_init(ctx, NULL); PyObject *val_42 = NULL; PyObject *val_43 = NULL; PyObject *val_big = NULL; From c06f4f43015528db45bd6b44b46c057d88b38583 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:38:46 +0100 Subject: [PATCH 160/498] GH-144679: When building with VS 2026 on Windows, use PlatformToolset v145 by default (GH-144680) --- .../next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst | 2 ++ PCbuild/python.props | 2 +- PCbuild/pythoncore.vcxproj | 2 +- Tools/msi/bundle/bootstrap/pythonba.vcxproj | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst diff --git a/Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst b/Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst new file mode 100644 index 00000000000000..ebcfda54da39a7 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst @@ -0,0 +1,2 @@ +When building with Visual Studio 2026 (Version 18), use PlatformToolSet v145 +by default. Patch by Chris Eibl. diff --git a/PCbuild/python.props b/PCbuild/python.props index 82e6365bb397a5..3ad8d81dfc9a95 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -11,7 +11,7 @@ We set BasePlatformToolset for ICC's benefit, it's otherwise ignored. --> - v143 + v145 v143 v142 v141 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 5e37dd33c849f2..61bee29c0af3d6 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -730,7 +730,7 @@ - + diff --git a/Tools/msi/bundle/bootstrap/pythonba.vcxproj b/Tools/msi/bundle/bootstrap/pythonba.vcxproj index 3970e857894ba5..4b38582f0d31e5 100644 --- a/Tools/msi/bundle/bootstrap/pythonba.vcxproj +++ b/Tools/msi/bundle/bootstrap/pythonba.vcxproj @@ -21,6 +21,7 @@ Release Win32 + v145 v143 v142 v141 From 52794cba13801f24c228c8e1d95a4ef25a62b4e3 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 19 Feb 2026 21:48:57 +0900 Subject: [PATCH 161/498] gh-141510: Update Whats News for frozendict (gh-144961) --- Doc/whatsnew/3.15.rst | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 62ce7121424651..feccc496fad0e0 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -188,14 +188,33 @@ raise :exc:`SyntaxError`). :pep:`814`: Add frozendict built-in type ---------------------------------------- -A new public immutable type :class:`frozendict` is added to the :mod:`builtins` -module. It is not a ``dict`` subclass but inherits directly from ``object``. - -A ``frozendict`` can be hashed with ``hash(frozendict)`` if all keys and values -can be hashed. +A new :term:`immutable` type, :class:`frozendict`, is added to the :mod:`builtins` module. +It does not allow modification after creation. A ``frozendict`` is not a subclass of ``dict``; +it inherits directly from ``object``. A ``frozendict`` is :term:`hashable` +as long as all of its keys and values are hashable. A ``frozendict`` preserves +insertion order, but comparison does not take order into account. + +For example:: + + >>> a = frozendict(x=1, y=2) + >>> a + frozendict({'x': 1, 'y': 2}) + >>> a['z'] = 3 + Traceback (most recent call last): + File "", line 1, in + a['z'] = 3 + ~^^^^^ + TypeError: 'frozendict' object does not support item assignment + >>> b = frozendict(y=2, x=1) + >>> hash(a) == hash(b) + True + >>> a == b + True .. seealso:: :pep:`814` for the full specification and rationale. +(Contributed by Victor Stinner and Donghee Na in :gh:`141510`.) + .. _whatsnew315-profiling-package: From 1d099164bc0732debb9e93f32ad96a7d3d55a9ba Mon Sep 17 00:00:00 2001 From: David Peter Date: Thu, 19 Feb 2026 14:31:13 +0100 Subject: [PATCH 162/498] gh-144702: Use standard terminology in class pattern error message (#144703) --- .../2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst | 2 ++ Python/ceval.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst new file mode 100644 index 00000000000000..01d2b6570ded96 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst @@ -0,0 +1,2 @@ +Clarify the error message raised when a class pattern is used to match on a +non-class object. diff --git a/Python/ceval.c b/Python/ceval.c index ab2eef560370f5..8e905a5e689ed9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -534,7 +534,7 @@ _PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs) { if (!PyType_Check(type)) { - const char *e = "called match pattern must be a class"; + const char *e = "class pattern must refer to a class"; _PyErr_Format(tstate, PyExc_TypeError, e); return NULL; } From 28b3a8ac08ed166705382113f5fea4b616064711 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 19 Feb 2026 23:06:15 +0900 Subject: [PATCH 163/498] gh-141510: Update ftscalingbench to support frozendict (gh-144999) --- Tools/ftscalingbench/ftscalingbench.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tools/ftscalingbench/ftscalingbench.py b/Tools/ftscalingbench/ftscalingbench.py index 50d0e4c04fc319..f60f5adba5c12c 100644 --- a/Tools/ftscalingbench/ftscalingbench.py +++ b/Tools/ftscalingbench/ftscalingbench.py @@ -180,6 +180,12 @@ def create_dict(): "key": "value", } +if hasattr(__builtins__, "frozendict"): + @register_benchmark + def create_frozendict(): + for i in range(1000 * WORK_SCALE): + d = frozendict(key="value") + thread_local = threading.local() @register_benchmark From f1cf762ee7d52e8acb567f1817da90ed535ef419 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 19 Feb 2026 15:11:21 +0100 Subject: [PATCH 164/498] gh-84393: Remove AIX workaround: re-enable posix_fadvise and f_allocate (GH-144784) Co-authored-by: Batuhan Taskaya --- .../2020-04-07-05-09-34.bpo-40212.oPYeBs.rst | 1 + Modules/clinic/posixmodule.c.h | 10 +++++----- Modules/posixmodule.c | 18 ++++-------------- 3 files changed, 10 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst diff --git a/Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst b/Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst new file mode 100644 index 00000000000000..2e9c3d81180e6a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst @@ -0,0 +1 @@ +Re-enable :func:`os.posix_fallocate` and :func:`os.posix_fadvise` on AIX. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 03c0f221ba98b3..c4f498d233164c 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -9418,7 +9418,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #endif /* (defined HAVE_TRUNCATE || defined MS_WINDOWS) */ -#if (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) && !defined(__wasi__)) +#if (defined(HAVE_POSIX_FALLOCATE) && !defined(__wasi__)) PyDoc_STRVAR(os_posix_fallocate__doc__, "posix_fallocate($module, fd, offset, length, /)\n" @@ -9463,9 +9463,9 @@ os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) && !defined(__wasi__)) */ +#endif /* (defined(HAVE_POSIX_FALLOCATE) && !defined(__wasi__)) */ -#if (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) +#if defined(HAVE_POSIX_FADVISE) PyDoc_STRVAR(os_posix_fadvise__doc__, "posix_fadvise($module, fd, offset, length, advice, /)\n" @@ -9520,7 +9520,7 @@ os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) */ +#endif /* defined(HAVE_POSIX_FADVISE) */ #if defined(MS_WINDOWS) @@ -13611,4 +13611,4 @@ os__emscripten_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py #ifndef OS__EMSCRIPTEN_LOG_METHODDEF #define OS__EMSCRIPTEN_LOG_METHODDEF #endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */ -/*[clinic end generated code: output=5fd2aeb6ba9a5df8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=89c21e2151ac7316 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ef90ac5de09c65..072027fa0f6174 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -13376,19 +13376,9 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) #endif /* HAVE_TRUNCATE || MS_WINDOWS */ -/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() - and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is - defined, which is the case in Python on AIX. AIX bug report: - http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ -#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) -# define POSIX_FADVISE_AIX_BUG -#endif - - /* GH-111804: Due to posix_fallocate() not having consistent semantics across OSs, support was dropped in WASI preview2. */ -#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) && \ - !defined(__wasi__) +#if defined(HAVE_POSIX_FALLOCATE) && !defined(__wasi__) /*[clinic input] os.posix_fallocate @@ -13426,10 +13416,10 @@ os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, errno = result; return posix_error(); } -#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG && !defined(__wasi__) */ +#endif /* HAVE_POSIX_FALLOCATE && !defined(__wasi__) */ -#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) +#if defined(HAVE_POSIX_FADVISE) /*[clinic input] os.posix_fadvise @@ -13473,7 +13463,7 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, errno = result; return posix_error(); } -#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */ +#endif /* HAVE_POSIX_FADVISE */ #ifdef MS_WINDOWS From 157f271de352f16ecd052fb1fb0fcce528962407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Thu, 19 Feb 2026 15:25:50 +0000 Subject: [PATCH 165/498] gh-139899: Introduce MetaPathFinder.discover and PathEntryFinder.discover (#139900) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gh-139899: Introduce MetaPathFinder.discover and PathEntryFinder.discover Signed-off-by: Filipe Laíns * Fix doc reference Signed-off-by: Filipe Laíns * Remove specific doc references Signed-off-by: Filipe Laíns * Fix docstrings Signed-off-by: Filipe Laíns * Revert "Remove specific doc references" This reverts commit 31d1a8f5510e0f7a53016c7120ea2e1bda46e60c. Signed-off-by: Filipe Laíns * Fix news references Signed-off-by: Filipe Laíns * Add docs warning Signed-off-by: Filipe Laíns * Raise ValueError on invalid parent Signed-off-by: Filipe Laíns * Dedupe __path__ in PathFinder.discover Signed-off-by: Filipe Laíns * Use context manager and add error handling to os.scandir Signed-off-by: Filipe Laíns * Raise ValueError on invalid parent Signed-off-by: Filipe Laíns * Dedupe when package exists with multiple suffixes Signed-off-by: Filipe Laíns * Apply suggestions from code review Co-authored-by: Alyssa Coghlan * Add tests Signed-off-by: Filipe Laíns --------- Signed-off-by: Filipe Laíns Co-authored-by: Alyssa Coghlan Co-authored-by: Brett Cannon --- Doc/library/importlib.rst | 44 +++++++ Lib/importlib/_bootstrap_external.py | 48 +++++++ Lib/importlib/abc.py | 19 +++ Lib/test/test_importlib/test_discover.py | 121 ++++++++++++++++++ ...-10-10-14-08-58.gh-issue-139899.09leRY.rst | 3 + 5 files changed, 235 insertions(+) create mode 100644 Lib/test/test_importlib/test_discover.py create mode 100644 Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 5f0858cb134ebf..795524e5b62145 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -275,6 +275,28 @@ ABC hierarchy:: .. versionchanged:: 3.4 Returns ``None`` when called instead of :data:`NotImplemented`. + .. method:: discover(parent=None) + + An optional method which searches for possible specs with given *parent* + module spec. If *parent* is *None*, :meth:`MetaPathFinder.discover` will + search for top-level modules. + + Returns an iterable of possible specs. + + Raises :exc:`ValueError` if *parent* is not a package module. + + .. warning:: + This method can potentially yield a very large number of objects, and + it may carry out IO operations when computing these values. + + Because of this, it will generaly be desirable to compute the result + values on-the-fly, as they are needed. As such, the returned object is + only guaranteed to be an :class:`iterable `, + instead of a :class:`list` or other + :class:`collection ` type. + + .. versionadded:: next + .. class:: PathEntryFinder @@ -307,6 +329,28 @@ ABC hierarchy:: :meth:`importlib.machinery.PathFinder.invalidate_caches` when invalidating the caches of all cached finders. + .. method:: discover(parent=None) + + An optional method which searches for possible specs with given *parent* + module spec. If *parent* is *None*, :meth:`PathEntryFinder.discover` will + search for top-level modules. + + Returns an iterable of possible specs. + + Raises :exc:`ValueError` if *parent* is not a package module. + + .. warning:: + This method can potentially yield a very large number of objects, and + it may carry out IO operations when computing these values. + + Because of this, it will generaly be desirable to compute the result + values on-the-fly, as they are needed. As such, the returned object is + only guaranteed to be an :class:`iterable `, + instead of a :class:`list` or other + :class:`collection ` type. + + .. versionadded:: next + .. class:: Loader diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index b576ceb1ce9f6e..213190d2098e75 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1283,6 +1283,23 @@ def find_spec(cls, fullname, path=None, target=None): else: return spec + @classmethod + def discover(cls, parent=None): + if parent is None: + path = sys.path + elif parent.submodule_search_locations is None: + raise ValueError(f'{parent} is not a package module') + else: + path = parent.submodule_search_locations + + for entry in set(path): + if not isinstance(entry, str): + continue + if (finder := cls._path_importer_cache(entry)) is None: + continue + if discover := getattr(finder, 'discover', None): + yield from discover(parent) + @staticmethod def find_distributions(*args, **kwargs): """ @@ -1432,6 +1449,37 @@ def path_hook_for_FileFinder(path): return path_hook_for_FileFinder + def _find_children(self): + with _os.scandir(self.path) as scan_iterator: + while True: + try: + entry = next(scan_iterator) + if entry.name == _PYCACHE: + continue + # packages + if entry.is_dir() and '.' not in entry.name: + yield entry.name + # files + if entry.is_file(): + yield from { + entry.name.removesuffix(suffix) + for suffix, _ in self._loaders + if entry.name.endswith(suffix) + } + except OSError: + pass # ignore exceptions from next(scan_iterator) and os.DirEntry + except StopIteration: + break + + def discover(self, parent=None): + if parent and parent.submodule_search_locations is None: + raise ValueError(f'{parent} is not a package module') + + module_prefix = f'{parent.name}.' if parent else '' + for child_name in self._find_children(): + if spec := self.find_spec(module_prefix + child_name): + yield spec + def __repr__(self): return f'FileFinder({self.path!r})' diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 87922f32d1111b..9ca127ad9c7d0f 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -45,6 +45,16 @@ def invalidate_caches(self): This method is used by importlib.invalidate_caches(). """ + def discover(self, parent=None): + """An optional method which searches for possible specs with given *parent* + module spec. If *parent* is *None*, MetaPathFinder.discover will search + for top-level modules. + + Returns an iterable of possible specs. + """ + return () + + _register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter, machinery.PathFinder, machinery.WindowsRegistryFinder) @@ -58,6 +68,15 @@ def invalidate_caches(self): This method is used by PathFinder.invalidate_caches(). """ + def discover(self, parent=None): + """An optional method which searches for possible specs with given + *parent* module spec. If *parent* is *None*, PathEntryFinder.discover + will search for top-level modules. + + Returns an iterable of possible specs. + """ + return () + _register(PathEntryFinder, machinery.FileFinder) diff --git a/Lib/test/test_importlib/test_discover.py b/Lib/test/test_importlib/test_discover.py new file mode 100644 index 00000000000000..8c5fa65a564c6d --- /dev/null +++ b/Lib/test/test_importlib/test_discover.py @@ -0,0 +1,121 @@ +from unittest.mock import Mock + +from test.test_importlib import util + +importlib = util.import_importlib('importlib') +machinery = util.import_importlib('importlib.machinery') + + +class DiscoverableFinder: + def __init__(self, discover=[]): + self._discovered_values = discover + + def find_spec(self, fullname, path=None, target=None): + raise NotImplemented + + def discover(self, parent=None): + yield from self._discovered_values + + +class TestPathFinder: + """PathFinder implements MetaPathFinder, which uses the PathEntryFinder(s) + registered in sys.path_hooks (and sys.path_importer_cache) to search + sys.path or the parent's __path__. + + PathFinder.discover() should redirect to the .discover() method of the + PathEntryFinder for each path entry. + """ + + def test_search_path_hooks_top_level(self): + modules = [ + self.machinery.ModuleSpec(name='example1', loader=None), + self.machinery.ModuleSpec(name='example2', loader=None), + self.machinery.ModuleSpec(name='example3', loader=None), + ] + + with util.import_state( + path_importer_cache={ + 'discoverable': DiscoverableFinder(discover=modules), + }, + path=['discoverable'], + ): + discovered = list(self.machinery.PathFinder.discover()) + + self.assertEqual(discovered, modules) + + + def test_search_path_hooks_parent(self): + parent = self.machinery.ModuleSpec(name='example', loader=None, is_package=True) + parent.submodule_search_locations.append('discoverable') + + children = [ + self.machinery.ModuleSpec(name='example.child1', loader=None), + self.machinery.ModuleSpec(name='example.child2', loader=None), + self.machinery.ModuleSpec(name='example.child3', loader=None), + ] + + with util.import_state( + path_importer_cache={ + 'discoverable': DiscoverableFinder(discover=children) + }, + path=[], + ): + discovered = list(self.machinery.PathFinder.discover(parent)) + + self.assertEqual(discovered, children) + + def test_invalid_parent(self): + parent = self.machinery.ModuleSpec(name='example', loader=None) + with self.assertRaises(ValueError): + list(self.machinery.PathFinder.discover(parent)) + + +( + Frozen_TestPathFinder, + Source_TestPathFinder, +) = util.test_both(TestPathFinder, importlib=importlib, machinery=machinery) + + +class TestFileFinder: + """FileFinder implements PathEntryFinder and provides the base finder + implementation to search the file system. + """ + + def get_finder(self, path): + loader_details = [ + (self.machinery.SourceFileLoader, self.machinery.SOURCE_SUFFIXES), + (self.machinery.SourcelessFileLoader, self.machinery.BYTECODE_SUFFIXES), + ] + return self.machinery.FileFinder(path, *loader_details) + + def test_discover_top_level(self): + modules = {'example1', 'example2', 'example3'} + with util.create_modules(*modules) as mapping: + finder = self.get_finder(mapping['.root']) + discovered = list(finder.discover()) + self.assertEqual({spec.name for spec in discovered}, modules) + + def test_discover_parent(self): + modules = { + 'example.child1', + 'example.child2', + 'example.child3', + } + with util.create_modules(*modules) as mapping: + example = self.get_finder(mapping['.root']).find_spec('example') + finder = self.get_finder(example.submodule_search_locations[0]) + discovered = list(finder.discover(example)) + self.assertEqual({spec.name for spec in discovered}, modules) + + def test_invalid_parent(self): + with util.create_modules('example') as mapping: + finder = self.get_finder(mapping['.root']) + example = finder.find_spec('example') + with self.assertRaises(ValueError): + list(finder.discover(example)) + + +( + Frozen_TestFileFinder, + Source_TestFileFinder, +) = util.test_both(TestFileFinder, importlib=importlib, machinery=machinery) diff --git a/Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst b/Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst new file mode 100644 index 00000000000000..fe5e7d17ab6c8c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst @@ -0,0 +1,3 @@ +Introduced :meth:`importlib.abc.MetaPathFinder.discover` +and :meth:`importlib.abc.PathEntryFinder.discover` to allow module and submodule +name discovery without assuming the use of traditional filesystem based imports. From f282f7aed91a872078ea88df3d22a780bbd7bee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Thu, 19 Feb 2026 16:10:58 +0000 Subject: [PATCH 166/498] GH-134872: add ModuleNotFoundError suggestions (#142512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gh-134872: Add traceback suggestions for ModuleNotFoundError Signed-off-by: Filipe Laíns * Add news Signed-off-by: Filipe Laíns --------- Signed-off-by: Filipe Laíns --- Lib/traceback.py | 17 +++++++++++++++++ ...26-02-19-15-42-06.gh-issue-134872.sjYX1-.rst | 1 + 2 files changed, 18 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst diff --git a/Lib/traceback.py b/Lib/traceback.py index 42453b4867ce99..b16cd8646e43f1 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -11,6 +11,7 @@ import keyword import tokenize import io +import importlib.util import _colorize from contextlib import suppress @@ -1128,6 +1129,10 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, self._str += (". Site initialization is disabled, did you forget to " + "add the site-packages directory to sys.path " + "or to enable your virtual environment?") + else: + suggestion = _compute_suggestion_error(exc_value, exc_traceback, module_name) + if suggestion: + self._str += f". Did you mean: '{suggestion}'?" elif exc_type and issubclass(exc_type, AttributeError) and \ getattr(exc_value, "name", None) is not None: wrong_name = getattr(exc_value, "name", None) @@ -1717,6 +1722,18 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): d = [x for x in d if x[:1] != '_'] except Exception: return None + elif isinstance(exc_value, ModuleNotFoundError): + try: + if parent_name := wrong_name.rpartition('.')[0]: + parent = importlib.util.find_spec(parent_name) + else: + parent = None + d = [] + for finder in sys.meta_path: + if discover := getattr(finder, 'discover', None): + d += [spec.name for spec in discover(parent)] + except Exception: + return None elif isinstance(exc_value, ImportError): try: mod = __import__(exc_value.name) diff --git a/Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst b/Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst new file mode 100644 index 00000000000000..4654dd060a6b78 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst @@ -0,0 +1 @@ +Add valid import name suggestions on :exc:`ModuleNotFoundError`. From 0341b10a5d790aa70776f881a1c9bc1f75fac602 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:38:26 +0100 Subject: [PATCH 167/498] GH-144679: MSVC tailcall CI no longer needs to specify PlatformToolset (GH-145004) MSVC tailcall CI no longer needs to specify PlatformToolset --- .github/workflows/tail-call.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tail-call.yml b/.github/workflows/tail-call.yml index 1ab225656d694d..32c6aa75e479f8 100644 --- a/.github/workflows/tail-call.yml +++ b/.github/workflows/tail-call.yml @@ -51,7 +51,6 @@ jobs: - name: Build shell: pwsh run: | - $env:PlatformToolset = "v145" ./PCbuild/build.bat --tail-call-interp ${{ matrix.build_flags }} -c Release -p ${{ matrix.architecture }} - name: Test if: matrix.run_tests From 930b3fd1df67eea85d0b1e284d76cb1223ba05f8 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:49:34 +0000 Subject: [PATCH 168/498] `compute-changes.py`: Fix & test `process_changed_files()` (#144674) Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> --- .github/CODEOWNERS | 7 +- Lib/test/test_tools/test_compute_changes.py | 144 ++++++++++++++++++++ Tools/build/compute-changes.py | 12 +- 3 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 Lib/test/test_tools/test_compute_changes.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dcebcbb434643f..67c08c9ddaee9e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -63,9 +63,10 @@ .azure-pipelines/ @AA-Turner # GitHub & related scripts -.github/ @ezio-melotti @hugovk @AA-Turner @webknjaz -Tools/build/compute-changes.py @AA-Turner @hugovk @webknjaz -Tools/build/verify_ensurepip_wheels.py @AA-Turner @pfmoore @pradyunsg +.github/ @ezio-melotti @hugovk @AA-Turner @webknjaz +Tools/build/compute-changes.py @AA-Turner @hugovk @webknjaz +Lib/test/test_tools/test_compute_changes.py @AA-Turner @hugovk @webknjaz +Tools/build/verify_ensurepip_wheels.py @AA-Turner @pfmoore @pradyunsg # Pre-commit .pre-commit-config.yaml @hugovk diff --git a/Lib/test/test_tools/test_compute_changes.py b/Lib/test/test_tools/test_compute_changes.py new file mode 100644 index 00000000000000..b20ff975fc2834 --- /dev/null +++ b/Lib/test/test_tools/test_compute_changes.py @@ -0,0 +1,144 @@ +"""Tests to cover the Tools/build/compute-changes.py script.""" + +import importlib +import os +import unittest +from pathlib import Path +from unittest.mock import patch + +from test.test_tools import skip_if_missing, imports_under_tool + +skip_if_missing("build") + +with patch.dict(os.environ, {"GITHUB_DEFAULT_BRANCH": "main"}): + with imports_under_tool("build"): + compute_changes = importlib.import_module("compute-changes") + +process_changed_files = compute_changes.process_changed_files +Outputs = compute_changes.Outputs +ANDROID_DIRS = compute_changes.ANDROID_DIRS +IOS_DIRS = compute_changes.IOS_DIRS +MACOS_DIRS = compute_changes.MACOS_DIRS +WASI_DIRS = compute_changes.WASI_DIRS +RUN_TESTS_IGNORE = compute_changes.RUN_TESTS_IGNORE +UNIX_BUILD_SYSTEM_FILE_NAMES = compute_changes.UNIX_BUILD_SYSTEM_FILE_NAMES +LIBRARY_FUZZER_PATHS = compute_changes.LIBRARY_FUZZER_PATHS + + +class TestProcessChangedFiles(unittest.TestCase): + + def test_windows(self): + f = {Path(".github/workflows/reusable-windows.yml")} + result = process_changed_files(f) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_windows_tests) + + def test_docs(self): + for f in ( + ".github/workflows/reusable-docs.yml", + "Doc/library/datetime.rst", + "Doc/Makefile", + ): + with self.subTest(f=f): + result = process_changed_files({Path(f)}) + self.assertTrue(result.run_docs) + self.assertFalse(result.run_tests) + + def test_ci_fuzz_stdlib(self): + for p in LIBRARY_FUZZER_PATHS: + with self.subTest(p=p): + if p.is_dir(): + f = p / "file" + elif p.is_file(): + f = p + else: + continue + result = process_changed_files({f}) + self.assertTrue(result.run_ci_fuzz_stdlib) + + def test_android(self): + for d in ANDROID_DIRS: + with self.subTest(d=d): + result = process_changed_files({Path(d) / "file"}) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_android) + self.assertFalse(result.run_windows_tests) + + def test_ios(self): + for d in IOS_DIRS: + with self.subTest(d=d): + result = process_changed_files({Path(d) / "file"}) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_ios) + self.assertFalse(result.run_windows_tests) + + def test_macos(self): + f = {Path(".github/workflows/reusable-macos.yml")} + result = process_changed_files(f) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_macos) + + for d in MACOS_DIRS: + with self.subTest(d=d): + result = process_changed_files({Path(d) / "file"}) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_macos) + self.assertFalse(result.run_windows_tests) + + def test_wasi(self): + f = {Path(".github/workflows/reusable-wasi.yml")} + result = process_changed_files(f) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_wasi) + + for d in WASI_DIRS: + with self.subTest(d=d): + result = process_changed_files({d / "file"}) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_wasi) + self.assertFalse(result.run_windows_tests) + + def test_unix(self): + for f in UNIX_BUILD_SYSTEM_FILE_NAMES: + with self.subTest(f=f): + result = process_changed_files({f}) + self.assertTrue(result.run_tests) + self.assertFalse(result.run_windows_tests) + + def test_msi(self): + for f in ( + ".github/workflows/reusable-windows-msi.yml", + "Tools/msi/build.bat", + ): + with self.subTest(f=f): + result = process_changed_files({Path(f)}) + self.assertTrue(result.run_windows_msi) + + def test_all_run(self): + for f in ( + ".github/workflows/some-new-workflow.yml", + ".github/workflows/build.yml", + ): + with self.subTest(f=f): + result = process_changed_files({Path(f)}) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_android) + self.assertTrue(result.run_ios) + self.assertTrue(result.run_macos) + self.assertTrue(result.run_ubuntu) + self.assertTrue(result.run_wasi) + + def test_all_ignored(self): + for f in RUN_TESTS_IGNORE: + with self.subTest(f=f): + self.assertEqual(process_changed_files({Path(f)}), Outputs()) + + def test_wasi_and_android(self): + f = {Path(".github/workflows/reusable-wasi.yml"), Path("Android/file")} + result = process_changed_files(f) + self.assertTrue(result.run_tests) + self.assertTrue(result.run_wasi) + + +if __name__ == "__main__": + unittest.main() diff --git a/Tools/build/compute-changes.py b/Tools/build/compute-changes.py index 00fd0edd8537bf..67d2b060969660 100644 --- a/Tools/build/compute-changes.py +++ b/Tools/build/compute-changes.py @@ -225,19 +225,27 @@ def process_changed_files(changed_files: Set[Path]) -> Outputs: if file.parent == GITHUB_WORKFLOWS_PATH: if file.name in ("build.yml", "reusable-cifuzz.yml"): - run_tests = run_ci_fuzz = run_ci_fuzz_stdlib = True + run_tests = run_ci_fuzz = run_ci_fuzz_stdlib = run_windows_tests = True has_platform_specific_change = False + continue if file.name == "reusable-docs.yml": run_docs = True + continue + if file.name == "reusable-windows.yml": + run_tests = True + run_windows_tests = True + continue if file.name == "reusable-windows-msi.yml": run_windows_msi = True + continue if file.name == "reusable-macos.yml": run_tests = True platforms_changed.add("macos") + continue if file.name == "reusable-wasi.yml": run_tests = True platforms_changed.add("wasi") - continue + continue if not doc_file and file not in RUN_TESTS_IGNORE: run_tests = True From 6485c8583a112c343525a14cf519275267b95185 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Thu, 19 Feb 2026 19:10:00 +0100 Subject: [PATCH 169/498] GH-144679: Switch to windows-2025-vs2026 build image in GitHub Actions (GH-145005) --- .github/workflows/jit.yml | 4 ++-- .github/workflows/reusable-windows-msi.yml | 2 +- .github/workflows/reusable-windows.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/jit.yml b/.github/workflows/jit.yml index 5a564b63f9d120..9188839b26ee71 100644 --- a/.github/workflows/jit.yml +++ b/.github/workflows/jit.yml @@ -74,10 +74,10 @@ jobs: include: - target: i686-pc-windows-msvc/msvc architecture: Win32 - runner: windows-2025 + runner: windows-2025-vs2026 - target: x86_64-pc-windows-msvc/msvc architecture: x64 - runner: windows-2025 + runner: windows-2025-vs2026 - target: aarch64-pc-windows-msvc/msvc architecture: ARM64 runner: windows-11-arm diff --git a/.github/workflows/reusable-windows-msi.yml b/.github/workflows/reusable-windows-msi.yml index 96fc338c47bf29..42c0dfd9636d30 100644 --- a/.github/workflows/reusable-windows-msi.yml +++ b/.github/workflows/reusable-windows-msi.yml @@ -17,7 +17,7 @@ env: jobs: build: name: installer for ${{ inputs.arch }} - runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025' }} + runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025-vs2026' }} timeout-minutes: 60 env: ARCH: ${{ inputs.arch }} diff --git a/.github/workflows/reusable-windows.yml b/.github/workflows/reusable-windows.yml index 2f6caf2f0044d4..2f667ace9194d7 100644 --- a/.github/workflows/reusable-windows.yml +++ b/.github/workflows/reusable-windows.yml @@ -21,7 +21,7 @@ env: jobs: build: name: Build and test (${{ inputs.arch }}) - runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025' }} + runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025-vs2026' }} timeout-minutes: 60 env: ARCH: ${{ inputs.arch }} From 0f7cd5544a4dd1d7cf892c93c661510d619caaa7 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Thu, 19 Feb 2026 19:29:05 +0100 Subject: [PATCH 170/498] gh-144156: Fix email header folding concatenating encoded words (#144692) The fix for gh-92081 (gh-92281) was unfortunately flawed, and broke whitespace handling for encoded word patterns that had previously been working correctly but had no corresponding tests, unfortunately in a way that made the resulting headers not RFC compliant, in such a way that Yahoo started rejecting the resulting emails. This fix was released in 3.14 alpha 1, 3.13 beta 2 and 3.12.5. This PR fixes the original problem in a way that does not break anything, and in fact fixes a small pre-existing bug (a spurious whitespace after the ':' of the header label if the header value is immediately wrapped on to the next line). (RDM) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: R. David Murray --- Lib/email/_header_value_parser.py | 73 ++++++++++--------- Lib/test/test_email/test_generator.py | 44 +++++++++++ Lib/test/test_email/test_headerregistry.py | 4 +- Lib/test/test_email/test_policy.py | 2 +- ...-02-10-22-05-51.gh-issue-144156.UbrC7F.rst | 1 + 5 files changed, 85 insertions(+), 39 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 172f9ef9e5f096..4c5394ab6353ac 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -80,7 +80,8 @@ # Useful constants and functions # -WSP = set(' \t') +_WSP = ' \t' +WSP = set(_WSP) CFWS_LEADER = WSP | set('(') SPECIALS = set(r'()<>@,:;.\"[]') ATOM_ENDS = SPECIALS | WSP @@ -2835,6 +2836,7 @@ def _steal_trailing_WSP_if_exists(lines): lines.pop() return wsp + def _refold_parse_tree(parse_tree, *, policy): """Return string of contents of parse_tree folded according to RFC rules. @@ -2843,11 +2845,9 @@ def _refold_parse_tree(parse_tree, *, policy): maxlen = policy.max_line_length or sys.maxsize encoding = 'utf-8' if policy.utf8 else 'us-ascii' lines = [''] # Folded lines to be output - leading_whitespace = '' # When we have whitespace between two encoded - # words, we may need to encode the whitespace - # at the beginning of the second word. - last_ew = None # Points to the last encoded character if there's an ew on - # the line + last_word_is_ew = False + last_ew = None # if there is an encoded word in the last line of lines, + # points to the encoded word's first character last_charset = None wrap_as_ew_blocked = 0 want_encoding = False # This is set to True if we need to encode this part @@ -2882,6 +2882,7 @@ def _refold_parse_tree(parse_tree, *, policy): if part.token_type == 'mime-parameters': # Mime parameter folding (using RFC2231) is extra special. _fold_mime_parameters(part, lines, maxlen, encoding) + last_word_is_ew = False continue if want_encoding and not wrap_as_ew_blocked: @@ -2898,6 +2899,7 @@ def _refold_parse_tree(parse_tree, *, policy): # XXX what if encoded_part has no leading FWS? lines.append(newline) lines[-1] += encoded_part + last_word_is_ew = False continue # Either this is not a major syntactic break, so we don't # want it on a line by itself even if it fits, or it @@ -2916,11 +2918,16 @@ def _refold_parse_tree(parse_tree, *, policy): (last_charset == 'unknown-8bit' or last_charset == 'utf-8' and charset != 'us-ascii')): last_ew = None - last_ew = _fold_as_ew(tstr, lines, maxlen, last_ew, - part.ew_combine_allowed, charset, leading_whitespace) - # This whitespace has been added to the lines in _fold_as_ew() - # so clear it now. - leading_whitespace = '' + last_ew = _fold_as_ew( + tstr, + lines, + maxlen, + last_ew, + part.ew_combine_allowed, + charset, + last_word_is_ew, + ) + last_word_is_ew = True last_charset = charset want_encoding = False continue @@ -2933,28 +2940,19 @@ def _refold_parse_tree(parse_tree, *, policy): if len(tstr) <= maxlen - len(lines[-1]): lines[-1] += tstr + last_word_is_ew = last_word_is_ew and not bool(tstr.strip(_WSP)) continue # This part is too long to fit. The RFC wants us to break at # "major syntactic breaks", so unless we don't consider this # to be one, check if it will fit on the next line by itself. - leading_whitespace = '' if (part.syntactic_break and len(tstr) + 1 <= maxlen): newline = _steal_trailing_WSP_if_exists(lines) if newline or part.startswith_fws(): - # We're going to fold the data onto a new line here. Due to - # the way encoded strings handle continuation lines, we need to - # be prepared to encode any whitespace if the next line turns - # out to start with an encoded word. lines.append(newline + tstr) - - whitespace_accumulator = [] - for char in lines[-1]: - if char not in WSP: - break - whitespace_accumulator.append(char) - leading_whitespace = ''.join(whitespace_accumulator) + last_word_is_ew = (last_word_is_ew + and not bool(lines[-1].strip(_WSP))) last_ew = None continue if not hasattr(part, 'encode'): @@ -2994,10 +2992,11 @@ def _refold_parse_tree(parse_tree, *, policy): else: # We can't fold it onto the next line either... lines[-1] += tstr + last_word_is_ew = last_word_is_ew and not bool(tstr.strip(_WSP)) return policy.linesep.join(lines) + policy.linesep -def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset, leading_whitespace): +def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset, last_word_is_ew): """Fold string to_encode into lines as encoded word, combining if allowed. Return the new value for last_ew, or None if ew_combine_allowed is False. @@ -3012,6 +3011,16 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset, to_encode = str( get_unstructured(lines[-1][last_ew:] + to_encode)) lines[-1] = lines[-1][:last_ew] + elif last_word_is_ew: + # If we are following up an encoded word with another encoded word, + # any white space between the two will be ignored when decoded. + # Therefore, we encode all to-be-displayed whitespace in the second + # encoded word. + len_without_wsp = len(lines[-1].rstrip(_WSP)) + leading_whitespace = lines[-1][len_without_wsp:] + lines[-1] = (lines[-1][:len_without_wsp] + + (' ' if leading_whitespace else '')) + to_encode = leading_whitespace + to_encode elif to_encode[0] in WSP: # We're joining this to non-encoded text, so don't encode # the leading blank. @@ -3040,20 +3049,13 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset, while to_encode: remaining_space = maxlen - len(lines[-1]) - text_space = remaining_space - chrome_len - len(leading_whitespace) + text_space = remaining_space - chrome_len if text_space <= 0: - lines.append(' ') + newline = _steal_trailing_WSP_if_exists(lines) + lines.append(newline or ' ') + new_last_ew = len(lines[-1]) continue - # If we are at the start of a continuation line, prepend whitespace - # (we only want to do this when the line starts with an encoded word - # but if we're folding in this helper function, then we know that we - # are going to be writing out an encoded word.) - if len(lines) > 1 and len(lines[-1]) == 1 and leading_whitespace: - encoded_word = _ew.encode(leading_whitespace, charset=encode_as) - lines[-1] += encoded_word - leading_whitespace = '' - to_encode_word = to_encode[:text_space] encoded_word = _ew.encode(to_encode_word, charset=encode_as) excess = len(encoded_word) - remaining_space @@ -3065,7 +3067,6 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset, excess = len(encoded_word) - remaining_space lines[-1] += encoded_word to_encode = to_encode[len(to_encode_word):] - leading_whitespace = '' if to_encode: lines.append(' ') diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py index 3ca79edf6a65d9..c2d7d09d591e86 100644 --- a/Lib/test/test_email/test_generator.py +++ b/Lib/test/test_email/test_generator.py @@ -393,6 +393,50 @@ def test_defaults_handle_spaces_at_start_of_continuation_line(self): g.flatten(msg) self.assertEqual(s.getvalue(), expected) + # gh-144156: fold between non-encoded and encoded words don't need to encoded + # the separating space + def test_defaults_handle_spaces_at_start_of_continuation_line_2(self): + source = ("Re: [SOS-1495488] Commande et livraison - Demande de retour - " + "bibijolie - 251210-AABBCC - Abo actualités digitales 20 semaines " + "d’abonnement à 24 heures, Bilan, Tribune de Genève et tous les titres Tamedia") + expected = ( + b"Subject: " + b"Re: [SOS-1495488] Commande et livraison - Demande de retour -\n" + b" bibijolie - 251210-AABBCC - Abo =?utf-8?q?actualit=C3=A9s?= digitales 20\n" + b" semaines =?utf-8?q?d=E2=80=99abonnement_=C3=A0?= 24 heures, Bilan, Tribune de\n" + b" =?utf-8?q?Gen=C3=A8ve?= et tous les titres Tamedia\n\n" + ) + msg = EmailMessage() + msg['Subject'] = source + s = io.BytesIO() + g = BytesGenerator(s) + g.flatten(msg) + self.assertEqual(s.getvalue(), expected) + + def test_ew_folding_round_trip_1(self): + print() + source = "aaaaaaaaa фффффффф " + msg = EmailMessage() + msg['Subject'] = source + s = io.BytesIO() + g = BytesGenerator(s, maxheaderlen=30) + g.flatten(msg) + flat = s.getvalue() + reparsed = message_from_bytes(flat, policy=policy.default)['Subject'] + self.assertMultiLineEqual(reparsed, source) + + def test_ew_folding_round_trip_2(self): + print() + source = "aaa aaaaaaa aaa ффф фффф " + msg = EmailMessage() + msg['Subject'] = source + s = io.BytesIO() + g = BytesGenerator(s, maxheaderlen=30) + g.flatten(msg) + flat = s.getvalue() + reparsed = message_from_bytes(flat, policy=policy.default)['Subject'] + self.assertMultiLineEqual(reparsed, source) + def test_cte_type_7bit_handles_unknown_8bit(self): source = ("Subject: Maintenant je vous présente mon " "collègue\n\n").encode('utf-8') diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index 95c6afbee41ef5..c9c63951597244 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -1711,7 +1711,7 @@ def test_fold_unstructured_with_overlong_word(self): 'singlewordthatwontfit') self.assertEqual( h.fold(policy=policy.default.clone(max_line_length=20)), - 'Subject: \n' + 'Subject:\n' ' =?utf-8?q?thisisa?=\n' ' =?utf-8?q?verylon?=\n' ' =?utf-8?q?glineco?=\n' @@ -1727,7 +1727,7 @@ def test_fold_unstructured_with_two_overlong_words(self): 'singlewordthatwontfit plusanotherverylongwordthatwontfit') self.assertEqual( h.fold(policy=policy.default.clone(max_line_length=20)), - 'Subject: \n' + 'Subject:\n' ' =?utf-8?q?thisisa?=\n' ' =?utf-8?q?verylon?=\n' ' =?utf-8?q?glineco?=\n' diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py index 71ec0febb0fd86..90e8e5580295f9 100644 --- a/Lib/test/test_email/test_policy.py +++ b/Lib/test/test_email/test_policy.py @@ -273,7 +273,7 @@ def test_non_ascii_chars_do_not_cause_inf_loop(self): actual = policy.fold('Subject', 'ą' * 12) self.assertEqual( actual, - 'Subject: \n' + + 'Subject:\n' + 12 * ' =?utf-8?q?=C4=85?=\n') def test_short_maxlen_error(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst new file mode 100644 index 00000000000000..c4a065528512e1 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst @@ -0,0 +1 @@ +Fix the folding of headers by the :mod:`email` library when :rfc:`2047` encoded words are used. Now whitespace is correctly preserved and also correctly added between adjacent encoded words. The latter property was broken by the fix for gh-92081, which mostly fixed previous failures to preserve whitespace. From b5c8e6e1334f1756ead5e2cd5966731844428e2c Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Thu, 19 Feb 2026 20:45:59 +0100 Subject: [PATCH 171/498] gh-100239: Use ``PyFloat_AS_DOUBLE`` and `_PyLong_IsZero`` in the float / compactlong specializations (#144826) --- .../2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst | 2 ++ Python/specialize.c | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst new file mode 100644 index 00000000000000..3cfc3e930d1e9d --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst @@ -0,0 +1,2 @@ +Speedup ``BINARY_OP_EXTEND`` for exact floats and medium-size integers by up +to 15%. Patch by Chris Eibl. diff --git a/Python/specialize.c b/Python/specialize.c index 4d3ba4acbbf038..1eabdb1b5b194e 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2100,7 +2100,7 @@ float_compactlong_guard(PyObject *lhs, PyObject *rhs) { return ( PyFloat_CheckExact(lhs) && - !isnan(PyFloat_AsDouble(lhs)) && + !isnan(PyFloat_AS_DOUBLE(lhs)) && PyLong_CheckExact(rhs) && _PyLong_IsCompact((PyLongObject *)rhs) ); @@ -2110,7 +2110,7 @@ static inline int nonzero_float_compactlong_guard(PyObject *lhs, PyObject *rhs) { return ( - float_compactlong_guard(lhs, rhs) && !PyLong_IsZero(rhs) + float_compactlong_guard(lhs, rhs) && !_PyLong_IsZero((PyLongObject*)rhs) ); } @@ -2118,7 +2118,7 @@ nonzero_float_compactlong_guard(PyObject *lhs, PyObject *rhs) static PyObject * \ (NAME)(PyObject *lhs, PyObject *rhs) \ { \ - double lhs_val = PyFloat_AsDouble(lhs); \ + double lhs_val = PyFloat_AS_DOUBLE(lhs); \ Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \ return PyFloat_FromDouble(lhs_val OP rhs_val); \ } @@ -2137,7 +2137,7 @@ compactlong_float_guard(PyObject *lhs, PyObject *rhs) PyLong_CheckExact(lhs) && _PyLong_IsCompact((PyLongObject *)lhs) && PyFloat_CheckExact(rhs) && - !isnan(PyFloat_AsDouble(rhs)) + !isnan(PyFloat_AS_DOUBLE(rhs)) ); } @@ -2145,7 +2145,7 @@ static inline int nonzero_compactlong_float_guard(PyObject *lhs, PyObject *rhs) { return ( - compactlong_float_guard(lhs, rhs) && PyFloat_AsDouble(rhs) != 0.0 + compactlong_float_guard(lhs, rhs) && PyFloat_AS_DOUBLE(rhs) != 0.0 ); } @@ -2153,7 +2153,7 @@ nonzero_compactlong_float_guard(PyObject *lhs, PyObject *rhs) static PyObject * \ (NAME)(PyObject *lhs, PyObject *rhs) \ { \ - double rhs_val = PyFloat_AsDouble(rhs); \ + double rhs_val = PyFloat_AS_DOUBLE(rhs); \ Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \ return PyFloat_FromDouble(lhs_val OP rhs_val); \ } From 87c4fc1321b8e5dae4db8d2ca9e335276c2ccfc3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 19 Feb 2026 15:18:37 -0500 Subject: [PATCH 172/498] Add myself as a codeowner for the C API documentation (#145017) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 67c08c9ddaee9e..f656e8e52cd3dc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -111,6 +111,7 @@ Doc/tools/ @AA-Turner @hugovk .readthedocs.yml @AA-Turner # Sections +Doc/c-api/ @ZeroIntensity Doc/reference/ @willingc @AA-Turner Doc/whatsnew/ @AA-Turner From 50c14719fbd47f500dd1a468998201d22475126d Mon Sep 17 00:00:00 2001 From: Shamil Date: Thu, 19 Feb 2026 23:42:55 +0300 Subject: [PATCH 173/498] gh-144986: Fix memory leak in atexit.register() (#144987) --- .../2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst | 2 ++ Modules/atexitmodule.c | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst b/Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst new file mode 100644 index 00000000000000..841c3758ec4df1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst @@ -0,0 +1,2 @@ +Fix a memory leak in :func:`atexit.register`. +Patch by Shamil Abdulaev. diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index 1c901d9124d9ca..3ddbbd59a1ef0c 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -185,6 +185,9 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs) return NULL; } PyObject *func_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (func_args == NULL) { + return NULL; + } PyObject *func_kwargs = kwargs; if (func_kwargs == NULL) @@ -192,6 +195,7 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs) func_kwargs = Py_None; } PyObject *callback = PyTuple_Pack(3, func, func_args, func_kwargs); + Py_DECREF(func_args); if (callback == NULL) { return NULL; From beb8e3f2763d35ed85ae4bb82ef0073dfaaa3a67 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 19 Feb 2026 22:13:16 +0100 Subject: [PATCH 174/498] gh-141510: Document ParameterizedMIMEHeader.params change (#145003) Document also the dataclasses.field() metadata change. --- Doc/library/dataclasses.rst | 4 ++++ Doc/library/email.headerregistry.rst | 4 ++++ .../Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst | 3 +++ .../Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst | 3 +++ 4 files changed, 14 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index cff36e258224d3..2864149a08fd50 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -333,6 +333,10 @@ Module contents :attr:`!C.t` will be ``20``, and the class attributes :attr:`!C.x` and :attr:`!C.y` will not be set. + .. versionchanged:: next + If *metadata* is ``None``, use an empty :class:`frozendict`, instead + of a :func:`~types.MappingProxyType` of an empty :class:`dict`. + .. class:: Field :class:`!Field` objects describe each defined field. These objects diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index ff8b601fe3d1bb..f4c11821c4b91d 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -269,6 +269,10 @@ variant, :attr:`~.BaseHeader.max_count` is set to 1. A dictionary mapping parameter names to parameter values. + .. versionchanged:: next + It is now a :class:`frozendict` instead of a + :class:`types.MappingProxyType`. + .. class:: ContentTypeHeader diff --git a/Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst b/Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst new file mode 100644 index 00000000000000..cf22e82b8415b8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst @@ -0,0 +1,3 @@ +``ParameterizedMIMEHeader.params`` of :mod:`email.headerregistry` is now a +:class:`frozendict` instead of a :class:`types.MappingProxyType`. Patch by +Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst b/Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst new file mode 100644 index 00000000000000..ae46ff0cbdd8b1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst @@ -0,0 +1,3 @@ +:func:`dataclasses.field`: if *metadata* is ``None``, use an empty +:class:`frozendict`, instead of a :func:`~types.MappingProxyType` of an +empty :class:`dict`. Patch by Victor Stinner. From 4141f0a1ee6a6e9d5b4ba24f15a9d17df6933321 Mon Sep 17 00:00:00 2001 From: J Berg Date: Thu, 19 Feb 2026 22:48:01 +0000 Subject: [PATCH 175/498] Correct MAX_N in Lib/zipfile ZipExtFile (GH-144973) "<<" has lower precedence than "-". --- Lib/test/test_compile.py | 4 ++-- Lib/test/test_unpack_ex.py | 4 ++-- Lib/zipfile/__init__.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 591332cb5b9bcf..302b2c21935efe 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -249,8 +249,8 @@ def test_32_63_bit_values(self): d = -281474976710656 # 1 << 48 e = +4611686018427387904 # 1 << 62 f = -4611686018427387904 # 1 << 62 - g = +9223372036854775807 # 1 << 63 - 1 - h = -9223372036854775807 # 1 << 63 - 1 + g = +9223372036854775807 # (1 << 63) - 1 + h = -9223372036854775807 # (1 << 63) - 1 for variable in self.test_32_63_bit_values.__code__.co_consts: if variable is not None: diff --git a/Lib/test/test_unpack_ex.py b/Lib/test/test_unpack_ex.py index d147cd96d207db..904cf4f626ae78 100644 --- a/Lib/test/test_unpack_ex.py +++ b/Lib/test/test_unpack_ex.py @@ -543,13 +543,13 @@ Some size constraints (all fail.) - >>> s = ", ".join("a%d" % i for i in range(1<<8)) + ", *rest = range(1<<8 + 1)" + >>> s = ", ".join("a%d" % i for i in range(1<<8)) + ", *rest = range((1<<8) + 1)" >>> compile(s, 'test', 'exec') # doctest:+ELLIPSIS Traceback (most recent call last): ... SyntaxError: too many expressions in star-unpacking assignment - >>> s = ", ".join("a%d" % i for i in range(1<<8 + 1)) + ", *rest = range(1<<8 + 2)" + >>> s = ", ".join("a%d" % i for i in range((1<<8) + 1)) + ", *rest = range((1<<8) + 2)" >>> compile(s, 'test', 'exec') # doctest:+ELLIPSIS Traceback (most recent call last): ... diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 8234bf52d39c5f..51e0ce9fa36d7e 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -950,7 +950,7 @@ class ZipExtFile(io.BufferedIOBase): """ # Max size supported by decompressor. - MAX_N = 1 << 31 - 1 + MAX_N = (1 << 31) - 1 # Read from compressed files in 4k blocks. MIN_READ_SIZE = 4096 From 852ec189784d6f11e6c2e29961d21b2ba4b59c68 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 19 Feb 2026 18:45:28 -0500 Subject: [PATCH 176/498] Docs: remove unneeded author attributions (#145002) These directives are not maintained and misleadingly indicate individual rather than community ownership. See https://github.com/python/docs-community/issues/180 for discussion, and https://github.com/python/devguide/pull/1740 for an update to the devguide. Also ensured that everyone is in the Misc/ACKS file. --- Doc/c-api/buffer.rst | 5 ----- Doc/c-api/code.rst | 2 -- Doc/c-api/init.rst | 8 -------- Doc/c-api/memory.rst | 4 ---- Doc/c-api/set.rst | 3 --- Doc/c-api/typeobj.rst | 15 --------------- Doc/c-api/unicode.rst | 3 --- Doc/extending/extending.rst | 3 --- Doc/extending/newtypes_tutorial.rst | 5 ----- Doc/extending/windows.rst | 6 ------ Doc/howto/logging-cookbook.rst | 3 --- Doc/library/abc.rst | 4 ---- Doc/library/argparse.rst | 3 --- Doc/library/ast.rst | 3 --- Doc/library/atexit.rst | 3 --- Doc/library/bisect.rst | 3 --- Doc/library/bz2.rst | 5 ----- Doc/library/calendar.rst | 2 -- Doc/library/cmd.rst | 4 ---- Doc/library/codecs.rst | 6 ------ Doc/library/codeop.rst | 3 --- Doc/library/collections.abc.rst | 3 --- Doc/library/collections.rst | 3 --- Doc/library/colorsys.rst | 2 -- Doc/library/concurrent.interpreters.rst | 3 --- Doc/library/configparser.rst | 7 ------- Doc/library/contextvars.rst | 2 -- Doc/library/csv.rst | 2 -- Doc/library/ctypes.rst | 2 -- Doc/library/curses.ascii.rst | 3 --- Doc/library/curses.panel.rst | 2 -- Doc/library/curses.rst | 6 ------ Doc/library/dataclasses.rst | 3 --- Doc/library/datetime.rst | 4 ---- Doc/library/decimal.rst | 8 -------- Doc/library/difflib.rst | 4 ---- Doc/library/doctest.rst | 5 ----- Doc/library/email.contentmanager.rst | 3 --- Doc/library/email.headerregistry.rst | 3 --- Doc/library/email.message.rst | 3 --- Doc/library/email.policy.rst | 3 --- Doc/library/email.rst | 3 --- Doc/library/enum.rst | 5 ----- Doc/library/fcntl.rst | 2 -- Doc/library/filecmp.rst | 2 -- Doc/library/fileinput.rst | 3 --- Doc/library/fractions.rst | 3 --- Doc/library/functools.rst | 7 ------- Doc/library/gc.rst | 3 --- Doc/library/getpass.rst | 4 ---- Doc/library/gettext.rst | 3 --- Doc/library/hashlib.rst | 5 ----- Doc/library/heapq.rst | 5 ----- Doc/library/hmac.rst | 3 --- Doc/library/html.entities.rst | 2 -- Doc/library/http.cookiejar.rst | 3 --- Doc/library/http.cookies.rst | 3 --- Doc/library/idle.rst | 2 -- Doc/library/imaplib.rst | 8 -------- Doc/library/importlib.rst | 3 --- Doc/library/inspect.rst | 3 --- Doc/library/io.rst | 8 -------- Doc/library/ipaddress.rst | 2 -- Doc/library/itertools.rst | 3 --- Doc/library/json.rst | 3 --- Doc/library/linecache.rst | 2 -- Doc/library/locale.rst | 3 --- Doc/library/logging.config.rst | 3 --- Doc/library/logging.handlers.rst | 3 --- Doc/library/logging.rst | 3 --- Doc/library/lzma.rst | 3 --- Doc/library/mailbox.rst | 3 --- Doc/library/mimetypes.rst | 2 -- Doc/library/modulefinder.rst | 2 -- Doc/library/msvcrt.rst | 2 -- Doc/library/netrc.rst | 3 --- Doc/library/operator.rst | 2 -- Doc/library/optparse.rst | 3 --- Doc/library/pickle.rst | 3 --- Doc/library/platform.rst | 3 --- Doc/library/plistlib.rst | 4 ---- Doc/library/poplib.rst | 3 --- Doc/library/posix.rst | 2 -- Doc/library/pprint.rst | 3 --- Doc/library/pty.rst | 5 ----- Doc/library/py_compile.rst | 3 --- Doc/library/pyclbr.rst | 2 -- Doc/library/pydoc.rst | 3 --- Doc/library/pyexpat.rst | 7 ------- Doc/library/re.rst | 5 ----- Doc/library/readline.rst | 2 -- Doc/library/reprlib.rst | 2 -- Doc/library/resource.rst | 3 --- Doc/library/rlcompleter.rst | 2 -- Doc/library/runpy.rst | 2 -- Doc/library/sched.rst | 2 -- Doc/library/secrets.rst | 2 -- Doc/library/shlex.rst | 5 ----- Doc/library/shutil.rst | 3 --- Doc/library/smtplib.rst | 2 -- Doc/library/sqlite3.rst | 2 -- Doc/library/ssl.rst | 3 --- Doc/library/stat.rst | 2 -- Doc/library/statistics.rst | 3 --- Doc/library/stringprep.rst | 3 --- Doc/library/subprocess.rst | 3 --- Doc/library/symtable.rst | 4 ---- Doc/library/sysconfig.rst | 3 --- Doc/library/tabnanny.rst | 5 ----- Doc/library/tarfile.rst | 3 --- Doc/library/tempfile.rst | 2 -- Doc/library/test.rst | 2 -- Doc/library/textwrap.rst | 3 --- Doc/library/tkinter.rst | 2 -- Doc/library/tkinter.scrolledtext.rst | 2 -- Doc/library/tkinter.ttk.rst | 2 -- Doc/library/token.rst | 2 -- Doc/library/tokenize.rst | 3 --- Doc/library/tomllib.rst | 3 --- Doc/library/tty.rst | 3 --- Doc/library/turtle.rst | 2 -- Doc/library/unicodedata.rst | 4 ---- Doc/library/unittest.mock-examples.rst | 1 - Doc/library/unittest.mock.rst | 1 - Doc/library/unittest.rst | 5 ----- Doc/library/urllib.error.rst | 3 --- Doc/library/urllib.request.rst | 4 ---- Doc/library/urllib.robotparser.rst | 2 -- Doc/library/uuid.rst | 2 -- Doc/library/venv.rst | 3 --- Doc/library/wave.rst | 3 --- Doc/library/weakref.rst | 5 ----- Doc/library/webbrowser.rst | 3 --- Doc/library/winreg.rst | 2 -- Doc/library/winsound.rst | 3 --- Doc/library/wsgiref.rst | 3 --- Doc/library/xml.dom.minidom.rst | 4 ---- Doc/library/xml.dom.pulldom.rst | 2 -- Doc/library/xml.dom.rst | 3 --- Doc/library/xml.etree.elementtree.rst | 2 -- Doc/library/xml.rst | 3 --- Doc/library/xml.sax.handler.rst | 3 --- Doc/library/xml.sax.reader.rst | 3 --- Doc/library/xml.sax.rst | 4 ---- Doc/library/xml.sax.utils.rst | 3 --- Doc/library/xmlrpc.client.rst | 3 --- Doc/library/xmlrpc.server.rst | 3 --- Doc/library/zipfile.rst | 3 --- Doc/library/zipimport.rst | 2 -- Doc/library/zoneinfo.rst | 3 --- Doc/tutorial/controlflow.rst | 2 -- Doc/tutorial/datastructures.rst | 5 ----- Doc/tutorial/floatingpoint.rst | 4 ---- Doc/using/mac.rst | 3 --- Doc/using/unix.rst | 3 --- Doc/using/windows.rst | 2 -- Misc/ACKS | 12 ++++++++++++ 157 files changed, 12 insertions(+), 515 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index 6bb72a2312be3b..e00b28ca4d7a7e 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -10,11 +10,6 @@ Buffer Protocol --------------- -.. sectionauthor:: Greg Stein -.. sectionauthor:: Benjamin Peterson -.. sectionauthor:: Stefan Krah - - Certain objects available in Python wrap access to an underlying memory array or *buffer*. Such objects include the built-in :class:`bytes` and :class:`bytearray`, and some extension types like :class:`array.array`. diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 048bc2c2154e77..be2c85ec97489e 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -7,8 +7,6 @@ Code Objects ------------ -.. sectionauthor:: Jeffrey Yasskin - Code objects are a low-level detail of the CPython implementation. Each one represents a chunk of executable code that hasn't yet been bound into a function. diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 6786aa76563f52..52ed9e0647780b 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1916,9 +1916,6 @@ pointer and a void pointer argument. Profiling and Tracing ===================== -.. sectionauthor:: Fred L. Drake, Jr. - - The Python interpreter provides some low-level support for attaching profiling and execution tracing facilities. These are used for profiling, debugging, and coverage analysis tools. @@ -2148,9 +2145,6 @@ Reference tracing Advanced Debugger Support ========================= -.. sectionauthor:: Fred L. Drake, Jr. - - These functions are only intended to be used by advanced debugging tools. @@ -2187,8 +2181,6 @@ These functions are only intended to be used by advanced debugging tools. Thread Local Storage Support ============================ -.. sectionauthor:: Masayuki Yamamoto - The Python interpreter provides low-level support for thread-local storage (TLS) which wraps the underlying native TLS implementation to support the Python-level thread local storage API (:class:`threading.local`). The diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 58f0de5d0fc541..563c5d96b05362 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -7,10 +7,6 @@ Memory Management ***************** -.. sectionauthor:: Vladimir Marangozov - - - .. _memoryoverview: Overview diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index b74859dd669c54..6974f74fbd597a 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -5,9 +5,6 @@ Set Objects ----------- -.. sectionauthor:: Raymond D. Hettinger - - .. index:: pair: object; set pair: object; frozenset diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index a33da367e6071f..bc134b5d00b4ad 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2632,9 +2632,6 @@ This is done by filling a :c:type:`PyType_Spec` structure and calling Number Object Structures ------------------------ -.. sectionauthor:: Amaury Forgeot d'Arc - - .. c:type:: PyNumberMethods This structure holds pointers to the functions which an object uses to @@ -2852,9 +2849,6 @@ Number Object Structures Mapping Object Structures ------------------------- -.. sectionauthor:: Amaury Forgeot d'Arc - - .. c:type:: PyMappingMethods This structure holds pointers to the functions which an object uses to @@ -2895,9 +2889,6 @@ Mapping Object Structures Sequence Object Structures -------------------------- -.. sectionauthor:: Amaury Forgeot d'Arc - - .. c:type:: PySequenceMethods This structure holds pointers to the functions which an object uses to @@ -2991,10 +2982,6 @@ Sequence Object Structures Buffer Object Structures ------------------------ -.. sectionauthor:: Greg J. Stein -.. sectionauthor:: Benjamin Peterson -.. sectionauthor:: Stefan Krah - .. c:type:: PyBufferProcs This structure holds pointers to the functions required by the @@ -3090,8 +3077,6 @@ Buffer Object Structures Async Object Structures ----------------------- -.. sectionauthor:: Yury Selivanov - .. versionadded:: 3.5 .. c:type:: PyAsyncMethods diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index d2b6643c700e88..4845e0f300278d 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -5,9 +5,6 @@ Unicode Objects and Codecs -------------------------- -.. sectionauthor:: Marc-André Lemburg -.. sectionauthor:: Georg Brandl - Unicode Objects ^^^^^^^^^^^^^^^ diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index c0066d315d092b..d33cbd2813d637 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -903,9 +903,6 @@ define this symbol). Providing a C API for an Extension Module ========================================= -.. sectionauthor:: Konrad Hinsen - - Many extension modules just provide new functions and types to be used from Python, but sometimes the code in an extension module can be useful for other extension modules. For example, an extension module could implement a type diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 3bbee33bd50698..9f3cd1d6f4cf33 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -6,11 +6,6 @@ Defining Extension Types: Tutorial ********************************** -.. sectionauthor:: Michael Hudson -.. sectionauthor:: Dave Kuhlman -.. sectionauthor:: Jim Fulton - - Python allows the writer of a C extension module to define new types that can be manipulated from Python code, much like the built-in :class:`str` and :class:`list` types. The code for all extension types follows a diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst index a97c6182553c30..cd81b443603d17 100644 --- a/Doc/extending/windows.rst +++ b/Doc/extending/windows.rst @@ -47,9 +47,6 @@ things manually, it may be instructive to study the project file for the Differences Between Unix and Windows ==================================== -.. sectionauthor:: Chris Phoenix - - Unix and Windows use completely different paradigms for run-time loading of code. Before you try to build a module that can be dynamically loaded, be aware of how your system works. @@ -109,9 +106,6 @@ separate copy. Using DLLs in Practice ====================== -.. sectionauthor:: Chris Phoenix - - Windows Python is built in Microsoft Visual C++; using other compilers may or may not work. The rest of this section is MSVC++ specific. diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 9633bc75f2c914..b87ac93296b915 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -1564,9 +1564,6 @@ process. This can be set up using a process management tool such as Supervisor - Using file rotation ------------------- -.. sectionauthor:: Doug Hellmann, Vinay Sajip (changes) -.. (see ) - Sometimes you want to let a log file grow to a certain size, then open a new file and log to that. You may want to keep a certain number of these files, and when that many files have been created, rotate the files so that the number of diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 49e541a9d9b1cb..8112cfee7d204d 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -4,10 +4,6 @@ .. module:: abc :synopsis: Abstract base classes according to :pep:`3119`. -.. moduleauthor:: Guido van Rossum -.. sectionauthor:: Georg Brandl -.. much of the content adapted from docstrings - **Source code:** :source:`Lib/abc.py` -------------- diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 60411b0a0c9748..ebcf8bf4dac002 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -4,9 +4,6 @@ .. module:: argparse :synopsis: Command-line option and argument parsing library. -.. moduleauthor:: Steven Bethard -.. sectionauthor:: Steven Bethard - .. versionadded:: 3.2 **Source code:** :source:`Lib/argparse.py` diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 8815187ea8c884..9660ad70932764 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -4,9 +4,6 @@ .. module:: ast :synopsis: Abstract Syntax Tree classes and manipulation. -.. sectionauthor:: Martin v. Löwis -.. sectionauthor:: Georg Brandl - .. testsetup:: import ast diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst index 24a3492ba10c91..b5caf5502d0e1c 100644 --- a/Doc/library/atexit.rst +++ b/Doc/library/atexit.rst @@ -4,9 +4,6 @@ .. module:: atexit :synopsis: Register and execute cleanup functions. -.. moduleauthor:: Skip Montanaro -.. sectionauthor:: Skip Montanaro - -------------- The :mod:`!atexit` module defines functions to register and unregister cleanup diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 3efa3999171646..7f75e85a7eb641 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -3,9 +3,6 @@ .. module:: bisect :synopsis: Array bisection algorithms for binary searching. -.. sectionauthor:: Fred L. Drake, Jr. -.. sectionauthor:: Raymond Hettinger -.. example based on the PyModules FAQ entry by Aaron Watters **Source code:** :source:`Lib/bisect.py` diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 32e223ddbdd8a2..6c20e9c94a3eae 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -4,11 +4,6 @@ .. module:: bz2 :synopsis: Interfaces for bzip2 compression and decompression. -.. moduleauthor:: Gustavo Niemeyer -.. moduleauthor:: Nadeem Vawda -.. sectionauthor:: Gustavo Niemeyer -.. sectionauthor:: Nadeem Vawda - **Source code:** :source:`Lib/bz2.py` -------------- diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index 48472840eab319..54cafaf4fe47d8 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -5,8 +5,6 @@ :synopsis: Functions for working with calendars, including some emulation of the Unix cal program. -.. sectionauthor:: Drew Csillag - **Source code:** :source:`Lib/calendar.py` -------------- diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index 1757dedabbf633..c988fcebd68a01 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -4,8 +4,6 @@ .. module:: cmd :synopsis: Build line-oriented command interpreters. -.. sectionauthor:: Eric S. Raymond - **Source code:** :source:`Lib/cmd.py` -------------- @@ -243,8 +241,6 @@ Instances of :class:`Cmd` subclasses have some public instance variables: Cmd Example ----------- -.. sectionauthor:: Raymond Hettinger - The :mod:`!cmd` module is mainly useful for building custom shells that let a user work with a program interactively. diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 36f5e94b8477ec..9259ab10d5850b 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -4,10 +4,6 @@ .. module:: codecs :synopsis: Encode and decode data and streams. -.. moduleauthor:: Marc-André Lemburg -.. sectionauthor:: Marc-André Lemburg -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/codecs.py` .. index:: @@ -1616,7 +1612,6 @@ This module implements the following exception: .. module:: encodings.idna :synopsis: Internationalized Domain Names implementation -.. moduleauthor:: Martin v. Löwis This module implements :rfc:`3490` (Internationalized Domain Names in Applications) and :rfc:`3492` (Nameprep: A Stringprep Profile for @@ -1700,7 +1695,6 @@ This module implements the ANSI codepage (CP_ACP). .. module:: encodings.utf_8_sig :synopsis: UTF-8 codec with BOM signature -.. moduleauthor:: Walter Dörwald This module implements a variant of the UTF-8 codec. On encoding, a UTF-8 encoded BOM will be prepended to the UTF-8 encoded bytes. For the stateful encoder this diff --git a/Doc/library/codeop.rst b/Doc/library/codeop.rst index 2e6d65980381ad..622e57d2ee63db 100644 --- a/Doc/library/codeop.rst +++ b/Doc/library/codeop.rst @@ -4,9 +4,6 @@ .. module:: codeop :synopsis: Compile (possibly incomplete) Python code. -.. sectionauthor:: Moshe Zadka -.. sectionauthor:: Michael Hudson - **Source code:** :source:`Lib/codeop.py` -------------- diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index e6daccb91f2b4e..51853725b1b297 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -4,9 +4,6 @@ .. module:: collections.abc :synopsis: Abstract base classes for containers -.. moduleauthor:: Raymond Hettinger -.. sectionauthor:: Raymond Hettinger - .. versionadded:: 3.3 Formerly, this module was part of the :mod:`collections` module. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 4e0db485e068a8..58bbc9afe709af 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -4,9 +4,6 @@ .. module:: collections :synopsis: Container datatypes -.. moduleauthor:: Raymond Hettinger -.. sectionauthor:: Raymond Hettinger - **Source code:** :source:`Lib/collections/__init__.py` .. testsetup:: * diff --git a/Doc/library/colorsys.rst b/Doc/library/colorsys.rst index 2d3dc2b8b57935..dffc16ae8b7d47 100644 --- a/Doc/library/colorsys.rst +++ b/Doc/library/colorsys.rst @@ -4,8 +4,6 @@ .. module:: colorsys :synopsis: Conversion functions between RGB and other color systems. -.. sectionauthor:: David Ascher - **Source code:** :source:`Lib/colorsys.py` -------------- diff --git a/Doc/library/concurrent.interpreters.rst b/Doc/library/concurrent.interpreters.rst index 55036090e8d5b8..a7b115e5f6307d 100644 --- a/Doc/library/concurrent.interpreters.rst +++ b/Doc/library/concurrent.interpreters.rst @@ -4,9 +4,6 @@ .. module:: concurrent.interpreters :synopsis: Multiple interpreters in the same process -.. moduleauthor:: Eric Snow -.. sectionauthor:: Eric Snow - .. versionadded:: 3.14 **Source code:** :source:`Lib/concurrent/interpreters` diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index f73252a90265cf..4c1750de1d3933 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -4,13 +4,6 @@ .. module:: configparser :synopsis: Configuration file parser. -.. moduleauthor:: Ken Manheimer -.. moduleauthor:: Barry Warsaw -.. moduleauthor:: Eric S. Raymond -.. moduleauthor:: Łukasz Langa -.. sectionauthor:: Christopher G. Petrilli -.. sectionauthor:: Łukasz Langa - **Source code:** :source:`Lib/configparser.py` .. index:: diff --git a/Doc/library/contextvars.rst b/Doc/library/contextvars.rst index 653d8b597c2362..93d0c0d34bf039 100644 --- a/Doc/library/contextvars.rst +++ b/Doc/library/contextvars.rst @@ -4,8 +4,6 @@ .. module:: contextvars :synopsis: Context Variables -.. sectionauthor:: Yury Selivanov - -------------- This module provides APIs to manage, store, and access context-local diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 5c086ab94229ac..21ecdbcc08f348 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -4,8 +4,6 @@ .. module:: csv :synopsis: Write and read tabular data to and from delimited files. -.. sectionauthor:: Skip Montanaro - **Source code:** :source:`Lib/csv.py` .. index:: diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 53849ac2a6aeb6..c23e81e29df0f5 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -4,8 +4,6 @@ .. module:: ctypes :synopsis: A foreign function library for Python. -.. moduleauthor:: Thomas Heller - **Source code:** :source:`Lib/ctypes` -------------- diff --git a/Doc/library/curses.ascii.rst b/Doc/library/curses.ascii.rst index 4910954b7784b0..9ae82c14465538 100644 --- a/Doc/library/curses.ascii.rst +++ b/Doc/library/curses.ascii.rst @@ -4,9 +4,6 @@ .. module:: curses.ascii :synopsis: Constants and set-membership functions for ASCII characters. -.. moduleauthor:: Eric S. Raymond -.. sectionauthor:: Eric S. Raymond - **Source code:** :source:`Lib/curses/ascii.py` -------------- diff --git a/Doc/library/curses.panel.rst b/Doc/library/curses.panel.rst index e52f588c5bc337..5bc6b74b7f07ca 100644 --- a/Doc/library/curses.panel.rst +++ b/Doc/library/curses.panel.rst @@ -4,8 +4,6 @@ .. module:: curses.panel :synopsis: A panel stack extension that adds depth to curses windows. -.. sectionauthor:: A.M. Kuchling - -------------- Panels are windows with the added feature of depth, so they can be stacked on diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 2dc638b3d4014b..0f1449873fcf73 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -5,9 +5,6 @@ :synopsis: An interface to the curses library, providing portable terminal handling. -.. sectionauthor:: Moshe Zadka -.. sectionauthor:: Eric Raymond - **Source code:** :source:`Lib/curses` -------------- @@ -1830,9 +1827,6 @@ The following table lists the predefined colors: .. module:: curses.textpad :synopsis: Emacs-like input editing in a curses window. -.. moduleauthor:: Eric Raymond -.. sectionauthor:: Eric Raymond - The :mod:`!curses.textpad` module provides a :class:`Textbox` class that handles elementary text editing in a curses window, supporting a set of keybindings diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 2864149a08fd50..447f05e67d8418 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -4,9 +4,6 @@ .. module:: dataclasses :synopsis: Generate special methods on user-defined classes. -.. moduleauthor:: Eric V. Smith -.. sectionauthor:: Eric V. Smith - **Source code:** :source:`Lib/dataclasses.py` -------------- diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index b806a49e1be903..f27844c98ccff6 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -4,10 +4,6 @@ .. module:: datetime :synopsis: Basic date and time types. -.. moduleauthor:: Tim Peters -.. sectionauthor:: Tim Peters -.. sectionauthor:: A.M. Kuchling - **Source code:** :source:`Lib/datetime.py` -------------- diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 17b1604dd0ee9b..2af5dfce9612b3 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -4,14 +4,6 @@ .. module:: decimal :synopsis: Implementation of the General Decimal Arithmetic Specification. -.. moduleauthor:: Eric Price -.. moduleauthor:: Facundo Batista -.. moduleauthor:: Raymond Hettinger -.. moduleauthor:: Aahz -.. moduleauthor:: Tim Peters -.. moduleauthor:: Stefan Krah -.. sectionauthor:: Raymond D. Hettinger - **Source code:** :source:`Lib/decimal.py` .. import modules for testing inline doctests with the Sphinx doctest builder diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 9e5a62d8fe5260..e56c4f5e7dfbf7 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -4,10 +4,6 @@ .. module:: difflib :synopsis: Helpers for computing differences between objects. -.. moduleauthor:: Tim Peters -.. sectionauthor:: Tim Peters -.. Markup by Fred L. Drake, Jr. - **Source code:** :source:`Lib/difflib.py` .. testsetup:: diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 3bc0f88d229681..3298697af8511b 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -4,11 +4,6 @@ .. module:: doctest :synopsis: Test pieces of code within docstrings. -.. moduleauthor:: Tim Peters -.. sectionauthor:: Tim Peters -.. sectionauthor:: Moshe Zadka -.. sectionauthor:: Edward Loper - **Source code:** :source:`Lib/doctest.py` -------------- diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index b33fe82a6e4c9f..04a41667f7dc2c 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -4,9 +4,6 @@ .. module:: email.contentmanager :synopsis: Storing and Retrieving Content from MIME Parts -.. moduleauthor:: R. David Murray -.. sectionauthor:: R. David Murray - **Source code:** :source:`Lib/email/contentmanager.py` ------------ diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index f4c11821c4b91d..8dfcd492f0a763 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -4,9 +4,6 @@ .. module:: email.headerregistry :synopsis: Automatic Parsing of headers based on the field name -.. moduleauthor:: R. David Murray -.. sectionauthor:: R. David Murray - **Source code:** :source:`Lib/email/headerregistry.py` -------------- diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index f6908d2e6e9748..b70df130e06dfa 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -3,9 +3,6 @@ .. module:: email.message :synopsis: The base class representing email messages. -.. moduleauthor:: R. David Murray -.. sectionauthor:: R. David Murray , - Barry A. Warsaw **Source code:** :source:`Lib/email/message.py` diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index fef064114ecf1b..8f6e4218c97b38 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -4,9 +4,6 @@ .. module:: email.policy :synopsis: Controlling the parsing and generating of messages -.. moduleauthor:: R. David Murray -.. sectionauthor:: R. David Murray - .. versionadded:: 3.3 **Source code:** :source:`Lib/email/policy.py` diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 03ac1783be08bd..98b47ffd74096c 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -4,9 +4,6 @@ .. module:: email :synopsis: Package supporting the parsing, manipulating, and generating email messages. -.. moduleauthor:: Barry A. Warsaw , - R. David Murray -.. sectionauthor:: R. David Murray **Source code:** :source:`Lib/email/__init__.py` diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index de56048f56a243..8a8a2edc9e542d 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -4,11 +4,6 @@ .. module:: enum :synopsis: Implementation of an enumeration class. -.. moduleauthor:: Ethan Furman -.. sectionauthor:: Barry Warsaw -.. sectionauthor:: Eli Bendersky -.. sectionauthor:: Ethan Furman - .. versionadded:: 3.4 **Source code:** :source:`Lib/enum.py` diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 6e69d24a0e4586..c28e4d6c0cc80c 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -4,8 +4,6 @@ .. module:: fcntl :synopsis: The fcntl() and ioctl() system calls. -.. sectionauthor:: Jaap Vermeulen - .. index:: pair: UNIX; file control pair: UNIX; I/O control diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst index e87a7869685d04..f8365b44c5a502 100644 --- a/Doc/library/filecmp.rst +++ b/Doc/library/filecmp.rst @@ -4,8 +4,6 @@ .. module:: filecmp :synopsis: Compare files efficiently. -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/filecmp.py` -------------- diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 8f32b11e565365..5be16797be908c 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -4,9 +4,6 @@ .. module:: fileinput :synopsis: Loop over standard input or a list of files. -.. moduleauthor:: Guido van Rossum -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/fileinput.py` -------------- diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 575e90942d48b0..b02e7b5b641136 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -4,9 +4,6 @@ .. module:: fractions :synopsis: Rational numbers. -.. moduleauthor:: Jeffrey Yasskin -.. sectionauthor:: Jeffrey Yasskin - **Source code:** :source:`Lib/fractions.py` -------------- diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index f09e4c0536639e..265610db3caabd 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -4,13 +4,6 @@ .. module:: functools :synopsis: Higher-order functions and operations on callable objects. -.. moduleauthor:: Peter Harris -.. moduleauthor:: Raymond Hettinger -.. moduleauthor:: Nick Coghlan -.. moduleauthor:: Łukasz Langa -.. moduleauthor:: Pablo Galindo -.. sectionauthor:: Peter Harris - **Source code:** :source:`Lib/functools.py` .. testsetup:: default diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 250c31e7eee63f..652475886fc30f 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -4,9 +4,6 @@ .. module:: gc :synopsis: Interface to the cycle-detecting garbage collector. -.. moduleauthor:: Neil Schemenauer -.. sectionauthor:: Neil Schemenauer - -------------- This module provides an interface to the optional garbage collector. It diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index 37ffbe1be55a73..1fb34d14d8b007 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -4,10 +4,6 @@ .. module:: getpass :synopsis: Portable reading of passwords and retrieval of the userid. -.. moduleauthor:: Piers Lauder -.. sectionauthor:: Fred L. Drake, Jr. -.. Windows (& Mac?) support by Guido van Rossum. - **Source code:** :source:`Lib/getpass.py` -------------- diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index ddd0188e6614e8..2de16fe40362b3 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -4,9 +4,6 @@ .. module:: gettext :synopsis: Multilingual internationalization services. -.. moduleauthor:: Barry A. Warsaw -.. sectionauthor:: Barry A. Warsaw - **Source code:** :source:`Lib/gettext.py` -------------- diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 542a72d4afe933..ed0b0b2735b5c3 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -4,9 +4,6 @@ .. module:: hashlib :synopsis: Secure hash and message digest algorithms. -.. moduleauthor:: Gregory P. Smith -.. sectionauthor:: Gregory P. Smith - **Source code:** :source:`Lib/hashlib.py` .. index:: @@ -379,8 +376,6 @@ include a `salt `_. BLAKE2 ------ -.. sectionauthor:: Dmitry Chestnykh - .. index:: single: blake2b, blake2s diff --git a/Doc/library/heapq.rst b/Doc/library/heapq.rst index 5049262306a228..26cffa7c643028 100644 --- a/Doc/library/heapq.rst +++ b/Doc/library/heapq.rst @@ -4,11 +4,6 @@ .. module:: heapq :synopsis: Heap queue algorithm (a.k.a. priority queue). -.. moduleauthor:: Kevin O'Connor -.. sectionauthor:: Guido van Rossum -.. sectionauthor:: François Pinard -.. sectionauthor:: Raymond Hettinger - **Source code:** :source:`Lib/heapq.py` -------------- diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst index d5608bd7543eb1..2ee0c0bd9128b8 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -4,9 +4,6 @@ .. module:: hmac :synopsis: Keyed-Hashing for Message Authentication (HMAC) implementation -.. moduleauthor:: Gerhard Häring -.. sectionauthor:: Gerhard Häring - **Source code:** :source:`Lib/hmac.py` -------------- diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst index add18e4c87d220..15d2dc2e9aa6bc 100644 --- a/Doc/library/html.entities.rst +++ b/Doc/library/html.entities.rst @@ -4,8 +4,6 @@ .. module:: html.entities :synopsis: Definitions of HTML general entities. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/html/entities.py` -------------- diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 90daaf28f8d505..5ee783b7fae950 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -4,9 +4,6 @@ .. module:: http.cookiejar :synopsis: Classes for automatic handling of HTTP cookies. -.. moduleauthor:: John J. Lee -.. sectionauthor:: John J. Lee - **Source code:** :source:`Lib/http/cookiejar.py` -------------- diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index a829fb27363ea5..b3fcd21c7e2244 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -4,9 +4,6 @@ .. module:: http.cookies :synopsis: Support for HTTP state management (cookies). -.. moduleauthor:: Timothy O'Malley -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/http/cookies.py` -------------- diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 89be225b6baae4..c7c30e5300c2a4 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -3,8 +3,6 @@ IDLE --- Python editor and shell ================================ -.. moduleauthor:: Guido van Rossum - **Source code:** :source:`Lib/idlelib/` .. index:: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 5129ae7f9d20f7..b29b02d3cf5fe8 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -4,14 +4,6 @@ .. module:: imaplib :synopsis: IMAP4 protocol client (requires sockets). -.. moduleauthor:: Piers Lauder -.. sectionauthor:: Piers Lauder -.. revised by ESR, January 2000 -.. changes for IMAP4_SSL by Tino Lange , March 2002 -.. changes for IMAP4_stream by Piers Lauder , - November 2002 -.. changes for IMAP4 IDLE by Forest , August 2024 - **Source code:** :source:`Lib/imaplib.py` .. index:: diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 795524e5b62145..d5036a0fe7510b 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -4,9 +4,6 @@ .. module:: importlib :synopsis: The implementation of the import machinery. -.. moduleauthor:: Brett Cannon -.. sectionauthor:: Brett Cannon - .. versionadded:: 3.1 **Source code:** :source:`Lib/importlib/__init__.py` diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 1455d907de8888..ff893a4513926a 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -9,9 +9,6 @@ .. module:: inspect :synopsis: Extract information and source code from live objects. -.. moduleauthor:: Ka-Ping Yee -.. sectionauthor:: Ka-Ping Yee - **Source code:** :source:`Lib/inspect.py` -------------- diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 84e28986c31599..494e57fe1c0474 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -4,14 +4,6 @@ .. module:: io :synopsis: Core tools for working with streams. -.. moduleauthor:: Guido van Rossum -.. moduleauthor:: Mike Verdone -.. moduleauthor:: Mark Russell -.. moduleauthor:: Antoine Pitrou -.. moduleauthor:: Amaury Forgeot d'Arc -.. moduleauthor:: Benjamin Peterson -.. sectionauthor:: Benjamin Peterson - **Source code:** :source:`Lib/io.py` -------------- diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index c546d913cbea9d..ba20310d63b277 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -4,8 +4,6 @@ .. module:: ipaddress :synopsis: IPv4/IPv6 manipulation library. -.. moduleauthor:: Peter Moody - **Source code:** :source:`Lib/ipaddress.py` -------------- diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 4f73a74bdd17e2..ce444d7bdfbadb 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -4,9 +4,6 @@ .. module:: itertools :synopsis: Functions creating iterators for efficient looping. -.. moduleauthor:: Raymond Hettinger -.. sectionauthor:: Raymond Hettinger - .. testsetup:: from itertools import * diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 57aad5ba9d1793..4a26419e65bee4 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -4,9 +4,6 @@ .. module:: json :synopsis: Encode and decode the JSON format. -.. moduleauthor:: Bob Ippolito -.. sectionauthor:: Bob Ippolito - **Source code:** :source:`Lib/json/__init__.py` -------------- diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 0a5373ec976371..ff07499e58f0f6 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -4,8 +4,6 @@ .. module:: linecache :synopsis: Provides random access to individual lines from text files. -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/linecache.py` -------------- diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 72311ecaabfc9f..e02cbe7d669f8b 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -4,9 +4,6 @@ .. module:: locale :synopsis: Internationalization services. -.. moduleauthor:: Martin von Löwis -.. sectionauthor:: Martin von Löwis - **Source code:** :source:`Lib/locale.py` -------------- diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 6709062dfca72b..30bf7860a75119 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -4,9 +4,6 @@ .. module:: logging.config :synopsis: Configuration of the logging module. -.. moduleauthor:: Vinay Sajip -.. sectionauthor:: Vinay Sajip - **Source code:** :source:`Lib/logging/config.py` .. sidebar:: Important diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index d128f64aae7236..714db5fa12af0a 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -4,9 +4,6 @@ .. module:: logging.handlers :synopsis: Handlers for the logging module. -.. moduleauthor:: Vinay Sajip -.. sectionauthor:: Vinay Sajip - **Source code:** :source:`Lib/logging/handlers.py` .. sidebar:: Important diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 35ee87d736e7d6..aba530844d7177 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -4,9 +4,6 @@ .. module:: logging :synopsis: Flexible event logging system for applications. -.. moduleauthor:: Vinay Sajip -.. sectionauthor:: Vinay Sajip - **Source code:** :source:`Lib/logging/__init__.py` .. index:: pair: Errors; logging diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 8a4f68f3502521..6cede00b218678 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -4,9 +4,6 @@ .. module:: lzma :synopsis: A Python wrapper for the liblzma compression library. -.. moduleauthor:: Nadeem Vawda -.. sectionauthor:: Nadeem Vawda - .. versionadded:: 3.3 **Source code:** :source:`Lib/lzma.py` diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index 3b0c17c838c879..b9a55a03dc8ae7 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -4,9 +4,6 @@ .. module:: mailbox :synopsis: Manipulate mailboxes in various formats -.. moduleauthor:: Gregory K. Johnson -.. sectionauthor:: Gregory K. Johnson - **Source code:** :source:`Lib/mailbox.py` -------------- diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index f489b60af3cb44..1e599bde8bcddd 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -4,8 +4,6 @@ .. module:: mimetypes :synopsis: Mapping of filename extensions to MIME types. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/mimetypes.py` .. index:: pair: MIME; content type diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst index 823d853f1ed8eb..d26dcbd5f68725 100644 --- a/Doc/library/modulefinder.rst +++ b/Doc/library/modulefinder.rst @@ -4,8 +4,6 @@ .. module:: modulefinder :synopsis: Find modules used by a script. -.. sectionauthor:: A.M. Kuchling - **Source code:** :source:`Lib/modulefinder.py` -------------- diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index ee6798f969a1b6..6b49c1a9ccd6e1 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -4,8 +4,6 @@ .. module:: msvcrt :synopsis: Miscellaneous useful routines from the MS VC++ runtime. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`PC/msvcrtmodule.c` -------------- diff --git a/Doc/library/netrc.rst b/Doc/library/netrc.rst index 74c97e8c9a9759..3fbd2b57426ebe 100644 --- a/Doc/library/netrc.rst +++ b/Doc/library/netrc.rst @@ -4,9 +4,6 @@ .. module:: netrc :synopsis: Loading of .netrc files. -.. moduleauthor:: Eric S. Raymond -.. sectionauthor:: Eric S. Raymond - **Source code:** :source:`Lib/netrc.py` -------------- diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index c715e977cca6cd..c0dab83977e427 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -4,8 +4,6 @@ .. module:: operator :synopsis: Functions corresponding to the standard operators. -.. sectionauthor:: Skip Montanaro - **Source code:** :source:`Lib/operator.py` .. testsetup:: diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 51827e1f8da534..905212965bd70f 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -4,9 +4,6 @@ .. module:: optparse :synopsis: Command-line option parsing library. -.. moduleauthor:: Greg Ward -.. sectionauthor:: Greg Ward - **Source code:** :source:`Lib/optparse.py` -------------- diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 02b79a9f3a7a47..f8975c2f4281d4 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -4,9 +4,6 @@ .. module:: pickle :synopsis: Convert Python objects to streams of bytes and back. -.. sectionauthor:: Jim Kerr . -.. sectionauthor:: Barry Warsaw - **Source code:** :source:`Lib/pickle.py` .. index:: diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index 9950d7ef36f4de..1d30966794fd1b 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -4,9 +4,6 @@ .. module:: platform :synopsis: Retrieves as much platform identifying data as possible. -.. moduleauthor:: Marc-André Lemburg -.. sectionauthor:: Bjorn Pettersen - **Source code:** :source:`Lib/platform.py` -------------- diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst index 415c4b45c4f100..e5fc19f495226e 100644 --- a/Doc/library/plistlib.rst +++ b/Doc/library/plistlib.rst @@ -4,10 +4,6 @@ .. module:: plistlib :synopsis: Generate and parse Apple plist files. -.. moduleauthor:: Jack Jansen -.. sectionauthor:: Georg Brandl -.. (harvested from docstrings in the original file) - **Source code:** :source:`Lib/plistlib.py` .. index:: diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 51ae480338ddb7..cd3a58016e9c12 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -4,9 +4,6 @@ .. module:: poplib :synopsis: POP3 protocol client (requires sockets). -.. sectionauthor:: Andrew T. Csillag -.. revised by ESR, January 2000 - **Source code:** :source:`Lib/poplib.py` .. index:: pair: POP3; protocol diff --git a/Doc/library/posix.rst b/Doc/library/posix.rst index 1f1ca03dfd6222..7d43b5d4cf7657 100644 --- a/Doc/library/posix.rst +++ b/Doc/library/posix.rst @@ -36,8 +36,6 @@ Large File Support single: large files single: file; large files -.. sectionauthor:: Steve Clift - Several operating systems (including AIX and Solaris) provide support for files that are larger than 2 GiB from a C programming model where :c:expr:`int` and :c:expr:`long` are 32-bit values. This is typically accomplished diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index be942949d3ebfe..350831d6ad3c1b 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -4,9 +4,6 @@ .. module:: pprint :synopsis: Data pretty printer. -.. moduleauthor:: Fred L. Drake, Jr. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/pprint.py` -------------- diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index f0314ea5af8118..a7be5779fb2620 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -4,9 +4,6 @@ .. module:: pty :synopsis: Pseudo-Terminal Handling for Unix. -.. moduleauthor:: Steen Lumholt -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/pty.py` -------------- @@ -92,8 +89,6 @@ The :mod:`!pty` module defines the following functions: Example ------- -.. sectionauthor:: Steen Lumholt - The following program acts like the Unix command :manpage:`script(1)`, using a pseudo-terminal to record all input and output of a terminal session in a "typescript". :: diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 1cff16b6c1bf97..7aa960de3f2345 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -4,9 +4,6 @@ .. module:: py_compile :synopsis: Generate byte-code files from Python source files. -.. sectionauthor:: Fred L. Drake, Jr. -.. documentation based on module docstrings - **Source code:** :source:`Lib/py_compile.py` .. index:: pair: file; byte-code diff --git a/Doc/library/pyclbr.rst b/Doc/library/pyclbr.rst index 40f93646af2ceb..ed9fc6d0b5cf8c 100644 --- a/Doc/library/pyclbr.rst +++ b/Doc/library/pyclbr.rst @@ -4,8 +4,6 @@ .. module:: pyclbr :synopsis: Supports information extraction for a Python module browser. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/pyclbr.py` -------------- diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst index e8f153ee1b35ce..f236eba8457657 100644 --- a/Doc/library/pydoc.rst +++ b/Doc/library/pydoc.rst @@ -4,9 +4,6 @@ .. module:: pydoc :synopsis: Documentation generator and online help system. -.. moduleauthor:: Ka-Ping Yee -.. sectionauthor:: Ka-Ping Yee - **Source code:** :source:`Lib/pydoc.py` .. index:: diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index ff5265835da3f8..2e6938b5cf6860 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -4,8 +4,6 @@ .. module:: xml.parsers.expat :synopsis: An interface to the Expat non-validating XML parser. -.. moduleauthor:: Paul Prescod - -------------- .. Markup notes: @@ -666,9 +664,6 @@ otherwise stated. ExpatError Exceptions --------------------- -.. sectionauthor:: Fred L. Drake, Jr. - - :exc:`ExpatError` exceptions have a number of interesting attributes: @@ -752,8 +747,6 @@ Content Model Descriptions .. module:: xml.parsers.expat.model -.. sectionauthor:: Fred L. Drake, Jr. - Content models are described using nested tuples. Each tuple contains four values: the type, the quantifier, the name, and a tuple of children. Children are simply additional content model descriptions. diff --git a/Doc/library/re.rst b/Doc/library/re.rst index df99acf354bf1b..cc11d0205dc5cb 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -4,9 +4,6 @@ .. module:: re :synopsis: Regular expression operations. -.. moduleauthor:: Fredrik Lundh -.. sectionauthor:: Andrew M. Kuchling - **Source code:** :source:`Lib/re/` -------------- @@ -1726,8 +1723,6 @@ The equivalent regular expression would be :: search() vs. prefixmatch() ^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. sectionauthor:: Fred L. Drake, Jr. - Python offers different primitive operations based on regular expressions: + :func:`re.prefixmatch` checks for a match only at the beginning of the string diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 59f5b54a042ea3..234af8d191e3e3 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -4,8 +4,6 @@ .. module:: readline :synopsis: GNU readline support for Python. -.. sectionauthor:: Skip Montanaro - -------------- The :mod:`!readline` module defines a number of functions to facilitate diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst index 28c7855dfeeef3..d269d8bbaa55da 100644 --- a/Doc/library/reprlib.rst +++ b/Doc/library/reprlib.rst @@ -4,8 +4,6 @@ .. module:: reprlib :synopsis: Alternate repr() implementation with size limits. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/reprlib.py` -------------- diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 94bfbeab967693..561b2976ecea22 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -4,9 +4,6 @@ .. module:: resource :synopsis: An interface to provide resource usage information on the current process. -.. moduleauthor:: Jeremy Hylton -.. sectionauthor:: Jeremy Hylton - -------------- This module provides basic mechanisms for measuring and controlling system diff --git a/Doc/library/rlcompleter.rst b/Doc/library/rlcompleter.rst index 91779feb525013..2acd1df3c49007 100644 --- a/Doc/library/rlcompleter.rst +++ b/Doc/library/rlcompleter.rst @@ -4,8 +4,6 @@ .. module:: rlcompleter :synopsis: Python identifier completion, suitable for the GNU readline library. -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/rlcompleter.py` -------------- diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index bb977e01a61bbf..536b5980f86a81 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -4,8 +4,6 @@ .. module:: runpy :synopsis: Locate and run Python modules without importing them first. -.. moduleauthor:: Nick Coghlan - **Source code:** :source:`Lib/runpy.py` -------------- diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 5560478ce15e28..70541c5f3cb367 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -4,8 +4,6 @@ .. module:: sched :synopsis: General purpose event scheduler. -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/sched.py` .. index:: single: event scheduling diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index e266849918a80b..3b5b57fb1c2170 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -4,8 +4,6 @@ .. module:: secrets :synopsis: Generate secure random numbers for managing secrets. -.. moduleauthor:: Steven D'Aprano -.. sectionauthor:: Steven D'Aprano .. versionadded:: 3.6 .. testsetup:: diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index 0653bf2f4189c2..2ab12f2f6f9169 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -4,11 +4,6 @@ .. module:: shlex :synopsis: Simple lexical analysis for Unix shell-like languages. -.. moduleauthor:: Eric S. Raymond -.. moduleauthor:: Gustavo Niemeyer -.. sectionauthor:: Eric S. Raymond -.. sectionauthor:: Gustavo Niemeyer - **Source code:** :source:`Lib/shlex.py` -------------- diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 33f56121e84514..22444c4d804265 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -4,9 +4,6 @@ .. module:: shutil :synopsis: High-level file operations, including copying. -.. sectionauthor:: Fred L. Drake, Jr. -.. partly based on the docstrings - **Source code:** :source:`Lib/shutil.py` .. index:: diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index e1a4cd9c2f50ea..5c97199bc453e8 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -4,8 +4,6 @@ .. module:: smtplib :synopsis: SMTP protocol client (requires sockets). -.. sectionauthor:: Eric S. Raymond - **Source code:** :source:`Lib/smtplib.py` .. index:: diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 02663e2054d5f1..40d103c13f8f38 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -4,8 +4,6 @@ .. module:: sqlite3 :synopsis: A DB-API 2.0 implementation using SQLite 3.x. -.. sectionauthor:: Gerhard Häring - **Source code:** :source:`Lib/sqlite3/` .. Make sure we always doctest the tutorial with an empty database. diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 366ae00efa2fc9..e83c2c9a8bc792 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -4,9 +4,6 @@ .. module:: ssl :synopsis: TLS/SSL wrapper for socket objects -.. moduleauthor:: Bill Janssen -.. sectionauthor:: Bill Janssen - **Source code:** :source:`Lib/ssl.py` .. index:: single: OpenSSL; (use in module ssl) diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index dc852bbb754d9b..5c5f1858ba4476 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -5,8 +5,6 @@ :synopsis: Utilities for interpreting the results of os.stat(), os.lstat() and os.fstat(). -.. sectionauthor:: Skip Montanaro - **Source code:** :source:`Lib/stat.py` -------------- diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 614f5b905a4a2e..cbb131855dc664 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -4,9 +4,6 @@ .. module:: statistics :synopsis: Mathematical statistics functions -.. moduleauthor:: Steven D'Aprano -.. sectionauthor:: Steven D'Aprano - .. versionadded:: 3.4 **Source code:** :source:`Lib/statistics.py` diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index b9caa2aa830e94..325ac9ae7c5293 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -4,9 +4,6 @@ .. module:: stringprep :synopsis: String preparation, as per RFC 3453 -.. moduleauthor:: Martin v. Löwis -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/stringprep.py` -------------- diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 020326b78c6b3d..def6d58eabbeee 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -4,9 +4,6 @@ .. module:: subprocess :synopsis: Subprocess management. -.. moduleauthor:: Peter Åstrand -.. sectionauthor:: Peter Åstrand - **Source code:** :source:`Lib/subprocess.py` -------------- diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 264857f7b76aad..52a722608db431 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -8,10 +8,6 @@ -------------- -.. moduleauthor:: Jeremy Hylton -.. sectionauthor:: Benjamin Peterson - - Symbol tables are generated by the compiler from AST just before bytecode is generated. The symbol table is responsible for calculating the scope of every identifier in the code. :mod:`!symtable` provides an interface to examine these diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 5c65d6fd016175..8aa912d99ba756 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -4,9 +4,6 @@ .. module:: sysconfig :synopsis: Python's configuration information -.. moduleauthor:: Tarek Ziadé -.. sectionauthor:: Tarek Ziadé - .. versionadded:: 3.2 **Source code:** :source:`Lib/sysconfig` diff --git a/Doc/library/tabnanny.rst b/Doc/library/tabnanny.rst index 4f61b3dd761400..570cc7fd93beef 100644 --- a/Doc/library/tabnanny.rst +++ b/Doc/library/tabnanny.rst @@ -5,11 +5,6 @@ :synopsis: Tool for detecting white space related problems in Python source files in a directory tree. -.. moduleauthor:: Tim Peters -.. sectionauthor:: Peter Funk - -.. rudimentary documentation based on module comments - **Source code:** :source:`Lib/tabnanny.py` -------------- diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index d162070e27a7d2..a86469bb9ad704 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -4,9 +4,6 @@ .. module:: tarfile :synopsis: Read and write tar-format archive files. -.. moduleauthor:: Lars Gustäbel -.. sectionauthor:: Lars Gustäbel - **Source code:** :source:`Lib/tarfile.py` -------------- diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 78d37d8135cc51..bf9198e175a0e1 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -4,8 +4,6 @@ .. module:: tempfile :synopsis: Generate temporary files and directories. -.. sectionauthor:: Zack Weinberg - **Source code:** :source:`Lib/tempfile.py` .. index:: diff --git a/Doc/library/test.rst b/Doc/library/test.rst index b5a3005f854410..7ae3fabf1cec64 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -4,8 +4,6 @@ .. module:: test :synopsis: Regression tests package containing the testing suite for Python. -.. sectionauthor:: Brett Cannon - .. note:: The :mod:`!test` package is meant for internal use by Python only. It is documented for the benefit of the core developers of Python. Any use of diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index c9230f7d82705f..d12968dee91f3c 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -4,9 +4,6 @@ .. module:: textwrap :synopsis: Text wrapping and filling -.. moduleauthor:: Greg Ward -.. sectionauthor:: Greg Ward - **Source code:** :source:`Lib/textwrap.py` -------------- diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 805f619eab8c07..a34b74a088874f 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -4,8 +4,6 @@ .. module:: tkinter :synopsis: Interface to Tcl/Tk for graphical user interfaces -.. moduleauthor:: Guido van Rossum - **Source code:** :source:`Lib/tkinter/__init__.py` -------------- diff --git a/Doc/library/tkinter.scrolledtext.rst b/Doc/library/tkinter.scrolledtext.rst index 6c3c74afd47d82..eb30b9c3eacc1b 100644 --- a/Doc/library/tkinter.scrolledtext.rst +++ b/Doc/library/tkinter.scrolledtext.rst @@ -4,8 +4,6 @@ .. module:: tkinter.scrolledtext :synopsis: Text widget with a vertical scroll bar. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/tkinter/scrolledtext.py` -------------- diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 7db5756469976b..e1383e189a31a2 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -4,8 +4,6 @@ .. module:: tkinter.ttk :synopsis: Tk themed widget set -.. sectionauthor:: Guilherme Polo - **Source code:** :source:`Lib/tkinter/ttk.py` .. index:: single: ttk diff --git a/Doc/library/token.rst b/Doc/library/token.rst index fb826f5465bd80..3253be96238c35 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -4,8 +4,6 @@ .. module:: token :synopsis: Constants representing terminal nodes of the parse tree. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/token.py` -------------- diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index cf638f0b095bd6..3db4cf42c17f3d 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -4,9 +4,6 @@ .. module:: tokenize :synopsis: Lexical scanner for Python source code. -.. moduleauthor:: Ka Ping Yee -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/tokenize.py` -------------- diff --git a/Doc/library/tomllib.rst b/Doc/library/tomllib.rst index dc6e0cc178bf66..2bac968c2bea68 100644 --- a/Doc/library/tomllib.rst +++ b/Doc/library/tomllib.rst @@ -4,9 +4,6 @@ .. module:: tomllib :synopsis: Parse TOML files. -.. moduleauthor:: Taneli Hukkinen -.. sectionauthor:: Taneli Hukkinen - **Source code:** :source:`Lib/tomllib` -------------- diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index fe46be8b3211a2..9a8e69f09e8946 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -4,9 +4,6 @@ .. module:: tty :synopsis: Utility functions that perform common terminal control operations. -.. moduleauthor:: Steen Lumholt -.. sectionauthor:: Moshe Zadka - **Source code:** :source:`Lib/tty.py` -------------- diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index bfe93bc253d4fc..234042c661f51a 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -5,8 +5,6 @@ .. module:: turtle :synopsis: An educational framework for simple graphics applications -.. sectionauthor:: Gregor Lingl - **Source code:** :source:`Lib/turtle.py` .. testsetup:: default diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 838744c3f899b9..2fc8b1d8b52341 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -4,10 +4,6 @@ .. module:: unicodedata :synopsis: Access the Unicode Database. -.. moduleauthor:: Marc-André Lemburg -.. sectionauthor:: Marc-André Lemburg -.. sectionauthor:: Martin v. Löwis - .. index:: single: Unicode single: character diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 61c75b5a03b103..7c81f52165972a 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -1,7 +1,6 @@ :mod:`!unittest.mock` --- getting started ========================================= -.. moduleauthor:: Michael Foord .. currentmodule:: unittest.mock .. versionadded:: 3.3 diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 549b04997886fa..2ff1015af7a86e 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -4,7 +4,6 @@ .. module:: unittest.mock :synopsis: Mock object library. -.. moduleauthor:: Michael Foord .. currentmodule:: unittest.mock .. versionadded:: 3.3 diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 9677612823df40..c7682c2274633b 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -4,11 +4,6 @@ .. module:: unittest :synopsis: Unit testing framework for Python. -.. moduleauthor:: Steve Purcell -.. sectionauthor:: Steve Purcell -.. sectionauthor:: Fred L. Drake, Jr. -.. sectionauthor:: Raymond Hettinger - **Source code:** :source:`Lib/unittest/__init__.py` -------------- diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index dd2c9858eaad69..b8864e36981ab9 100644 --- a/Doc/library/urllib.error.rst +++ b/Doc/library/urllib.error.rst @@ -4,9 +4,6 @@ .. module:: urllib.error :synopsis: Exception classes raised by urllib.request. -.. moduleauthor:: Jeremy Hylton -.. sectionauthor:: Senthil Kumaran - **Source code:** :source:`Lib/urllib/error.py` -------------- diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index b857b2a235e1bd..64e915d042d4a0 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -4,10 +4,6 @@ .. module:: urllib.request :synopsis: Extensible library for opening URLs. -.. moduleauthor:: Jeremy Hylton -.. sectionauthor:: Moshe Zadka -.. sectionauthor:: Senthil Kumaran - **Source code:** :source:`Lib/urllib/request.py` -------------- diff --git a/Doc/library/urllib.robotparser.rst b/Doc/library/urllib.robotparser.rst index ba719ae084e7e0..492c65ae209d92 100644 --- a/Doc/library/urllib.robotparser.rst +++ b/Doc/library/urllib.robotparser.rst @@ -5,8 +5,6 @@ :synopsis: Load a robots.txt file and answer questions about fetchability of other URLs. -.. sectionauthor:: Skip Montanaro - **Source code:** :source:`Lib/urllib/robotparser.py` .. index:: diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index fe3a3a8e510bd8..4b505c81c06f0f 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -3,8 +3,6 @@ .. module:: uuid :synopsis: UUID objects (universally unique identifiers) according to RFC 9562 -.. moduleauthor:: Ka-Ping Yee -.. sectionauthor:: George Yoshida **Source code:** :source:`Lib/uuid.py` diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index c75d7348343e16..8bb267d5a0b958 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -4,9 +4,6 @@ .. module:: venv :synopsis: Creation of virtual environments. -.. moduleauthor:: Vinay Sajip -.. sectionauthor:: Vinay Sajip - .. versionadded:: 3.3 **Source code:** :source:`Lib/venv/` diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index da793a64c45f0d..6e61a1a44ad232 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -4,9 +4,6 @@ .. module:: wave :synopsis: Provide an interface to the WAV sound format. -.. sectionauthor:: Moshe Zadka -.. Documentations stolen from comments in file. - **Source code:** :source:`Lib/wave.py` -------------- diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 6dc5f90686c778..87dd860da4dcc4 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -6,11 +6,6 @@ .. module:: weakref :synopsis: Support for weak references and weak dictionaries. -.. moduleauthor:: Fred L. Drake, Jr. -.. moduleauthor:: Neil Schemenauer -.. moduleauthor:: Martin von Löwis -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/weakref.py` -------------- diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 7b37b270e75343..389648d4f393e4 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -4,9 +4,6 @@ .. module:: webbrowser :synopsis: Easy-to-use controller for web browsers. -.. moduleauthor:: Fred L. Drake, Jr. -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/webbrowser.py` -------------- diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 12f9252af9356e..2353bfd5281dab 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -4,8 +4,6 @@ .. module:: winreg :synopsis: Routines and objects for manipulating the Windows registry. -.. sectionauthor:: Mark Hammond - **Source code:** :source:`PC/winreg.c` -------------- diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst index 730b1bac658002..6b5f88021489d3 100644 --- a/Doc/library/winsound.rst +++ b/Doc/library/winsound.rst @@ -4,9 +4,6 @@ .. module:: winsound :synopsis: Access to the sound-playing machinery for Windows. -.. moduleauthor:: Toby Dickenson -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`PC/winsound.c` -------------- diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 0ace7b72d32570..2af54dc2a7e632 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -4,9 +4,6 @@ .. module:: wsgiref :synopsis: WSGI Utilities and Reference Implementation. -.. moduleauthor:: Phillip J. Eby -.. sectionauthor:: Phillip J. Eby - **Source code:** :source:`Lib/wsgiref` -------------- diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 321d93079bc6fa..1a5291d018ac70 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -4,10 +4,6 @@ .. module:: xml.dom.minidom :synopsis: Minimal Document Object Model (DOM) implementation. -.. moduleauthor:: Paul Prescod -.. sectionauthor:: Paul Prescod -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/xml/dom/minidom.py` -------------- diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst index 5027596ed96ad5..52340ffe92eb85 100644 --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -4,8 +4,6 @@ .. module:: xml.dom.pulldom :synopsis: Support for building partial DOM trees from SAX events. -.. moduleauthor:: Paul Prescod - **Source code:** :source:`Lib/xml/dom/pulldom.py` -------------- diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 8e5a3c13cfd860..34e58dcad93012 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -4,9 +4,6 @@ .. module:: xml.dom :synopsis: Document Object Model API for Python. -.. sectionauthor:: Paul Prescod -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/xml/dom/__init__.py` -------------- diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 177be9ff4bad25..e021a81d2a2b87 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -4,8 +4,6 @@ .. module:: xml.etree.ElementTree :synopsis: Implementation of the ElementTree API. -.. moduleauthor:: Fredrik Lundh - **Source code:** :source:`Lib/xml/etree/ElementTree.py` -------------- diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index 81d47147f33816..a47d31465b19f1 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -6,9 +6,6 @@ XML Processing Modules .. module:: xml :synopsis: Package containing XML processing modules -.. sectionauthor:: Christian Heimes -.. sectionauthor:: Georg Brandl - **Source code:** :source:`Lib/xml/` -------------- diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index 5079fc0f19ea96..4188debf566d9b 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -4,9 +4,6 @@ .. module:: xml.sax.handler :synopsis: Base classes for SAX event handlers. -.. moduleauthor:: Lars Marius Garshol -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/xml/sax/handler.py` -------------- diff --git a/Doc/library/xml.sax.reader.rst b/Doc/library/xml.sax.reader.rst index b0bc84062e0719..1a5ab6a214f819 100644 --- a/Doc/library/xml.sax.reader.rst +++ b/Doc/library/xml.sax.reader.rst @@ -4,9 +4,6 @@ .. module:: xml.sax.xmlreader :synopsis: Interface which SAX-compliant XML parsers must implement. -.. moduleauthor:: Lars Marius Garshol -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/xml/sax/xmlreader.py` -------------- diff --git a/Doc/library/xml.sax.rst b/Doc/library/xml.sax.rst index 148cb863aca277..77234cac5d92ad 100644 --- a/Doc/library/xml.sax.rst +++ b/Doc/library/xml.sax.rst @@ -4,10 +4,6 @@ .. module:: xml.sax :synopsis: Package containing SAX2 base classes and convenience functions. -.. moduleauthor:: Lars Marius Garshol -.. sectionauthor:: Fred L. Drake, Jr. -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/xml/sax/__init__.py` -------------- diff --git a/Doc/library/xml.sax.utils.rst b/Doc/library/xml.sax.utils.rst index f93fe374e1c862..2de7ae2bda4260 100644 --- a/Doc/library/xml.sax.utils.rst +++ b/Doc/library/xml.sax.utils.rst @@ -4,9 +4,6 @@ .. module:: xml.sax.saxutils :synopsis: Convenience functions and classes for use with SAX. -.. moduleauthor:: Lars Marius Garshol -.. sectionauthor:: Martin v. Löwis - **Source code:** :source:`Lib/xml/sax/saxutils.py` -------------- diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 75de47d9595628..8b3b3dcaa13447 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -4,9 +4,6 @@ .. module:: xmlrpc.client :synopsis: XML-RPC client access. -.. moduleauthor:: Fredrik Lundh -.. sectionauthor:: Eric S. Raymond - **Source code:** :source:`Lib/xmlrpc/client.py` .. XXX Not everything is documented yet. It might be good to describe diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 9f16c470567406..2c130785be0db0 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -4,9 +4,6 @@ .. module:: xmlrpc.server :synopsis: Basic XML-RPC server implementations. -.. moduleauthor:: Brian Quinlan -.. sectionauthor:: Fred L. Drake, Jr. - **Source code:** :source:`Lib/xmlrpc/server.py` -------------- diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 082c4f8d3b40c3..2d9231707d9f2d 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -4,9 +4,6 @@ .. module:: zipfile :synopsis: Read and write ZIP-format archive files. -.. moduleauthor:: James C. Ahlstrom -.. sectionauthor:: James C. Ahlstrom - **Source code:** :source:`Lib/zipfile/` -------------- diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 97f3ede21525cf..a4136733a55030 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -4,8 +4,6 @@ .. module:: zipimport :synopsis: Support for importing Python modules from ZIP archives. -.. moduleauthor:: Just van Rossum - **Source code:** :source:`Lib/zipimport.py` -------------- diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index 099b50b0747504..cba08d6614fc08 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -6,9 +6,6 @@ .. versionadded:: 3.9 -.. moduleauthor:: Paul Ganssle -.. sectionauthor:: Paul Ganssle - **Source code:** :source:`Lib/zoneinfo` -------------- diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index bee6cc39fafcdb..8bac8df4368c00 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -1068,7 +1068,6 @@ Here is an example of a multi-line docstring:: Function Annotations -------------------- -.. sectionauthor:: Zachary Ware .. index:: pair: function; annotations single: ->; function annotations @@ -1102,7 +1101,6 @@ value annotated:: Intermezzo: Coding Style ======================== -.. sectionauthor:: Georg Brandl .. index:: pair: coding; style Now that you are about to write longer, more complex pieces of Python, it is a diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index fe62ee153fe034..eba2474cd4009d 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -136,9 +136,6 @@ comparison. Using Lists as Stacks --------------------- -.. sectionauthor:: Ka-Ping Yee - - The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved ("last-in, first-out"). To add an item to the top of the stack, use :meth:`~list.append`. To retrieve an item from the @@ -166,8 +163,6 @@ top of the stack, use :meth:`~list.pop` without an explicit index. For example: Using Lists as Queues --------------------- -.. sectionauthor:: Ka-Ping Yee - It is also possible to use a list as a queue, where the first element added is the first element retrieved ("first-in, first-out"); however, lists are not efficient for this purpose. While appends and pops from the end of list are diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index dfe2d1d3a8378f..37e23ba1cd0c81 100644 --- a/Doc/tutorial/floatingpoint.rst +++ b/Doc/tutorial/floatingpoint.rst @@ -9,10 +9,6 @@ Floating-Point Arithmetic: Issues and Limitations ************************************************** -.. sectionauthor:: Tim Peters -.. sectionauthor:: Raymond Hettinger - - Floating-point numbers are represented in computer hardware as base 2 (binary) fractions. For example, the **decimal** fraction ``0.625`` has value 6/10 + 2/100 + 5/1000, and in the same way the **binary** fraction ``0.101`` diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 2fd6eace2b5dda..6cf945de5b3f3b 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -5,9 +5,6 @@ Using Python on macOS ********************* -.. sectionauthor:: Bob Savage -.. sectionauthor:: Ned Deily - This document aims to give an overview of macOS-specific behavior you should know about to get started with Python on Mac computers. Python on a Mac running macOS is very similar to Python on other Unix-derived platforms, diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index a9950ef7525497..829bdfe8b1121f 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -6,9 +6,6 @@ Using Python on Unix platforms ******************************** -.. sectionauthor:: Shriphani Palakodety - - Getting and installing the latest version of Python =================================================== diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index d286788e8054cc..69fe89290e3b27 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -12,8 +12,6 @@ Using Python on Windows ************************* -.. sectionauthor:: Steve Dower - This document aims to give an overview of Windows-specific behaviour you should know about when using Python on Microsoft Windows. diff --git a/Misc/ACKS b/Misc/ACKS index 4295eff8c1e225..3464bd95bac791 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -122,6 +122,7 @@ Don Bashford Pior Bastida Nick Bastin Ned Batchelder +Facundo Batista Jeff Bauer Michael R Bax Anthony Baxter @@ -328,6 +329,7 @@ David Chaum Nicolas Chauvat Jerry Chen Michael Chermside +Dmitry Chestnykh Ingrid Cheung Adam Chhina Terry Chia @@ -424,6 +426,7 @@ Eric Daniel Scott David Daniels Derzsi Dániel Lawrence D'Anna +Steven D'Aprano Ben Darnell Kushal Das Jonathan Dasteel @@ -500,6 +503,7 @@ Eugene Dvurechenski Karmen Dykstra Josip Dzolonga Maxim Dzumanenko +Phillip J. Eby Hans Eckardt Rodolpho Eckhardt Ulrich Eckhardt @@ -738,6 +742,7 @@ Derek Harland Jason Harper David Harrigan Brian Harring +Peter Harris Jonathan Hartley Travis B. Hartwell Henrik Harutyunyan @@ -758,6 +763,7 @@ Tim Heaney Henrik Heimbuerger Christian Heimes Thomas Heller +Doug Hellmann Malte Helmert Lance Finn Helsten Gordon P. Hemsley @@ -844,6 +850,7 @@ Lawrence Hudson Michael Hudson Roberto Hueso Gomez Jim Hugunin +Taneli Hukkinen Greg Humphreys Chris Hunt Eric Huss @@ -1051,6 +1058,7 @@ Jon Kuhn Andrei Kulakov Ilya Kulakov Upendra Kumar +Senthil Kumaran Toshio Kuratomi Ilia Kurenkov Vladimir Kushnir @@ -1159,6 +1167,7 @@ Yuan Liu Nick Lockwood Stephanie Lockwood Martin von Löwis +Edward Loper Hugo Lopes Tavares Guillermo López-Anglada Anne Lord @@ -1175,6 +1184,7 @@ Kang-Hao (Kenny) Lu Raymond Lu Lukas Lueg Loren Luke +Steen Lumholt Fredrik Lundh Mike Lundy Zhongyue Luo @@ -1661,6 +1671,7 @@ Amit Saha Suman Saha Koki Saito Hajime Saitou +Vinay Sajip George Sakkis Victor Salgado Rich Salz @@ -2134,6 +2145,7 @@ Alakshendra Yadav Hirokazu Yamamoto Masayuki Yamamoto Zhikang Yan +Jeffrey Yasskin Jingchen Ye Ka-Ping Yee Chi Hsuan Yen From 175ab31377d9e616efb95168099d8c2c9036504a Mon Sep 17 00:00:00 2001 From: Anton Ryzhov Date: Fri, 20 Feb 2026 08:56:56 +0100 Subject: [PATCH 177/498] Update comments in `_strptime` module (GH-144979) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Lib/_strptime.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/_strptime.py b/Lib/_strptime.py index fe34808d88769a..0d81ff6765e1ed 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -7,7 +7,7 @@ FUNCTIONS: _getlang -- Figure out what language is being used for the locale - strptime -- Calculates the time struct represented by the passed-in string + _strptime -- Calculates the time struct represented by the passed-in string """ import os @@ -518,9 +518,10 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): - """Return a 2-tuple consisting of a time struct and an int containing - the number of microseconds based on the input string and the - format string.""" + """Return a 3-tuple consisting of a tuple with time components, + an int containing the number of microseconds, and an int + containing the microseconds part of the GMT offset, based on the + input string and the format string.""" for index, arg in enumerate([data_string, format]): if not isinstance(arg, str): From 60f3c396fe5dc56bc3a56341e2d31fd6061bb068 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 20 Feb 2026 11:37:39 -0500 Subject: [PATCH 178/498] gh-141811: Split up `init.rst` into multiple pages (GH-144844) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Benedikt Johannes --- Doc/c-api/index.rst | 9 +- Doc/c-api/init.rst | 2758 +------------------------------- Doc/c-api/interp-lifecycle.rst | 797 +++++++++ Doc/c-api/profiling.rst | 239 +++ Doc/c-api/subinterpreters.rst | 470 ++++++ Doc/c-api/synchronization.rst | 308 ++++ Doc/c-api/threads.rst | 827 ++++++++++ Doc/c-api/tls.rst | 155 ++ 8 files changed, 2813 insertions(+), 2750 deletions(-) create mode 100644 Doc/c-api/interp-lifecycle.rst create mode 100644 Doc/c-api/profiling.rst create mode 100644 Doc/c-api/subinterpreters.rst create mode 100644 Doc/c-api/synchronization.rst create mode 100644 Doc/c-api/threads.rst create mode 100644 Doc/c-api/tls.rst diff --git a/Doc/c-api/index.rst b/Doc/c-api/index.rst index e9df2a304d975b..eabe00f4004001 100644 --- a/Doc/c-api/index.rst +++ b/Doc/c-api/index.rst @@ -1,7 +1,7 @@ .. _c-api-index: ################################## - Python/C API Reference Manual + Python/C API reference manual ################################## This manual documents the API used by C and C++ programmers who want to write @@ -21,7 +21,12 @@ document the API functions in detail. utilities.rst abstract.rst concrete.rst - init.rst + interp-lifecycle.rst + threads.rst + synchronization.rst + tls.rst + subinterpreters.rst + profiling.rst init_config.rst memory.rst objimpl.rst diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 52ed9e0647780b..e56c67f95348c7 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -1,2751 +1,13 @@ -.. highlight:: c +:orphan: +Initialization, finalization, and threads +========================================= -.. _initialization: +This page has been split up into the following: -***************************************** -Initialization, Finalization, and Threads -***************************************** - -See :ref:`Python Initialization Configuration ` for details -on how to configure the interpreter prior to initialization. - -.. _pre-init-safe: - -Before Python Initialization -============================ - -In an application embedding Python, the :c:func:`Py_Initialize` function must -be called before using any other Python/C API functions; with the exception of -a few functions and the :ref:`global configuration variables -`. - -The following functions can be safely called before Python is initialized: - -* Functions that initialize the interpreter: - - * :c:func:`Py_Initialize` - * :c:func:`Py_InitializeEx` - * :c:func:`Py_InitializeFromConfig` - * :c:func:`Py_BytesMain` - * :c:func:`Py_Main` - * the runtime pre-initialization functions covered in :ref:`init-config` - -* Configuration functions: - - * :c:func:`PyImport_AppendInittab` - * :c:func:`PyImport_ExtendInittab` - * :c:func:`!PyInitFrozenExtensions` - * :c:func:`PyMem_SetAllocator` - * :c:func:`PyMem_SetupDebugHooks` - * :c:func:`PyObject_SetArenaAllocator` - * :c:func:`Py_SetProgramName` - * :c:func:`Py_SetPythonHome` - * the configuration functions covered in :ref:`init-config` - -* Informative functions: - - * :c:func:`Py_IsInitialized` - * :c:func:`PyMem_GetAllocator` - * :c:func:`PyObject_GetArenaAllocator` - * :c:func:`Py_GetBuildInfo` - * :c:func:`Py_GetCompiler` - * :c:func:`Py_GetCopyright` - * :c:func:`Py_GetPlatform` - * :c:func:`Py_GetVersion` - * :c:func:`Py_IsInitialized` - -* Utilities: - - * :c:func:`Py_DecodeLocale` - * the status reporting and utility functions covered in :ref:`init-config` - -* Memory allocators: - - * :c:func:`PyMem_RawMalloc` - * :c:func:`PyMem_RawRealloc` - * :c:func:`PyMem_RawCalloc` - * :c:func:`PyMem_RawFree` - -* Synchronization: - - * :c:func:`PyMutex_Lock` - * :c:func:`PyMutex_Unlock` - -.. note:: - - Despite their apparent similarity to some of the functions listed above, - the following functions **should not be called** before the interpreter has - been initialized: :c:func:`Py_EncodeLocale`, :c:func:`PyEval_InitThreads`, and - :c:func:`Py_RunMain`. - - -.. _global-conf-vars: - -Global configuration variables -============================== - -Python has variables for the global configuration to control different features -and options. By default, these flags are controlled by :ref:`command line -options `. - -When a flag is set by an option, the value of the flag is the number of times -that the option was set. For example, ``-b`` sets :c:data:`Py_BytesWarningFlag` -to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. - -.. c:var:: int Py_BytesWarningFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.bytes_warning` should be used instead, see :ref:`Python - Initialization Configuration `. - - Issue a warning when comparing :class:`bytes` or :class:`bytearray` with - :class:`str` or :class:`bytes` with :class:`int`. Issue an error if greater - or equal to ``2``. - - Set by the :option:`-b` option. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_DebugFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.parser_debug` should be used instead, see :ref:`Python - Initialization Configuration `. - - Turn on parser debugging output (for expert only, depending on compilation - options). - - Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment - variable. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_DontWriteBytecodeFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.write_bytecode` should be used instead, see :ref:`Python - Initialization Configuration `. - - If set to non-zero, Python won't try to write ``.pyc`` files on the - import of source modules. - - Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE` - environment variable. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_FrozenFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.pathconfig_warnings` should be used instead, see - :ref:`Python Initialization Configuration `. - - Private flag used by ``_freeze_module`` and ``frozenmain`` programs. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_HashRandomizationFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.hash_seed` and :c:member:`PyConfig.use_hash_seed` should - be used instead, see :ref:`Python Initialization Configuration - `. - - Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to - a non-empty string. - - If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment - variable to initialize the secret hash seed. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_IgnoreEnvironmentFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.use_environment` should be used instead, see - :ref:`Python Initialization Configuration `. - - Ignore all :envvar:`!PYTHON*` environment variables, e.g. - :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. - - Set by the :option:`-E` and :option:`-I` options. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_InspectFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.inspect` should be used instead, see - :ref:`Python Initialization Configuration `. - - When a script is passed as first argument or the :option:`-c` option is used, - enter interactive mode after executing the script or the command, even when - :data:`sys.stdin` does not appear to be a terminal. - - Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment - variable. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_InteractiveFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.interactive` should be used instead, see - :ref:`Python Initialization Configuration `. - - Set by the :option:`-i` option. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_IsolatedFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.isolated` should be used instead, see - :ref:`Python Initialization Configuration `. - - Run Python in isolated mode. In isolated mode :data:`sys.path` contains - neither the script's directory nor the user's site-packages directory. - - Set by the :option:`-I` option. - - .. versionadded:: 3.4 - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_LegacyWindowsFSEncodingFlag - - This API is kept for backward compatibility: setting - :c:member:`PyPreConfig.legacy_windows_fs_encoding` should be used instead, see - :ref:`Python Initialization Configuration `. - - If the flag is non-zero, use the ``mbcs`` encoding with ``replace`` error - handler, instead of the UTF-8 encoding with ``surrogatepass`` error handler, - for the :term:`filesystem encoding and error handler`. - - Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment - variable is set to a non-empty string. - - See :pep:`529` for more details. - - .. availability:: Windows. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_LegacyWindowsStdioFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.legacy_windows_stdio` should be used instead, see - :ref:`Python Initialization Configuration `. - - If the flag is non-zero, use :class:`io.FileIO` instead of - :class:`!io._WindowsConsoleIO` for :mod:`sys` standard streams. - - Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment - variable is set to a non-empty string. - - See :pep:`528` for more details. - - .. availability:: Windows. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_NoSiteFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.site_import` should be used instead, see - :ref:`Python Initialization Configuration `. - - Disable the import of the module :mod:`site` and the site-dependent - manipulations of :data:`sys.path` that it entails. Also disable these - manipulations if :mod:`site` is explicitly imported later (call - :func:`site.main` if you want them to be triggered). - - Set by the :option:`-S` option. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_NoUserSiteDirectory - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.user_site_directory` should be used instead, see - :ref:`Python Initialization Configuration `. - - Don't add the :data:`user site-packages directory ` to - :data:`sys.path`. - - Set by the :option:`-s` and :option:`-I` options, and the - :envvar:`PYTHONNOUSERSITE` environment variable. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_OptimizeFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.optimization_level` should be used instead, see - :ref:`Python Initialization Configuration `. - - Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment - variable. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_QuietFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.quiet` should be used instead, see :ref:`Python - Initialization Configuration `. - - Don't display the copyright and version messages even in interactive mode. - - Set by the :option:`-q` option. - - .. versionadded:: 3.2 - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_UnbufferedStdioFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.buffered_stdio` should be used instead, see :ref:`Python - Initialization Configuration `. - - Force the stdout and stderr streams to be unbuffered. - - Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED` - environment variable. - - .. deprecated-removed:: 3.12 3.15 - -.. c:var:: int Py_VerboseFlag - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.verbose` should be used instead, see :ref:`Python - Initialization Configuration `. - - Print a message each time a module is initialized, showing the place - (filename or built-in module) from which it is loaded. If greater or equal - to ``2``, print a message for each file that is checked for when - searching for a module. Also provides information on module cleanup at exit. - - Set by the :option:`-v` option and the :envvar:`PYTHONVERBOSE` environment - variable. - - .. deprecated-removed:: 3.12 3.15 - - -Initializing and finalizing the interpreter -=========================================== - - -.. c:function:: void Py_Initialize() - - .. index:: - single: PyEval_InitThreads() - single: modules (in module sys) - single: path (in module sys) - pair: module; builtins - pair: module; __main__ - pair: module; sys - triple: module; search; path - single: Py_FinalizeEx (C function) - - Initialize the Python interpreter. In an application embedding Python, - this should be called before using any other Python/C API functions; see - :ref:`Before Python Initialization ` for the few exceptions. - - This initializes the table of loaded modules (``sys.modules``), and creates - the fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. - It also initializes the module search path (``sys.path``). It does not set - ``sys.argv``; use the :ref:`Python Initialization Configuration ` - API for that. This is a no-op when called for a second time (without calling - :c:func:`Py_FinalizeEx` first). There is no return value; it is a fatal - error if the initialization fails. - - Use :c:func:`Py_InitializeFromConfig` to customize the - :ref:`Python Initialization Configuration `. - - .. note:: - On Windows, changes the console mode from ``O_TEXT`` to ``O_BINARY``, - which will also affect non-Python uses of the console using the C Runtime. - - -.. c:function:: void Py_InitializeEx(int initsigs) - - This function works like :c:func:`Py_Initialize` if *initsigs* is ``1``. If - *initsigs* is ``0``, it skips initialization registration of signal handlers, - which may be useful when CPython is embedded as part of a larger application. - - Use :c:func:`Py_InitializeFromConfig` to customize the - :ref:`Python Initialization Configuration `. - - -.. c:function:: PyStatus Py_InitializeFromConfig(const PyConfig *config) - - Initialize Python from *config* configuration, as described in - :ref:`init-from-config`. - - See the :ref:`init-config` section for details on pre-initializing the - interpreter, populating the runtime configuration structure, and querying - the returned status structure. - - -.. c:function:: int Py_IsInitialized() - - Return true (nonzero) when the Python interpreter has been initialized, false - (zero) if not. After :c:func:`Py_FinalizeEx` is called, this returns false until - :c:func:`Py_Initialize` is called again. - - -.. c:function:: int Py_IsFinalizing() - - Return true (non-zero) if the main Python interpreter is - :term:`shutting down `. Return false (zero) otherwise. - - .. versionadded:: 3.13 - - -.. c:function:: int Py_FinalizeEx() - - Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of - Python/C API functions, and destroy all sub-interpreters (see - :c:func:`Py_NewInterpreter` below) that were created and not yet destroyed since - the last call to :c:func:`Py_Initialize`. This is a no-op when called for a second - time (without calling :c:func:`Py_Initialize` again first). - - Since this is the reverse of :c:func:`Py_Initialize`, it should be called - in the same thread with the same interpreter active. That means - the main thread and the main interpreter. - This should never be called while :c:func:`Py_RunMain` is running. - - Normally the return value is ``0``. - If there were errors during finalization (flushing buffered data), - ``-1`` is returned. - - Note that Python will do a best effort at freeing all memory allocated by the Python - interpreter. Therefore, any C-Extension should make sure to correctly clean up all - of the previously allocated PyObjects before using them in subsequent calls to - :c:func:`Py_Initialize`. Otherwise it could introduce vulnerabilities and incorrect - behavior. - - This function is provided for a number of reasons. An embedding application - might want to restart Python without having to restart the application itself. - An application that has loaded the Python interpreter from a dynamically - loadable library (or DLL) might want to free all memory allocated by Python - before unloading the DLL. During a hunt for memory leaks in an application a - developer might want to free all memory allocated by Python before exiting from - the application. - - **Bugs and caveats:** The destruction of modules and objects in modules is done - in random order; this may cause destructors (:meth:`~object.__del__` methods) to fail - when they depend on other objects (even functions) or modules. Dynamically - loaded extension modules loaded by Python are not unloaded. Small amounts of - memory allocated by the Python interpreter may not be freed (if you find a leak, - please report it). Memory tied up in circular references between objects is not - freed. Interned strings will all be deallocated regardless of their reference count. - Some memory allocated by extension modules may not be freed. Some extensions may not - work properly if their initialization routine is called more than once; this can - happen if an application calls :c:func:`Py_Initialize` and :c:func:`Py_FinalizeEx` - more than once. :c:func:`Py_FinalizeEx` must not be called recursively from - within itself. Therefore, it must not be called by any code that may be run - as part of the interpreter shutdown process, such as :py:mod:`atexit` - handlers, object finalizers, or any code that may be run while flushing the - stdout and stderr files. - - .. audit-event:: cpython._PySys_ClearAuditHooks "" c.Py_FinalizeEx - - .. versionadded:: 3.6 - - -.. c:function:: void Py_Finalize() - - This is a backwards-compatible version of :c:func:`Py_FinalizeEx` that - disregards the return value. - - -.. c:function:: int Py_BytesMain(int argc, char **argv) - - Similar to :c:func:`Py_Main` but *argv* is an array of bytes strings, - allowing the calling application to delegate the text decoding step to - the CPython runtime. - - .. versionadded:: 3.8 - - -.. c:function:: int Py_Main(int argc, wchar_t **argv) - - The main program for the standard interpreter, encapsulating a full - initialization/finalization cycle, as well as additional - behaviour to implement reading configurations settings from the environment - and command line, and then executing ``__main__`` in accordance with - :ref:`using-on-cmdline`. - - This is made available for programs which wish to support the full CPython - command line interface, rather than just embedding a Python runtime in a - larger application. - - The *argc* and *argv* parameters are similar to those which are passed to a - C program's :c:func:`main` function, except that the *argv* entries are first - converted to ``wchar_t`` using :c:func:`Py_DecodeLocale`. It is also - important to note that the argument list entries may be modified to point to - strings other than those passed in (however, the contents of the strings - pointed to by the argument list are not modified). - - The return value is ``2`` if the argument list does not represent a valid - Python command line, and otherwise the same as :c:func:`Py_RunMain`. - - In terms of the CPython runtime configuration APIs documented in the - :ref:`runtime configuration ` section (and without accounting - for error handling), ``Py_Main`` is approximately equivalent to:: - - PyConfig config; - PyConfig_InitPythonConfig(&config); - PyConfig_SetArgv(&config, argc, argv); - Py_InitializeFromConfig(&config); - PyConfig_Clear(&config); - - Py_RunMain(); - - In normal usage, an embedding application will call this function - *instead* of calling :c:func:`Py_Initialize`, :c:func:`Py_InitializeEx` or - :c:func:`Py_InitializeFromConfig` directly, and all settings will be applied - as described elsewhere in this documentation. If this function is instead - called *after* a preceding runtime initialization API call, then exactly - which environmental and command line configuration settings will be updated - is version dependent (as it depends on which settings correctly support - being modified after they have already been set once when the runtime was - first initialized). - - -.. c:function:: int Py_RunMain(void) - - Executes the main module in a fully configured CPython runtime. - - Executes the command (:c:member:`PyConfig.run_command`), the script - (:c:member:`PyConfig.run_filename`) or the module - (:c:member:`PyConfig.run_module`) specified on the command line or in the - configuration. If none of these values are set, runs the interactive Python - prompt (REPL) using the ``__main__`` module's global namespace. - - If :c:member:`PyConfig.inspect` is not set (the default), the return value - will be ``0`` if the interpreter exits normally (that is, without raising - an exception), the exit status of an unhandled :exc:`SystemExit`, or ``1`` - for any other unhandled exception. - - If :c:member:`PyConfig.inspect` is set (such as when the :option:`-i` option - is used), rather than returning when the interpreter exits, execution will - instead resume in an interactive Python prompt (REPL) using the ``__main__`` - module's global namespace. If the interpreter exited with an exception, it - is immediately raised in the REPL session. The function return value is - then determined by the way the *REPL session* terminates: ``0``, ``1``, or - the status of a :exc:`SystemExit`, as specified above. - - This function always finalizes the Python interpreter before it returns. - - See :ref:`Python Configuration ` for an example of a - customized Python that always runs in isolated mode using - :c:func:`Py_RunMain`. - -.. c:function:: int PyUnstable_AtExit(PyInterpreterState *interp, void (*func)(void *), void *data) - - Register an :mod:`atexit` callback for the target interpreter *interp*. - This is similar to :c:func:`Py_AtExit`, but takes an explicit interpreter and - data pointer for the callback. - - There must be an :term:`attached thread state` for *interp*. - - .. versionadded:: 3.13 - -Process-wide parameters -======================= - - -.. c:function:: void Py_SetProgramName(const wchar_t *name) - - .. index:: - single: Py_Initialize() - single: main() - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.program_name` should be used instead, see :ref:`Python - Initialization Configuration `. - - This function should be called before :c:func:`Py_Initialize` is called for - the first time, if it is called at all. It tells the interpreter the value - of the ``argv[0]`` argument to the :c:func:`main` function of the program - (converted to wide characters). - This is used by some other functions below to find - the Python run-time libraries relative to the interpreter executable. The - default value is ``'python'``. The argument should point to a - zero-terminated wide character string in static storage whose contents will not - change for the duration of the program's execution. No code in the Python - interpreter will change the contents of this storage. - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - .. deprecated-removed:: 3.11 3.15 - - -.. c:function:: const char* Py_GetVersion() - - Return the version of this Python interpreter. This is a string that looks - something like :: - - "3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]" - - .. index:: single: version (in module sys) - - The first word (up to the first space character) is the current Python version; - the first characters are the major and minor version separated by a - period. The returned string points into static storage; the caller should not - modify its value. The value is available to Python code as :data:`sys.version`. - - See also the :c:var:`Py_Version` constant. - - -.. c:function:: const char* Py_GetPlatform() - - .. index:: single: platform (in module sys) - - Return the platform identifier for the current platform. On Unix, this is - formed from the "official" name of the operating system, converted to lower - case, followed by the major revision number; e.g., for Solaris 2.x, which is - also known as SunOS 5.x, the value is ``'sunos5'``. On macOS, it is - ``'darwin'``. On Windows, it is ``'win'``. The returned string points into - static storage; the caller should not modify its value. The value is available - to Python code as ``sys.platform``. - - -.. c:function:: const char* Py_GetCopyright() - - Return the official copyright string for the current Python version, for example - - ``'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'`` - - .. index:: single: copyright (in module sys) - - The returned string points into static storage; the caller should not modify its - value. The value is available to Python code as ``sys.copyright``. - - -.. c:function:: const char* Py_GetCompiler() - - Return an indication of the compiler used to build the current Python version, - in square brackets, for example:: - - "[GCC 2.7.2.2]" - - .. index:: single: version (in module sys) - - The returned string points into static storage; the caller should not modify its - value. The value is available to Python code as part of the variable - ``sys.version``. - - -.. c:function:: const char* Py_GetBuildInfo() - - Return information about the sequence number and build date and time of the - current Python interpreter instance, for example :: - - "#67, Aug 1 1997, 22:34:28" - - .. index:: single: version (in module sys) - - The returned string points into static storage; the caller should not modify its - value. The value is available to Python code as part of the variable - ``sys.version``. - - -.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) - - .. index:: - single: main() - single: Py_FatalError() - single: argv (in module sys) - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.argv`, :c:member:`PyConfig.parse_argv` and - :c:member:`PyConfig.safe_path` should be used instead, see :ref:`Python - Initialization Configuration `. - - Set :data:`sys.argv` based on *argc* and *argv*. These parameters are - similar to those passed to the program's :c:func:`main` function with the - difference that the first entry should refer to the script file to be - executed rather than the executable hosting the Python interpreter. If there - isn't a script that will be run, the first entry in *argv* can be an empty - string. If this function fails to initialize :data:`sys.argv`, a fatal - condition is signalled using :c:func:`Py_FatalError`. - - If *updatepath* is zero, this is all the function does. If *updatepath* - is non-zero, the function also modifies :data:`sys.path` according to the - following algorithm: - - - If the name of an existing script is passed in ``argv[0]``, the absolute - path of the directory where the script is located is prepended to - :data:`sys.path`. - - Otherwise (that is, if *argc* is ``0`` or ``argv[0]`` doesn't point - to an existing file name), an empty string is prepended to - :data:`sys.path`, which is the same as prepending the current working - directory (``"."``). - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv` - members of the :ref:`Python Initialization Configuration `. - - .. note:: - It is recommended that applications embedding the Python interpreter - for purposes other than executing a single script pass ``0`` as *updatepath*, - and update :data:`sys.path` themselves if desired. - See :cve:`2008-5983`. - - On versions before 3.1.3, you can achieve the same effect by manually - popping the first :data:`sys.path` element after having called - :c:func:`PySys_SetArgv`, for example using:: - - PyRun_SimpleString("import sys; sys.path.pop(0)\n"); - - .. versionadded:: 3.1.3 - - .. XXX impl. doesn't seem consistent in allowing ``0``/``NULL`` for the params; - check w/ Guido. - - .. deprecated-removed:: 3.11 3.15 - - -.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv) - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` should be used - instead, see :ref:`Python Initialization Configuration `. - - This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set - to ``1`` unless the :program:`python` interpreter was started with the - :option:`-I`. - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv` - members of the :ref:`Python Initialization Configuration `. - - .. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`. - - .. deprecated-removed:: 3.11 3.15 - - -.. c:function:: void Py_SetPythonHome(const wchar_t *home) - - This API is kept for backward compatibility: setting - :c:member:`PyConfig.home` should be used instead, see :ref:`Python - Initialization Configuration `. - - Set the default "home" directory, that is, the location of the standard - Python libraries. See :envvar:`PYTHONHOME` for the meaning of the - argument string. - - The argument should point to a zero-terminated character string in static - storage whose contents will not change for the duration of the program's - execution. No code in the Python interpreter will change the contents of - this storage. - - Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_t*` string. - - .. deprecated-removed:: 3.11 3.15 - - -.. _threads: - -Thread State and the Global Interpreter Lock -============================================ - -.. index:: - single: global interpreter lock - single: interpreter lock - single: lock, interpreter - -Unless on a :term:`free-threaded ` build of :term:`CPython`, -the Python interpreter is not fully thread-safe. In order to support -multi-threaded Python programs, there's a global lock, called the :term:`global -interpreter lock` or :term:`GIL`, that must be held by the current thread before -it can safely access Python objects. Without the lock, even the simplest -operations could cause problems in a multi-threaded program: for example, when -two threads simultaneously increment the reference count of the same object, the -reference count could end up being incremented only once instead of twice. - -.. index:: single: setswitchinterval (in module sys) - -Therefore, the rule exists that only the thread that has acquired the -:term:`GIL` may operate on Python objects or call Python/C API functions. -In order to emulate concurrency of execution, the interpreter regularly -tries to switch threads (see :func:`sys.setswitchinterval`). The lock is also -released around potentially blocking I/O operations like reading or writing -a file, so that other Python threads can run in the meantime. - -.. index:: - single: PyThreadState (C type) - -The Python interpreter keeps some thread-specific bookkeeping information -inside a data structure called :c:type:`PyThreadState`, known as a :term:`thread state`. -Each OS thread has a thread-local pointer to a :c:type:`PyThreadState`; a thread state -referenced by this pointer is considered to be :term:`attached `. - -A thread can only have one :term:`attached thread state` at a time. An attached -thread state is typically analogous with holding the :term:`GIL`, except on -:term:`free-threaded ` builds. On builds with the :term:`GIL` enabled, -:term:`attaching ` a thread state will block until the :term:`GIL` -can be acquired. However, even on builds with the :term:`GIL` disabled, it is still required -to have an attached thread state to call most of the C API. - -In general, there will always be an :term:`attached thread state` when using Python's C API. -Only in some specific cases (such as in a :c:macro:`Py_BEGIN_ALLOW_THREADS` block) will the -thread not have an attached thread state. If uncertain, check if :c:func:`PyThreadState_GetUnchecked` returns -``NULL``. - -Detaching the thread state from extension code ----------------------------------------------- - -Most extension code manipulating the :term:`thread state` has the following simple -structure:: - - Save the thread state in a local variable. - ... Do some blocking I/O operation ... - Restore the thread state from the local variable. - -This is so common that a pair of macros exists to simplify it:: - - Py_BEGIN_ALLOW_THREADS - ... Do some blocking I/O operation ... - Py_END_ALLOW_THREADS - -.. index:: - single: Py_BEGIN_ALLOW_THREADS (C macro) - single: Py_END_ALLOW_THREADS (C macro) - -The :c:macro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a -hidden local variable; the :c:macro:`Py_END_ALLOW_THREADS` macro closes the -block. - -The block above expands to the following code:: - - PyThreadState *_save; - - _save = PyEval_SaveThread(); - ... Do some blocking I/O operation ... - PyEval_RestoreThread(_save); - -.. index:: - single: PyEval_RestoreThread (C function) - single: PyEval_SaveThread (C function) - -Here is how these functions work: - -The :term:`attached thread state` holds the :term:`GIL` for the entire interpreter. When detaching -the :term:`attached thread state`, the :term:`GIL` is released, allowing other threads to attach -a thread state to their own thread, thus getting the :term:`GIL` and can start executing. -The pointer to the prior :term:`attached thread state` is stored as a local variable. -Upon reaching :c:macro:`Py_END_ALLOW_THREADS`, the thread state that was -previously :term:`attached ` is passed to :c:func:`PyEval_RestoreThread`. -This function will block until another releases its :term:`thread state `, -thus allowing the old :term:`thread state ` to get re-attached and the -C API can be called again. - -For :term:`free-threaded ` builds, the :term:`GIL` is normally -out of the question, but detaching the :term:`thread state ` is still required -for blocking I/O and long operations. The difference is that threads don't have to wait for the :term:`GIL` -to be released to attach their thread state, allowing true multi-core parallelism. - -.. note:: - Calling system I/O functions is the most common use case for detaching - the :term:`thread state `, but it can also be useful before calling - long-running computations which don't need access to Python objects, such - as compression or cryptographic functions operating over memory buffers. - For example, the standard :mod:`zlib` and :mod:`hashlib` modules detach the - :term:`thread state ` when compressing or hashing data. - - -.. _gilstate: - -Non-Python created threads --------------------------- - -When threads are created using the dedicated Python APIs (such as the -:mod:`threading` module), a thread state is automatically associated to them -and the code showed above is therefore correct. However, when threads are -created from C (for example by a third-party library with its own thread -management), they don't hold the :term:`GIL`, because they don't have an -:term:`attached thread state`. - -If you need to call Python code from these threads (often this will be part -of a callback API provided by the aforementioned third-party library), -you must first register these threads with the interpreter by -creating an :term:`attached thread state` before you can start using the Python/C -API. When you are done, you should detach the :term:`thread state `, and -finally free it. - -The :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` functions do -all of the above automatically. The typical idiom for calling into Python -from a C thread is:: - - PyGILState_STATE gstate; - gstate = PyGILState_Ensure(); - - /* Perform Python actions here. */ - result = CallSomeFunction(); - /* evaluate result or handle exception */ - - /* Release the thread. No Python API allowed beyond this point. */ - PyGILState_Release(gstate); - -Note that the ``PyGILState_*`` functions assume there is only one global -interpreter (created automatically by :c:func:`Py_Initialize`). Python -supports the creation of additional interpreters (using -:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the -``PyGILState_*`` API is unsupported. This is because :c:func:`PyGILState_Ensure` -and similar functions default to :term:`attaching ` a -:term:`thread state` for the main interpreter, meaning that the thread can't safely -interact with the calling subinterpreter. - -Supporting subinterpreters in non-Python threads ------------------------------------------------- - -If you would like to support subinterpreters with non-Python created threads, you -must use the ``PyThreadState_*`` API instead of the traditional ``PyGILState_*`` -API. - -In particular, you must store the interpreter state from the calling -function and pass it to :c:func:`PyThreadState_New`, which will ensure that -the :term:`thread state` is targeting the correct interpreter:: - - /* The return value of PyInterpreterState_Get() from the - function that created this thread. */ - PyInterpreterState *interp = ThreadData->interp; - PyThreadState *tstate = PyThreadState_New(interp); - PyThreadState_Swap(tstate); - - /* GIL of the subinterpreter is now held. - Perform Python actions here. */ - result = CallSomeFunction(); - /* evaluate result or handle exception */ - - /* Destroy the thread state. No Python API allowed beyond this point. */ - PyThreadState_Clear(tstate); - PyThreadState_DeleteCurrent(); - -.. _fork-and-threads: - -Cautions about fork() ---------------------- - -Another important thing to note about threads is their behaviour in the face -of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a -process forks only the thread that issued the fork will exist. This has a -concrete impact both on how locks must be handled and on all stored state -in CPython's runtime. - -The fact that only the "current" thread remains -means any locks held by other threads will never be released. Python solves -this for :func:`os.fork` by acquiring the locks it uses internally before -the fork, and releasing them afterwards. In addition, it resets any -:ref:`lock-objects` in the child. When extending or embedding Python, there -is no way to inform Python of additional (non-Python) locks that need to be -acquired before or reset after a fork. OS facilities such as -:c:func:`!pthread_atfork` would need to be used to accomplish the same thing. -Additionally, when extending or embedding Python, calling :c:func:`fork` -directly rather than through :func:`os.fork` (and returning to or calling -into Python) may result in a deadlock by one of Python's internal locks -being held by a thread that is defunct after the fork. -:c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not -always able to. - -The fact that all other threads go away also means that CPython's -runtime state there must be cleaned up properly, which :func:`os.fork` -does. This means finalizing all other :c:type:`PyThreadState` objects -belonging to the current interpreter and all other -:c:type:`PyInterpreterState` objects. Due to this and the special -nature of the :ref:`"main" interpreter `, -:c:func:`fork` should only be called in that interpreter's "main" -thread, where the CPython global runtime was originally initialized. -The only exception is if :c:func:`exec` will be called immediately -after. - -.. _cautions-regarding-runtime-finalization: - -Cautions regarding runtime finalization ---------------------------------------- - -In the late stage of :term:`interpreter shutdown`, after attempting to wait for -non-daemon threads to exit (though this can be interrupted by -:class:`KeyboardInterrupt`) and running the :mod:`atexit` functions, the runtime -is marked as *finalizing*: :c:func:`Py_IsFinalizing` and -:func:`sys.is_finalizing` return true. At this point, only the *finalization -thread* that initiated finalization (typically the main thread) is allowed to -acquire the :term:`GIL`. - -If any thread, other than the finalization thread, attempts to attach a :term:`thread state` -during finalization, either explicitly or -implicitly, the thread enters **a permanently blocked state** -where it remains until the program exits. In most cases this is harmless, but this can result -in deadlock if a later stage of finalization attempts to acquire a lock owned by the -blocked thread, or otherwise waits on the blocked thread. - -Gross? Yes. This prevents random crashes and/or unexpectedly skipped C++ -finalizations further up the call stack when such threads were forcibly exited -here in CPython 3.13 and earlier. The CPython runtime :term:`thread state` C APIs -have never had any error reporting or handling expectations at :term:`thread state` -attachment time that would've allowed for graceful exit from this situation. Changing that -would require new stable C APIs and rewriting the majority of C code in the -CPython ecosystem to use those with error handling. - - -High-level API --------------- - -These are the most commonly used types and functions when writing C extension -code, or when embedding the Python interpreter: - -.. c:type:: PyInterpreterState - - This data structure represents the state shared by a number of cooperating - threads. Threads belonging to the same interpreter share their module - administration and a few other internal items. There are no public members in - this structure. - - Threads belonging to different interpreters initially share nothing, except - process state like available memory, open file descriptors and such. The global - interpreter lock is also shared by all threads, regardless of to which - interpreter they belong. - - .. versionchanged:: 3.12 - - :pep:`684` introduced the possibility - of a :ref:`per-interpreter GIL `. - See :c:func:`Py_NewInterpreterFromConfig`. - - -.. c:type:: PyThreadState - - This data structure represents the state of a single thread. The only public - data member is: - - .. c:member:: PyInterpreterState *interp - - This thread's interpreter state. - - -.. c:function:: void PyEval_InitThreads() - - .. index:: - single: PyEval_AcquireThread() - single: PyEval_ReleaseThread() - single: PyEval_SaveThread() - single: PyEval_RestoreThread() - - Deprecated function which does nothing. - - In Python 3.6 and older, this function created the GIL if it didn't exist. - - .. versionchanged:: 3.9 - The function now does nothing. - - .. versionchanged:: 3.7 - This function is now called by :c:func:`Py_Initialize()`, so you don't - have to call it yourself anymore. - - .. versionchanged:: 3.2 - This function cannot be called before :c:func:`Py_Initialize()` anymore. - - .. deprecated:: 3.9 - - .. index:: pair: module; _thread - - -.. c:function:: PyThreadState* PyEval_SaveThread() - - Detach the :term:`attached thread state` and return it. - The thread will have no :term:`thread state` upon returning. - - -.. c:function:: void PyEval_RestoreThread(PyThreadState *tstate) - - Set the :term:`attached thread state` to *tstate*. - The passed :term:`thread state` **should not** be :term:`attached `, - otherwise deadlock ensues. *tstate* will be attached upon returning. - - .. note:: - Calling this function from a thread when the runtime is finalizing will - hang the thread until the program exits, even if the thread was not - created by Python. Refer to - :ref:`cautions-regarding-runtime-finalization` for more details. - - .. versionchanged:: 3.14 - Hangs the current thread, rather than terminating it, if called while the - interpreter is finalizing. - -.. c:function:: PyThreadState* PyThreadState_Get() - - Return the :term:`attached thread state`. If the thread has no attached - thread state, (such as when inside of :c:macro:`Py_BEGIN_ALLOW_THREADS` - block), then this issues a fatal error (so that the caller needn't check - for ``NULL``). - - See also :c:func:`PyThreadState_GetUnchecked`. - -.. c:function:: PyThreadState* PyThreadState_GetUnchecked() - - Similar to :c:func:`PyThreadState_Get`, but don't kill the process with a - fatal error if it is NULL. The caller is responsible to check if the result - is NULL. - - .. versionadded:: 3.13 - In Python 3.5 to 3.12, the function was private and known as - ``_PyThreadState_UncheckedGet()``. - - -.. c:function:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) - - Set the :term:`attached thread state` to *tstate*, and return the - :term:`thread state` that was attached prior to calling. - - This function is safe to call without an :term:`attached thread state`; it - will simply return ``NULL`` indicating that there was no prior thread state. - - .. seealso:: - :c:func:`PyEval_ReleaseThread` - - .. note:: - Similar to :c:func:`PyGILState_Ensure`, this function will hang the - thread if the runtime is finalizing. - - -The following functions use thread-local storage, and are not compatible -with sub-interpreters: - -.. c:type:: PyGILState_STATE - - The type of the value returned by :c:func:`PyGILState_Ensure` and passed to - :c:func:`PyGILState_Release`. - - .. c:enumerator:: PyGILState_LOCKED - - The GIL was already held when :c:func:`PyGILState_Ensure` was called. - - .. c:enumerator:: PyGILState_UNLOCKED - - The GIL was not held when :c:func:`PyGILState_Ensure` was called. - -.. c:function:: PyGILState_STATE PyGILState_Ensure() - - Ensure that the current thread is ready to call the Python C API regardless - of the current state of Python, or of the :term:`attached thread state`. This may - be called as many times as desired by a thread as long as each call is - matched with a call to :c:func:`PyGILState_Release`. In general, other - thread-related APIs may be used between :c:func:`PyGILState_Ensure` and - :c:func:`PyGILState_Release` calls as long as the thread state is restored to - its previous state before the Release(). For example, normal usage of the - :c:macro:`Py_BEGIN_ALLOW_THREADS` and :c:macro:`Py_END_ALLOW_THREADS` macros is - acceptable. - - The return value is an opaque "handle" to the :term:`attached thread state` when - :c:func:`PyGILState_Ensure` was called, and must be passed to - :c:func:`PyGILState_Release` to ensure Python is left in the same state. Even - though recursive calls are allowed, these handles *cannot* be shared - each - unique call to :c:func:`PyGILState_Ensure` must save the handle for its call - to :c:func:`PyGILState_Release`. - - When the function returns, there will be an :term:`attached thread state` - and the thread will be able to call arbitrary Python code. Failure is a fatal error. - - .. warning:: - Calling this function when the runtime is finalizing is unsafe. Doing - so will either hang the thread until the program ends, or fully crash - the interpreter in rare cases. Refer to - :ref:`cautions-regarding-runtime-finalization` for more details. - - .. versionchanged:: 3.14 - Hangs the current thread, rather than terminating it, if called while the - interpreter is finalizing. - -.. c:function:: void PyGILState_Release(PyGILState_STATE) - - Release any resources previously acquired. After this call, Python's state will - be the same as it was prior to the corresponding :c:func:`PyGILState_Ensure` call - (but generally this state will be unknown to the caller, hence the use of the - GILState API). - - Every call to :c:func:`PyGILState_Ensure` must be matched by a call to - :c:func:`PyGILState_Release` on the same thread. - -.. c:function:: PyThreadState* PyGILState_GetThisThreadState() - - Get the :term:`attached thread state` for this thread. May return ``NULL`` if no - GILState API has been used on the current thread. Note that the main thread - always has such a thread-state, even if no auto-thread-state call has been - made on the main thread. This is mainly a helper/diagnostic function. - - .. note:: - This function may return non-``NULL`` even when the :term:`thread state` - is detached. - Prefer :c:func:`PyThreadState_Get` or :c:func:`PyThreadState_GetUnchecked` - for most cases. - - .. seealso:: :c:func:`PyThreadState_Get` - -.. c:function:: int PyGILState_Check() - - Return ``1`` if the current thread is holding the :term:`GIL` and ``0`` otherwise. - This function can be called from any thread at any time. - Only if it has had its :term:`thread state ` initialized - via :c:func:`PyGILState_Ensure` will it return ``1``. - This is mainly a helper/diagnostic function. It can be useful - for example in callback contexts or memory allocation functions when - knowing that the :term:`GIL` is locked can allow the caller to perform sensitive - actions or otherwise behave differently. - - .. note:: - If the current Python process has ever created a subinterpreter, this - function will *always* return ``1``. Prefer :c:func:`PyThreadState_GetUnchecked` - for most cases. - - .. versionadded:: 3.4 - - -The following macros are normally used without a trailing semicolon; look for -example usage in the Python source distribution. - - -.. c:macro:: Py_BEGIN_ALLOW_THREADS - - This macro expands to ``{ PyThreadState *_save; _save = PyEval_SaveThread();``. - Note that it contains an opening brace; it must be matched with a following - :c:macro:`Py_END_ALLOW_THREADS` macro. See above for further discussion of this - macro. - - -.. c:macro:: Py_END_ALLOW_THREADS - - This macro expands to ``PyEval_RestoreThread(_save); }``. Note that it contains - a closing brace; it must be matched with an earlier - :c:macro:`Py_BEGIN_ALLOW_THREADS` macro. See above for further discussion of - this macro. - - -.. c:macro:: Py_BLOCK_THREADS - - This macro expands to ``PyEval_RestoreThread(_save);``: it is equivalent to - :c:macro:`Py_END_ALLOW_THREADS` without the closing brace. - - -.. c:macro:: Py_UNBLOCK_THREADS - - This macro expands to ``_save = PyEval_SaveThread();``: it is equivalent to - :c:macro:`Py_BEGIN_ALLOW_THREADS` without the opening brace and variable - declaration. - - -Low-level API -------------- - -All of the following functions must be called after :c:func:`Py_Initialize`. - -.. versionchanged:: 3.7 - :c:func:`Py_Initialize()` now initializes the :term:`GIL` - and sets an :term:`attached thread state`. - - -.. c:function:: PyInterpreterState* PyInterpreterState_New() - - Create a new interpreter state object. An :term:`attached thread state` is not needed, - but may optionally exist if it is necessary to serialize calls to this - function. - - .. audit-event:: cpython.PyInterpreterState_New "" c.PyInterpreterState_New - - -.. c:function:: void PyInterpreterState_Clear(PyInterpreterState *interp) - - Reset all information in an interpreter state object. There must be - an :term:`attached thread state` for the interpreter. - - .. audit-event:: cpython.PyInterpreterState_Clear "" c.PyInterpreterState_Clear - - -.. c:function:: void PyInterpreterState_Delete(PyInterpreterState *interp) - - Destroy an interpreter state object. There **should not** be an - :term:`attached thread state` for the target interpreter. The interpreter - state must have been reset with a previous call to :c:func:`PyInterpreterState_Clear`. - - -.. c:function:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) - - Create a new thread state object belonging to the given interpreter object. - An :term:`attached thread state` is not needed. - -.. c:function:: void PyThreadState_Clear(PyThreadState *tstate) - - Reset all information in a :term:`thread state` object. *tstate* - must be :term:`attached ` - - .. versionchanged:: 3.9 - This function now calls the :c:member:`!PyThreadState.on_delete` callback. - Previously, that happened in :c:func:`PyThreadState_Delete`. - - .. versionchanged:: 3.13 - The :c:member:`!PyThreadState.on_delete` callback was removed. - - -.. c:function:: void PyThreadState_Delete(PyThreadState *tstate) - - Destroy a :term:`thread state` object. *tstate* should not - be :term:`attached ` to any thread. - *tstate* must have been reset with a previous call to - :c:func:`PyThreadState_Clear`. - - -.. c:function:: void PyThreadState_DeleteCurrent(void) - - Detach the :term:`attached thread state` (which must have been reset - with a previous call to :c:func:`PyThreadState_Clear`) and then destroy it. - - No :term:`thread state` will be :term:`attached ` upon - returning. - -.. c:function:: PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) - - Get the current frame of the Python thread state *tstate*. - - Return a :term:`strong reference`. Return ``NULL`` if no frame is currently - executing. - - See also :c:func:`PyEval_GetFrame`. - - *tstate* must not be ``NULL``, and must be :term:`attached `. - - .. versionadded:: 3.9 - - -.. c:function:: uint64_t PyThreadState_GetID(PyThreadState *tstate) - - Get the unique :term:`thread state` identifier of the Python thread state *tstate*. - - *tstate* must not be ``NULL``, and must be :term:`attached `. - - .. versionadded:: 3.9 - - -.. c:function:: PyInterpreterState* PyThreadState_GetInterpreter(PyThreadState *tstate) - - Get the interpreter of the Python thread state *tstate*. - - *tstate* must not be ``NULL``, and must be :term:`attached `. - - .. versionadded:: 3.9 - - -.. c:function:: void PyThreadState_EnterTracing(PyThreadState *tstate) - - Suspend tracing and profiling in the Python thread state *tstate*. - - Resume them using the :c:func:`PyThreadState_LeaveTracing` function. - - .. versionadded:: 3.11 - - -.. c:function:: void PyThreadState_LeaveTracing(PyThreadState *tstate) - - Resume tracing and profiling in the Python thread state *tstate* suspended - by the :c:func:`PyThreadState_EnterTracing` function. - - See also :c:func:`PyEval_SetTrace` and :c:func:`PyEval_SetProfile` - functions. - - .. versionadded:: 3.11 - - -.. c:function:: int PyUnstable_ThreadState_SetStackProtection(PyThreadState *tstate, void *stack_start_addr, size_t stack_size) - - Set the stack protection start address and stack protection size - of a Python thread state. - - On success, return ``0``. - On failure, set an exception and return ``-1``. - - CPython implements :ref:`recursion control ` for C code by raising - :py:exc:`RecursionError` when it notices that the machine execution stack is close - to overflow. See for example the :c:func:`Py_EnterRecursiveCall` function. - For this, it needs to know the location of the current thread's stack, which it - normally gets from the operating system. - When the stack is changed, for example using context switching techniques like the - Boost library's ``boost::context``, you must call - :c:func:`~PyUnstable_ThreadState_SetStackProtection` to inform CPython of the change. - - Call :c:func:`~PyUnstable_ThreadState_SetStackProtection` either before - or after changing the stack. - Do not call any other Python C API between the call and the stack - change. - - See :c:func:`PyUnstable_ThreadState_ResetStackProtection` for undoing this operation. - - .. versionadded:: 3.15 - - -.. c:function:: void PyUnstable_ThreadState_ResetStackProtection(PyThreadState *tstate) - - Reset the stack protection start address and stack protection size - of a Python thread state to the operating system defaults. - - See :c:func:`PyUnstable_ThreadState_SetStackProtection` for an explanation. - - .. versionadded:: 3.15 - - -.. c:function:: PyInterpreterState* PyInterpreterState_Get(void) - - Get the current interpreter. - - Issue a fatal error if there is no :term:`attached thread state`. - It cannot return NULL. - - .. versionadded:: 3.9 - - -.. c:function:: int64_t PyInterpreterState_GetID(PyInterpreterState *interp) - - Return the interpreter's unique ID. If there was any error in doing - so then ``-1`` is returned and an error is set. - - The caller must have an :term:`attached thread state`. - - .. versionadded:: 3.7 - - -.. c:function:: PyObject* PyInterpreterState_GetDict(PyInterpreterState *interp) - - Return a dictionary in which interpreter-specific data may be stored. - If this function returns ``NULL`` then no exception has been raised and - the caller should assume no interpreter-specific dict is available. - - This is not a replacement for :c:func:`PyModule_GetState()`, which - extensions should use to store interpreter-specific state information. - - The returned dictionary is borrowed from the interpreter and is valid until - interpreter shutdown. - - .. versionadded:: 3.8 - - -.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) - - Type of a frame evaluation function. - - The *throwflag* parameter is used by the ``throw()`` method of generators: - if non-zero, handle the current exception. - - .. versionchanged:: 3.9 - The function now takes a *tstate* parameter. - - .. versionchanged:: 3.11 - The *frame* parameter changed from ``PyFrameObject*`` to ``_PyInterpreterFrame*``. - -.. c:function:: _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp) - - Get the frame evaluation function. - - See the :pep:`523` "Adding a frame evaluation API to CPython". - - .. versionadded:: 3.9 - -.. c:function:: void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame) - - Set the frame evaluation function. - - See the :pep:`523` "Adding a frame evaluation API to CPython". - - .. versionadded:: 3.9 - - -.. c:function:: PyObject* PyThreadState_GetDict() - - Return a dictionary in which extensions can store thread-specific state - information. Each extension should use a unique key to use to store state in - the dictionary. It is okay to call this function when no :term:`thread state` - is :term:`attached `. If this function returns - ``NULL``, no exception has been raised and the caller should assume no - thread state is attached. - - -.. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) - - Asynchronously raise an exception in a thread. The *id* argument is the thread - id of the target thread; *exc* is the exception object to be raised. This - function does not steal any references to *exc*. To prevent naive misuse, you - must write your own C extension to call this. Must be called with an :term:`attached thread state`. - Returns the number of thread states modified; this is normally one, but will be - zero if the thread id isn't found. If *exc* is ``NULL``, the pending - exception (if any) for the thread is cleared. This raises no exceptions. - - .. versionchanged:: 3.7 - The type of the *id* parameter changed from :c:expr:`long` to - :c:expr:`unsigned long`. - -.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate) - - :term:`Attach ` *tstate* to the current thread, - which must not be ``NULL`` or already :term:`attached `. - - The calling thread must not already have an :term:`attached thread state`. - - .. note:: - Calling this function from a thread when the runtime is finalizing will - hang the thread until the program exits, even if the thread was not - created by Python. Refer to - :ref:`cautions-regarding-runtime-finalization` for more details. - - .. versionchanged:: 3.8 - Updated to be consistent with :c:func:`PyEval_RestoreThread`, - :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`, - and terminate the current thread if called while the interpreter is finalizing. - - .. versionchanged:: 3.14 - Hangs the current thread, rather than terminating it, if called while the - interpreter is finalizing. - - :c:func:`PyEval_RestoreThread` is a higher-level function which is always - available (even when threads have not been initialized). - - -.. c:function:: void PyEval_ReleaseThread(PyThreadState *tstate) - - Detach the :term:`attached thread state`. - The *tstate* argument, which must not be ``NULL``, is only used to check - that it represents the :term:`attached thread state` --- if it isn't, a fatal error is - reported. - - :c:func:`PyEval_SaveThread` is a higher-level function which is always - available (even when threads have not been initialized). - - -.. _sub-interpreter-support: - -Sub-interpreter support -======================= - -While in most uses, you will only embed a single Python interpreter, there -are cases where you need to create several independent interpreters in the -same process and perhaps even in the same thread. Sub-interpreters allow -you to do that. - -The "main" interpreter is the first one created when the runtime initializes. -It is usually the only Python interpreter in a process. Unlike sub-interpreters, -the main interpreter has unique process-global responsibilities like signal -handling. It is also responsible for execution during runtime initialization and -is usually the active interpreter during runtime finalization. The -:c:func:`PyInterpreterState_Main` function returns a pointer to its state. - -You can switch between sub-interpreters using the :c:func:`PyThreadState_Swap` -function. You can create and destroy them using the following functions: - - -.. c:type:: PyInterpreterConfig - - Structure containing most parameters to configure a sub-interpreter. - Its values are used only in :c:func:`Py_NewInterpreterFromConfig` and - never modified by the runtime. - - .. versionadded:: 3.12 - - Structure fields: - - .. c:member:: int use_main_obmalloc - - If this is ``0`` then the sub-interpreter will use its own - "object" allocator state. - Otherwise it will use (share) the main interpreter's. - - If this is ``0`` then - :c:member:`~PyInterpreterConfig.check_multi_interp_extensions` - must be ``1`` (non-zero). - If this is ``1`` then :c:member:`~PyInterpreterConfig.gil` - must not be :c:macro:`PyInterpreterConfig_OWN_GIL`. - - .. c:member:: int allow_fork - - If this is ``0`` then the runtime will not support forking the - process in any thread where the sub-interpreter is currently active. - Otherwise fork is unrestricted. - - Note that the :mod:`subprocess` module still works - when fork is disallowed. - - .. c:member:: int allow_exec - - If this is ``0`` then the runtime will not support replacing the - current process via exec (e.g. :func:`os.execv`) in any thread - where the sub-interpreter is currently active. - Otherwise exec is unrestricted. - - Note that the :mod:`subprocess` module still works - when exec is disallowed. - - .. c:member:: int allow_threads - - If this is ``0`` then the sub-interpreter's :mod:`threading` module - won't create threads. - Otherwise threads are allowed. - - .. c:member:: int allow_daemon_threads - - If this is ``0`` then the sub-interpreter's :mod:`threading` module - won't create daemon threads. - Otherwise daemon threads are allowed (as long as - :c:member:`~PyInterpreterConfig.allow_threads` is non-zero). - - .. c:member:: int check_multi_interp_extensions - - If this is ``0`` then all extension modules may be imported, - including legacy (single-phase init) modules, - in any thread where the sub-interpreter is currently active. - Otherwise only multi-phase init extension modules - (see :pep:`489`) may be imported. - (Also see :c:macro:`Py_mod_multiple_interpreters`.) - - This must be ``1`` (non-zero) if - :c:member:`~PyInterpreterConfig.use_main_obmalloc` is ``0``. - - .. c:member:: int gil - - This determines the operation of the GIL for the sub-interpreter. - It may be one of the following: - - .. c:namespace:: NULL - - .. c:macro:: PyInterpreterConfig_DEFAULT_GIL - - Use the default selection (:c:macro:`PyInterpreterConfig_SHARED_GIL`). - - .. c:macro:: PyInterpreterConfig_SHARED_GIL - - Use (share) the main interpreter's GIL. - - .. c:macro:: PyInterpreterConfig_OWN_GIL - - Use the sub-interpreter's own GIL. - - If this is :c:macro:`PyInterpreterConfig_OWN_GIL` then - :c:member:`PyInterpreterConfig.use_main_obmalloc` must be ``0``. - - -.. c:function:: PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config) - - .. index:: - pair: module; builtins - pair: module; __main__ - pair: module; sys - single: stdout (in module sys) - single: stderr (in module sys) - single: stdin (in module sys) - - Create a new sub-interpreter. This is an (almost) totally separate environment - for the execution of Python code. In particular, the new interpreter has - separate, independent versions of all imported modules, including the - fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. The - table of loaded modules (``sys.modules``) and the module search path - (``sys.path``) are also separate. The new environment has no ``sys.argv`` - variable. It has new standard I/O stream file objects ``sys.stdin``, - ``sys.stdout`` and ``sys.stderr`` (however these refer to the same underlying - file descriptors). - - The given *config* controls the options with which the interpreter - is initialized. - - Upon success, *tstate_p* will be set to the first :term:`thread state` - created in the new sub-interpreter. This thread state is - :term:`attached `. - Note that no actual thread is created; see the discussion of thread states - below. If creation of the new interpreter is unsuccessful, - *tstate_p* is set to ``NULL``; - no exception is set since the exception state is stored in the - :term:`attached thread state`, which might not exist. - - Like all other Python/C API functions, an :term:`attached thread state` - must be present before calling this function, but it might be detached upon - returning. On success, the returned thread state will be :term:`attached `. - If the sub-interpreter is created with its own :term:`GIL` then the - :term:`attached thread state` of the calling interpreter will be detached. - When the function returns, the new interpreter's :term:`thread state` - will be :term:`attached ` to the current thread and - the previous interpreter's :term:`attached thread state` will remain detached. - - .. versionadded:: 3.12 - - Sub-interpreters are most effective when isolated from each other, - with certain functionality restricted:: - - PyInterpreterConfig config = { - .use_main_obmalloc = 0, - .allow_fork = 0, - .allow_exec = 0, - .allow_threads = 1, - .allow_daemon_threads = 0, - .check_multi_interp_extensions = 1, - .gil = PyInterpreterConfig_OWN_GIL, - }; - PyThreadState *tstate = NULL; - PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - - Note that the config is used only briefly and does not get modified. - During initialization the config's values are converted into various - :c:type:`PyInterpreterState` values. A read-only copy of the config - may be stored internally on the :c:type:`PyInterpreterState`. - - .. index:: - single: Py_FinalizeEx (C function) - single: Py_Initialize (C function) - - Extension modules are shared between (sub-)interpreters as follows: - - * For modules using multi-phase initialization, - e.g. :c:func:`PyModule_FromDefAndSpec`, a separate module object is - created and initialized for each interpreter. - Only C-level static and global variables are shared between these - module objects. - - * For modules using legacy - :ref:`single-phase initialization `, - e.g. :c:func:`PyModule_Create`, the first time a particular extension - is imported, it is initialized normally, and a (shallow) copy of its - module's dictionary is squirreled away. - When the same extension is imported by another (sub-)interpreter, a new - module is initialized and filled with the contents of this copy; the - extension's ``init`` function is not called. - Objects in the module's dictionary thus end up shared across - (sub-)interpreters, which might cause unwanted behavior (see - `Bugs and caveats`_ below). - - Note that this is different from what happens when an extension is - imported after the interpreter has been completely re-initialized by - calling :c:func:`Py_FinalizeEx` and :c:func:`Py_Initialize`; in that - case, the extension's ``initmodule`` function *is* called again. - As with multi-phase initialization, this means that only C-level static - and global variables are shared between these modules. - - .. index:: single: close (in module os) - - -.. c:function:: PyThreadState* Py_NewInterpreter(void) - - .. index:: - pair: module; builtins - pair: module; __main__ - pair: module; sys - single: stdout (in module sys) - single: stderr (in module sys) - single: stdin (in module sys) - - Create a new sub-interpreter. This is essentially just a wrapper - around :c:func:`Py_NewInterpreterFromConfig` with a config that - preserves the existing behavior. The result is an unisolated - sub-interpreter that shares the main interpreter's GIL, allows - fork/exec, allows daemon threads, and allows single-phase init - modules. - - -.. c:function:: void Py_EndInterpreter(PyThreadState *tstate) - - .. index:: single: Py_FinalizeEx (C function) - - Destroy the (sub-)interpreter represented by the given :term:`thread state`. - The given thread state must be :term:`attached `. - When the call returns, there will be no :term:`attached thread state`. - All thread states associated with this interpreter are destroyed. - - :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that - haven't been explicitly destroyed at that point. - - -.. _per-interpreter-gil: - -A Per-Interpreter GIL ---------------------- - -Using :c:func:`Py_NewInterpreterFromConfig` you can create -a sub-interpreter that is completely isolated from other interpreters, -including having its own GIL. The most important benefit of this -isolation is that such an interpreter can execute Python code without -being blocked by other interpreters or blocking any others. Thus a -single Python process can truly take advantage of multiple CPU cores -when running Python code. The isolation also encourages a different -approach to concurrency than that of just using threads. -(See :pep:`554` and :pep:`684`.) - -Using an isolated interpreter requires vigilance in preserving that -isolation. That especially means not sharing any objects or mutable -state without guarantees about thread-safety. Even objects that are -otherwise immutable (e.g. ``None``, ``(1, 5)``) can't normally be shared -because of the refcount. One simple but less-efficient approach around -this is to use a global lock around all use of some state (or object). -Alternately, effectively immutable objects (like integers or strings) -can be made safe in spite of their refcounts by making them :term:`immortal`. -In fact, this has been done for the builtin singletons, small integers, -and a number of other builtin objects. - -If you preserve isolation then you will have access to proper multi-core -computing without the complications that come with free-threading. -Failure to preserve isolation will expose you to the full consequences -of free-threading, including races and hard-to-debug crashes. - -Aside from that, one of the main challenges of using multiple isolated -interpreters is how to communicate between them safely (not break -isolation) and efficiently. The runtime and stdlib do not provide -any standard approach to this yet. A future stdlib module would help -mitigate the effort of preserving isolation and expose effective tools -for communicating (and sharing) data between interpreters. - -.. versionadded:: 3.12 - - -Bugs and caveats ----------------- - -Because sub-interpreters (and the main interpreter) are part of the same -process, the insulation between them isn't perfect --- for example, using -low-level file operations like :func:`os.close` they can -(accidentally or maliciously) affect each other's open files. Because of the -way extensions are shared between (sub-)interpreters, some extensions may not -work properly; this is especially likely when using single-phase initialization -or (static) global variables. -It is possible to insert objects created in one sub-interpreter into -a namespace of another (sub-)interpreter; this should be avoided if possible. - -Special care should be taken to avoid sharing user-defined functions, -methods, instances or classes between sub-interpreters, since import -operations executed by such objects may affect the wrong (sub-)interpreter's -dictionary of loaded modules. It is equally important to avoid sharing -objects from which the above are reachable. - -Also note that combining this functionality with ``PyGILState_*`` APIs -is delicate, because these APIs assume a bijection between Python thread states -and OS-level threads, an assumption broken by the presence of sub-interpreters. -It is highly recommended that you don't switch sub-interpreters between a pair -of matching :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` calls. -Furthermore, extensions (such as :mod:`ctypes`) using these APIs to allow calling -of Python code from non-Python created threads will probably be broken when using -sub-interpreters. - - -Asynchronous Notifications -========================== - -A mechanism is provided to make asynchronous notifications to the main -interpreter thread. These notifications take the form of a function -pointer and a void pointer argument. - - -.. c:function:: int Py_AddPendingCall(int (*func)(void *), void *arg) - - Schedule a function to be called from the main interpreter thread. On - success, ``0`` is returned and *func* is queued for being called in the - main thread. On failure, ``-1`` is returned without setting any exception. - - When successfully queued, *func* will be *eventually* called from the - main interpreter thread with the argument *arg*. It will be called - asynchronously with respect to normally running Python code, but with - both these conditions met: - - * on a :term:`bytecode` boundary; - * with the main thread holding an :term:`attached thread state` - (*func* can therefore use the full C API). - - *func* must return ``0`` on success, or ``-1`` on failure with an exception - set. *func* won't be interrupted to perform another asynchronous - notification recursively, but it can still be interrupted to switch - threads if the :term:`thread state ` is detached. - - This function doesn't need an :term:`attached thread state`. However, to call this - function in a subinterpreter, the caller must have an :term:`attached thread state`. - Otherwise, the function *func* can be scheduled to be called from the wrong interpreter. - - .. warning:: - This is a low-level function, only useful for very special cases. - There is no guarantee that *func* will be called as quick as - possible. If the main thread is busy executing a system call, - *func* won't be called before the system call returns. This - function is generally **not** suitable for calling Python code from - arbitrary C threads. Instead, use the :ref:`PyGILState API`. - - .. versionadded:: 3.1 - - .. versionchanged:: 3.9 - If this function is called in a subinterpreter, the function *func* is - now scheduled to be called from the subinterpreter, rather than being - called from the main interpreter. Each subinterpreter now has its own - list of scheduled calls. - - .. versionchanged:: 3.12 - This function now always schedules *func* to be run in the main - interpreter. - - -.. c:function:: int Py_MakePendingCalls(void) - - Execute all pending calls. This is usually executed automatically by the - interpreter. - - This function returns ``0`` on success, and returns ``-1`` with an exception - set on failure. - - If this is not called in the main thread of the main - interpreter, this function does nothing and returns ``0``. - The caller must hold an :term:`attached thread state`. - - .. versionadded:: 3.1 - - .. versionchanged:: 3.12 - This function only runs pending calls in the main interpreter. - - -.. _profiling: - -Profiling and Tracing -===================== - -The Python interpreter provides some low-level support for attaching profiling -and execution tracing facilities. These are used for profiling, debugging, and -coverage analysis tools. - -This C interface allows the profiling or tracing code to avoid the overhead of -calling through Python-level callable objects, making a direct C function call -instead. The essential attributes of the facility have not changed; the -interface allows trace functions to be installed per-thread, and the basic -events reported to the trace function are the same as had been reported to the -Python-level trace functions in previous versions. - - -.. c:type:: int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) - - The type of the trace function registered using :c:func:`PyEval_SetProfile` and - :c:func:`PyEval_SetTrace`. The first parameter is the object passed to the - registration function as *obj*, *frame* is the frame object to which the event - pertains, *what* is one of the constants :c:data:`PyTrace_CALL`, - :c:data:`PyTrace_EXCEPTION`, :c:data:`PyTrace_LINE`, :c:data:`PyTrace_RETURN`, - :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION`, :c:data:`PyTrace_C_RETURN`, - or :c:data:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: - - +-------------------------------+----------------------------------------+ - | Value of *what* | Meaning of *arg* | - +===============================+========================================+ - | :c:data:`PyTrace_CALL` | Always :c:data:`Py_None`. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_EXCEPTION` | Exception information as returned by | - | | :func:`sys.exc_info`. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_LINE` | Always :c:data:`Py_None`. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_RETURN` | Value being returned to the caller, | - | | or ``NULL`` if caused by an exception. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_C_CALL` | Function object being called. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_C_EXCEPTION` | Function object being called. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_C_RETURN` | Function object being called. | - +-------------------------------+----------------------------------------+ - | :c:data:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | - +-------------------------------+----------------------------------------+ - -.. c:var:: int PyTrace_CALL - - The value of the *what* parameter to a :c:type:`Py_tracefunc` function when a new - call to a function or method is being reported, or a new entry into a generator. - Note that the creation of the iterator for a generator function is not reported - as there is no control transfer to the Python bytecode in the corresponding - frame. - - -.. c:var:: int PyTrace_EXCEPTION - - The value of the *what* parameter to a :c:type:`Py_tracefunc` function when an - exception has been raised. The callback function is called with this value for - *what* when after any bytecode is processed after which the exception becomes - set within the frame being executed. The effect of this is that as exception - propagation causes the Python stack to unwind, the callback is called upon - return to each frame as the exception propagates. Only trace functions receive - these events; they are not needed by the profiler. - - -.. c:var:: int PyTrace_LINE - - The value passed as the *what* parameter to a :c:type:`Py_tracefunc` function - (but not a profiling function) when a line-number event is being reported. - It may be disabled for a frame by setting :attr:`~frame.f_trace_lines` to - *0* on that frame. - - -.. c:var:: int PyTrace_RETURN - - The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a - call is about to return. - - -.. c:var:: int PyTrace_C_CALL - - The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C - function is about to be called. - - -.. c:var:: int PyTrace_C_EXCEPTION - - The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C - function has raised an exception. - - -.. c:var:: int PyTrace_C_RETURN - - The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C - function has returned. - - -.. c:var:: int PyTrace_OPCODE - - The value for the *what* parameter to :c:type:`Py_tracefunc` functions (but not - profiling functions) when a new opcode is about to be executed. This event is - not emitted by default: it must be explicitly requested by setting - :attr:`~frame.f_trace_opcodes` to *1* on the frame. - - -.. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj) - - Set the profiler function to *func*. The *obj* parameter is passed to the - function as its first parameter, and may be any Python object, or ``NULL``. If - the profile function needs to maintain state, using a different value for *obj* - for each thread provides a convenient and thread-safe place to store it. The - profile function is called for all monitored events except :c:data:`PyTrace_LINE` - :c:data:`PyTrace_OPCODE` and :c:data:`PyTrace_EXCEPTION`. - - See also the :func:`sys.setprofile` function. - - The caller must have an :term:`attached thread state`. - -.. c:function:: void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj) - - Like :c:func:`PyEval_SetProfile` but sets the profile function in all running threads - belonging to the current interpreter instead of the setting it only on the current thread. - - The caller must have an :term:`attached thread state`. - - As :c:func:`PyEval_SetProfile`, this function ignores any exceptions raised while - setting the profile functions in all threads. - -.. versionadded:: 3.12 - - -.. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj) - - Set the tracing function to *func*. This is similar to - :c:func:`PyEval_SetProfile`, except the tracing function does receive line-number - events and per-opcode events, but does not receive any event related to C function - objects being called. Any trace function registered using :c:func:`PyEval_SetTrace` - will not receive :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION` or - :c:data:`PyTrace_C_RETURN` as a value for the *what* parameter. - - See also the :func:`sys.settrace` function. - - The caller must have an :term:`attached thread state`. - -.. c:function:: void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj) - - Like :c:func:`PyEval_SetTrace` but sets the tracing function in all running threads - belonging to the current interpreter instead of the setting it only on the current thread. - - The caller must have an :term:`attached thread state`. - - As :c:func:`PyEval_SetTrace`, this function ignores any exceptions raised while - setting the trace functions in all threads. - -.. versionadded:: 3.12 - -Reference tracing -================= - -.. versionadded:: 3.13 - -.. c:type:: int (*PyRefTracer)(PyObject *, int event, void* data) - - The type of the trace function registered using :c:func:`PyRefTracer_SetTracer`. - The first parameter is a Python object that has been just created (when **event** - is set to :c:data:`PyRefTracer_CREATE`) or about to be destroyed (when **event** - is set to :c:data:`PyRefTracer_DESTROY`). The **data** argument is the opaque pointer - that was provided when :c:func:`PyRefTracer_SetTracer` was called. - - If a new tracing function is registered replacing the current a call to the - trace function will be made with the object set to **NULL** and **event** set to - :c:data:`PyRefTracer_TRACKER_REMOVED`. This will happen just before the new - function is registered. - -.. versionadded:: 3.13 - -.. c:var:: int PyRefTracer_CREATE - - The value for the *event* parameter to :c:type:`PyRefTracer` functions when a Python - object has been created. - -.. c:var:: int PyRefTracer_DESTROY - - The value for the *event* parameter to :c:type:`PyRefTracer` functions when a Python - object has been destroyed. - -.. c:var:: int PyRefTracer_TRACKER_REMOVED - - The value for the *event* parameter to :c:type:`PyRefTracer` functions when the - current tracer is about to be replaced by a new one. - - .. versionadded:: 3.14 - -.. c:function:: int PyRefTracer_SetTracer(PyRefTracer tracer, void *data) - - Register a reference tracer function. The function will be called when a new - Python has been created or when an object is going to be destroyed. If - **data** is provided it must be an opaque pointer that will be provided when - the tracer function is called. Return ``0`` on success. Set an exception and - return ``-1`` on error. - - Note that tracer functions **must not** create Python objects inside or - otherwise the call will be re-entrant. The tracer also **must not** clear - any existing exception or set an exception. A :term:`thread state` will be active - every time the tracer function is called. - - There must be an :term:`attached thread state` when calling this function. - - If another tracer function was already registered, the old function will be - called with **event** set to :c:data:`PyRefTracer_TRACKER_REMOVED` just before - the new function is registered. - -.. versionadded:: 3.13 - -.. c:function:: PyRefTracer PyRefTracer_GetTracer(void** data) - - Get the registered reference tracer function and the value of the opaque data - pointer that was registered when :c:func:`PyRefTracer_SetTracer` was called. - If no tracer was registered this function will return NULL and will set the - **data** pointer to NULL. - - There must be an :term:`attached thread state` when calling this function. - -.. versionadded:: 3.13 - -.. _advanced-debugging: - -Advanced Debugger Support -========================= - -These functions are only intended to be used by advanced debugging tools. - - -.. c:function:: PyInterpreterState* PyInterpreterState_Head() - - Return the interpreter state object at the head of the list of all such objects. - - -.. c:function:: PyInterpreterState* PyInterpreterState_Main() - - Return the main interpreter state object. - - -.. c:function:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp) - - Return the next interpreter state object after *interp* from the list of all - such objects. - - -.. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp) - - Return the pointer to the first :c:type:`PyThreadState` object in the list of - threads associated with the interpreter *interp*. - - -.. c:function:: PyThreadState* PyThreadState_Next(PyThreadState *tstate) - - Return the next thread state object after *tstate* from the list of all such - objects belonging to the same :c:type:`PyInterpreterState` object. - - -.. _thread-local-storage: - -Thread Local Storage Support -============================ - -The Python interpreter provides low-level support for thread-local storage -(TLS) which wraps the underlying native TLS implementation to support the -Python-level thread local storage API (:class:`threading.local`). The -CPython C level APIs are similar to those offered by pthreads and Windows: -use a thread key and functions to associate a :c:expr:`void*` value per -thread. - -A :term:`thread state` does *not* need to be :term:`attached ` -when calling these functions; they supply their own locking. - -Note that :file:`Python.h` does not include the declaration of the TLS APIs, -you need to include :file:`pythread.h` to use thread-local storage. - -.. note:: - None of these API functions handle memory management on behalf of the - :c:expr:`void*` values. You need to allocate and deallocate them yourself. - If the :c:expr:`void*` values happen to be :c:expr:`PyObject*`, these - functions don't do refcount operations on them either. - -.. _thread-specific-storage-api: - -Thread Specific Storage (TSS) API ---------------------------------- - -TSS API is introduced to supersede the use of the existing TLS API within the -CPython interpreter. This API uses a new type :c:type:`Py_tss_t` instead of -:c:expr:`int` to represent thread keys. - -.. versionadded:: 3.7 - -.. seealso:: "A New C-API for Thread-Local Storage in CPython" (:pep:`539`) - - -.. c:type:: Py_tss_t - - This data structure represents the state of a thread key, the definition of - which may depend on the underlying TLS implementation, and it has an - internal field representing the key's initialization state. There are no - public members in this structure. - - When :ref:`Py_LIMITED_API ` is not defined, static allocation of - this type by :c:macro:`Py_tss_NEEDS_INIT` is allowed. - - -.. c:macro:: Py_tss_NEEDS_INIT - - This macro expands to the initializer for :c:type:`Py_tss_t` variables. - Note that this macro won't be defined with :ref:`Py_LIMITED_API `. - - -Dynamic Allocation -~~~~~~~~~~~~~~~~~~ - -Dynamic allocation of the :c:type:`Py_tss_t`, required in extension modules -built with :ref:`Py_LIMITED_API `, where static allocation of this type -is not possible due to its implementation being opaque at build time. - - -.. c:function:: Py_tss_t* PyThread_tss_alloc() - - Return a value which is the same state as a value initialized with - :c:macro:`Py_tss_NEEDS_INIT`, or ``NULL`` in the case of dynamic allocation - failure. - - -.. c:function:: void PyThread_tss_free(Py_tss_t *key) - - Free the given *key* allocated by :c:func:`PyThread_tss_alloc`, after - first calling :c:func:`PyThread_tss_delete` to ensure any associated - thread locals have been unassigned. This is a no-op if the *key* - argument is ``NULL``. - - .. note:: - A freed key becomes a dangling pointer. You should reset the key to - ``NULL``. - - -Methods -~~~~~~~ - -The parameter *key* of these functions must not be ``NULL``. Moreover, the -behaviors of :c:func:`PyThread_tss_set` and :c:func:`PyThread_tss_get` are -undefined if the given :c:type:`Py_tss_t` has not been initialized by -:c:func:`PyThread_tss_create`. - - -.. c:function:: int PyThread_tss_is_created(Py_tss_t *key) - - Return a non-zero value if the given :c:type:`Py_tss_t` has been initialized - by :c:func:`PyThread_tss_create`. - - -.. c:function:: int PyThread_tss_create(Py_tss_t *key) - - Return a zero value on successful initialization of a TSS key. The behavior - is undefined if the value pointed to by the *key* argument is not - initialized by :c:macro:`Py_tss_NEEDS_INIT`. This function can be called - repeatedly on the same key -- calling it on an already initialized key is a - no-op and immediately returns success. - - -.. c:function:: void PyThread_tss_delete(Py_tss_t *key) - - Destroy a TSS key to forget the values associated with the key across all - threads, and change the key's initialization state to uninitialized. A - destroyed key is able to be initialized again by - :c:func:`PyThread_tss_create`. This function can be called repeatedly on - the same key -- calling it on an already destroyed key is a no-op. - - -.. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value) - - Return a zero value to indicate successfully associating a :c:expr:`void*` - value with a TSS key in the current thread. Each thread has a distinct - mapping of the key to a :c:expr:`void*` value. - - -.. c:function:: void* PyThread_tss_get(Py_tss_t *key) - - Return the :c:expr:`void*` value associated with a TSS key in the current - thread. This returns ``NULL`` if no value is associated with the key in the - current thread. - - -.. _thread-local-storage-api: - -Thread Local Storage (TLS) API ------------------------------- - -.. deprecated:: 3.7 - This API is superseded by - :ref:`Thread Specific Storage (TSS) API `. - -.. note:: - This version of the API does not support platforms where the native TLS key - is defined in a way that cannot be safely cast to ``int``. On such platforms, - :c:func:`PyThread_create_key` will return immediately with a failure status, - and the other TLS functions will all be no-ops on such platforms. - -Due to the compatibility problem noted above, this version of the API should not -be used in new code. - -.. c:function:: int PyThread_create_key() -.. c:function:: void PyThread_delete_key(int key) -.. c:function:: int PyThread_set_key_value(int key, void *value) -.. c:function:: void* PyThread_get_key_value(int key) -.. c:function:: void PyThread_delete_key_value(int key) -.. c:function:: void PyThread_ReInitTLS() - -Synchronization Primitives -========================== - -The C-API provides a basic mutual exclusion lock. - -.. c:type:: PyMutex - - A mutual exclusion lock. The :c:type:`!PyMutex` should be initialized to - zero to represent the unlocked state. For example:: - - PyMutex mutex = {0}; - - Instances of :c:type:`!PyMutex` should not be copied or moved. Both the - contents and address of a :c:type:`!PyMutex` are meaningful, and it must - remain at a fixed, writable location in memory. - - .. note:: - - A :c:type:`!PyMutex` currently occupies one byte, but the size should be - considered unstable. The size may change in future Python releases - without a deprecation period. - - .. versionadded:: 3.13 - -.. c:function:: void PyMutex_Lock(PyMutex *m) - - Lock mutex *m*. If another thread has already locked it, the calling - thread will block until the mutex is unlocked. While blocked, the thread - will temporarily detach the :term:`thread state ` if one exists. - - .. versionadded:: 3.13 - -.. c:function:: void PyMutex_Unlock(PyMutex *m) - - Unlock mutex *m*. The mutex must be locked --- otherwise, the function will - issue a fatal error. - - .. versionadded:: 3.13 - -.. c:function:: int PyMutex_IsLocked(PyMutex *m) - - Returns non-zero if the mutex *m* is currently locked, zero otherwise. - - .. note:: - - This function is intended for use in assertions and debugging only and - should not be used to make concurrency control decisions, as the lock - state may change immediately after the check. - - .. versionadded:: 3.14 - -.. _python-critical-section-api: - -Python Critical Section API ---------------------------- - -The critical section API provides a deadlock avoidance layer on top of -per-object locks for :term:`free-threaded ` CPython. They are -intended to replace reliance on the :term:`global interpreter lock`, and are -no-ops in versions of Python with the global interpreter lock. - -Critical sections are intended to be used for custom types implemented -in C-API extensions. They should generally not be used with built-in types like -:class:`list` and :class:`dict` because their public C-APIs -already use critical sections internally, with the notable -exception of :c:func:`PyDict_Next`, which requires critical section -to be acquired externally. - -Critical sections avoid deadlocks by implicitly suspending active critical -sections, hence, they do not provide exclusive access such as provided by -traditional locks like :c:type:`PyMutex`. When a critical section is started, -the per-object lock for the object is acquired. If the code executed inside the -critical section calls C-API functions then it can suspend the critical section thereby -releasing the per-object lock, so other threads can acquire the per-object lock -for the same object. - -Variants that accept :c:type:`PyMutex` pointers rather than Python objects are also -available. Use these variants to start a critical section in a situation where -there is no :c:type:`PyObject` -- for example, when working with a C type that -does not extend or wrap :c:type:`PyObject` but still needs to call into the C -API in a manner that might lead to deadlocks. - -The functions and structs used by the macros are exposed for cases -where C macros are not available. They should only be used as in the -given macro expansions. Note that the sizes and contents of the structures may -change in future Python versions. - -.. note:: - - Operations that need to lock two objects at once must use - :c:macro:`Py_BEGIN_CRITICAL_SECTION2`. You *cannot* use nested critical - sections to lock more than one object at once, because the inner critical - section may suspend the outer critical sections. This API does not provide - a way to lock more than two objects at once. - -Example usage:: - - static PyObject * - set_field(MyObject *self, PyObject *value) - { - Py_BEGIN_CRITICAL_SECTION(self); - Py_SETREF(self->field, Py_XNewRef(value)); - Py_END_CRITICAL_SECTION(); - Py_RETURN_NONE; - } - -In the above example, :c:macro:`Py_SETREF` calls :c:macro:`Py_DECREF`, which -can call arbitrary code through an object's deallocation function. The critical -section API avoids potential deadlocks due to reentrancy and lock ordering -by allowing the runtime to temporarily suspend the critical section if the -code triggered by the finalizer blocks and calls :c:func:`PyEval_SaveThread`. - -.. c:macro:: Py_BEGIN_CRITICAL_SECTION(op) - - Acquires the per-object lock for the object *op* and begins a - critical section. - - In the free-threaded build, this macro expands to:: - - { - PyCriticalSection _py_cs; - PyCriticalSection_Begin(&_py_cs, (PyObject*)(op)) - - In the default build, this macro expands to ``{``. - - .. versionadded:: 3.13 - -.. c:macro:: Py_BEGIN_CRITICAL_SECTION_MUTEX(m) - - Locks the mutex *m* and begins a critical section. - - In the free-threaded build, this macro expands to:: - - { - PyCriticalSection _py_cs; - PyCriticalSection_BeginMutex(&_py_cs, m) - - Note that unlike :c:macro:`Py_BEGIN_CRITICAL_SECTION`, there is no cast for - the argument of the macro - it must be a :c:type:`PyMutex` pointer. - - On the default build, this macro expands to ``{``. - - .. versionadded:: 3.14 - -.. c:macro:: Py_END_CRITICAL_SECTION() - - Ends the critical section and releases the per-object lock. - - In the free-threaded build, this macro expands to:: - - PyCriticalSection_End(&_py_cs); - } - - In the default build, this macro expands to ``}``. - - .. versionadded:: 3.13 - -.. c:macro:: Py_BEGIN_CRITICAL_SECTION2(a, b) - - Acquires the per-objects locks for the objects *a* and *b* and begins a - critical section. The locks are acquired in a consistent order (lowest - address first) to avoid lock ordering deadlocks. - - In the free-threaded build, this macro expands to:: - - { - PyCriticalSection2 _py_cs2; - PyCriticalSection2_Begin(&_py_cs2, (PyObject*)(a), (PyObject*)(b)) - - In the default build, this macro expands to ``{``. - - .. versionadded:: 3.13 - -.. c:macro:: Py_BEGIN_CRITICAL_SECTION2_MUTEX(m1, m2) - - Locks the mutexes *m1* and *m2* and begins a critical section. - - In the free-threaded build, this macro expands to:: - - { - PyCriticalSection2 _py_cs2; - PyCriticalSection2_BeginMutex(&_py_cs2, m1, m2) - - Note that unlike :c:macro:`Py_BEGIN_CRITICAL_SECTION2`, there is no cast for - the arguments of the macro - they must be :c:type:`PyMutex` pointers. - - On the default build, this macro expands to ``{``. - - .. versionadded:: 3.14 - -.. c:macro:: Py_END_CRITICAL_SECTION2() - - Ends the critical section and releases the per-object locks. - - In the free-threaded build, this macro expands to:: - - PyCriticalSection2_End(&_py_cs2); - } - - In the default build, this macro expands to ``}``. - - .. versionadded:: 3.13 - - -Legacy Locking APIs -------------------- - -These APIs are obsolete since Python 3.13 with the introduction of -:c:type:`PyMutex`. - -.. versionchanged:: 3.15 - These APIs are now a simple wrapper around ``PyMutex``. - - -.. c:type:: PyThread_type_lock - - A pointer to a mutual exclusion lock. - - -.. c:type:: PyLockStatus - - The result of acquiring a lock with a timeout. - - .. c:namespace:: NULL - - .. c:enumerator:: PY_LOCK_FAILURE - - Failed to acquire the lock. - - .. c:enumerator:: PY_LOCK_ACQUIRED - - The lock was successfully acquired. - - .. c:enumerator:: PY_LOCK_INTR - - The lock was interrupted by a signal. - - -.. c:function:: PyThread_type_lock PyThread_allocate_lock(void) - - Allocate a new lock. - - On success, this function returns a lock; on failure, this - function returns ``0`` without an exception set. - - The caller does not need to hold an :term:`attached thread state`. - - .. versionchanged:: 3.15 - This function now always uses :c:type:`PyMutex`. In prior versions, this - would use a lock provided by the operating system. - - -.. c:function:: void PyThread_free_lock(PyThread_type_lock lock) - - Destroy *lock*. The lock should not be held by any thread when calling - this. - - The caller does not need to hold an :term:`attached thread state`. - - -.. c:function:: PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock lock, long long microseconds, int intr_flag) - - Acquire *lock* with a timeout. - - This will wait for *microseconds* microseconds to acquire the lock. If the - timeout expires, this function returns :c:enumerator:`PY_LOCK_FAILURE`. - If *microseconds* is ``-1``, this will wait indefinitely until the lock has - been released. - - If *intr_flag* is ``1``, acquiring the lock may be interrupted by a signal, - in which case this function returns :c:enumerator:`PY_LOCK_INTR`. Upon - interruption, it's generally expected that the caller makes a call to - :c:func:`Py_MakePendingCalls` to propagate an exception to Python code. - - If the lock is successfully acquired, this function returns - :c:enumerator:`PY_LOCK_ACQUIRED`. - - The caller does not need to hold an :term:`attached thread state`. - - -.. c:function:: int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) - - Acquire *lock*. - - If *waitflag* is ``1`` and another thread currently holds the lock, this - function will wait until the lock can be acquired and will always return - ``1``. - - If *waitflag* is ``0`` and another thread holds the lock, this function will - not wait and instead return ``0``. If the lock is not held by any other - thread, then this function will acquire it and return ``1``. - - Unlike :c:func:`PyThread_acquire_lock_timed`, acquiring the lock cannot be - interrupted by a signal. - - The caller does not need to hold an :term:`attached thread state`. - - -.. c:function:: int PyThread_release_lock(PyThread_type_lock lock) - - Release *lock*. If *lock* is not held, then this function issues a - fatal error. - - The caller does not need to hold an :term:`attached thread state`. - - -Operating System Thread APIs -============================ - -.. c:macro:: PYTHREAD_INVALID_THREAD_ID - - Sentinel value for an invalid thread ID. - - This is currently equivalent to ``(unsigned long)-1``. - - -.. c:function:: unsigned long PyThread_start_new_thread(void (*func)(void *), void *arg) - - Start function *func* in a new thread with argument *arg*. - The resulting thread is not intended to be joined. - - *func* must not be ``NULL``, but *arg* may be ``NULL``. - - On success, this function returns the identifier of the new thread; on failure, - this returns :c:macro:`PYTHREAD_INVALID_THREAD_ID`. - - The caller does not need to hold an :term:`attached thread state`. - - -.. c:function:: unsigned long PyThread_get_thread_ident(void) - - Return the identifier of the current thread, which will never be zero. - - This function cannot fail, and the caller does not need to hold an - :term:`attached thread state`. - - .. seealso:: - :py:func:`threading.get_ident` - - -.. c:function:: PyObject *PyThread_GetInfo(void) - - Get general information about the current thread in the form of a - :ref:`struct sequence ` object. This information is - accessible as :py:attr:`sys.thread_info` in Python. - - On success, this returns a new :term:`strong reference` to the thread - information; on failure, this returns ``NULL`` with an exception set. - - The caller must hold an :term:`attached thread state`. - - -.. c:macro:: PY_HAVE_THREAD_NATIVE_ID - - This macro is defined when the system supports native thread IDs. - - -.. c:function:: unsigned long PyThread_get_thread_native_id(void) - - Get the native identifier of the current thread as it was assigned by the operating - system's kernel, which will never be less than zero. - - This function is only available when :c:macro:`PY_HAVE_THREAD_NATIVE_ID` is - defined. - - This function cannot fail, and the caller does not need to hold an - :term:`attached thread state`. - - .. seealso:: - :py:func:`threading.get_native_id` - - -.. c:function:: void PyThread_exit_thread(void) - - Terminate the current thread. This function is generally considered unsafe - and should be avoided. It is kept solely for backwards compatibility. - - This function is only safe to call if all functions in the full call - stack are written to safely allow it. - - .. warning:: - - If the current system uses POSIX threads (also known as "pthreads"), - this calls :manpage:`pthread_exit(3)`, which attempts to unwind the stack - and call C++ destructors on some libc implementations. However, if a - ``noexcept`` function is reached, it may terminate the process. - Other systems, such as macOS, do unwinding. - - On Windows, this function calls ``_endthreadex()``, which kills the thread - without calling C++ destructors. - - In any case, there is a risk of corruption on the thread's stack. - - .. deprecated:: 3.14 - - -.. c:function:: void PyThread_init_thread(void) - - Initialize ``PyThread*`` APIs. Python executes this function automatically, - so there's little need to call it from an extension module. - - -.. c:function:: int PyThread_set_stacksize(size_t size) - - Set the stack size of the current thread to *size* bytes. - - This function returns ``0`` on success, ``-1`` if *size* is invalid, or - ``-2`` if the system does not support changing the stack size. This function - does not set exceptions. - - The caller does not need to hold an :term:`attached thread state`. - - -.. c:function:: size_t PyThread_get_stacksize(void) - - Return the stack size of the current thread in bytes, or ``0`` if the system's - default stack size is in use. - - The caller does not need to hold an :term:`attached thread state`. +- :ref:`initialization` +- :ref:`threads` +- :ref:`synchronization` +- :ref:`thread-local-storage` +- :ref:`sub-interpreter-support` +- :ref:`profiling` diff --git a/Doc/c-api/interp-lifecycle.rst b/Doc/c-api/interp-lifecycle.rst new file mode 100644 index 00000000000000..189d8e424f6814 --- /dev/null +++ b/Doc/c-api/interp-lifecycle.rst @@ -0,0 +1,797 @@ +.. highlight:: c + +.. _initialization: + +Interpreter initialization and finalization +=========================================== + +See :ref:`Python Initialization Configuration ` for details +on how to configure the interpreter prior to initialization. + +.. _pre-init-safe: + +Before Python initialization +---------------------------- + +In an application embedding Python, the :c:func:`Py_Initialize` function must +be called before using any other Python/C API functions; with the exception of +a few functions and the :ref:`global configuration variables +`. + +The following functions can be safely called before Python is initialized: + +* Functions that initialize the interpreter: + + * :c:func:`Py_Initialize` + * :c:func:`Py_InitializeEx` + * :c:func:`Py_InitializeFromConfig` + * :c:func:`Py_BytesMain` + * :c:func:`Py_Main` + * the runtime pre-initialization functions covered in :ref:`init-config` + +* Configuration functions: + + * :c:func:`PyImport_AppendInittab` + * :c:func:`PyImport_ExtendInittab` + * :c:func:`!PyInitFrozenExtensions` + * :c:func:`PyMem_SetAllocator` + * :c:func:`PyMem_SetupDebugHooks` + * :c:func:`PyObject_SetArenaAllocator` + * :c:func:`Py_SetProgramName` + * :c:func:`Py_SetPythonHome` + * the configuration functions covered in :ref:`init-config` + +* Informative functions: + + * :c:func:`Py_IsInitialized` + * :c:func:`PyMem_GetAllocator` + * :c:func:`PyObject_GetArenaAllocator` + * :c:func:`Py_GetBuildInfo` + * :c:func:`Py_GetCompiler` + * :c:func:`Py_GetCopyright` + * :c:func:`Py_GetPlatform` + * :c:func:`Py_GetVersion` + * :c:func:`Py_IsInitialized` + +* Utilities: + + * :c:func:`Py_DecodeLocale` + * the status reporting and utility functions covered in :ref:`init-config` + +* Memory allocators: + + * :c:func:`PyMem_RawMalloc` + * :c:func:`PyMem_RawRealloc` + * :c:func:`PyMem_RawCalloc` + * :c:func:`PyMem_RawFree` + +* Synchronization: + + * :c:func:`PyMutex_Lock` + * :c:func:`PyMutex_Unlock` + +.. note:: + + Despite their apparent similarity to some of the functions listed above, + the following functions **should not be called** before the interpreter has + been initialized: :c:func:`Py_EncodeLocale`, :c:func:`PyEval_InitThreads`, and + :c:func:`Py_RunMain`. + + +.. _global-conf-vars: + +Global configuration variables +------------------------------ + +Python has variables for the global configuration to control different features +and options. By default, these flags are controlled by :ref:`command line +options `. + +When a flag is set by an option, the value of the flag is the number of times +that the option was set. For example, ``-b`` sets :c:data:`Py_BytesWarningFlag` +to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. + + +.. c:var:: int Py_BytesWarningFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.bytes_warning` should be used instead, see :ref:`Python + Initialization Configuration `. + + Issue a warning when comparing :class:`bytes` or :class:`bytearray` with + :class:`str` or :class:`bytes` with :class:`int`. Issue an error if greater + or equal to ``2``. + + Set by the :option:`-b` option. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_DebugFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.parser_debug` should be used instead, see :ref:`Python + Initialization Configuration `. + + Turn on parser debugging output (for expert only, depending on compilation + options). + + Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment + variable. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_DontWriteBytecodeFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.write_bytecode` should be used instead, see :ref:`Python + Initialization Configuration `. + + If set to non-zero, Python won't try to write ``.pyc`` files on the + import of source modules. + + Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE` + environment variable. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_FrozenFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.pathconfig_warnings` should be used instead, see + :ref:`Python Initialization Configuration `. + + Private flag used by ``_freeze_module`` and ``frozenmain`` programs. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_HashRandomizationFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.hash_seed` and :c:member:`PyConfig.use_hash_seed` should + be used instead, see :ref:`Python Initialization Configuration + `. + + Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to + a non-empty string. + + If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment + variable to initialize the secret hash seed. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_IgnoreEnvironmentFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.use_environment` should be used instead, see + :ref:`Python Initialization Configuration `. + + Ignore all :envvar:`!PYTHON*` environment variables, e.g. + :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. + + Set by the :option:`-E` and :option:`-I` options. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_InspectFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.inspect` should be used instead, see + :ref:`Python Initialization Configuration `. + + When a script is passed as first argument or the :option:`-c` option is used, + enter interactive mode after executing the script or the command, even when + :data:`sys.stdin` does not appear to be a terminal. + + Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment + variable. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_InteractiveFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.interactive` should be used instead, see + :ref:`Python Initialization Configuration `. + + Set by the :option:`-i` option. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_IsolatedFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.isolated` should be used instead, see + :ref:`Python Initialization Configuration `. + + Run Python in isolated mode. In isolated mode :data:`sys.path` contains + neither the script's directory nor the user's site-packages directory. + + Set by the :option:`-I` option. + + .. versionadded:: 3.4 + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_LegacyWindowsFSEncodingFlag + + This API is kept for backward compatibility: setting + :c:member:`PyPreConfig.legacy_windows_fs_encoding` should be used instead, see + :ref:`Python Initialization Configuration `. + + If the flag is non-zero, use the ``mbcs`` encoding with ``replace`` error + handler, instead of the UTF-8 encoding with ``surrogatepass`` error handler, + for the :term:`filesystem encoding and error handler`. + + Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment + variable is set to a non-empty string. + + See :pep:`529` for more details. + + .. availability:: Windows. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_LegacyWindowsStdioFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.legacy_windows_stdio` should be used instead, see + :ref:`Python Initialization Configuration `. + + If the flag is non-zero, use :class:`io.FileIO` instead of + :class:`!io._WindowsConsoleIO` for :mod:`sys` standard streams. + + Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment + variable is set to a non-empty string. + + See :pep:`528` for more details. + + .. availability:: Windows. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_NoSiteFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.site_import` should be used instead, see + :ref:`Python Initialization Configuration `. + + Disable the import of the module :mod:`site` and the site-dependent + manipulations of :data:`sys.path` that it entails. Also disable these + manipulations if :mod:`site` is explicitly imported later (call + :func:`site.main` if you want them to be triggered). + + Set by the :option:`-S` option. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_NoUserSiteDirectory + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.user_site_directory` should be used instead, see + :ref:`Python Initialization Configuration `. + + Don't add the :data:`user site-packages directory ` to + :data:`sys.path`. + + Set by the :option:`-s` and :option:`-I` options, and the + :envvar:`PYTHONNOUSERSITE` environment variable. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_OptimizeFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.optimization_level` should be used instead, see + :ref:`Python Initialization Configuration `. + + Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment + variable. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_QuietFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.quiet` should be used instead, see :ref:`Python + Initialization Configuration `. + + Don't display the copyright and version messages even in interactive mode. + + Set by the :option:`-q` option. + + .. versionadded:: 3.2 + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_UnbufferedStdioFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.buffered_stdio` should be used instead, see :ref:`Python + Initialization Configuration `. + + Force the stdout and stderr streams to be unbuffered. + + Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED` + environment variable. + + .. deprecated-removed:: 3.12 3.15 + + +.. c:var:: int Py_VerboseFlag + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.verbose` should be used instead, see :ref:`Python + Initialization Configuration `. + + Print a message each time a module is initialized, showing the place + (filename or built-in module) from which it is loaded. If greater or equal + to ``2``, print a message for each file that is checked for when + searching for a module. Also provides information on module cleanup at exit. + + Set by the :option:`-v` option and the :envvar:`PYTHONVERBOSE` environment + variable. + + .. deprecated-removed:: 3.12 3.15 + + +Initializing and finalizing the interpreter +------------------------------------------- + +.. c:function:: void Py_Initialize() + + .. index:: + single: PyEval_InitThreads() + single: modules (in module sys) + single: path (in module sys) + pair: module; builtins + pair: module; __main__ + pair: module; sys + triple: module; search; path + single: Py_FinalizeEx (C function) + + Initialize the Python interpreter. In an application embedding Python, + this should be called before using any other Python/C API functions; see + :ref:`Before Python Initialization ` for the few exceptions. + + This initializes the table of loaded modules (``sys.modules``), and creates + the fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. + It also initializes the module search path (``sys.path``). It does not set + ``sys.argv``; use the :ref:`Python Initialization Configuration ` + API for that. This is a no-op when called for a second time (without calling + :c:func:`Py_FinalizeEx` first). There is no return value; it is a fatal + error if the initialization fails. + + Use :c:func:`Py_InitializeFromConfig` to customize the + :ref:`Python Initialization Configuration `. + + .. note:: + On Windows, changes the console mode from ``O_TEXT`` to ``O_BINARY``, + which will also affect non-Python uses of the console using the C Runtime. + + +.. c:function:: void Py_InitializeEx(int initsigs) + + This function works like :c:func:`Py_Initialize` if *initsigs* is ``1``. If + *initsigs* is ``0``, it skips initialization registration of signal handlers, + which may be useful when CPython is embedded as part of a larger application. + + Use :c:func:`Py_InitializeFromConfig` to customize the + :ref:`Python Initialization Configuration `. + + +.. c:function:: PyStatus Py_InitializeFromConfig(const PyConfig *config) + + Initialize Python from *config* configuration, as described in + :ref:`init-from-config`. + + See the :ref:`init-config` section for details on pre-initializing the + interpreter, populating the runtime configuration structure, and querying + the returned status structure. + + +.. c:function:: int Py_IsInitialized() + + Return true (nonzero) when the Python interpreter has been initialized, false + (zero) if not. After :c:func:`Py_FinalizeEx` is called, this returns false until + :c:func:`Py_Initialize` is called again. + + +.. c:function:: int Py_IsFinalizing() + + Return true (non-zero) if the main Python interpreter is + :term:`shutting down `. Return false (zero) otherwise. + + .. versionadded:: 3.13 + + +.. c:function:: int Py_FinalizeEx() + + Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of + Python/C API functions, and destroy all sub-interpreters (see + :c:func:`Py_NewInterpreter` below) that were created and not yet destroyed since + the last call to :c:func:`Py_Initialize`. This is a no-op when called for a second + time (without calling :c:func:`Py_Initialize` again first). + + Since this is the reverse of :c:func:`Py_Initialize`, it should be called + in the same thread with the same interpreter active. That means + the main thread and the main interpreter. + This should never be called while :c:func:`Py_RunMain` is running. + + Normally the return value is ``0``. + If there were errors during finalization (flushing buffered data), + ``-1`` is returned. + + Note that Python will do a best effort at freeing all memory allocated by the Python + interpreter. Therefore, any C-Extension should make sure to correctly clean up all + of the previously allocated PyObjects before using them in subsequent calls to + :c:func:`Py_Initialize`. Otherwise it could introduce vulnerabilities and incorrect + behavior. + + This function is provided for a number of reasons. An embedding application + might want to restart Python without having to restart the application itself. + An application that has loaded the Python interpreter from a dynamically + loadable library (or DLL) might want to free all memory allocated by Python + before unloading the DLL. During a hunt for memory leaks in an application a + developer might want to free all memory allocated by Python before exiting from + the application. + + **Bugs and caveats:** The destruction of modules and objects in modules is done + in random order; this may cause destructors (:meth:`~object.__del__` methods) to fail + when they depend on other objects (even functions) or modules. Dynamically + loaded extension modules loaded by Python are not unloaded. Small amounts of + memory allocated by the Python interpreter may not be freed (if you find a leak, + please report it). Memory tied up in circular references between objects is not + freed. Interned strings will all be deallocated regardless of their reference count. + Some memory allocated by extension modules may not be freed. Some extensions may not + work properly if their initialization routine is called more than once; this can + happen if an application calls :c:func:`Py_Initialize` and :c:func:`Py_FinalizeEx` + more than once. :c:func:`Py_FinalizeEx` must not be called recursively from + within itself. Therefore, it must not be called by any code that may be run + as part of the interpreter shutdown process, such as :py:mod:`atexit` + handlers, object finalizers, or any code that may be run while flushing the + stdout and stderr files. + + .. audit-event:: cpython._PySys_ClearAuditHooks "" c.Py_FinalizeEx + + .. versionadded:: 3.6 + + +.. c:function:: void Py_Finalize() + + This is a backwards-compatible version of :c:func:`Py_FinalizeEx` that + disregards the return value. + + +.. c:function:: int Py_BytesMain(int argc, char **argv) + + Similar to :c:func:`Py_Main` but *argv* is an array of bytes strings, + allowing the calling application to delegate the text decoding step to + the CPython runtime. + + .. versionadded:: 3.8 + + +.. c:function:: int Py_Main(int argc, wchar_t **argv) + + The main program for the standard interpreter, encapsulating a full + initialization/finalization cycle, as well as additional + behaviour to implement reading configurations settings from the environment + and command line, and then executing ``__main__`` in accordance with + :ref:`using-on-cmdline`. + + This is made available for programs which wish to support the full CPython + command line interface, rather than just embedding a Python runtime in a + larger application. + + The *argc* and *argv* parameters are similar to those which are passed to a + C program's :c:func:`main` function, except that the *argv* entries are first + converted to ``wchar_t`` using :c:func:`Py_DecodeLocale`. It is also + important to note that the argument list entries may be modified to point to + strings other than those passed in (however, the contents of the strings + pointed to by the argument list are not modified). + + The return value is ``2`` if the argument list does not represent a valid + Python command line, and otherwise the same as :c:func:`Py_RunMain`. + + In terms of the CPython runtime configuration APIs documented in the + :ref:`runtime configuration ` section (and without accounting + for error handling), ``Py_Main`` is approximately equivalent to:: + + PyConfig config; + PyConfig_InitPythonConfig(&config); + PyConfig_SetArgv(&config, argc, argv); + Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + + Py_RunMain(); + + In normal usage, an embedding application will call this function + *instead* of calling :c:func:`Py_Initialize`, :c:func:`Py_InitializeEx` or + :c:func:`Py_InitializeFromConfig` directly, and all settings will be applied + as described elsewhere in this documentation. If this function is instead + called *after* a preceding runtime initialization API call, then exactly + which environmental and command line configuration settings will be updated + is version dependent (as it depends on which settings correctly support + being modified after they have already been set once when the runtime was + first initialized). + + +.. c:function:: int Py_RunMain(void) + + Executes the main module in a fully configured CPython runtime. + + Executes the command (:c:member:`PyConfig.run_command`), the script + (:c:member:`PyConfig.run_filename`) or the module + (:c:member:`PyConfig.run_module`) specified on the command line or in the + configuration. If none of these values are set, runs the interactive Python + prompt (REPL) using the ``__main__`` module's global namespace. + + If :c:member:`PyConfig.inspect` is not set (the default), the return value + will be ``0`` if the interpreter exits normally (that is, without raising + an exception), the exit status of an unhandled :exc:`SystemExit`, or ``1`` + for any other unhandled exception. + + If :c:member:`PyConfig.inspect` is set (such as when the :option:`-i` option + is used), rather than returning when the interpreter exits, execution will + instead resume in an interactive Python prompt (REPL) using the ``__main__`` + module's global namespace. If the interpreter exited with an exception, it + is immediately raised in the REPL session. The function return value is + then determined by the way the *REPL session* terminates: ``0``, ``1``, or + the status of a :exc:`SystemExit`, as specified above. + + This function always finalizes the Python interpreter before it returns. + + See :ref:`Python Configuration ` for an example of a + customized Python that always runs in isolated mode using + :c:func:`Py_RunMain`. + +.. c:function:: int PyUnstable_AtExit(PyInterpreterState *interp, void (*func)(void *), void *data) + + Register an :mod:`atexit` callback for the target interpreter *interp*. + This is similar to :c:func:`Py_AtExit`, but takes an explicit interpreter and + data pointer for the callback. + + There must be an :term:`attached thread state` for *interp*. + + .. versionadded:: 3.13 + + +.. _cautions-regarding-runtime-finalization: + +Cautions regarding runtime finalization +--------------------------------------- + +In the late stage of :term:`interpreter shutdown`, after attempting to wait for +non-daemon threads to exit (though this can be interrupted by +:class:`KeyboardInterrupt`) and running the :mod:`atexit` functions, the runtime +is marked as *finalizing*: :c:func:`Py_IsFinalizing` and +:func:`sys.is_finalizing` return true. At this point, only the *finalization +thread* that initiated finalization (typically the main thread) is allowed to +acquire the :term:`GIL`. + +If any thread, other than the finalization thread, attempts to attach a :term:`thread state` +during finalization, either explicitly or +implicitly, the thread enters **a permanently blocked state** +where it remains until the program exits. In most cases this is harmless, but this can result +in deadlock if a later stage of finalization attempts to acquire a lock owned by the +blocked thread, or otherwise waits on the blocked thread. + +Gross? Yes. This prevents random crashes and/or unexpectedly skipped C++ +finalizations further up the call stack when such threads were forcibly exited +here in CPython 3.13 and earlier. The CPython runtime :term:`thread state` C APIs +have never had any error reporting or handling expectations at :term:`thread state` +attachment time that would've allowed for graceful exit from this situation. Changing that +would require new stable C APIs and rewriting the majority of C code in the +CPython ecosystem to use those with error handling. + + +Process-wide parameters +----------------------- + +.. c:function:: void Py_SetProgramName(const wchar_t *name) + + .. index:: + single: Py_Initialize() + single: main() + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.program_name` should be used instead, see :ref:`Python + Initialization Configuration `. + + This function should be called before :c:func:`Py_Initialize` is called for + the first time, if it is called at all. It tells the interpreter the value + of the ``argv[0]`` argument to the :c:func:`main` function of the program + (converted to wide characters). + This is used by some other functions below to find + the Python run-time libraries relative to the interpreter executable. The + default value is ``'python'``. The argument should point to a + zero-terminated wide character string in static storage whose contents will not + change for the duration of the program's execution. No code in the Python + interpreter will change the contents of this storage. + + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:expr:`wchar_t*` string. + + .. deprecated-removed:: 3.11 3.15 + + +.. c:function:: const char* Py_GetVersion() + + Return the version of this Python interpreter. This is a string that looks + something like :: + + "3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]" + + .. index:: single: version (in module sys) + + The first word (up to the first space character) is the current Python version; + the first characters are the major and minor version separated by a + period. The returned string points into static storage; the caller should not + modify its value. The value is available to Python code as :data:`sys.version`. + + See also the :c:var:`Py_Version` constant. + + +.. c:function:: const char* Py_GetPlatform() + + .. index:: single: platform (in module sys) + + Return the platform identifier for the current platform. On Unix, this is + formed from the "official" name of the operating system, converted to lower + case, followed by the major revision number; e.g., for Solaris 2.x, which is + also known as SunOS 5.x, the value is ``'sunos5'``. On macOS, it is + ``'darwin'``. On Windows, it is ``'win'``. The returned string points into + static storage; the caller should not modify its value. The value is available + to Python code as ``sys.platform``. + + +.. c:function:: const char* Py_GetCopyright() + + Return the official copyright string for the current Python version, for example + + ``'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'`` + + .. index:: single: copyright (in module sys) + + The returned string points into static storage; the caller should not modify its + value. The value is available to Python code as ``sys.copyright``. + + +.. c:function:: const char* Py_GetCompiler() + + Return an indication of the compiler used to build the current Python version, + in square brackets, for example:: + + "[GCC 2.7.2.2]" + + .. index:: single: version (in module sys) + + The returned string points into static storage; the caller should not modify its + value. The value is available to Python code as part of the variable + ``sys.version``. + + +.. c:function:: const char* Py_GetBuildInfo() + + Return information about the sequence number and build date and time of the + current Python interpreter instance, for example :: + + "#67, Aug 1 1997, 22:34:28" + + .. index:: single: version (in module sys) + + The returned string points into static storage; the caller should not modify its + value. The value is available to Python code as part of the variable + ``sys.version``. + + +.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) + + .. index:: + single: main() + single: Py_FatalError() + single: argv (in module sys) + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.argv`, :c:member:`PyConfig.parse_argv` and + :c:member:`PyConfig.safe_path` should be used instead, see :ref:`Python + Initialization Configuration `. + + Set :data:`sys.argv` based on *argc* and *argv*. These parameters are + similar to those passed to the program's :c:func:`main` function with the + difference that the first entry should refer to the script file to be + executed rather than the executable hosting the Python interpreter. If there + isn't a script that will be run, the first entry in *argv* can be an empty + string. If this function fails to initialize :data:`sys.argv`, a fatal + condition is signalled using :c:func:`Py_FatalError`. + + If *updatepath* is zero, this is all the function does. If *updatepath* + is non-zero, the function also modifies :data:`sys.path` according to the + following algorithm: + + - If the name of an existing script is passed in ``argv[0]``, the absolute + path of the directory where the script is located is prepended to + :data:`sys.path`. + - Otherwise (that is, if *argc* is ``0`` or ``argv[0]`` doesn't point + to an existing file name), an empty string is prepended to + :data:`sys.path`, which is the same as prepending the current working + directory (``"."``). + + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:expr:`wchar_t*` string. + + See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv` + members of the :ref:`Python Initialization Configuration `. + + .. note:: + It is recommended that applications embedding the Python interpreter + for purposes other than executing a single script pass ``0`` as *updatepath*, + and update :data:`sys.path` themselves if desired. + See :cve:`2008-5983`. + + On versions before 3.1.3, you can achieve the same effect by manually + popping the first :data:`sys.path` element after having called + :c:func:`PySys_SetArgv`, for example using:: + + PyRun_SimpleString("import sys; sys.path.pop(0)\n"); + + .. versionadded:: 3.1.3 + + .. deprecated-removed:: 3.11 3.15 + + +.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv) + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` should be used + instead, see :ref:`Python Initialization Configuration `. + + This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set + to ``1`` unless the :program:`python` interpreter was started with the + :option:`-I`. + + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:expr:`wchar_t*` string. + + See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv` + members of the :ref:`Python Initialization Configuration `. + + .. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`. + + .. deprecated-removed:: 3.11 3.15 + + +.. c:function:: void Py_SetPythonHome(const wchar_t *home) + + This API is kept for backward compatibility: setting + :c:member:`PyConfig.home` should be used instead, see :ref:`Python + Initialization Configuration `. + + Set the default "home" directory, that is, the location of the standard + Python libraries. See :envvar:`PYTHONHOME` for the meaning of the + argument string. + + The argument should point to a zero-terminated character string in static + storage whose contents will not change for the duration of the program's + execution. No code in the Python interpreter will change the contents of + this storage. + + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:expr:`wchar_t*` string. + + .. deprecated-removed:: 3.11 3.15 diff --git a/Doc/c-api/profiling.rst b/Doc/c-api/profiling.rst new file mode 100644 index 00000000000000..0200f2eac6d908 --- /dev/null +++ b/Doc/c-api/profiling.rst @@ -0,0 +1,239 @@ +.. highlight:: c + +.. _profiling: + +Profiling and tracing +===================== + +The Python interpreter provides some low-level support for attaching profiling +and execution tracing facilities. These are used for profiling, debugging, and +coverage analysis tools. + +This C interface allows the profiling or tracing code to avoid the overhead of +calling through Python-level callable objects, making a direct C function call +instead. The essential attributes of the facility have not changed; the +interface allows trace functions to be installed per-thread, and the basic +events reported to the trace function are the same as had been reported to the +Python-level trace functions in previous versions. + + +.. c:type:: int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) + + The type of the trace function registered using :c:func:`PyEval_SetProfile` and + :c:func:`PyEval_SetTrace`. The first parameter is the object passed to the + registration function as *obj*, *frame* is the frame object to which the event + pertains, *what* is one of the constants :c:data:`PyTrace_CALL`, + :c:data:`PyTrace_EXCEPTION`, :c:data:`PyTrace_LINE`, :c:data:`PyTrace_RETURN`, + :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION`, :c:data:`PyTrace_C_RETURN`, + or :c:data:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: + + +-------------------------------+----------------------------------------+ + | Value of *what* | Meaning of *arg* | + +===============================+========================================+ + | :c:data:`PyTrace_CALL` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_EXCEPTION` | Exception information as returned by | + | | :func:`sys.exc_info`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_LINE` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_RETURN` | Value being returned to the caller, | + | | or ``NULL`` if caused by an exception. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_CALL` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_EXCEPTION` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_RETURN` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + +.. c:var:: int PyTrace_CALL + + The value of the *what* parameter to a :c:type:`Py_tracefunc` function when a new + call to a function or method is being reported, or a new entry into a generator. + Note that the creation of the iterator for a generator function is not reported + as there is no control transfer to the Python bytecode in the corresponding + frame. + + +.. c:var:: int PyTrace_EXCEPTION + + The value of the *what* parameter to a :c:type:`Py_tracefunc` function when an + exception has been raised. The callback function is called with this value for + *what* when after any bytecode is processed after which the exception becomes + set within the frame being executed. The effect of this is that as exception + propagation causes the Python stack to unwind, the callback is called upon + return to each frame as the exception propagates. Only trace functions receive + these events; they are not needed by the profiler. + + +.. c:var:: int PyTrace_LINE + + The value passed as the *what* parameter to a :c:type:`Py_tracefunc` function + (but not a profiling function) when a line-number event is being reported. + It may be disabled for a frame by setting :attr:`~frame.f_trace_lines` to + *0* on that frame. + + +.. c:var:: int PyTrace_RETURN + + The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a + call is about to return. + + +.. c:var:: int PyTrace_C_CALL + + The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C + function is about to be called. + + +.. c:var:: int PyTrace_C_EXCEPTION + + The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C + function has raised an exception. + + +.. c:var:: int PyTrace_C_RETURN + + The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a C + function has returned. + + +.. c:var:: int PyTrace_OPCODE + + The value for the *what* parameter to :c:type:`Py_tracefunc` functions (but not + profiling functions) when a new opcode is about to be executed. This event is + not emitted by default: it must be explicitly requested by setting + :attr:`~frame.f_trace_opcodes` to *1* on the frame. + + +.. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj) + + Set the profiler function to *func*. The *obj* parameter is passed to the + function as its first parameter, and may be any Python object, or ``NULL``. If + the profile function needs to maintain state, using a different value for *obj* + for each thread provides a convenient and thread-safe place to store it. The + profile function is called for all monitored events except :c:data:`PyTrace_LINE` + :c:data:`PyTrace_OPCODE` and :c:data:`PyTrace_EXCEPTION`. + + See also the :func:`sys.setprofile` function. + + The caller must have an :term:`attached thread state`. + + +.. c:function:: void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj) + + Like :c:func:`PyEval_SetProfile` but sets the profile function in all running threads + belonging to the current interpreter instead of the setting it only on the current thread. + + The caller must have an :term:`attached thread state`. + + As :c:func:`PyEval_SetProfile`, this function ignores any exceptions raised while + setting the profile functions in all threads. + +.. versionadded:: 3.12 + + +.. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj) + + Set the tracing function to *func*. This is similar to + :c:func:`PyEval_SetProfile`, except the tracing function does receive line-number + events and per-opcode events, but does not receive any event related to C function + objects being called. Any trace function registered using :c:func:`PyEval_SetTrace` + will not receive :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION` or + :c:data:`PyTrace_C_RETURN` as a value for the *what* parameter. + + See also the :func:`sys.settrace` function. + + The caller must have an :term:`attached thread state`. + + +.. c:function:: void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj) + + Like :c:func:`PyEval_SetTrace` but sets the tracing function in all running threads + belonging to the current interpreter instead of the setting it only on the current thread. + + The caller must have an :term:`attached thread state`. + + As :c:func:`PyEval_SetTrace`, this function ignores any exceptions raised while + setting the trace functions in all threads. + +.. versionadded:: 3.12 + + +Reference tracing +================= + +.. versionadded:: 3.13 + + +.. c:type:: int (*PyRefTracer)(PyObject *, int event, void* data) + + The type of the trace function registered using :c:func:`PyRefTracer_SetTracer`. + The first parameter is a Python object that has been just created (when **event** + is set to :c:data:`PyRefTracer_CREATE`) or about to be destroyed (when **event** + is set to :c:data:`PyRefTracer_DESTROY`). The **data** argument is the opaque pointer + that was provided when :c:func:`PyRefTracer_SetTracer` was called. + + If a new tracing function is registered replacing the current one, a call to the + trace function will be made with the object set to **NULL** and **event** set to + :c:data:`PyRefTracer_TRACKER_REMOVED`. This will happen just before the new + function is registered. + +.. versionadded:: 3.13 + + +.. c:var:: int PyRefTracer_CREATE + + The value for the *event* parameter to :c:type:`PyRefTracer` functions when a Python + object has been created. + + +.. c:var:: int PyRefTracer_DESTROY + + The value for the *event* parameter to :c:type:`PyRefTracer` functions when a Python + object has been destroyed. + + +.. c:var:: int PyRefTracer_TRACKER_REMOVED + + The value for the *event* parameter to :c:type:`PyRefTracer` functions when the + current tracer is about to be replaced by a new one. + + .. versionadded:: 3.14 + + +.. c:function:: int PyRefTracer_SetTracer(PyRefTracer tracer, void *data) + + Register a reference tracer function. The function will be called when a new + Python object has been created or when an object is going to be destroyed. If + **data** is provided it must be an opaque pointer that will be provided when + the tracer function is called. Return ``0`` on success. Set an exception and + return ``-1`` on error. + + Note that tracer functions **must not** create Python objects inside or + otherwise the call will be re-entrant. The tracer also **must not** clear + any existing exception or set an exception. A :term:`thread state` will be active + every time the tracer function is called. + + There must be an :term:`attached thread state` when calling this function. + + If another tracer function was already registered, the old function will be + called with **event** set to :c:data:`PyRefTracer_TRACKER_REMOVED` just before + the new function is registered. + +.. versionadded:: 3.13 + + +.. c:function:: PyRefTracer PyRefTracer_GetTracer(void** data) + + Get the registered reference tracer function and the value of the opaque data + pointer that was registered when :c:func:`PyRefTracer_SetTracer` was called. + If no tracer was registered this function will return NULL and will set the + **data** pointer to NULL. + + There must be an :term:`attached thread state` when calling this function. + +.. versionadded:: 3.13 diff --git a/Doc/c-api/subinterpreters.rst b/Doc/c-api/subinterpreters.rst new file mode 100644 index 00000000000000..44e3fc96841aac --- /dev/null +++ b/Doc/c-api/subinterpreters.rst @@ -0,0 +1,470 @@ +.. highlight:: c + +.. _sub-interpreter-support: + +Multiple interpreters in a Python process +========================================= + +While in most uses, you will only embed a single Python interpreter, there +are cases where you need to create several independent interpreters in the +same process and perhaps even in the same thread. Sub-interpreters allow +you to do that. + +The "main" interpreter is the first one created when the runtime initializes. +It is usually the only Python interpreter in a process. Unlike sub-interpreters, +the main interpreter has unique process-global responsibilities like signal +handling. It is also responsible for execution during runtime initialization and +is usually the active interpreter during runtime finalization. The +:c:func:`PyInterpreterState_Main` function returns a pointer to its state. + +You can switch between sub-interpreters using the :c:func:`PyThreadState_Swap` +function. You can create and destroy them using the following functions: + + +.. c:type:: PyInterpreterConfig + + Structure containing most parameters to configure a sub-interpreter. + Its values are used only in :c:func:`Py_NewInterpreterFromConfig` and + never modified by the runtime. + + .. versionadded:: 3.12 + + Structure fields: + + .. c:member:: int use_main_obmalloc + + If this is ``0`` then the sub-interpreter will use its own + "object" allocator state. + Otherwise it will use (share) the main interpreter's. + + If this is ``0`` then + :c:member:`~PyInterpreterConfig.check_multi_interp_extensions` + must be ``1`` (non-zero). + If this is ``1`` then :c:member:`~PyInterpreterConfig.gil` + must not be :c:macro:`PyInterpreterConfig_OWN_GIL`. + + .. c:member:: int allow_fork + + If this is ``0`` then the runtime will not support forking the + process in any thread where the sub-interpreter is currently active. + Otherwise fork is unrestricted. + + Note that the :mod:`subprocess` module still works + when fork is disallowed. + + .. c:member:: int allow_exec + + If this is ``0`` then the runtime will not support replacing the + current process via exec (e.g. :func:`os.execv`) in any thread + where the sub-interpreter is currently active. + Otherwise exec is unrestricted. + + Note that the :mod:`subprocess` module still works + when exec is disallowed. + + .. c:member:: int allow_threads + + If this is ``0`` then the sub-interpreter's :mod:`threading` module + won't create threads. + Otherwise threads are allowed. + + .. c:member:: int allow_daemon_threads + + If this is ``0`` then the sub-interpreter's :mod:`threading` module + won't create daemon threads. + Otherwise daemon threads are allowed (as long as + :c:member:`~PyInterpreterConfig.allow_threads` is non-zero). + + .. c:member:: int check_multi_interp_extensions + + If this is ``0`` then all extension modules may be imported, + including legacy (single-phase init) modules, + in any thread where the sub-interpreter is currently active. + Otherwise only multi-phase init extension modules + (see :pep:`489`) may be imported. + (Also see :c:macro:`Py_mod_multiple_interpreters`.) + + This must be ``1`` (non-zero) if + :c:member:`~PyInterpreterConfig.use_main_obmalloc` is ``0``. + + .. c:member:: int gil + + This determines the operation of the GIL for the sub-interpreter. + It may be one of the following: + + .. c:namespace:: NULL + + .. c:macro:: PyInterpreterConfig_DEFAULT_GIL + + Use the default selection (:c:macro:`PyInterpreterConfig_SHARED_GIL`). + + .. c:macro:: PyInterpreterConfig_SHARED_GIL + + Use (share) the main interpreter's GIL. + + .. c:macro:: PyInterpreterConfig_OWN_GIL + + Use the sub-interpreter's own GIL. + + If this is :c:macro:`PyInterpreterConfig_OWN_GIL` then + :c:member:`PyInterpreterConfig.use_main_obmalloc` must be ``0``. + + +.. c:function:: PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config) + + .. index:: + pair: module; builtins + pair: module; __main__ + pair: module; sys + single: stdout (in module sys) + single: stderr (in module sys) + single: stdin (in module sys) + + Create a new sub-interpreter. This is an (almost) totally separate environment + for the execution of Python code. In particular, the new interpreter has + separate, independent versions of all imported modules, including the + fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. The + table of loaded modules (``sys.modules``) and the module search path + (``sys.path``) are also separate. The new environment has no ``sys.argv`` + variable. It has new standard I/O stream file objects ``sys.stdin``, + ``sys.stdout`` and ``sys.stderr`` (however these refer to the same underlying + file descriptors). + + The given *config* controls the options with which the interpreter + is initialized. + + Upon success, *tstate_p* will be set to the first :term:`thread state` + created in the new sub-interpreter. This thread state is + :term:`attached `. + Note that no actual thread is created; see the discussion of thread states + below. If creation of the new interpreter is unsuccessful, + *tstate_p* is set to ``NULL``; + no exception is set since the exception state is stored in the + :term:`attached thread state`, which might not exist. + + Like all other Python/C API functions, an :term:`attached thread state` + must be present before calling this function, but it might be detached upon + returning. On success, the returned thread state will be :term:`attached `. + If the sub-interpreter is created with its own :term:`GIL` then the + :term:`attached thread state` of the calling interpreter will be detached. + When the function returns, the new interpreter's :term:`thread state` + will be :term:`attached ` to the current thread and + the previous interpreter's :term:`attached thread state` will remain detached. + + .. versionadded:: 3.12 + + Sub-interpreters are most effective when isolated from each other, + with certain functionality restricted:: + + PyInterpreterConfig config = { + .use_main_obmalloc = 0, + .allow_fork = 0, + .allow_exec = 0, + .allow_threads = 1, + .allow_daemon_threads = 0, + .check_multi_interp_extensions = 1, + .gil = PyInterpreterConfig_OWN_GIL, + }; + PyThreadState *tstate = NULL; + PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + Note that the config is used only briefly and does not get modified. + During initialization the config's values are converted into various + :c:type:`PyInterpreterState` values. A read-only copy of the config + may be stored internally on the :c:type:`PyInterpreterState`. + + .. index:: + single: Py_FinalizeEx (C function) + single: Py_Initialize (C function) + + Extension modules are shared between (sub-)interpreters as follows: + + * For modules using multi-phase initialization, + e.g. :c:func:`PyModule_FromDefAndSpec`, a separate module object is + created and initialized for each interpreter. + Only C-level static and global variables are shared between these + module objects. + + * For modules using legacy + :ref:`single-phase initialization `, + e.g. :c:func:`PyModule_Create`, the first time a particular extension + is imported, it is initialized normally, and a (shallow) copy of its + module's dictionary is squirreled away. + When the same extension is imported by another (sub-)interpreter, a new + module is initialized and filled with the contents of this copy; the + extension's ``init`` function is not called. + Objects in the module's dictionary thus end up shared across + (sub-)interpreters, which might cause unwanted behavior (see + `Bugs and caveats`_ below). + + Note that this is different from what happens when an extension is + imported after the interpreter has been completely re-initialized by + calling :c:func:`Py_FinalizeEx` and :c:func:`Py_Initialize`; in that + case, the extension's ``initmodule`` function *is* called again. + As with multi-phase initialization, this means that only C-level static + and global variables are shared between these modules. + + .. index:: single: close (in module os) + + +.. c:function:: PyThreadState* Py_NewInterpreter(void) + + .. index:: + pair: module; builtins + pair: module; __main__ + pair: module; sys + single: stdout (in module sys) + single: stderr (in module sys) + single: stdin (in module sys) + + Create a new sub-interpreter. This is essentially just a wrapper + around :c:func:`Py_NewInterpreterFromConfig` with a config that + preserves the existing behavior. The result is an unisolated + sub-interpreter that shares the main interpreter's GIL, allows + fork/exec, allows daemon threads, and allows single-phase init + modules. + + +.. c:function:: void Py_EndInterpreter(PyThreadState *tstate) + + .. index:: single: Py_FinalizeEx (C function) + + Destroy the (sub-)interpreter represented by the given :term:`thread state`. + The given thread state must be :term:`attached `. + When the call returns, there will be no :term:`attached thread state`. + All thread states associated with this interpreter are destroyed. + + :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that + haven't been explicitly destroyed at that point. + + +.. _per-interpreter-gil: + +A per-interpreter GIL +--------------------- + +.. versionadded:: 3.12 + +Using :c:func:`Py_NewInterpreterFromConfig` you can create +a sub-interpreter that is completely isolated from other interpreters, +including having its own GIL. The most important benefit of this +isolation is that such an interpreter can execute Python code without +being blocked by other interpreters or blocking any others. Thus a +single Python process can truly take advantage of multiple CPU cores +when running Python code. The isolation also encourages a different +approach to concurrency than that of just using threads. +(See :pep:`554` and :pep:`684`.) + +Using an isolated interpreter requires vigilance in preserving that +isolation. That especially means not sharing any objects or mutable +state without guarantees about thread-safety. Even objects that are +otherwise immutable (e.g. ``None``, ``(1, 5)``) can't normally be shared +because of the refcount. One simple but less-efficient approach around +this is to use a global lock around all use of some state (or object). +Alternately, effectively immutable objects (like integers or strings) +can be made safe in spite of their refcounts by making them :term:`immortal`. +In fact, this has been done for the builtin singletons, small integers, +and a number of other builtin objects. + +If you preserve isolation then you will have access to proper multi-core +computing without the complications that come with free-threading. +Failure to preserve isolation will expose you to the full consequences +of free-threading, including races and hard-to-debug crashes. + +Aside from that, one of the main challenges of using multiple isolated +interpreters is how to communicate between them safely (not break +isolation) and efficiently. The runtime and stdlib do not provide +any standard approach to this yet. A future stdlib module would help +mitigate the effort of preserving isolation and expose effective tools +for communicating (and sharing) data between interpreters. + + +Bugs and caveats +---------------- + +Because sub-interpreters (and the main interpreter) are part of the same +process, the insulation between them isn't perfect --- for example, using +low-level file operations like :func:`os.close` they can +(accidentally or maliciously) affect each other's open files. Because of the +way extensions are shared between (sub-)interpreters, some extensions may not +work properly; this is especially likely when using single-phase initialization +or (static) global variables. +It is possible to insert objects created in one sub-interpreter into +a namespace of another (sub-)interpreter; this should be avoided if possible. + +Special care should be taken to avoid sharing user-defined functions, +methods, instances or classes between sub-interpreters, since import +operations executed by such objects may affect the wrong (sub-)interpreter's +dictionary of loaded modules. It is equally important to avoid sharing +objects from which the above are reachable. + +Also note that combining this functionality with ``PyGILState_*`` APIs +is delicate, because these APIs assume a bijection between Python thread states +and OS-level threads, an assumption broken by the presence of sub-interpreters. +It is highly recommended that you don't switch sub-interpreters between a pair +of matching :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` calls. +Furthermore, extensions (such as :mod:`ctypes`) using these APIs to allow calling +of Python code from non-Python created threads will probably be broken when using +sub-interpreters. + + +High-level APIs +--------------- + +.. c:type:: PyInterpreterState + + This data structure represents the state shared by a number of cooperating + threads. Threads belonging to the same interpreter share their module + administration and a few other internal items. There are no public members in + this structure. + + Threads belonging to different interpreters initially share nothing, except + process state like available memory, open file descriptors and such. The global + interpreter lock is also shared by all threads, regardless of to which + interpreter they belong. + + .. versionchanged:: 3.12 + + :pep:`684` introduced the possibility + of a :ref:`per-interpreter GIL `. + See :c:func:`Py_NewInterpreterFromConfig`. + + +.. c:function:: PyInterpreterState* PyInterpreterState_Get(void) + + Get the current interpreter. + + Issue a fatal error if there is no :term:`attached thread state`. + It cannot return NULL. + + .. versionadded:: 3.9 + + +.. c:function:: int64_t PyInterpreterState_GetID(PyInterpreterState *interp) + + Return the interpreter's unique ID. If there was any error in doing + so then ``-1`` is returned and an error is set. + + The caller must have an :term:`attached thread state`. + + .. versionadded:: 3.7 + + +.. c:function:: PyObject* PyInterpreterState_GetDict(PyInterpreterState *interp) + + Return a dictionary in which interpreter-specific data may be stored. + If this function returns ``NULL`` then no exception has been raised and + the caller should assume no interpreter-specific dict is available. + + This is not a replacement for :c:func:`PyModule_GetState()`, which + extensions should use to store interpreter-specific state information. + + The returned dictionary is borrowed from the interpreter and is valid until + interpreter shutdown. + + .. versionadded:: 3.8 + + +.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) + + Type of a frame evaluation function. + + The *throwflag* parameter is used by the ``throw()`` method of generators: + if non-zero, handle the current exception. + + .. versionchanged:: 3.9 + The function now takes a *tstate* parameter. + + .. versionchanged:: 3.11 + The *frame* parameter changed from ``PyFrameObject*`` to ``_PyInterpreterFrame*``. + + +.. c:function:: _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp) + + Get the frame evaluation function. + + See the :pep:`523` "Adding a frame evaluation API to CPython". + + .. versionadded:: 3.9 + + +.. c:function:: void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame) + + Set the frame evaluation function. + + See the :pep:`523` "Adding a frame evaluation API to CPython". + + .. versionadded:: 3.9 + + +Low-level APIs +-------------- + +All of the following functions must be called after :c:func:`Py_Initialize`. + +.. versionchanged:: 3.7 + :c:func:`Py_Initialize()` now initializes the :term:`GIL` + and sets an :term:`attached thread state`. + + +.. c:function:: PyInterpreterState* PyInterpreterState_New() + + Create a new interpreter state object. An :term:`attached thread state` is not needed, + but may optionally exist if it is necessary to serialize calls to this + function. + + .. audit-event:: cpython.PyInterpreterState_New "" c.PyInterpreterState_New + + +.. c:function:: void PyInterpreterState_Clear(PyInterpreterState *interp) + + Reset all information in an interpreter state object. There must be + an :term:`attached thread state` for the interpreter. + + .. audit-event:: cpython.PyInterpreterState_Clear "" c.PyInterpreterState_Clear + + +.. c:function:: void PyInterpreterState_Delete(PyInterpreterState *interp) + + Destroy an interpreter state object. There **should not** be an + :term:`attached thread state` for the target interpreter. The interpreter + state must have been reset with a previous call to :c:func:`PyInterpreterState_Clear`. + + +.. _advanced-debugging: + +Advanced debugger support +------------------------- + +These functions are only intended to be used by advanced debugging tools. + + +.. c:function:: PyInterpreterState* PyInterpreterState_Head() + + Return the interpreter state object at the head of the list of all such objects. + + +.. c:function:: PyInterpreterState* PyInterpreterState_Main() + + Return the main interpreter state object. + + +.. c:function:: PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp) + + Return the next interpreter state object after *interp* from the list of all + such objects. + + +.. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp) + + Return the pointer to the first :c:type:`PyThreadState` object in the list of + threads associated with the interpreter *interp*. + + +.. c:function:: PyThreadState* PyThreadState_Next(PyThreadState *tstate) + + Return the next thread state object after *tstate* from the list of all such + objects belonging to the same :c:type:`PyInterpreterState` object. diff --git a/Doc/c-api/synchronization.rst b/Doc/c-api/synchronization.rst new file mode 100644 index 00000000000000..53c9faeae35464 --- /dev/null +++ b/Doc/c-api/synchronization.rst @@ -0,0 +1,308 @@ +.. highlight:: c + +.. _synchronization: + +Synchronization primitives +========================== + +The C-API provides a basic mutual exclusion lock. + +.. c:type:: PyMutex + + A mutual exclusion lock. The :c:type:`!PyMutex` should be initialized to + zero to represent the unlocked state. For example:: + + PyMutex mutex = {0}; + + Instances of :c:type:`!PyMutex` should not be copied or moved. Both the + contents and address of a :c:type:`!PyMutex` are meaningful, and it must + remain at a fixed, writable location in memory. + + .. note:: + + A :c:type:`!PyMutex` currently occupies one byte, but the size should be + considered unstable. The size may change in future Python releases + without a deprecation period. + + .. versionadded:: 3.13 + +.. c:function:: void PyMutex_Lock(PyMutex *m) + + Lock mutex *m*. If another thread has already locked it, the calling + thread will block until the mutex is unlocked. While blocked, the thread + will temporarily detach the :term:`thread state ` if one exists. + + .. versionadded:: 3.13 + +.. c:function:: void PyMutex_Unlock(PyMutex *m) + + Unlock mutex *m*. The mutex must be locked --- otherwise, the function will + issue a fatal error. + + .. versionadded:: 3.13 + +.. c:function:: int PyMutex_IsLocked(PyMutex *m) + + Returns non-zero if the mutex *m* is currently locked, zero otherwise. + + .. note:: + + This function is intended for use in assertions and debugging only and + should not be used to make concurrency control decisions, as the lock + state may change immediately after the check. + + .. versionadded:: 3.14 + +.. _python-critical-section-api: + +Python critical section API +--------------------------- + +The critical section API provides a deadlock avoidance layer on top of +per-object locks for :term:`free-threaded ` CPython. They are +intended to replace reliance on the :term:`global interpreter lock`, and are +no-ops in versions of Python with the global interpreter lock. + +Critical sections are intended to be used for custom types implemented +in C-API extensions. They should generally not be used with built-in types like +:class:`list` and :class:`dict` because their public C-APIs +already use critical sections internally, with the notable +exception of :c:func:`PyDict_Next`, which requires critical section +to be acquired externally. + +Critical sections avoid deadlocks by implicitly suspending active critical +sections, hence, they do not provide exclusive access such as provided by +traditional locks like :c:type:`PyMutex`. When a critical section is started, +the per-object lock for the object is acquired. If the code executed inside the +critical section calls C-API functions then it can suspend the critical section thereby +releasing the per-object lock, so other threads can acquire the per-object lock +for the same object. + +Variants that accept :c:type:`PyMutex` pointers rather than Python objects are also +available. Use these variants to start a critical section in a situation where +there is no :c:type:`PyObject` -- for example, when working with a C type that +does not extend or wrap :c:type:`PyObject` but still needs to call into the C +API in a manner that might lead to deadlocks. + +The functions and structs used by the macros are exposed for cases +where C macros are not available. They should only be used as in the +given macro expansions. Note that the sizes and contents of the structures may +change in future Python versions. + +.. note:: + + Operations that need to lock two objects at once must use + :c:macro:`Py_BEGIN_CRITICAL_SECTION2`. You *cannot* use nested critical + sections to lock more than one object at once, because the inner critical + section may suspend the outer critical sections. This API does not provide + a way to lock more than two objects at once. + +Example usage:: + + static PyObject * + set_field(MyObject *self, PyObject *value) + { + Py_BEGIN_CRITICAL_SECTION(self); + Py_SETREF(self->field, Py_XNewRef(value)); + Py_END_CRITICAL_SECTION(); + Py_RETURN_NONE; + } + +In the above example, :c:macro:`Py_SETREF` calls :c:macro:`Py_DECREF`, which +can call arbitrary code through an object's deallocation function. The critical +section API avoids potential deadlocks due to reentrancy and lock ordering +by allowing the runtime to temporarily suspend the critical section if the +code triggered by the finalizer blocks and calls :c:func:`PyEval_SaveThread`. + +.. c:macro:: Py_BEGIN_CRITICAL_SECTION(op) + + Acquires the per-object lock for the object *op* and begins a + critical section. + + In the free-threaded build, this macro expands to:: + + { + PyCriticalSection _py_cs; + PyCriticalSection_Begin(&_py_cs, (PyObject*)(op)) + + In the default build, this macro expands to ``{``. + + .. versionadded:: 3.13 + +.. c:macro:: Py_BEGIN_CRITICAL_SECTION_MUTEX(m) + + Locks the mutex *m* and begins a critical section. + + In the free-threaded build, this macro expands to:: + + { + PyCriticalSection _py_cs; + PyCriticalSection_BeginMutex(&_py_cs, m) + + Note that unlike :c:macro:`Py_BEGIN_CRITICAL_SECTION`, there is no cast for + the argument of the macro - it must be a :c:type:`PyMutex` pointer. + + On the default build, this macro expands to ``{``. + + .. versionadded:: 3.14 + +.. c:macro:: Py_END_CRITICAL_SECTION() + + Ends the critical section and releases the per-object lock. + + In the free-threaded build, this macro expands to:: + + PyCriticalSection_End(&_py_cs); + } + + In the default build, this macro expands to ``}``. + + .. versionadded:: 3.13 + +.. c:macro:: Py_BEGIN_CRITICAL_SECTION2(a, b) + + Acquires the per-object locks for the objects *a* and *b* and begins a + critical section. The locks are acquired in a consistent order (lowest + address first) to avoid lock ordering deadlocks. + + In the free-threaded build, this macro expands to:: + + { + PyCriticalSection2 _py_cs2; + PyCriticalSection2_Begin(&_py_cs2, (PyObject*)(a), (PyObject*)(b)) + + In the default build, this macro expands to ``{``. + + .. versionadded:: 3.13 + +.. c:macro:: Py_BEGIN_CRITICAL_SECTION2_MUTEX(m1, m2) + + Locks the mutexes *m1* and *m2* and begins a critical section. + + In the free-threaded build, this macro expands to:: + + { + PyCriticalSection2 _py_cs2; + PyCriticalSection2_BeginMutex(&_py_cs2, m1, m2) + + Note that unlike :c:macro:`Py_BEGIN_CRITICAL_SECTION2`, there is no cast for + the arguments of the macro - they must be :c:type:`PyMutex` pointers. + + On the default build, this macro expands to ``{``. + + .. versionadded:: 3.14 + +.. c:macro:: Py_END_CRITICAL_SECTION2() + + Ends the critical section and releases the per-object locks. + + In the free-threaded build, this macro expands to:: + + PyCriticalSection2_End(&_py_cs2); + } + + In the default build, this macro expands to ``}``. + + .. versionadded:: 3.13 + + +Legacy locking APIs +------------------- + +These APIs are obsolete since Python 3.13 with the introduction of +:c:type:`PyMutex`. + +.. versionchanged:: 3.15 + These APIs are now a simple wrapper around ``PyMutex``. + + +.. c:type:: PyThread_type_lock + + A pointer to a mutual exclusion lock. + + +.. c:type:: PyLockStatus + + The result of acquiring a lock with a timeout. + + .. c:namespace:: NULL + + .. c:enumerator:: PY_LOCK_FAILURE + + Failed to acquire the lock. + + .. c:enumerator:: PY_LOCK_ACQUIRED + + The lock was successfully acquired. + + .. c:enumerator:: PY_LOCK_INTR + + The lock was interrupted by a signal. + + +.. c:function:: PyThread_type_lock PyThread_allocate_lock(void) + + Allocate a new lock. + + On success, this function returns a lock; on failure, this + function returns ``0`` without an exception set. + + The caller does not need to hold an :term:`attached thread state`. + + .. versionchanged:: 3.15 + This function now always uses :c:type:`PyMutex`. In prior versions, this + would use a lock provided by the operating system. + + +.. c:function:: void PyThread_free_lock(PyThread_type_lock lock) + + Destroy *lock*. The lock should not be held by any thread when calling + this. + + The caller does not need to hold an :term:`attached thread state`. + + +.. c:function:: PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock lock, long long microseconds, int intr_flag) + + Acquire *lock* with a timeout. + + This will wait for *microseconds* microseconds to acquire the lock. If the + timeout expires, this function returns :c:enumerator:`PY_LOCK_FAILURE`. + If *microseconds* is ``-1``, this will wait indefinitely until the lock has + been released. + + If *intr_flag* is ``1``, acquiring the lock may be interrupted by a signal, + in which case this function returns :c:enumerator:`PY_LOCK_INTR`. Upon + interruption, it's generally expected that the caller makes a call to + :c:func:`Py_MakePendingCalls` to propagate an exception to Python code. + + If the lock is successfully acquired, this function returns + :c:enumerator:`PY_LOCK_ACQUIRED`. + + The caller does not need to hold an :term:`attached thread state`. + + +.. c:function:: int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) + + Acquire *lock*. + + If *waitflag* is ``1`` and another thread currently holds the lock, this + function will wait until the lock can be acquired and will always return + ``1``. + + If *waitflag* is ``0`` and another thread holds the lock, this function will + not wait and instead return ``0``. If the lock is not held by any other + thread, then this function will acquire it and return ``1``. + + Unlike :c:func:`PyThread_acquire_lock_timed`, acquiring the lock cannot be + interrupted by a signal. + + The caller does not need to hold an :term:`attached thread state`. + + +.. c:function:: int PyThread_release_lock(PyThread_type_lock lock) + + Release *lock*. If *lock* is not held, then this function issues a + fatal error. + + The caller does not need to hold an :term:`attached thread state`. diff --git a/Doc/c-api/threads.rst b/Doc/c-api/threads.rst new file mode 100644 index 00000000000000..46e713f4b5f96f --- /dev/null +++ b/Doc/c-api/threads.rst @@ -0,0 +1,827 @@ +.. highlight:: c + +.. _threads: + +Thread states and the global interpreter lock +============================================= + +.. index:: + single: global interpreter lock + single: interpreter lock + single: lock, interpreter + +Unless on a :term:`free-threaded ` build of :term:`CPython`, +the Python interpreter is not fully thread-safe. In order to support +multi-threaded Python programs, there's a global lock, called the :term:`global +interpreter lock` or :term:`GIL`, that must be held by the current thread before +it can safely access Python objects. Without the lock, even the simplest +operations could cause problems in a multi-threaded program: for example, when +two threads simultaneously increment the reference count of the same object, the +reference count could end up being incremented only once instead of twice. + +.. index:: single: setswitchinterval (in module sys) + +Therefore, the rule exists that only the thread that has acquired the +:term:`GIL` may operate on Python objects or call Python/C API functions. +In order to emulate concurrency of execution, the interpreter regularly +tries to switch threads (see :func:`sys.setswitchinterval`). The lock is also +released around potentially blocking I/O operations like reading or writing +a file, so that other Python threads can run in the meantime. + +.. index:: + single: PyThreadState (C type) + +The Python interpreter keeps some thread-specific bookkeeping information +inside a data structure called :c:type:`PyThreadState`, known as a :term:`thread state`. +Each OS thread has a thread-local pointer to a :c:type:`PyThreadState`; a thread state +referenced by this pointer is considered to be :term:`attached `. + +A thread can only have one :term:`attached thread state` at a time. An attached +thread state is typically analogous with holding the :term:`GIL`, except on +:term:`free-threaded ` builds. On builds with the :term:`GIL` enabled, +:term:`attaching ` a thread state will block until the :term:`GIL` +can be acquired. However, even on builds with the :term:`GIL` disabled, it is still required +to have an attached thread state to call most of the C API. + +In general, there will always be an :term:`attached thread state` when using Python's C API. +Only in some specific cases (such as in a :c:macro:`Py_BEGIN_ALLOW_THREADS` block) will the +thread not have an attached thread state. If uncertain, check if :c:func:`PyThreadState_GetUnchecked` returns +``NULL``. + +Detaching the thread state from extension code +---------------------------------------------- + +Most extension code manipulating the :term:`thread state` has the following simple +structure:: + + Save the thread state in a local variable. + ... Do some blocking I/O operation ... + Restore the thread state from the local variable. + +This is so common that a pair of macros exists to simplify it:: + + Py_BEGIN_ALLOW_THREADS + ... Do some blocking I/O operation ... + Py_END_ALLOW_THREADS + +.. index:: + single: Py_BEGIN_ALLOW_THREADS (C macro) + single: Py_END_ALLOW_THREADS (C macro) + +The :c:macro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a +hidden local variable; the :c:macro:`Py_END_ALLOW_THREADS` macro closes the +block. + +The block above expands to the following code:: + + PyThreadState *_save; + + _save = PyEval_SaveThread(); + ... Do some blocking I/O operation ... + PyEval_RestoreThread(_save); + +.. index:: + single: PyEval_RestoreThread (C function) + single: PyEval_SaveThread (C function) + +Here is how these functions work: + +The :term:`attached thread state` holds the :term:`GIL` for the entire interpreter. When detaching +the :term:`attached thread state`, the :term:`GIL` is released, allowing other threads to attach +a thread state to their own thread, thus getting the :term:`GIL` and can start executing. +The pointer to the prior :term:`attached thread state` is stored as a local variable. +Upon reaching :c:macro:`Py_END_ALLOW_THREADS`, the thread state that was +previously :term:`attached ` is passed to :c:func:`PyEval_RestoreThread`. +This function will block until another releases its :term:`thread state `, +thus allowing the old :term:`thread state ` to get re-attached and the +C API can be called again. + +For :term:`free-threaded ` builds, the :term:`GIL` is normally +out of the question, but detaching the :term:`thread state ` is still required +for blocking I/O and long operations. The difference is that threads don't have to wait for the :term:`GIL` +to be released to attach their thread state, allowing true multi-core parallelism. + +.. note:: + Calling system I/O functions is the most common use case for detaching + the :term:`thread state `, but it can also be useful before calling + long-running computations which don't need access to Python objects, such + as compression or cryptographic functions operating over memory buffers. + For example, the standard :mod:`zlib` and :mod:`hashlib` modules detach the + :term:`thread state ` when compressing or hashing data. + +APIs +^^^^ + +The following macros are normally used without a trailing semicolon; look for +example usage in the Python source distribution. + +.. note:: + + These macros are still necessary on the :term:`free-threaded build` to prevent + deadlocks. + +.. c:macro:: Py_BEGIN_ALLOW_THREADS + + This macro expands to ``{ PyThreadState *_save; _save = PyEval_SaveThread();``. + Note that it contains an opening brace; it must be matched with a following + :c:macro:`Py_END_ALLOW_THREADS` macro. See above for further discussion of this + macro. + + +.. c:macro:: Py_END_ALLOW_THREADS + + This macro expands to ``PyEval_RestoreThread(_save); }``. Note that it contains + a closing brace; it must be matched with an earlier + :c:macro:`Py_BEGIN_ALLOW_THREADS` macro. See above for further discussion of + this macro. + + +.. c:macro:: Py_BLOCK_THREADS + + This macro expands to ``PyEval_RestoreThread(_save);``: it is equivalent to + :c:macro:`Py_END_ALLOW_THREADS` without the closing brace. + + +.. c:macro:: Py_UNBLOCK_THREADS + + This macro expands to ``_save = PyEval_SaveThread();``: it is equivalent to + :c:macro:`Py_BEGIN_ALLOW_THREADS` without the opening brace and variable + declaration. + + +.. _gilstate: + +Non-Python created threads +-------------------------- + +When threads are created using the dedicated Python APIs (such as the +:mod:`threading` module), a thread state is automatically associated to them +and the code shown above is therefore correct. However, when threads are +created from C (for example by a third-party library with its own thread +management), they don't hold the :term:`GIL`, because they don't have an +:term:`attached thread state`. + +If you need to call Python code from these threads (often this will be part +of a callback API provided by the aforementioned third-party library), +you must first register these threads with the interpreter by +creating an :term:`attached thread state` before you can start using the Python/C +API. When you are done, you should detach the :term:`thread state `, and +finally free it. + +The :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` functions do +all of the above automatically. The typical idiom for calling into Python +from a C thread is:: + + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + /* Perform Python actions here. */ + result = CallSomeFunction(); + /* evaluate result or handle exception */ + + /* Release the thread. No Python API allowed beyond this point. */ + PyGILState_Release(gstate); + +Note that the ``PyGILState_*`` functions assume there is only one global +interpreter (created automatically by :c:func:`Py_Initialize`). Python +supports the creation of additional interpreters (using +:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the +``PyGILState_*`` API is unsupported. This is because :c:func:`PyGILState_Ensure` +and similar functions default to :term:`attaching ` a +:term:`thread state` for the main interpreter, meaning that the thread can't safely +interact with the calling subinterpreter. + +Supporting subinterpreters in non-Python threads +------------------------------------------------ + +If you would like to support subinterpreters with non-Python created threads, you +must use the ``PyThreadState_*`` API instead of the traditional ``PyGILState_*`` +API. + +In particular, you must store the interpreter state from the calling +function and pass it to :c:func:`PyThreadState_New`, which will ensure that +the :term:`thread state` is targeting the correct interpreter:: + + /* The return value of PyInterpreterState_Get() from the + function that created this thread. */ + PyInterpreterState *interp = ThreadData->interp; + PyThreadState *tstate = PyThreadState_New(interp); + PyThreadState_Swap(tstate); + + /* GIL of the subinterpreter is now held. + Perform Python actions here. */ + result = CallSomeFunction(); + /* evaluate result or handle exception */ + + /* Destroy the thread state. No Python API allowed beyond this point. */ + PyThreadState_Clear(tstate); + PyThreadState_DeleteCurrent(); + + +.. _fork-and-threads: + +Cautions about fork() +--------------------- + +Another important thing to note about threads is their behaviour in the face +of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a +process forks only the thread that issued the fork will exist. This has a +concrete impact both on how locks must be handled and on all stored state +in CPython's runtime. + +The fact that only the "current" thread remains +means any locks held by other threads will never be released. Python solves +this for :func:`os.fork` by acquiring the locks it uses internally before +the fork, and releasing them afterwards. In addition, it resets any +:ref:`lock-objects` in the child. When extending or embedding Python, there +is no way to inform Python of additional (non-Python) locks that need to be +acquired before or reset after a fork. OS facilities such as +:c:func:`!pthread_atfork` would need to be used to accomplish the same thing. +Additionally, when extending or embedding Python, calling :c:func:`fork` +directly rather than through :func:`os.fork` (and returning to or calling +into Python) may result in a deadlock by one of Python's internal locks +being held by a thread that is defunct after the fork. +:c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not +always able to. + +The fact that all other threads go away also means that CPython's +runtime state there must be cleaned up properly, which :func:`os.fork` +does. This means finalizing all other :c:type:`PyThreadState` objects +belonging to the current interpreter and all other +:c:type:`PyInterpreterState` objects. Due to this and the special +nature of the :ref:`"main" interpreter `, +:c:func:`fork` should only be called in that interpreter's "main" +thread, where the CPython global runtime was originally initialized. +The only exception is if :c:func:`exec` will be called immediately +after. + + +High-level APIs +--------------- + +These are the most commonly used types and functions when writing multi-threaded +C extensions. + + +.. c:type:: PyThreadState + + This data structure represents the state of a single thread. The only public + data member is: + + .. c:member:: PyInterpreterState *interp + + This thread's interpreter state. + + +.. c:function:: void PyEval_InitThreads() + + .. index:: + single: PyEval_AcquireThread() + single: PyEval_ReleaseThread() + single: PyEval_SaveThread() + single: PyEval_RestoreThread() + + Deprecated function which does nothing. + + In Python 3.6 and older, this function created the GIL if it didn't exist. + + .. versionchanged:: 3.9 + The function now does nothing. + + .. versionchanged:: 3.7 + This function is now called by :c:func:`Py_Initialize()`, so you don't + have to call it yourself anymore. + + .. versionchanged:: 3.2 + This function cannot be called before :c:func:`Py_Initialize()` anymore. + + .. deprecated:: 3.9 + + .. index:: pair: module; _thread + + +.. c:function:: PyThreadState* PyEval_SaveThread() + + Detach the :term:`attached thread state` and return it. + The thread will have no :term:`thread state` upon returning. + + +.. c:function:: void PyEval_RestoreThread(PyThreadState *tstate) + + Set the :term:`attached thread state` to *tstate*. + The passed :term:`thread state` **should not** be :term:`attached `, + otherwise deadlock ensues. *tstate* will be attached upon returning. + + .. note:: + Calling this function from a thread when the runtime is finalizing will + hang the thread until the program exits, even if the thread was not + created by Python. Refer to + :ref:`cautions-regarding-runtime-finalization` for more details. + + .. versionchanged:: 3.14 + Hangs the current thread, rather than terminating it, if called while the + interpreter is finalizing. + +.. c:function:: PyThreadState* PyThreadState_Get() + + Return the :term:`attached thread state`. If the thread has no attached + thread state, (such as when inside of :c:macro:`Py_BEGIN_ALLOW_THREADS` + block), then this issues a fatal error (so that the caller needn't check + for ``NULL``). + + See also :c:func:`PyThreadState_GetUnchecked`. + +.. c:function:: PyThreadState* PyThreadState_GetUnchecked() + + Similar to :c:func:`PyThreadState_Get`, but don't kill the process with a + fatal error if it is NULL. The caller is responsible to check if the result + is NULL. + + .. versionadded:: 3.13 + In Python 3.5 to 3.12, the function was private and known as + ``_PyThreadState_UncheckedGet()``. + + +.. c:function:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) + + Set the :term:`attached thread state` to *tstate*, and return the + :term:`thread state` that was attached prior to calling. + + This function is safe to call without an :term:`attached thread state`; it + will simply return ``NULL`` indicating that there was no prior thread state. + + .. seealso:: + :c:func:`PyEval_ReleaseThread` + + .. note:: + Similar to :c:func:`PyGILState_Ensure`, this function will hang the + thread if the runtime is finalizing. + + +GIL-state APIs +-------------- + +The following functions use thread-local storage, and are not compatible +with sub-interpreters: + +.. c:type:: PyGILState_STATE + + The type of the value returned by :c:func:`PyGILState_Ensure` and passed to + :c:func:`PyGILState_Release`. + + .. c:enumerator:: PyGILState_LOCKED + + The GIL was already held when :c:func:`PyGILState_Ensure` was called. + + .. c:enumerator:: PyGILState_UNLOCKED + + The GIL was not held when :c:func:`PyGILState_Ensure` was called. + +.. c:function:: PyGILState_STATE PyGILState_Ensure() + + Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the :term:`attached thread state`. This may + be called as many times as desired by a thread as long as each call is + matched with a call to :c:func:`PyGILState_Release`. In general, other + thread-related APIs may be used between :c:func:`PyGILState_Ensure` and + :c:func:`PyGILState_Release` calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + :c:macro:`Py_BEGIN_ALLOW_THREADS` and :c:macro:`Py_END_ALLOW_THREADS` macros is + acceptable. + + The return value is an opaque "handle" to the :term:`attached thread state` when + :c:func:`PyGILState_Ensure` was called, and must be passed to + :c:func:`PyGILState_Release` to ensure Python is left in the same state. Even + though recursive calls are allowed, these handles *cannot* be shared - each + unique call to :c:func:`PyGILState_Ensure` must save the handle for its call + to :c:func:`PyGILState_Release`. + + When the function returns, there will be an :term:`attached thread state` + and the thread will be able to call arbitrary Python code. Failure is a fatal error. + + .. warning:: + Calling this function when the runtime is finalizing is unsafe. Doing + so will either hang the thread until the program ends, or fully crash + the interpreter in rare cases. Refer to + :ref:`cautions-regarding-runtime-finalization` for more details. + + .. versionchanged:: 3.14 + Hangs the current thread, rather than terminating it, if called while the + interpreter is finalizing. + +.. c:function:: void PyGILState_Release(PyGILState_STATE) + + Release any resources previously acquired. After this call, Python's state will + be the same as it was prior to the corresponding :c:func:`PyGILState_Ensure` call + (but generally this state will be unknown to the caller, hence the use of the + GILState API). + + Every call to :c:func:`PyGILState_Ensure` must be matched by a call to + :c:func:`PyGILState_Release` on the same thread. + +.. c:function:: PyThreadState* PyGILState_GetThisThreadState() + + Get the :term:`attached thread state` for this thread. May return ``NULL`` if no + GILState API has been used on the current thread. Note that the main thread + always has such a thread-state, even if no auto-thread-state call has been + made on the main thread. This is mainly a helper/diagnostic function. + + .. note:: + This function may return non-``NULL`` even when the :term:`thread state` + is detached. + Prefer :c:func:`PyThreadState_Get` or :c:func:`PyThreadState_GetUnchecked` + for most cases. + + .. seealso:: :c:func:`PyThreadState_Get` + +.. c:function:: int PyGILState_Check() + + Return ``1`` if the current thread is holding the :term:`GIL` and ``0`` otherwise. + This function can be called from any thread at any time. + Only if it has had its :term:`thread state ` initialized + via :c:func:`PyGILState_Ensure` will it return ``1``. + This is mainly a helper/diagnostic function. It can be useful + for example in callback contexts or memory allocation functions when + knowing that the :term:`GIL` is locked can allow the caller to perform sensitive + actions or otherwise behave differently. + + .. note:: + If the current Python process has ever created a subinterpreter, this + function will *always* return ``1``. Prefer :c:func:`PyThreadState_GetUnchecked` + for most cases. + + .. versionadded:: 3.4 + + +Low-level APIs +-------------- + +.. c:function:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) + + Create a new thread state object belonging to the given interpreter object. + An :term:`attached thread state` is not needed. + +.. c:function:: void PyThreadState_Clear(PyThreadState *tstate) + + Reset all information in a :term:`thread state` object. *tstate* + must be :term:`attached ` + + .. versionchanged:: 3.9 + This function now calls the :c:member:`!PyThreadState.on_delete` callback. + Previously, that happened in :c:func:`PyThreadState_Delete`. + + .. versionchanged:: 3.13 + The :c:member:`!PyThreadState.on_delete` callback was removed. + + +.. c:function:: void PyThreadState_Delete(PyThreadState *tstate) + + Destroy a :term:`thread state` object. *tstate* should not + be :term:`attached ` to any thread. + *tstate* must have been reset with a previous call to + :c:func:`PyThreadState_Clear`. + + +.. c:function:: void PyThreadState_DeleteCurrent(void) + + Detach the :term:`attached thread state` (which must have been reset + with a previous call to :c:func:`PyThreadState_Clear`) and then destroy it. + + No :term:`thread state` will be :term:`attached ` upon + returning. + +.. c:function:: PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) + + Get the current frame of the Python thread state *tstate*. + + Return a :term:`strong reference`. Return ``NULL`` if no frame is currently + executing. + + See also :c:func:`PyEval_GetFrame`. + + *tstate* must not be ``NULL``, and must be :term:`attached `. + + .. versionadded:: 3.9 + + +.. c:function:: uint64_t PyThreadState_GetID(PyThreadState *tstate) + + Get the unique :term:`thread state` identifier of the Python thread state *tstate*. + + *tstate* must not be ``NULL``, and must be :term:`attached `. + + .. versionadded:: 3.9 + + +.. c:function:: PyInterpreterState* PyThreadState_GetInterpreter(PyThreadState *tstate) + + Get the interpreter of the Python thread state *tstate*. + + *tstate* must not be ``NULL``, and must be :term:`attached `. + + .. versionadded:: 3.9 + + +.. c:function:: void PyThreadState_EnterTracing(PyThreadState *tstate) + + Suspend tracing and profiling in the Python thread state *tstate*. + + Resume them using the :c:func:`PyThreadState_LeaveTracing` function. + + .. versionadded:: 3.11 + + +.. c:function:: void PyThreadState_LeaveTracing(PyThreadState *tstate) + + Resume tracing and profiling in the Python thread state *tstate* suspended + by the :c:func:`PyThreadState_EnterTracing` function. + + See also :c:func:`PyEval_SetTrace` and :c:func:`PyEval_SetProfile` + functions. + + .. versionadded:: 3.11 + + +.. c:function:: int PyUnstable_ThreadState_SetStackProtection(PyThreadState *tstate, void *stack_start_addr, size_t stack_size) + + Set the stack protection start address and stack protection size + of a Python thread state. + + On success, return ``0``. + On failure, set an exception and return ``-1``. + + CPython implements :ref:`recursion control ` for C code by raising + :py:exc:`RecursionError` when it notices that the machine execution stack is close + to overflow. See for example the :c:func:`Py_EnterRecursiveCall` function. + For this, it needs to know the location of the current thread's stack, which it + normally gets from the operating system. + When the stack is changed, for example using context switching techniques like the + Boost library's ``boost::context``, you must call + :c:func:`~PyUnstable_ThreadState_SetStackProtection` to inform CPython of the change. + + Call :c:func:`~PyUnstable_ThreadState_SetStackProtection` either before + or after changing the stack. + Do not call any other Python C API between the call and the stack + change. + + See :c:func:`PyUnstable_ThreadState_ResetStackProtection` for undoing this operation. + + .. versionadded:: 3.15 + + +.. c:function:: void PyUnstable_ThreadState_ResetStackProtection(PyThreadState *tstate) + + Reset the stack protection start address and stack protection size + of a Python thread state to the operating system defaults. + + See :c:func:`PyUnstable_ThreadState_SetStackProtection` for an explanation. + + .. versionadded:: 3.15 + + +.. c:function:: PyObject* PyThreadState_GetDict() + + Return a dictionary in which extensions can store thread-specific state + information. Each extension should use a unique key to use to store state in + the dictionary. It is okay to call this function when no :term:`thread state` + is :term:`attached `. If this function returns + ``NULL``, no exception has been raised and the caller should assume no + thread state is attached. + + +.. c:function:: void PyEval_AcquireThread(PyThreadState *tstate) + + :term:`Attach ` *tstate* to the current thread, + which must not be ``NULL`` or already :term:`attached `. + + The calling thread must not already have an :term:`attached thread state`. + + .. note:: + Calling this function from a thread when the runtime is finalizing will + hang the thread until the program exits, even if the thread was not + created by Python. Refer to + :ref:`cautions-regarding-runtime-finalization` for more details. + + .. versionchanged:: 3.8 + Updated to be consistent with :c:func:`PyEval_RestoreThread`, + :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`, + and terminate the current thread if called while the interpreter is finalizing. + + .. versionchanged:: 3.14 + Hangs the current thread, rather than terminating it, if called while the + interpreter is finalizing. + + :c:func:`PyEval_RestoreThread` is a higher-level function which is always + available (even when threads have not been initialized). + + +.. c:function:: void PyEval_ReleaseThread(PyThreadState *tstate) + + Detach the :term:`attached thread state`. + The *tstate* argument, which must not be ``NULL``, is only used to check + that it represents the :term:`attached thread state` --- if it isn't, a fatal error is + reported. + + :c:func:`PyEval_SaveThread` is a higher-level function which is always + available (even when threads have not been initialized). + + +Asynchronous notifications +========================== + +A mechanism is provided to make asynchronous notifications to the main +interpreter thread. These notifications take the form of a function +pointer and a void pointer argument. + + +.. c:function:: int Py_AddPendingCall(int (*func)(void *), void *arg) + + Schedule a function to be called from the main interpreter thread. On + success, ``0`` is returned and *func* is queued for being called in the + main thread. On failure, ``-1`` is returned without setting any exception. + + When successfully queued, *func* will be *eventually* called from the + main interpreter thread with the argument *arg*. It will be called + asynchronously with respect to normally running Python code, but with + both these conditions met: + + * on a :term:`bytecode` boundary; + * with the main thread holding an :term:`attached thread state` + (*func* can therefore use the full C API). + + *func* must return ``0`` on success, or ``-1`` on failure with an exception + set. *func* won't be interrupted to perform another asynchronous + notification recursively, but it can still be interrupted to switch + threads if the :term:`thread state ` is detached. + + This function doesn't need an :term:`attached thread state`. However, to call this + function in a subinterpreter, the caller must have an :term:`attached thread state`. + Otherwise, the function *func* can be scheduled to be called from the wrong interpreter. + + .. warning:: + This is a low-level function, only useful for very special cases. + There is no guarantee that *func* will be called as quick as + possible. If the main thread is busy executing a system call, + *func* won't be called before the system call returns. This + function is generally **not** suitable for calling Python code from + arbitrary C threads. Instead, use the :ref:`PyGILState API`. + + .. versionadded:: 3.1 + + .. versionchanged:: 3.9 + If this function is called in a subinterpreter, the function *func* is + now scheduled to be called from the subinterpreter, rather than being + called from the main interpreter. Each subinterpreter now has its own + list of scheduled calls. + + .. versionchanged:: 3.12 + This function now always schedules *func* to be run in the main + interpreter. + + +.. c:function:: int Py_MakePendingCalls(void) + + Execute all pending calls. This is usually executed automatically by the + interpreter. + + This function returns ``0`` on success, and returns ``-1`` with an exception + set on failure. + + If this is not called in the main thread of the main + interpreter, this function does nothing and returns ``0``. + The caller must hold an :term:`attached thread state`. + + .. versionadded:: 3.1 + + .. versionchanged:: 3.12 + This function only runs pending calls in the main interpreter. + + +.. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) + + Asynchronously raise an exception in a thread. The *id* argument is the thread + id of the target thread; *exc* is the exception object to be raised. This + function does not steal any references to *exc*. To prevent naive misuse, you + must write your own C extension to call this. Must be called with an :term:`attached thread state`. + Returns the number of thread states modified; this is normally one, but will be + zero if the thread id isn't found. If *exc* is ``NULL``, the pending + exception (if any) for the thread is cleared. This raises no exceptions. + + .. versionchanged:: 3.7 + The type of the *id* parameter changed from :c:expr:`long` to + :c:expr:`unsigned long`. + + +Operating system thread APIs +============================ + +.. c:macro:: PYTHREAD_INVALID_THREAD_ID + + Sentinel value for an invalid thread ID. + + This is currently equivalent to ``(unsigned long)-1``. + + +.. c:function:: unsigned long PyThread_start_new_thread(void (*func)(void *), void *arg) + + Start function *func* in a new thread with argument *arg*. + The resulting thread is not intended to be joined. + + *func* must not be ``NULL``, but *arg* may be ``NULL``. + + On success, this function returns the identifier of the new thread; on failure, + this returns :c:macro:`PYTHREAD_INVALID_THREAD_ID`. + + The caller does not need to hold an :term:`attached thread state`. + + +.. c:function:: unsigned long PyThread_get_thread_ident(void) + + Return the identifier of the current thread, which will never be zero. + + This function cannot fail, and the caller does not need to hold an + :term:`attached thread state`. + + .. seealso:: + :py:func:`threading.get_ident` + + +.. c:function:: PyObject *PyThread_GetInfo(void) + + Get general information about the current thread in the form of a + :ref:`struct sequence ` object. This information is + accessible as :py:attr:`sys.thread_info` in Python. + + On success, this returns a new :term:`strong reference` to the thread + information; on failure, this returns ``NULL`` with an exception set. + + The caller must hold an :term:`attached thread state`. + + +.. c:macro:: PY_HAVE_THREAD_NATIVE_ID + + This macro is defined when the system supports native thread IDs. + + +.. c:function:: unsigned long PyThread_get_thread_native_id(void) + + Get the native identifier of the current thread as it was assigned by the operating + system's kernel, which will never be less than zero. + + This function is only available when :c:macro:`PY_HAVE_THREAD_NATIVE_ID` is + defined. + + This function cannot fail, and the caller does not need to hold an + :term:`attached thread state`. + + .. seealso:: + :py:func:`threading.get_native_id` + + +.. c:function:: void PyThread_exit_thread(void) + + Terminate the current thread. This function is generally considered unsafe + and should be avoided. It is kept solely for backwards compatibility. + + This function is only safe to call if all functions in the full call + stack are written to safely allow it. + + .. warning:: + + If the current system uses POSIX threads (also known as "pthreads"), + this calls :manpage:`pthread_exit(3)`, which attempts to unwind the stack + and call C++ destructors on some libc implementations. However, if a + ``noexcept`` function is reached, it may terminate the process. + Other systems, such as macOS, do unwinding. + + On Windows, this function calls ``_endthreadex()``, which kills the thread + without calling C++ destructors. + + In any case, there is a risk of corruption on the thread's stack. + + .. deprecated:: 3.14 + + +.. c:function:: void PyThread_init_thread(void) + + Initialize ``PyThread*`` APIs. Python executes this function automatically, + so there's little need to call it from an extension module. + + +.. c:function:: int PyThread_set_stacksize(size_t size) + + Set the stack size of the current thread to *size* bytes. + + This function returns ``0`` on success, ``-1`` if *size* is invalid, or + ``-2`` if the system does not support changing the stack size. This function + does not set exceptions. + + The caller does not need to hold an :term:`attached thread state`. + + +.. c:function:: size_t PyThread_get_stacksize(void) + + Return the stack size of the current thread in bytes, or ``0`` if the system's + default stack size is in use. + + The caller does not need to hold an :term:`attached thread state`. diff --git a/Doc/c-api/tls.rst b/Doc/c-api/tls.rst new file mode 100644 index 00000000000000..93ac5557141e25 --- /dev/null +++ b/Doc/c-api/tls.rst @@ -0,0 +1,155 @@ +.. highlight:: c + +.. _thread-local-storage: + +Thread-local storage support +============================ + +The Python interpreter provides low-level support for thread-local storage +(TLS) which wraps the underlying native TLS implementation to support the +Python-level thread-local storage API (:class:`threading.local`). The +CPython C level APIs are similar to those offered by pthreads and Windows: +use a thread key and functions to associate a :c:expr:`void*` value per +thread. + +A :term:`thread state` does *not* need to be :term:`attached ` +when calling these functions; they supply their own locking. + +Note that :file:`Python.h` does not include the declaration of the TLS APIs, +you need to include :file:`pythread.h` to use thread-local storage. + +.. note:: + None of these API functions handle memory management on behalf of the + :c:expr:`void*` values. You need to allocate and deallocate them yourself. + If the :c:expr:`void*` values happen to be :c:expr:`PyObject*`, these + functions don't do refcount operations on them either. + +.. _thread-specific-storage-api: + +Thread-specific storage API +--------------------------- + +The thread-specific storage (TSS) API was introduced to supersede the use of the existing TLS API within the +CPython interpreter. This API uses a new type :c:type:`Py_tss_t` instead of +:c:expr:`int` to represent thread keys. + +.. versionadded:: 3.7 + +.. seealso:: "A New C-API for Thread-Local Storage in CPython" (:pep:`539`) + + +.. c:type:: Py_tss_t + + This data structure represents the state of a thread key, the definition of + which may depend on the underlying TLS implementation, and it has an + internal field representing the key's initialization state. There are no + public members in this structure. + + When :ref:`Py_LIMITED_API ` is not defined, static allocation of + this type by :c:macro:`Py_tss_NEEDS_INIT` is allowed. + + +.. c:macro:: Py_tss_NEEDS_INIT + + This macro expands to the initializer for :c:type:`Py_tss_t` variables. + Note that this macro won't be defined with :ref:`Py_LIMITED_API `. + + +Dynamic allocation +------------------ + +Dynamic allocation of the :c:type:`Py_tss_t`, required in extension modules +built with :ref:`Py_LIMITED_API `, where static allocation of this type +is not possible due to its implementation being opaque at build time. + + +.. c:function:: Py_tss_t* PyThread_tss_alloc() + + Return a value which is the same state as a value initialized with + :c:macro:`Py_tss_NEEDS_INIT`, or ``NULL`` in the case of dynamic allocation + failure. + + +.. c:function:: void PyThread_tss_free(Py_tss_t *key) + + Free the given *key* allocated by :c:func:`PyThread_tss_alloc`, after + first calling :c:func:`PyThread_tss_delete` to ensure any associated + thread locals have been unassigned. This is a no-op if the *key* + argument is ``NULL``. + + .. note:: + A freed key becomes a dangling pointer. You should reset the key to + ``NULL``. + + +Methods +------- + +The parameter *key* of these functions must not be ``NULL``. Moreover, the +behaviors of :c:func:`PyThread_tss_set` and :c:func:`PyThread_tss_get` are +undefined if the given :c:type:`Py_tss_t` has not been initialized by +:c:func:`PyThread_tss_create`. + + +.. c:function:: int PyThread_tss_is_created(Py_tss_t *key) + + Return a non-zero value if the given :c:type:`Py_tss_t` has been initialized + by :c:func:`PyThread_tss_create`. + + +.. c:function:: int PyThread_tss_create(Py_tss_t *key) + + Return a zero value on successful initialization of a TSS key. The behavior + is undefined if the value pointed to by the *key* argument is not + initialized by :c:macro:`Py_tss_NEEDS_INIT`. This function can be called + repeatedly on the same key -- calling it on an already initialized key is a + no-op and immediately returns success. + + +.. c:function:: void PyThread_tss_delete(Py_tss_t *key) + + Destroy a TSS key to forget the values associated with the key across all + threads, and change the key's initialization state to uninitialized. A + destroyed key is able to be initialized again by + :c:func:`PyThread_tss_create`. This function can be called repeatedly on + the same key -- calling it on an already destroyed key is a no-op. + + +.. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value) + + Return a zero value to indicate successfully associating a :c:expr:`void*` + value with a TSS key in the current thread. Each thread has a distinct + mapping of the key to a :c:expr:`void*` value. + + +.. c:function:: void* PyThread_tss_get(Py_tss_t *key) + + Return the :c:expr:`void*` value associated with a TSS key in the current + thread. This returns ``NULL`` if no value is associated with the key in the + current thread. + + +.. _thread-local-storage-api: + +Legacy APIs +----------- + +.. deprecated:: 3.7 + This API is superseded by the + :ref:`thread-specific storage (TSS) API `. + +.. note:: + This version of the API does not support platforms where the native TLS key + is defined in a way that cannot be safely cast to ``int``. On such platforms, + :c:func:`PyThread_create_key` will return immediately with a failure status, + and the other TLS functions will all be no-ops on such platforms. + +Due to the compatibility problem noted above, this version of the API should not +be used in new code. + +.. c:function:: int PyThread_create_key() +.. c:function:: void PyThread_delete_key(int key) +.. c:function:: int PyThread_set_key_value(int key, void *value) +.. c:function:: void* PyThread_get_key_value(int key) +.. c:function:: void PyThread_delete_key_value(int key) +.. c:function:: void PyThread_ReInitTLS() From 8246d588e48f7072c283db3e4eb1795a9a9780bf Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 20 Feb 2026 12:44:30 -0600 Subject: [PATCH 179/498] Simplify summary tables in the itertools docs (gh-145050) Combine two dispatch tables into once. --- Doc/library/itertools.rst | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index ce444d7bdfbadb..06a71535b5c93c 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -27,18 +27,7 @@ For instance, SML provides a tabulation tool: ``tabulate(f)`` which produces a sequence ``f(0), f(1), ...``. The same effect can be achieved in Python by combining :func:`map` and :func:`count` to form ``map(f, count())``. - -**Infinite iterators:** - -================== ================= ================================================= ========================================= -Iterator Arguments Results Example -================== ================= ================================================= ========================================= -:func:`count` [start[, step]] start, start+step, start+2*step, ... ``count(10) → 10 11 12 13 14 ...`` -:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') → A B C D A B C D ...`` -:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) → 10 10 10`` -================== ================= ================================================= ========================================= - -**Iterators terminating on the shortest input sequence:** +**General iterators:** ============================ ============================ ================================================= ============================================================= Iterator Arguments Results Example @@ -48,11 +37,14 @@ Iterator Arguments Results :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') → A B C D E F`` :func:`chain.from_iterable` iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) → A B C D E F`` :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) → A C E F`` +:func:`count` [start[, step]] start, start+step, start+2*step, ... ``count(10) → 10 11 12 13 14 ...`` +:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') → A B C D A B C D ...`` :func:`dropwhile` predicate, seq seq[n], seq[n+1], starting when predicate fails ``dropwhile(lambda x: x<5, [1,4,6,3,8]) → 6 3 8`` :func:`filterfalse` predicate, seq elements of seq where predicate(elem) fails ``filterfalse(lambda x: x<5, [1,4,6,3,8]) → 6 8`` :func:`groupby` iterable[, key] sub-iterators grouped by value of key(v) ``groupby(['A','B','DEF'], len) → (1, A B) (3, DEF)`` :func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) → C D E F G`` :func:`pairwise` iterable (p[0], p[1]), (p[1], p[2]) ``pairwise('ABCDEFG') → AB BC CD DE EF FG`` +:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) → 10 10 10`` :func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) → 32 9 1000`` :func:`takewhile` predicate, seq seq[0], seq[1], until predicate fails ``takewhile(lambda x: x<5, [1,4,6,3,8]) → 1 4`` :func:`tee` it, n it1, it2, ... itn splits one iterator into n ``tee('ABC', 2) → A B C, A B C`` From a56532771a9e24689576a0c38146f0ab2d82b491 Mon Sep 17 00:00:00 2001 From: Alper Date: Fri, 20 Feb 2026 10:52:18 -0800 Subject: [PATCH 180/498] gh-144981: Make PyUnstable_Code_SetExtra/GetExtra thread-safe (#144980) * Make PyUnstable_Code_SetExtra/GetExtra thread-safe --- Lib/test/test_free_threading/test_code.py | 109 ++++++++++++++ ...-02-18-15-12-34.gh-issue-144981.4ZdM63.rst | 3 + Objects/codeobject.c | 142 ++++++++++++++---- Python/ceval.c | 20 ++- 4 files changed, 243 insertions(+), 31 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst diff --git a/Lib/test/test_free_threading/test_code.py b/Lib/test/test_free_threading/test_code.py index a5136a3ba4edc7..2fc5eea3773c39 100644 --- a/Lib/test/test_free_threading/test_code.py +++ b/Lib/test/test_free_threading/test_code.py @@ -1,9 +1,41 @@ import unittest +try: + import ctypes +except ImportError: + ctypes = None + from threading import Thread from unittest import TestCase from test.support import threading_helper +from test.support.threading_helper import run_concurrently + +if ctypes is not None: + capi = ctypes.pythonapi + + freefunc = ctypes.CFUNCTYPE(None, ctypes.c_voidp) + + RequestCodeExtraIndex = capi.PyUnstable_Eval_RequestCodeExtraIndex + RequestCodeExtraIndex.argtypes = (freefunc,) + RequestCodeExtraIndex.restype = ctypes.c_ssize_t + + SetExtra = capi.PyUnstable_Code_SetExtra + SetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, ctypes.c_voidp) + SetExtra.restype = ctypes.c_int + + GetExtra = capi.PyUnstable_Code_GetExtra + GetExtra.argtypes = ( + ctypes.py_object, + ctypes.c_ssize_t, + ctypes.POINTER(ctypes.c_voidp), + ) + GetExtra.restype = ctypes.c_int + +# Note: each call to RequestCodeExtraIndex permanently allocates a slot +# (the counter is monotonically increasing), up to MAX_CO_EXTRA_USERS (255). +NTHREADS = 20 + @threading_helper.requires_working_threading() class TestCode(TestCase): @@ -25,6 +57,83 @@ def run_in_thread(): for thread in threads: thread.join() + @unittest.skipUnless(ctypes, "ctypes is required") + def test_request_code_extra_index_concurrent(self): + """Test concurrent calls to RequestCodeExtraIndex""" + results = [] + + def worker(): + idx = RequestCodeExtraIndex(freefunc(0)) + self.assertGreaterEqual(idx, 0) + results.append(idx) + + run_concurrently(worker_func=worker, nthreads=NTHREADS) + + # Every thread must get a unique index. + self.assertEqual(len(results), NTHREADS) + self.assertEqual(len(set(results)), NTHREADS) + + @unittest.skipUnless(ctypes, "ctypes is required") + def test_code_extra_all_ops_concurrent(self): + """Test concurrent RequestCodeExtraIndex + SetExtra + GetExtra""" + LOOP = 100 + + def f(): + pass + + code = f.__code__ + + def worker(): + idx = RequestCodeExtraIndex(freefunc(0)) + self.assertGreaterEqual(idx, 0) + + for i in range(LOOP): + ret = SetExtra(code, idx, ctypes.c_voidp(i + 1)) + self.assertEqual(ret, 0) + + for _ in range(LOOP): + extra = ctypes.c_voidp() + ret = GetExtra(code, idx, extra) + self.assertEqual(ret, 0) + # The slot was set by this thread, so the value must + # be the last one written. + self.assertEqual(extra.value, LOOP) + + run_concurrently(worker_func=worker, nthreads=NTHREADS) + + @unittest.skipUnless(ctypes, "ctypes is required") + def test_code_extra_set_get_concurrent(self): + """Test concurrent SetExtra + GetExtra on a shared index""" + LOOP = 100 + + def f(): + pass + + code = f.__code__ + + idx = RequestCodeExtraIndex(freefunc(0)) + self.assertGreaterEqual(idx, 0) + + def worker(): + for i in range(LOOP): + ret = SetExtra(code, idx, ctypes.c_voidp(i + 1)) + self.assertEqual(ret, 0) + + for _ in range(LOOP): + extra = ctypes.c_voidp() + ret = GetExtra(code, idx, extra) + self.assertEqual(ret, 0) + # Value is set by any writer thread. + self.assertTrue(1 <= extra.value <= LOOP) + + run_concurrently(worker_func=worker, nthreads=NTHREADS) + + # Every thread's last write is LOOP, so the final value must be LOOP. + extra = ctypes.c_voidp() + ret = GetExtra(code, idx, extra) + self.assertEqual(ret, 0) + self.assertEqual(extra.value, LOOP) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst b/Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst new file mode 100644 index 00000000000000..d86886ab09704a --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst @@ -0,0 +1,3 @@ +Made :c:func:`PyUnstable_Code_SetExtra`, :c:func:`PyUnstable_Code_GetExtra`, +and :c:func:`PyUnstable_Eval_RequestCodeExtraIndex` thread-safe on the +:term:`free threaded ` build. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 776444a0cc2086..520190824fbf1a 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1575,6 +1575,67 @@ typedef struct { } _PyCodeObjectExtra; +static inline size_t +code_extra_size(Py_ssize_t n) +{ + return sizeof(_PyCodeObjectExtra) + (n - 1) * sizeof(void *); +} + +#ifdef Py_GIL_DISABLED +static int +code_extra_grow_ft(PyCodeObject *co, _PyCodeObjectExtra *old_co_extra, + Py_ssize_t old_ce_size, Py_ssize_t new_ce_size, + Py_ssize_t index, void *extra) +{ + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(co); + _PyCodeObjectExtra *new_co_extra = PyMem_Malloc( + code_extra_size(new_ce_size)); + if (new_co_extra == NULL) { + PyErr_NoMemory(); + return -1; + } + + if (old_ce_size > 0) { + memcpy(new_co_extra->ce_extras, old_co_extra->ce_extras, + old_ce_size * sizeof(void *)); + } + for (Py_ssize_t i = old_ce_size; i < new_ce_size; i++) { + new_co_extra->ce_extras[i] = NULL; + } + new_co_extra->ce_size = new_ce_size; + new_co_extra->ce_extras[index] = extra; + + // Publish new buffer and its contents to lock-free readers. + FT_ATOMIC_STORE_PTR_RELEASE(co->co_extra, new_co_extra); + if (old_co_extra != NULL) { + // QSBR: defer old-buffer free until lock-free readers quiesce. + _PyMem_FreeDelayed(old_co_extra, code_extra_size(old_ce_size)); + } + return 0; +} +#else +static int +code_extra_grow_gil(PyCodeObject *co, _PyCodeObjectExtra *old_co_extra, + Py_ssize_t old_ce_size, Py_ssize_t new_ce_size, + Py_ssize_t index, void *extra) +{ + _PyCodeObjectExtra *new_co_extra = PyMem_Realloc( + old_co_extra, code_extra_size(new_ce_size)); + if (new_co_extra == NULL) { + PyErr_NoMemory(); + return -1; + } + + for (Py_ssize_t i = old_ce_size; i < new_ce_size; i++) { + new_co_extra->ce_extras[i] = NULL; + } + new_co_extra->ce_size = new_ce_size; + new_co_extra->ce_extras[index] = extra; + co->co_extra = new_co_extra; + return 0; +} +#endif + int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra) { @@ -1583,15 +1644,19 @@ PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra) return -1; } - PyCodeObject *o = (PyCodeObject*) code; - _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra; + PyCodeObject *co = (PyCodeObject *)code; + *extra = NULL; - if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) { - *extra = NULL; + if (index < 0) { return 0; } - *extra = co_extra->ce_extras[index]; + // Lock-free read; pairs with release stores in SetExtra. + _PyCodeObjectExtra *co_extra = FT_ATOMIC_LOAD_PTR_ACQUIRE(co->co_extra); + if (co_extra != NULL && index < co_extra->ce_size) { + *extra = FT_ATOMIC_LOAD_PTR_ACQUIRE(co_extra->ce_extras[index]); + } + return 0; } @@ -1601,40 +1666,59 @@ PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra) { PyInterpreterState *interp = _PyInterpreterState_GET(); - if (!PyCode_Check(code) || index < 0 || - index >= interp->co_extra_user_count) { + // co_extra_user_count is monotonically increasing and published with + // release store in RequestCodeExtraIndex, so once an index is valid + // it stays valid. + Py_ssize_t user_count = FT_ATOMIC_LOAD_SSIZE_ACQUIRE( + interp->co_extra_user_count); + + if (!PyCode_Check(code) || index < 0 || index >= user_count) { PyErr_BadInternalCall(); return -1; } - PyCodeObject *o = (PyCodeObject*) code; - _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra; + PyCodeObject *co = (PyCodeObject *)code; + int result = 0; + void *old_slot_value = NULL; - if (co_extra == NULL || co_extra->ce_size <= index) { - Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size); - co_extra = PyMem_Realloc( - co_extra, - sizeof(_PyCodeObjectExtra) + - (interp->co_extra_user_count-1) * sizeof(void*)); - if (co_extra == NULL) { - return -1; - } - for (; i < interp->co_extra_user_count; i++) { - co_extra->ce_extras[i] = NULL; - } - co_extra->ce_size = interp->co_extra_user_count; - o->co_extra = co_extra; + Py_BEGIN_CRITICAL_SECTION(co); + + _PyCodeObjectExtra *old_co_extra = (_PyCodeObjectExtra *)co->co_extra; + Py_ssize_t old_ce_size = (old_co_extra == NULL) + ? 0 : old_co_extra->ce_size; + + // Fast path: slot already exists, update in place. + if (index < old_ce_size) { + old_slot_value = old_co_extra->ce_extras[index]; + FT_ATOMIC_STORE_PTR_RELEASE(old_co_extra->ce_extras[index], extra); + goto done; } - if (co_extra->ce_extras[index] != NULL) { - freefunc free = interp->co_extra_freefuncs[index]; - if (free != NULL) { - free(co_extra->ce_extras[index]); + // Slow path: buffer needs to grow. + Py_ssize_t new_ce_size = user_count; +#ifdef Py_GIL_DISABLED + // FT build: allocate new buffer and swap; QSBR reclaims the old one. + result = code_extra_grow_ft( + co, old_co_extra, old_ce_size, new_ce_size, index, extra); +#else + // GIL build: grow with realloc. + result = code_extra_grow_gil( + co, old_co_extra, old_ce_size, new_ce_size, index, extra); +#endif + +done:; + Py_END_CRITICAL_SECTION(); + if (old_slot_value != NULL) { + // Free the old slot value if a free function was registered. + // The caller must ensure no other thread can still access the old + // value after this overwrite. + freefunc free_extra = interp->co_extra_freefuncs[index]; + if (free_extra != NULL) { + free_extra(old_slot_value); } } - co_extra->ce_extras[index] = extra; - return 0; + return result; } diff --git a/Python/ceval.c b/Python/ceval.c index 8e905a5e689ed9..2cd7c7bfd28d09 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3493,11 +3493,27 @@ PyUnstable_Eval_RequestCodeExtraIndex(freefunc free) PyInterpreterState *interp = _PyInterpreterState_GET(); Py_ssize_t new_index; - if (interp->co_extra_user_count == MAX_CO_EXTRA_USERS - 1) { +#ifdef Py_GIL_DISABLED + struct _py_code_state *state = &interp->code_state; + FT_MUTEX_LOCK(&state->mutex); +#endif + + if (interp->co_extra_user_count >= MAX_CO_EXTRA_USERS - 1) { +#ifdef Py_GIL_DISABLED + FT_MUTEX_UNLOCK(&state->mutex); +#endif return -1; } - new_index = interp->co_extra_user_count++; + + new_index = interp->co_extra_user_count; interp->co_extra_freefuncs[new_index] = free; + + // Publish freefuncs[new_index] before making the index visible. + FT_ATOMIC_STORE_SSIZE_RELEASE(interp->co_extra_user_count, new_index + 1); + +#ifdef Py_GIL_DISABLED + FT_MUTEX_UNLOCK(&state->mutex); +#endif return new_index; } From 75c57531996afabf3bc551c4add4ba1e9e9ce827 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 20 Feb 2026 19:02:14 +0000 Subject: [PATCH 181/498] Fix errors in `CODEOWNERS` (#145049) Fix erros in CODEOWNERS --- .github/CODEOWNERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f656e8e52cd3dc..1adbacbb7d1098 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -295,10 +295,10 @@ Tools/jit/ @brandtbucher @savannahostrowski @diegorusso InternalDocs/jit.md @brandtbucher @savannahostrowski @diegorusso @AA-Turner # Lazy imports (PEP 810) -Objects/lazyimportobject.c @twouters @DinoV @pablogsal -Include/internal/pycore_lazyimportobject.h @twouters @DinoV @pablogsal -Lib/test/test_import/test_lazy_imports.py @twouters @DinoV @pablogsal -Lib/test/test_import/data/lazy_imports/ @twouters @DinoV @pablogsal +Objects/lazyimportobject.c @yhg1s @DinoV @pablogsal +Include/internal/pycore_lazyimportobject.h @yhg1s @DinoV @pablogsal +Lib/test/test_import/test_lazy_imports.py @yhg1s @DinoV @pablogsal +Lib/test/test_import/data/lazy_imports/ @yhg1s @DinoV @pablogsal # Micro-op / μop / Tier 2 Optimiser Python/optimizer.c @markshannon @Fidget-Spinner From 70da972f97ec799dc7d7ab069fe195455f2f81b2 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 20 Feb 2026 14:31:58 -0500 Subject: [PATCH 182/498] gh-144809: Make deque copy atomic in free-threaded build (gh-144966) --- .../test_free_threading/test_collections.py | 29 ++++++++++++ ...-02-18-00-00-00.gh-issue-144809.nYpEUx.rst | 1 + Modules/_collectionsmodule.c | 45 ++++++++++++------- 3 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 Lib/test/test_free_threading/test_collections.py create mode 100644 Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst diff --git a/Lib/test/test_free_threading/test_collections.py b/Lib/test/test_free_threading/test_collections.py new file mode 100644 index 00000000000000..3a413ccf396d4b --- /dev/null +++ b/Lib/test/test_free_threading/test_collections.py @@ -0,0 +1,29 @@ +import unittest +from collections import deque +from copy import copy +from test.support import threading_helper + +threading_helper.requires_working_threading(module=True) + + +class TestDeque(unittest.TestCase): + def test_copy_race(self): + # gh-144809: Test that deque copy is thread safe. It previously + # could raise a "deque mutated during iteration" error. + d = deque(range(100)) + + def mutate(): + for i in range(1000): + d.append(i) + if len(d) > 200: + d.popleft() + + def copy_loop(): + for _ in range(1000): + copy(d) + + threading_helper.run_concurrently([mutate, copy_loop]) + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst b/Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst new file mode 100644 index 00000000000000..62c20b7fa06d94 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst @@ -0,0 +1 @@ +Make :class:`collections.deque` copy atomic in the :term:`free-threaded build`. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 45ca63e6d7c77f..72865f87fc484f 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -605,29 +605,42 @@ deque_copy_impl(dequeobject *deque) collections_state *state = find_module_state_by_def(Py_TYPE(deque)); if (Py_IS_TYPE(deque, state->deque_type)) { dequeobject *new_deque; - PyObject *rv; + Py_ssize_t n = Py_SIZE(deque); new_deque = (dequeobject *)deque_new(state->deque_type, NULL, NULL); if (new_deque == NULL) return NULL; new_deque->maxlen = old_deque->maxlen; - /* Fast path for the deque_repeat() common case where len(deque) == 1 - * - * It's safe to not acquire the per-object lock for new_deque; it's - * invisible to other threads. + + /* Copy elements directly by walking the block structure. + * This is safe because the caller holds the deque lock and + * the new deque is not yet visible to other threads. */ - if (Py_SIZE(deque) == 1) { - PyObject *item = old_deque->leftblock->data[old_deque->leftindex]; - rv = deque_append_impl(new_deque, item); - } else { - rv = deque_extend_impl(new_deque, (PyObject *)deque); - } - if (rv != NULL) { - Py_DECREF(rv); - return (PyObject *)new_deque; + if (n > 0) { + block *b = old_deque->leftblock; + Py_ssize_t index = old_deque->leftindex; + + /* Space saving heuristic. Start filling from the left */ + assert(new_deque->leftblock == new_deque->rightblock); + assert(new_deque->leftindex == new_deque->rightindex + 1); + new_deque->leftindex = 1; + new_deque->rightindex = 0; + + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *item = b->data[index]; + if (deque_append_lock_held(new_deque, Py_NewRef(item), + new_deque->maxlen) < 0) { + Py_DECREF(new_deque); + return NULL; + } + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } } - Py_DECREF(new_deque); - return NULL; + return (PyObject *)new_deque; } if (old_deque->maxlen < 0) result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), From 06292614ff7cef0ba28da6dfded58fb0e731b2e3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 20 Feb 2026 19:25:45 -0500 Subject: [PATCH 183/498] gh-144748: Document 3.12 and 3.14 changes to `PyErr_CheckSignals` (GH-144982) Co-authored-by: Petr Viktorin --- Doc/c-api/exceptions.rst | 52 +++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index a1cfb8872345cf..72b013612d77f5 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -673,28 +673,46 @@ Signal Handling single: SIGINT (C macro) single: KeyboardInterrupt (built-in exception) - This function interacts with Python's signal handling. + Handle external interruptions, such as signals or activating a debugger, + whose processing has been delayed until it is safe + to run Python code and/or raise exceptions. - If the function is called from the main thread and under the main Python - interpreter, it checks whether a signal has been sent to the processes - and if so, invokes the corresponding signal handler. If the :mod:`signal` - module is supported, this can invoke a signal handler written in Python. + For example, pressing :kbd:`Ctrl-C` causes a terminal to send the + :py:data:`signal.SIGINT` signal. + This function executes the corresponding Python signal handler, which, + by default, raises the :exc:`KeyboardInterrupt` exception. - The function attempts to handle all pending signals, and then returns ``0``. - However, if a Python signal handler raises an exception, the error - indicator is set and the function returns ``-1`` immediately (such that - other pending signals may not have been handled yet: they will be on the - next :c:func:`PyErr_CheckSignals()` invocation). + :c:func:`!PyErr_CheckSignals` should be called by long-running C code + frequently enough so that the response appears immediate to humans. - If the function is called from a non-main thread, or under a non-main - Python interpreter, it does nothing and returns ``0``. + Handlers invoked by this function currently include: - This function can be called by long-running C code that wants to - be interruptible by user requests (such as by pressing Ctrl-C). + - Signal handlers, including Python functions registered using + the :mod:`signal` module. - .. note:: - The default Python signal handler for :c:macro:`!SIGINT` raises the - :exc:`KeyboardInterrupt` exception. + Signal handlers are only run in the main thread of the main interpreter. + + (This is where the function got the name: originally, signals + were the only way to interrupt the interpreter.) + + - Running the garbage collector, if necessary. + + - Executing a pending :ref:`remote debugger ` script. + + If any handler raises an exception, immediately return ``-1`` with that + exception set. + Any remaining interruptions are left to be processed on the next + :c:func:`PyErr_CheckSignals()` invocation, if appropriate. + + If all handlers finish successfully, or there are no handlers to run, + return ``0``. + + .. versionchanged:: 3.12 + This function may now invoke the garbage collector. + + .. versionchanged:: 3.14 + This function may now execute a remote debugger script, if remote + debugging is enabled. .. c:function:: void PyErr_SetInterrupt() From 273d5062ca17ac47354486f3fc6e672a04cf22e0 Mon Sep 17 00:00:00 2001 From: Rafael Santos Date: Fri, 20 Feb 2026 22:57:29 -0600 Subject: [PATCH 184/498] gh-145028: Fix blake2 tests in test_hashlib when it is missing due to build config (GH-145029) specifically configure --without-builtin-hashlib-hashes means the otherwise guaranteed available blake2 family will not exist. this allows the test suite to still pass. --- Lib/test/test_hashlib.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 489bb049d2fadb..f0e2d527af2615 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -134,8 +134,11 @@ def __init__(self, *args, **kwargs): algorithms.add(algorithm.lower()) _blake2 = self._conditional_import_module('_blake2') + blake2_hashes = {'blake2b', 'blake2s'} if _blake2: - algorithms.update({'blake2b', 'blake2s'}) + algorithms.update(blake2_hashes) + else: + algorithms.difference_update(blake2_hashes) self.constructors_to_test = {} for algorithm in algorithms: @@ -232,7 +235,12 @@ def test_algorithms_available(self): # 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) + with self.subTest(name): + try: + _ = hashlib.new(name, usedforsecurity=False) + except ValueError as exc: + self.skip_if_blake2_not_builtin(name, exc) + raise def test_usedforsecurity_true(self): hashlib.new("sha256", usedforsecurity=True) @@ -504,6 +512,7 @@ def test_sha3_256_update_over_4gb(self): self.assertEqual(h.hexdigest(), "e2d4535e3b613135c14f2fe4e026d7ad8d569db44901740beffa30d430acb038") @requires_resource('cpu') + @requires_blake2 def test_blake2_update_over_4gb(self): # blake2s or blake2b doesn't matter based on how our C code is structured, this tests the # common loop macro logic. @@ -798,6 +807,12 @@ def test_case_sha512_3(self): "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b") + def skip_if_blake2_not_builtin(self, name, skip_reason): + # blake2 builtins may be absent if python built with + # a subset of --with-builtin-hashlib-hashes or none. + if "blake2" in name and "blake2" not in builtin_hashes: + self.skipTest(skip_reason) + def check_blake2(self, constructor, salt_size, person_size, key_size, digest_size, max_offset): self.assertEqual(constructor.SALT_SIZE, salt_size) @@ -1080,10 +1095,16 @@ def test_sha256_gil(self): def test_threaded_hashing_fast(self): # Same as test_threaded_hashing_slow() but only tests some functions # since otherwise test_hashlib.py becomes too slow during development. - for name in ['md5', 'sha1', 'sha256', 'sha3_256', 'blake2s']: + algos = ['md5', 'sha1', 'sha256', 'sha3_256', 'blake2s'] + for name in algos: if constructor := getattr(hashlib, name, None): with self.subTest(name): - self.do_test_threaded_hashing(constructor, is_shake=False) + try: + self.do_test_threaded_hashing(constructor, is_shake=False) + except ValueError as exc: + self.skip_if_blake2_not_builtin(name, exc) + raise + if shake_128 := getattr(hashlib, 'shake_128', None): self.do_test_threaded_hashing(shake_128, is_shake=True) From 85021bc2477f3ab394172b6dda3110e59f4777dd Mon Sep 17 00:00:00 2001 From: Mohsin Mehmood <55545648+mohsinm-dev@users.noreply.github.com> Date: Sat, 21 Feb 2026 10:36:26 +0500 Subject: [PATCH 185/498] gh-144694: Fix re.Match.group() doc claiming [1..99] range limit (#144696) The documentation incorrectly stated that numeric group arguments must be in the range [1..99]. This limit was removed in Python 3.5 (bpo-22437). Replace with "a positive integer" since the next sentence already documents the IndexError for out-of-range values. --- Doc/library/re.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index cc11d0205dc5cb..7edb85ca507722 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -1434,10 +1434,10 @@ when there is no match, you can test whether there was a match with a simple result is a single string; if there are multiple arguments, the result is a tuple with one item per argument. Without arguments, *group1* defaults to zero (the whole match is returned). If a *groupN* argument is zero, the corresponding - return value is the entire matching string; if it is in the inclusive range - [1..99], it is the string matching the corresponding parenthesized group. If a - group number is negative or larger than the number of groups defined in the - pattern, an :exc:`IndexError` exception is raised. If a group is contained in a + return value is the entire matching string; if it is a positive integer, it is + the string matching the corresponding parenthesized group. If a group number is + negative or larger than the number of groups defined in the pattern, an + :exc:`IndexError` exception is raised. If a group is contained in a part of the pattern that did not match, the corresponding result is ``None``. If a group is contained in a part of the pattern that matched multiple times, the last match is returned. :: From 20b1535ca40a5b93088cdbc669e86215f1630599 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 11:07:55 +0100 Subject: [PATCH 186/498] gh-141510, PEP 814: Add frozendict support to pickle (#144967) Add frozendict.__getnewargs__() method. --- Lib/test/picklecommon.py | 11 ++++++++ Lib/test/pickletester.py | 45 ++++++++++++++++++++++++++++++++- Lib/test/test_dict.py | 54 +++++++++++++++++++++++++++++++++++++--- Objects/dictobject.c | 13 ++++++++++ 4 files changed, 118 insertions(+), 5 deletions(-) diff --git a/Lib/test/picklecommon.py b/Lib/test/picklecommon.py index b749ee09f564bf..bb8e41b01492ea 100644 --- a/Lib/test/picklecommon.py +++ b/Lib/test/picklecommon.py @@ -263,6 +263,17 @@ class MyFrozenSet(frozenset): MyStr, MyUnicode, MyTuple, MyList, MyDict, MySet, MyFrozenSet] +try: + frozendict +except NameError: + # Python 3.14 and older + pass +else: + class MyFrozenDict(dict): + sample = frozendict({"a": 1, "b": 2}) + myclasses.append(MyFrozenDict) + + # For test_newobj_overridden_new class MyIntWithNew(int): def __new__(cls, value): diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 3d4ed8a2b6ee40..0624b6a0257829 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2839,11 +2839,13 @@ def test_recursive_multi(self): self.assertEqual(list(x[0].attr.keys()), [1]) self.assertIs(x[0].attr[1], x) - def _test_recursive_collection_and_inst(self, factory, oldminproto=None): + def _test_recursive_collection_and_inst(self, factory, oldminproto=None, + minprotocol=0): if self.py_version < (3, 0): self.skipTest('"classic" classes are not interoperable with Python 2') # Mutable object containing a collection containing the original # object. + protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1) o = Object() o.attr = factory([o]) t = type(o.attr) @@ -2883,6 +2885,11 @@ def test_recursive_tuple_and_inst(self): def test_recursive_dict_and_inst(self): self._test_recursive_collection_and_inst(dict.fromkeys, oldminproto=0) + def test_recursive_frozendict_and_inst(self): + if self.py_version < (3, 15): + self.skipTest('need frozendict') + self._test_recursive_collection_and_inst(frozendict.fromkeys, minprotocol=2) + def test_recursive_set_and_inst(self): self._test_recursive_collection_and_inst(set) @@ -2904,6 +2911,42 @@ def test_recursive_set_subclass_and_inst(self): def test_recursive_frozenset_subclass_and_inst(self): self._test_recursive_collection_and_inst(MyFrozenSet) + def _test_recursive_collection_in_key(self, factory, minprotocol=0): + protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1) + key = Object() + o = factory({key: 1}) + key.attr = o + for proto in protocols: + with self.subTest(proto=proto): + s = self.dumps(o, proto) + x = self.loads(s) + keys = list(x.keys()) + self.assertEqual(len(keys), 1) + self.assertIs(keys[0].attr, x) + + def test_recursive_frozendict_in_key(self): + self._test_recursive_collection_in_key(frozendict, minprotocol=2) + + def test_recursive_frozendict_subclass_in_key(self): + self._test_recursive_collection_in_key(MyFrozenDict) + + def _test_recursive_collection_in_value(self, factory, minprotocol=0): + protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1) + o = factory(key=[]) + o['key'].append(o) + for proto in protocols: + with self.subTest(proto=proto): + s = self.dumps(o, proto) + x = self.loads(s) + self.assertEqual(len(x['key']), 1) + self.assertIs(x['key'][0], x) + + def test_recursive_frozendict_in_value(self): + self._test_recursive_collection_in_value(frozendict, minprotocol=2) + + def test_recursive_frozendict_subclass_in_value(self): + self._test_recursive_collection_in_value(MyFrozenDict) + def test_recursive_inst_state(self): # Mutable object containing itself. y = REX_state() diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 71f72cb2557670..9cfaa4a86fa9fd 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1731,6 +1731,10 @@ class FrozenDict(frozendict): pass +class FrozenDictSlots(frozendict): + __slots__ = ('slot_attr',) + + class FrozenDictTests(unittest.TestCase): def test_copy(self): d = frozendict(x=1, y=2) @@ -1773,10 +1777,8 @@ def test_repr(self): d = frozendict(x=1, y=2) self.assertEqual(repr(d), "frozendict({'x': 1, 'y': 2})") - class MyFrozenDict(frozendict): - pass - d = MyFrozenDict(x=1, y=2) - self.assertEqual(repr(d), "MyFrozenDict({'x': 1, 'y': 2})") + d = FrozenDict(x=1, y=2) + self.assertEqual(repr(d), "FrozenDict({'x': 1, 'y': 2})") def test_hash(self): # hash() doesn't rely on the items order @@ -1825,6 +1827,50 @@ def __new__(self): self.assertEqual(type(fd), DictSubclass) self.assertEqual(created, frozendict(x=1)) + def test_pickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for fd in ( + frozendict(), + frozendict(x=1, y=2), + FrozenDict(x=1, y=2), + FrozenDictSlots(x=1, y=2), + ): + if type(fd) == FrozenDict: + fd.attr = 123 + if type(fd) == FrozenDictSlots: + fd.slot_attr = 456 + with self.subTest(fd=fd, proto=proto): + if proto >= 2: + p = pickle.dumps(fd, proto) + fd2 = pickle.loads(p) + self.assertEqual(fd2, fd) + self.assertEqual(type(fd2), type(fd)) + if type(fd) == FrozenDict: + self.assertEqual(fd2.attr, 123) + if type(fd) == FrozenDictSlots: + self.assertEqual(fd2.slot_attr, 456) + else: + # protocol 0 and 1 don't support frozendict + with self.assertRaises(TypeError): + pickle.dumps(fd, proto) + + def test_pickle_iter(self): + fd = frozendict(c=1, b=2, a=3, d=4, e=5, f=6) + for method_name in (None, 'keys', 'values', 'items'): + if method_name is not None: + meth = getattr(fd, method_name) + else: + meth = lambda: fd + expected = list(meth())[1:] + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(method_name=method_name, protocol=proto): + it = iter(meth()) + next(it) + p = pickle.dumps(it, proto) + unpickled = pickle.loads(p) + self.assertEqual(list(unpickled), expected) + self.assertEqual(list(it), expected) + if __name__ == "__main__": unittest.main() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index af3fcca7455470..8f960352fa4824 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -7930,6 +7930,18 @@ _PyObject_InlineValuesConsistencyCheck(PyObject *obj) // --- frozendict implementation --------------------------------------------- +static PyObject * +frozendict_getnewargs(PyObject *op, PyObject *Py_UNUSED(dummy)) +{ + // Call dict(op): convert 'op' frozendict to a dict + PyObject *arg = PyObject_CallOneArg((PyObject*)&PyDict_Type, op); + if (arg == NULL) { + return NULL; + } + return Py_BuildValue("(N)", arg); +} + + static PyNumberMethods frozendict_as_number = { .nb_or = frozendict_or, }; @@ -7951,6 +7963,7 @@ static PyMethodDef frozendict_methods[] = { DICT_COPY_METHODDEF DICT___REVERSED___METHODDEF {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, + {"__getnewargs__", frozendict_getnewargs, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; From 347fc438cf903c1d7fa5063464ae2e93c11b2232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:20:42 +0100 Subject: [PATCH 187/498] gh-143698: correctly check `scheduler` and `setpgroup` values for `os.posix_spawn[p]` (#143699) Fix an issue where passing invalid arguments to `os.posix_spawn[p]` functions raised a SystemError instead of a TypeError, and allow to explicitly use `None` for `scheduler` and `setpgroup` as specified in the docs. --- Lib/test/test_inspect/test_inspect.py | 3 +-- Lib/test/test_os/test_posix.py | 19 +++++++++++++++ ...-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst | 3 +++ ...-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst | 3 +++ Modules/clinic/posixmodule.c.h | 10 ++++---- Modules/posixmodule.c | 23 ++++++++++++------- 6 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst create mode 100644 Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 00cc5aab32c273..4ad32c649ea83c 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -6267,8 +6267,7 @@ def test_operator_module_has_signatures(self): def test_os_module_has_signatures(self): unsupported_signature = {'chmod', 'utime'} unsupported_signature |= {name for name in - ['get_terminal_size', 'link', 'posix_spawn', 'posix_spawnp', - 'register_at_fork', 'startfile'] + ['get_terminal_size', 'link', 'register_at_fork', 'startfile'] if hasattr(os, name)} self._test_module_has_signatures(os, unsupported_signature=unsupported_signature) diff --git a/Lib/test/test_os/test_posix.py b/Lib/test/test_os/test_posix.py index 995c48bdbbffd6..0e8495a4eff2ed 100644 --- a/Lib/test/test_os/test_posix.py +++ b/Lib/test/test_os/test_posix.py @@ -2008,6 +2008,11 @@ def test_setpgroup(self): ) support.wait_process(pid, exitcode=0) + def test_setpgroup_allow_none(self): + path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM + pid = self.spawn_func(path, args, os.environ, setpgroup=None) + support.wait_process(pid, exitcode=0) + def test_setpgroup_wrong_type(self): with self.assertRaises(TypeError): self.spawn_func(sys.executable, @@ -2108,6 +2113,20 @@ def test_setsigdef_wrong_type(self): [sys.executable, "-c", "pass"], os.environ, setsigdef=[signal.NSIG, signal.NSIG+1]) + def test_scheduler_allow_none(self): + path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM + pid = self.spawn_func(path, args, os.environ, scheduler=None) + support.wait_process(pid, exitcode=0) + + @support.subTests("scheduler", [object(), 1, [1, 2]]) + def test_scheduler_wrong_type(self, scheduler): + path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM + with self.assertRaisesRegex( + TypeError, + "scheduler must be a tuple or None", + ): + self.spawn_func(path, args, os.environ, scheduler=scheduler) + @requires_sched @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')), "bpo-34685: test can fail on BSD") diff --git a/Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst b/Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst new file mode 100644 index 00000000000000..05dc4941c98a83 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst @@ -0,0 +1,3 @@ +Raise :exc:`TypeError` instead of :exc:`SystemError` when the *scheduler* +in :func:`os.posix_spawn` or :func:`os.posix_spawnp` is not a tuple. +Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst b/Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst new file mode 100644 index 00000000000000..5f95b0de7d8895 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst @@ -0,0 +1,3 @@ +Allow *scheduler* and *setpgroup* arguments to be explicitly :const:`None` +when calling :func:`os.posix_spawn` or :func:`os.posix_spawnp`. Patch by +Bénédikt Tran. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index c4f498d233164c..ad4c5dd1c9bc08 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -3910,8 +3910,8 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k PyDoc_STRVAR(os_posix_spawn__doc__, "posix_spawn($module, path, argv, env, /, *, file_actions=(),\n" -" setpgroup=, resetids=False, setsid=False,\n" -" setsigmask=(), setsigdef=(), scheduler=)\n" +" setpgroup=None, resetids=False, setsid=False,\n" +" setsigmask=(), setsigdef=(), scheduler=None)\n" "--\n" "\n" "Execute the program specified by path in a new process.\n" @@ -4063,8 +4063,8 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyDoc_STRVAR(os_posix_spawnp__doc__, "posix_spawnp($module, path, argv, env, /, *, file_actions=(),\n" -" setpgroup=, resetids=False, setsid=False,\n" -" setsigmask=(), setsigdef=(), scheduler=)\n" +" setpgroup=None, resetids=False, setsid=False,\n" +" setsigmask=(), setsigdef=(), scheduler=None)\n" "--\n" "\n" "Execute the program specified by path in a new process.\n" @@ -13611,4 +13611,4 @@ os__emscripten_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py #ifndef OS__EMSCRIPTEN_LOG_METHODDEF #define OS__EMSCRIPTEN_LOG_METHODDEF #endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */ -/*[clinic end generated code: output=89c21e2151ac7316 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e709b8b783fbc261 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 072027fa0f6174..8d38e034aa6b5e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7611,6 +7611,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg PyObject *setsigdef, PyObject *scheduler, posix_spawnattr_t *attrp) { + assert(scheduler == NULL || scheduler == Py_None || PyTuple_Check(scheduler)); long all_flags = 0; errno = posix_spawnattr_init(attrp); @@ -7619,7 +7620,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg return -1; } - if (setpgroup) { + if (setpgroup && setpgroup != Py_None) { pid_t pgid = PyLong_AsPid(setpgroup); if (pgid == (pid_t)-1 && PyErr_Occurred()) { goto fail; @@ -7692,7 +7693,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg } #endif - if (scheduler) { + if (scheduler && scheduler != Py_None) { #ifdef POSIX_SPAWN_SETSCHEDULER PyObject *py_schedpolicy; PyObject *schedparam_obj; @@ -7917,6 +7918,12 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a goto exit; } + if (scheduler && !PyTuple_Check(scheduler) && scheduler != Py_None) { + PyErr_Format(PyExc_TypeError, + "%s: scheduler must be a tuple or None", func_name); + goto exit; + } + argvlist = parse_arglist(argv, &argc); if (argvlist == NULL) { goto exit; @@ -8028,7 +8035,7 @@ os.posix_spawn * file_actions: object(c_default='NULL') = () A sequence of file action tuples. - setpgroup: object = NULL + setpgroup: object(c_default='NULL') = None The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. resetids: bool = False If the value is `true` the POSIX_SPAWN_RESETIDS will be activated. @@ -8038,7 +8045,7 @@ os.posix_spawn The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. setsigdef: object(c_default='NULL') = () The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. - scheduler: object = NULL + scheduler: object(c_default='NULL') = None A tuple with the scheduler policy (optional) and parameters. Execute the program specified by path in a new process. @@ -8050,7 +8057,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=14a1098c566bc675 input=808aed1090d84e33]*/ +/*[clinic end generated code: output=14a1098c566bc675 input=69e7c9ebbdcf94a5]*/ { return py_posix_spawn(0, module, path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, @@ -8074,7 +8081,7 @@ os.posix_spawnp * file_actions: object(c_default='NULL') = () A sequence of file action tuples. - setpgroup: object = NULL + setpgroup: object(c_default='NULL') = None The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. resetids: bool = False If the value is `True` the POSIX_SPAWN_RESETIDS will be activated. @@ -8084,7 +8091,7 @@ os.posix_spawnp The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. setsigdef: object(c_default='NULL') = () The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. - scheduler: object = NULL + scheduler: object(c_default='NULL') = None A tuple with the scheduler policy (optional) and parameters. Execute the program specified by path in a new process. @@ -8096,7 +8103,7 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=7b9aaefe3031238d input=9e89e616116752a1]*/ +/*[clinic end generated code: output=7b9aaefe3031238d input=a5c057527c6881a5]*/ { return py_posix_spawn(1, module, path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, From 7b0bd9eb91ce0d4546c6d6f537eea558d1bf5fc8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 12:22:47 +0100 Subject: [PATCH 188/498] gh-141510, PEP 814: Add frozendict support to json (#144903) --- Lib/json/encoder.py | 8 ++++---- Lib/test/test_json/test_dump.py | 12 ++++++++++++ .../2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst | 2 ++ Modules/_json.c | 4 ++-- 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py index 4c70e8b75ed132..718b3254241c56 100644 --- a/Lib/json/encoder.py +++ b/Lib/json/encoder.py @@ -79,7 +79,7 @@ class JSONEncoder(object): +-------------------+---------------+ | Python | JSON | +===================+===============+ - | dict | object | + | dict, frozendict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ @@ -308,7 +308,7 @@ def _iterencode_list(lst, _current_indent_level): yield buf if isinstance(value, (list, tuple)): chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): + elif isinstance(value, (dict, frozendict)): chunks = _iterencode_dict(value, _current_indent_level) else: chunks = _iterencode(value, _current_indent_level) @@ -395,7 +395,7 @@ def _iterencode_dict(dct, _current_indent_level): else: if isinstance(value, (list, tuple)): chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): + elif isinstance(value, (dict, frozendict)): chunks = _iterencode_dict(value, _current_indent_level) else: chunks = _iterencode(value, _current_indent_level) @@ -429,7 +429,7 @@ def _iterencode(o, _current_indent_level): yield _floatstr(o) elif isinstance(o, (list, tuple)): yield from _iterencode_list(o, _current_indent_level) - elif isinstance(o, dict): + elif isinstance(o, (dict, frozendict)): yield from _iterencode_dict(o, _current_indent_level) else: if markers is not None: diff --git a/Lib/test/test_json/test_dump.py b/Lib/test/test_json/test_dump.py index 39470754003bb6..9880698455ca5e 100644 --- a/Lib/test/test_json/test_dump.py +++ b/Lib/test/test_json/test_dump.py @@ -12,6 +12,18 @@ def test_dump(self): def test_dumps(self): self.assertEqual(self.dumps({}), '{}') + def test_dumps_dict(self): + self.assertEqual(self.dumps({'x': 1, 'y': 2}), + '{"x": 1, "y": 2}') + self.assertEqual(self.dumps(frozendict({'x': 1, 'y': 2})), + '{"x": 1, "y": 2}') + lst = [{'x': 1}, frozendict(y=2)] + self.assertEqual(self.dumps(lst), + '[{"x": 1}, {"y": 2}]') + data = {'x': dict(a=1), 'y': frozendict(b=2)} + self.assertEqual(self.dumps(data), + '{"x": {"a": 1}, "y": {"b": 2}}') + def test_dump_skipkeys(self): v = {b'invalid_key': False, 'valid_key': True} with self.assertRaises(TypeError): diff --git a/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst b/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst new file mode 100644 index 00000000000000..59a8b4165cdd15 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst @@ -0,0 +1,2 @@ +The :mod:`json` module now supports the :class:`frozendict` type. Patch by +Victor Stinner. diff --git a/Modules/_json.c b/Modules/_json.c index c7e62c4fe55c64..cbede8f44dc065 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1599,7 +1599,7 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, _Py_LeaveRecursiveCall(); return rv; } - else if (PyDict_Check(obj)) { + else if (PyAnyDict_Check(obj)) { if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; rv = encoder_listencode_dict(s, writer, obj, indent_level, indent_cache); @@ -1838,7 +1838,7 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer, goto bail; } - if (s->sort_keys || !PyDict_CheckExact(dct)) { + if (s->sort_keys || !PyAnyDict_CheckExact(dct)) { PyObject *items = PyMapping_Items(dct); if (items == NULL || (s->sort_keys && PyList_Sort(items) < 0)) { Py_XDECREF(items); From 3a2a686cc45de2fb685ff332b7b914f27f660680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:31:16 +0100 Subject: [PATCH 189/498] gh-142516: fix reference leaks in `ssl.SSLContext` objects (#143685) --- Lib/test/test_ssl.py | 106 +++++++++++++++--- ...-01-11-13-03-32.gh-issue-142516.u7An-s.rst | 2 + Modules/_ssl.c | 25 ++++- 3 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 7e9ba735b3ce66..dc795c6bd8a41f 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -57,6 +57,16 @@ CAN_GET_SELECTED_OPENSSL_SIGALG = ssl.OPENSSL_VERSION_INFO >= (3, 5) PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') +HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename') +requires_keylog = unittest.skipUnless( + HAS_KEYLOG, 'test requires OpenSSL 1.1.1 with keylog callback') +CAN_SET_KEYLOG = HAS_KEYLOG and os.name != "nt" +requires_keylog_setter = unittest.skipUnless( + CAN_SET_KEYLOG, + "cannot set 'keylog_filename' on Windows" +) + + PROTOCOL_TO_TLS_VERSION = {} for proto, ver in ( ("PROTOCOL_SSLv3", "SSLv3"), @@ -266,34 +276,69 @@ def utc_offset(): #NOTE: ignore issues like #1647654 ) -def test_wrap_socket(sock, *, - cert_reqs=ssl.CERT_NONE, ca_certs=None, - ciphers=None, ciphersuites=None, - min_version=None, max_version=None, - certfile=None, keyfile=None, - **kwargs): - if not kwargs.get("server_side"): - kwargs["server_hostname"] = SIGNED_CERTFILE_HOSTNAME - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - else: +def make_test_context( + *, + server_side=False, + check_hostname=None, + cert_reqs=ssl.CERT_NONE, + ca_certs=None, certfile=None, keyfile=None, + ciphers=None, ciphersuites=None, + min_version=None, max_version=None, +): + if server_side: context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - if cert_reqs is not None: + else: + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + + if check_hostname is None: if cert_reqs == ssl.CERT_NONE: context.check_hostname = False + else: + context.check_hostname = check_hostname + + if cert_reqs is not None: context.verify_mode = cert_reqs + if ca_certs is not None: context.load_verify_locations(ca_certs) if certfile is not None or keyfile is not None: context.load_cert_chain(certfile, keyfile) + if ciphers is not None: context.set_ciphers(ciphers) if ciphersuites is not None: context.set_ciphersuites(ciphersuites) + if min_version is not None: context.minimum_version = min_version if max_version is not None: context.maximum_version = max_version - return context.wrap_socket(sock, **kwargs) + + return context + + +def test_wrap_socket( + sock, + *, + server_side=False, + check_hostname=None, + cert_reqs=ssl.CERT_NONE, + ca_certs=None, certfile=None, keyfile=None, + ciphers=None, ciphersuites=None, + min_version=None, max_version=None, + **kwargs, +): + context = make_test_context( + server_side=server_side, + check_hostname=check_hostname, + cert_reqs=cert_reqs, + ca_certs=ca_certs, certfile=certfile, keyfile=keyfile, + ciphers=ciphers, ciphersuites=ciphersuites, + min_version=min_version, max_version=max_version, + ) + if not server_side: + kwargs.setdefault("server_hostname", SIGNED_CERTFILE_HOSTNAME) + return context.wrap_socket(sock, server_side=server_side, **kwargs) USE_SAME_TEST_CONTEXT = False @@ -1741,6 +1786,39 @@ def test_num_tickest(self): with self.assertRaises(ValueError): ctx.num_tickets = 1 + @support.cpython_only + def test_refcycle_msg_callback(self): + # See https://github.com/python/cpython/issues/142516. + ctx = make_test_context() + def msg_callback(*args, _=ctx, **kwargs): ... + ctx._msg_callback = msg_callback + + @support.cpython_only + @requires_keylog_setter + def test_refcycle_keylog_filename(self): + # See https://github.com/python/cpython/issues/142516. + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + ctx = make_test_context() + class KeylogFilename(str): ... + ctx.keylog_filename = KeylogFilename(os_helper.TESTFN) + ctx.keylog_filename._ = ctx + + @support.cpython_only + @unittest.skipUnless(ssl.HAS_PSK, 'requires TLS-PSK') + def test_refcycle_psk_client_callback(self): + # See https://github.com/python/cpython/issues/142516. + ctx = make_test_context() + def psk_client_callback(*args, _=ctx, **kwargs): ... + ctx.set_psk_client_callback(psk_client_callback) + + @support.cpython_only + @unittest.skipUnless(ssl.HAS_PSK, 'requires TLS-PSK') + def test_refcycle_psk_server_callback(self): + # See https://github.com/python/cpython/issues/142516. + ctx = make_test_context(server_side=True) + def psk_server_callback(*args, _=ctx, **kwargs): ... + ctx.set_psk_server_callback(psk_server_callback) + class SSLErrorTests(unittest.TestCase): @@ -5174,10 +5252,6 @@ def test_internal_chain_server(self): self.assertEqual(res, b'\x02\n') -HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename') -requires_keylog = unittest.skipUnless( - HAS_KEYLOG, 'test requires OpenSSL 1.1.1 with keylog callback') - class TestSSLDebug(unittest.TestCase): def keylog_lines(self, fname=os_helper.TESTFN): diff --git a/Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst b/Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst new file mode 100644 index 00000000000000..efa7c8a1f62692 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst @@ -0,0 +1,2 @@ +:mod:`ssl`: fix reference leaks in :class:`ssl.SSLContext` objects. Patch by +Bénédikt Tran. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b0c0d8deeecd23..2eb31229a9bf3c 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -331,7 +331,7 @@ typedef struct { int post_handshake_auth; #endif PyObject *msg_cb; - PyObject *keylog_filename; + PyObject *keylog_filename; // can be anything accepted by Py_fopen() BIO *keylog_bio; /* Cached module state, also used in SSLSocket and SSLSession code. */ _sslmodulestate *state; @@ -361,7 +361,7 @@ typedef struct { PySSLContext *ctx; /* weakref to SSL context */ char shutdown_seen_zero; enum py_ssl_server_or_client socket_type; - PyObject *owner; /* Python level "owner" passed to servername callback */ + PyObject *owner; /* weakref to Python level "owner" passed to servername callback */ PyObject *server_hostname; } PySSLSocket; @@ -2436,6 +2436,17 @@ PySSL_traverse(PyObject *op, visitproc visit, void *arg) return 0; } +static int +PySSL_clear(PyObject *op) +{ + PySSLSocket *self = PySSLSocket_CAST(op); + Py_CLEAR(self->Socket); + Py_CLEAR(self->ctx); + Py_CLEAR(self->owner); + Py_CLEAR(self->server_hostname); + return 0; +} + static void PySSL_dealloc(PyObject *op) { @@ -2456,10 +2467,7 @@ PySSL_dealloc(PyObject *op) SSL_set_shutdown(self->ssl, SSL_SENT_SHUTDOWN | SSL_get_shutdown(self->ssl)); SSL_free(self->ssl); } - Py_XDECREF(self->Socket); - Py_XDECREF(self->ctx); - Py_XDECREF(self->server_hostname); - Py_XDECREF(self->owner); + (void)PySSL_clear(op); PyObject_GC_Del(self); Py_DECREF(tp); } @@ -3568,6 +3576,11 @@ context_traverse(PyObject *op, visitproc visit, void *arg) PySSLContext *self = PySSLContext_CAST(op); Py_VISIT(self->set_sni_cb); Py_VISIT(self->msg_cb); + Py_VISIT(self->keylog_filename); +#ifndef OPENSSL_NO_PSK + Py_VISIT(self->psk_client_callback); + Py_VISIT(self->psk_server_callback); +#endif Py_VISIT(Py_TYPE(self)); return 0; } From 34f4fa8425afed341e44921033b130ba7d099337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:42:13 +0100 Subject: [PATCH 190/498] gh-141226: Deprecate PEP-456 support for embedders (#141287) Deprecate PEP-456 [1] support for providing an external definition of the string hashing scheme. Removal is scheduled for Python 3.19. Previously, embedders could define the ``Py_HASH_ALGORITHM`` macro to be ``Py_HASH_EXTERNAL`` [2] to indicate that the hashing scheme was provided externally but this feature was undocumented, untested and most likely unused. [1]: https://peps.python.org/pep-0456/ [2]: https://peps.python.org/pep-0456/#hash-function-selection --- Doc/deprecations/c-api-pending-removal-in-3.19.rst | 4 ++++ Doc/deprecations/index.rst | 4 ++++ Doc/whatsnew/3.15.rst | 10 ++++++++++ .../2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst | 3 +++ Python/pyhash.c | 2 +- 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Doc/deprecations/c-api-pending-removal-in-3.19.rst create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst diff --git a/Doc/deprecations/c-api-pending-removal-in-3.19.rst b/Doc/deprecations/c-api-pending-removal-in-3.19.rst new file mode 100644 index 00000000000000..ac9dcb8b424a17 --- /dev/null +++ b/Doc/deprecations/c-api-pending-removal-in-3.19.rst @@ -0,0 +1,4 @@ +Pending removal in Python 3.19 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* :pep:`456` embedders support for the string hashing scheme definition. diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst index c91c64a1092457..bb8bfb5c227c2d 100644 --- a/Doc/deprecations/index.rst +++ b/Doc/deprecations/index.rst @@ -20,8 +20,12 @@ C API deprecations .. include:: c-api-pending-removal-in-3.15.rst +.. include:: c-api-pending-removal-in-3.16.rst + .. include:: c-api-pending-removal-in-3.18.rst +.. include:: c-api-pending-removal-in-3.19.rst + .. include:: c-api-pending-removal-in-3.20.rst .. include:: c-api-pending-removal-in-future.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index feccc496fad0e0..4aac6c453f533d 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1723,6 +1723,16 @@ on Python 3.13 and older. Deprecated C APIs ----------------- +* Deprecate :pep:`456` support for providing an external definition + of the string hashing scheme. Removal is scheduled for Python 3.19. + + Previously, embedders could define :c:macro:`Py_HASH_ALGORITHM` to be + ``Py_HASH_EXTERNAL`` to indicate that the hashing scheme was provided + externally but this feature was undocumented, untested and most likely + unused. + + (Contributed by Bénédikt Tran in :gh:`141226`.) + * For unsigned integer formats in :c:func:`PyArg_ParseTuple`, accepting Python integers with value that is larger than the maximal value for the C type or less than the minimal value for the corresponding diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst new file mode 100644 index 00000000000000..3f7ce7326187d4 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst @@ -0,0 +1,3 @@ +Deprecate :pep:`456` support for providing an external definition +of the string hashing scheme. Removal is scheduled for Python 3.19. +Patch by Bénédikt Tran. diff --git a/Python/pyhash.c b/Python/pyhash.c index 157312a936bbcc..1eb890794a7544 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -17,7 +17,7 @@ _Py_HashSecret_t _Py_HashSecret = {{0}}; #if Py_HASH_ALGORITHM == Py_HASH_EXTERNAL -extern PyHash_FuncDef PyHash_Func; +Py_DEPRECATED(3.15) extern PyHash_FuncDef PyHash_Func; #else static PyHash_FuncDef PyHash_Func; #endif From 2133e16bfe6d0a93c26873e82fd52a27bbf75774 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 13:05:35 +0100 Subject: [PATCH 191/498] gh-141510: Fix test_xpickle for Python 3.14 and older (#145069) Skip tests on frozendict on Python 3.14 and older. --- Lib/test/pickletester.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 0624b6a0257829..6ac4b19da3ea9c 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2925,9 +2925,13 @@ def _test_recursive_collection_in_key(self, factory, minprotocol=0): self.assertIs(keys[0].attr, x) def test_recursive_frozendict_in_key(self): + if self.py_version < (3, 15): + self.skipTest('need frozendict') self._test_recursive_collection_in_key(frozendict, minprotocol=2) def test_recursive_frozendict_subclass_in_key(self): + if self.py_version < (3, 15): + self.skipTest('need frozendict') self._test_recursive_collection_in_key(MyFrozenDict) def _test_recursive_collection_in_value(self, factory, minprotocol=0): @@ -2942,9 +2946,13 @@ def _test_recursive_collection_in_value(self, factory, minprotocol=0): self.assertIs(x['key'][0], x) def test_recursive_frozendict_in_value(self): + if self.py_version < (3, 15): + self.skipTest('need frozendict') self._test_recursive_collection_in_value(frozendict, minprotocol=2) def test_recursive_frozendict_subclass_in_value(self): + if self.py_version < (3, 15): + self.skipTest('need frozendict') self._test_recursive_collection_in_value(MyFrozenDict) def test_recursive_inst_state(self): @@ -3437,6 +3445,8 @@ def test_newobj_generic(self): self.skipTest('int and str subclasses are not interoperable with Python 2') if (3, 0) <= self.py_version < (3, 4) and proto < 2 and C in (MyStr, MyUnicode): self.skipTest('str subclasses are not interoperable with Python < 3.4') + if self.py_version < (3, 15) and C == MyFrozenDict: + self.skipTest('frozendict is not available on Python < 3.15') B = C.__base__ x = C(C.sample) x.foo = 42 @@ -3458,6 +3468,8 @@ def test_newobj_proxies(self): with self.subTest(proto=proto, C=C): if self.py_version < (3, 4) and proto < 3 and C in (MyStr, MyUnicode): self.skipTest('str subclasses are not interoperable with Python < 3.4') + if self.py_version < (3, 15) and C == MyFrozenDict: + self.skipTest('frozendict is not available on Python < 3.15') B = C.__base__ x = C(C.sample) x.foo = 42 From 0499a0c17f59178dee4513323268c00f60939cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Sat, 21 Feb 2026 13:50:55 +0100 Subject: [PATCH 192/498] gh-144285: Update *What's New* entry after GH-144299 (#145077) --- Doc/whatsnew/3.15.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 4aac6c453f533d..fa3ba25a954e40 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -403,7 +403,7 @@ Improved error messages File "/home/pablogsal/github/python/main/lel.py", line 42, in print(container.area) ^^^^^^^^^^^^^^ - AttributeError: 'Container' object has no attribute 'area'. Did you mean: 'inner.area'? + AttributeError: 'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'? Other language changes From e1bd0cd37b1816092761e5ad5f2d0464c0e78fbb Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:52:40 +0000 Subject: [PATCH 193/498] gh-145058: Add input validation to `_PyImport_LazyImportModuleLevelObject` (#145068) --- Lib/test/test_import/test_lazy_imports.py | 9 +++++++++ .../2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst | 2 ++ Python/import.c | 11 +++++++++++ 3 files changed, 22 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py index a4c9c14ae2b5f8..dc185c070acc62 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_import/test_lazy_imports.py @@ -393,6 +393,15 @@ def test_dunder_lazy_import_used(self): import test.test_import.data.lazy_imports.dunder_lazy_import_used self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + def test_dunder_lazy_import_invalid_arguments(self): + """__lazy_import__ should reject invalid arguments.""" + for invalid_name in (b"", 123, None): + with self.assertRaises(TypeError): + __lazy_import__(invalid_name) + + with self.assertRaises(ValueError): + __lazy_import__("sys", level=-1) + def test_dunder_lazy_import_builtins(self): """__lazy_import__ should use module's __builtins__ for __import__.""" from test.test_import.data.lazy_imports import dunder_lazy_import_builtins diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst new file mode 100644 index 00000000000000..05eb296f96ec6d --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst @@ -0,0 +1,2 @@ +Fix a crash when :func:`!__lazy_import__` is passed a non-string argument, +by raising an :exc:`TypeError` instead. diff --git a/Python/import.c b/Python/import.c index c20c55727d2f94..4c234a4a70437c 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4468,6 +4468,17 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { + assert(name != NULL); + if (!PyUnicode_Check(name)) { + _PyErr_Format(tstate, PyExc_TypeError, + "module name must be a string, got %T", name); + return NULL; + } + if (level < 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0"); + return NULL; + } + PyObject *abs_name = get_abs_name(tstate, name, globals, level); if (abs_name == NULL) { return NULL; From 7258dbc51803e27c1fec7b2a402e297187de3b95 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 21 Feb 2026 08:14:53 -0600 Subject: [PATCH 194/498] Use `lazy` imports in `collections` (gh-145054) --- Lib/collections/__init__.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 55ffc36ea5b0c7..2eee4c70955513 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -32,6 +32,8 @@ _sys.modules['collections.abc'] = _collections_abc abc = _collections_abc +lazy from copy import copy as _copy +lazy from heapq import nlargest as _nlargest from itertools import chain as _chain from itertools import repeat as _repeat from itertools import starmap as _starmap @@ -59,8 +61,6 @@ except ImportError: pass -heapq = None # Lazily imported - ################################################################################ ### OrderedDict @@ -634,12 +634,7 @@ def most_common(self, n=None): if n is None: return sorted(self.items(), key=_itemgetter(1), reverse=True) - # Lazy import to speedup Python startup time - global heapq - if heapq is None: - import heapq - - return heapq.nlargest(n, self.items(), key=_itemgetter(1)) + return _nlargest(n, self.items(), key=_itemgetter(1)) def elements(self): '''Iterator over elements repeating each as many times as its count. @@ -1249,11 +1244,10 @@ def __copy__(self): def copy(self): if self.__class__ is UserDict: return UserDict(self.data.copy()) - import copy data = self.data try: self.data = {} - c = copy.copy(self) + c = _copy(self) finally: self.data = data c.update(self) From 646bd86e3b2f4f484129bd4a926cf73fafc9f874 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 16:30:40 +0100 Subject: [PATCH 195/498] gh-141510: Fix copy.deepcopy() for recursive frozendict (#145027) --- Lib/copy.py | 12 +++++++++++- Lib/test/test_copy.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Lib/copy.py b/Lib/copy.py index 33dabb3395a7c0..6149301ad1389e 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -204,7 +204,17 @@ def _deepcopy_dict(x, memo, deepcopy=deepcopy): d[dict] = _deepcopy_dict def _deepcopy_frozendict(x, memo, deepcopy=deepcopy): - y = _deepcopy_dict(x, memo, deepcopy) + y = {} + for key, value in x.items(): + y[deepcopy(key, memo)] = deepcopy(value, memo) + + # We're not going to put the frozendict in the memo, but it's still + # important we check for it, in case the frozendict contains recursive + # mutable structures. + try: + return memo[id(x)] + except KeyError: + pass return frozendict(y) d[frozendict] = _deepcopy_frozendict diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index 858e5e089d5aba..98f56b5ae87f96 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -432,6 +432,23 @@ def test_deepcopy_frozendict(self): self.assertIsNot(x, y) self.assertIsNot(x["foo"], y["foo"]) + # recursive frozendict + x = frozendict(foo=[]) + x['foo'].append(x) + y = copy.deepcopy(x) + self.assertEqual(y.keys(), x.keys()) + self.assertIsNot(x, y) + self.assertIsNot(x["foo"], y["foo"]) + self.assertIs(y['foo'][0], y) + + x = frozendict(foo=[]) + x['foo'].append(x) + x = x['foo'] + y = copy.deepcopy(x) + self.assertIsNot(x, y) + self.assertIsNot(x[0], y[0]) + self.assertIs(y[0]['foo'], y) + @support.skip_emscripten_stack_overflow() @support.skip_wasi_stack_overflow() def test_deepcopy_reflexive_dict(self): From 9e083b57eeb0282f8c5f7bbeec3750b51cf80dcc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 17:00:23 +0100 Subject: [PATCH 196/498] gh-141510: Test frozendict C API (#145081) Add tests on functions: * PyAnyDict_Check() * PyAnyDict_CheckExact() * PyFrozenDict_Check() * PyFrozenDict_CheckExact() * PyFrozenDict_New() --- Lib/test/test_capi/test_dict.py | 68 +++++++++++++++++++++++++++++++++ Modules/_testcapi/dict.c | 42 ++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index e726e3d813d888..bdd7aa9819fc48 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -26,6 +26,19 @@ def gen(): yield 'c' +class FrozenDictSubclass(frozendict): + pass + + +DICT_TYPES = (dict, DictSubclass, OrderedDict) +FROZENDICT_TYPES = (frozendict, FrozenDictSubclass) +ANYDICT_TYPES = DICT_TYPES + FROZENDICT_TYPES +MAPPING_TYPES = (UserDict,) +NOT_FROZENDICT_TYPES = DICT_TYPES + MAPPING_TYPES +NOT_ANYDICT_TYPES = MAPPING_TYPES +OTHER_TYPES = (lambda: [1], lambda: 42, object) # (list, int, object) + + class CAPITest(unittest.TestCase): def test_dict_check(self): @@ -545,6 +558,61 @@ def test_dict_popstring(self): # CRASHES dict_popstring({}, NULL) # CRASHES dict_popstring({"a": 1}, NULL) + def test_frozendict_check(self): + # Test PyFrozenDict_Check() + check = _testcapi.frozendict_check + for dict_type in FROZENDICT_TYPES: + self.assertTrue(check(dict_type(x=1))) + for dict_type in NOT_FROZENDICT_TYPES + OTHER_TYPES: + self.assertFalse(check(dict_type())) + # CRASHES check(NULL) + + def test_frozendict_checkexact(self): + # Test PyFrozenDict_CheckExact() + check = _testcapi.frozendict_checkexact + for dict_type in FROZENDICT_TYPES: + self.assertEqual(check(dict_type(x=1)), dict_type == frozendict) + for dict_type in NOT_FROZENDICT_TYPES + OTHER_TYPES: + self.assertFalse(check(dict_type())) + # CRASHES check(NULL) + + def test_anydict_check(self): + # Test PyAnyDict_Check() + check = _testcapi.anydict_check + for dict_type in ANYDICT_TYPES: + self.assertTrue(check(dict_type({1: 2}))) + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertFalse(check(test_type())) + # CRASHES check(NULL) + + def test_anydict_checkexact(self): + # Test PyAnyDict_CheckExact() + check = _testcapi.anydict_checkexact + for dict_type in ANYDICT_TYPES: + self.assertEqual(check(dict_type(x=1)), + dict_type in (dict, frozendict)) + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertFalse(check(test_type())) + # CRASHES check(NULL) + + def test_frozendict_new(self): + # Test PyFrozenDict_New() + frozendict_new = _testcapi.frozendict_new + + for dict_type in ANYDICT_TYPES: + dct = frozendict_new(dict_type({'x': 1})) + self.assertEqual(dct, frozendict(x=1)) + self.assertIs(type(dct), frozendict) + + dct = frozendict_new([('x', 1), ('y', 2)]) + self.assertEqual(dct, frozendict(x=1, y=2)) + self.assertIs(type(dct), frozendict) + + # PyFrozenDict_New(NULL) creates an empty dictionary + dct = frozendict_new(NULL) + self.assertEqual(dct, frozendict()) + self.assertIs(type(dct), frozendict) + if __name__ == "__main__": unittest.main() diff --git a/Modules/_testcapi/dict.c b/Modules/_testcapi/dict.c index b7c73d7332bd4e..172591b03182ab 100644 --- a/Modules/_testcapi/dict.c +++ b/Modules/_testcapi/dict.c @@ -258,6 +258,43 @@ test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored)) } +static PyObject * +frozendict_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyFrozenDict_Check(obj)); +} + +static PyObject * +frozendict_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyFrozenDict_CheckExact(obj)); +} + +static PyObject * +anydict_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyAnyDict_Check(obj)); +} + +static PyObject * +anydict_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyAnyDict_CheckExact(obj)); +} + + +static PyObject * +frozendict_new(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyFrozenDict_New(obj); +} + + static PyMethodDef test_methods[] = { {"dict_containsstring", dict_containsstring, METH_VARARGS}, {"dict_getitemref", dict_getitemref, METH_VARARGS}, @@ -269,6 +306,11 @@ static PyMethodDef test_methods[] = { {"dict_popstring", dict_popstring, METH_VARARGS}, {"dict_popstring_null", dict_popstring_null, METH_VARARGS}, {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, + {"frozendict_check", frozendict_check, METH_O}, + {"frozendict_checkexact", frozendict_checkexact, METH_O}, + {"anydict_check", anydict_check, METH_O}, + {"anydict_checkexact", anydict_checkexact, METH_O}, + {"frozendict_new", frozendict_new, METH_O}, {NULL}, }; From 770d354549914e3538e7db07e537dab17ece2610 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 17:08:24 +0100 Subject: [PATCH 197/498] gh-141510: Support frozendict in pprint (#144908) Co-authored-by: devdanzin <74280297+devdanzin@users.noreply.github.com> --- Lib/pprint.py | 34 ++++++++++++++++++++++++++++++---- Lib/test/test_pprint.py | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/Lib/pprint.py b/Lib/pprint.py index 92a2c543ac279c..e111bd59d4152c 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -235,6 +235,20 @@ def _pprint_dict(self, object, stream, indent, allowance, context, level): _dispatch[dict.__repr__] = _pprint_dict + def _pprint_frozendict(self, object, stream, indent, allowance, context, level): + write = stream.write + cls = object.__class__ + stream.write(cls.__name__ + '(') + length = len(object) + if length: + self._pprint_dict(object, stream, + indent + len(cls.__name__) + 1, + allowance + 1, + context, level) + write(')') + + _dispatch[frozendict.__repr__] = _pprint_frozendict + def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level): if not len(object): stream.write(repr(object)) @@ -623,12 +637,21 @@ def _safe_repr(self, object, context, maxlevels, level): else: return repr(object), True, False - if issubclass(typ, dict) and r is dict.__repr__: + if ((issubclass(typ, dict) and r is dict.__repr__) + or (issubclass(typ, frozendict) and r is frozendict.__repr__)): + is_frozendict = issubclass(typ, frozendict) if not object: - return "{}", True, False + if is_frozendict: + rep = f"{object.__class__.__name__}()" + else: + rep = "{}" + return rep, True, False objid = id(object) if maxlevels and level >= maxlevels: - return "{...}", False, objid in context + rep = "{...}" + if is_frozendict: + rep = f"{object.__class__.__name__}({rep})" + return rep, False, objid in context if objid in context: return _recursion(object), False, True context[objid] = 1 @@ -651,7 +674,10 @@ def _safe_repr(self, object, context, maxlevels, level): if krecur or vrecur: recursive = True del context[objid] - return "{%s}" % ", ".join(components), readable, recursive + rep = "{%s}" % ", ".join(components) + if is_frozendict: + rep = f"{object.__class__.__name__}({rep})" + return rep, readable, recursive if (issubclass(typ, list) and r is list.__repr__) or \ (issubclass(typ, tuple) and r is tuple.__repr__): diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 41c337ade7eca1..f3860a5d511989 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -67,6 +67,13 @@ class dict3(dict): def __repr__(self): return dict.__repr__(self) +class frozendict2(frozendict): + pass + +class frozendict3(frozendict): + def __repr__(self): + return frozendict.__repr__(self) + class dict_custom_repr(dict): def __repr__(self): return '*'*len(dict.__repr__(self)) @@ -254,18 +261,22 @@ def test_same_as_repr(self): set(), set2(), set3(), frozenset(), frozenset2(), frozenset3(), {}, dict2(), dict3(), + frozendict(), frozendict2(), frozendict3(), {}.keys(), {}.values(), {}.items(), MappingView({}), KeysView({}), ItemsView({}), ValuesView({}), self.assertTrue, pprint, -6, -6, -6-6j, -1.5, "x", b"x", bytearray(b"x"), (3,), [3], {3: 6}, - (1,2), [3,4], {5: 6}, + (1,2), [3,4], tuple2((1,2)), tuple3((1,2)), tuple3(range(100)), [3,4], list2([3,4]), list3([3,4]), list3(range(100)), set({7}), set2({7}), set3({7}), frozenset({8}), frozenset2({8}), frozenset3({8}), - dict2({5: 6}), dict3({5: 6}), + {5: 6}, dict2({5: 6}), dict3({5: 6}), + frozendict({5: 6}), frozendict2({5: 6}), frozendict3({5: 6}), {5: 6}.keys(), {5: 6}.values(), {5: 6}.items(), + frozendict({5: 6}).keys(), frozendict({5: 6}).values(), + frozendict({5: 6}).items(), MappingView({5: 6}), KeysView({5: 6}), ItemsView({5: 6}), ValuesView({5: 6}), range(10, -11, -1), @@ -330,20 +341,45 @@ def test_basic_line_wrap(self): for type in [dict, dict2]: self.assertEqual(pprint.pformat(type(o)), exp) + exp = """\ +frozendict({'RPM_cal': 0, + 'RPM_cal2': 48059, + 'Speed_cal': 0, + 'controldesk_runtime_us': 0, + 'main_code_runtime_us': 0, + 'read_io_runtime_us': 0, + 'write_io_runtime_us': 43690})""" + self.assertEqual(pprint.pformat(frozendict(o)), exp) + exp = """\ +frozendict2({'RPM_cal': 0, + 'RPM_cal2': 48059, + 'Speed_cal': 0, + 'controldesk_runtime_us': 0, + 'main_code_runtime_us': 0, + 'read_io_runtime_us': 0, + 'write_io_runtime_us': 43690})""" + self.assertEqual(pprint.pformat(frozendict2(o)), exp) + o = range(100) exp = 'dict_keys([%s])' % ',\n '.join(map(str, o)) keys = dict.fromkeys(o).keys() self.assertEqual(pprint.pformat(keys), exp) + keys = frozendict.fromkeys(o).keys() + self.assertEqual(pprint.pformat(keys), exp) o = range(100) exp = 'dict_values([%s])' % ',\n '.join(map(str, o)) values = {v: v for v in o}.values() self.assertEqual(pprint.pformat(values), exp) + values = frozendict({v: v for v in o}).values() + self.assertEqual(pprint.pformat(values), exp) o = range(100) exp = 'dict_items([%s])' % ',\n '.join("(%s, %s)" % (i, i) for i in o) items = {v: v for v in o}.items() self.assertEqual(pprint.pformat(items), exp) + items = frozendict({v: v for v in o}).items() + self.assertEqual(pprint.pformat(items), exp) o = range(100) exp = 'odict_keys([%s])' % ',\n '.join(map(str, o)) From 6940c1dc0c211670a4531bc13c10233e2fcf1335 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 17:21:43 +0100 Subject: [PATCH 198/498] gh-141510: Check argument in PyDict_MergeFromSeq2() (#145082) PyDict_MergeFromSeq2() now fails with SystemError if the first argument is not a dict or a dict subclass. PyDict_Update(), PyDict_Merge() and _PyDict_MergeEx() no longer accept frozendict. --- Lib/test/test_capi/test_dict.py | 9 +++-- Objects/dictobject.c | 64 +++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index bdd7aa9819fc48..d3cc279cd3f955 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -419,6 +419,7 @@ def test_dict_next(self): # CRASHES dict_next(NULL, 0) def test_dict_update(self): + # Test PyDict_Update() update = _testlimitedcapi.dict_update for cls1 in dict, DictSubclass: for cls2 in dict, DictSubclass, UserDict: @@ -429,11 +430,13 @@ def test_dict_update(self): self.assertRaises(AttributeError, update, {}, []) self.assertRaises(AttributeError, update, {}, 42) self.assertRaises(SystemError, update, UserDict(), {}) + self.assertRaises(SystemError, update, frozendict(), {}) self.assertRaises(SystemError, update, 42, {}) self.assertRaises(SystemError, update, {}, NULL) self.assertRaises(SystemError, update, NULL, {}) def test_dict_merge(self): + # Test PyDict_Merge() merge = _testlimitedcapi.dict_merge for cls1 in dict, DictSubclass: for cls2 in dict, DictSubclass, UserDict: @@ -447,11 +450,13 @@ def test_dict_merge(self): self.assertRaises(AttributeError, merge, {}, [], 0) self.assertRaises(AttributeError, merge, {}, 42, 0) self.assertRaises(SystemError, merge, UserDict(), {}, 0) + self.assertRaises(SystemError, merge, frozendict(), {}, 0) self.assertRaises(SystemError, merge, 42, {}, 0) self.assertRaises(SystemError, merge, {}, NULL, 0) self.assertRaises(SystemError, merge, NULL, {}, 0) def test_dict_mergefromseq2(self): + # Test PyDict_MergeFromSeq2() mergefromseq2 = _testlimitedcapi.dict_mergefromseq2 for cls1 in dict, DictSubclass: for cls2 in list, iter: @@ -466,8 +471,8 @@ def test_dict_mergefromseq2(self): self.assertRaises(ValueError, mergefromseq2, {}, [(1, 2, 3)], 0) self.assertRaises(TypeError, mergefromseq2, {}, [1], 0) self.assertRaises(TypeError, mergefromseq2, {}, 42, 0) - # CRASHES mergefromseq2(UserDict(), [], 0) - # CRASHES mergefromseq2(42, [], 0) + self.assertRaises(SystemError, mergefromseq2, UserDict(), [], 0) + self.assertRaises(SystemError, mergefromseq2, 42, [], 0) # CRASHES mergefromseq2({}, NULL, 0) # CRASHES mergefromseq2(NULL, {}, 0) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 8f960352fa4824..276e1df21a80d8 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -140,6 +140,7 @@ static PyObject* frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject* dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static int dict_merge(PyObject *a, PyObject *b, int override); +static int dict_merge_from_seq2(PyObject *d, PyObject *seq2, int override); /*[clinic input] @@ -3818,16 +3819,16 @@ static int dict_update_arg(PyObject *self, PyObject *arg) { if (PyAnyDict_CheckExact(arg)) { - return PyDict_Merge(self, arg, 1); + return dict_merge(self, arg, 1); } int has_keys = PyObject_HasAttrWithError(arg, &_Py_ID(keys)); if (has_keys < 0) { return -1; } if (has_keys) { - return PyDict_Merge(self, arg, 1); + return dict_merge(self, arg, 1); } - return PyDict_MergeFromSeq2(self, arg, 1); + return dict_merge_from_seq2(self, arg, 1); } static int @@ -3846,7 +3847,7 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, if (result == 0 && kwds != NULL) { if (PyArg_ValidateKeywordArguments(kwds)) - result = PyDict_Merge(self, kwds, 1); + result = dict_merge(self, kwds, 1); else result = -1; } @@ -3960,8 +3961,8 @@ merge_from_seq2_lock_held(PyObject *d, PyObject *seq2, int override) return Py_SAFE_DOWNCAST(i, Py_ssize_t, int); } -int -PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) +static int +dict_merge_from_seq2(PyObject *d, PyObject *seq2, int override) { int res; Py_BEGIN_CRITICAL_SECTION(d); @@ -3971,6 +3972,19 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) return res; } +int +PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) +{ + assert(d != NULL); + assert(seq2 != NULL); + if (!PyDict_Check(d)) { + PyErr_BadInternalCall(); + return -1; + } + + return dict_merge_from_seq2(d, seq2, override); +} + static int dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override) { @@ -4070,23 +4084,14 @@ dict_dict_merge(PyDictObject *mp, PyDictObject *other, int override) static int dict_merge(PyObject *a, PyObject *b, int override) { - PyDictObject *mp, *other; - + assert(a != NULL); + assert(b != NULL); assert(0 <= override && override <= 2); - /* We accept for the argument either a concrete dictionary object, - * or an abstract "mapping" object. For the former, we can do - * things quite efficiently. For the latter, we only require that - * PyMapping_Keys() and PyObject_GetItem() be supported. - */ - if (a == NULL || !PyAnyDict_Check(a) || b == NULL) { - PyErr_BadInternalCall(); - return -1; - } - mp = (PyDictObject*)a; + PyDictObject *mp = _PyAnyDict_CAST(a); int res = 0; if (PyAnyDict_Check(b) && (Py_TYPE(b)->tp_iter == dict_iter)) { - other = (PyDictObject*)b; + PyDictObject *other = (PyDictObject*)b; int res; Py_BEGIN_CRITICAL_SECTION2(a, b); res = dict_dict_merge((PyDictObject *)a, other, override); @@ -4167,23 +4172,38 @@ dict_merge(PyObject *a, PyObject *b, int override) } } +static int +dict_merge_api(PyObject *a, PyObject *b, int override) +{ + /* We accept for the argument either a concrete dictionary object, + * or an abstract "mapping" object. For the former, we can do + * things quite efficiently. For the latter, we only require that + * PyMapping_Keys() and PyObject_GetItem() be supported. + */ + if (a == NULL || !PyDict_Check(a) || b == NULL) { + PyErr_BadInternalCall(); + return -1; + } + return dict_merge(a, b, override); +} + int PyDict_Update(PyObject *a, PyObject *b) { - return dict_merge(a, b, 1); + return dict_merge_api(a, b, 1); } int PyDict_Merge(PyObject *a, PyObject *b, int override) { /* XXX Deprecate override not in (0, 1). */ - return dict_merge(a, b, override != 0); + return dict_merge_api(a, b, override != 0); } int _PyDict_MergeEx(PyObject *a, PyObject *b, int override) { - return dict_merge(a, b, override); + return dict_merge_api(a, b, override); } /*[clinic input] From f1f61bf87207c27da06ff73611b76933e456ef18 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 21 Feb 2026 17:27:55 +0000 Subject: [PATCH 199/498] gh-66802: Add `unicodedata.block()` function (#145042) Closes #66802 --- Doc/library/unicodedata.rst | 12 + Doc/whatsnew/3.15.rst | 5 + Lib/test/test_unicodedata.py | 91 +++ ...6-02-20-13-03-10.gh-issue-66802.OYcAi_.rst | 3 + Modules/clinic/unicodedata.c.h | 38 +- Modules/unicodedata.c | 36 +- Modules/unicodedata_db.h | 703 ++++++++++++++++++ Tools/unicode/makeunicodedata.py | 36 + 8 files changed, 922 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 2fc8b1d8b52341..d5f0405efbecc6 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -130,6 +130,18 @@ following functions: `Unicode Standard Annex #11 `_. +.. function:: block(chr, /) + + Returns the `block + `_ + assigned to the character *chr*. For example:: + + >>> unicodedata.block('S') + 'Basic Latin' + + .. versionadded:: next + + .. function:: mirrored(chr, /) Returns the mirrored property assigned to the character *chr* as diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index fa3ba25a954e40..cd1ec0e5c452d3 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1134,6 +1134,11 @@ unicodedata of the character which are related to the above algorithm. (Contributed by Serhiy Storchaka and Guillaume Sanchez in :gh:`74902`.) +* Add :func:`~unicodedata.block` function to return the `Unicode block + `_ + assigned to a character. + (Contributed by Stan Ulbrych in :gh:`66802`.) + unittest -------- diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 1d03e7d9fec717..8d4ba677faaa6f 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -973,6 +973,97 @@ def graphemes(*args): 'a\U0001F1FA\U0001F1E6\U0001F1FA\U0001F1F3'), ['a', '\U0001F1FA\U0001F1E6', '\U0001F1FA\U0001F1F3']) + def test_block(self): + self.assertEqual(self.db.block('\u0000'), 'Basic Latin') + self.assertEqual(self.db.block('\u0041'), 'Basic Latin') + self.assertEqual(self.db.block('\u007F'), 'Basic Latin') + self.assertEqual(self.db.block('\u0080'), 'Latin-1 Supplement') + self.assertEqual(self.db.block('\u00FF'), 'Latin-1 Supplement') + self.assertEqual(self.db.block('\u1159'), 'Hangul Jamo') + self.assertEqual(self.db.block('\u11F9'), 'Hangul Jamo') + self.assertEqual(self.db.block('\uD788'), 'Hangul Syllables') + self.assertEqual(self.db.block('\uD7A3'), 'Hangul Syllables') + # New in 5.0.0 + self.assertEqual(self.db.block('\u05BA'), 'Hebrew') + self.assertEqual(self.db.block('\u20EF'), 'Combining Diacritical Marks for Symbols') + # New in 5.1.0 + self.assertEqual(self.db.block('\u2064'), 'General Punctuation') + self.assertEqual(self.db.block('\uAA4D'), 'Cham') + # New in 5.2.0 + self.assertEqual(self.db.block('\u0816'), 'Samaritan') + self.assertEqual(self.db.block('\uA97C'), 'Hangul Jamo Extended-A') + self.assertEqual(self.db.block('\uD7C6'), 'Hangul Jamo Extended-B') + self.assertEqual(self.db.block('\uD7FB'), 'Hangul Jamo Extended-B') + # New in 6.0.0 + self.assertEqual(self.db.block('\u093A'), 'Devanagari') + self.assertEqual(self.db.block('\U00011002'), 'Brahmi') + # New in 6.1.0 + self.assertEqual(self.db.block('\U000E0FFF'), 'No_Block') + self.assertEqual(self.db.block('\U00016F7E'), 'Miao') + # New in 6.2.0 + self.assertEqual(self.db.block('\U0001F1E6'), 'Enclosed Alphanumeric Supplement') + self.assertEqual(self.db.block('\U0001F1FF'), 'Enclosed Alphanumeric Supplement') + # New in 6.3.0 + self.assertEqual(self.db.block('\u180E'), 'Mongolian') + self.assertEqual(self.db.block('\u1A1B'), 'Buginese') + # New in 7.0.0 + self.assertEqual(self.db.block('\u0E33'), 'Thai') + self.assertEqual(self.db.block('\u0EB3'), 'Lao') + self.assertEqual(self.db.block('\U0001BCA3'), 'Shorthand Format Controls') + self.assertEqual(self.db.block('\U0001E8D6'), 'Mende Kikakui') + self.assertEqual(self.db.block('\U0001163E'), 'Modi') + # New in 8.0.0 + self.assertEqual(self.db.block('\u08E3'), 'Arabic Extended-A') + self.assertEqual(self.db.block('\U00011726'), 'Ahom') + # New in 9.0.0 + self.assertEqual(self.db.block('\u0600'), 'Arabic') + self.assertEqual(self.db.block('\U000E007F'), 'Tags') + self.assertEqual(self.db.block('\U00011CB4'), 'Marchen') + self.assertEqual(self.db.block('\u200D'), 'General Punctuation') + # New in 10.0.0 + self.assertEqual(self.db.block('\U00011D46'), 'Masaram Gondi') + self.assertEqual(self.db.block('\U00011D47'), 'Masaram Gondi') + self.assertEqual(self.db.block('\U00011A97'), 'Soyombo') + # New in 11.0.0 + self.assertEqual(self.db.block('\U000110CD'), 'Kaithi') + self.assertEqual(self.db.block('\u07FD'), 'NKo') + self.assertEqual(self.db.block('\U00011EF6'), 'Makasar') + # New in 12.0.0 + self.assertEqual(self.db.block('\U00011A84'), 'Soyombo') + self.assertEqual(self.db.block('\U00013438'), 'Egyptian Hieroglyph Format Controls') + self.assertEqual(self.db.block('\U0001E2EF'), 'Wancho') + self.assertEqual(self.db.block('\U00016F87'), 'Miao') + # New in 13.0.0 + self.assertEqual(self.db.block('\U00011941'), 'Dives Akuru') + self.assertEqual(self.db.block('\U00016FE4'), 'Ideographic Symbols and Punctuation') + self.assertEqual(self.db.block('\U00011942'), 'Dives Akuru') + # New in 14.0.0 + self.assertEqual(self.db.block('\u0891'), 'Arabic Extended-B') + self.assertEqual(self.db.block('\U0001E2AE'), 'Toto') + # New in 15.0.0 + self.assertEqual(self.db.block('\U00011F02'), 'Kawi') + self.assertEqual(self.db.block('\U0001343F'), 'Egyptian Hieroglyph Format Controls') + self.assertEqual(self.db.block('\U0001E4EF'), 'Nag Mundari') + self.assertEqual(self.db.block('\U00011F3F'), 'Kawi') + # New in 16.0.0 + self.assertEqual(self.db.block('\U000113D1'), 'Tulu-Tigalari') + self.assertEqual(self.db.block('\U0001E5EF'), 'Ol Onal') + self.assertEqual(self.db.block('\U0001612C'), 'Gurung Khema') + self.assertEqual(self.db.block('\U00016D63'), 'Kirat Rai') + # New in 17.0.0 + self.assertEqual(self.db.block('\u1AEB'), 'Combining Diacritical Marks Extended') + self.assertEqual(self.db.block('\U00011B67'), 'Sharada Supplement') + # Unassigned + self.assertEqual(self.db.block('\U00100000'), 'Supplementary Private Use Area-B') + self.assertEqual(self.db.block('\U0010FFFF'), 'Supplementary Private Use Area-B') + + def test_block_invalid_input(self): + self.assertRaises(TypeError, self.db.block) + self.assertRaises(TypeError, self.db.block, b'x') + self.assertRaises(TypeError, self.db.block, 120) + self.assertRaises(TypeError, self.db.block, '') + self.assertRaises(TypeError, self.db.block, 'xx') + class Unicode_3_2_0_FunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): db = unicodedata.ucd_3_2_0 diff --git a/Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst b/Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst new file mode 100644 index 00000000000000..68a25262c7d7f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst @@ -0,0 +1,3 @@ +Add :func:`unicodedata.block` function to return the `Unicode block +`_ of a +character. diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index 8e2dd7a0ce5663..5443893079b1af 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -691,6 +691,42 @@ unicodedata_iter_graphemes(PyObject *module, PyObject *const *args, Py_ssize_t n return return_value; } +PyDoc_STRVAR(unicodedata_block__doc__, +"block($module, chr, /)\n" +"--\n" +"\n" +"Return block assigned to the character chr."); + +#define UNICODEDATA_BLOCK_METHODDEF \ + {"block", (PyCFunction)unicodedata_block, METH_O, unicodedata_block__doc__}, + +static PyObject * +unicodedata_block_impl(PyObject *module, int chr); + +static PyObject * +unicodedata_block(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("block", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + PyErr_Format(PyExc_TypeError, + "block(): argument must be a unicode character, " + "not a string of length %zd", + PyUnicode_GET_LENGTH(arg)); + goto exit; + } + chr = PyUnicode_READ_CHAR(arg, 0); + return_value = unicodedata_block_impl(module, chr); + +exit: + return return_value; +} + PyDoc_STRVAR(unicodedata_grapheme_cluster_break__doc__, "grapheme_cluster_break($module, chr, /)\n" "--\n" @@ -798,4 +834,4 @@ unicodedata_extended_pictographic(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=0f09cc90f06ace76 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=482a87df218f07c1 input=a9049054013a1b77]*/ diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 1ed9760874b2a6..f20726a937ce38 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -2066,6 +2066,39 @@ unicodedata_iter_graphemes_impl(PyObject *module, PyObject *unistr, return (PyObject*)gbi; } +/*[clinic input] +unicodedata.block + + chr: int(accept={str}) + / + +Return block assigned to the character chr. +[clinic start generated code]*/ + +static PyObject * +unicodedata_block_impl(PyObject *module, int chr) +/*[clinic end generated code: output=5f8b40c49eaec75a input=0834cf2642d6eaae]*/ +{ + Py_UCS4 c = (Py_UCS4)chr; + int lo = 0, hi = BLOCK_COUNT - 1; + while (lo <= hi) { + int mid = (lo + hi) / 2; + if (c < _PyUnicode_Blocks[mid].start) { + hi = mid - 1; + } + else if (c > _PyUnicode_Blocks[mid].end) { + lo = mid + 1; + } + else { + size_t name = _PyUnicode_Blocks[mid].name; + return PyUnicode_FromString(_PyUnicode_BlockNames[name]); + } + } + // Otherwise, return the default value per + // https://www.unicode.org/versions/latest/core-spec/chapter-3/#G64189 + return PyUnicode_FromString("No_Block"); +} + /*[clinic input] unicodedata.grapheme_cluster_break @@ -2128,6 +2161,7 @@ unicodedata_extended_pictographic_impl(PyObject *module, int chr) // an UCD instance. static PyMethodDef unicodedata_functions[] = { // Module only functions. + UNICODEDATA_BLOCK_METHODDEF UNICODEDATA_GRAPHEME_CLUSTER_BREAK_METHODDEF UNICODEDATA_INDIC_CONJUNCT_BREAK_METHODDEF UNICODEDATA_EXTENDED_PICTOGRAPHIC_METHODDEF @@ -2137,7 +2171,7 @@ static PyMethodDef unicodedata_functions[] = { // The following definitions are shared between the module // and the UCD class. -#define DB_methods (unicodedata_functions + 6) +#define DB_methods (unicodedata_functions + 7) UNICODEDATA_UCD_DECIMAL_METHODDEF UNICODEDATA_UCD_DIGIT_METHODDEF diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index 3cc5776a1f240d..9e88f5cca7115b 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -796,6 +796,709 @@ const char * const _PyUnicode_IndicConjunctBreakNames[] = { "Extend", NULL }; +static const char * const _PyUnicode_BlockNames[] = { + "Basic Latin", + "Latin-1 Supplement", + "Latin Extended-A", + "Latin Extended-B", + "IPA Extensions", + "Spacing Modifier Letters", + "Combining Diacritical Marks", + "Greek and Coptic", + "Cyrillic", + "Cyrillic Supplement", + "Armenian", + "Hebrew", + "Arabic", + "Syriac", + "Arabic Supplement", + "Thaana", + "NKo", + "Samaritan", + "Mandaic", + "Syriac Supplement", + "Arabic Extended-B", + "Arabic Extended-A", + "Devanagari", + "Bengali", + "Gurmukhi", + "Gujarati", + "Oriya", + "Tamil", + "Telugu", + "Kannada", + "Malayalam", + "Sinhala", + "Thai", + "Lao", + "Tibetan", + "Myanmar", + "Georgian", + "Hangul Jamo", + "Ethiopic", + "Ethiopic Supplement", + "Cherokee", + "Unified Canadian Aboriginal Syllabics", + "Ogham", + "Runic", + "Tagalog", + "Hanunoo", + "Buhid", + "Tagbanwa", + "Khmer", + "Mongolian", + "Unified Canadian Aboriginal Syllabics Extended", + "Limbu", + "Tai Le", + "New Tai Lue", + "Khmer Symbols", + "Buginese", + "Tai Tham", + "Combining Diacritical Marks Extended", + "Balinese", + "Sundanese", + "Batak", + "Lepcha", + "Ol Chiki", + "Cyrillic Extended-C", + "Georgian Extended", + "Sundanese Supplement", + "Vedic Extensions", + "Phonetic Extensions", + "Phonetic Extensions Supplement", + "Combining Diacritical Marks Supplement", + "Latin Extended Additional", + "Greek Extended", + "General Punctuation", + "Superscripts and Subscripts", + "Currency Symbols", + "Combining Diacritical Marks for Symbols", + "Letterlike Symbols", + "Number Forms", + "Arrows", + "Mathematical Operators", + "Miscellaneous Technical", + "Control Pictures", + "Optical Character Recognition", + "Enclosed Alphanumerics", + "Box Drawing", + "Block Elements", + "Geometric Shapes", + "Miscellaneous Symbols", + "Dingbats", + "Miscellaneous Mathematical Symbols-A", + "Supplemental Arrows-A", + "Braille Patterns", + "Supplemental Arrows-B", + "Miscellaneous Mathematical Symbols-B", + "Supplemental Mathematical Operators", + "Miscellaneous Symbols and Arrows", + "Glagolitic", + "Latin Extended-C", + "Coptic", + "Georgian Supplement", + "Tifinagh", + "Ethiopic Extended", + "Cyrillic Extended-A", + "Supplemental Punctuation", + "CJK Radicals Supplement", + "Kangxi Radicals", + "Ideographic Description Characters", + "CJK Symbols and Punctuation", + "Hiragana", + "Katakana", + "Bopomofo", + "Hangul Compatibility Jamo", + "Kanbun", + "Bopomofo Extended", + "CJK Strokes", + "Katakana Phonetic Extensions", + "Enclosed CJK Letters and Months", + "CJK Compatibility", + "CJK Unified Ideographs Extension A", + "Yijing Hexagram Symbols", + "CJK Unified Ideographs", + "Yi Syllables", + "Yi Radicals", + "Lisu", + "Vai", + "Cyrillic Extended-B", + "Bamum", + "Modifier Tone Letters", + "Latin Extended-D", + "Syloti Nagri", + "Common Indic Number Forms", + "Phags-pa", + "Saurashtra", + "Devanagari Extended", + "Kayah Li", + "Rejang", + "Hangul Jamo Extended-A", + "Javanese", + "Myanmar Extended-B", + "Cham", + "Myanmar Extended-A", + "Tai Viet", + "Meetei Mayek Extensions", + "Ethiopic Extended-A", + "Latin Extended-E", + "Cherokee Supplement", + "Meetei Mayek", + "Hangul Syllables", + "Hangul Jamo Extended-B", + "High Surrogates", + "High Private Use Surrogates", + "Low Surrogates", + "Private Use Area", + "CJK Compatibility Ideographs", + "Alphabetic Presentation Forms", + "Arabic Presentation Forms-A", + "Variation Selectors", + "Vertical Forms", + "Combining Half Marks", + "CJK Compatibility Forms", + "Small Form Variants", + "Arabic Presentation Forms-B", + "Halfwidth and Fullwidth Forms", + "Specials", + "Linear B Syllabary", + "Linear B Ideograms", + "Aegean Numbers", + "Ancient Greek Numbers", + "Ancient Symbols", + "Phaistos Disc", + "Lycian", + "Carian", + "Coptic Epact Numbers", + "Old Italic", + "Gothic", + "Old Permic", + "Ugaritic", + "Old Persian", + "Deseret", + "Shavian", + "Osmanya", + "Osage", + "Elbasan", + "Caucasian Albanian", + "Vithkuqi", + "Todhri", + "Linear A", + "Latin Extended-F", + "Cypriot Syllabary", + "Imperial Aramaic", + "Palmyrene", + "Nabataean", + "Hatran", + "Phoenician", + "Lydian", + "Sidetic", + "Meroitic Hieroglyphs", + "Meroitic Cursive", + "Kharoshthi", + "Old South Arabian", + "Old North Arabian", + "Manichaean", + "Avestan", + "Inscriptional Parthian", + "Inscriptional Pahlavi", + "Psalter Pahlavi", + "Old Turkic", + "Old Hungarian", + "Hanifi Rohingya", + "Garay", + "Rumi Numeral Symbols", + "Yezidi", + "Arabic Extended-C", + "Old Sogdian", + "Sogdian", + "Old Uyghur", + "Chorasmian", + "Elymaic", + "Brahmi", + "Kaithi", + "Sora Sompeng", + "Chakma", + "Mahajani", + "Sharada", + "Sinhala Archaic Numbers", + "Khojki", + "Multani", + "Khudawadi", + "Grantha", + "Tulu-Tigalari", + "Newa", + "Tirhuta", + "Siddham", + "Modi", + "Mongolian Supplement", + "Takri", + "Myanmar Extended-C", + "Ahom", + "Dogra", + "Warang Citi", + "Dives Akuru", + "Nandinagari", + "Zanabazar Square", + "Soyombo", + "Unified Canadian Aboriginal Syllabics Extended-A", + "Pau Cin Hau", + "Devanagari Extended-A", + "Sharada Supplement", + "Sunuwar", + "Bhaiksuki", + "Marchen", + "Masaram Gondi", + "Gunjala Gondi", + "Tolong Siki", + "Makasar", + "Kawi", + "Lisu Supplement", + "Tamil Supplement", + "Cuneiform", + "Cuneiform Numbers and Punctuation", + "Early Dynastic Cuneiform", + "Cypro-Minoan", + "Egyptian Hieroglyphs", + "Egyptian Hieroglyph Format Controls", + "Egyptian Hieroglyphs Extended-A", + "Anatolian Hieroglyphs", + "Gurung Khema", + "Bamum Supplement", + "Mro", + "Tangsa", + "Bassa Vah", + "Pahawh Hmong", + "Kirat Rai", + "Medefaidrin", + "Beria Erfe", + "Miao", + "Ideographic Symbols and Punctuation", + "Tangut", + "Tangut Components", + "Khitan Small Script", + "Tangut Supplement", + "Tangut Components Supplement", + "Kana Extended-B", + "Kana Supplement", + "Kana Extended-A", + "Small Kana Extension", + "Nushu", + "Duployan", + "Shorthand Format Controls", + "Symbols for Legacy Computing Supplement", + "Miscellaneous Symbols Supplement", + "Znamenny Musical Notation", + "Byzantine Musical Symbols", + "Musical Symbols", + "Ancient Greek Musical Notation", + "Kaktovik Numerals", + "Mayan Numerals", + "Tai Xuan Jing Symbols", + "Counting Rod Numerals", + "Mathematical Alphanumeric Symbols", + "Sutton SignWriting", + "Latin Extended-G", + "Glagolitic Supplement", + "Cyrillic Extended-D", + "Nyiakeng Puachue Hmong", + "Toto", + "Wancho", + "Nag Mundari", + "Ol Onal", + "Tai Yo", + "Ethiopic Extended-B", + "Mende Kikakui", + "Adlam", + "Indic Siyaq Numbers", + "Ottoman Siyaq Numbers", + "Arabic Mathematical Alphabetic Symbols", + "Mahjong Tiles", + "Domino Tiles", + "Playing Cards", + "Enclosed Alphanumeric Supplement", + "Enclosed Ideographic Supplement", + "Miscellaneous Symbols and Pictographs", + "Emoticons", + "Ornamental Dingbats", + "Transport and Map Symbols", + "Alchemical Symbols", + "Geometric Shapes Extended", + "Supplemental Arrows-C", + "Supplemental Symbols and Pictographs", + "Chess Symbols", + "Symbols and Pictographs Extended-A", + "Symbols for Legacy Computing", + "CJK Unified Ideographs Extension B", + "CJK Unified Ideographs Extension C", + "CJK Unified Ideographs Extension D", + "CJK Unified Ideographs Extension E", + "CJK Unified Ideographs Extension F", + "CJK Unified Ideographs Extension I", + "CJK Compatibility Ideographs Supplement", + "CJK Unified Ideographs Extension G", + "CJK Unified Ideographs Extension H", + "CJK Unified Ideographs Extension J", + "Tags", + "Variation Selectors Supplement", + "Supplementary Private Use Area-A", + "Supplementary Private Use Area-B", +}; +typedef struct { + Py_UCS4 start; + Py_UCS4 end; + unsigned short name; +} _PyUnicode_Block; +static const _PyUnicode_Block _PyUnicode_Blocks[] = { + {0x0000, 0x007F, 0}, + {0x0080, 0x00FF, 1}, + {0x0100, 0x017F, 2}, + {0x0180, 0x024F, 3}, + {0x0250, 0x02AF, 4}, + {0x02B0, 0x02FF, 5}, + {0x0300, 0x036F, 6}, + {0x0370, 0x03FF, 7}, + {0x0400, 0x04FF, 8}, + {0x0500, 0x052F, 9}, + {0x0530, 0x058F, 10}, + {0x0590, 0x05FF, 11}, + {0x0600, 0x06FF, 12}, + {0x0700, 0x074F, 13}, + {0x0750, 0x077F, 14}, + {0x0780, 0x07BF, 15}, + {0x07C0, 0x07FF, 16}, + {0x0800, 0x083F, 17}, + {0x0840, 0x085F, 18}, + {0x0860, 0x086F, 19}, + {0x0870, 0x089F, 20}, + {0x08A0, 0x08FF, 21}, + {0x0900, 0x097F, 22}, + {0x0980, 0x09FF, 23}, + {0x0A00, 0x0A7F, 24}, + {0x0A80, 0x0AFF, 25}, + {0x0B00, 0x0B7F, 26}, + {0x0B80, 0x0BFF, 27}, + {0x0C00, 0x0C7F, 28}, + {0x0C80, 0x0CFF, 29}, + {0x0D00, 0x0D7F, 30}, + {0x0D80, 0x0DFF, 31}, + {0x0E00, 0x0E7F, 32}, + {0x0E80, 0x0EFF, 33}, + {0x0F00, 0x0FFF, 34}, + {0x1000, 0x109F, 35}, + {0x10A0, 0x10FF, 36}, + {0x1100, 0x11FF, 37}, + {0x1200, 0x137F, 38}, + {0x1380, 0x139F, 39}, + {0x13A0, 0x13FF, 40}, + {0x1400, 0x167F, 41}, + {0x1680, 0x169F, 42}, + {0x16A0, 0x16FF, 43}, + {0x1700, 0x171F, 44}, + {0x1720, 0x173F, 45}, + {0x1740, 0x175F, 46}, + {0x1760, 0x177F, 47}, + {0x1780, 0x17FF, 48}, + {0x1800, 0x18AF, 49}, + {0x18B0, 0x18FF, 50}, + {0x1900, 0x194F, 51}, + {0x1950, 0x197F, 52}, + {0x1980, 0x19DF, 53}, + {0x19E0, 0x19FF, 54}, + {0x1A00, 0x1A1F, 55}, + {0x1A20, 0x1AAF, 56}, + {0x1AB0, 0x1AFF, 57}, + {0x1B00, 0x1B7F, 58}, + {0x1B80, 0x1BBF, 59}, + {0x1BC0, 0x1BFF, 60}, + {0x1C00, 0x1C4F, 61}, + {0x1C50, 0x1C7F, 62}, + {0x1C80, 0x1C8F, 63}, + {0x1C90, 0x1CBF, 64}, + {0x1CC0, 0x1CCF, 65}, + {0x1CD0, 0x1CFF, 66}, + {0x1D00, 0x1D7F, 67}, + {0x1D80, 0x1DBF, 68}, + {0x1DC0, 0x1DFF, 69}, + {0x1E00, 0x1EFF, 70}, + {0x1F00, 0x1FFF, 71}, + {0x2000, 0x206F, 72}, + {0x2070, 0x209F, 73}, + {0x20A0, 0x20CF, 74}, + {0x20D0, 0x20FF, 75}, + {0x2100, 0x214F, 76}, + {0x2150, 0x218F, 77}, + {0x2190, 0x21FF, 78}, + {0x2200, 0x22FF, 79}, + {0x2300, 0x23FF, 80}, + {0x2400, 0x243F, 81}, + {0x2440, 0x245F, 82}, + {0x2460, 0x24FF, 83}, + {0x2500, 0x257F, 84}, + {0x2580, 0x259F, 85}, + {0x25A0, 0x25FF, 86}, + {0x2600, 0x26FF, 87}, + {0x2700, 0x27BF, 88}, + {0x27C0, 0x27EF, 89}, + {0x27F0, 0x27FF, 90}, + {0x2800, 0x28FF, 91}, + {0x2900, 0x297F, 92}, + {0x2980, 0x29FF, 93}, + {0x2A00, 0x2AFF, 94}, + {0x2B00, 0x2BFF, 95}, + {0x2C00, 0x2C5F, 96}, + {0x2C60, 0x2C7F, 97}, + {0x2C80, 0x2CFF, 98}, + {0x2D00, 0x2D2F, 99}, + {0x2D30, 0x2D7F, 100}, + {0x2D80, 0x2DDF, 101}, + {0x2DE0, 0x2DFF, 102}, + {0x2E00, 0x2E7F, 103}, + {0x2E80, 0x2EFF, 104}, + {0x2F00, 0x2FDF, 105}, + {0x2FF0, 0x2FFF, 106}, + {0x3000, 0x303F, 107}, + {0x3040, 0x309F, 108}, + {0x30A0, 0x30FF, 109}, + {0x3100, 0x312F, 110}, + {0x3130, 0x318F, 111}, + {0x3190, 0x319F, 112}, + {0x31A0, 0x31BF, 113}, + {0x31C0, 0x31EF, 114}, + {0x31F0, 0x31FF, 115}, + {0x3200, 0x32FF, 116}, + {0x3300, 0x33FF, 117}, + {0x3400, 0x4DBF, 118}, + {0x4DC0, 0x4DFF, 119}, + {0x4E00, 0x9FFF, 120}, + {0xA000, 0xA48F, 121}, + {0xA490, 0xA4CF, 122}, + {0xA4D0, 0xA4FF, 123}, + {0xA500, 0xA63F, 124}, + {0xA640, 0xA69F, 125}, + {0xA6A0, 0xA6FF, 126}, + {0xA700, 0xA71F, 127}, + {0xA720, 0xA7FF, 128}, + {0xA800, 0xA82F, 129}, + {0xA830, 0xA83F, 130}, + {0xA840, 0xA87F, 131}, + {0xA880, 0xA8DF, 132}, + {0xA8E0, 0xA8FF, 133}, + {0xA900, 0xA92F, 134}, + {0xA930, 0xA95F, 135}, + {0xA960, 0xA97F, 136}, + {0xA980, 0xA9DF, 137}, + {0xA9E0, 0xA9FF, 138}, + {0xAA00, 0xAA5F, 139}, + {0xAA60, 0xAA7F, 140}, + {0xAA80, 0xAADF, 141}, + {0xAAE0, 0xAAFF, 142}, + {0xAB00, 0xAB2F, 143}, + {0xAB30, 0xAB6F, 144}, + {0xAB70, 0xABBF, 145}, + {0xABC0, 0xABFF, 146}, + {0xAC00, 0xD7AF, 147}, + {0xD7B0, 0xD7FF, 148}, + {0xD800, 0xDB7F, 149}, + {0xDB80, 0xDBFF, 150}, + {0xDC00, 0xDFFF, 151}, + {0xE000, 0xF8FF, 152}, + {0xF900, 0xFAFF, 153}, + {0xFB00, 0xFB4F, 154}, + {0xFB50, 0xFDFF, 155}, + {0xFE00, 0xFE0F, 156}, + {0xFE10, 0xFE1F, 157}, + {0xFE20, 0xFE2F, 158}, + {0xFE30, 0xFE4F, 159}, + {0xFE50, 0xFE6F, 160}, + {0xFE70, 0xFEFF, 161}, + {0xFF00, 0xFFEF, 162}, + {0xFFF0, 0xFFFF, 163}, + {0x10000, 0x1007F, 164}, + {0x10080, 0x100FF, 165}, + {0x10100, 0x1013F, 166}, + {0x10140, 0x1018F, 167}, + {0x10190, 0x101CF, 168}, + {0x101D0, 0x101FF, 169}, + {0x10280, 0x1029F, 170}, + {0x102A0, 0x102DF, 171}, + {0x102E0, 0x102FF, 172}, + {0x10300, 0x1032F, 173}, + {0x10330, 0x1034F, 174}, + {0x10350, 0x1037F, 175}, + {0x10380, 0x1039F, 176}, + {0x103A0, 0x103DF, 177}, + {0x10400, 0x1044F, 178}, + {0x10450, 0x1047F, 179}, + {0x10480, 0x104AF, 180}, + {0x104B0, 0x104FF, 181}, + {0x10500, 0x1052F, 182}, + {0x10530, 0x1056F, 183}, + {0x10570, 0x105BF, 184}, + {0x105C0, 0x105FF, 185}, + {0x10600, 0x1077F, 186}, + {0x10780, 0x107BF, 187}, + {0x10800, 0x1083F, 188}, + {0x10840, 0x1085F, 189}, + {0x10860, 0x1087F, 190}, + {0x10880, 0x108AF, 191}, + {0x108E0, 0x108FF, 192}, + {0x10900, 0x1091F, 193}, + {0x10920, 0x1093F, 194}, + {0x10940, 0x1095F, 195}, + {0x10980, 0x1099F, 196}, + {0x109A0, 0x109FF, 197}, + {0x10A00, 0x10A5F, 198}, + {0x10A60, 0x10A7F, 199}, + {0x10A80, 0x10A9F, 200}, + {0x10AC0, 0x10AFF, 201}, + {0x10B00, 0x10B3F, 202}, + {0x10B40, 0x10B5F, 203}, + {0x10B60, 0x10B7F, 204}, + {0x10B80, 0x10BAF, 205}, + {0x10C00, 0x10C4F, 206}, + {0x10C80, 0x10CFF, 207}, + {0x10D00, 0x10D3F, 208}, + {0x10D40, 0x10D8F, 209}, + {0x10E60, 0x10E7F, 210}, + {0x10E80, 0x10EBF, 211}, + {0x10EC0, 0x10EFF, 212}, + {0x10F00, 0x10F2F, 213}, + {0x10F30, 0x10F6F, 214}, + {0x10F70, 0x10FAF, 215}, + {0x10FB0, 0x10FDF, 216}, + {0x10FE0, 0x10FFF, 217}, + {0x11000, 0x1107F, 218}, + {0x11080, 0x110CF, 219}, + {0x110D0, 0x110FF, 220}, + {0x11100, 0x1114F, 221}, + {0x11150, 0x1117F, 222}, + {0x11180, 0x111DF, 223}, + {0x111E0, 0x111FF, 224}, + {0x11200, 0x1124F, 225}, + {0x11280, 0x112AF, 226}, + {0x112B0, 0x112FF, 227}, + {0x11300, 0x1137F, 228}, + {0x11380, 0x113FF, 229}, + {0x11400, 0x1147F, 230}, + {0x11480, 0x114DF, 231}, + {0x11580, 0x115FF, 232}, + {0x11600, 0x1165F, 233}, + {0x11660, 0x1167F, 234}, + {0x11680, 0x116CF, 235}, + {0x116D0, 0x116FF, 236}, + {0x11700, 0x1174F, 237}, + {0x11800, 0x1184F, 238}, + {0x118A0, 0x118FF, 239}, + {0x11900, 0x1195F, 240}, + {0x119A0, 0x119FF, 241}, + {0x11A00, 0x11A4F, 242}, + {0x11A50, 0x11AAF, 243}, + {0x11AB0, 0x11ABF, 244}, + {0x11AC0, 0x11AFF, 245}, + {0x11B00, 0x11B5F, 246}, + {0x11B60, 0x11B7F, 247}, + {0x11BC0, 0x11BFF, 248}, + {0x11C00, 0x11C6F, 249}, + {0x11C70, 0x11CBF, 250}, + {0x11D00, 0x11D5F, 251}, + {0x11D60, 0x11DAF, 252}, + {0x11DB0, 0x11DEF, 253}, + {0x11EE0, 0x11EFF, 254}, + {0x11F00, 0x11F5F, 255}, + {0x11FB0, 0x11FBF, 256}, + {0x11FC0, 0x11FFF, 257}, + {0x12000, 0x123FF, 258}, + {0x12400, 0x1247F, 259}, + {0x12480, 0x1254F, 260}, + {0x12F90, 0x12FFF, 261}, + {0x13000, 0x1342F, 262}, + {0x13430, 0x1345F, 263}, + {0x13460, 0x143FF, 264}, + {0x14400, 0x1467F, 265}, + {0x16100, 0x1613F, 266}, + {0x16800, 0x16A3F, 267}, + {0x16A40, 0x16A6F, 268}, + {0x16A70, 0x16ACF, 269}, + {0x16AD0, 0x16AFF, 270}, + {0x16B00, 0x16B8F, 271}, + {0x16D40, 0x16D7F, 272}, + {0x16E40, 0x16E9F, 273}, + {0x16EA0, 0x16EDF, 274}, + {0x16F00, 0x16F9F, 275}, + {0x16FE0, 0x16FFF, 276}, + {0x17000, 0x187FF, 277}, + {0x18800, 0x18AFF, 278}, + {0x18B00, 0x18CFF, 279}, + {0x18D00, 0x18D7F, 280}, + {0x18D80, 0x18DFF, 281}, + {0x1AFF0, 0x1AFFF, 282}, + {0x1B000, 0x1B0FF, 283}, + {0x1B100, 0x1B12F, 284}, + {0x1B130, 0x1B16F, 285}, + {0x1B170, 0x1B2FF, 286}, + {0x1BC00, 0x1BC9F, 287}, + {0x1BCA0, 0x1BCAF, 288}, + {0x1CC00, 0x1CEBF, 289}, + {0x1CEC0, 0x1CEFF, 290}, + {0x1CF00, 0x1CFCF, 291}, + {0x1D000, 0x1D0FF, 292}, + {0x1D100, 0x1D1FF, 293}, + {0x1D200, 0x1D24F, 294}, + {0x1D2C0, 0x1D2DF, 295}, + {0x1D2E0, 0x1D2FF, 296}, + {0x1D300, 0x1D35F, 297}, + {0x1D360, 0x1D37F, 298}, + {0x1D400, 0x1D7FF, 299}, + {0x1D800, 0x1DAAF, 300}, + {0x1DF00, 0x1DFFF, 301}, + {0x1E000, 0x1E02F, 302}, + {0x1E030, 0x1E08F, 303}, + {0x1E100, 0x1E14F, 304}, + {0x1E290, 0x1E2BF, 305}, + {0x1E2C0, 0x1E2FF, 306}, + {0x1E4D0, 0x1E4FF, 307}, + {0x1E5D0, 0x1E5FF, 308}, + {0x1E6C0, 0x1E6FF, 309}, + {0x1E7E0, 0x1E7FF, 310}, + {0x1E800, 0x1E8DF, 311}, + {0x1E900, 0x1E95F, 312}, + {0x1EC70, 0x1ECBF, 313}, + {0x1ED00, 0x1ED4F, 314}, + {0x1EE00, 0x1EEFF, 315}, + {0x1F000, 0x1F02F, 316}, + {0x1F030, 0x1F09F, 317}, + {0x1F0A0, 0x1F0FF, 318}, + {0x1F100, 0x1F1FF, 319}, + {0x1F200, 0x1F2FF, 320}, + {0x1F300, 0x1F5FF, 321}, + {0x1F600, 0x1F64F, 322}, + {0x1F650, 0x1F67F, 323}, + {0x1F680, 0x1F6FF, 324}, + {0x1F700, 0x1F77F, 325}, + {0x1F780, 0x1F7FF, 326}, + {0x1F800, 0x1F8FF, 327}, + {0x1F900, 0x1F9FF, 328}, + {0x1FA00, 0x1FA6F, 329}, + {0x1FA70, 0x1FAFF, 330}, + {0x1FB00, 0x1FBFF, 331}, + {0x20000, 0x2A6DF, 332}, + {0x2A700, 0x2B73F, 333}, + {0x2B740, 0x2B81F, 334}, + {0x2B820, 0x2CEAF, 335}, + {0x2CEB0, 0x2EBEF, 336}, + {0x2EBF0, 0x2EE5F, 337}, + {0x2F800, 0x2FA1F, 338}, + {0x30000, 0x3134F, 339}, + {0x31350, 0x323AF, 340}, + {0x323B0, 0x3347F, 341}, + {0xE0000, 0xE007F, 342}, + {0xE0100, 0xE01EF, 343}, + {0xF0000, 0xFFFFF, 344}, + {0x100000, 0x10FFFF, 345}, +}; +#define BLOCK_COUNT 346 + static const char *decomp_prefix[] = { "", "", diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 11f626ca0aba7a..5db850ca2d1f0c 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -60,6 +60,7 @@ CASE_FOLDING = "CaseFolding%s.txt" GRAPHEME_CLUSTER_BREAK = "auxiliary/GraphemeBreakProperty%s.txt" EMOJI_DATA = "emoji/emoji-data%s.txt" +BLOCKS = "Blocks%s.txt" # Private Use Areas -- in planes 1, 15, 16 PUA_1 = range(0xE000, 0xF900) @@ -392,6 +393,34 @@ def makeunicodedata(unicode, trace): fprint(" NULL") fprint("};") + # Generate block tables + names = [] + name_to_index = {} + blocks = [] + for start, end, name in unicode.blocks: + if name not in name_to_index: + name_to_index[name] = len(names) + names.append(name) + blocks.append((start, end, name_to_index[name])) + + fprint("static const char * const _PyUnicode_BlockNames[] = {") + for name in names: + fprint(' "%s",' % name) + fprint("};") + + fprint("typedef struct {") + fprint(" Py_UCS4 start;") + fprint(" Py_UCS4 end;") + fprint(" unsigned short name;") + fprint("} _PyUnicode_Block;") + + fprint("static const _PyUnicode_Block _PyUnicode_Blocks[] = {") + for start, end, name in blocks: + fprint(" {0x%04X, 0x%04X, %d}," % (start, end, name)) + fprint("};") + fprint(f"#define BLOCK_COUNT {len(blocks)}") + fprint() + fprint("static const char *decomp_prefix[] = {") for name in decomp_prefix: fprint(" \"%s\"," % name) @@ -1205,6 +1234,13 @@ def __init__(self, version, ideograph_check=True): ext_picts[char] = True self.ext_picts = ext_picts + # See https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G64189 + self.blocks = [] + for record in UcdFile(BLOCKS, version).records(): + start_end, name = record + start, end = [int(c, 16) for c in start_end.split('..')] + self.blocks.append((start, end, name)) + self.blocks.sort() def uselatin1(self): # restrict character range to ISO Latin 1 From c9380aebbe35973528392ff85f8914eb4c626d5b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 18:36:02 +0100 Subject: [PATCH 200/498] gh-141510: Check argument in PyDict_Contains() (#145083) PyDict_Contains() and PyDict_ContainsString() now fail with SystemError if the first argument is not a dict, frozendict, dict subclass or frozendict subclass. --- Lib/test/test_capi/test_dict.py | 8 ++++++-- Objects/dictobject.c | 28 ++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index d3cc279cd3f955..f69ccbdbd1117d 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -223,6 +223,7 @@ def test_dict_getitemwitherror(self): # CRASHES getitem(NULL, 'a') def test_dict_contains(self): + # Test PyDict_Contains() contains = _testlimitedcapi.dict_contains dct = {'a': 1, '\U0001f40d': 2} self.assertTrue(contains(dct, 'a')) @@ -235,11 +236,12 @@ def test_dict_contains(self): self.assertRaises(TypeError, contains, {}, []) # unhashable # CRASHES contains({}, NULL) - # CRASHES contains(UserDict(), 'a') - # CRASHES contains(42, 'a') + self.assertRaises(SystemError, contains, UserDict(), 'a') + self.assertRaises(SystemError, contains, 42, 'a') # CRASHES contains(NULL, 'a') def test_dict_contains_string(self): + # Test PyDict_ContainsString() contains_string = _testcapi.dict_containsstring dct = {'a': 1, '\U0001f40d': 2} self.assertTrue(contains_string(dct, b'a')) @@ -251,6 +253,8 @@ def test_dict_contains_string(self): self.assertTrue(contains_string(dct2, b'a')) self.assertFalse(contains_string(dct2, b'b')) + self.assertRaises(SystemError, contains_string, UserDict(), 'a') + self.assertRaises(SystemError, contains_string, 42, 'a') # CRASHES contains({}, NULL) # CRASHES contains(NULL, b'a') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 276e1df21a80d8..0a8ba74c2287c1 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -140,6 +140,7 @@ static PyObject* frozendict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject* dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static int dict_merge(PyObject *a, PyObject *b, int override); +static int dict_contains(PyObject *op, PyObject *key); static int dict_merge_from_seq2(PyObject *d, PyObject *seq2, int override); @@ -4126,7 +4127,7 @@ dict_merge(PyObject *a, PyObject *b, int override) for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { if (override != 1) { - status = PyDict_Contains(a, key); + status = dict_contains(a, key); if (status != 0) { if (status > 0) { if (override == 0) { @@ -4484,7 +4485,7 @@ static PyObject * dict___contains___impl(PyDictObject *self, PyObject *key) /*[clinic end generated code: output=1b314e6da7687dae input=fe1cb42ad831e820]*/ { - int contains = PyDict_Contains((PyObject *)self, key); + int contains = dict_contains((PyObject *)self, key); if (contains < 0) { return NULL; } @@ -4984,9 +4985,8 @@ static PyMethodDef mapp_methods[] = { {NULL, NULL} /* sentinel */ }; -/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */ -int -PyDict_Contains(PyObject *op, PyObject *key) +static int +dict_contains(PyObject *op, PyObject *key) { Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { @@ -4997,6 +4997,18 @@ PyDict_Contains(PyObject *op, PyObject *key) return _PyDict_Contains_KnownHash(op, key, hash); } +/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */ +int +PyDict_Contains(PyObject *op, PyObject *key) +{ + if (!PyAnyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + + return dict_contains(op, key); +} + int PyDict_ContainsString(PyObject *op, const char *key) { @@ -5013,7 +5025,7 @@ PyDict_ContainsString(PyObject *op, const char *key) int _PyDict_Contains_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) { - PyDictObject *mp = (PyDictObject *)op; + PyDictObject *mp = _PyAnyDict_CAST(op); PyObject *value; Py_ssize_t ix; @@ -5042,7 +5054,7 @@ static PySequenceMethods dict_as_sequence = { 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ - PyDict_Contains, /* sq_contains */ + dict_contains, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }; @@ -6292,7 +6304,7 @@ dictkeys_contains(PyObject *self, PyObject *obj) _PyDictViewObject *dv = (_PyDictViewObject *)self; if (dv->dv_dict == NULL) return 0; - return PyDict_Contains((PyObject *)dv->dv_dict, obj); + return dict_contains((PyObject *)dv->dv_dict, obj); } static PySequenceMethods dictkeys_as_sequence = { From 25fc04d041bc28ee45db2576640164bc68dc4a45 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 20:07:30 +0100 Subject: [PATCH 201/498] gh-141510: Test frozendict in test_capi.test_dict (#145084) Complete PyDict_Clear() documentation. --- Doc/c-api/dict.rst | 3 + Lib/test/test_capi/test_dict.py | 566 ++++++++++++++++---------------- Modules/_testlimitedcapi/dict.c | 1 + 3 files changed, 290 insertions(+), 280 deletions(-) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 736f282e7bd47a..1d74140ea360ba 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -58,6 +58,9 @@ Dictionary objects Empty an existing dictionary of all key-value pairs. + Do nothing if the argument is not a :class:`dict` or a :class:`!dict` + subclass. + .. c:function:: int PyDict_Contains(PyObject *p, PyObject *key) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index f69ccbdbd1117d..d9de9bb4c8125d 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -34,6 +34,7 @@ class FrozenDictSubclass(frozendict): FROZENDICT_TYPES = (frozendict, FrozenDictSubclass) ANYDICT_TYPES = DICT_TYPES + FROZENDICT_TYPES MAPPING_TYPES = (UserDict,) +NOT_DICT_TYPES = FROZENDICT_TYPES + MAPPING_TYPES NOT_FROZENDICT_TYPES = DICT_TYPES + MAPPING_TYPES NOT_ANYDICT_TYPES = MAPPING_TYPES OTHER_TYPES = (lambda: [1], lambda: 42, object) # (list, int, object) @@ -42,24 +43,29 @@ class FrozenDictSubclass(frozendict): class CAPITest(unittest.TestCase): def test_dict_check(self): + # Test PyDict_Check() check = _testlimitedcapi.dict_check - self.assertTrue(check({1: 2})) - self.assertTrue(check(OrderedDict({1: 2}))) - self.assertFalse(check(UserDict({1: 2}))) - self.assertFalse(check([1, 2])) - self.assertFalse(check(object())) + for dict_type in DICT_TYPES: + self.assertTrue(check(dict_type({1: 2}))) + for test_type in NOT_DICT_TYPES: + self.assertFalse(check(test_type({1: 2}))) + for test_type in OTHER_TYPES: + self.assertFalse(check(test_type())) # CRASHES check(NULL) def test_dict_checkexact(self): + # Test PyDict_CheckExact() check = _testlimitedcapi.dict_checkexact - self.assertTrue(check({1: 2})) - self.assertFalse(check(OrderedDict({1: 2}))) - self.assertFalse(check(UserDict({1: 2}))) - self.assertFalse(check([1, 2])) - self.assertFalse(check(object())) + for dict_type in DICT_TYPES: + self.assertEqual(check(dict_type({1: 2})), dict_type == dict) + for test_type in NOT_DICT_TYPES: + self.assertFalse(check(test_type({1: 2}))) + for test_type in OTHER_TYPES: + self.assertFalse(check(test_type())) # CRASHES check(NULL) def test_dict_new(self): + # Test PyDict_New() dict_new = _testlimitedcapi.dict_new dct = dict_new() self.assertEqual(dct, {}) @@ -68,73 +74,84 @@ def test_dict_new(self): self.assertIsNot(dct2, dct) def test_dictproxy_new(self): + # Test PyDictProxy_New() dictproxy_new = _testlimitedcapi.dictproxy_new - for dct in {1: 2}, OrderedDict({1: 2}), UserDict({1: 2}): + for dict_type in ANYDICT_TYPES + MAPPING_TYPES: + if dict_type == DictSubclass: + continue + dct = dict_type({1: 2}) proxy = dictproxy_new(dct) self.assertIs(type(proxy), MappingProxyType) self.assertEqual(proxy, dct) with self.assertRaises(TypeError): proxy[1] = 3 self.assertEqual(proxy[1], 2) - dct[1] = 4 - self.assertEqual(proxy[1], 4) + if not isinstance(dct, frozendict): + dct[1] = 4 + self.assertEqual(proxy[1], 4) self.assertRaises(TypeError, dictproxy_new, []) self.assertRaises(TypeError, dictproxy_new, 42) # CRASHES dictproxy_new(NULL) def test_dict_copy(self): + # Test PyDict_Copy() copy = _testlimitedcapi.dict_copy - for dct in {1: 2}, OrderedDict({1: 2}): + for dict_type in ANYDICT_TYPES: + if issubclass(dict_type, frozendict): + expected_type = frozendict + else: + expected_type = dict + dct = dict_type({1: 2}) dct_copy = copy(dct) - self.assertIs(type(dct_copy), dict) + self.assertIs(type(dct_copy), expected_type) self.assertEqual(dct_copy, dct) - self.assertRaises(SystemError, copy, UserDict()) - self.assertRaises(SystemError, copy, []) - self.assertRaises(SystemError, copy, 42) + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, copy, test_type()) self.assertRaises(SystemError, copy, NULL) def test_dict_clear(self): + # Test PyDict_Clear() clear = _testlimitedcapi.dict_clear - dct = {1: 2} - clear(dct) - self.assertEqual(dct, {}) - - # NOTE: It is not safe to call it with OrderedDict. + for dict_type in DICT_TYPES: + if dict_type == OrderedDict: + # NOTE: It is not safe to call it with OrderedDict. + continue + dct = dict_type({1: 2}) + clear(dct) + self.assertEqual(dct, {}) # Has no effect for non-dicts. - dct = UserDict({1: 2}) - clear(dct) - self.assertEqual(dct, {1: 2}) + for test_type in NOT_DICT_TYPES: + dct = test_type({1: 2}) + clear(dct) + self.assertEqual(dct, {1: 2}) lst = [1, 2] clear(lst) self.assertEqual(lst, [1, 2]) clear(object()) - # CRASHES? clear(NULL) + # CRASHES clear(NULL) def test_dict_size(self): + # Test PyDict_Size() size = _testlimitedcapi.dict_size - self.assertEqual(size({1: 2}), 1) - self.assertEqual(size(OrderedDict({1: 2})), 1) + for dict_type in ANYDICT_TYPES: + self.assertEqual(size(dict_type({1: 2, 3: 4})), 2) - self.assertRaises(SystemError, size, UserDict()) - self.assertRaises(SystemError, size, []) - self.assertRaises(SystemError, size, 42) - self.assertRaises(SystemError, size, object()) + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, size, test_type()) self.assertRaises(SystemError, size, NULL) def test_dict_getitem(self): + # Test PyDict_GetItem() getitem = _testlimitedcapi.dict_getitem - dct = {'a': 1, '\U0001f40d': 2} - self.assertEqual(getitem(dct, 'a'), 1) - self.assertIs(getitem(dct, 'b'), KeyError) - self.assertEqual(getitem(dct, '\U0001f40d'), 2) - - dct2 = DictSubclass(dct) - self.assertEqual(getitem(dct2, 'a'), 1) - self.assertIs(getitem(dct2, 'b'), KeyError) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) with support.catch_unraisable_exception() as cm: self.assertIs(getitem({}, []), KeyError) # unhashable @@ -142,21 +159,20 @@ def test_dict_getitem(self): self.assertEqual(str(cm.unraisable.exc_value), "unhashable type: 'list'") - self.assertIs(getitem(42, 'a'), KeyError) - self.assertIs(getitem([1], 0), KeyError) + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertIs(getitem(test_type(), 'a'), KeyError) + # CRASHES getitem({}, NULL) # CRASHES getitem(NULL, 'a') def test_dict_getitemstring(self): + # Test PyDict_GetItemString() getitemstring = _testlimitedcapi.dict_getitemstring - dct = {'a': 1, '\U0001f40d': 2} - self.assertEqual(getitemstring(dct, b'a'), 1) - self.assertIs(getitemstring(dct, b'b'), KeyError) - self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) - - dct2 = DictSubclass(dct) - self.assertEqual(getitemstring(dct2, b'a'), 1) - self.assertIs(getitemstring(dct2, b'b'), KeyError) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertIs(getitemstring(dct, b'b'), KeyError) + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) with support.catch_unraisable_exception() as cm: self.assertIs(getitemstring({}, INVALID_UTF8), KeyError) @@ -164,225 +180,196 @@ def test_dict_getitemstring(self): self.assertRegex(str(cm.unraisable.exc_value), "'utf-8' codec can't decode") - self.assertIs(getitemstring(42, b'a'), KeyError) - self.assertIs(getitemstring([], b'a'), KeyError) + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertIs(getitemstring(test_type(), b'a'), KeyError) # CRASHES getitemstring({}, NULL) # CRASHES getitemstring(NULL, b'a') def test_dict_getitemref(self): + # Test PyDict_GetItemRef() getitem = _testcapi.dict_getitemref - dct = {'a': 1, '\U0001f40d': 2} - self.assertEqual(getitem(dct, 'a'), 1) - self.assertIs(getitem(dct, 'b'), KeyError) - self.assertEqual(getitem(dct, '\U0001f40d'), 2) - - dct2 = DictSubclass(dct) - self.assertEqual(getitem(dct2, 'a'), 1) - self.assertIs(getitem(dct2, 'b'), KeyError) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) - self.assertRaises(SystemError, getitem, 42, 'a') self.assertRaises(TypeError, getitem, {}, []) # unhashable - self.assertRaises(SystemError, getitem, [], 1) - self.assertRaises(SystemError, getitem, [], 'a') + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, getitem, test_type(), 'a') # CRASHES getitem({}, NULL) # CRASHES getitem(NULL, 'a') def test_dict_getitemstringref(self): + # Test PyDict_GetItemStringRef() getitemstring = _testcapi.dict_getitemstringref - dct = {'a': 1, '\U0001f40d': 2} - self.assertEqual(getitemstring(dct, b'a'), 1) - self.assertIs(getitemstring(dct, b'b'), KeyError) - self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) - - dct2 = DictSubclass(dct) - self.assertEqual(getitemstring(dct2, b'a'), 1) - self.assertIs(getitemstring(dct2, b'b'), KeyError) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertIs(getitemstring(dct, b'b'), KeyError) + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) - self.assertRaises(SystemError, getitemstring, 42, b'a') self.assertRaises(UnicodeDecodeError, getitemstring, {}, INVALID_UTF8) - self.assertRaises(SystemError, getitemstring, [], b'a') + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, getitemstring, test_type(), b'a') # CRASHES getitemstring({}, NULL) # CRASHES getitemstring(NULL, b'a') def test_dict_getitemwitherror(self): + # Test PyDict_GetItemWithError() getitem = _testlimitedcapi.dict_getitemwitherror - dct = {'a': 1, '\U0001f40d': 2} - self.assertEqual(getitem(dct, 'a'), 1) - self.assertIs(getitem(dct, 'b'), KeyError) - self.assertEqual(getitem(dct, '\U0001f40d'), 2) - - dct2 = DictSubclass(dct) - self.assertEqual(getitem(dct2, 'a'), 1) - self.assertIs(getitem(dct2, 'b'), KeyError) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) - self.assertRaises(SystemError, getitem, 42, 'a') self.assertRaises(TypeError, getitem, {}, []) # unhashable - self.assertRaises(SystemError, getitem, [], 1) - self.assertRaises(SystemError, getitem, [], 'a') + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, getitem, [], 'a') # CRASHES getitem({}, NULL) # CRASHES getitem(NULL, 'a') def test_dict_contains(self): # Test PyDict_Contains() contains = _testlimitedcapi.dict_contains - dct = {'a': 1, '\U0001f40d': 2} - self.assertTrue(contains(dct, 'a')) - self.assertFalse(contains(dct, 'b')) - self.assertTrue(contains(dct, '\U0001f40d')) - - dct2 = DictSubclass(dct) - self.assertTrue(contains(dct2, 'a')) - self.assertFalse(contains(dct2, 'b')) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertTrue(contains(dct, 'a')) + self.assertFalse(contains(dct, 'b')) + self.assertTrue(contains(dct, '\U0001f40d')) self.assertRaises(TypeError, contains, {}, []) # unhashable + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, contains, test_type(), 'a') + # CRASHES contains({}, NULL) - self.assertRaises(SystemError, contains, UserDict(), 'a') - self.assertRaises(SystemError, contains, 42, 'a') # CRASHES contains(NULL, 'a') def test_dict_contains_string(self): # Test PyDict_ContainsString() contains_string = _testcapi.dict_containsstring - dct = {'a': 1, '\U0001f40d': 2} - self.assertTrue(contains_string(dct, b'a')) - self.assertFalse(contains_string(dct, b'b')) - self.assertTrue(contains_string(dct, '\U0001f40d'.encode())) - self.assertRaises(UnicodeDecodeError, contains_string, dct, INVALID_UTF8) - - dct2 = DictSubclass(dct) - self.assertTrue(contains_string(dct2, b'a')) - self.assertFalse(contains_string(dct2, b'b')) - - self.assertRaises(SystemError, contains_string, UserDict(), 'a') - self.assertRaises(SystemError, contains_string, 42, 'a') + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, '\U0001f40d': 2}) + self.assertTrue(contains_string(dct, b'a')) + self.assertFalse(contains_string(dct, b'b')) + self.assertTrue(contains_string(dct, '\U0001f40d'.encode())) + self.assertRaises(UnicodeDecodeError, contains_string, dct, INVALID_UTF8) + + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, contains_string, test_type(), b'a') + # CRASHES contains({}, NULL) # CRASHES contains(NULL, b'a') def test_dict_setitem(self): + # Test PyDict_SetItem() setitem = _testlimitedcapi.dict_setitem - dct = {} - setitem(dct, 'a', 5) - self.assertEqual(dct, {'a': 5}) - setitem(dct, '\U0001f40d', 8) - self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) - - dct2 = DictSubclass() - setitem(dct2, 'a', 5) - self.assertEqual(dct2, {'a': 5}) + for dict_type in DICT_TYPES: + dct = dict_type() + setitem(dct, 'a', 5) + self.assertEqual(dct, {'a': 5}) + setitem(dct, '\U0001f40d', 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable - self.assertRaises(SystemError, setitem, UserDict(), 'a', 5) - self.assertRaises(SystemError, setitem, [1], 0, 5) - self.assertRaises(SystemError, setitem, 42, 'a', 5) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, setitem, test_type(), 'a', 5) # CRASHES setitem({}, NULL, 5) # CRASHES setitem({}, 'a', NULL) # CRASHES setitem(NULL, 'a', 5) def test_dict_setitemstring(self): + # Test PyDict_SetItemString() setitemstring = _testlimitedcapi.dict_setitemstring - dct = {} - setitemstring(dct, b'a', 5) - self.assertEqual(dct, {'a': 5}) - setitemstring(dct, '\U0001f40d'.encode(), 8) - self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) - - dct2 = DictSubclass() - setitemstring(dct2, b'a', 5) - self.assertEqual(dct2, {'a': 5}) + for dict_type in DICT_TYPES: + dct = dict_type() + setitemstring(dct, b'a', 5) + self.assertEqual(dct, {'a': 5}) + setitemstring(dct, '\U0001f40d'.encode(), 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) self.assertRaises(UnicodeDecodeError, setitemstring, {}, INVALID_UTF8, 5) - self.assertRaises(SystemError, setitemstring, UserDict(), b'a', 5) - self.assertRaises(SystemError, setitemstring, 42, b'a', 5) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, setitemstring, test_type(), b'a', 5) # CRASHES setitemstring({}, NULL, 5) # CRASHES setitemstring({}, b'a', NULL) # CRASHES setitemstring(NULL, b'a', 5) def test_dict_delitem(self): + # Test PyDict_DelItem() delitem = _testlimitedcapi.dict_delitem - dct = {'a': 1, 'c': 2, '\U0001f40d': 3} - delitem(dct, 'a') - self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) - self.assertRaises(KeyError, delitem, dct, 'b') - delitem(dct, '\U0001f40d') - self.assertEqual(dct, {'c': 2}) - - dct2 = DictSubclass({'a': 1, 'c': 2}) - delitem(dct2, 'a') - self.assertEqual(dct2, {'c': 2}) - self.assertRaises(KeyError, delitem, dct2, 'b') + for dict_type in DICT_TYPES: + dct = dict_type({'a': 1, 'c': 2, '\U0001f40d': 3}) + delitem(dct, 'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitem, dct, 'b') + delitem(dct, '\U0001f40d') + self.assertEqual(dct, {'c': 2}) self.assertRaises(TypeError, delitem, {}, []) # unhashable - self.assertRaises(SystemError, delitem, UserDict({'a': 1}), 'a') - self.assertRaises(SystemError, delitem, [1], 0) - self.assertRaises(SystemError, delitem, 42, 'a') + for test_type in NOT_DICT_TYPES: + self.assertRaises(SystemError, delitem, test_type({'a': 1}), 'a') + for test_type in OTHER_TYPES: + self.assertRaises(SystemError, delitem, test_type(), 'a') # CRASHES delitem({}, NULL) # CRASHES delitem(NULL, 'a') def test_dict_delitemstring(self): + # Test PyDict_DelItemString() delitemstring = _testlimitedcapi.dict_delitemstring - dct = {'a': 1, 'c': 2, '\U0001f40d': 3} - delitemstring(dct, b'a') - self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) - self.assertRaises(KeyError, delitemstring, dct, b'b') - delitemstring(dct, '\U0001f40d'.encode()) - self.assertEqual(dct, {'c': 2}) - - dct2 = DictSubclass({'a': 1, 'c': 2}) - delitemstring(dct2, b'a') - self.assertEqual(dct2, {'c': 2}) - self.assertRaises(KeyError, delitemstring, dct2, b'b') + for dict_type in DICT_TYPES: + dct = dict_type({'a': 1, 'c': 2, '\U0001f40d': 3}) + delitemstring(dct, b'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitemstring, dct, b'b') + delitemstring(dct, '\U0001f40d'.encode()) + self.assertEqual(dct, {'c': 2}) self.assertRaises(UnicodeDecodeError, delitemstring, {}, INVALID_UTF8) - self.assertRaises(SystemError, delitemstring, UserDict({'a': 1}), b'a') - self.assertRaises(SystemError, delitemstring, 42, b'a') + for test_type in NOT_DICT_TYPES: + self.assertRaises(SystemError, delitemstring, test_type({'a': 1}), b'a') + for test_type in OTHER_TYPES: + self.assertRaises(SystemError, delitemstring, test_type(), b'a') # CRASHES delitemstring({}, NULL) # CRASHES delitemstring(NULL, b'a') def test_dict_setdefault(self): + # Test PyDict_SetDefault() setdefault = _testcapi.dict_setdefault - dct = {} - self.assertEqual(setdefault(dct, 'a', 5), 5) - self.assertEqual(dct, {'a': 5}) - self.assertEqual(setdefault(dct, 'a', 8), 5) - self.assertEqual(dct, {'a': 5}) - - dct2 = DictSubclass() - self.assertEqual(setdefault(dct2, 'a', 5), 5) - self.assertEqual(dct2, {'a': 5}) - self.assertEqual(setdefault(dct2, 'a', 8), 5) - self.assertEqual(dct2, {'a': 5}) + for dict_type in DICT_TYPES: + dct = dict_type() + self.assertEqual(setdefault(dct, 'a', 5), 5) + self.assertEqual(dct, {'a': 5}) + self.assertEqual(setdefault(dct, 'a', 8), 5) + self.assertEqual(dct, {'a': 5}) self.assertRaises(TypeError, setdefault, {}, [], 5) # unhashable - self.assertRaises(SystemError, setdefault, UserDict(), 'a', 5) - self.assertRaises(SystemError, setdefault, [1], 0, 5) - self.assertRaises(SystemError, setdefault, 42, 'a', 5) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, setdefault, test_type(), 'a', 5) # CRASHES setdefault({}, NULL, 5) # CRASHES setdefault({}, 'a', NULL) # CRASHES setdefault(NULL, 'a', 5) def test_dict_setdefaultref(self): + # Test PyDict_SetDefaultRef() setdefault = _testcapi.dict_setdefaultref - dct = {} - self.assertEqual(setdefault(dct, 'a', 5), 5) - self.assertEqual(dct, {'a': 5}) - self.assertEqual(setdefault(dct, 'a', 8), 5) - self.assertEqual(dct, {'a': 5}) - - dct2 = DictSubclass() - self.assertEqual(setdefault(dct2, 'a', 5), 5) - self.assertEqual(dct2, {'a': 5}) - self.assertEqual(setdefault(dct2, 'a', 8), 5) - self.assertEqual(dct2, {'a': 5}) + for dict_type in DICT_TYPES: + dct = dict_type() + self.assertEqual(setdefault(dct, 'a', 5), 5) + self.assertEqual(dct, {'a': 5}) + self.assertEqual(setdefault(dct, 'a', 8), 5) + self.assertEqual(dct, {'a': 5}) self.assertRaises(TypeError, setdefault, {}, [], 5) # unhashable - self.assertRaises(SystemError, setdefault, UserDict(), 'a', 5) - self.assertRaises(SystemError, setdefault, [1], 0, 5) - self.assertRaises(SystemError, setdefault, 42, 'a', 5) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, setdefault, test_type(), 'a', 5) # CRASHES setdefault({}, NULL, 5) # CRASHES setdefault({}, 'a', NULL) # CRASHES setdefault(NULL, 'a', 5) def test_mapping_keys_valuesitems(self): + # Test PyDict_Keys(), PyDict_Values() and PyDict_Items() class BadMapping(dict): def keys(self): return None @@ -391,7 +378,8 @@ def values(self): def items(self): return None dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} - for mapping in [dict_obj, DictSubclass(dict_obj), BadMapping(dict_obj)]: + for dict_type in ANYDICT_TYPES + (BadMapping,): + mapping = dict_type(dict_obj) self.assertListEqual(_testlimitedcapi.dict_keys(mapping), list(dict_obj.keys())) self.assertListEqual(_testlimitedcapi.dict_values(mapping), @@ -399,51 +387,57 @@ def items(self): self.assertListEqual(_testlimitedcapi.dict_items(mapping), list(dict_obj.items())) - def test_dict_keys_valuesitems_bad_arg(self): - for mapping in UserDict(), [], object(): + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + mapping = test_type() self.assertRaises(SystemError, _testlimitedcapi.dict_keys, mapping) self.assertRaises(SystemError, _testlimitedcapi.dict_values, mapping) self.assertRaises(SystemError, _testlimitedcapi.dict_items, mapping) def test_dict_next(self): + # Test PyDict_Next() dict_next = _testlimitedcapi.dict_next self.assertIsNone(dict_next({}, 0)) - dct = {'a': 1, 'b': 2, 'c': 3} - pos = 0 - pairs = [] - while True: - res = dict_next(dct, pos) - if res is None: - break - rc, pos, key, value = res - self.assertEqual(rc, 1) - pairs.append((key, value)) - self.assertEqual(pairs, list(dct.items())) + for dict_type in ANYDICT_TYPES: + dct = dict_type({'a': 1, 'b': 2, 'c': 3}) + pos = 0 + pairs = [] + while True: + res = dict_next(dct, pos) + if res is None: + break + rc, pos, key, value = res + self.assertEqual(rc, 1) + pairs.append((key, value)) + self.assertEqual(pairs, list(dct.items())) + + for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + dct = test_type() + pos = 0 + self.assertEqual(dict_next(dct, pos), None) # CRASHES dict_next(NULL, 0) def test_dict_update(self): # Test PyDict_Update() update = _testlimitedcapi.dict_update - for cls1 in dict, DictSubclass: - for cls2 in dict, DictSubclass, UserDict: + for cls1 in DICT_TYPES: + for cls2 in ANYDICT_TYPES + MAPPING_TYPES: dct = cls1({'a': 1, 'b': 2}) update(dct, cls2({'b': 3, 'c': 4})) self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) self.assertRaises(AttributeError, update, {}, []) self.assertRaises(AttributeError, update, {}, 42) - self.assertRaises(SystemError, update, UserDict(), {}) - self.assertRaises(SystemError, update, frozendict(), {}) - self.assertRaises(SystemError, update, 42, {}) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, update, test_type(), {}) self.assertRaises(SystemError, update, {}, NULL) self.assertRaises(SystemError, update, NULL, {}) def test_dict_merge(self): # Test PyDict_Merge() merge = _testlimitedcapi.dict_merge - for cls1 in dict, DictSubclass: - for cls2 in dict, DictSubclass, UserDict: + for cls1 in DICT_TYPES: + for cls2 in ANYDICT_TYPES + MAPPING_TYPES: dct = cls1({'a': 1, 'b': 2}) merge(dct, cls2({'b': 3, 'c': 4}), 0) self.assertEqual(dct, {'a': 1, 'b': 2, 'c': 4}) @@ -453,16 +447,15 @@ def test_dict_merge(self): self.assertRaises(AttributeError, merge, {}, [], 0) self.assertRaises(AttributeError, merge, {}, 42, 0) - self.assertRaises(SystemError, merge, UserDict(), {}, 0) - self.assertRaises(SystemError, merge, frozendict(), {}, 0) - self.assertRaises(SystemError, merge, 42, {}, 0) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, merge, test_type(), {}, 0) self.assertRaises(SystemError, merge, {}, NULL, 0) self.assertRaises(SystemError, merge, NULL, {}, 0) def test_dict_mergefromseq2(self): # Test PyDict_MergeFromSeq2() mergefromseq2 = _testlimitedcapi.dict_mergefromseq2 - for cls1 in dict, DictSubclass: + for cls1 in DICT_TYPES: for cls2 in list, iter: dct = cls1({'a': 1, 'b': 2}) mergefromseq2(dct, cls2([('b', 3), ('c', 4)]), 0) @@ -475,8 +468,8 @@ def test_dict_mergefromseq2(self): self.assertRaises(ValueError, mergefromseq2, {}, [(1, 2, 3)], 0) self.assertRaises(TypeError, mergefromseq2, {}, [1], 0) self.assertRaises(TypeError, mergefromseq2, {}, 42, 0) - self.assertRaises(SystemError, mergefromseq2, UserDict(), [], 0) - self.assertRaises(SystemError, mergefromseq2, 42, [], 0) + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + self.assertRaises(SystemError, mergefromseq2, test_type(), [], 0) # CRASHES mergefromseq2({}, NULL, 0) # CRASHES mergefromseq2(NULL, {}, 0) @@ -485,39 +478,47 @@ def test_dict_pop(self): dict_pop = _testcapi.dict_pop dict_pop_null = _testcapi.dict_pop_null - # key present, get removed value - mydict = {"key": "value", "key2": "value2"} - self.assertEqual(dict_pop(mydict, "key"), (1, "value")) - self.assertEqual(mydict, {"key2": "value2"}) - self.assertEqual(dict_pop(mydict, "key2"), (1, "value2")) - self.assertEqual(mydict, {}) - - # key present, ignore removed value - mydict = {"key": "value", "key2": "value2"} - self.assertEqual(dict_pop_null(mydict, "key"), 1) - self.assertEqual(mydict, {"key2": "value2"}) - self.assertEqual(dict_pop_null(mydict, "key2"), 1) - self.assertEqual(mydict, {}) - - # key missing, expect removed value; empty dict has a fast path - self.assertEqual(dict_pop({}, "key"), (0, NULL)) - self.assertEqual(dict_pop({"a": 1}, "key"), (0, NULL)) - - # key missing, ignored removed value; empty dict has a fast path - self.assertEqual(dict_pop_null({}, "key"), 0) - self.assertEqual(dict_pop_null({"a": 1}, "key"), 0) - - # dict error - not_dict = UserDict({1: 2}) - self.assertRaises(SystemError, dict_pop, not_dict, "key") - self.assertRaises(SystemError, dict_pop_null, not_dict, "key") - - # key error; don't hash key if dict is empty - not_hashable_key = ["list"] - self.assertEqual(dict_pop({}, not_hashable_key), (0, NULL)) - with self.assertRaises(TypeError): - dict_pop({'key': 1}, not_hashable_key) - dict_pop({}, NULL) # key is not checked if dict is empty + for dict_type in DICT_TYPES: + # key present, get removed value + mydict = dict_type({"key": "value", "key2": "value2"}) + self.assertEqual(dict_pop(mydict, "key"), (1, "value")) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_pop(mydict, "key2"), (1, "value2")) + self.assertEqual(mydict, {}) + + # key present, ignore removed value + mydict = dict_type({"key": "value", "key2": "value2"}) + self.assertEqual(dict_pop_null(mydict, "key"), 1) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_pop_null(mydict, "key2"), 1) + self.assertEqual(mydict, {}) + + # key missing, expect removed value; empty dict has a fast path + mydict = dict_type() + self.assertEqual(dict_pop(mydict, "key"), (0, NULL)) + mydict = dict_type({"a": 1}) + self.assertEqual(dict_pop(mydict, "key"), (0, NULL)) + + # key missing, ignored removed value; empty dict has a fast path + mydict = dict_type() + self.assertEqual(dict_pop_null(mydict, "key"), 0) + mydict = dict_type({"a": 1}) + self.assertEqual(dict_pop_null(mydict, "key"), 0) + + # key error; don't hash key if dict is empty + not_hashable_key = ["list"] + mydict = dict_type() + self.assertEqual(dict_pop(mydict, not_hashable_key), (0, NULL)) + dict_pop(mydict, NULL) # key is not checked if dict is empty + mydict = dict_type({'key': 1}) + with self.assertRaises(TypeError): + dict_pop(mydict, not_hashable_key) + + # wrong dict type + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + not_dict = test_type() + self.assertRaises(SystemError, dict_pop, not_dict, "key") + self.assertRaises(SystemError, dict_pop_null, not_dict, "key") # CRASHES dict_pop(NULL, "key") # CRASHES dict_pop({"a": 1}, NULL) @@ -527,41 +528,46 @@ def test_dict_popstring(self): dict_popstring = _testcapi.dict_popstring dict_popstring_null = _testcapi.dict_popstring_null - # key present, get removed value - mydict = {"key": "value", "key2": "value2"} - self.assertEqual(dict_popstring(mydict, "key"), (1, "value")) - self.assertEqual(mydict, {"key2": "value2"}) - self.assertEqual(dict_popstring(mydict, "key2"), (1, "value2")) - self.assertEqual(mydict, {}) - - # key present, ignore removed value - mydict = {"key": "value", "key2": "value2"} - self.assertEqual(dict_popstring_null(mydict, "key"), 1) - self.assertEqual(mydict, {"key2": "value2"}) - self.assertEqual(dict_popstring_null(mydict, "key2"), 1) - self.assertEqual(mydict, {}) - - # key missing; empty dict has a fast path - self.assertEqual(dict_popstring({}, "key"), (0, NULL)) - self.assertEqual(dict_popstring_null({}, "key"), 0) - self.assertEqual(dict_popstring({"a": 1}, "key"), (0, NULL)) - self.assertEqual(dict_popstring_null({"a": 1}, "key"), 0) - - # non-ASCII key - non_ascii = '\U0001f40d' - dct = {'\U0001f40d': 123} - self.assertEqual(dict_popstring(dct, '\U0001f40d'.encode()), (1, 123)) - dct = {'\U0001f40d': 123} - self.assertEqual(dict_popstring_null(dct, '\U0001f40d'.encode()), 1) - - # dict error - not_dict = UserDict({1: 2}) - self.assertRaises(SystemError, dict_popstring, not_dict, "key") - self.assertRaises(SystemError, dict_popstring_null, not_dict, "key") - - # key error - self.assertRaises(UnicodeDecodeError, dict_popstring, {1: 2}, INVALID_UTF8) - self.assertRaises(UnicodeDecodeError, dict_popstring_null, {1: 2}, INVALID_UTF8) + for dict_type in DICT_TYPES: + # key present, get removed value + mydict = dict_type({"key": "value", "key2": "value2"}) + self.assertEqual(dict_popstring(mydict, "key"), (1, "value")) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_popstring(mydict, "key2"), (1, "value2")) + self.assertEqual(mydict, {}) + + # key present, ignore removed value + mydict = dict_type({"key": "value", "key2": "value2"}) + self.assertEqual(dict_popstring_null(mydict, "key"), 1) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_popstring_null(mydict, "key2"), 1) + self.assertEqual(mydict, {}) + + # key missing; empty dict has a fast path + mydict = dict_type() + self.assertEqual(dict_popstring(mydict, "key"), (0, NULL)) + self.assertEqual(dict_popstring_null(mydict, "key"), 0) + mydict = dict_type({"a": 1}) + self.assertEqual(dict_popstring(mydict, "key"), (0, NULL)) + self.assertEqual(dict_popstring_null(mydict, "key"), 0) + + # non-ASCII key + non_ascii = '\U0001f40d' + dct = dict_type({'\U0001f40d': 123}) + self.assertEqual(dict_popstring(dct, '\U0001f40d'.encode()), (1, 123)) + dct = dict_type({'\U0001f40d': 123}) + self.assertEqual(dict_popstring_null(dct, '\U0001f40d'.encode()), 1) + + # key error + mydict = dict_type({1: 2}) + self.assertRaises(UnicodeDecodeError, dict_popstring, mydict, INVALID_UTF8) + self.assertRaises(UnicodeDecodeError, dict_popstring_null, mydict, INVALID_UTF8) + + # wrong dict type + for test_type in NOT_DICT_TYPES + OTHER_TYPES: + not_dict = test_type() + self.assertRaises(SystemError, dict_popstring, not_dict, "key") + self.assertRaises(SystemError, dict_popstring_null, not_dict, "key") # CRASHES dict_popstring(NULL, "key") # CRASHES dict_popstring({}, NULL) diff --git a/Modules/_testlimitedcapi/dict.c b/Modules/_testlimitedcapi/dict.c index ec32712eef6434..b9acda00897ad4 100644 --- a/Modules/_testlimitedcapi/dict.c +++ b/Modules/_testlimitedcapi/dict.c @@ -32,6 +32,7 @@ dictproxy_new(PyObject *self, PyObject *obj) static PyObject * dict_clear(PyObject *self, PyObject *obj) { + NULLABLE(obj); PyDict_Clear(obj); Py_RETURN_NONE; } From fbd3b25e00fdfd5e0a30c64848624dc471987c30 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 20:08:28 +0100 Subject: [PATCH 202/498] gh-141510: Change dict_unhashable_type() error message for frozendict (#145085) --- Lib/test/test_dict.py | 29 +++++++++++++++++++++++++++++ Objects/dictobject.c | 37 +++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 9cfaa4a86fa9fd..14b501360d0b8e 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1871,6 +1871,35 @@ def test_pickle_iter(self): self.assertEqual(list(unpickled), expected) self.assertEqual(list(it), expected) + def test_unhashable_key(self): + d = frozendict(a=1) + key = [1, 2, 3] + + def check_unhashable_key(): + msg = "cannot use 'list' as a frozendict key (unhashable type: 'list')" + return self.assertRaisesRegex(TypeError, re.escape(msg)) + + with check_unhashable_key(): + key in d + with check_unhashable_key(): + d[key] + with check_unhashable_key(): + d.get(key) + + # Only TypeError exception is overridden, + # other exceptions are left unchanged. + class HashError: + def __hash__(self): + raise KeyError('error') + + key2 = HashError() + with self.assertRaises(KeyError): + key2 in d + with self.assertRaises(KeyError): + d[key2] + with self.assertRaises(KeyError): + d.get(key2) + if __name__ == "__main__": unittest.main() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 0a8ba74c2287c1..6c802ca569d48c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2377,7 +2377,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) } static void -dict_unhashable_type(PyObject *key) +dict_unhashable_type(PyObject *op, PyObject *key) { PyObject *exc = PyErr_GetRaisedException(); assert(exc != NULL); @@ -2386,9 +2386,14 @@ dict_unhashable_type(PyObject *key) return; } - PyErr_Format(PyExc_TypeError, - "cannot use '%T' as a dict key (%S)", - key, exc); + const char *errmsg; + if (PyObject_IsInstance(op, (PyObject*)&PyFrozenDict_Type)) { + errmsg = "cannot use '%T' as a frozendict key (%S)"; + } + else { + errmsg = "cannot use '%T' as a dict key (%S)"; + } + PyErr_Format(PyExc_TypeError, errmsg, key, exc); Py_DECREF(exc); } @@ -2401,7 +2406,7 @@ _PyDict_LookupIndexAndValue(PyDictObject *mp, PyObject *key, PyObject **value) Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type((PyObject*)mp, key); return -1; } @@ -2505,7 +2510,7 @@ PyDict_GetItemRef(PyObject *op, PyObject *key, PyObject **result) Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(op, key); *result = NULL; return -1; } @@ -2521,7 +2526,7 @@ _PyDict_GetItemRef_Unicode_LockHeld(PyDictObject *op, PyObject *key, PyObject ** Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type((PyObject*)op, key); *result = NULL; return -1; } @@ -2559,7 +2564,7 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) } hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(op, key); return NULL; } @@ -2705,7 +2710,7 @@ setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type((PyObject*)mp, key); Py_DECREF(key); Py_DECREF(value); return -1; @@ -2864,7 +2869,7 @@ PyDict_DelItem(PyObject *op, PyObject *key) assert(key); Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(op, key); return -1; } @@ -3183,7 +3188,7 @@ pop_lock_held(PyObject *op, PyObject *key, PyObject **result) Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(op, key); if (result) { *result = NULL; } @@ -3596,7 +3601,7 @@ dict_subscript(PyObject *self, PyObject *key) hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(self, key); return NULL; } ix = _Py_dict_lookup_threadsafe(mp, key, hash, &value); @@ -4515,7 +4520,7 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type((PyObject*)self, key); return NULL; } ix = _Py_dict_lookup_threadsafe(self, key, hash, &val); @@ -4547,7 +4552,7 @@ dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_valu hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(d, key); if (result) { *result = NULL; } @@ -4990,7 +4995,7 @@ dict_contains(PyObject *op, PyObject *key) { Py_hash_t hash = _PyObject_HashFast(key); if (hash == -1) { - dict_unhashable_type(key); + dict_unhashable_type(op, key); return -1; } @@ -7066,7 +7071,7 @@ _PyDict_SetItem_LockHeld(PyDictObject *dict, PyObject *name, PyObject *value) if (value == NULL) { Py_hash_t hash = _PyObject_HashFast(name); if (hash == -1) { - dict_unhashable_type(name); + dict_unhashable_type((PyObject*)dict, name); return -1; } return _PyDict_DelItem_KnownHash_LockHeld((PyObject *)dict, name, hash); From 2be2dd5fc219a5c252d72f351c85db14314bfca5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 Feb 2026 22:06:59 +0100 Subject: [PATCH 203/498] gh-145076: Check globals type in __lazy_import__() (#145086) --- Lib/test/test_import/test_lazy_imports.py | 2 ++ Python/bltinmodule.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py index dc185c070acc62..39d37f68e0b47b 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_import/test_lazy_imports.py @@ -401,6 +401,8 @@ def test_dunder_lazy_import_invalid_arguments(self): with self.assertRaises(ValueError): __lazy_import__("sys", level=-1) + with self.assertRaises(TypeError): + __lazy_import__("sys", globals=1) def test_dunder_lazy_import_builtins(self): """__lazy_import__ should use module's __builtins__ for __import__.""" diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 493a6e0413d8eb..301125051f3b0e 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -318,6 +318,12 @@ builtin___lazy_import___impl(PyObject *module, PyObject *name, locals = globals; } + if (!PyDict_Check(globals)) { + PyErr_Format(PyExc_TypeError, + "expect dict for globals, got %T", globals); + return NULL; + } + if (PyDict_GetItemRef(globals, &_Py_ID(__builtins__), &builtins) < 0) { return NULL; } From faea32b729e132172d39d54517822e772ad0017a Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Sun, 22 Feb 2026 19:01:27 +1100 Subject: [PATCH 204/498] gh-145092: Fix compiler warning for memchr() and wcschr() returning const pointer (GH-145093) --- Objects/stringlib/fastsearch.h | 4 ++-- Python/preconfig.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index b447865c986bef..26bb0555ca9b6c 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -69,8 +69,8 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) and UCS4 representations. */ if (needle != 0) { do { - void *candidate = memchr(p, needle, - (e - p) * sizeof(STRINGLIB_CHAR)); + const void *candidate = memchr(p, needle, + (e - p) * sizeof(STRINGLIB_CHAR)); if (candidate == NULL) return -1; s1 = p; diff --git a/Python/preconfig.c b/Python/preconfig.c index e4cd10d9e3d40d..0fdc0a87317712 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -584,7 +584,7 @@ _Py_get_xoption(const PyWideStringList *xoptions, const wchar_t *name) for (Py_ssize_t i=0; i < xoptions->length; i++) { const wchar_t *option = xoptions->items[i]; size_t len; - wchar_t *sep = wcschr(option, L'='); + const wchar_t *sep = wcschr(option, L'='); if (sep != NULL) { len = (sep - option); } @@ -615,7 +615,7 @@ preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline) const wchar_t *xopt; xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); if (xopt) { - wchar_t *sep = wcschr(xopt, L'='); + const wchar_t *sep = wcschr(xopt, L'='); if (sep) { xopt = sep + 1; if (wcscmp(xopt, L"1") == 0) { From 5944a539b91cc6bd140c64a3530d08015a4f8c30 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:02:15 +0100 Subject: [PATCH 205/498] Fix warnings on main (GH-145104) --- Modules/unicodedata.c | 2 +- Python/optimizer.c | 4 +++- Python/optimizer_bytecodes.c | 12 ++++++++---- Python/optimizer_cases.c.h | 12 ++++++++---- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index f20726a937ce38..27bdd19c409471 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1493,7 +1493,7 @@ _getcode(const char* name, int namelen, Py_UCS4* code) } if (i < (int)Py_ARRAY_LENGTH(derived_name_prefixes)) { - Py_UCS4 v = parse_hex_code(name + prefixlen, namelen - prefixlen); + Py_UCS4 v = parse_hex_code(name + prefixlen, namelen - (int)prefixlen); if (find_prefix_id(v) != i) { return 0; } diff --git a/Python/optimizer.c b/Python/optimizer.c index f075e28d71e0f8..6a575c8573724a 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -40,6 +40,7 @@ #define _PyExecutorObject_CAST(op) ((_PyExecutorObject *)(op)) +#ifndef Py_GIL_DISABLED static bool has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr) { @@ -110,6 +111,7 @@ insert_executor(PyCodeObject *code, _Py_CODEUNIT *instr, int index, _PyExecutorO instr->op.code = ENTER_EXECUTOR; instr->op.arg = index; } +#endif // Py_GIL_DISABLED static _PyExecutorObject * make_executor_from_uops(_PyThreadStateImpl *tstate, _PyUOpInstruction *buffer, int length, const _PyBloomFilter *dependencies); @@ -128,7 +130,6 @@ _PyOptimizer_Optimize( _PyInterpreterFrame *frame, PyThreadState *tstate) { _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; - int chain_depth = _tstate->jit_tracer_state->initial_state.chain_depth; PyInterpreterState *interp = _PyInterpreterState_GET(); if (!interp->jit) { // gh-140936: It is possible that interp->jit will become false during @@ -152,6 +153,7 @@ _PyOptimizer_Optimize( // make progress in order to avoid infinite loops or excessively-long // side-exit chains. We can only insert the executor into the bytecode if // this is true, since a deopt won't infinitely re-enter the executor: + int chain_depth = _tstate->jit_tracer_state->initial_state.chain_depth; chain_depth %= MAX_CHAIN_DEPTH; bool progress_needed = chain_depth == 0; PyCodeObject *code = (PyCodeObject *)_tstate->jit_tracer_state->initial_state.code; diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 228bd51a28bb69..4e4aec2f37e29b 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1641,7 +1641,8 @@ dummy_func(void) { } op(_GUARD_IP__PUSH_FRAME, (ip/4 --)) { - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + (void)ip; + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); // TO DO // Normal function calls to known functions // do not need an IP guard. @@ -1659,24 +1660,27 @@ dummy_func(void) { } op(_GUARD_IP_YIELD_VALUE, (ip/4 --)) { + (void)ip; if (ctx->frame->caller) { REPLACE_OP(this_instr, _NOP, 0, 0); } - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); } op(_GUARD_IP_RETURN_VALUE, (ip/4 --)) { + (void)ip; if (ctx->frame->caller) { REPLACE_OP(this_instr, _NOP, 0, 0); } - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); } op(_GUARD_IP_RETURN_GENERATOR, (ip/4 --)) { + (void)ip; if (ctx->frame->caller) { REPLACE_OP(this_instr, _NOP, 0, 0); } - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index a93e85329297cd..286fe014b65f0e 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -4159,34 +4159,38 @@ case _GUARD_IP__PUSH_FRAME: { PyObject *ip = (PyObject *)this_instr->operand0; - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + (void)ip; + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); break; } case _GUARD_IP_YIELD_VALUE: { PyObject *ip = (PyObject *)this_instr->operand0; + (void)ip; if (ctx->frame->caller) { REPLACE_OP(this_instr, _NOP, 0, 0); } - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); break; } case _GUARD_IP_RETURN_VALUE: { PyObject *ip = (PyObject *)this_instr->operand0; + (void)ip; if (ctx->frame->caller) { REPLACE_OP(this_instr, _NOP, 0, 0); } - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); break; } case _GUARD_IP_RETURN_GENERATOR: { PyObject *ip = (PyObject *)this_instr->operand0; + (void)ip; if (ctx->frame->caller) { REPLACE_OP(this_instr, _NOP, 0, 0); } - stack_pointer = sym_set_stack_depth(this_instr->operand1, stack_pointer); + stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer); break; } From 819ea3ca6836026bc611d0c8ea1cd5e95cbefc09 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sun, 22 Feb 2026 10:43:35 -0800 Subject: [PATCH 206/498] Refactor jit.yml (#144577) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/workflows/jit.yml | 183 ++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 95 deletions(-) diff --git a/.github/workflows/jit.yml b/.github/workflows/jit.yml index 9188839b26ee71..da9c75ec75391a 100644 --- a/.github/workflows/jit.yml +++ b/.github/workflows/jit.yml @@ -1,7 +1,7 @@ name: JIT on: pull_request: - paths: + paths: &paths - '**jit**' - 'Python/bytecodes.c' - 'Python/optimizer*.c' @@ -12,16 +12,7 @@ on: - '!**/*.md' - '!**/*.ini' push: - paths: - - '**jit**' - - 'Python/bytecodes.c' - - 'Python/optimizer*.c' - - 'Python/executor_cases.c.h' - - 'Python/optimizer_cases.c.h' - - '**_testinternalcapi**' - - '!Python/perf_jit_trampoline.c' - - '!**/*.md' - - '!**/*.ini' + paths: *paths workflow_dispatch: permissions: @@ -33,12 +24,13 @@ concurrency: env: FORCE_COLOR: 1 + LLVM_VERSION: 21 jobs: interpreter: name: Interpreter (Debug) runs-on: ubuntu-24.04 - timeout-minutes: 90 + timeout-minutes: 60 steps: - uses: actions/checkout@v6 with: @@ -50,11 +42,12 @@ jobs: - name: Test tier two interpreter run: | ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - jit: + + windows: name: ${{ matrix.target }} (${{ matrix.debug && 'Debug' || 'Release' }}) - needs: interpreter + runs-on: ${{ matrix.runner }} - timeout-minutes: 90 + timeout-minutes: 60 strategy: fail-fast: false matrix: @@ -62,15 +55,9 @@ jobs: - i686-pc-windows-msvc/msvc - x86_64-pc-windows-msvc/msvc - aarch64-pc-windows-msvc/msvc - - x86_64-apple-darwin/clang - - aarch64-apple-darwin/clang - - x86_64-unknown-linux-gnu/gcc - - aarch64-unknown-linux-gnu/gcc debug: - true - false - llvm: - - 21 include: - target: i686-pc-windows-msvc/msvc architecture: Win32 @@ -81,18 +68,6 @@ jobs: - target: aarch64-pc-windows-msvc/msvc architecture: ARM64 runner: windows-11-arm - - target: x86_64-apple-darwin/clang - architecture: x86_64 - runner: macos-15-intel - - target: aarch64-apple-darwin/clang - architecture: aarch64 - runner: macos-14 - - target: x86_64-unknown-linux-gnu/gcc - architecture: x86_64 - runner: ubuntu-24.04 - - target: aarch64-unknown-linux-gnu/gcc - architecture: aarch64 - runner: ubuntu-24.04-arm steps: - uses: actions/checkout@v6 with: @@ -100,47 +75,33 @@ jobs: - uses: actions/setup-python@v6 with: python-version: '3.11' - # PCbuild downloads LLVM automatically: - - name: Windows - if: runner.os == 'Windows' + - name: Build run: | ./PCbuild/build.bat --experimental-jit ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }} - ./PCbuild/rt.bat ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - - - name: macOS - if: runner.os == 'macOS' + - name: Test run: | - brew update - brew install llvm@${{ matrix.llvm }} - export SDKROOT="$(xcrun --show-sdk-path)" - # Set MACOSX_DEPLOYMENT_TARGET and -Werror=unguarded-availability to - # make sure we don't break downstream distributors (like uv): - export CFLAGS_JIT='-Werror=unguarded-availability' - export MACOSX_DEPLOYMENT_TARGET=10.15 - ./configure --enable-experimental-jit --enable-universalsdk --with-universal-archs=universal2 ${{ matrix.debug && '--with-pydebug' || '' }} - make all --jobs 4 - ./python.exe -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 + ./PCbuild/rt.bat ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }} -q --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - - name: Linux - if: runner.os == 'Linux' - run: | - sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }} - export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH" - ./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '' }} - make all --jobs 4 - ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 + macos: + name: ${{ matrix.target }} (${{ matrix.debug && 'Debug' || 'Release' }}) - jit-with-disabled-gil: - name: Free-Threaded (Debug) - needs: interpreter - runs-on: ubuntu-24.04 - timeout-minutes: 90 + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: fail-fast: false matrix: - llvm: - - 21 + target: + - x86_64-apple-darwin/clang + - aarch64-apple-darwin/clang + debug: + - true + - false + include: + - target: x86_64-apple-darwin/clang + runner: macos-15-intel + - target: aarch64-apple-darwin/clang + runner: macos-14 steps: - uses: actions/checkout@v6 with: @@ -148,27 +109,42 @@ jobs: - uses: actions/setup-python@v6 with: python-version: '3.11' - - name: Build with JIT enabled and GIL disabled + - name: Install LLVM + run: | + brew update + brew install llvm@${{ env.LLVM_VERSION }} + - name: Build run: | - sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }} - export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH" - ./configure --enable-experimental-jit --with-pydebug --disable-gil + export SDKROOT="$(xcrun --show-sdk-path)" + # Set MACOSX_DEPLOYMENT_TARGET and -Werror=unguarded-availability to + # make sure we don't break downstream distributors (like uv): + export CFLAGS_JIT='-Werror=unguarded-availability' + export MACOSX_DEPLOYMENT_TARGET=10.15 + ./configure --enable-experimental-jit --enable-universalsdk --with-universal-archs=universal2 ${{ matrix.debug && '--with-pydebug' || '' }} make all --jobs 4 - - name: Run tests + - name: Test run: | - ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - continue-on-error: true + ./python.exe -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 - no-opt-jit: - name: JIT without optimizations (Debug) - needs: interpreter - runs-on: ubuntu-24.04 - timeout-minutes: 90 + linux: + name: ${{ matrix.target }} (${{ matrix.debug && 'Debug' || 'Release' }}) + + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: fail-fast: false matrix: - llvm: - - 21 + target: + - x86_64-unknown-linux-gnu/gcc + - aarch64-unknown-linux-gnu/gcc + debug: + - true + - false + include: + - target: x86_64-unknown-linux-gnu/gcc + runner: ubuntu-24.04 + - target: aarch64-unknown-linux-gnu/gcc + runner: ubuntu-24.04-arm steps: - uses: actions/checkout@v6 with: @@ -176,26 +152,35 @@ jobs: - uses: actions/setup-python@v6 with: python-version: '3.11' - - name: Build with JIT + - name: Build run: | - sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }} - export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH" - ./configure --enable-experimental-jit --with-pydebug + sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ env.LLVM_VERSION }} + export PATH="$(llvm-config-${{ env.LLVM_VERSION }} --bindir):$PATH" + ./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '' }} make all --jobs 4 - - name: Run tests without optimizations + - name: Test run: | - PYTHON_UOPS_OPTIMIZE=0 ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 + ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 + + linux-extras: + name: ${{ matrix.name }} - tail-call-jit: - name: JIT with tail calling interpreter - needs: interpreter runs-on: ubuntu-24.04 - timeout-minutes: 90 + timeout-minutes: 60 strategy: fail-fast: false matrix: - llvm: - - 21 + include: + - name: Free-Threaded (Debug) + configure_flags: --enable-experimental-jit --with-pydebug --disable-gil + continue_on_error: true + - name: JIT without optimizations (Debug) + configure_flags: --enable-experimental-jit --with-pydebug + test_env: "PYTHON_UOPS_OPTIMIZE=0" + - name: JIT with tail calling interpreter + configure_flags: --enable-experimental-jit --with-tail-call-interp --with-pydebug + use_clang: true + run_tests: false steps: - uses: actions/checkout@v6 with: @@ -203,9 +188,17 @@ jobs: - uses: actions/setup-python@v6 with: python-version: '3.11' - - name: Build with JIT and tailcall + - name: Build run: | - sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }} - export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH" - CC=clang-${{ matrix.llvm }} ./configure --enable-experimental-jit --with-tail-call-interp --with-pydebug + sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ env.LLVM_VERSION }} + export PATH="$(llvm-config-${{ env.LLVM_VERSION }} --bindir):$PATH" + if [ "${{ matrix.use_clang }}" = "true" ]; then + export CC=clang-${{ env.LLVM_VERSION }} + fi + ./configure ${{ matrix.configure_flags }} make all --jobs 4 + - name: Test + if: matrix.run_tests != false + run: | + ${{ matrix.test_env }} ./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3 + continue-on-error: ${{ matrix.continue_on_error }} From fd01372d4e509b2cbec708adcf7cdf6f7c1c1298 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Mon, 23 Feb 2026 02:46:03 +0800 Subject: [PATCH 207/498] gh-145064: Fix JIT assertion failure during CALL_ALLOC_AND_ENTER_INIT side exit (GH-145100) --- Lib/test/test_capi/test_opt.py | 49 +++++++++++++++++++ ...-02-22-07-51-10.gh-issue-145064.iIMGKA.rst | 1 + Python/optimizer.c | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 7ac71fbfab1fe0..fe1b45608841a2 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -4065,6 +4065,55 @@ def hot_loop(): self.assertNotIn('_PyJit_TryInitializeTracing', stderr, f"JIT tracer memory leak detected:\n{stderr}") + def test_cold_exit_on_init_cleanup_frame(self): + + result = script_helper.run_python_until_end('-c', textwrap.dedent(""" + class A: + __slots__ = ('x', 'y', 'z', 'w') + def __init__(self): + self.x = self.y = -1 + self.z = self.w = None + + class B(A): + __slots__ = ('a', 'b', 'c', 'd', 'e') + def __init__(self): + super().__init__() + self.a = self.b = None + self.c = "" + self.d = self.e = False + + class C(B): + __slots__ = ('name', 'flag') + def __init__(self, name): + super().__init__() + self.name = name + self.flag = False + + funcs = [] + for n in range(20, 80): + lines = [f"def f{n}(names, info):"] + for j in range(n): + lines.append(f" v{j} = names[{j % 3}]") + if j % 3 == 0: + lines.append(f" if v{j} in info:") + lines.append(f" v{j} = info[v{j}]") + elif j % 5 == 0: + lines.append(f" v{j} = len(v{j}) if isinstance(v{j}, str) else 0") + lines.append(" return C(names[0])") + ns = {'C': C} + exec("\\n".join(lines), ns) + funcs.append(ns[f"f{n}"]) + + names = ['alpha', 'beta', 'gamma'] + info = {'alpha': 'x', 'beta': 'y', 'gamma': 'z'} + + for f in funcs: + for _ in range(10): + f(names, info) + """), PYTHON_JIT="1", PYTHON_JIT_STRESS="1", + PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE="1") + self.assertEqual(result[0].rc, 0, result) + def global_identity(x): return x diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst new file mode 100644 index 00000000000000..1f298e164f4488 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst @@ -0,0 +1 @@ +Fix JIT optimizer assertion failure during ``CALL_ALLOC_AND_ENTER_INIT`` side exit. diff --git a/Python/optimizer.c b/Python/optimizer.c index 6a575c8573724a..f485c27bca2a4f 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -995,7 +995,7 @@ _PyJit_TryInitializeTracing( return 0; } PyObject *func = PyStackRef_AsPyObjectBorrow(frame->f_funcobj); - if (func == NULL) { + if (func == NULL || !PyFunction_Check(func)) { return 0; } PyCodeObject *code = _PyFrame_GetCode(frame); From 79f6caf8f1f52788e15c97debd822e99672e5181 Mon Sep 17 00:00:00 2001 From: dgpb <3577712+dg-pb@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:59:40 +0200 Subject: [PATCH 208/498] gh-145131: difflib.Differ._fancy_replace performance (re-use ratio) (#145133) re-use calculated ratio --- Lib/difflib.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/difflib.py b/Lib/difflib.py index 7c7e233b013a76..8f3cdaed9564d8 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -942,10 +942,12 @@ def _fancy_replace(self, a, alo, ahi, b, blo, bhi): cruncher.set_seq1(a[i]) # Ordering by cheapest to most expensive ratio is very # valuable, most often getting out early. - if (crqr() > best_ratio - and cqr() > best_ratio - and cr() > best_ratio): - best_i, best_j, best_ratio = i, j, cr() + if crqr() <= best_ratio or cqr() <= best_ratio: + continue + + ratio = cr() + if ratio > best_ratio: + best_i, best_j, best_ratio = i, j, ratio if best_i is None: # found nothing to synch on yet - move to next j From ad4ee7cb0f75d9c6615eaefe69692fc8e3ec553b Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:19:03 -0800 Subject: [PATCH 209/498] gh-144015: Add portable SIMD optimization for bytes.hex() et. al. (GH-143991) Add SIMD optimization for `bytes.hex()`, `bytearray.hex()`, and `binascii.hexlify()` as well as `hashlib` `.hexdigest()` methods using platform-agnostic GCC/Clang vector extensions that compile to native SIMD instructions on our [PEP-11 Tier 1 Linux and macOS](https://peps.python.org/pep-0011/#tier-1) platforms. - 1.1-3x faster for common small data (16-64 bytes, covering md5 through sha512 digest sizes) - Up to 11x faster for large data (1KB+) - Retains the existing scalar code for short inputs (<16 bytes) or platforms lacking SIMD instructions, no observable performance regressions there. ## Supported platforms: - x86-64: the compiler generates SSE2 - always available, no flags or CPU feature checks needed - ARM64: NEON is always available, always available, no flags or CPU feature checks needed - ARM32: Requires NEON support and that appropriate compiler flags enable that (e.g., `-march=native` on a Raspberry Pi 3+) - while we _could_ use runtime detection to allow neon when compiled without a recent enough `-march=` flag (`cortex-a53` and later IIRC), there are diminishing returns in doing so. Anyone using 32-bit ARM in a situation where performance matters will already be compiling with such flags. (as opposed to 32-bit Raspbian compilation that defaults to aiming primarily for compatibility with rpi1&0 armv6 arch=armhf which lacks neon) - Windows/MSVC: Not supported. MSVC lacks `__builtin_shufflevector`, so the existing scalar path is used. Leaving it as an opportunity for the future for someone to figure out how to express the intent to that compiler. This is compile time detection of features that are always available on the target architectures. No need for runtime feature inspection. --- Lib/test/test_bytes.py | 31 +++++ ...20-15-00.gh-issue-144015.pystrhex_simd.rst | 5 + Python/pystrhex.c | 121 +++++++++++++++++- configure | 66 ++++++++++ configure.ac | 35 +++++ pyconfig.h.in | 4 + 6 files changed, 256 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 742bad21a3346b..1c64bf888f9d27 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -584,6 +584,37 @@ def test_hex_separator_six_bytes(self): self.assertEqual(six_bytes.hex(':', -6), '0306090c0f12') self.assertEqual(six_bytes.hex(' ', -95), '0306090c0f12') + def test_hex_simd_boundaries(self): + # Test lengths around the SIMD threshold (16 bytes). + # SIMD processes 16 bytes at a time; smaller inputs use scalar code. + for length in (14, 15, 16, 17, 31, 32, 33, 64, 65): + data = self.type2test(bytes(range(length))) + expected = ''.join(f'{b:02x}' for b in range(length)) + with self.subTest(length=length): + self.assertEqual(data.hex(), expected) + + def test_hex_nibble_boundaries(self): + # Test the nibble value boundary at 9/10 (where '9' becomes 'a'). + # SIMD uses signed comparison for efficiency; verify correctness + # at this boundary for various nibble combinations. + boundary_bytes = self.type2test(bytes([ + 0x09, # both nibbles: 0, 9 + 0x0a, # both nibbles: 0, 10 + 0x90, # both nibbles: 9, 0 + 0x99, # both nibbles: 9, 9 (max all-digit) + 0x9a, # both nibbles: 9, 10 + 0xa0, # both nibbles: 10, 0 + 0xa9, # both nibbles: 10, 9 + 0xaa, # both nibbles: 10, 10 (min all-letter) + 0x00, # min value + 0xff, # max value + ])) + self.assertEqual(boundary_bytes.hex(), '090a90999aa0a9aa00ff') + + # Repeat with 16+ bytes to exercise SIMD path + simd_boundary = self.type2test(boundary_bytes * 2) + self.assertEqual(simd_boundary.hex(), '090a90999aa0a9aa00ff' * 2) + def test_join(self): self.assertEqual(self.type2test(b"").join([]), b"") self.assertEqual(self.type2test(b"").join([b""]), b"") diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst new file mode 100644 index 00000000000000..122315e031bc87 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst @@ -0,0 +1,5 @@ +Speed up :meth:`bytes.hex`, :meth:`bytearray.hex`, :func:`binascii.hexlify`, +and :mod:`hashlib` ``.hexdigest()`` operations with SIMD on x86-64, ARM64, +and ARM32 with NEON when built with gcc (version 12 or higher) or clang +(version 3 or higher) compilers. Around 1.1-3x faster for common 16-64 byte +inputs such as hashlib hex digests, and up to 8x faster for larger data. diff --git a/Python/pystrhex.c b/Python/pystrhex.c index af2f5c5dce5fca..698e7f26fbaae7 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -4,6 +4,113 @@ #include "pycore_strhex.h" // _Py_strhex_with_sep() #include "pycore_unicodeobject.h" // _PyUnicode_CheckConsistency() +/* Scalar hexlify: convert len bytes to 2*len hex characters. + Uses table lookup via Py_hexdigits for the conversion. */ +static inline void +_Py_hexlify_scalar(const unsigned char *src, Py_UCS1 *dst, Py_ssize_t len) +{ + /* Various optimizations like using math instead of a table lookup, + manually unrolling the loop, storing the global table pointer locally, + and doing wider dst writes have been tried and benchmarked; all produced + nearly identical performance on gcc 15. Using a 256 entry uint16_t + table was a bit slower. So we keep our old simple and obvious code. */ + for (Py_ssize_t i = 0; i < len; i++) { + unsigned char c = src[i]; + *dst++ = Py_hexdigits[c >> 4]; + *dst++ = Py_hexdigits[c & 0x0f]; + } +} + +/* Portable SIMD optimization for hexlify using GCC/Clang vector extensions. + Uses __builtin_shufflevector for portable interleave that compiles to + native SIMD instructions (SSE2 punpcklbw/punpckhbw on x86-64 [always], + NEON zip1/zip2 on ARM64 [always], & vzip on ARM32 when compiler flags + for the target microarch allow it [try -march=native if running 32-bit + on an RPi3 or later]). + + Performance: + - For more common small data it varies between 1.1-3x faster. + - Up to 11x faster on larger data than the scalar code. + + While faster is possible for big data using AVX2 or AVX512, that + adds a ton of complication. Who ever really hexes huge data? + The 16-64 byte boosts align nicely with md5 - sha512 hexdigests. +*/ +#ifdef HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR + +/* 128-bit vector of 16 unsigned bytes */ +typedef unsigned char v16u8 __attribute__((vector_size(16))); +/* 128-bit vector of 16 signed bytes - for efficient comparison. + Using signed comparison generates pcmpgtb on x86-64 instead of + the slower psubusb+pcmpeqb sequence from unsigned comparison. + ARM NEON performs the same either way. */ +typedef signed char v16s8 __attribute__((vector_size(16))); + +/* Splat a byte value across all 16 lanes */ +static inline v16u8 +v16u8_splat(unsigned char x) +{ + return (v16u8){x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}; +} + +static inline v16s8 +v16s8_splat(signed char x) +{ + return (v16s8){x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}; +} + +/* Portable SIMD hexlify: converts 16 bytes to 32 hex chars per iteration. + Compiles to native SSE2 on x86-64, NEON on ARM64 (and some ARM32). */ +static void +_Py_hexlify_simd(const unsigned char *src, Py_UCS1 *dst, Py_ssize_t len) +{ + const v16u8 mask_0f = v16u8_splat(0x0f); + const v16u8 ascii_0 = v16u8_splat('0'); + const v16u8 offset = v16u8_splat('a' - '0' - 10); /* 0x27 */ + const v16s8 nine = v16s8_splat(9); + + Py_ssize_t i = 0; + + /* Process 16 bytes at a time */ + for (; i + 16 <= len; i += 16, dst += 32) { + /* Load 16 bytes (memcpy for safe unaligned access) */ + v16u8 data; + memcpy(&data, src + i, 16); + + /* Extract high and low nibbles using vector operators */ + v16u8 hi = (data >> 4) & mask_0f; + v16u8 lo = data & mask_0f; + + /* Compare > 9 using signed comparison for efficient codegen. + Nibble values 0-15 are safely in signed byte range. + This generates pcmpgtb on x86-64, avoiding the slower + psubusb+pcmpeqb sequence from unsigned comparison. */ + v16u8 hi_gt9 = (v16u8)((v16s8)hi > nine); + v16u8 lo_gt9 = (v16u8)((v16s8)lo > nine); + + /* Convert nibbles to hex ASCII */ + hi = hi + ascii_0 + (hi_gt9 & offset); + lo = lo + ascii_0 + (lo_gt9 & offset); + + /* Interleave hi/lo nibbles using portable shufflevector. + This compiles to punpcklbw/punpckhbw on x86-64, zip1/zip2 on ARM64, + or vzip on ARM32. */ + v16u8 result0 = __builtin_shufflevector(hi, lo, + 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23); + v16u8 result1 = __builtin_shufflevector(hi, lo, + 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31); + + /* Store 32 hex characters */ + memcpy(dst, &result0, 16); + memcpy(dst + 16, &result1, 16); + } + + /* Scalar fallback for remaining 0-15 bytes */ + _Py_hexlify_scalar(src + i, dst, len - i); +} + +#endif /* HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR */ + static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, PyObject* sep, int bytes_per_sep_group, const int return_bytes) @@ -82,13 +189,15 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, unsigned char c; if (bytes_per_sep_group == 0) { - for (i = j = 0; i < arglen; ++i) { - assert((j + 1) < resultlen); - c = argbuf[i]; - retbuf[j++] = Py_hexdigits[c >> 4]; - retbuf[j++] = Py_hexdigits[c & 0x0f]; +#ifdef HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR + if (arglen >= 16) { + _Py_hexlify_simd((const unsigned char *)argbuf, retbuf, arglen); + } + else +#endif + { + _Py_hexlify_scalar((const unsigned char *)argbuf, retbuf, arglen); } - assert(j == resultlen); } else { /* The number of complete chunk+sep periods */ diff --git a/configure b/configure index 73a758384553b2..98b4af86858673 100755 --- a/configure +++ b/configure @@ -18889,6 +18889,72 @@ then : printf "%s\n" "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h +fi + +# Check for __builtin_shufflevector with 128-bit vector support on an +# architecture where it compiles to worthwhile native SIMD instructions. +# Used for SIMD-accelerated bytes.hex() in Python/pystrhex.c. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __builtin_shufflevector" >&5 +printf %s "checking for __builtin_shufflevector... " >&6; } +if test ${ac_cv_efficient_builtin_shufflevector+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + /* __builtin_shufflevector is available on many platforms, but 128-bit + vector code is only worthwhile on architectures with native SIMD: + x86-64 (SSE2, always available), ARM64 (NEON, always available), + or ARM32 when NEON is enabled via compiler flags (e.g. -march=native + on RPi3+). On ARM32 without NEON (e.g. armv6 builds), the compiler + has the builtin but generates slow scalar code instead. */ + #if !defined(__x86_64__) && !defined(__aarch64__) && \ + !(defined(__arm__) && defined(__ARM_NEON)) + # error "128-bit vector SIMD not worthwhile on this architecture" + #endif + typedef unsigned char v16u8 __attribute__((vector_size(16))); + +int +main (void) +{ + + v16u8 a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + v16u8 b = {16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + v16u8 c = __builtin_shufflevector(a, b, + 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23); + (void)c; + return 0; + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_efficient_builtin_shufflevector=yes +else case e in #( + e) ac_cv_efficient_builtin_shufflevector=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_efficient_builtin_shufflevector" >&5 +printf "%s\n" "$ac_cv_efficient_builtin_shufflevector" >&6; } + +if test "x$ac_cv_efficient_builtin_shufflevector" = xyes +then : + + +printf "%s\n" "#define HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR 1" >>confdefs.h + + fi # --with-mimalloc diff --git a/configure.ac b/configure.ac index 2ba63b2a8a05e0..34318769fcc29f 100644 --- a/configure.ac +++ b/configure.ac @@ -5017,6 +5017,41 @@ AS_VAR_IF([ac_cv_builtin_atomic], [yes], [ AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Has builtin __atomic_load_n() and __atomic_store_n() functions]) ]) +# Check for __builtin_shufflevector with 128-bit vector support on an +# architecture where it compiles to worthwhile native SIMD instructions. +# Used for SIMD-accelerated bytes.hex() in Python/pystrhex.c. +AC_CACHE_CHECK([for __builtin_shufflevector], [ac_cv_efficient_builtin_shufflevector], [ +AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + /* __builtin_shufflevector is available on many platforms, but 128-bit + vector code is only worthwhile on architectures with native SIMD: + x86-64 (SSE2, always available), ARM64 (NEON, always available), + or ARM32 when NEON is enabled via compiler flags (e.g. -march=native + on RPi3+). On ARM32 without NEON (e.g. armv6 builds), the compiler + has the builtin but generates slow scalar code instead. */ + #if !defined(__x86_64__) && !defined(__aarch64__) && \ + !(defined(__arm__) && defined(__ARM_NEON)) + # error "128-bit vector SIMD not worthwhile on this architecture" + #endif + typedef unsigned char v16u8 __attribute__((vector_size(16))); + ]], [[ + v16u8 a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + v16u8 b = {16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + v16u8 c = __builtin_shufflevector(a, b, + 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23); + (void)c; + return 0; + ]]) +],[ac_cv_efficient_builtin_shufflevector=yes],[ac_cv_efficient_builtin_shufflevector=no]) +]) + +AS_VAR_IF([ac_cv_efficient_builtin_shufflevector], [yes], [ + AC_DEFINE([HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR], [1], + [Define if compiler supports __builtin_shufflevector with 128-bit + vectors AND the target architecture has native SIMD (not just API + availability)]) +]) + # --with-mimalloc AC_MSG_CHECKING([for --with-mimalloc]) AC_ARG_WITH([mimalloc], diff --git a/pyconfig.h.in b/pyconfig.h.in index e2009b2d9ee57e..fbd5d4d625908e 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -324,6 +324,10 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EDITLINE_READLINE_H +/* Define if compiler supports __builtin_shufflevector with 128-bit vectors + AND the target architecture has native SIMD (not just API availability) */ +#undef HAVE_EFFICIENT_BUILTIN_SHUFFLEVECTOR + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H From 3dc8fdb3219293547890808ab52a2171867fd3af Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 23 Feb 2026 08:22:29 +0100 Subject: [PATCH 210/498] gh-145089: Fix frozendict constructor (#145128) --- Lib/test/test_dict.py | 10 ++++++++++ Objects/dictobject.c | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 14b501360d0b8e..8a4e19c95a36ef 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1736,6 +1736,16 @@ class FrozenDictSlots(frozendict): class FrozenDictTests(unittest.TestCase): + def test_constructor(self): + # frozendict.__init__() has no effect + d = frozendict(a=1, b=2, c=3) + d.__init__(x=1) + self.assertEqual(d, frozendict(a=1, b=2, c=3)) + + # dict constructor cannot be used on frozendict + with self.assertRaises(TypeError): + dict.__init__(d, x=1) + def test_copy(self): d = frozendict(x=1, y=2) d2 = d.copy() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 6c802ca569d48c..35ca9933bfa8ae 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -8143,7 +8143,6 @@ PyTypeObject PyFrozenDict_Type = { .tp_richcompare = dict_richcompare, .tp_iter = dict_iter, .tp_methods = frozendict_methods, - .tp_init = dict_init, .tp_alloc = _PyType_AllocNoTrack, .tp_new = frozendict_new, .tp_free = PyObject_GC_Del, From 24cc998c164f137603f1c6d95b929d640211d237 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 23 Feb 2026 09:18:45 -0500 Subject: [PATCH 211/498] gh-141004: Document `PyModuleDef_Type` (GH-145043) --- Doc/c-api/module.rst | 5 +++++ Tools/check-c-api-docs/ignored_c_api.txt | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index aa2145b5fe5d09..39293b0fa228df 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -755,6 +755,11 @@ remove it. functions are no longer called before the module state is allocated. +.. c:var:: PyTypeObject PyModuleDef_Type + + The type of ``PyModuleDef`` objects. + + .. _moduledef-dynamic: The following API can be used to create modules from a :c:type:`!PyModuleDef` diff --git a/Tools/check-c-api-docs/ignored_c_api.txt b/Tools/check-c-api-docs/ignored_c_api.txt index e628bdfebcbded..7bf79872bd4630 100644 --- a/Tools/check-c-api-docs/ignored_c_api.txt +++ b/Tools/check-c-api-docs/ignored_c_api.txt @@ -20,8 +20,6 @@ Py_UTF8Mode Py_HASH_EXTERNAL # modsupport.h PyABIInfo_FREETHREADING_AGNOSTIC -# moduleobject.h -PyModuleDef_Type # object.h Py_INVALID_SIZE Py_TPFLAGS_HAVE_VERSION_TAG From 8db8fc9b51060b61d14fbe6aa0f2e2591292279e Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 23 Feb 2026 09:32:16 -0500 Subject: [PATCH 212/498] gh-144777: Fix data races in IncrementalNewlineDecoder (gh-144971) --- Lib/test/test_free_threading/test_io.py | 55 +++++++++++++++++++ ...-02-18-13-45-00.gh-issue-144777.R97q0a.rst | 1 + Modules/_io/clinic/textio.c.h | 22 +++++++- Modules/_io/textio.c | 12 ++-- 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst diff --git a/Lib/test/test_free_threading/test_io.py b/Lib/test/test_free_threading/test_io.py index c67aaff31b3f5b..8a0ad30c4bc770 100644 --- a/Lib/test/test_free_threading/test_io.py +++ b/Lib/test/test_free_threading/test_io.py @@ -1,11 +1,15 @@ +import codecs import io import _pyio as pyio import threading from unittest import TestCase from test.support import threading_helper +from test.support.threading_helper import run_concurrently from random import randint from sys import getsizeof +threading_helper.requires_working_threading(module=True) + class ThreadSafetyMixin: # Test pretty much everything that can break under free-threading. @@ -115,3 +119,54 @@ class CBytesIOTest(ThreadSafetyMixin, TestCase): class PyBytesIOTest(ThreadSafetyMixin, TestCase): ioclass = pyio.BytesIO + + +class IncrementalNewlineDecoderTest(TestCase): + def make_decoder(self): + utf8_decoder = codecs.getincrementaldecoder('utf-8')() + return io.IncrementalNewlineDecoder(utf8_decoder, translate=True) + + def test_concurrent_reset(self): + decoder = self.make_decoder() + + def worker(): + for _ in range(100): + decoder.reset() + + run_concurrently(worker_func=worker, nthreads=2) + + def test_concurrent_decode(self): + decoder = self.make_decoder() + + def worker(): + for _ in range(100): + decoder.decode(b"line\r\n", final=False) + + run_concurrently(worker_func=worker, nthreads=2) + + def test_concurrent_getstate_setstate(self): + decoder = self.make_decoder() + state = decoder.getstate() + + def getstate_worker(): + for _ in range(100): + decoder.getstate() + + def setstate_worker(): + for _ in range(100): + decoder.setstate(state) + + run_concurrently([getstate_worker] * 2 + [setstate_worker] * 2) + + def test_concurrent_decode_and_reset(self): + decoder = self.make_decoder() + + def decode_worker(): + for _ in range(100): + decoder.decode(b"line\r\n", final=False) + + def reset_worker(): + for _ in range(100): + decoder.reset() + + run_concurrently([decode_worker] * 2 + [reset_worker] * 2) diff --git a/Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst b/Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst new file mode 100644 index 00000000000000..fd720bfd3f3da6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst @@ -0,0 +1 @@ +Fix data races in :class:`io.IncrementalNewlineDecoder` in the :term:`free-threaded build`. diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 128a5ad1678f26..3898a9c2982436 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -430,7 +430,9 @@ _io_IncrementalNewlineDecoder_decode(PyObject *self, PyObject *const *args, Py_s goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_IncrementalNewlineDecoder_decode_impl((nldecoder_object *)self, input, final); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -450,7 +452,13 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self); static PyObject * _io_IncrementalNewlineDecoder_getstate(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return _io_IncrementalNewlineDecoder_getstate_impl((nldecoder_object *)self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_IncrementalNewlineDecoder_getstate_impl((nldecoder_object *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_IncrementalNewlineDecoder_setstate__doc__, @@ -470,7 +478,9 @@ _io_IncrementalNewlineDecoder_setstate(PyObject *self, PyObject *state) { PyObject *return_value = NULL; + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_IncrementalNewlineDecoder_setstate_impl((nldecoder_object *)self, state); + Py_END_CRITICAL_SECTION(); return return_value; } @@ -489,7 +499,13 @@ _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self); static PyObject * _io_IncrementalNewlineDecoder_reset(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return _io_IncrementalNewlineDecoder_reset_impl((nldecoder_object *)self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_IncrementalNewlineDecoder_reset_impl((nldecoder_object *)self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper___init____doc__, @@ -1312,4 +1328,4 @@ _io_TextIOWrapper__CHUNK_SIZE_set(PyObject *self, PyObject *value, void *Py_UNUS return return_value; } -/*[clinic end generated code: output=30404271a1151056 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c38e6cd5ff4b7eea input=a9049054013a1b77]*/ diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index f9881952561292..347bfe976619e8 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -519,6 +519,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, } /*[clinic input] +@critical_section _io.IncrementalNewlineDecoder.decode input: object final: bool = False @@ -527,18 +528,19 @@ _io.IncrementalNewlineDecoder.decode static PyObject * _io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, PyObject *input, int final) -/*[clinic end generated code: output=0d486755bb37a66e input=90e223c70322c5cd]*/ +/*[clinic end generated code: output=0d486755bb37a66e input=9475d16a73168504]*/ { return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); } /*[clinic input] +@critical_section _io.IncrementalNewlineDecoder.getstate [clinic start generated code]*/ static PyObject * _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) -/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/ +/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=dc3e1f27aa850f12]*/ { PyObject *buffer; unsigned long long flag; @@ -576,6 +578,7 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) } /*[clinic input] +@critical_section _io.IncrementalNewlineDecoder.setstate state: object / @@ -584,7 +587,7 @@ _io.IncrementalNewlineDecoder.setstate static PyObject * _io_IncrementalNewlineDecoder_setstate_impl(nldecoder_object *self, PyObject *state) -/*[clinic end generated code: output=09135cb6e78a1dc8 input=c53fb505a76dbbe2]*/ +/*[clinic end generated code: output=09135cb6e78a1dc8 input=275fd3982d2b08cb]*/ { PyObject *buffer; unsigned long long flag; @@ -614,12 +617,13 @@ _io_IncrementalNewlineDecoder_setstate_impl(nldecoder_object *self, } /*[clinic input] +@critical_section _io.IncrementalNewlineDecoder.reset [clinic start generated code]*/ static PyObject * _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) -/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/ +/*[clinic end generated code: output=32fa40c7462aa8ff input=31bd8ae4e36cec83]*/ { CHECK_INITIALIZED_DECODER(self); From 6194a552f2b010e1dcdd006996f613c956520124 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 23 Feb 2026 09:25:05 -0800 Subject: [PATCH 213/498] Update argparse `suggest_on_error` code snippet in docs (#144985) --- Doc/library/argparse.rst | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index ebcf8bf4dac002..ca4f439c345f32 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -602,18 +602,13 @@ choices (if specified) or subparser names, along with a "maybe you meant" suggestion if a close match is found. Note that this only applies for arguments when the choices specified are strings:: - >>> parser = argparse.ArgumentParser(description='Process some integers.', - suggest_on_error=True) - >>> parser.add_argument('--action', choices=['sum', 'max']) - >>> parser.add_argument('integers', metavar='N', type=int, nargs='+', - ... help='an integer for the accumulator') - >>> parser.parse_args(['--action', 'sumn', 1, 2, 3]) - tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max') - -You can disable suggestions by setting ``suggest_on_error`` to ``False``:: + >>> parser = argparse.ArgumentParser(suggest_on_error=True) + >>> parser.add_argument('--action', choices=['debug', 'dryrun']) + >>> parser.parse_args(['--action', 'debugg']) + usage: tester.py [-h] [--action {debug,dryrun}] + tester.py: error: argument --action: invalid choice: 'debugg', maybe you meant 'debug'? (choose from debug, dryrun) - >>> parser = argparse.ArgumentParser(description='Process some integers.', - suggest_on_error=False) +You can disable suggestions by setting ``suggest_on_error`` to ``False``. .. versionadded:: 3.14 .. versionchanged:: 3.15 From 6180e79ed2175f7b095807b78a5ea58b4da3de0b Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 23 Feb 2026 09:54:14 -0800 Subject: [PATCH 214/498] Add Savannah as `jit.yml` CODEOWNER (#145152) Add Savannah for jit.yml CODEOWNER --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1adbacbb7d1098..f33196bb0eb168 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -289,6 +289,7 @@ Programs/_bootstrap_python.c @ericsnowcurrently Programs/python.c @ericsnowcurrently # JIT +.github/workflows/jit.yml @savannahostrowski Include/internal/pycore_jit.h @brandtbucher @savannahostrowski @diegorusso Python/jit.c @brandtbucher @savannahostrowski @diegorusso Tools/jit/ @brandtbucher @savannahostrowski @diegorusso From c7d7105b8d230741a5fa04924701d5245d07dace Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 23 Feb 2026 12:31:35 -0600 Subject: [PATCH 215/498] Indexing is more straight-forward (and faster) than unpacking (gh-145154) --- Lib/heapq.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/heapq.py b/Lib/heapq.py index f944376bcd291f..a3af6dc05bff37 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -511,7 +511,7 @@ def nsmallest(n, iterable, key=None): for elem in it: if elem < top: _heapreplace(result, (elem, order)) - top, _order = result[0] + top = result[0][0] order += 1 result.sort() return [elem for (elem, order) in result] @@ -529,7 +529,7 @@ def nsmallest(n, iterable, key=None): k = key(elem) if k < top: _heapreplace(result, (k, order, elem)) - top, _order, _elem = result[0] + top = result[0][0] order += 1 result.sort() return [elem for (k, order, elem) in result] @@ -569,7 +569,7 @@ def nlargest(n, iterable, key=None): for elem in it: if top < elem: _heapreplace(result, (elem, order)) - top, _order = result[0] + top = result[0][0] order -= 1 result.sort(reverse=True) return [elem for (elem, order) in result] @@ -587,7 +587,7 @@ def nlargest(n, iterable, key=None): k = key(elem) if top < k: _heapreplace(result, (k, order, elem)) - top, _order, _elem = result[0] + top = result[0][0] order -= 1 result.sort(reverse=True) return [elem for (k, order, elem) in result] From 1dfbde9299854c9f056250a658ccf9820bc54df3 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 23 Feb 2026 22:04:16 +0000 Subject: [PATCH 216/498] gh-145118: Add `frozendict` support to `str.maketrans()` (gh-145129) Add support to `str.maketrans` --- Lib/test/test_str.py | 7 +++++++ .../2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst | 1 + Objects/unicodeobject.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index 0a8dddb026f6c8..4f57499af70f4d 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -454,6 +454,13 @@ def test_maketrans_translate(self): self.assertEqual("[a\xe9]".translate(str.maketrans({'a': '<\u20ac>'})), "[<\u20ac>\xe9]") + # with frozendict + tbl = self.type2test.maketrans(frozendict({'s': 'S', 'T': 't'})) + self.assertEqual(tbl, {ord('s'): 'S', ord('T'): 't'}) + self.assertEqual('sTan'.translate(tbl), 'Stan') + tbl = self.type2test.maketrans(frozendict({'a': None, 'b': ''})) + self.checkequalnofix('c', 'abababc', 'translate', tbl) + # invalid Unicode characters invalid_char = 0x10ffff+1 for before in "a\xe9\u20ac\U0010ffff": diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst new file mode 100644 index 00000000000000..fccc3bc2a1804e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst @@ -0,0 +1 @@ +:meth:`str.maketrans` now accepts :class:`frozendict`. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fdcbcf51cb62c2..988e5f95573fe1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13149,7 +13149,7 @@ unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z) const void *data; /* x must be a dict */ - if (!PyDict_CheckExact(x)) { + if (!PyAnyDict_CheckExact(x)) { PyErr_SetString(PyExc_TypeError, "if you give only one argument " "to maketrans it must be a dict"); goto err; From da39c68c2fb0027365651598eff5704affff5131 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 23 Feb 2026 22:28:23 +0000 Subject: [PATCH 217/498] Update Python install manager docs (GH-145160) These updates align with v26.0 that was just released. --- Doc/using/windows.rst | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 69fe89290e3b27..1a913c624e99b0 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -285,6 +285,12 @@ work. Passing ``--dry-run`` will generate output and logs, but will not modify any installs. +Passing ``--refresh`` will update all registrations for installed runtimes. This +will recreate Start menu shortcuts, registry keys, and global aliases (such as +``python3.14.exe`` or for any installed scripts). These are automatically +refreshed on installation of any runtime, but may need to be manually refreshed +after installing packages. + In addition to the above options, the ``--target`` option will extract the runtime to the specified directory instead of doing a normal install. This is useful for embedding runtimes into larger applications. @@ -467,6 +473,14 @@ customization. - ``PYTHON_MANAGER_SOURCE_URL`` - Override the index feed to obtain new installs from. + * - ``install.enable_entrypoints`` + - (none) + - True to generate global commands for installed packages (such as + ``pip.exe``). These are defined by the packages themselves. + If set to false, only the Python interpreter has global commands created. + By default, true. You should run ``py install --refresh`` after changing + this setting. + * - ``list.format`` - ``PYTHON_MANAGER_LIST_FORMAT`` - Specify the default format used by the ``py list`` command. @@ -480,8 +494,8 @@ customization. * - ``global_dir`` - (none) - - Specify the directory where global commands (such as ``python3.14.exe``) - are stored. + - Specify the directory where global commands (such as ``python3.14.exe`` + and ``pip.exe``) are stored. This directory should be added to your :envvar:`PATH` to make the commands available from your terminal. @@ -491,6 +505,7 @@ customization. This directory is a temporary cache, and can be cleaned up from time to time. + Dotted names should be nested inside JSON objects, for example, ``list.format`` would be specified as ``{"list": {"format": "table"}}``. @@ -737,6 +752,14 @@ directory containing the configuration file that specified them. (e.g. ``"pep514,start"``). Disabled shortcuts are not reactivated by ``enable_shortcut_kinds``. + * - ``install.hard_link_entrypoints`` + - True to use hard links for global shortcuts to save disk space. If false, + each shortcut executable is copied instead. After changing this setting, + you must run ``py install --refresh --force`` to update existing + commands. + By default, true. Disabling this may be necessary for troubleshooting or + systems that have issues with file links. + * - ``pep514_root`` - Registry location to read and write PEP 514 entries into. By default, :file:`HKEY_CURRENT_USER\\Software\\Python`. @@ -876,12 +899,22 @@ default). * - - The package may be available but missing the generated executable. - We recommend using the ``python -m pip`` command instead, - or alternatively the ``python -m pip install --force pip`` command - will recreate the executables and show you the path to - add to :envvar:`PATH`. - These scripts are separated for each runtime, and so you may need to - add multiple paths. + We recommend using the ``python -m pip`` command instead. + Running ``py install --refresh`` and ensuring that the global shortcuts + directory is on :envvar:`PATH` (it will be shown in the command output if + it is not) should make commands such as ``pip`` (and other installed + packages) available. + + * - I installed a package with ``pip`` but its command is not found. + - Have you activated a virtual environment? + Run the ``.venv\Scripts\activate`` script in your terminal to activate. + + * - + - New packages do not automatically have global shortcuts created by the + Python install manager. Similarly, uninstalled packages do not have their + shortcuts removed. + Run ``py install --refresh`` to update the global shortcuts for newly + installed packages. * - Typing ``script-name.py`` in the terminal opens in a new window. - This is a known limitation of the operating system. Either specify ``py`` From 0e4b1ba55dee1da7bc19d370e784483cd64b12e7 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Mon, 23 Feb 2026 23:53:56 +0100 Subject: [PATCH 218/498] gh-145110: Fix cleaning of PGO builds in Windows build.bat script (GH-145111) --- ...-02-22-13-35-20.gh-issue-145110.KgWofW.rst | 2 ++ PCbuild/build.bat | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst diff --git a/Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst b/Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst new file mode 100644 index 00000000000000..035d0c141d36ed --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst @@ -0,0 +1,2 @@ +Fix targets "Clean" and "CLeanAll" in case of PGO builds on Windows. Patch by +Chris Eibl. diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 8c24309be262ba..8fb2f096c93c0e 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -66,6 +66,7 @@ setlocal set platf=x64 set conf=Release set target=Build +set clean=false set dir=%~dp0 set parallel=/m set verbose=/nologo /v:m /clp:summary @@ -119,6 +120,9 @@ if "%UseJIT%" NEQ "true" set IncludeLLVM=false if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" +if /I "%target%"=="Clean" set clean=true +if /I "%target%"=="CleanAll" set clean=true + if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" ( if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" ( echo.ERROR: Cannot cross-compile with PGO @@ -159,15 +163,20 @@ if "%do_pgo%"=="true" ( rem %VARS% are evaluated eagerly, which would lose the ERRORLEVEL rem value if we didn't split it out here. if "%do_pgo%"=="true" if ERRORLEVEL 1 exit /B %ERRORLEVEL% + +rem In case of a PGO build, we switch the conf here to PGUpdate +rem to get it cleaned or built as well. if "%do_pgo%"=="true" ( del /s "%dir%\*.pgc" del /s "%dir%\..\Lib\*.pyc" - echo on - call "%dir%\..\python.bat" %pgo_job% - @echo off - call :Kill set conf=PGUpdate - set target=Build + if "%clean%"=="false" ( + echo on + call "%dir%\..\python.bat" %pgo_job% + @echo off + call :Kill + set target=Build + ) ) goto :Build From ae7fc4a4f6b711173bb70d23755ec15b8ac958a6 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Tue, 24 Feb 2026 00:51:03 +0100 Subject: [PATCH 219/498] gh-110937: Document full public importlib.metadata.Distribution API (#143480) --- Doc/library/importlib.metadata.rst | 142 +++++++++++++----- Lib/importlib/metadata/__init__.py | 1 + ...-01-06-16-04-08.gh-issue-110937.SyO5lk.rst | 1 + 3 files changed, 104 insertions(+), 40 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 9e08e5aa989cf7..cc426326b29932 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -125,8 +125,8 @@ Entry points :meth:`!select` method for comparison to the attributes of the individual entry point definitions. - Note: it is not currently possible to query for entry points based on - their :attr:`!EntryPoint.dist` attribute (as different :class:`!Distribution` + Note: to query for entry points based on :attr:`!EntryPoint.dist` attribute, + use :meth:`Distribution.entry_points` instead (as different :class:`Distribution` instances do not currently compare equal, even if they have the same attributes) .. class:: EntryPoints @@ -291,7 +291,7 @@ Distribution files .. function:: files(distribution_name) Return the full set of files contained within the named - distribution package. + distribution package as :class:`PackagePath` instances. Raises :exc:`PackageNotFoundError` if the named distribution package is not installed in the current Python environment. @@ -304,12 +304,22 @@ Distribution files A :class:`pathlib.PurePath` derived object with additional ``dist``, ``size``, and ``hash`` properties corresponding to the distribution - package's installation metadata for that file. + package's installation metadata for that file, also: + + .. method:: locate() + + If possible, return the concrete :class:`SimplePath` allowing to access data, + or raise a :exc:`NotImplementedError` otherwise. + +.. class:: SimplePath + + A protocol representing a minimal subset of :class:`pathlib.Path` that allows to + check if it ``exists()``, to traverse using ``joinpath()`` and ``parent``, + and to retrieve data using ``read_text()`` and ``read_bytes()``. The :func:`!files` function takes a `Distribution Package `_ -name and returns all of the files installed by this distribution. Each file is reported -as a :class:`PackagePath` instance. For example:: +name and returns all of the files installed by this distribution. For example:: >>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP >>> util # doctest: +SKIP @@ -402,6 +412,18 @@ function is not reliable with such installs. Distributions ============= +While the module level API described above is the most common and convenient usage, +all that information is accessible from the :class:`Distribution` class. +:class:`!Distribution` is an abstract object that represents the metadata for +a Python `Distribution Package `_. +Get the concrete :class:`!Distribution` subclass instance for an installed +distribution package by calling the :func:`distribution` function:: + + >>> from importlib.metadata import distribution # doctest: +SKIP + >>> dist = distribution('wheel') # doctest: +SKIP + >>> type(dist) # doctest: +SKIP + + .. function:: distribution(distribution_name) Return a :class:`Distribution` instance describing the named @@ -410,6 +432,14 @@ Distributions Raises :exc:`PackageNotFoundError` if the named distribution package is not installed in the current Python environment. +Thus, an alternative way to get e.g. the version number is through the +:attr:`Distribution.version` attribute:: + + >>> dist.version # doctest: +SKIP + '0.32.3' + +The same applies for :func:`entry_points` and :func:`files`. + .. class:: Distribution Details of an installed distribution package. @@ -418,53 +448,85 @@ Distributions equal, even if they relate to the same installed distribution and accordingly have the same attributes. - .. method:: discover(cls, *, context=None, **kwargs) + .. staticmethod:: at(path) + .. classmethod:: from_name(name) + + Return a :class:`!Distribution` instance at the given path or + with the given name. - Returns an iterable of :class:`Distribution` instances for all packages. + .. classmethod:: discover(*, context=None, **kwargs) + + Returns an iterable of :class:`!Distribution` instances for all packages + (see distribution-discovery_). The optional argument *context* is a :class:`DistributionFinder.Context` instance, used to modify the search for distributions. Alternatively, *kwargs* may contain keyword arguments for constructing a new :class:`!DistributionFinder.Context`. + .. attribute:: metadata + :type: PackageMetadata -While the module level API described above is the most common and convenient usage, -you can get all of that information from the :class:`!Distribution` class. -:class:`!Distribution` is an abstract object that represents the metadata for -a Python `Distribution Package `_. -You can get the concrete :class:`!Distribution` subclass instance for an installed -distribution package by calling the :func:`distribution` function:: + There are all kinds of additional metadata available on :class:`!Distribution` + instances as a :class:`PackageMetadata` instance:: - >>> from importlib.metadata import distribution # doctest: +SKIP - >>> dist = distribution('wheel') # doctest: +SKIP - >>> type(dist) # doctest: +SKIP - + >>> dist.metadata['Requires-Python'] # doctest: +SKIP + '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' + >>> dist.metadata['License'] # doctest: +SKIP + 'MIT' -Thus, an alternative way to get the version number is through the -:class:`!Distribution` instance:: + The full set of available metadata is not described here. + See the PyPA `Core metadata specification `_ for additional details. - >>> dist.version # doctest: +SKIP - '0.32.3' + .. attribute:: name + :type: str + .. attribute:: requires + :type: list[str] + .. attribute:: version + :type: str -There are all kinds of additional metadata available on :class:`!Distribution` -instances:: + A few metadata fields are also available as shortcut properties. - >>> dist.metadata['Requires-Python'] # doctest: +SKIP - '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' - >>> dist.metadata['License'] # doctest: +SKIP - 'MIT' + .. versionadded:: 3.10 -For editable packages, an ``origin`` property may present :pep:`610` -metadata:: + The ``name`` shortcut was added. - >>> dist.origin.url - 'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl' + .. attribute:: origin -The full set of available metadata is not described here. -See the PyPA `Core metadata specification `_ for additional details. + For editable packages, an ``origin`` property may present :pep:`610` + metadata (for non-editable packages, ``origin`` is :const:`None`):: + + >>> dist.origin.url + 'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl' + + The ``origin`` object follows the `Direct URL Data Structure + `_. + + .. versionadded:: 3.13 + + .. attribute:: entry_points + :type: EntryPoints + + The entry points provided by this distribution package. + + .. attribute:: files + :type: list[PackagePath] | None + + All files contained in this distribution package. + Like :func:`files`, this returns :const:`None` if there are no records. + + The following two abstract methods need to be implemented when implementing-custom-providers_: + + .. method:: locate_file(path) + + Like :meth:`!PackagePath.locate`, return a :class:`SimplePath` for the given path. + Takes a :class:`os.PathLike` or a :class:`str`. + + .. method:: read_text(filename) + + A shortcut for ``distribution.locate_file(filename).read_text()``. -.. versionadded:: 3.13 - The ``.origin`` property was added. +.. _distribution-discovery: Distribution Discovery ====================== @@ -575,8 +637,8 @@ consumer. In practice, to support finding distribution package metadata in locations other than the file system, subclass -``Distribution`` and implement the abstract methods. Then from -a custom finder, return instances of this derived ``Distribution`` in the +:class:`!Distribution` and implement the abstract methods. Then from +a custom finder, return instances of this derived :class:`!Distribution` in the ``find_distributions()`` method. Example @@ -653,8 +715,8 @@ packages served by the ``DatabaseImporter``, assuming that the ``.entry_points`` attributes. The ``DatabaseDistribution`` may also provide other metadata files, like -``RECORD`` (required for ``Distribution.files``) or override the -implementation of ``Distribution.files``. See the source for more inspiration. +``RECORD`` (required for :attr:`!Distribution.files`) or override the +implementation of :attr:`!Distribution.files`. See the source for more inspiration. .. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index 7cf4d29d330c91..e91acc065ba9ae 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -41,6 +41,7 @@ 'DistributionFinder', 'PackageMetadata', 'PackageNotFoundError', + 'PackagePath', 'SimplePath', 'distribution', 'distributions', diff --git a/Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst b/Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst new file mode 100644 index 00000000000000..d29bde5ca690c6 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst @@ -0,0 +1 @@ +Document rest of full public :class:`importlib.metadata.Distribution` API. Also add the (already documented) :class:`~importlib.metadata.PackagePath` to ``__all__``. From fd0400585eb957c7d10812d87a8cb9e1f3c72519 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 24 Feb 2026 00:53:17 +0000 Subject: [PATCH 220/498] `_struct.c`: Fix UB from integer overflow in `prepare_s` (GH-145158) Avoid possible undefined behaviour from signed overflow in `struct` module As discovered via oss-fuzz. --- Lib/test/test_struct.py | 3 +++ .../2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst | 2 ++ Modules/_struct.c | 10 +++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index bffbcb1a60757d..aa793a2c223de9 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -552,6 +552,9 @@ def test_count_overflow(self): hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) self.assertRaises(struct.error, struct.calcsize, hugecount2) + hugecount3 = '{}i{}q'.format(sys.maxsize // 4, sys.maxsize // 8) + self.assertRaises(struct.error, struct.calcsize, hugecount3) + def test_trailing_counter(self): store = array.array('b', b' '*100) diff --git a/Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst b/Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst new file mode 100644 index 00000000000000..60a5e4ad1f0ca4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst @@ -0,0 +1,2 @@ +Avoid undefined behaviour from signed integer overflow when parsing format +strings in the :mod:`struct` module. diff --git a/Modules/_struct.c b/Modules/_struct.c index 7d2dfc591a2a58..ae8a8ffb3c005a 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1678,7 +1678,15 @@ prepare_s(PyStructObject *self) case 's': _Py_FALLTHROUGH; case 'p': len++; ncodes++; break; case 'x': break; - default: len += num; if (num) ncodes++; break; + default: + if (num > PY_SSIZE_T_MAX - len) { + goto overflow; + } + len += num; + if (num) { + ncodes++; + } + break; } itemsize = e->size; From b32c830d444c85421bd2c0c7af494c9d85485a29 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 24 Feb 2026 11:40:24 +0200 Subject: [PATCH 221/498] gh-101178: Fix possible integer overflow in Ascii85 encoder with wrapcol=1 (GH-144778) It could happen if the size of the input is more than 4/5 of sys.maxsize (only feasible on 32-bit platforms). Also simplify the integer overflow checks in the Base64 encoder, and harmonize them with the code for Ascii85 and Base85. --- Modules/binascii.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Modules/binascii.c b/Modules/binascii.c index 3abb90ab38bb7f..e6cd64338064b3 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -785,22 +785,21 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, size_t wrapcol, * Use unsigned integer arithmetic to avoid signed integer overflow. */ size_t out_len = ((size_t)bin_len + 2u) / 3u * 4u; - if (out_len > PY_SSIZE_T_MAX) { - goto toolong; - } if (wrapcol && out_len) { /* Each line should encode a whole number of bytes. */ wrapcol = wrapcol < 4 ? 4 : wrapcol / 4 * 4; out_len += (out_len - 1u) / wrapcol; - if (out_len > PY_SSIZE_T_MAX) { - goto toolong; - } } if (newline) { out_len++; - if (out_len > PY_SSIZE_T_MAX) { - goto toolong; + } + if (out_len > PY_SSIZE_T_MAX) { + binascii_state *state = get_binascii_state(module); + if (state == NULL) { + return NULL; } + PyErr_SetString(state->Error, "Too much data for base64"); + return NULL; } PyBytesWriter *writer = PyBytesWriter_Create(out_len); if (writer == NULL) { @@ -841,14 +840,6 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, size_t wrapcol, *ascii_data++ = '\n'; /* Append a courtesy newline */ return PyBytesWriter_FinishWithPointer(writer, ascii_data); - -toolong:; - binascii_state *state = get_binascii_state(module); - if (state == NULL) { - return NULL; - } - PyErr_SetString(state->Error, "Too much data for base64"); - return NULL; } /*[clinic input] @@ -1046,7 +1037,7 @@ binascii_b2a_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, if (!pad && (bin_len % 4)) { out_len -= 4 - (bin_len % 4); } - if (wrapcol && out_len) { + if (wrapcol && out_len && out_len <= PY_SSIZE_T_MAX) { out_len += (out_len - 1) / wrapcol; } if (out_len > PY_SSIZE_T_MAX) { From ca66d3c40cd9ac1fb94dd7cd79ccb8fecf019527 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 24 Feb 2026 13:05:06 +0200 Subject: [PATCH 222/498] gh-66305: Fix a hang on Windows in the tempfile module (GH-144672) It occurred when trying to create a temporary file or subdirectory in a non-writable directory. --- Lib/tempfile.py | 36 +++++++++---------- Lib/test/test_tempfile.py | 31 ++++++++++++---- ...6-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst | 3 ++ 3 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 2bc61662459992..6dac9ab3c41717 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -57,10 +57,11 @@ if hasattr(_os, 'O_BINARY'): _bin_openflags |= _os.O_BINARY -if hasattr(_os, 'TMP_MAX'): - TMP_MAX = _os.TMP_MAX -else: - TMP_MAX = 10000 +# This is more than enough. +# Each name contains over 40 random bits. Even with a million temporary +# files, the chance of a conflict is less than 1 in a million, and with +# 20 attempts, it is less than 1e-120. +TMP_MAX = 20 # This variable _was_ unused for legacy reasons, see issue 10354. # But as of 3.5 we actually use it at runtime so changing it would @@ -196,8 +197,7 @@ def _get_default_tempdir(dirlist=None): for dir in dirlist: if dir != _os.curdir: dir = _os.path.abspath(dir) - # Try only a few names per directory. - for seq in range(100): + for seq in range(TMP_MAX): name = next(namer) filename = _os.path.join(dir, name) try: @@ -213,10 +213,8 @@ def _get_default_tempdir(dirlist=None): except FileExistsError: pass except PermissionError: - # This exception is thrown when a directory with the chosen name - # already exists on windows. - if (_os.name == 'nt' and _os.path.isdir(dir) and - _os.access(dir, _os.W_OK)): + # See the comment in mkdtemp(). + if _os.name == 'nt' and _os.path.isdir(dir): continue break # no point trying more names in this directory except OSError: @@ -258,10 +256,8 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type): except FileExistsError: continue # try again except PermissionError: - # This exception is thrown when a directory with the chosen name - # already exists on windows. - if (_os.name == 'nt' and _os.path.isdir(dir) and - _os.access(dir, _os.W_OK)): + # See the comment in mkdtemp(). + if _os.name == 'nt' and _os.path.isdir(dir) and seq < TMP_MAX - 1: continue else: raise @@ -386,10 +382,14 @@ def mkdtemp(suffix=None, prefix=None, dir=None): except FileExistsError: continue # try again except PermissionError: - # This exception is thrown when a directory with the chosen name - # already exists on windows. - if (_os.name == 'nt' and _os.path.isdir(dir) and - _os.access(dir, _os.W_OK)): + # On Posix, this exception is raised when the user has no + # write access to the parent directory. + # On Windows, it is also raised when a directory with + # the chosen name already exists, or if the parent directory + # is not a directory. + # We cannot distinguish between "directory-exists-error" and + # "access-denied-error". + if _os.name == 'nt' and _os.path.isdir(dir) and seq < TMP_MAX - 1: continue else: raise diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 7eec34f2f294ad..b2b5390af33b00 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -330,17 +330,36 @@ def _mock_candidate_names(*names): class TestBadTempdir: def test_read_only_directory(self): with _inside_empty_temp_dir(): - oldmode = mode = os.stat(tempfile.tempdir).st_mode - mode &= ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH) - os.chmod(tempfile.tempdir, mode) + probe = os.path.join(tempfile.tempdir, 'probe') + if os.name == 'nt': + cmd = ['icacls', tempfile.tempdir, '/deny', 'Everyone:(W)'] + stdout = None if support.verbose > 1 else subprocess.DEVNULL + subprocess.run(cmd, check=True, stdout=stdout) + else: + oldmode = mode = os.stat(tempfile.tempdir).st_mode + mode &= ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH) + mode = stat.S_IREAD + os.chmod(tempfile.tempdir, mode) try: - if os.access(tempfile.tempdir, os.W_OK): + # Check that the directory is read-only. + try: + os.mkdir(probe) + except PermissionError: + pass + else: + os.rmdir(probe) self.skipTest("can't set the directory read-only") + # gh-66305: Now it takes a split second, but previously + # it took about 10 days on Windows. with self.assertRaises(PermissionError): self.make_temp() - self.assertEqual(os.listdir(tempfile.tempdir), []) finally: - os.chmod(tempfile.tempdir, oldmode) + if os.name == 'nt': + cmd = ['icacls', tempfile.tempdir, '/grant:r', 'Everyone:(M)'] + subprocess.run(cmd, check=True, stdout=stdout) + else: + os.chmod(tempfile.tempdir, oldmode) + self.assertEqual(os.listdir(tempfile.tempdir), []) def test_nonexisting_directory(self): with _inside_empty_temp_dir(): diff --git a/Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst b/Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst new file mode 100644 index 00000000000000..276711e6ba3900 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst @@ -0,0 +1,3 @@ +Fixed a hang on Windows in the :mod:`tempfile` module when +trying to create a temporary file or subdirectory in a non-writable +directory. From d6a71f4690c702892644b1fbae90ae9ef733a8ab Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 24 Feb 2026 13:27:49 +0200 Subject: [PATCH 223/498] gh-137335: Fix unlikely name conflicts for named pipes in multiprocessing and asyncio on Windows (#137389) Since os.stat() raises an OSError for existing named pipe "\\.\pipe\...", os.path.exists() always returns False for it, and tempfile.mktemp() can return a name that matches an existing named pipe. So, tempfile.mktemp() cannot be used to generate unique names for named pipes. Instead, CreateNamedPipe() should be called in a loop with different names until it completes successfully. --- Lib/asyncio/windows_utils.py | 23 +++++--- Lib/multiprocessing/connection.py | 58 +++++++++++++------ ...-08-04-23-20-43.gh-issue-137335.IIjDJN.rst | 2 + 3 files changed, 57 insertions(+), 26 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py index ef277fac3e291c..acd49441131b04 100644 --- a/Lib/asyncio/windows_utils.py +++ b/Lib/asyncio/windows_utils.py @@ -10,7 +10,6 @@ import msvcrt import os import subprocess -import tempfile import warnings @@ -24,6 +23,7 @@ PIPE = subprocess.PIPE STDOUT = subprocess.STDOUT _mmap_counter = itertools.count() +_MAX_PIPE_ATTEMPTS = 20 # Replacement for os.pipe() using handles instead of fds @@ -31,10 +31,6 @@ def pipe(*, duplex=False, overlapped=(True, True), bufsize=BUFSIZE): """Like os.pipe() but with overlapped support and using handles not fds.""" - address = tempfile.mktemp( - prefix=r'\\.\pipe\python-pipe-{:d}-{:d}-'.format( - os.getpid(), next(_mmap_counter))) - if duplex: openmode = _winapi.PIPE_ACCESS_DUPLEX access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE @@ -56,9 +52,20 @@ def pipe(*, duplex=False, overlapped=(True, True), bufsize=BUFSIZE): h1 = h2 = None try: - h1 = _winapi.CreateNamedPipe( - address, openmode, _winapi.PIPE_WAIT, - 1, obsize, ibsize, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL) + for attempts in itertools.count(): + address = r'\\.\pipe\python-pipe-{:d}-{:d}-{}'.format( + os.getpid(), next(_mmap_counter), os.urandom(8).hex()) + try: + h1 = _winapi.CreateNamedPipe( + address, openmode, _winapi.PIPE_WAIT, + 1, obsize, ibsize, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL) + break + except OSError as e: + if attempts >= _MAX_PIPE_ATTEMPTS: + raise + if e.winerror not in (_winapi.ERROR_PIPE_BUSY, + _winapi.ERROR_ACCESS_DENIED): + raise h2 = _winapi.CreateFile( address, access, 0, _winapi.NULL, _winapi.OPEN_EXISTING, diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 64ec53884aeb5d..41b36066c62fcb 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -46,6 +46,7 @@ CONNECTION_TIMEOUT = 20. _mmap_counter = itertools.count() +_MAX_PIPE_ATTEMPTS = 100 default_family = 'AF_INET' families = ['AF_INET'] @@ -78,8 +79,8 @@ def arbitrary_address(family): elif family == 'AF_UNIX': return tempfile.mktemp(prefix='sock-', dir=util.get_temp_dir()) elif family == 'AF_PIPE': - return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % - (os.getpid(), next(_mmap_counter)), dir="") + return (r'\\.\pipe\pyc-%d-%d-%s' % + (os.getpid(), next(_mmap_counter), os.urandom(8).hex())) else: raise ValueError('unrecognized family') @@ -472,17 +473,29 @@ class Listener(object): def __init__(self, address=None, family=None, backlog=1, authkey=None): family = family or (address and address_type(address)) \ or default_family - address = address or arbitrary_address(family) - _validate_family(family) + if authkey is not None and not isinstance(authkey, bytes): + raise TypeError('authkey should be a byte string') + if family == 'AF_PIPE': - self._listener = PipeListener(address, backlog) + if address: + self._listener = PipeListener(address, backlog) + else: + for attempts in itertools.count(): + address = arbitrary_address(family) + try: + self._listener = PipeListener(address, backlog) + break + except OSError as e: + if attempts >= _MAX_PIPE_ATTEMPTS: + raise + if e.winerror not in (_winapi.ERROR_PIPE_BUSY, + _winapi.ERROR_ACCESS_DENIED): + raise else: + address = address or arbitrary_address(family) self._listener = SocketListener(address, family, backlog) - if authkey is not None and not isinstance(authkey, bytes): - raise TypeError('authkey should be a byte string') - self._authkey = authkey def accept(self): @@ -570,7 +583,6 @@ def Pipe(duplex=True): ''' Returns pair of connection objects at either end of a pipe ''' - address = arbitrary_address('AF_PIPE') if duplex: openmode = _winapi.PIPE_ACCESS_DUPLEX access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE @@ -580,15 +592,25 @@ def Pipe(duplex=True): access = _winapi.GENERIC_WRITE obsize, ibsize = 0, BUFSIZE - h1 = _winapi.CreateNamedPipe( - address, openmode | _winapi.FILE_FLAG_OVERLAPPED | - _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE, - _winapi.PIPE_TYPE_MESSAGE | _winapi.PIPE_READMODE_MESSAGE | - _winapi.PIPE_WAIT, - 1, obsize, ibsize, _winapi.NMPWAIT_WAIT_FOREVER, - # default security descriptor: the handle cannot be inherited - _winapi.NULL - ) + for attempts in itertools.count(): + address = arbitrary_address('AF_PIPE') + try: + h1 = _winapi.CreateNamedPipe( + address, openmode | _winapi.FILE_FLAG_OVERLAPPED | + _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE, + _winapi.PIPE_TYPE_MESSAGE | _winapi.PIPE_READMODE_MESSAGE | + _winapi.PIPE_WAIT, + 1, obsize, ibsize, _winapi.NMPWAIT_WAIT_FOREVER, + # default security descriptor: the handle cannot be inherited + _winapi.NULL + ) + break + except OSError as e: + if attempts >= _MAX_PIPE_ATTEMPTS: + raise + if e.winerror not in (_winapi.ERROR_PIPE_BUSY, + _winapi.ERROR_ACCESS_DENIED): + raise h2 = _winapi.CreateFile( address, access, 0, _winapi.NULL, _winapi.OPEN_EXISTING, _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL diff --git a/Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst b/Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst new file mode 100644 index 00000000000000..2311ace10e411d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst @@ -0,0 +1,2 @@ +Get rid of any possibility of a name conflict for named pipes in +:mod:`multiprocessing` and :mod:`asyncio` on Windows, no matter how small. From 27ded243485670fa836c9bb421e37a6ef16eca8e Mon Sep 17 00:00:00 2001 From: Arjit Singh Grover <143692910+Koolvansh07@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:46:58 +0530 Subject: [PATCH 224/498] gh-143304: Fix ctypes.CDLL to honor handle parameter on POSIX systems (GH-143318) The handle parameter was being ignored in the POSIX implementation of CDLL._load_library(), causing it to always call _dlopen() even when a valid handle was provided. This was a regression introduced in recent refactoring. --- Lib/ctypes/__init__.py | 2 ++ Lib/test/test_ctypes/test_loading.py | 8 ++++++++ .../2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst | 1 + 3 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index aec92f3aee2472..1c822759eca912 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -458,6 +458,8 @@ def _load_library(self, name, mode, handle, winmode): if name and name.endswith(")") and ".a(" in name: mode |= _os.RTLD_MEMBER | _os.RTLD_NOW self._name = name + if handle is not None: + return handle return _dlopen(name, mode) def __repr__(self): diff --git a/Lib/test/test_ctypes/test_loading.py b/Lib/test/test_ctypes/test_loading.py index 3b8332fbb30928..343f6a07c0a32c 100644 --- a/Lib/test/test_ctypes/test_loading.py +++ b/Lib/test/test_ctypes/test_loading.py @@ -106,6 +106,14 @@ def test_load_without_name_and_with_handle(self): lib = ctypes.WinDLL(name=None, handle=handle) self.assertIs(handle, lib._handle) + @unittest.skipIf(os.name == "nt", 'POSIX-specific test') + @unittest.skipIf(libc_name is None, 'could not find libc') + def test_load_without_name_and_with_handle_posix(self): + lib1 = CDLL(libc_name) + handle = lib1._handle + lib2 = CDLL(name=None, handle=handle) + self.assertIs(lib2._handle, handle) + @unittest.skipUnless(os.name == "nt", 'Windows-specific test') def test_1703286_A(self): # On winXP 64-bit, advapi32 loads at an address that does diff --git a/Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst b/Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst new file mode 100644 index 00000000000000..826b2e9a126d36 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst @@ -0,0 +1 @@ +Fix :class:`ctypes.CDLL` to honor the ``handle`` parameter on POSIX systems. From 4c95ad8e495646eae4130957e0a4c1cc5ef19120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Tue, 24 Feb 2026 13:17:45 +0100 Subject: [PATCH 225/498] Fix `inspect.Parameter` docstring on the `kind` attribute (GH-143541) --- Lib/inspect.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 0eed68d17c702b..5d8ebb3dd54000 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2666,11 +2666,12 @@ class Parameter: The annotation for the parameter if specified. If the parameter has no annotation, this attribute is set to `Parameter.empty`. - * kind : str + * kind Describes how argument values are bound to the parameter. Possible values: `Parameter.POSITIONAL_ONLY`, `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`, `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`. + Every value has a `description` attribute describing meaning. """ __slots__ = ('_name', '_kind', '_default', '_annotation') From 0f759f11716a05726d46d0e1f6801485b9e8d22b Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Wed, 25 Feb 2026 00:48:45 +0900 Subject: [PATCH 226/498] gh-145122: Add _GUARD_NOS_ANY_DICT to prevent STORE_SUBSCR_DICT on frozendict (gh-145039) --- Include/internal/pycore_opcode_metadata.h | 4 +- Include/internal/pycore_uop_ids.h | 2075 +++++++++++---------- Include/internal/pycore_uop_metadata.h | 53 +- Lib/test/test_opcache.py | 24 + Modules/_testinternalcapi/test_cases.c.h | 6 +- Python/bytecodes.c | 11 +- Python/executor_cases.c.h | 103 +- Python/generated_cases.c.h | 6 +- Python/optimizer_bytecodes.c | 21 +- Python/optimizer_cases.c.h | 18 +- 10 files changed, 1243 insertions(+), 1078 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 4c1e7aebd0d291..fa8337bd08d470 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1353,7 +1353,7 @@ _PyOpcode_macro_expansion[256] = { [BINARY_OP_INPLACE_ADD_UNICODE] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_INPLACE_ADD_UNICODE, OPARG_SIMPLE, 5 } } }, [BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } }, [BINARY_OP_MULTIPLY_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } }, - [BINARY_OP_SUBSCR_DICT] = { .nuops = 4, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, + [BINARY_OP_SUBSCR_DICT] = { .nuops = 4, .uops = { { _GUARD_NOS_ANY_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_GETITEM] = { .nuops = 5, .uops = { { _RECORD_NOS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 5, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } }, @@ -1405,7 +1405,7 @@ _PyOpcode_macro_expansion[256] = { [COMPARE_OP_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 } } }, [COMPARE_OP_STR] = { .nuops = 5, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _COMPARE_OP_STR, OPARG_SIMPLE, 1 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 1 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 1 } } }, [CONTAINS_OP] = { .nuops = 3, .uops = { { _CONTAINS_OP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } }, - [CONTAINS_OP_DICT] = { .nuops = 4, .uops = { { _GUARD_TOS_DICT, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_DICT, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } }, + [CONTAINS_OP_DICT] = { .nuops = 4, .uops = { { _GUARD_TOS_ANY_DICT, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_DICT, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } }, [CONTAINS_OP_SET] = { .nuops = 4, .uops = { { _GUARD_TOS_ANY_SET, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_SET, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } }, [CONVERT_VALUE] = { .nuops = 1, .uops = { { _CONVERT_VALUE, OPARG_SIMPLE, 0 } } }, [COPY] = { .nuops = 1, .uops = { { _COPY, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index ebf21b12633c78..760fe86783fb8a 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -160,45 +160,46 @@ extern "C" { #define _GUARD_IS_NOT_NONE_POP 415 #define _GUARD_IS_TRUE_POP 416 #define _GUARD_KEYS_VERSION 417 -#define _GUARD_NOS_COMPACT_ASCII 418 -#define _GUARD_NOS_DICT 419 -#define _GUARD_NOS_FLOAT 420 -#define _GUARD_NOS_INT 421 -#define _GUARD_NOS_LIST 422 -#define _GUARD_NOS_NOT_NULL 423 -#define _GUARD_NOS_NULL 424 -#define _GUARD_NOS_OVERFLOWED 425 -#define _GUARD_NOS_TUPLE 426 -#define _GUARD_NOS_UNICODE 427 -#define _GUARD_NOT_EXHAUSTED_LIST 428 -#define _GUARD_NOT_EXHAUSTED_RANGE 429 -#define _GUARD_NOT_EXHAUSTED_TUPLE 430 -#define _GUARD_THIRD_NULL 431 -#define _GUARD_TOS_ANY_SET 432 -#define _GUARD_TOS_DICT 433 -#define _GUARD_TOS_FLOAT 434 -#define _GUARD_TOS_INT 435 -#define _GUARD_TOS_LIST 436 -#define _GUARD_TOS_OVERFLOWED 437 -#define _GUARD_TOS_SLICE 438 -#define _GUARD_TOS_TUPLE 439 -#define _GUARD_TOS_UNICODE 440 -#define _GUARD_TYPE_VERSION 441 -#define _GUARD_TYPE_VERSION_AND_LOCK 442 -#define _HANDLE_PENDING_AND_DEOPT 443 +#define _GUARD_NOS_ANY_DICT 418 +#define _GUARD_NOS_COMPACT_ASCII 419 +#define _GUARD_NOS_DICT 420 +#define _GUARD_NOS_FLOAT 421 +#define _GUARD_NOS_INT 422 +#define _GUARD_NOS_LIST 423 +#define _GUARD_NOS_NOT_NULL 424 +#define _GUARD_NOS_NULL 425 +#define _GUARD_NOS_OVERFLOWED 426 +#define _GUARD_NOS_TUPLE 427 +#define _GUARD_NOS_UNICODE 428 +#define _GUARD_NOT_EXHAUSTED_LIST 429 +#define _GUARD_NOT_EXHAUSTED_RANGE 430 +#define _GUARD_NOT_EXHAUSTED_TUPLE 431 +#define _GUARD_THIRD_NULL 432 +#define _GUARD_TOS_ANY_DICT 433 +#define _GUARD_TOS_ANY_SET 434 +#define _GUARD_TOS_FLOAT 435 +#define _GUARD_TOS_INT 436 +#define _GUARD_TOS_LIST 437 +#define _GUARD_TOS_OVERFLOWED 438 +#define _GUARD_TOS_SLICE 439 +#define _GUARD_TOS_TUPLE 440 +#define _GUARD_TOS_UNICODE 441 +#define _GUARD_TYPE_VERSION 442 +#define _GUARD_TYPE_VERSION_AND_LOCK 443 +#define _HANDLE_PENDING_AND_DEOPT 444 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 444 -#define _INIT_CALL_PY_EXACT_ARGS 445 -#define _INIT_CALL_PY_EXACT_ARGS_0 446 -#define _INIT_CALL_PY_EXACT_ARGS_1 447 -#define _INIT_CALL_PY_EXACT_ARGS_2 448 -#define _INIT_CALL_PY_EXACT_ARGS_3 449 -#define _INIT_CALL_PY_EXACT_ARGS_4 450 -#define _INSERT_1_LOAD_CONST_INLINE 451 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW 452 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW 453 -#define _INSERT_NULL 454 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 445 +#define _INIT_CALL_PY_EXACT_ARGS 446 +#define _INIT_CALL_PY_EXACT_ARGS_0 447 +#define _INIT_CALL_PY_EXACT_ARGS_1 448 +#define _INIT_CALL_PY_EXACT_ARGS_2 449 +#define _INIT_CALL_PY_EXACT_ARGS_3 450 +#define _INIT_CALL_PY_EXACT_ARGS_4 451 +#define _INSERT_1_LOAD_CONST_INLINE 452 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW 453 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW 454 +#define _INSERT_NULL 455 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -208,1050 +209,1054 @@ extern "C" { #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE -#define _IS_NONE 455 -#define _IS_OP 456 -#define _ITER_CHECK_LIST 457 -#define _ITER_CHECK_RANGE 458 -#define _ITER_CHECK_TUPLE 459 -#define _ITER_JUMP_LIST 460 -#define _ITER_JUMP_RANGE 461 -#define _ITER_JUMP_TUPLE 462 -#define _ITER_NEXT_LIST 463 -#define _ITER_NEXT_LIST_TIER_TWO 464 -#define _ITER_NEXT_RANGE 465 -#define _ITER_NEXT_TUPLE 466 +#define _IS_NONE 456 +#define _IS_OP 457 +#define _ITER_CHECK_LIST 458 +#define _ITER_CHECK_RANGE 459 +#define _ITER_CHECK_TUPLE 460 +#define _ITER_JUMP_LIST 461 +#define _ITER_JUMP_RANGE 462 +#define _ITER_JUMP_TUPLE 463 +#define _ITER_NEXT_LIST 464 +#define _ITER_NEXT_LIST_TIER_TWO 465 +#define _ITER_NEXT_RANGE 466 +#define _ITER_NEXT_TUPLE 467 #define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT -#define _JUMP_TO_TOP 467 +#define _JUMP_TO_TOP 468 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 468 -#define _LOAD_ATTR_CLASS 469 +#define _LOAD_ATTR 469 +#define _LOAD_ATTR_CLASS 470 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 470 -#define _LOAD_ATTR_METHOD_LAZY_DICT 471 -#define _LOAD_ATTR_METHOD_NO_DICT 472 -#define _LOAD_ATTR_METHOD_WITH_VALUES 473 -#define _LOAD_ATTR_MODULE 474 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 475 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 476 -#define _LOAD_ATTR_PROPERTY_FRAME 477 -#define _LOAD_ATTR_SLOT 478 -#define _LOAD_ATTR_WITH_HINT 479 +#define _LOAD_ATTR_INSTANCE_VALUE 471 +#define _LOAD_ATTR_METHOD_LAZY_DICT 472 +#define _LOAD_ATTR_METHOD_NO_DICT 473 +#define _LOAD_ATTR_METHOD_WITH_VALUES 474 +#define _LOAD_ATTR_MODULE 475 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 476 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 477 +#define _LOAD_ATTR_PROPERTY_FRAME 478 +#define _LOAD_ATTR_SLOT 479 +#define _LOAD_ATTR_WITH_HINT 480 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 480 +#define _LOAD_BYTECODE 481 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 481 -#define _LOAD_CONST_INLINE_BORROW 482 -#define _LOAD_CONST_UNDER_INLINE 483 -#define _LOAD_CONST_UNDER_INLINE_BORROW 484 +#define _LOAD_CONST_INLINE 482 +#define _LOAD_CONST_INLINE_BORROW 483 +#define _LOAD_CONST_UNDER_INLINE 484 +#define _LOAD_CONST_UNDER_INLINE_BORROW 485 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 485 -#define _LOAD_FAST_0 486 -#define _LOAD_FAST_1 487 -#define _LOAD_FAST_2 488 -#define _LOAD_FAST_3 489 -#define _LOAD_FAST_4 490 -#define _LOAD_FAST_5 491 -#define _LOAD_FAST_6 492 -#define _LOAD_FAST_7 493 +#define _LOAD_FAST 486 +#define _LOAD_FAST_0 487 +#define _LOAD_FAST_1 488 +#define _LOAD_FAST_2 489 +#define _LOAD_FAST_3 490 +#define _LOAD_FAST_4 491 +#define _LOAD_FAST_5 492 +#define _LOAD_FAST_6 493 +#define _LOAD_FAST_7 494 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 494 -#define _LOAD_FAST_BORROW_0 495 -#define _LOAD_FAST_BORROW_1 496 -#define _LOAD_FAST_BORROW_2 497 -#define _LOAD_FAST_BORROW_3 498 -#define _LOAD_FAST_BORROW_4 499 -#define _LOAD_FAST_BORROW_5 500 -#define _LOAD_FAST_BORROW_6 501 -#define _LOAD_FAST_BORROW_7 502 +#define _LOAD_FAST_BORROW 495 +#define _LOAD_FAST_BORROW_0 496 +#define _LOAD_FAST_BORROW_1 497 +#define _LOAD_FAST_BORROW_2 498 +#define _LOAD_FAST_BORROW_3 499 +#define _LOAD_FAST_BORROW_4 500 +#define _LOAD_FAST_BORROW_5 501 +#define _LOAD_FAST_BORROW_6 502 +#define _LOAD_FAST_BORROW_7 503 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 503 -#define _LOAD_GLOBAL_BUILTINS 504 -#define _LOAD_GLOBAL_MODULE 505 +#define _LOAD_GLOBAL 504 +#define _LOAD_GLOBAL_BUILTINS 505 +#define _LOAD_GLOBAL_MODULE 506 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 506 -#define _LOAD_SMALL_INT_0 507 -#define _LOAD_SMALL_INT_1 508 -#define _LOAD_SMALL_INT_2 509 -#define _LOAD_SMALL_INT_3 510 -#define _LOAD_SPECIAL 511 +#define _LOAD_SMALL_INT 507 +#define _LOAD_SMALL_INT_0 508 +#define _LOAD_SMALL_INT_1 509 +#define _LOAD_SMALL_INT_2 510 +#define _LOAD_SMALL_INT_3 511 +#define _LOAD_SPECIAL 512 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 512 +#define _MAKE_CALLARGS_A_TUPLE 513 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 513 +#define _MAKE_WARM 514 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 514 -#define _MAYBE_EXPAND_METHOD_KW 515 -#define _MONITOR_CALL 516 -#define _MONITOR_CALL_KW 517 -#define _MONITOR_JUMP_BACKWARD 518 -#define _MONITOR_RESUME 519 +#define _MAYBE_EXPAND_METHOD 515 +#define _MAYBE_EXPAND_METHOD_KW 516 +#define _MONITOR_CALL 517 +#define _MONITOR_CALL_KW 518 +#define _MONITOR_JUMP_BACKWARD 519 +#define _MONITOR_RESUME 520 #define _NOP NOP -#define _POP_CALL 520 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 521 -#define _POP_CALL_ONE 522 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 523 -#define _POP_CALL_TWO 524 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 525 +#define _POP_CALL 521 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 522 +#define _POP_CALL_ONE 523 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 524 +#define _POP_CALL_TWO 525 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 526 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 526 -#define _POP_JUMP_IF_TRUE 527 +#define _POP_JUMP_IF_FALSE 527 +#define _POP_JUMP_IF_TRUE 528 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 528 -#define _POP_TOP_INT 529 -#define _POP_TOP_LOAD_CONST_INLINE 530 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 531 -#define _POP_TOP_NOP 532 -#define _POP_TOP_UNICODE 533 -#define _POP_TWO 534 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 535 +#define _POP_TOP_FLOAT 529 +#define _POP_TOP_INT 530 +#define _POP_TOP_LOAD_CONST_INLINE 531 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 532 +#define _POP_TOP_NOP 533 +#define _POP_TOP_UNICODE 534 +#define _POP_TWO 535 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 536 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 536 +#define _PUSH_FRAME 537 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 537 -#define _PY_FRAME_EX 538 -#define _PY_FRAME_GENERAL 539 -#define _PY_FRAME_KW 540 -#define _QUICKEN_RESUME 541 -#define _RECORD_4OS 542 -#define _RECORD_BOUND_METHOD 543 -#define _RECORD_CALLABLE 544 -#define _RECORD_CODE 545 -#define _RECORD_NOS 546 -#define _RECORD_NOS_GEN_FUNC 547 -#define _RECORD_TOS 548 -#define _RECORD_TOS_TYPE 549 -#define _REPLACE_WITH_TRUE 550 +#define _PUSH_NULL_CONDITIONAL 538 +#define _PY_FRAME_EX 539 +#define _PY_FRAME_GENERAL 540 +#define _PY_FRAME_KW 541 +#define _QUICKEN_RESUME 542 +#define _RECORD_4OS 543 +#define _RECORD_BOUND_METHOD 544 +#define _RECORD_CALLABLE 545 +#define _RECORD_CODE 546 +#define _RECORD_NOS 547 +#define _RECORD_NOS_GEN_FUNC 548 +#define _RECORD_TOS 549 +#define _RECORD_TOS_TYPE 550 +#define _REPLACE_WITH_TRUE 551 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 551 -#define _SEND 552 -#define _SEND_GEN_FRAME 553 +#define _SAVE_RETURN_OFFSET 552 +#define _SEND 553 +#define _SEND_GEN_FRAME 554 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 554 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 555 -#define _SPILL_OR_RELOAD 556 -#define _START_EXECUTOR 557 -#define _STORE_ATTR 558 -#define _STORE_ATTR_INSTANCE_VALUE 559 -#define _STORE_ATTR_SLOT 560 -#define _STORE_ATTR_WITH_HINT 561 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 555 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 556 +#define _SPILL_OR_RELOAD 557 +#define _START_EXECUTOR 558 +#define _STORE_ATTR 559 +#define _STORE_ATTR_INSTANCE_VALUE 560 +#define _STORE_ATTR_SLOT 561 +#define _STORE_ATTR_WITH_HINT 562 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 562 -#define _STORE_SUBSCR 563 -#define _STORE_SUBSCR_DICT 564 -#define _STORE_SUBSCR_LIST_INT 565 -#define _SWAP 566 -#define _SWAP_2 567 -#define _SWAP_3 568 -#define _SWAP_FAST 569 -#define _SWAP_FAST_0 570 -#define _SWAP_FAST_1 571 -#define _SWAP_FAST_2 572 -#define _SWAP_FAST_3 573 -#define _SWAP_FAST_4 574 -#define _SWAP_FAST_5 575 -#define _SWAP_FAST_6 576 -#define _SWAP_FAST_7 577 -#define _TIER2_RESUME_CHECK 578 -#define _TO_BOOL 579 +#define _STORE_SLICE 563 +#define _STORE_SUBSCR 564 +#define _STORE_SUBSCR_DICT 565 +#define _STORE_SUBSCR_LIST_INT 566 +#define _SWAP 567 +#define _SWAP_2 568 +#define _SWAP_3 569 +#define _SWAP_FAST 570 +#define _SWAP_FAST_0 571 +#define _SWAP_FAST_1 572 +#define _SWAP_FAST_2 573 +#define _SWAP_FAST_3 574 +#define _SWAP_FAST_4 575 +#define _SWAP_FAST_5 576 +#define _SWAP_FAST_6 577 +#define _SWAP_FAST_7 578 +#define _TIER2_RESUME_CHECK 579 +#define _TO_BOOL 580 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 580 -#define _TO_BOOL_LIST 581 +#define _TO_BOOL_INT 581 +#define _TO_BOOL_LIST 582 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 582 +#define _TO_BOOL_STR 583 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 583 -#define _UNARY_NEGATIVE 584 +#define _UNARY_INVERT 584 +#define _UNARY_NEGATIVE 585 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 585 -#define _UNPACK_SEQUENCE_LIST 586 -#define _UNPACK_SEQUENCE_TUPLE 587 -#define _UNPACK_SEQUENCE_TWO_TUPLE 588 +#define _UNPACK_SEQUENCE 586 +#define _UNPACK_SEQUENCE_LIST 587 +#define _UNPACK_SEQUENCE_TUPLE 588 +#define _UNPACK_SEQUENCE_TWO_TUPLE 589 #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 588 -#define _BINARY_OP_r23 589 -#define _BINARY_OP_ADD_FLOAT_r03 590 -#define _BINARY_OP_ADD_FLOAT_r13 591 -#define _BINARY_OP_ADD_FLOAT_r23 592 -#define _BINARY_OP_ADD_INT_r03 593 -#define _BINARY_OP_ADD_INT_r13 594 -#define _BINARY_OP_ADD_INT_r23 595 -#define _BINARY_OP_ADD_UNICODE_r03 596 -#define _BINARY_OP_ADD_UNICODE_r13 597 -#define _BINARY_OP_ADD_UNICODE_r23 598 -#define _BINARY_OP_EXTEND_r23 599 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 600 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 601 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 602 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 603 -#define _BINARY_OP_MULTIPLY_INT_r03 604 -#define _BINARY_OP_MULTIPLY_INT_r13 605 -#define _BINARY_OP_MULTIPLY_INT_r23 606 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 607 -#define _BINARY_OP_SUBSCR_DICT_r23 608 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 609 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 610 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 611 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 612 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 613 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 614 -#define _BINARY_OP_SUBSCR_STR_INT_r23 615 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 616 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 617 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 618 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 619 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 620 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 621 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 622 -#define _BINARY_OP_SUBTRACT_INT_r03 623 -#define _BINARY_OP_SUBTRACT_INT_r13 624 -#define _BINARY_OP_SUBTRACT_INT_r23 625 -#define _BINARY_SLICE_r31 626 -#define _BUILD_INTERPOLATION_r01 627 -#define _BUILD_LIST_r01 628 -#define _BUILD_MAP_r01 629 -#define _BUILD_SET_r01 630 -#define _BUILD_SLICE_r01 631 -#define _BUILD_STRING_r01 632 -#define _BUILD_TEMPLATE_r21 633 -#define _BUILD_TUPLE_r01 634 -#define _CALL_BUILTIN_CLASS_r01 635 -#define _CALL_BUILTIN_FAST_r01 636 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 637 -#define _CALL_BUILTIN_O_r03 638 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 639 -#define _CALL_INTRINSIC_1_r11 640 -#define _CALL_INTRINSIC_2_r21 641 -#define _CALL_ISINSTANCE_r31 642 -#define _CALL_KW_NON_PY_r11 643 -#define _CALL_LEN_r33 644 -#define _CALL_LIST_APPEND_r03 645 -#define _CALL_LIST_APPEND_r13 646 -#define _CALL_LIST_APPEND_r23 647 -#define _CALL_LIST_APPEND_r33 648 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 649 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 650 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 651 -#define _CALL_METHOD_DESCRIPTOR_O_r03 652 -#define _CALL_NON_PY_GENERAL_r01 653 -#define _CALL_STR_1_r32 654 -#define _CALL_TUPLE_1_r32 655 -#define _CALL_TYPE_1_r02 656 -#define _CALL_TYPE_1_r12 657 -#define _CALL_TYPE_1_r22 658 -#define _CALL_TYPE_1_r32 659 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 660 -#define _CHECK_ATTR_CLASS_r01 661 -#define _CHECK_ATTR_CLASS_r11 662 -#define _CHECK_ATTR_CLASS_r22 663 -#define _CHECK_ATTR_CLASS_r33 664 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 665 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 666 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 667 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 668 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 669 -#define _CHECK_EG_MATCH_r22 670 -#define _CHECK_EXC_MATCH_r22 671 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 672 -#define _CHECK_FUNCTION_VERSION_r00 673 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 674 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 675 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 676 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 677 -#define _CHECK_FUNCTION_VERSION_KW_r11 678 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 679 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 680 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 681 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 682 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 683 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 684 -#define _CHECK_IS_PY_CALLABLE_EX_r03 685 -#define _CHECK_IS_PY_CALLABLE_EX_r13 686 -#define _CHECK_IS_PY_CALLABLE_EX_r23 687 -#define _CHECK_IS_PY_CALLABLE_EX_r33 688 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 689 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 690 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 691 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 692 -#define _CHECK_METHOD_VERSION_r00 693 -#define _CHECK_METHOD_VERSION_KW_r11 694 -#define _CHECK_PEP_523_r00 695 -#define _CHECK_PEP_523_r11 696 -#define _CHECK_PEP_523_r22 697 -#define _CHECK_PEP_523_r33 698 -#define _CHECK_PERIODIC_r00 699 -#define _CHECK_PERIODIC_AT_END_r00 700 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 701 -#define _CHECK_RECURSION_REMAINING_r00 702 -#define _CHECK_RECURSION_REMAINING_r11 703 -#define _CHECK_RECURSION_REMAINING_r22 704 -#define _CHECK_RECURSION_REMAINING_r33 705 -#define _CHECK_STACK_SPACE_r00 706 -#define _CHECK_STACK_SPACE_OPERAND_r00 707 -#define _CHECK_STACK_SPACE_OPERAND_r11 708 -#define _CHECK_STACK_SPACE_OPERAND_r22 709 -#define _CHECK_STACK_SPACE_OPERAND_r33 710 -#define _CHECK_VALIDITY_r00 711 -#define _CHECK_VALIDITY_r11 712 -#define _CHECK_VALIDITY_r22 713 -#define _CHECK_VALIDITY_r33 714 -#define _COLD_DYNAMIC_EXIT_r00 715 -#define _COLD_EXIT_r00 716 -#define _COMPARE_OP_r21 717 -#define _COMPARE_OP_FLOAT_r03 718 -#define _COMPARE_OP_FLOAT_r13 719 -#define _COMPARE_OP_FLOAT_r23 720 -#define _COMPARE_OP_INT_r23 721 -#define _COMPARE_OP_STR_r23 722 -#define _CONTAINS_OP_r23 723 -#define _CONTAINS_OP_DICT_r23 724 -#define _CONTAINS_OP_SET_r23 725 -#define _CONVERT_VALUE_r11 726 -#define _COPY_r01 727 -#define _COPY_1_r02 728 -#define _COPY_1_r12 729 -#define _COPY_1_r23 730 -#define _COPY_2_r03 731 -#define _COPY_2_r13 732 -#define _COPY_2_r23 733 -#define _COPY_3_r03 734 -#define _COPY_3_r13 735 -#define _COPY_3_r23 736 -#define _COPY_3_r33 737 -#define _COPY_FREE_VARS_r00 738 -#define _COPY_FREE_VARS_r11 739 -#define _COPY_FREE_VARS_r22 740 -#define _COPY_FREE_VARS_r33 741 -#define _CREATE_INIT_FRAME_r01 742 -#define _DELETE_ATTR_r10 743 -#define _DELETE_DEREF_r00 744 -#define _DELETE_FAST_r00 745 -#define _DELETE_GLOBAL_r00 746 -#define _DELETE_NAME_r00 747 -#define _DELETE_SUBSCR_r20 748 -#define _DEOPT_r00 749 -#define _DEOPT_r10 750 -#define _DEOPT_r20 751 -#define _DEOPT_r30 752 -#define _DICT_MERGE_r10 753 -#define _DICT_UPDATE_r10 754 -#define _DO_CALL_r01 755 -#define _DO_CALL_FUNCTION_EX_r31 756 -#define _DO_CALL_KW_r11 757 -#define _DYNAMIC_EXIT_r00 758 -#define _DYNAMIC_EXIT_r10 759 -#define _DYNAMIC_EXIT_r20 760 -#define _DYNAMIC_EXIT_r30 761 -#define _END_FOR_r10 762 -#define _END_SEND_r21 763 -#define _ERROR_POP_N_r00 764 -#define _EXIT_INIT_CHECK_r10 765 -#define _EXIT_TRACE_r00 766 -#define _EXIT_TRACE_r10 767 -#define _EXIT_TRACE_r20 768 -#define _EXIT_TRACE_r30 769 -#define _EXPAND_METHOD_r00 770 -#define _EXPAND_METHOD_KW_r11 771 -#define _FATAL_ERROR_r00 772 -#define _FATAL_ERROR_r11 773 -#define _FATAL_ERROR_r22 774 -#define _FATAL_ERROR_r33 775 -#define _FORMAT_SIMPLE_r11 776 -#define _FORMAT_WITH_SPEC_r21 777 -#define _FOR_ITER_r23 778 -#define _FOR_ITER_GEN_FRAME_r03 779 -#define _FOR_ITER_GEN_FRAME_r13 780 -#define _FOR_ITER_GEN_FRAME_r23 781 -#define _FOR_ITER_TIER_TWO_r23 782 -#define _GET_AITER_r11 783 -#define _GET_ANEXT_r12 784 -#define _GET_AWAITABLE_r11 785 -#define _GET_ITER_r12 786 -#define _GET_LEN_r12 787 -#define _GET_YIELD_FROM_ITER_r11 788 -#define _GUARD_BINARY_OP_EXTEND_r22 789 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 790 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 791 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 792 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 793 -#define _GUARD_BIT_IS_SET_POP_r00 794 -#define _GUARD_BIT_IS_SET_POP_r10 795 -#define _GUARD_BIT_IS_SET_POP_r21 796 -#define _GUARD_BIT_IS_SET_POP_r32 797 -#define _GUARD_BIT_IS_SET_POP_4_r00 798 -#define _GUARD_BIT_IS_SET_POP_4_r10 799 -#define _GUARD_BIT_IS_SET_POP_4_r21 800 -#define _GUARD_BIT_IS_SET_POP_4_r32 801 -#define _GUARD_BIT_IS_SET_POP_5_r00 802 -#define _GUARD_BIT_IS_SET_POP_5_r10 803 -#define _GUARD_BIT_IS_SET_POP_5_r21 804 -#define _GUARD_BIT_IS_SET_POP_5_r32 805 -#define _GUARD_BIT_IS_SET_POP_6_r00 806 -#define _GUARD_BIT_IS_SET_POP_6_r10 807 -#define _GUARD_BIT_IS_SET_POP_6_r21 808 -#define _GUARD_BIT_IS_SET_POP_6_r32 809 -#define _GUARD_BIT_IS_SET_POP_7_r00 810 -#define _GUARD_BIT_IS_SET_POP_7_r10 811 -#define _GUARD_BIT_IS_SET_POP_7_r21 812 -#define _GUARD_BIT_IS_SET_POP_7_r32 813 -#define _GUARD_BIT_IS_UNSET_POP_r00 814 -#define _GUARD_BIT_IS_UNSET_POP_r10 815 -#define _GUARD_BIT_IS_UNSET_POP_r21 816 -#define _GUARD_BIT_IS_UNSET_POP_r32 817 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 818 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 819 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 820 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 821 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 822 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 823 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 824 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 825 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 826 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 827 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 828 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 829 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 830 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 831 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 832 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 833 -#define _GUARD_CALLABLE_ISINSTANCE_r03 834 -#define _GUARD_CALLABLE_ISINSTANCE_r13 835 -#define _GUARD_CALLABLE_ISINSTANCE_r23 836 -#define _GUARD_CALLABLE_ISINSTANCE_r33 837 -#define _GUARD_CALLABLE_LEN_r03 838 -#define _GUARD_CALLABLE_LEN_r13 839 -#define _GUARD_CALLABLE_LEN_r23 840 -#define _GUARD_CALLABLE_LEN_r33 841 -#define _GUARD_CALLABLE_LIST_APPEND_r03 842 -#define _GUARD_CALLABLE_LIST_APPEND_r13 843 -#define _GUARD_CALLABLE_LIST_APPEND_r23 844 -#define _GUARD_CALLABLE_LIST_APPEND_r33 845 -#define _GUARD_CALLABLE_STR_1_r03 846 -#define _GUARD_CALLABLE_STR_1_r13 847 -#define _GUARD_CALLABLE_STR_1_r23 848 -#define _GUARD_CALLABLE_STR_1_r33 849 -#define _GUARD_CALLABLE_TUPLE_1_r03 850 -#define _GUARD_CALLABLE_TUPLE_1_r13 851 -#define _GUARD_CALLABLE_TUPLE_1_r23 852 -#define _GUARD_CALLABLE_TUPLE_1_r33 853 -#define _GUARD_CALLABLE_TYPE_1_r03 854 -#define _GUARD_CALLABLE_TYPE_1_r13 855 -#define _GUARD_CALLABLE_TYPE_1_r23 856 -#define _GUARD_CALLABLE_TYPE_1_r33 857 -#define _GUARD_CODE_VERSION_r00 858 -#define _GUARD_CODE_VERSION_r11 859 -#define _GUARD_CODE_VERSION_r22 860 -#define _GUARD_CODE_VERSION_r33 861 -#define _GUARD_DORV_NO_DICT_r01 862 -#define _GUARD_DORV_NO_DICT_r11 863 -#define _GUARD_DORV_NO_DICT_r22 864 -#define _GUARD_DORV_NO_DICT_r33 865 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 866 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 867 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 868 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 869 -#define _GUARD_GLOBALS_VERSION_r00 870 -#define _GUARD_GLOBALS_VERSION_r11 871 -#define _GUARD_GLOBALS_VERSION_r22 872 -#define _GUARD_GLOBALS_VERSION_r33 873 -#define _GUARD_IP_RETURN_GENERATOR_r00 874 -#define _GUARD_IP_RETURN_GENERATOR_r11 875 -#define _GUARD_IP_RETURN_GENERATOR_r22 876 -#define _GUARD_IP_RETURN_GENERATOR_r33 877 -#define _GUARD_IP_RETURN_VALUE_r00 878 -#define _GUARD_IP_RETURN_VALUE_r11 879 -#define _GUARD_IP_RETURN_VALUE_r22 880 -#define _GUARD_IP_RETURN_VALUE_r33 881 -#define _GUARD_IP_YIELD_VALUE_r00 882 -#define _GUARD_IP_YIELD_VALUE_r11 883 -#define _GUARD_IP_YIELD_VALUE_r22 884 -#define _GUARD_IP_YIELD_VALUE_r33 885 -#define _GUARD_IP__PUSH_FRAME_r00 886 -#define _GUARD_IP__PUSH_FRAME_r11 887 -#define _GUARD_IP__PUSH_FRAME_r22 888 -#define _GUARD_IP__PUSH_FRAME_r33 889 -#define _GUARD_IS_FALSE_POP_r00 890 -#define _GUARD_IS_FALSE_POP_r10 891 -#define _GUARD_IS_FALSE_POP_r21 892 -#define _GUARD_IS_FALSE_POP_r32 893 -#define _GUARD_IS_NONE_POP_r00 894 -#define _GUARD_IS_NONE_POP_r10 895 -#define _GUARD_IS_NONE_POP_r21 896 -#define _GUARD_IS_NONE_POP_r32 897 -#define _GUARD_IS_NOT_NONE_POP_r10 898 -#define _GUARD_IS_TRUE_POP_r00 899 -#define _GUARD_IS_TRUE_POP_r10 900 -#define _GUARD_IS_TRUE_POP_r21 901 -#define _GUARD_IS_TRUE_POP_r32 902 -#define _GUARD_KEYS_VERSION_r01 903 -#define _GUARD_KEYS_VERSION_r11 904 -#define _GUARD_KEYS_VERSION_r22 905 -#define _GUARD_KEYS_VERSION_r33 906 -#define _GUARD_NOS_COMPACT_ASCII_r02 907 -#define _GUARD_NOS_COMPACT_ASCII_r12 908 -#define _GUARD_NOS_COMPACT_ASCII_r22 909 -#define _GUARD_NOS_COMPACT_ASCII_r33 910 -#define _GUARD_NOS_DICT_r02 911 -#define _GUARD_NOS_DICT_r12 912 -#define _GUARD_NOS_DICT_r22 913 -#define _GUARD_NOS_DICT_r33 914 -#define _GUARD_NOS_FLOAT_r02 915 -#define _GUARD_NOS_FLOAT_r12 916 -#define _GUARD_NOS_FLOAT_r22 917 -#define _GUARD_NOS_FLOAT_r33 918 -#define _GUARD_NOS_INT_r02 919 -#define _GUARD_NOS_INT_r12 920 -#define _GUARD_NOS_INT_r22 921 -#define _GUARD_NOS_INT_r33 922 -#define _GUARD_NOS_LIST_r02 923 -#define _GUARD_NOS_LIST_r12 924 -#define _GUARD_NOS_LIST_r22 925 -#define _GUARD_NOS_LIST_r33 926 -#define _GUARD_NOS_NOT_NULL_r02 927 -#define _GUARD_NOS_NOT_NULL_r12 928 -#define _GUARD_NOS_NOT_NULL_r22 929 -#define _GUARD_NOS_NOT_NULL_r33 930 -#define _GUARD_NOS_NULL_r02 931 -#define _GUARD_NOS_NULL_r12 932 -#define _GUARD_NOS_NULL_r22 933 -#define _GUARD_NOS_NULL_r33 934 -#define _GUARD_NOS_OVERFLOWED_r02 935 -#define _GUARD_NOS_OVERFLOWED_r12 936 -#define _GUARD_NOS_OVERFLOWED_r22 937 -#define _GUARD_NOS_OVERFLOWED_r33 938 -#define _GUARD_NOS_TUPLE_r02 939 -#define _GUARD_NOS_TUPLE_r12 940 -#define _GUARD_NOS_TUPLE_r22 941 -#define _GUARD_NOS_TUPLE_r33 942 -#define _GUARD_NOS_UNICODE_r02 943 -#define _GUARD_NOS_UNICODE_r12 944 -#define _GUARD_NOS_UNICODE_r22 945 -#define _GUARD_NOS_UNICODE_r33 946 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 947 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 948 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 949 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 950 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 951 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 952 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 953 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 954 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 955 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 956 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 957 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 958 -#define _GUARD_THIRD_NULL_r03 959 -#define _GUARD_THIRD_NULL_r13 960 -#define _GUARD_THIRD_NULL_r23 961 -#define _GUARD_THIRD_NULL_r33 962 -#define _GUARD_TOS_ANY_SET_r01 963 -#define _GUARD_TOS_ANY_SET_r11 964 -#define _GUARD_TOS_ANY_SET_r22 965 -#define _GUARD_TOS_ANY_SET_r33 966 -#define _GUARD_TOS_DICT_r01 967 -#define _GUARD_TOS_DICT_r11 968 -#define _GUARD_TOS_DICT_r22 969 -#define _GUARD_TOS_DICT_r33 970 -#define _GUARD_TOS_FLOAT_r01 971 -#define _GUARD_TOS_FLOAT_r11 972 -#define _GUARD_TOS_FLOAT_r22 973 -#define _GUARD_TOS_FLOAT_r33 974 -#define _GUARD_TOS_INT_r01 975 -#define _GUARD_TOS_INT_r11 976 -#define _GUARD_TOS_INT_r22 977 -#define _GUARD_TOS_INT_r33 978 -#define _GUARD_TOS_LIST_r01 979 -#define _GUARD_TOS_LIST_r11 980 -#define _GUARD_TOS_LIST_r22 981 -#define _GUARD_TOS_LIST_r33 982 -#define _GUARD_TOS_OVERFLOWED_r01 983 -#define _GUARD_TOS_OVERFLOWED_r11 984 -#define _GUARD_TOS_OVERFLOWED_r22 985 -#define _GUARD_TOS_OVERFLOWED_r33 986 -#define _GUARD_TOS_SLICE_r01 987 -#define _GUARD_TOS_SLICE_r11 988 -#define _GUARD_TOS_SLICE_r22 989 -#define _GUARD_TOS_SLICE_r33 990 -#define _GUARD_TOS_TUPLE_r01 991 -#define _GUARD_TOS_TUPLE_r11 992 -#define _GUARD_TOS_TUPLE_r22 993 -#define _GUARD_TOS_TUPLE_r33 994 -#define _GUARD_TOS_UNICODE_r01 995 -#define _GUARD_TOS_UNICODE_r11 996 -#define _GUARD_TOS_UNICODE_r22 997 -#define _GUARD_TOS_UNICODE_r33 998 -#define _GUARD_TYPE_VERSION_r01 999 -#define _GUARD_TYPE_VERSION_r11 1000 -#define _GUARD_TYPE_VERSION_r22 1001 -#define _GUARD_TYPE_VERSION_r33 1002 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1003 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1004 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1005 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1006 -#define _HANDLE_PENDING_AND_DEOPT_r00 1007 -#define _HANDLE_PENDING_AND_DEOPT_r10 1008 -#define _HANDLE_PENDING_AND_DEOPT_r20 1009 -#define _HANDLE_PENDING_AND_DEOPT_r30 1010 -#define _IMPORT_FROM_r12 1011 -#define _IMPORT_NAME_r21 1012 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1013 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1014 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1015 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1016 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1017 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1018 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1019 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1020 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1021 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1022 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1023 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1024 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1025 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1026 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1027 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1028 -#define _INSERT_NULL_r10 1029 -#define _INSTRUMENTED_FOR_ITER_r23 1030 -#define _INSTRUMENTED_INSTRUCTION_r00 1031 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1032 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1033 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1034 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1035 -#define _INSTRUMENTED_LINE_r00 1036 -#define _INSTRUMENTED_NOT_TAKEN_r00 1037 -#define _INSTRUMENTED_NOT_TAKEN_r11 1038 -#define _INSTRUMENTED_NOT_TAKEN_r22 1039 -#define _INSTRUMENTED_NOT_TAKEN_r33 1040 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1041 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1042 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1043 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1044 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1045 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1046 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1047 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1048 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1049 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1050 -#define _IS_NONE_r11 1051 -#define _IS_OP_r03 1052 -#define _IS_OP_r13 1053 -#define _IS_OP_r23 1054 -#define _ITER_CHECK_LIST_r02 1055 -#define _ITER_CHECK_LIST_r12 1056 -#define _ITER_CHECK_LIST_r22 1057 -#define _ITER_CHECK_LIST_r33 1058 -#define _ITER_CHECK_RANGE_r02 1059 -#define _ITER_CHECK_RANGE_r12 1060 -#define _ITER_CHECK_RANGE_r22 1061 -#define _ITER_CHECK_RANGE_r33 1062 -#define _ITER_CHECK_TUPLE_r02 1063 -#define _ITER_CHECK_TUPLE_r12 1064 -#define _ITER_CHECK_TUPLE_r22 1065 -#define _ITER_CHECK_TUPLE_r33 1066 -#define _ITER_JUMP_LIST_r02 1067 -#define _ITER_JUMP_LIST_r12 1068 -#define _ITER_JUMP_LIST_r22 1069 -#define _ITER_JUMP_LIST_r33 1070 -#define _ITER_JUMP_RANGE_r02 1071 -#define _ITER_JUMP_RANGE_r12 1072 -#define _ITER_JUMP_RANGE_r22 1073 -#define _ITER_JUMP_RANGE_r33 1074 -#define _ITER_JUMP_TUPLE_r02 1075 -#define _ITER_JUMP_TUPLE_r12 1076 -#define _ITER_JUMP_TUPLE_r22 1077 -#define _ITER_JUMP_TUPLE_r33 1078 -#define _ITER_NEXT_LIST_r23 1079 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1080 -#define _ITER_NEXT_RANGE_r03 1081 -#define _ITER_NEXT_RANGE_r13 1082 -#define _ITER_NEXT_RANGE_r23 1083 -#define _ITER_NEXT_TUPLE_r03 1084 -#define _ITER_NEXT_TUPLE_r13 1085 -#define _ITER_NEXT_TUPLE_r23 1086 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1087 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1088 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1089 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1090 -#define _JUMP_TO_TOP_r00 1091 -#define _LIST_APPEND_r10 1092 -#define _LIST_EXTEND_r10 1093 -#define _LOAD_ATTR_r10 1094 -#define _LOAD_ATTR_CLASS_r11 1095 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1096 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1097 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1098 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1099 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1100 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1101 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1102 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1103 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1104 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1105 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1106 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1107 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1108 -#define _LOAD_ATTR_MODULE_r12 1109 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1110 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1111 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1112 -#define _LOAD_ATTR_SLOT_r02 1113 -#define _LOAD_ATTR_SLOT_r12 1114 -#define _LOAD_ATTR_SLOT_r23 1115 -#define _LOAD_ATTR_WITH_HINT_r12 1116 -#define _LOAD_BUILD_CLASS_r01 1117 -#define _LOAD_BYTECODE_r00 1118 -#define _LOAD_COMMON_CONSTANT_r01 1119 -#define _LOAD_COMMON_CONSTANT_r12 1120 -#define _LOAD_COMMON_CONSTANT_r23 1121 -#define _LOAD_CONST_r01 1122 -#define _LOAD_CONST_r12 1123 -#define _LOAD_CONST_r23 1124 -#define _LOAD_CONST_INLINE_r01 1125 -#define _LOAD_CONST_INLINE_r12 1126 -#define _LOAD_CONST_INLINE_r23 1127 -#define _LOAD_CONST_INLINE_BORROW_r01 1128 -#define _LOAD_CONST_INLINE_BORROW_r12 1129 -#define _LOAD_CONST_INLINE_BORROW_r23 1130 -#define _LOAD_CONST_UNDER_INLINE_r02 1131 -#define _LOAD_CONST_UNDER_INLINE_r12 1132 -#define _LOAD_CONST_UNDER_INLINE_r23 1133 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1134 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1135 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1136 -#define _LOAD_DEREF_r01 1137 -#define _LOAD_FAST_r01 1138 -#define _LOAD_FAST_r12 1139 -#define _LOAD_FAST_r23 1140 -#define _LOAD_FAST_0_r01 1141 -#define _LOAD_FAST_0_r12 1142 -#define _LOAD_FAST_0_r23 1143 -#define _LOAD_FAST_1_r01 1144 -#define _LOAD_FAST_1_r12 1145 -#define _LOAD_FAST_1_r23 1146 -#define _LOAD_FAST_2_r01 1147 -#define _LOAD_FAST_2_r12 1148 -#define _LOAD_FAST_2_r23 1149 -#define _LOAD_FAST_3_r01 1150 -#define _LOAD_FAST_3_r12 1151 -#define _LOAD_FAST_3_r23 1152 -#define _LOAD_FAST_4_r01 1153 -#define _LOAD_FAST_4_r12 1154 -#define _LOAD_FAST_4_r23 1155 -#define _LOAD_FAST_5_r01 1156 -#define _LOAD_FAST_5_r12 1157 -#define _LOAD_FAST_5_r23 1158 -#define _LOAD_FAST_6_r01 1159 -#define _LOAD_FAST_6_r12 1160 -#define _LOAD_FAST_6_r23 1161 -#define _LOAD_FAST_7_r01 1162 -#define _LOAD_FAST_7_r12 1163 -#define _LOAD_FAST_7_r23 1164 -#define _LOAD_FAST_AND_CLEAR_r01 1165 -#define _LOAD_FAST_AND_CLEAR_r12 1166 -#define _LOAD_FAST_AND_CLEAR_r23 1167 -#define _LOAD_FAST_BORROW_r01 1168 -#define _LOAD_FAST_BORROW_r12 1169 -#define _LOAD_FAST_BORROW_r23 1170 -#define _LOAD_FAST_BORROW_0_r01 1171 -#define _LOAD_FAST_BORROW_0_r12 1172 -#define _LOAD_FAST_BORROW_0_r23 1173 -#define _LOAD_FAST_BORROW_1_r01 1174 -#define _LOAD_FAST_BORROW_1_r12 1175 -#define _LOAD_FAST_BORROW_1_r23 1176 -#define _LOAD_FAST_BORROW_2_r01 1177 -#define _LOAD_FAST_BORROW_2_r12 1178 -#define _LOAD_FAST_BORROW_2_r23 1179 -#define _LOAD_FAST_BORROW_3_r01 1180 -#define _LOAD_FAST_BORROW_3_r12 1181 -#define _LOAD_FAST_BORROW_3_r23 1182 -#define _LOAD_FAST_BORROW_4_r01 1183 -#define _LOAD_FAST_BORROW_4_r12 1184 -#define _LOAD_FAST_BORROW_4_r23 1185 -#define _LOAD_FAST_BORROW_5_r01 1186 -#define _LOAD_FAST_BORROW_5_r12 1187 -#define _LOAD_FAST_BORROW_5_r23 1188 -#define _LOAD_FAST_BORROW_6_r01 1189 -#define _LOAD_FAST_BORROW_6_r12 1190 -#define _LOAD_FAST_BORROW_6_r23 1191 -#define _LOAD_FAST_BORROW_7_r01 1192 -#define _LOAD_FAST_BORROW_7_r12 1193 -#define _LOAD_FAST_BORROW_7_r23 1194 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1195 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1196 -#define _LOAD_FAST_CHECK_r01 1197 -#define _LOAD_FAST_CHECK_r12 1198 -#define _LOAD_FAST_CHECK_r23 1199 -#define _LOAD_FAST_LOAD_FAST_r02 1200 -#define _LOAD_FAST_LOAD_FAST_r13 1201 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1202 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1203 -#define _LOAD_GLOBAL_r00 1204 -#define _LOAD_GLOBAL_BUILTINS_r01 1205 -#define _LOAD_GLOBAL_MODULE_r01 1206 -#define _LOAD_LOCALS_r01 1207 -#define _LOAD_LOCALS_r12 1208 -#define _LOAD_LOCALS_r23 1209 -#define _LOAD_NAME_r01 1210 -#define _LOAD_SMALL_INT_r01 1211 -#define _LOAD_SMALL_INT_r12 1212 -#define _LOAD_SMALL_INT_r23 1213 -#define _LOAD_SMALL_INT_0_r01 1214 -#define _LOAD_SMALL_INT_0_r12 1215 -#define _LOAD_SMALL_INT_0_r23 1216 -#define _LOAD_SMALL_INT_1_r01 1217 -#define _LOAD_SMALL_INT_1_r12 1218 -#define _LOAD_SMALL_INT_1_r23 1219 -#define _LOAD_SMALL_INT_2_r01 1220 -#define _LOAD_SMALL_INT_2_r12 1221 -#define _LOAD_SMALL_INT_2_r23 1222 -#define _LOAD_SMALL_INT_3_r01 1223 -#define _LOAD_SMALL_INT_3_r12 1224 -#define _LOAD_SMALL_INT_3_r23 1225 -#define _LOAD_SPECIAL_r00 1226 -#define _LOAD_SUPER_ATTR_ATTR_r31 1227 -#define _LOAD_SUPER_ATTR_METHOD_r32 1228 -#define _MAKE_CALLARGS_A_TUPLE_r33 1229 -#define _MAKE_CELL_r00 1230 -#define _MAKE_FUNCTION_r11 1231 -#define _MAKE_WARM_r00 1232 -#define _MAKE_WARM_r11 1233 -#define _MAKE_WARM_r22 1234 -#define _MAKE_WARM_r33 1235 -#define _MAP_ADD_r20 1236 -#define _MATCH_CLASS_r31 1237 -#define _MATCH_KEYS_r23 1238 -#define _MATCH_MAPPING_r02 1239 -#define _MATCH_MAPPING_r12 1240 -#define _MATCH_MAPPING_r23 1241 -#define _MATCH_SEQUENCE_r02 1242 -#define _MATCH_SEQUENCE_r12 1243 -#define _MATCH_SEQUENCE_r23 1244 -#define _MAYBE_EXPAND_METHOD_r00 1245 -#define _MAYBE_EXPAND_METHOD_KW_r11 1246 -#define _MONITOR_CALL_r00 1247 -#define _MONITOR_CALL_KW_r11 1248 -#define _MONITOR_JUMP_BACKWARD_r00 1249 -#define _MONITOR_JUMP_BACKWARD_r11 1250 -#define _MONITOR_JUMP_BACKWARD_r22 1251 -#define _MONITOR_JUMP_BACKWARD_r33 1252 -#define _MONITOR_RESUME_r00 1253 -#define _NOP_r00 1254 -#define _NOP_r11 1255 -#define _NOP_r22 1256 -#define _NOP_r33 1257 -#define _POP_CALL_r20 1258 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1259 -#define _POP_CALL_ONE_r30 1260 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1261 -#define _POP_CALL_TWO_r30 1262 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1263 -#define _POP_EXCEPT_r10 1264 -#define _POP_ITER_r20 1265 -#define _POP_JUMP_IF_FALSE_r00 1266 -#define _POP_JUMP_IF_FALSE_r10 1267 -#define _POP_JUMP_IF_FALSE_r21 1268 -#define _POP_JUMP_IF_FALSE_r32 1269 -#define _POP_JUMP_IF_TRUE_r00 1270 -#define _POP_JUMP_IF_TRUE_r10 1271 -#define _POP_JUMP_IF_TRUE_r21 1272 -#define _POP_JUMP_IF_TRUE_r32 1273 -#define _POP_TOP_r10 1274 -#define _POP_TOP_FLOAT_r00 1275 -#define _POP_TOP_FLOAT_r10 1276 -#define _POP_TOP_FLOAT_r21 1277 -#define _POP_TOP_FLOAT_r32 1278 -#define _POP_TOP_INT_r00 1279 -#define _POP_TOP_INT_r10 1280 -#define _POP_TOP_INT_r21 1281 -#define _POP_TOP_INT_r32 1282 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1283 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1284 -#define _POP_TOP_NOP_r00 1285 -#define _POP_TOP_NOP_r10 1286 -#define _POP_TOP_NOP_r21 1287 -#define _POP_TOP_NOP_r32 1288 -#define _POP_TOP_UNICODE_r00 1289 -#define _POP_TOP_UNICODE_r10 1290 -#define _POP_TOP_UNICODE_r21 1291 -#define _POP_TOP_UNICODE_r32 1292 -#define _POP_TWO_r20 1293 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1294 -#define _PUSH_EXC_INFO_r02 1295 -#define _PUSH_EXC_INFO_r12 1296 -#define _PUSH_EXC_INFO_r23 1297 -#define _PUSH_FRAME_r10 1298 -#define _PUSH_NULL_r01 1299 -#define _PUSH_NULL_r12 1300 -#define _PUSH_NULL_r23 1301 -#define _PUSH_NULL_CONDITIONAL_r00 1302 -#define _PY_FRAME_EX_r31 1303 -#define _PY_FRAME_GENERAL_r01 1304 -#define _PY_FRAME_KW_r11 1305 -#define _QUICKEN_RESUME_r00 1306 -#define _QUICKEN_RESUME_r11 1307 -#define _QUICKEN_RESUME_r22 1308 -#define _QUICKEN_RESUME_r33 1309 -#define _REPLACE_WITH_TRUE_r02 1310 -#define _REPLACE_WITH_TRUE_r12 1311 -#define _REPLACE_WITH_TRUE_r23 1312 -#define _RESUME_CHECK_r00 1313 -#define _RESUME_CHECK_r11 1314 -#define _RESUME_CHECK_r22 1315 -#define _RESUME_CHECK_r33 1316 -#define _RETURN_GENERATOR_r01 1317 -#define _RETURN_VALUE_r11 1318 -#define _SAVE_RETURN_OFFSET_r00 1319 -#define _SAVE_RETURN_OFFSET_r11 1320 -#define _SAVE_RETURN_OFFSET_r22 1321 -#define _SAVE_RETURN_OFFSET_r33 1322 -#define _SEND_r22 1323 -#define _SEND_GEN_FRAME_r22 1324 -#define _SETUP_ANNOTATIONS_r00 1325 -#define _SET_ADD_r10 1326 -#define _SET_FUNCTION_ATTRIBUTE_r01 1327 -#define _SET_FUNCTION_ATTRIBUTE_r11 1328 -#define _SET_FUNCTION_ATTRIBUTE_r21 1329 -#define _SET_FUNCTION_ATTRIBUTE_r32 1330 -#define _SET_IP_r00 1331 -#define _SET_IP_r11 1332 -#define _SET_IP_r22 1333 -#define _SET_IP_r33 1334 -#define _SET_UPDATE_r10 1335 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1336 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1337 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1338 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1339 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1340 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1341 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1342 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1343 -#define _SPILL_OR_RELOAD_r01 1344 -#define _SPILL_OR_RELOAD_r02 1345 -#define _SPILL_OR_RELOAD_r03 1346 -#define _SPILL_OR_RELOAD_r10 1347 -#define _SPILL_OR_RELOAD_r12 1348 -#define _SPILL_OR_RELOAD_r13 1349 -#define _SPILL_OR_RELOAD_r20 1350 -#define _SPILL_OR_RELOAD_r21 1351 -#define _SPILL_OR_RELOAD_r23 1352 -#define _SPILL_OR_RELOAD_r30 1353 -#define _SPILL_OR_RELOAD_r31 1354 -#define _SPILL_OR_RELOAD_r32 1355 -#define _START_EXECUTOR_r00 1356 -#define _STORE_ATTR_r20 1357 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1358 -#define _STORE_ATTR_SLOT_r21 1359 -#define _STORE_ATTR_WITH_HINT_r21 1360 -#define _STORE_DEREF_r10 1361 -#define _STORE_FAST_LOAD_FAST_r11 1362 -#define _STORE_FAST_STORE_FAST_r20 1363 -#define _STORE_GLOBAL_r10 1364 -#define _STORE_NAME_r10 1365 -#define _STORE_SLICE_r30 1366 -#define _STORE_SUBSCR_r30 1367 -#define _STORE_SUBSCR_DICT_r31 1368 -#define _STORE_SUBSCR_LIST_INT_r32 1369 -#define _SWAP_r11 1370 -#define _SWAP_2_r02 1371 -#define _SWAP_2_r12 1372 -#define _SWAP_2_r22 1373 -#define _SWAP_2_r33 1374 -#define _SWAP_3_r03 1375 -#define _SWAP_3_r13 1376 -#define _SWAP_3_r23 1377 -#define _SWAP_3_r33 1378 -#define _SWAP_FAST_r01 1379 -#define _SWAP_FAST_r11 1380 -#define _SWAP_FAST_r22 1381 -#define _SWAP_FAST_r33 1382 -#define _SWAP_FAST_0_r01 1383 -#define _SWAP_FAST_0_r11 1384 -#define _SWAP_FAST_0_r22 1385 -#define _SWAP_FAST_0_r33 1386 -#define _SWAP_FAST_1_r01 1387 -#define _SWAP_FAST_1_r11 1388 -#define _SWAP_FAST_1_r22 1389 -#define _SWAP_FAST_1_r33 1390 -#define _SWAP_FAST_2_r01 1391 -#define _SWAP_FAST_2_r11 1392 -#define _SWAP_FAST_2_r22 1393 -#define _SWAP_FAST_2_r33 1394 -#define _SWAP_FAST_3_r01 1395 -#define _SWAP_FAST_3_r11 1396 -#define _SWAP_FAST_3_r22 1397 -#define _SWAP_FAST_3_r33 1398 -#define _SWAP_FAST_4_r01 1399 -#define _SWAP_FAST_4_r11 1400 -#define _SWAP_FAST_4_r22 1401 -#define _SWAP_FAST_4_r33 1402 -#define _SWAP_FAST_5_r01 1403 -#define _SWAP_FAST_5_r11 1404 -#define _SWAP_FAST_5_r22 1405 -#define _SWAP_FAST_5_r33 1406 -#define _SWAP_FAST_6_r01 1407 -#define _SWAP_FAST_6_r11 1408 -#define _SWAP_FAST_6_r22 1409 -#define _SWAP_FAST_6_r33 1410 -#define _SWAP_FAST_7_r01 1411 -#define _SWAP_FAST_7_r11 1412 -#define _SWAP_FAST_7_r22 1413 -#define _SWAP_FAST_7_r33 1414 -#define _TIER2_RESUME_CHECK_r00 1415 -#define _TIER2_RESUME_CHECK_r11 1416 -#define _TIER2_RESUME_CHECK_r22 1417 -#define _TIER2_RESUME_CHECK_r33 1418 -#define _TO_BOOL_r11 1419 -#define _TO_BOOL_BOOL_r01 1420 -#define _TO_BOOL_BOOL_r11 1421 -#define _TO_BOOL_BOOL_r22 1422 -#define _TO_BOOL_BOOL_r33 1423 -#define _TO_BOOL_INT_r02 1424 -#define _TO_BOOL_INT_r12 1425 -#define _TO_BOOL_INT_r23 1426 -#define _TO_BOOL_LIST_r02 1427 -#define _TO_BOOL_LIST_r12 1428 -#define _TO_BOOL_LIST_r23 1429 -#define _TO_BOOL_NONE_r01 1430 -#define _TO_BOOL_NONE_r11 1431 -#define _TO_BOOL_NONE_r22 1432 -#define _TO_BOOL_NONE_r33 1433 -#define _TO_BOOL_STR_r02 1434 -#define _TO_BOOL_STR_r12 1435 -#define _TO_BOOL_STR_r23 1436 -#define _TRACE_RECORD_r00 1437 -#define _UNARY_INVERT_r12 1438 -#define _UNARY_NEGATIVE_r12 1439 -#define _UNARY_NOT_r01 1440 -#define _UNARY_NOT_r11 1441 -#define _UNARY_NOT_r22 1442 -#define _UNARY_NOT_r33 1443 -#define _UNPACK_EX_r10 1444 -#define _UNPACK_SEQUENCE_r10 1445 -#define _UNPACK_SEQUENCE_LIST_r10 1446 -#define _UNPACK_SEQUENCE_TUPLE_r10 1447 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1448 -#define _WITH_EXCEPT_START_r33 1449 -#define _YIELD_VALUE_r11 1450 -#define MAX_UOP_REGS_ID 1450 +#define MAX_UOP_ID 589 +#define _BINARY_OP_r23 590 +#define _BINARY_OP_ADD_FLOAT_r03 591 +#define _BINARY_OP_ADD_FLOAT_r13 592 +#define _BINARY_OP_ADD_FLOAT_r23 593 +#define _BINARY_OP_ADD_INT_r03 594 +#define _BINARY_OP_ADD_INT_r13 595 +#define _BINARY_OP_ADD_INT_r23 596 +#define _BINARY_OP_ADD_UNICODE_r03 597 +#define _BINARY_OP_ADD_UNICODE_r13 598 +#define _BINARY_OP_ADD_UNICODE_r23 599 +#define _BINARY_OP_EXTEND_r23 600 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 601 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 602 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 603 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 604 +#define _BINARY_OP_MULTIPLY_INT_r03 605 +#define _BINARY_OP_MULTIPLY_INT_r13 606 +#define _BINARY_OP_MULTIPLY_INT_r23 607 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 608 +#define _BINARY_OP_SUBSCR_DICT_r23 609 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 610 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 611 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 612 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 613 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 614 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 615 +#define _BINARY_OP_SUBSCR_STR_INT_r23 616 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 617 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 618 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 619 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 620 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 621 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 622 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 623 +#define _BINARY_OP_SUBTRACT_INT_r03 624 +#define _BINARY_OP_SUBTRACT_INT_r13 625 +#define _BINARY_OP_SUBTRACT_INT_r23 626 +#define _BINARY_SLICE_r31 627 +#define _BUILD_INTERPOLATION_r01 628 +#define _BUILD_LIST_r01 629 +#define _BUILD_MAP_r01 630 +#define _BUILD_SET_r01 631 +#define _BUILD_SLICE_r01 632 +#define _BUILD_STRING_r01 633 +#define _BUILD_TEMPLATE_r21 634 +#define _BUILD_TUPLE_r01 635 +#define _CALL_BUILTIN_CLASS_r01 636 +#define _CALL_BUILTIN_FAST_r01 637 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 638 +#define _CALL_BUILTIN_O_r03 639 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 640 +#define _CALL_INTRINSIC_1_r11 641 +#define _CALL_INTRINSIC_2_r21 642 +#define _CALL_ISINSTANCE_r31 643 +#define _CALL_KW_NON_PY_r11 644 +#define _CALL_LEN_r33 645 +#define _CALL_LIST_APPEND_r03 646 +#define _CALL_LIST_APPEND_r13 647 +#define _CALL_LIST_APPEND_r23 648 +#define _CALL_LIST_APPEND_r33 649 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 650 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 651 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 652 +#define _CALL_METHOD_DESCRIPTOR_O_r03 653 +#define _CALL_NON_PY_GENERAL_r01 654 +#define _CALL_STR_1_r32 655 +#define _CALL_TUPLE_1_r32 656 +#define _CALL_TYPE_1_r02 657 +#define _CALL_TYPE_1_r12 658 +#define _CALL_TYPE_1_r22 659 +#define _CALL_TYPE_1_r32 660 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 661 +#define _CHECK_ATTR_CLASS_r01 662 +#define _CHECK_ATTR_CLASS_r11 663 +#define _CHECK_ATTR_CLASS_r22 664 +#define _CHECK_ATTR_CLASS_r33 665 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 666 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 667 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 668 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 669 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 670 +#define _CHECK_EG_MATCH_r22 671 +#define _CHECK_EXC_MATCH_r22 672 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 673 +#define _CHECK_FUNCTION_VERSION_r00 674 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 675 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 676 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 677 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 678 +#define _CHECK_FUNCTION_VERSION_KW_r11 679 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 680 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 681 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 682 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 683 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 684 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 685 +#define _CHECK_IS_PY_CALLABLE_EX_r03 686 +#define _CHECK_IS_PY_CALLABLE_EX_r13 687 +#define _CHECK_IS_PY_CALLABLE_EX_r23 688 +#define _CHECK_IS_PY_CALLABLE_EX_r33 689 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 690 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 691 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 692 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 693 +#define _CHECK_METHOD_VERSION_r00 694 +#define _CHECK_METHOD_VERSION_KW_r11 695 +#define _CHECK_PEP_523_r00 696 +#define _CHECK_PEP_523_r11 697 +#define _CHECK_PEP_523_r22 698 +#define _CHECK_PEP_523_r33 699 +#define _CHECK_PERIODIC_r00 700 +#define _CHECK_PERIODIC_AT_END_r00 701 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 702 +#define _CHECK_RECURSION_REMAINING_r00 703 +#define _CHECK_RECURSION_REMAINING_r11 704 +#define _CHECK_RECURSION_REMAINING_r22 705 +#define _CHECK_RECURSION_REMAINING_r33 706 +#define _CHECK_STACK_SPACE_r00 707 +#define _CHECK_STACK_SPACE_OPERAND_r00 708 +#define _CHECK_STACK_SPACE_OPERAND_r11 709 +#define _CHECK_STACK_SPACE_OPERAND_r22 710 +#define _CHECK_STACK_SPACE_OPERAND_r33 711 +#define _CHECK_VALIDITY_r00 712 +#define _CHECK_VALIDITY_r11 713 +#define _CHECK_VALIDITY_r22 714 +#define _CHECK_VALIDITY_r33 715 +#define _COLD_DYNAMIC_EXIT_r00 716 +#define _COLD_EXIT_r00 717 +#define _COMPARE_OP_r21 718 +#define _COMPARE_OP_FLOAT_r03 719 +#define _COMPARE_OP_FLOAT_r13 720 +#define _COMPARE_OP_FLOAT_r23 721 +#define _COMPARE_OP_INT_r23 722 +#define _COMPARE_OP_STR_r23 723 +#define _CONTAINS_OP_r23 724 +#define _CONTAINS_OP_DICT_r23 725 +#define _CONTAINS_OP_SET_r23 726 +#define _CONVERT_VALUE_r11 727 +#define _COPY_r01 728 +#define _COPY_1_r02 729 +#define _COPY_1_r12 730 +#define _COPY_1_r23 731 +#define _COPY_2_r03 732 +#define _COPY_2_r13 733 +#define _COPY_2_r23 734 +#define _COPY_3_r03 735 +#define _COPY_3_r13 736 +#define _COPY_3_r23 737 +#define _COPY_3_r33 738 +#define _COPY_FREE_VARS_r00 739 +#define _COPY_FREE_VARS_r11 740 +#define _COPY_FREE_VARS_r22 741 +#define _COPY_FREE_VARS_r33 742 +#define _CREATE_INIT_FRAME_r01 743 +#define _DELETE_ATTR_r10 744 +#define _DELETE_DEREF_r00 745 +#define _DELETE_FAST_r00 746 +#define _DELETE_GLOBAL_r00 747 +#define _DELETE_NAME_r00 748 +#define _DELETE_SUBSCR_r20 749 +#define _DEOPT_r00 750 +#define _DEOPT_r10 751 +#define _DEOPT_r20 752 +#define _DEOPT_r30 753 +#define _DICT_MERGE_r10 754 +#define _DICT_UPDATE_r10 755 +#define _DO_CALL_r01 756 +#define _DO_CALL_FUNCTION_EX_r31 757 +#define _DO_CALL_KW_r11 758 +#define _DYNAMIC_EXIT_r00 759 +#define _DYNAMIC_EXIT_r10 760 +#define _DYNAMIC_EXIT_r20 761 +#define _DYNAMIC_EXIT_r30 762 +#define _END_FOR_r10 763 +#define _END_SEND_r21 764 +#define _ERROR_POP_N_r00 765 +#define _EXIT_INIT_CHECK_r10 766 +#define _EXIT_TRACE_r00 767 +#define _EXIT_TRACE_r10 768 +#define _EXIT_TRACE_r20 769 +#define _EXIT_TRACE_r30 770 +#define _EXPAND_METHOD_r00 771 +#define _EXPAND_METHOD_KW_r11 772 +#define _FATAL_ERROR_r00 773 +#define _FATAL_ERROR_r11 774 +#define _FATAL_ERROR_r22 775 +#define _FATAL_ERROR_r33 776 +#define _FORMAT_SIMPLE_r11 777 +#define _FORMAT_WITH_SPEC_r21 778 +#define _FOR_ITER_r23 779 +#define _FOR_ITER_GEN_FRAME_r03 780 +#define _FOR_ITER_GEN_FRAME_r13 781 +#define _FOR_ITER_GEN_FRAME_r23 782 +#define _FOR_ITER_TIER_TWO_r23 783 +#define _GET_AITER_r11 784 +#define _GET_ANEXT_r12 785 +#define _GET_AWAITABLE_r11 786 +#define _GET_ITER_r12 787 +#define _GET_LEN_r12 788 +#define _GET_YIELD_FROM_ITER_r11 789 +#define _GUARD_BINARY_OP_EXTEND_r22 790 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 791 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 792 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 793 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 794 +#define _GUARD_BIT_IS_SET_POP_r00 795 +#define _GUARD_BIT_IS_SET_POP_r10 796 +#define _GUARD_BIT_IS_SET_POP_r21 797 +#define _GUARD_BIT_IS_SET_POP_r32 798 +#define _GUARD_BIT_IS_SET_POP_4_r00 799 +#define _GUARD_BIT_IS_SET_POP_4_r10 800 +#define _GUARD_BIT_IS_SET_POP_4_r21 801 +#define _GUARD_BIT_IS_SET_POP_4_r32 802 +#define _GUARD_BIT_IS_SET_POP_5_r00 803 +#define _GUARD_BIT_IS_SET_POP_5_r10 804 +#define _GUARD_BIT_IS_SET_POP_5_r21 805 +#define _GUARD_BIT_IS_SET_POP_5_r32 806 +#define _GUARD_BIT_IS_SET_POP_6_r00 807 +#define _GUARD_BIT_IS_SET_POP_6_r10 808 +#define _GUARD_BIT_IS_SET_POP_6_r21 809 +#define _GUARD_BIT_IS_SET_POP_6_r32 810 +#define _GUARD_BIT_IS_SET_POP_7_r00 811 +#define _GUARD_BIT_IS_SET_POP_7_r10 812 +#define _GUARD_BIT_IS_SET_POP_7_r21 813 +#define _GUARD_BIT_IS_SET_POP_7_r32 814 +#define _GUARD_BIT_IS_UNSET_POP_r00 815 +#define _GUARD_BIT_IS_UNSET_POP_r10 816 +#define _GUARD_BIT_IS_UNSET_POP_r21 817 +#define _GUARD_BIT_IS_UNSET_POP_r32 818 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 819 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 820 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 821 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 822 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 823 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 824 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 825 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 826 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 827 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 828 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 829 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 830 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 831 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 832 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 833 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 834 +#define _GUARD_CALLABLE_ISINSTANCE_r03 835 +#define _GUARD_CALLABLE_ISINSTANCE_r13 836 +#define _GUARD_CALLABLE_ISINSTANCE_r23 837 +#define _GUARD_CALLABLE_ISINSTANCE_r33 838 +#define _GUARD_CALLABLE_LEN_r03 839 +#define _GUARD_CALLABLE_LEN_r13 840 +#define _GUARD_CALLABLE_LEN_r23 841 +#define _GUARD_CALLABLE_LEN_r33 842 +#define _GUARD_CALLABLE_LIST_APPEND_r03 843 +#define _GUARD_CALLABLE_LIST_APPEND_r13 844 +#define _GUARD_CALLABLE_LIST_APPEND_r23 845 +#define _GUARD_CALLABLE_LIST_APPEND_r33 846 +#define _GUARD_CALLABLE_STR_1_r03 847 +#define _GUARD_CALLABLE_STR_1_r13 848 +#define _GUARD_CALLABLE_STR_1_r23 849 +#define _GUARD_CALLABLE_STR_1_r33 850 +#define _GUARD_CALLABLE_TUPLE_1_r03 851 +#define _GUARD_CALLABLE_TUPLE_1_r13 852 +#define _GUARD_CALLABLE_TUPLE_1_r23 853 +#define _GUARD_CALLABLE_TUPLE_1_r33 854 +#define _GUARD_CALLABLE_TYPE_1_r03 855 +#define _GUARD_CALLABLE_TYPE_1_r13 856 +#define _GUARD_CALLABLE_TYPE_1_r23 857 +#define _GUARD_CALLABLE_TYPE_1_r33 858 +#define _GUARD_CODE_VERSION_r00 859 +#define _GUARD_CODE_VERSION_r11 860 +#define _GUARD_CODE_VERSION_r22 861 +#define _GUARD_CODE_VERSION_r33 862 +#define _GUARD_DORV_NO_DICT_r01 863 +#define _GUARD_DORV_NO_DICT_r11 864 +#define _GUARD_DORV_NO_DICT_r22 865 +#define _GUARD_DORV_NO_DICT_r33 866 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 867 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 868 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 869 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 870 +#define _GUARD_GLOBALS_VERSION_r00 871 +#define _GUARD_GLOBALS_VERSION_r11 872 +#define _GUARD_GLOBALS_VERSION_r22 873 +#define _GUARD_GLOBALS_VERSION_r33 874 +#define _GUARD_IP_RETURN_GENERATOR_r00 875 +#define _GUARD_IP_RETURN_GENERATOR_r11 876 +#define _GUARD_IP_RETURN_GENERATOR_r22 877 +#define _GUARD_IP_RETURN_GENERATOR_r33 878 +#define _GUARD_IP_RETURN_VALUE_r00 879 +#define _GUARD_IP_RETURN_VALUE_r11 880 +#define _GUARD_IP_RETURN_VALUE_r22 881 +#define _GUARD_IP_RETURN_VALUE_r33 882 +#define _GUARD_IP_YIELD_VALUE_r00 883 +#define _GUARD_IP_YIELD_VALUE_r11 884 +#define _GUARD_IP_YIELD_VALUE_r22 885 +#define _GUARD_IP_YIELD_VALUE_r33 886 +#define _GUARD_IP__PUSH_FRAME_r00 887 +#define _GUARD_IP__PUSH_FRAME_r11 888 +#define _GUARD_IP__PUSH_FRAME_r22 889 +#define _GUARD_IP__PUSH_FRAME_r33 890 +#define _GUARD_IS_FALSE_POP_r00 891 +#define _GUARD_IS_FALSE_POP_r10 892 +#define _GUARD_IS_FALSE_POP_r21 893 +#define _GUARD_IS_FALSE_POP_r32 894 +#define _GUARD_IS_NONE_POP_r00 895 +#define _GUARD_IS_NONE_POP_r10 896 +#define _GUARD_IS_NONE_POP_r21 897 +#define _GUARD_IS_NONE_POP_r32 898 +#define _GUARD_IS_NOT_NONE_POP_r10 899 +#define _GUARD_IS_TRUE_POP_r00 900 +#define _GUARD_IS_TRUE_POP_r10 901 +#define _GUARD_IS_TRUE_POP_r21 902 +#define _GUARD_IS_TRUE_POP_r32 903 +#define _GUARD_KEYS_VERSION_r01 904 +#define _GUARD_KEYS_VERSION_r11 905 +#define _GUARD_KEYS_VERSION_r22 906 +#define _GUARD_KEYS_VERSION_r33 907 +#define _GUARD_NOS_ANY_DICT_r02 908 +#define _GUARD_NOS_ANY_DICT_r12 909 +#define _GUARD_NOS_ANY_DICT_r22 910 +#define _GUARD_NOS_ANY_DICT_r33 911 +#define _GUARD_NOS_COMPACT_ASCII_r02 912 +#define _GUARD_NOS_COMPACT_ASCII_r12 913 +#define _GUARD_NOS_COMPACT_ASCII_r22 914 +#define _GUARD_NOS_COMPACT_ASCII_r33 915 +#define _GUARD_NOS_DICT_r02 916 +#define _GUARD_NOS_DICT_r12 917 +#define _GUARD_NOS_DICT_r22 918 +#define _GUARD_NOS_DICT_r33 919 +#define _GUARD_NOS_FLOAT_r02 920 +#define _GUARD_NOS_FLOAT_r12 921 +#define _GUARD_NOS_FLOAT_r22 922 +#define _GUARD_NOS_FLOAT_r33 923 +#define _GUARD_NOS_INT_r02 924 +#define _GUARD_NOS_INT_r12 925 +#define _GUARD_NOS_INT_r22 926 +#define _GUARD_NOS_INT_r33 927 +#define _GUARD_NOS_LIST_r02 928 +#define _GUARD_NOS_LIST_r12 929 +#define _GUARD_NOS_LIST_r22 930 +#define _GUARD_NOS_LIST_r33 931 +#define _GUARD_NOS_NOT_NULL_r02 932 +#define _GUARD_NOS_NOT_NULL_r12 933 +#define _GUARD_NOS_NOT_NULL_r22 934 +#define _GUARD_NOS_NOT_NULL_r33 935 +#define _GUARD_NOS_NULL_r02 936 +#define _GUARD_NOS_NULL_r12 937 +#define _GUARD_NOS_NULL_r22 938 +#define _GUARD_NOS_NULL_r33 939 +#define _GUARD_NOS_OVERFLOWED_r02 940 +#define _GUARD_NOS_OVERFLOWED_r12 941 +#define _GUARD_NOS_OVERFLOWED_r22 942 +#define _GUARD_NOS_OVERFLOWED_r33 943 +#define _GUARD_NOS_TUPLE_r02 944 +#define _GUARD_NOS_TUPLE_r12 945 +#define _GUARD_NOS_TUPLE_r22 946 +#define _GUARD_NOS_TUPLE_r33 947 +#define _GUARD_NOS_UNICODE_r02 948 +#define _GUARD_NOS_UNICODE_r12 949 +#define _GUARD_NOS_UNICODE_r22 950 +#define _GUARD_NOS_UNICODE_r33 951 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 952 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 953 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 954 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 955 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 956 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 957 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 958 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 959 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 960 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 961 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 962 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 963 +#define _GUARD_THIRD_NULL_r03 964 +#define _GUARD_THIRD_NULL_r13 965 +#define _GUARD_THIRD_NULL_r23 966 +#define _GUARD_THIRD_NULL_r33 967 +#define _GUARD_TOS_ANY_DICT_r01 968 +#define _GUARD_TOS_ANY_DICT_r11 969 +#define _GUARD_TOS_ANY_DICT_r22 970 +#define _GUARD_TOS_ANY_DICT_r33 971 +#define _GUARD_TOS_ANY_SET_r01 972 +#define _GUARD_TOS_ANY_SET_r11 973 +#define _GUARD_TOS_ANY_SET_r22 974 +#define _GUARD_TOS_ANY_SET_r33 975 +#define _GUARD_TOS_FLOAT_r01 976 +#define _GUARD_TOS_FLOAT_r11 977 +#define _GUARD_TOS_FLOAT_r22 978 +#define _GUARD_TOS_FLOAT_r33 979 +#define _GUARD_TOS_INT_r01 980 +#define _GUARD_TOS_INT_r11 981 +#define _GUARD_TOS_INT_r22 982 +#define _GUARD_TOS_INT_r33 983 +#define _GUARD_TOS_LIST_r01 984 +#define _GUARD_TOS_LIST_r11 985 +#define _GUARD_TOS_LIST_r22 986 +#define _GUARD_TOS_LIST_r33 987 +#define _GUARD_TOS_OVERFLOWED_r01 988 +#define _GUARD_TOS_OVERFLOWED_r11 989 +#define _GUARD_TOS_OVERFLOWED_r22 990 +#define _GUARD_TOS_OVERFLOWED_r33 991 +#define _GUARD_TOS_SLICE_r01 992 +#define _GUARD_TOS_SLICE_r11 993 +#define _GUARD_TOS_SLICE_r22 994 +#define _GUARD_TOS_SLICE_r33 995 +#define _GUARD_TOS_TUPLE_r01 996 +#define _GUARD_TOS_TUPLE_r11 997 +#define _GUARD_TOS_TUPLE_r22 998 +#define _GUARD_TOS_TUPLE_r33 999 +#define _GUARD_TOS_UNICODE_r01 1000 +#define _GUARD_TOS_UNICODE_r11 1001 +#define _GUARD_TOS_UNICODE_r22 1002 +#define _GUARD_TOS_UNICODE_r33 1003 +#define _GUARD_TYPE_VERSION_r01 1004 +#define _GUARD_TYPE_VERSION_r11 1005 +#define _GUARD_TYPE_VERSION_r22 1006 +#define _GUARD_TYPE_VERSION_r33 1007 +#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1008 +#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1009 +#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1010 +#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1011 +#define _HANDLE_PENDING_AND_DEOPT_r00 1012 +#define _HANDLE_PENDING_AND_DEOPT_r10 1013 +#define _HANDLE_PENDING_AND_DEOPT_r20 1014 +#define _HANDLE_PENDING_AND_DEOPT_r30 1015 +#define _IMPORT_FROM_r12 1016 +#define _IMPORT_NAME_r21 1017 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1018 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1019 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1020 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1021 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1022 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1023 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1024 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1025 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1026 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1027 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1028 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1029 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1030 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1031 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1032 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1033 +#define _INSERT_NULL_r10 1034 +#define _INSTRUMENTED_FOR_ITER_r23 1035 +#define _INSTRUMENTED_INSTRUCTION_r00 1036 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1037 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1038 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1039 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1040 +#define _INSTRUMENTED_LINE_r00 1041 +#define _INSTRUMENTED_NOT_TAKEN_r00 1042 +#define _INSTRUMENTED_NOT_TAKEN_r11 1043 +#define _INSTRUMENTED_NOT_TAKEN_r22 1044 +#define _INSTRUMENTED_NOT_TAKEN_r33 1045 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1046 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1047 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1048 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1049 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1050 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1051 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1052 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1053 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1054 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1055 +#define _IS_NONE_r11 1056 +#define _IS_OP_r03 1057 +#define _IS_OP_r13 1058 +#define _IS_OP_r23 1059 +#define _ITER_CHECK_LIST_r02 1060 +#define _ITER_CHECK_LIST_r12 1061 +#define _ITER_CHECK_LIST_r22 1062 +#define _ITER_CHECK_LIST_r33 1063 +#define _ITER_CHECK_RANGE_r02 1064 +#define _ITER_CHECK_RANGE_r12 1065 +#define _ITER_CHECK_RANGE_r22 1066 +#define _ITER_CHECK_RANGE_r33 1067 +#define _ITER_CHECK_TUPLE_r02 1068 +#define _ITER_CHECK_TUPLE_r12 1069 +#define _ITER_CHECK_TUPLE_r22 1070 +#define _ITER_CHECK_TUPLE_r33 1071 +#define _ITER_JUMP_LIST_r02 1072 +#define _ITER_JUMP_LIST_r12 1073 +#define _ITER_JUMP_LIST_r22 1074 +#define _ITER_JUMP_LIST_r33 1075 +#define _ITER_JUMP_RANGE_r02 1076 +#define _ITER_JUMP_RANGE_r12 1077 +#define _ITER_JUMP_RANGE_r22 1078 +#define _ITER_JUMP_RANGE_r33 1079 +#define _ITER_JUMP_TUPLE_r02 1080 +#define _ITER_JUMP_TUPLE_r12 1081 +#define _ITER_JUMP_TUPLE_r22 1082 +#define _ITER_JUMP_TUPLE_r33 1083 +#define _ITER_NEXT_LIST_r23 1084 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1085 +#define _ITER_NEXT_RANGE_r03 1086 +#define _ITER_NEXT_RANGE_r13 1087 +#define _ITER_NEXT_RANGE_r23 1088 +#define _ITER_NEXT_TUPLE_r03 1089 +#define _ITER_NEXT_TUPLE_r13 1090 +#define _ITER_NEXT_TUPLE_r23 1091 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1092 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1093 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1094 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1095 +#define _JUMP_TO_TOP_r00 1096 +#define _LIST_APPEND_r10 1097 +#define _LIST_EXTEND_r10 1098 +#define _LOAD_ATTR_r10 1099 +#define _LOAD_ATTR_CLASS_r11 1100 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1101 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1102 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1103 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1104 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1105 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1106 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1107 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1108 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1109 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1110 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1111 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1112 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1113 +#define _LOAD_ATTR_MODULE_r12 1114 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1115 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1116 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1117 +#define _LOAD_ATTR_SLOT_r02 1118 +#define _LOAD_ATTR_SLOT_r12 1119 +#define _LOAD_ATTR_SLOT_r23 1120 +#define _LOAD_ATTR_WITH_HINT_r12 1121 +#define _LOAD_BUILD_CLASS_r01 1122 +#define _LOAD_BYTECODE_r00 1123 +#define _LOAD_COMMON_CONSTANT_r01 1124 +#define _LOAD_COMMON_CONSTANT_r12 1125 +#define _LOAD_COMMON_CONSTANT_r23 1126 +#define _LOAD_CONST_r01 1127 +#define _LOAD_CONST_r12 1128 +#define _LOAD_CONST_r23 1129 +#define _LOAD_CONST_INLINE_r01 1130 +#define _LOAD_CONST_INLINE_r12 1131 +#define _LOAD_CONST_INLINE_r23 1132 +#define _LOAD_CONST_INLINE_BORROW_r01 1133 +#define _LOAD_CONST_INLINE_BORROW_r12 1134 +#define _LOAD_CONST_INLINE_BORROW_r23 1135 +#define _LOAD_CONST_UNDER_INLINE_r02 1136 +#define _LOAD_CONST_UNDER_INLINE_r12 1137 +#define _LOAD_CONST_UNDER_INLINE_r23 1138 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1139 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1140 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1141 +#define _LOAD_DEREF_r01 1142 +#define _LOAD_FAST_r01 1143 +#define _LOAD_FAST_r12 1144 +#define _LOAD_FAST_r23 1145 +#define _LOAD_FAST_0_r01 1146 +#define _LOAD_FAST_0_r12 1147 +#define _LOAD_FAST_0_r23 1148 +#define _LOAD_FAST_1_r01 1149 +#define _LOAD_FAST_1_r12 1150 +#define _LOAD_FAST_1_r23 1151 +#define _LOAD_FAST_2_r01 1152 +#define _LOAD_FAST_2_r12 1153 +#define _LOAD_FAST_2_r23 1154 +#define _LOAD_FAST_3_r01 1155 +#define _LOAD_FAST_3_r12 1156 +#define _LOAD_FAST_3_r23 1157 +#define _LOAD_FAST_4_r01 1158 +#define _LOAD_FAST_4_r12 1159 +#define _LOAD_FAST_4_r23 1160 +#define _LOAD_FAST_5_r01 1161 +#define _LOAD_FAST_5_r12 1162 +#define _LOAD_FAST_5_r23 1163 +#define _LOAD_FAST_6_r01 1164 +#define _LOAD_FAST_6_r12 1165 +#define _LOAD_FAST_6_r23 1166 +#define _LOAD_FAST_7_r01 1167 +#define _LOAD_FAST_7_r12 1168 +#define _LOAD_FAST_7_r23 1169 +#define _LOAD_FAST_AND_CLEAR_r01 1170 +#define _LOAD_FAST_AND_CLEAR_r12 1171 +#define _LOAD_FAST_AND_CLEAR_r23 1172 +#define _LOAD_FAST_BORROW_r01 1173 +#define _LOAD_FAST_BORROW_r12 1174 +#define _LOAD_FAST_BORROW_r23 1175 +#define _LOAD_FAST_BORROW_0_r01 1176 +#define _LOAD_FAST_BORROW_0_r12 1177 +#define _LOAD_FAST_BORROW_0_r23 1178 +#define _LOAD_FAST_BORROW_1_r01 1179 +#define _LOAD_FAST_BORROW_1_r12 1180 +#define _LOAD_FAST_BORROW_1_r23 1181 +#define _LOAD_FAST_BORROW_2_r01 1182 +#define _LOAD_FAST_BORROW_2_r12 1183 +#define _LOAD_FAST_BORROW_2_r23 1184 +#define _LOAD_FAST_BORROW_3_r01 1185 +#define _LOAD_FAST_BORROW_3_r12 1186 +#define _LOAD_FAST_BORROW_3_r23 1187 +#define _LOAD_FAST_BORROW_4_r01 1188 +#define _LOAD_FAST_BORROW_4_r12 1189 +#define _LOAD_FAST_BORROW_4_r23 1190 +#define _LOAD_FAST_BORROW_5_r01 1191 +#define _LOAD_FAST_BORROW_5_r12 1192 +#define _LOAD_FAST_BORROW_5_r23 1193 +#define _LOAD_FAST_BORROW_6_r01 1194 +#define _LOAD_FAST_BORROW_6_r12 1195 +#define _LOAD_FAST_BORROW_6_r23 1196 +#define _LOAD_FAST_BORROW_7_r01 1197 +#define _LOAD_FAST_BORROW_7_r12 1198 +#define _LOAD_FAST_BORROW_7_r23 1199 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1200 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1201 +#define _LOAD_FAST_CHECK_r01 1202 +#define _LOAD_FAST_CHECK_r12 1203 +#define _LOAD_FAST_CHECK_r23 1204 +#define _LOAD_FAST_LOAD_FAST_r02 1205 +#define _LOAD_FAST_LOAD_FAST_r13 1206 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1207 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1208 +#define _LOAD_GLOBAL_r00 1209 +#define _LOAD_GLOBAL_BUILTINS_r01 1210 +#define _LOAD_GLOBAL_MODULE_r01 1211 +#define _LOAD_LOCALS_r01 1212 +#define _LOAD_LOCALS_r12 1213 +#define _LOAD_LOCALS_r23 1214 +#define _LOAD_NAME_r01 1215 +#define _LOAD_SMALL_INT_r01 1216 +#define _LOAD_SMALL_INT_r12 1217 +#define _LOAD_SMALL_INT_r23 1218 +#define _LOAD_SMALL_INT_0_r01 1219 +#define _LOAD_SMALL_INT_0_r12 1220 +#define _LOAD_SMALL_INT_0_r23 1221 +#define _LOAD_SMALL_INT_1_r01 1222 +#define _LOAD_SMALL_INT_1_r12 1223 +#define _LOAD_SMALL_INT_1_r23 1224 +#define _LOAD_SMALL_INT_2_r01 1225 +#define _LOAD_SMALL_INT_2_r12 1226 +#define _LOAD_SMALL_INT_2_r23 1227 +#define _LOAD_SMALL_INT_3_r01 1228 +#define _LOAD_SMALL_INT_3_r12 1229 +#define _LOAD_SMALL_INT_3_r23 1230 +#define _LOAD_SPECIAL_r00 1231 +#define _LOAD_SUPER_ATTR_ATTR_r31 1232 +#define _LOAD_SUPER_ATTR_METHOD_r32 1233 +#define _MAKE_CALLARGS_A_TUPLE_r33 1234 +#define _MAKE_CELL_r00 1235 +#define _MAKE_FUNCTION_r11 1236 +#define _MAKE_WARM_r00 1237 +#define _MAKE_WARM_r11 1238 +#define _MAKE_WARM_r22 1239 +#define _MAKE_WARM_r33 1240 +#define _MAP_ADD_r20 1241 +#define _MATCH_CLASS_r31 1242 +#define _MATCH_KEYS_r23 1243 +#define _MATCH_MAPPING_r02 1244 +#define _MATCH_MAPPING_r12 1245 +#define _MATCH_MAPPING_r23 1246 +#define _MATCH_SEQUENCE_r02 1247 +#define _MATCH_SEQUENCE_r12 1248 +#define _MATCH_SEQUENCE_r23 1249 +#define _MAYBE_EXPAND_METHOD_r00 1250 +#define _MAYBE_EXPAND_METHOD_KW_r11 1251 +#define _MONITOR_CALL_r00 1252 +#define _MONITOR_CALL_KW_r11 1253 +#define _MONITOR_JUMP_BACKWARD_r00 1254 +#define _MONITOR_JUMP_BACKWARD_r11 1255 +#define _MONITOR_JUMP_BACKWARD_r22 1256 +#define _MONITOR_JUMP_BACKWARD_r33 1257 +#define _MONITOR_RESUME_r00 1258 +#define _NOP_r00 1259 +#define _NOP_r11 1260 +#define _NOP_r22 1261 +#define _NOP_r33 1262 +#define _POP_CALL_r20 1263 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1264 +#define _POP_CALL_ONE_r30 1265 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1266 +#define _POP_CALL_TWO_r30 1267 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1268 +#define _POP_EXCEPT_r10 1269 +#define _POP_ITER_r20 1270 +#define _POP_JUMP_IF_FALSE_r00 1271 +#define _POP_JUMP_IF_FALSE_r10 1272 +#define _POP_JUMP_IF_FALSE_r21 1273 +#define _POP_JUMP_IF_FALSE_r32 1274 +#define _POP_JUMP_IF_TRUE_r00 1275 +#define _POP_JUMP_IF_TRUE_r10 1276 +#define _POP_JUMP_IF_TRUE_r21 1277 +#define _POP_JUMP_IF_TRUE_r32 1278 +#define _POP_TOP_r10 1279 +#define _POP_TOP_FLOAT_r00 1280 +#define _POP_TOP_FLOAT_r10 1281 +#define _POP_TOP_FLOAT_r21 1282 +#define _POP_TOP_FLOAT_r32 1283 +#define _POP_TOP_INT_r00 1284 +#define _POP_TOP_INT_r10 1285 +#define _POP_TOP_INT_r21 1286 +#define _POP_TOP_INT_r32 1287 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1288 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1289 +#define _POP_TOP_NOP_r00 1290 +#define _POP_TOP_NOP_r10 1291 +#define _POP_TOP_NOP_r21 1292 +#define _POP_TOP_NOP_r32 1293 +#define _POP_TOP_UNICODE_r00 1294 +#define _POP_TOP_UNICODE_r10 1295 +#define _POP_TOP_UNICODE_r21 1296 +#define _POP_TOP_UNICODE_r32 1297 +#define _POP_TWO_r20 1298 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1299 +#define _PUSH_EXC_INFO_r02 1300 +#define _PUSH_EXC_INFO_r12 1301 +#define _PUSH_EXC_INFO_r23 1302 +#define _PUSH_FRAME_r10 1303 +#define _PUSH_NULL_r01 1304 +#define _PUSH_NULL_r12 1305 +#define _PUSH_NULL_r23 1306 +#define _PUSH_NULL_CONDITIONAL_r00 1307 +#define _PY_FRAME_EX_r31 1308 +#define _PY_FRAME_GENERAL_r01 1309 +#define _PY_FRAME_KW_r11 1310 +#define _QUICKEN_RESUME_r00 1311 +#define _QUICKEN_RESUME_r11 1312 +#define _QUICKEN_RESUME_r22 1313 +#define _QUICKEN_RESUME_r33 1314 +#define _REPLACE_WITH_TRUE_r02 1315 +#define _REPLACE_WITH_TRUE_r12 1316 +#define _REPLACE_WITH_TRUE_r23 1317 +#define _RESUME_CHECK_r00 1318 +#define _RESUME_CHECK_r11 1319 +#define _RESUME_CHECK_r22 1320 +#define _RESUME_CHECK_r33 1321 +#define _RETURN_GENERATOR_r01 1322 +#define _RETURN_VALUE_r11 1323 +#define _SAVE_RETURN_OFFSET_r00 1324 +#define _SAVE_RETURN_OFFSET_r11 1325 +#define _SAVE_RETURN_OFFSET_r22 1326 +#define _SAVE_RETURN_OFFSET_r33 1327 +#define _SEND_r22 1328 +#define _SEND_GEN_FRAME_r22 1329 +#define _SETUP_ANNOTATIONS_r00 1330 +#define _SET_ADD_r10 1331 +#define _SET_FUNCTION_ATTRIBUTE_r01 1332 +#define _SET_FUNCTION_ATTRIBUTE_r11 1333 +#define _SET_FUNCTION_ATTRIBUTE_r21 1334 +#define _SET_FUNCTION_ATTRIBUTE_r32 1335 +#define _SET_IP_r00 1336 +#define _SET_IP_r11 1337 +#define _SET_IP_r22 1338 +#define _SET_IP_r33 1339 +#define _SET_UPDATE_r10 1340 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1341 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1342 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1343 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1344 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1345 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1346 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1347 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1348 +#define _SPILL_OR_RELOAD_r01 1349 +#define _SPILL_OR_RELOAD_r02 1350 +#define _SPILL_OR_RELOAD_r03 1351 +#define _SPILL_OR_RELOAD_r10 1352 +#define _SPILL_OR_RELOAD_r12 1353 +#define _SPILL_OR_RELOAD_r13 1354 +#define _SPILL_OR_RELOAD_r20 1355 +#define _SPILL_OR_RELOAD_r21 1356 +#define _SPILL_OR_RELOAD_r23 1357 +#define _SPILL_OR_RELOAD_r30 1358 +#define _SPILL_OR_RELOAD_r31 1359 +#define _SPILL_OR_RELOAD_r32 1360 +#define _START_EXECUTOR_r00 1361 +#define _STORE_ATTR_r20 1362 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1363 +#define _STORE_ATTR_SLOT_r21 1364 +#define _STORE_ATTR_WITH_HINT_r21 1365 +#define _STORE_DEREF_r10 1366 +#define _STORE_FAST_LOAD_FAST_r11 1367 +#define _STORE_FAST_STORE_FAST_r20 1368 +#define _STORE_GLOBAL_r10 1369 +#define _STORE_NAME_r10 1370 +#define _STORE_SLICE_r30 1371 +#define _STORE_SUBSCR_r30 1372 +#define _STORE_SUBSCR_DICT_r31 1373 +#define _STORE_SUBSCR_LIST_INT_r32 1374 +#define _SWAP_r11 1375 +#define _SWAP_2_r02 1376 +#define _SWAP_2_r12 1377 +#define _SWAP_2_r22 1378 +#define _SWAP_2_r33 1379 +#define _SWAP_3_r03 1380 +#define _SWAP_3_r13 1381 +#define _SWAP_3_r23 1382 +#define _SWAP_3_r33 1383 +#define _SWAP_FAST_r01 1384 +#define _SWAP_FAST_r11 1385 +#define _SWAP_FAST_r22 1386 +#define _SWAP_FAST_r33 1387 +#define _SWAP_FAST_0_r01 1388 +#define _SWAP_FAST_0_r11 1389 +#define _SWAP_FAST_0_r22 1390 +#define _SWAP_FAST_0_r33 1391 +#define _SWAP_FAST_1_r01 1392 +#define _SWAP_FAST_1_r11 1393 +#define _SWAP_FAST_1_r22 1394 +#define _SWAP_FAST_1_r33 1395 +#define _SWAP_FAST_2_r01 1396 +#define _SWAP_FAST_2_r11 1397 +#define _SWAP_FAST_2_r22 1398 +#define _SWAP_FAST_2_r33 1399 +#define _SWAP_FAST_3_r01 1400 +#define _SWAP_FAST_3_r11 1401 +#define _SWAP_FAST_3_r22 1402 +#define _SWAP_FAST_3_r33 1403 +#define _SWAP_FAST_4_r01 1404 +#define _SWAP_FAST_4_r11 1405 +#define _SWAP_FAST_4_r22 1406 +#define _SWAP_FAST_4_r33 1407 +#define _SWAP_FAST_5_r01 1408 +#define _SWAP_FAST_5_r11 1409 +#define _SWAP_FAST_5_r22 1410 +#define _SWAP_FAST_5_r33 1411 +#define _SWAP_FAST_6_r01 1412 +#define _SWAP_FAST_6_r11 1413 +#define _SWAP_FAST_6_r22 1414 +#define _SWAP_FAST_6_r33 1415 +#define _SWAP_FAST_7_r01 1416 +#define _SWAP_FAST_7_r11 1417 +#define _SWAP_FAST_7_r22 1418 +#define _SWAP_FAST_7_r33 1419 +#define _TIER2_RESUME_CHECK_r00 1420 +#define _TIER2_RESUME_CHECK_r11 1421 +#define _TIER2_RESUME_CHECK_r22 1422 +#define _TIER2_RESUME_CHECK_r33 1423 +#define _TO_BOOL_r11 1424 +#define _TO_BOOL_BOOL_r01 1425 +#define _TO_BOOL_BOOL_r11 1426 +#define _TO_BOOL_BOOL_r22 1427 +#define _TO_BOOL_BOOL_r33 1428 +#define _TO_BOOL_INT_r02 1429 +#define _TO_BOOL_INT_r12 1430 +#define _TO_BOOL_INT_r23 1431 +#define _TO_BOOL_LIST_r02 1432 +#define _TO_BOOL_LIST_r12 1433 +#define _TO_BOOL_LIST_r23 1434 +#define _TO_BOOL_NONE_r01 1435 +#define _TO_BOOL_NONE_r11 1436 +#define _TO_BOOL_NONE_r22 1437 +#define _TO_BOOL_NONE_r33 1438 +#define _TO_BOOL_STR_r02 1439 +#define _TO_BOOL_STR_r12 1440 +#define _TO_BOOL_STR_r23 1441 +#define _TRACE_RECORD_r00 1442 +#define _UNARY_INVERT_r12 1443 +#define _UNARY_NEGATIVE_r12 1444 +#define _UNARY_NOT_r01 1445 +#define _UNARY_NOT_r11 1446 +#define _UNARY_NOT_r22 1447 +#define _UNARY_NOT_r33 1448 +#define _UNPACK_EX_r10 1449 +#define _UNPACK_SEQUENCE_r10 1450 +#define _UNPACK_SEQUENCE_LIST_r10 1451 +#define _UNPACK_SEQUENCE_TUPLE_r10 1452 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1453 +#define _WITH_EXCEPT_START_r33 1454 +#define _YIELD_VALUE_r11 1455 +#define MAX_UOP_REGS_ID 1455 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 7921d229f11db3..be06738b54ca67 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -127,7 +127,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = HAS_DEOPT_FLAG, [_BINARY_OP_SUBSCR_TUPLE_INT] = 0, [_GUARD_NOS_DICT] = HAS_EXIT_FLAG, - [_GUARD_TOS_DICT] = HAS_EXIT_FLAG, + [_GUARD_NOS_ANY_DICT] = HAS_EXIT_FLAG, + [_GUARD_TOS_ANY_DICT] = HAS_EXIT_FLAG, [_BINARY_OP_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_BINARY_OP_SUBSCR_CHECK_FUNC] = HAS_DEOPT_FLAG, [_BINARY_OP_SUBSCR_INIT_CALL] = 0, @@ -1226,13 +1227,22 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { 3, 3, _GUARD_NOS_DICT_r33 }, }, }, - [_GUARD_TOS_DICT] = { + [_GUARD_NOS_ANY_DICT] = { .best = { 0, 1, 2, 3 }, .entries = { - { 1, 0, _GUARD_TOS_DICT_r01 }, - { 1, 1, _GUARD_TOS_DICT_r11 }, - { 2, 2, _GUARD_TOS_DICT_r22 }, - { 3, 3, _GUARD_TOS_DICT_r33 }, + { 2, 0, _GUARD_NOS_ANY_DICT_r02 }, + { 2, 1, _GUARD_NOS_ANY_DICT_r12 }, + { 2, 2, _GUARD_NOS_ANY_DICT_r22 }, + { 3, 3, _GUARD_NOS_ANY_DICT_r33 }, + }, + }, + [_GUARD_TOS_ANY_DICT] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _GUARD_TOS_ANY_DICT_r01 }, + { 1, 1, _GUARD_TOS_ANY_DICT_r11 }, + { 2, 2, _GUARD_TOS_ANY_DICT_r22 }, + { 3, 3, _GUARD_TOS_ANY_DICT_r33 }, }, }, [_BINARY_OP_SUBSCR_DICT] = { @@ -3724,10 +3734,14 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_GUARD_NOS_DICT_r12] = _GUARD_NOS_DICT, [_GUARD_NOS_DICT_r22] = _GUARD_NOS_DICT, [_GUARD_NOS_DICT_r33] = _GUARD_NOS_DICT, - [_GUARD_TOS_DICT_r01] = _GUARD_TOS_DICT, - [_GUARD_TOS_DICT_r11] = _GUARD_TOS_DICT, - [_GUARD_TOS_DICT_r22] = _GUARD_TOS_DICT, - [_GUARD_TOS_DICT_r33] = _GUARD_TOS_DICT, + [_GUARD_NOS_ANY_DICT_r02] = _GUARD_NOS_ANY_DICT, + [_GUARD_NOS_ANY_DICT_r12] = _GUARD_NOS_ANY_DICT, + [_GUARD_NOS_ANY_DICT_r22] = _GUARD_NOS_ANY_DICT, + [_GUARD_NOS_ANY_DICT_r33] = _GUARD_NOS_ANY_DICT, + [_GUARD_TOS_ANY_DICT_r01] = _GUARD_TOS_ANY_DICT, + [_GUARD_TOS_ANY_DICT_r11] = _GUARD_TOS_ANY_DICT, + [_GUARD_TOS_ANY_DICT_r22] = _GUARD_TOS_ANY_DICT, + [_GUARD_TOS_ANY_DICT_r33] = _GUARD_TOS_ANY_DICT, [_BINARY_OP_SUBSCR_DICT_r23] = _BINARY_OP_SUBSCR_DICT, [_BINARY_OP_SUBSCR_CHECK_FUNC_r23] = _BINARY_OP_SUBSCR_CHECK_FUNC, [_BINARY_OP_SUBSCR_INIT_CALL_r01] = _BINARY_OP_SUBSCR_INIT_CALL, @@ -4717,6 +4731,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_KEYS_VERSION_r11] = "_GUARD_KEYS_VERSION_r11", [_GUARD_KEYS_VERSION_r22] = "_GUARD_KEYS_VERSION_r22", [_GUARD_KEYS_VERSION_r33] = "_GUARD_KEYS_VERSION_r33", + [_GUARD_NOS_ANY_DICT] = "_GUARD_NOS_ANY_DICT", + [_GUARD_NOS_ANY_DICT_r02] = "_GUARD_NOS_ANY_DICT_r02", + [_GUARD_NOS_ANY_DICT_r12] = "_GUARD_NOS_ANY_DICT_r12", + [_GUARD_NOS_ANY_DICT_r22] = "_GUARD_NOS_ANY_DICT_r22", + [_GUARD_NOS_ANY_DICT_r33] = "_GUARD_NOS_ANY_DICT_r33", [_GUARD_NOS_COMPACT_ASCII] = "_GUARD_NOS_COMPACT_ASCII", [_GUARD_NOS_COMPACT_ASCII_r02] = "_GUARD_NOS_COMPACT_ASCII_r02", [_GUARD_NOS_COMPACT_ASCII_r12] = "_GUARD_NOS_COMPACT_ASCII_r12", @@ -4787,16 +4806,16 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_THIRD_NULL_r13] = "_GUARD_THIRD_NULL_r13", [_GUARD_THIRD_NULL_r23] = "_GUARD_THIRD_NULL_r23", [_GUARD_THIRD_NULL_r33] = "_GUARD_THIRD_NULL_r33", + [_GUARD_TOS_ANY_DICT] = "_GUARD_TOS_ANY_DICT", + [_GUARD_TOS_ANY_DICT_r01] = "_GUARD_TOS_ANY_DICT_r01", + [_GUARD_TOS_ANY_DICT_r11] = "_GUARD_TOS_ANY_DICT_r11", + [_GUARD_TOS_ANY_DICT_r22] = "_GUARD_TOS_ANY_DICT_r22", + [_GUARD_TOS_ANY_DICT_r33] = "_GUARD_TOS_ANY_DICT_r33", [_GUARD_TOS_ANY_SET] = "_GUARD_TOS_ANY_SET", [_GUARD_TOS_ANY_SET_r01] = "_GUARD_TOS_ANY_SET_r01", [_GUARD_TOS_ANY_SET_r11] = "_GUARD_TOS_ANY_SET_r11", [_GUARD_TOS_ANY_SET_r22] = "_GUARD_TOS_ANY_SET_r22", [_GUARD_TOS_ANY_SET_r33] = "_GUARD_TOS_ANY_SET_r33", - [_GUARD_TOS_DICT] = "_GUARD_TOS_DICT", - [_GUARD_TOS_DICT_r01] = "_GUARD_TOS_DICT_r01", - [_GUARD_TOS_DICT_r11] = "_GUARD_TOS_DICT_r11", - [_GUARD_TOS_DICT_r22] = "_GUARD_TOS_DICT_r22", - [_GUARD_TOS_DICT_r33] = "_GUARD_TOS_DICT_r33", [_GUARD_TOS_FLOAT] = "_GUARD_TOS_FLOAT", [_GUARD_TOS_FLOAT_r01] = "_GUARD_TOS_FLOAT_r01", [_GUARD_TOS_FLOAT_r11] = "_GUARD_TOS_FLOAT_r11", @@ -5584,7 +5603,9 @@ int _PyUop_num_popped(int opcode, int oparg) return 2; case _GUARD_NOS_DICT: return 0; - case _GUARD_TOS_DICT: + case _GUARD_NOS_ANY_DICT: + return 0; + case _GUARD_TOS_ANY_DICT: return 0; case _BINARY_OP_SUBSCR_DICT: return 2; diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 1f5b0596107704..4ca108cd6ca43e 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1885,6 +1885,30 @@ def __getitem__(self, item): self.assert_specialized(binary_subscr_getitems, "BINARY_OP_SUBSCR_GETITEM") self.assert_no_opcode(binary_subscr_getitems, "BINARY_OP") + @cpython_only + @requires_specialization + def test_store_subscr(self): + def store_subscr_dict(): + for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD): + a = {1: 2, 2: 3} + a[1] = 4 + self.assertEqual(a[1], 4) + + store_subscr_dict() + self.assert_specialized(store_subscr_dict, "STORE_SUBSCR_DICT") + self.assert_no_opcode(store_subscr_dict, "STORE_SUBSCR") + + def store_subscr_frozen_dict(): + dicts = [{1: 2}, frozendict({1: 2})] + for i in range(_testinternalcapi.SPECIALIZATION_THRESHOLD + 1): + d = dicts[i == _testinternalcapi.SPECIALIZATION_THRESHOLD] + d[1] = 3 + + with self.assertRaises(TypeError): + store_subscr_frozen_dict() + self.assert_specialized(store_subscr_frozen_dict, "STORE_SUBSCR_DICT") + self.assert_no_opcode(store_subscr_frozen_dict, "STORE_SUBSCR") + @cpython_only @requires_specialization def test_compare_op(self): diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index fde6db4933f74a..395c429f7ef3db 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -638,7 +638,7 @@ _PyStackRef ds; _PyStackRef ss; _PyStackRef value; - // _GUARD_NOS_DICT + // _GUARD_NOS_ANY_DICT { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); @@ -5135,7 +5135,7 @@ _PyStackRef l; _PyStackRef r; _PyStackRef value; - // _GUARD_TOS_DICT + // _GUARD_TOS_ANY_DICT { tos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); @@ -11483,7 +11483,7 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyAnyDict_CheckExact(o)) { + if (!PyDict_CheckExact(o)) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); JUMP_TO_PREDICTED(STORE_SUBSCR); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 01eaf4a59b645a..36af61412b7417 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1057,17 +1057,22 @@ dummy_func( } op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) { + PyObject *o = PyStackRef_AsPyObjectBorrow(nos); + EXIT_IF(!PyDict_CheckExact(o)); + } + + op(_GUARD_NOS_ANY_DICT, (nos, unused -- nos, unused)) { PyObject *o = PyStackRef_AsPyObjectBorrow(nos); EXIT_IF(!PyAnyDict_CheckExact(o)); } - op(_GUARD_TOS_DICT, (tos -- tos)) { + op(_GUARD_TOS_ANY_DICT, (tos -- tos)) { PyObject *o = PyStackRef_AsPyObjectBorrow(tos); EXIT_IF(!PyAnyDict_CheckExact(o)); } macro(BINARY_OP_SUBSCR_DICT) = - _GUARD_NOS_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP; + _GUARD_NOS_ANY_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP; op(_BINARY_OP_SUBSCR_DICT, (dict_st, sub_st -- res, ds, ss)) { PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); @@ -2934,7 +2939,7 @@ dummy_func( INPUTS_DEAD(); } - macro(CONTAINS_OP_DICT) = _GUARD_TOS_DICT + unused/1 + _CONTAINS_OP_DICT + POP_TOP + POP_TOP; + macro(CONTAINS_OP_DICT) = _GUARD_TOS_ANY_DICT + unused/1 + _CONTAINS_OP_DICT + POP_TOP + POP_TOP; op(_CONTAINS_OP_DICT, (left, right -- b, l, r)) { PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 8b36d1abf2e916..4a67ede8a02265 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5920,7 +5920,7 @@ _PyStackRef nos; nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyAnyDict_CheckExact(o)) { + if (!PyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); SET_CURRENT_CACHED_VALUES(0); JUMP_TO_JUMP_TARGET(); @@ -5941,7 +5941,7 @@ _PyStackRef _stack_item_0 = _tos_cache0; nos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyAnyDict_CheckExact(o)) { + if (!PyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = _stack_item_0; SET_CURRENT_CACHED_VALUES(1); @@ -5964,7 +5964,7 @@ _PyStackRef _stack_item_1 = _tos_cache1; nos = _stack_item_0; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyAnyDict_CheckExact(o)) { + if (!PyDict_CheckExact(o)) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; _tos_cache0 = nos; @@ -5979,6 +5979,95 @@ } case _GUARD_NOS_DICT_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef nos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + nos = _stack_item_1; + PyObject *o = PyStackRef_AsPyObjectBorrow(nos); + if (!PyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = _stack_item_2; + _tos_cache1 = nos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = _stack_item_2; + _tos_cache1 = nos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_NOS_ANY_DICT_r02: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef nos; + nos = stack_pointer[-2]; + PyObject *o = PyStackRef_AsPyObjectBorrow(nos); + if (!PyAnyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = stack_pointer[-1]; + _tos_cache0 = nos; + SET_CURRENT_CACHED_VALUES(2); + stack_pointer += -2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_NOS_ANY_DICT_r12: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef nos; + _PyStackRef _stack_item_0 = _tos_cache0; + nos = stack_pointer[-1]; + PyObject *o = PyStackRef_AsPyObjectBorrow(nos); + if (!PyAnyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = _stack_item_0; + _tos_cache0 = nos; + SET_CURRENT_CACHED_VALUES(2); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_NOS_ANY_DICT_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef nos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + nos = _stack_item_0; + PyObject *o = PyStackRef_AsPyObjectBorrow(nos); + if (!PyAnyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = _stack_item_1; + _tos_cache0 = nos; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = _stack_item_1; + _tos_cache0 = nos; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_NOS_ANY_DICT_r33: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef nos; @@ -6003,7 +6092,7 @@ break; } - case _GUARD_TOS_DICT_r01: { + case _GUARD_TOS_ANY_DICT_r01: { CHECK_CURRENT_CACHED_VALUES(0); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef tos; @@ -6022,7 +6111,7 @@ break; } - case _GUARD_TOS_DICT_r11: { + case _GUARD_TOS_ANY_DICT_r11: { CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef tos; @@ -6041,7 +6130,7 @@ break; } - case _GUARD_TOS_DICT_r22: { + case _GUARD_TOS_ANY_DICT_r22: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef tos; @@ -6063,7 +6152,7 @@ break; } - case _GUARD_TOS_DICT_r33: { + case _GUARD_TOS_ANY_DICT_r33: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef tos; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index bc9ae7e0ab3be3..12362943465e3d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -638,7 +638,7 @@ _PyStackRef ds; _PyStackRef ss; _PyStackRef value; - // _GUARD_NOS_DICT + // _GUARD_NOS_ANY_DICT { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); @@ -5135,7 +5135,7 @@ _PyStackRef l; _PyStackRef r; _PyStackRef value; - // _GUARD_TOS_DICT + // _GUARD_TOS_ANY_DICT { tos = stack_pointer[-1]; PyObject *o = PyStackRef_AsPyObjectBorrow(tos); @@ -11480,7 +11480,7 @@ { nos = stack_pointer[-2]; PyObject *o = PyStackRef_AsPyObjectBorrow(nos); - if (!PyAnyDict_CheckExact(o)) { + if (!PyDict_CheckExact(o)) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); JUMP_TO_PREDICTED(STORE_SUBSCR); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 4e4aec2f37e29b..3dd5d65702b47f 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1348,18 +1348,27 @@ dummy_func(void) { sym_set_type(nos, &PyTuple_Type); } - op(_GUARD_TOS_DICT, (tos -- tos)) { - if (sym_matches_type(tos, &PyDict_Type)) { + op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) { + if (sym_matches_type(nos, &PyDict_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PyDict_Type); + sym_set_type(nos, &PyDict_Type); } - op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) { - if (sym_matches_type(nos, &PyDict_Type)) { + op(_GUARD_NOS_ANY_DICT, (nos, unused -- nos, unused)) { + PyTypeObject *tp = sym_get_type(nos); + if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { ADD_OP(_NOP, 0, 0); + sym_set_type(nos, tp); + } + } + + op(_GUARD_TOS_ANY_DICT, (tos -- tos)) { + PyTypeObject *tp = sym_get_type(tos); + if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { + ADD_OP(_NOP, 0, 0); + sym_set_type(tos, tp); } - sym_set_type(nos, &PyDict_Type); } op(_GUARD_TOS_ANY_SET, (tos -- tos)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 286fe014b65f0e..f2616eddbb758a 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1101,13 +1101,25 @@ break; } - case _GUARD_TOS_DICT: { + case _GUARD_NOS_ANY_DICT: { + JitOptRef nos; + nos = stack_pointer[-2]; + PyTypeObject *tp = sym_get_type(nos); + if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { + ADD_OP(_NOP, 0, 0); + sym_set_type(nos, tp); + } + break; + } + + case _GUARD_TOS_ANY_DICT: { JitOptRef tos; tos = stack_pointer[-1]; - if (sym_matches_type(tos, &PyDict_Type)) { + PyTypeObject *tp = sym_get_type(tos); + if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { ADD_OP(_NOP, 0, 0); + sym_set_type(tos, tp); } - sym_set_type(tos, &PyDict_Type); break; } From 97181bb336dcf896188ae46d87c909067375e779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Tue, 24 Feb 2026 17:04:37 +0100 Subject: [PATCH 227/498] gh-143535: Dispatch on the second argument if generic method is instance-bindable (GH-144615) Co-authored-by: Jason R. Coombs --- Doc/whatsnew/3.15.rst | 4 ++ Lib/functools.py | 22 +++++++- Lib/test/test_functools.py | 51 +++++++++++++++++++ ...-02-09-02-16-36.gh-issue-144615.s04x4n.rst | 3 ++ 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index cd1ec0e5c452d3..816d45e0756824 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -744,6 +744,10 @@ functools callables. (Contributed by Serhiy Storchaka in :gh:`140873`.) +* :func:`~functools.singledispatchmethod` now dispatches on the second argument + if it wraps a regular method and is called as a class attribute. + (Contributed by Bartosz Sławecki in :gh:`143535`.) + hashlib ------- diff --git a/Lib/functools.py b/Lib/functools.py index 59fc2a8fbf6219..9bc2ee7e8c894c 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -19,7 +19,7 @@ # import weakref # Deferred to single_dispatch() from operator import itemgetter from reprlib import recursive_repr -from types import GenericAlias, MethodType, MappingProxyType, UnionType +from types import FunctionType, GenericAlias, MethodType, MappingProxyType, UnionType from _thread import RLock ################################################################################ @@ -1060,6 +1060,11 @@ def __init__(self, unbound, obj, cls): # Set instance attributes which cannot be handled in __getattr__() # because they conflict with type descriptors. func = unbound.func + + # Dispatch on the second argument if a generic method turns into + # a bound method on instance-level access. See GH-143535. + self._dispatch_arg_index = 1 if obj is None and isinstance(func, FunctionType) else 0 + try: self.__module__ = func.__module__ except AttributeError: @@ -1088,9 +1093,22 @@ def __call__(self, /, *args, **kwargs): 'singledispatchmethod method') raise TypeError(f'{funcname} requires at least ' '1 positional argument') - method = self._dispatch(args[0].__class__) + method = self._dispatch(args[self._dispatch_arg_index].__class__) + if hasattr(method, "__get__"): + # If the method is a descriptor, it might be necessary + # to drop the first argument before calling + # as it can be no longer expected after descriptor access. + skip_bound_arg = False + if isinstance(method, staticmethod): + skip_bound_arg = self._dispatch_arg_index == 1 + method = method.__get__(self._obj, self._cls) + if isinstance(method, MethodType): + skip_bound_arg = self._dispatch_arg_index == 1 + + if skip_bound_arg: + return method(*args[1:], **kwargs) return method(*args, **kwargs) def __getattr__(self, name): diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 3801a82a610891..86652b7fa4d6df 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -3005,6 +3005,57 @@ def static_func(arg: int) -> str: self.assertEqual(A.static_func.__name__, 'static_func') self.assertEqual(A().static_func.__name__, 'static_func') + def test_method_classlevel_calls(self): + """Regression test for GH-143535.""" + class C: + @functools.singledispatchmethod + def generic(self, x: object): + return "generic" + + @generic.register + def special1(self, x: int): + return "special1" + + @generic.register + @classmethod + def special2(self, x: float): + return "special2" + + @generic.register + @staticmethod + def special3(x: complex): + return "special3" + + def special4(self, x): + return "special4" + + class D1: + def __get__(self, _, owner): + return lambda inst, x: owner.special4(inst, x) + + generic.register(D1, D1()) + + def special5(self, x): + return "special5" + + class D2: + def __get__(self, inst, owner): + # Different instance bound to the returned method + # doesn't cause it to receive the original instance + # as a separate argument. + # To work around this, wrap the returned bound method + # with `functools.partial`. + return C().special5 + + generic.register(D2, D2()) + + self.assertEqual(C.generic(C(), "foo"), "generic") + self.assertEqual(C.generic(C(), 1), "special1") + self.assertEqual(C.generic(C(), 2.0), "special2") + self.assertEqual(C.generic(C(), 3j), "special3") + self.assertEqual(C.generic(C(), C.D1()), "special4") + self.assertEqual(C.generic(C(), C.D2()), "special5") + def test_method_repr(self): class Callable: def __call__(self, *args): diff --git a/Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst b/Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst new file mode 100644 index 00000000000000..1db257ae312e84 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst @@ -0,0 +1,3 @@ +Methods directly decorated with :deco:`functools.singledispatchmethod` now +dispatch on the second argument when called after being accessed as class +attributes. Patch by Bartosz Sławecki. From 56c4f10d6e474604a162521228b5f3b5ff79236c Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:42:33 +0000 Subject: [PATCH 228/498] gh-88091: Fix unicodedata.decomposition() for Hangul Syllables (GH-144993) --- Lib/test/test_unicodedata.py | 14 ++++-- ...6-02-19-10-57-40.gh-issue-88091.N7qGV-.rst | 1 + Modules/unicodedata.c | 44 ++++++++++++++----- 3 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 8d4ba677faaa6f..30a26751d3ac54 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -378,6 +378,12 @@ def test_decomposition(self): # New in 17.0.0 self.assertEqual(self.db.decomposition('\uA7F1'), '' if self.old else ' 0053') + # Hangul characters + self.assertEqual(self.db.decomposition('\uAC00'), '1100 1161') + self.assertEqual(self.db.decomposition('\uD4DB'), '1111 1171 11B6') + self.assertEqual(self.db.decomposition('\uC2F8'), '110A 1161') + self.assertEqual(self.db.decomposition('\uD7A3'), '1112 1175 11C2') + self.assertRaises(TypeError, self.db.decomposition) self.assertRaises(TypeError, self.db.decomposition, 'xx') @@ -687,9 +693,9 @@ class UnicodeFunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): # Update this if the database changes. Make sure to do a full rebuild # (e.g. 'make distclean && make') to get the correct checksum. - expectedchecksum = ('668dbbea1136e69d4f00677a5988b23bc78aefc6' + expectedchecksum = ('00b13fa975a60b1d3f490f1fc8c126ab24990c75' if quicktest else - 'b869af769bd8fe352c04622ab90533dc54df5cf3') + 'ebfc9dd281c2226998fd435744dd2e9321899beb') @requires_resource('network') def test_all_names(self): @@ -1068,9 +1074,9 @@ def test_block_invalid_input(self): class Unicode_3_2_0_FunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest): db = unicodedata.ucd_3_2_0 old = True - expectedchecksum = ('2164a66700e03cba9c9f5ed9e9a8d594d2da136a' + expectedchecksum = ('cb5bbbd1f55b67371e18222b90a8e21c87f16b72' if quicktest else - 'a8276cec9b6991779c5bdaa46c1ae7cc50bc2403') + '74936dffe949d99203a47e6a66565b2fc337bae7') class UnicodeMiscTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst b/Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst new file mode 100644 index 00000000000000..15cf25052bbb46 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst @@ -0,0 +1 @@ +Fix :func:`unicodedata.decomposition` for Hangul characters. diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 27bdd19c409471..401f64e7416944 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -429,6 +429,17 @@ unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) return PyUnicode_FromString(_PyUnicode_EastAsianWidthNames[index]); } +// For Hangul decomposition +#define SBase 0xAC00 +#define LBase 0x1100 +#define VBase 0x1161 +#define TBase 0x11A7 +#define LCount 19 +#define VCount 21 +#define TCount 28 +#define NCount (VCount*TCount) +#define SCount (LCount*NCount) + /*[clinic input] @permit_long_summary unicodedata.UCD.decomposition @@ -460,6 +471,25 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) return Py_GetConstant(Py_CONSTANT_EMPTY_STR); /* unassigned */ } + // Hangul Decomposition. + // See section 3.12.2, "Hangul Syllable Decomposition" + // https://www.unicode.org/versions/latest/core-spec/chapter-3/#G56669 + if (SBase <= code && code < (SBase + SCount)) { + int SIndex = code - SBase; + int L = LBase + SIndex / NCount; + int V = VBase + (SIndex % NCount) / TCount; + int T = TBase + SIndex % TCount; + if (T != TBase) { + PyOS_snprintf(decomp, sizeof(decomp), + "%04X %04X %04X", L, V, T); + } + else { + PyOS_snprintf(decomp, sizeof(decomp), + "%04X %04X", L, V); + } + return PyUnicode_FromString(decomp); + } + if (code < 0 || code >= 0x110000) index = 0; else { @@ -522,16 +552,6 @@ get_decomp_record(PyObject *self, Py_UCS4 code, (*index)++; } -#define SBase 0xAC00 -#define LBase 0x1100 -#define VBase 0x1161 -#define TBase 0x11A7 -#define LCount 19 -#define VCount 21 -#define TCount 28 -#define NCount (VCount*TCount) -#define SCount (LCount*NCount) - static PyObject* nfd_nfkd(PyObject *self, PyObject *input, int k) { @@ -585,7 +605,9 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) } output = new_output; } - /* Hangul Decomposition. */ + // Hangul Decomposition. + // See section 3.12.2, "Hangul Syllable Decomposition" + // https://www.unicode.org/versions/latest/core-spec/chapter-3/#G56669 if (SBase <= code && code < (SBase+SCount)) { int SIndex = code - SBase; int L = LBase + SIndex / NCount; From 5e61a16c1058e5de66b71dfdc9720d40e9f515d9 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 24 Feb 2026 20:44:57 +0000 Subject: [PATCH 229/498] gh-145187: Fix crash on invalid type parameter bound expression in conditional block (GH-145188) Fix parsing crash found by oss-fuzz --- Lib/test/test_type_params.py | 7 +++++++ .../2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst | 2 ++ Python/codegen.c | 6 +++--- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py index 0f393def827271..84c1b954136736 100644 --- a/Lib/test/test_type_params.py +++ b/Lib/test/test_type_params.py @@ -152,6 +152,13 @@ def test_incorrect_mro_explicit_object(self): with self.assertRaisesRegex(TypeError, r"\(MRO\) for bases object, Generic"): class My[X](object): ... + def test_compile_error_in_type_param_bound(self): + # This should not crash, see gh-145187 + check_syntax_error( + self, + "if True:\n class h[l:{7for*()in 0}]:2" + ) + class TypeParamsNonlocalTest(unittest.TestCase): def test_nonlocal_disallowed_01(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst new file mode 100644 index 00000000000000..08c6b44164ebc3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst @@ -0,0 +1,2 @@ +Fix compiler assertion fail when a type parameter bound contains an invalid +expression in a conditional block. diff --git a/Python/codegen.c b/Python/codegen.c index 42fccb07d31dba..5749b615386717 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -1244,11 +1244,11 @@ codegen_type_param_bound_or_default(compiler *c, expr_ty e, ADDOP_LOAD_CONST_NEW(c, LOC(e), defaults); RETURN_IF_ERROR(codegen_setup_annotations_scope(c, LOC(e), key, name)); if (allow_starred && e->kind == Starred_kind) { - VISIT(c, expr, e->v.Starred.value); - ADDOP_I(c, LOC(e), UNPACK_SEQUENCE, (Py_ssize_t)1); + VISIT_IN_SCOPE(c, expr, e->v.Starred.value); + ADDOP_I_IN_SCOPE(c, LOC(e), UNPACK_SEQUENCE, (Py_ssize_t)1); } else { - VISIT(c, expr, e); + VISIT_IN_SCOPE(c, expr, e); } ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE); PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1); From 4e45c9c309abb12c622334c7a419503d169af380 Mon Sep 17 00:00:00 2001 From: rueteh <60346006+rueteh@users.noreply.github.com> Date: Wed, 25 Feb 2026 09:52:02 +1100 Subject: [PATCH 230/498] gh-136677: Introduce executable specific linker flags to configure (#137296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * introduce executable specific linker flags Add PY_CORE_EXE_LDFLAGS and EXE_LDFLAGS which stores executable specific LDFLAGS, replacing PY_CORE_LDFLAGS for building executable targets. If PY_CORE_EXE_LDFLAGS / EXE_LDFLAGS is not provided, then it defaults to the value of PY_CORE_LDFLAGS which is the existing behaviour. If both flags are supplied, and there is a need to distinguish between executable and shared specific LDFLAGS, in particular, PY_CORE_LDFLAGS should contain the shared specific LDFLAGS. * documentation for new linker flags * update Misc folder documentation * Update Makefile.pre.in Co-authored-by: Victor Stinner --------- Co-authored-by: Filipe Laíns Co-authored-by: Victor Stinner Co-authored-by: Filipe Laíns --- Doc/using/configure.rst | 27 +++++++++++++++++++ Lib/_osx_support.py | 3 ++- Lib/test/pythoninfo.py | 1 + Lib/test/test__osx_support.py | 2 +- Makefile.pre.in | 8 ++++-- Misc/ACKS | 1 + ...-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst | 1 + configure | 2 ++ configure.ac | 1 + 9 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 50812358a690c3..813127663ed8fe 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -1650,6 +1650,9 @@ Linker flags value to be able to build extension modules using the directories specified in the environment variables. + Please consider using ``EXE_LDFLAGS`` if the supplied linker flags are + executable specific, e.g. GCC's ``-pie`` flag. + .. envvar:: LIBS Linker flags to pass libraries to the linker when linking the Python @@ -1685,6 +1688,30 @@ Linker flags .. versionadded:: 3.8 +.. envvar:: EXE_LDFLAGS + + Linker flags used for building executable targets such as the + interpreter. If supplied, :envvar:`PY_CORE_EXE_LDFLAGS` + will be used in replacement of :envvar:`PY_CORE_LDFLAGS`. + + .. versionadded:: 3.15 + +.. envvar:: CONFIGURE_EXE_LDFLAGS + + Value of :envvar:`EXE_LDFLAGS` variable passed to the ``./configure`` + script. + + .. versionadded:: 3.15 + +.. envvar:: PY_CORE_EXE_LDFLAGS + + Linker flags used for building the interpreter and + executable targets. + + Default: ``$(PY_CORE_LDFLAGS)`` + + .. versionadded:: 3.15 + .. rubric:: Footnotes diff --git a/Lib/_osx_support.py b/Lib/_osx_support.py index 0cb064fcd791be..29b89e311cb1fe 100644 --- a/Lib/_osx_support.py +++ b/Lib/_osx_support.py @@ -17,7 +17,8 @@ _UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC', 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS', - 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS') + 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS', + 'PY_CORE_EXE_LDFLAGS') # configuration variables that may contain compiler calls _COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX') diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 3befc0f2e633ca..fdd8989f9cb3f8 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -528,6 +528,7 @@ def collect_sysconfig(info_add): 'PY_CFLAGS', 'PY_CFLAGS_NODIST', 'PY_CORE_LDFLAGS', + 'PY_CORE_EXE_LDFLAGS', 'PY_LDFLAGS', 'PY_LDFLAGS_NODIST', 'PY_STDMODULE_CFLAGS', diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index 0813c4804c1cdc..b92ce6796b50fb 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -25,7 +25,7 @@ def setUp(self): 'CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC', 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS', - 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS' + 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS', 'PY_CORE_EXE_LDFLAGS' ) def add_expected_saved_initial_values(self, config_vars, expected_vars): diff --git a/Makefile.pre.in b/Makefile.pre.in index f4119abf324fca..122957dec29b6f 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -123,7 +123,11 @@ PY_STDMODULE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFOR PY_BUILTIN_MODULE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE_BUILTIN PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE # Linker flags used for building the interpreter object files +# In particular, EXE_LDFLAGS is an extra flag to provide fine grain distinction between +# LDFLAGS used to build executables and shared targets. PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST) +CONFIGURE_EXE_LDFLAGS=@EXE_LDFLAGS@ +PY_CORE_EXE_LDFLAGS:= $(if $(CONFIGURE_EXE_LDFLAGS), $(CONFIGURE_EXE_LDFLAGS) $(PY_LDFLAGS_NODIST), $(PY_CORE_LDFLAGS)) # Strict or non-strict aliasing flags used to compile dtoa.c, see above CFLAGS_ALIASING=@CFLAGS_ALIASING@ @@ -986,7 +990,7 @@ clinic-tests: check-clean-src $(srcdir)/Lib/test/clinic.test.c # Build the interpreter $(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) - $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + $(LINKCC) $(PY_CORE_EXE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform @@ -1676,7 +1680,7 @@ regen-re: $(BUILDPYTHON) $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/generate_re_casefix.py $(srcdir)/Lib/re/_casefix.py Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS) - $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + $(LINKCC) $(PY_CORE_EXE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ # "Bootstrap Python" used to run Programs/_freeze_module.py diff --git a/Misc/ACKS b/Misc/ACKS index 3464bd95bac791..e38bda37bfa92d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1916,6 +1916,7 @@ Guo Ci Teo Mikhail Terekhov Victor Terrón Pablo Galindo +Rue Ching Teh Richard M. Tew Srinivas Reddy Thatiparthy Tobias Thelen diff --git a/Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst b/Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst new file mode 100644 index 00000000000000..30addc4bf64d4b --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst @@ -0,0 +1 @@ +Introduce executable specific linker flags to ``./configure``. diff --git a/configure b/configure index 98b4af86858673..dd62fd90e38ee1 100755 --- a/configure +++ b/configure @@ -915,6 +915,7 @@ UNIVERSAL_ARCH_FLAGS WASM_STDLIB WASM_ASSETS_DIR LDFLAGS_NOLTO +EXE_LDFLAGS LDFLAGS_NODIST CFLAGS_NODIST BASECFLAGS @@ -9745,6 +9746,7 @@ esac + # The -arch flags for universal builds on macOS UNIVERSAL_ARCH_FLAGS= diff --git a/configure.ac b/configure.ac index 34318769fcc29f..8b90d8ca896f0c 100644 --- a/configure.ac +++ b/configure.ac @@ -2422,6 +2422,7 @@ AS_CASE([$enable_wasm_dynamic_linking], AC_SUBST([BASECFLAGS]) AC_SUBST([CFLAGS_NODIST]) AC_SUBST([LDFLAGS_NODIST]) +AC_SUBST([EXE_LDFLAGS]) AC_SUBST([LDFLAGS_NOLTO]) AC_SUBST([WASM_ASSETS_DIR]) AC_SUBST([WASM_STDLIB]) From 1ac9d138ae0563f2829ba91efe7989af507f47e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Wed, 25 Feb 2026 00:53:01 +0000 Subject: [PATCH 231/498] =?UTF-8?q?GH-145006:=20add=20ModuleNotFoundError?= =?UTF-8?q?=20hints=20when=20a=20module=20for=20a=20differen=E2=80=A6=20(#?= =?UTF-8?q?145007)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * GH-145006: add ModuleNotFoundError hints when a module for a different ABI exists Signed-off-by: Filipe Laíns * Fix deprecation warnings Signed-off-by: Filipe Laíns * Use SHLIB_SUFFIX in test_find_incompatible_extension_modules when available Signed-off-by: Filipe Laíns * Add test_incompatible_extension_modules_hint Signed-off-by: Filipe Laíns * Fix Windows Signed-off-by: Filipe Laíns * Show the whole extension module file name in hint Signed-off-by: Filipe Laíns --------- Signed-off-by: Filipe Laíns --- Lib/test/test_traceback.py | 55 ++++++++++++++++++- Lib/traceback.py | 36 ++++++++++++ ...-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst | 2 + 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 99ac7fd83d91cb..3896f34a34c8d6 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -9,15 +9,18 @@ import builtins import unittest import unittest.mock +import os import re import tempfile import random import string +import importlib.machinery +import sysconfig from test import support import shutil from test.support import (Error, captured_output, cpython_only, ALWAYS_EQ, requires_debug_ranges, has_no_debug_ranges, - requires_subprocess) + requires_subprocess, os_helper) from test.support.os_helper import TESTFN, temp_dir, unlink from test.support.script_helper import assert_python_ok, assert_python_failure, make_script from test.support.import_helper import forget @@ -5194,6 +5197,56 @@ def test_windows_only_module_error(self): else: self.fail("ModuleNotFoundError was not raised") + @unittest.skipIf(not importlib.machinery.EXTENSION_SUFFIXES, 'Platform does not support extension modules') + def test_find_incompatible_extension_modules(self): + """_find_incompatible_extension_modules assumes the last extension in + importlib.machinery.EXTENSION_SUFFIXES (defined in Python/dynload_*.c) + is untagged (eg. .so, .pyd). + + This test exists to make sure that assumption is correct. + """ + last_extension_suffix = importlib.machinery.EXTENSION_SUFFIXES[-1] + if shlib_suffix := sysconfig.get_config_var('SHLIB_SUFFIX'): + self.assertEqual(last_extension_suffix, shlib_suffix) + else: + before_dot, *extensions = last_extension_suffix.split('.') + expected_prefixes = [''] + if os.name == 'nt': + # Windows puts the debug tag in the module file stem (eg. foo_d.pyd) + expected_prefixes.append('_d') + self.assertIn(before_dot, expected_prefixes, msg=( + f'Unexpected prefix {before_dot!r} in extension module ' + f'suffix {last_extension_suffix!r}. ' + 'traceback._find_incompatible_extension_module needs to be ' + 'updated to take this into account!' + )) + # if SHLIB_SUFFIX is not define, we assume the native + # shared library suffix only contains one extension + # (eg. '.so', bad eg. '.cpython-315-x86_64-linux-gnu.so') + self.assertEqual(len(extensions), 1, msg=( + 'The last suffix in importlib.machinery.EXTENSION_SUFFIXES ' + 'contains more than one extension, so it is probably different ' + 'than SHLIB_SUFFIX. It probably contains an ABI tag! ' + 'If this is a false positive, define SHLIB_SUFFIX in sysconfig.' + )) + + @unittest.skipIf(not importlib.machinery.EXTENSION_SUFFIXES, 'Platform does not support extension modules') + def test_incompatible_extension_modules_hint(self): + untagged_suffix = importlib.machinery.EXTENSION_SUFFIXES[-1] + with os_helper.temp_dir() as tmp: + # create a module with a incompatible ABI tag + incompatible_module = f'foo.some-abi{untagged_suffix}' + open(os.path.join(tmp, incompatible_module), "wb").close() + # try importing it + code = f''' + import sys + sys.path.insert(0, {tmp!r}) + import foo + ''' + _, _, stderr = assert_python_failure('-c', code, __cwd=tmp) + hint = f'Although a module with this name was found for a different Python version ({incompatible_module}).' + self.assertIn(hint, stderr.decode()) + class TestColorizedTraceback(unittest.TestCase): maxDiff = None diff --git a/Lib/traceback.py b/Lib/traceback.py index b16cd8646e43f1..4e809acb7a01bb 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -3,6 +3,7 @@ import collections.abc import itertools import linecache +import os import sys import textwrap import types @@ -12,6 +13,7 @@ import tokenize import io import importlib.util +import pathlib import _colorize from contextlib import suppress @@ -1129,6 +1131,11 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, self._str += (". Site initialization is disabled, did you forget to " + "add the site-packages directory to sys.path " + "or to enable your virtual environment?") + elif abi_tag := _find_incompatible_extension_module(module_name): + self._str += ( + ". Although a module with this name was found for a " + f"different Python version ({abi_tag})." + ) else: suggestion = _compute_suggestion_error(exc_value, exc_traceback, module_name) if suggestion: @@ -1880,3 +1887,32 @@ def _levenshtein_distance(a, b, max_cost): # Everything in this row is too big, so bail early. return max_cost + 1 return result + + +def _find_incompatible_extension_module(module_name): + import importlib.machinery + import importlib.resources.readers + + if not module_name or not importlib.machinery.EXTENSION_SUFFIXES: + return + + # We assume the last extension is untagged (eg. .so, .pyd)! + # tests.test_traceback.MiscTest.test_find_incompatible_extension_modules + # tests that assumption. + untagged_suffix = importlib.machinery.EXTENSION_SUFFIXES[-1] + # On Windows the debug tag is part of the module file stem, instead of the + # extension (eg. foo_d.pyd), so let's remove it and just look for .pyd. + if os.name == 'nt': + untagged_suffix = untagged_suffix.removeprefix('_d') + + parent, _, child = module_name.rpartition('.') + if parent: + traversable = importlib.resources.files(parent) + else: + traversable = importlib.resources.readers.MultiplexedPath( + *map(pathlib.Path, filter(os.path.isdir, sys.path)) + ) + + for entry in traversable.iterdir(): + if entry.name.startswith(child + '.') and entry.name.endswith(untagged_suffix): + return entry.name diff --git a/Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst b/Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst new file mode 100644 index 00000000000000..69052c7ca92c8a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst @@ -0,0 +1,2 @@ +Add :exc:`ModuleNotFoundError` hints when a module for a different ABI +exists. From f8ce51a52209aa04c781d20fe0778247df5a465b Mon Sep 17 00:00:00 2001 From: Matthias Kievernagel Date: Wed, 25 Feb 2026 08:34:00 +0000 Subject: [PATCH 232/498] gh-47655: Add support for user data and detail of Tk events to tkinter (GH-7142) Expose the %d substitution as the tkinter.Event attributes: * "detail" for Enter, Leave, FocusIn, FocusOut, and ConfigureRequest events * "user_data" for virtual events Co-authored-by: Serhiy Storchaka --- Doc/whatsnew/3.15.rst | 5 +++ Lib/test/test_tkinter/test_misc.py | 32 ++++++++++++++++++- Lib/tkinter/__init__.py | 21 +++++++++--- .../2018-05-11-12-26-16.bpo-3405.CacMw9.rst | 3 ++ 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 816d45e0756824..37ebdfee7915fe 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1059,6 +1059,11 @@ tkinter with outdated names. (Contributed by Serhiy Storchaka in :gh:`143754`.) +* Added :class:`!Event` attributes :attr:`!user_data` for Tk virtual events + and :attr:`!detail` for ``Enter``, ``Leave``, ``FocusIn``, ``FocusOut``, + and ``ConfigureRequest`` events. + (Contributed by Matthias Kievernagel and Serhiy Storchaka in :gh:`47655`.) + .. _whatsnew315-tomllib-1-1-0: diff --git a/Lib/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py index a6ba55b3fcadb3..f017e94a8b3c22 100644 --- a/Lib/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -636,6 +636,8 @@ def test_focus(self): self.assertEqual(e.x_root, '??') self.assertEqual(e.y_root, '??') self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, 'NotifyAncestor') self.assertEqual(repr(e), '') def test_configure(self): @@ -669,6 +671,8 @@ def test_configure(self): self.assertEqual(e.x_root, '??') self.assertEqual(e.y_root, '??') self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, '??') self.assertEqual(repr(e), '') def test_event_generate_key_press(self): @@ -705,6 +709,8 @@ def test_event_generate_key_press(self): self.assertEqual(e.x_root, -1) self.assertEqual(e.y_root, -1) self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, '??') self.assertEqual(repr(e), f"") @@ -740,8 +746,17 @@ def test_event_generate_enter(self): self.assertEqual(e.x_root, 100 + f.winfo_rootx()) self.assertEqual(e.y_root, 50 + f.winfo_rooty()) self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, 'NotifyAncestor') self.assertEqual(repr(e), '') + f.event_generate('', x=100, y=50, detail='NotifyPointer') + self.assertEqual(len(events), 2, events) + e = events[1] + self.assertIs(e.type, tkinter.EventType.Enter) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, 'NotifyPointer') + def test_event_generate_button_press(self): f = tkinter.Frame(self.root, width=150, height=100) f.pack() @@ -774,6 +789,8 @@ def test_event_generate_button_press(self): self.assertEqual(e.x_root, f.winfo_rootx() + 100) self.assertEqual(e.y_root, f.winfo_rooty() + 50) self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, '??') self.assertEqual(repr(e), '') def test_event_generate_motion(self): @@ -808,6 +825,8 @@ def test_event_generate_motion(self): self.assertEqual(e.x_root, f.winfo_rootx() + 100) self.assertEqual(e.y_root, f.winfo_rooty() + 50) self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, '??') self.assertEqual(repr(e), '') def test_event_generate_mouse_wheel(self): @@ -842,9 +861,11 @@ def test_event_generate_mouse_wheel(self): self.assertEqual(e.x_root, f.winfo_rootx() + 100) self.assertEqual(e.y_root, f.winfo_rooty() + 50) self.assertEqual(e.delta, -5) + self.assertEqual(e.user_data, '??') + self.assertEqual(e.detail, '??') self.assertEqual(repr(e), '') - def test_generate_event_virtual_event(self): + def test_event_generate_virtual_event(self): f = tkinter.Frame(self.root, width=150, height=100) f.pack() self.root.wait_visibility() # needed on Windows @@ -876,9 +897,18 @@ def test_generate_event_virtual_event(self): self.assertEqual(e.x_root, f.winfo_rootx() + 50) self.assertEqual(e.y_root, -1) self.assertEqual(e.delta, 0) + self.assertEqual(e.user_data, '') + self.assertEqual(e.detail, '??') self.assertEqual(repr(e), f"") + f.event_generate('<>', data='spam') + self.assertEqual(len(events), 2, events) + e = events[1] + self.assertIs(e.type, tkinter.EventType.VirtualEvent) + self.assertEqual(e.user_data, 'spam') + self.assertEqual(e.detail, '??') + class BindTest(AbstractTkTest, unittest.TestCase): diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index d695e3ec9cb1b4..ba8365f56c37a7 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -255,6 +255,10 @@ class Event: type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) + detail - certain fixed strings (see Tcl/Tk documentation) + (Enter, Leave, FocusIn, FocusOut, ConfigureRequest) + user_data - data string which was passed to event_generate() or empty + string (VirtualEvent) """ def __repr__(self): @@ -1538,7 +1542,7 @@ def bind(self, sequence=None, func=None, add=None): for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This - event can be generated by event_generate. + event can be generated by event_generate(). If events are concatenated they must appear shortly after each other. @@ -1723,7 +1727,7 @@ def _root(self): w = self while w.master is not None: w = w.master return w - _subst_format = ('%#', '%b', '%f', '%h', '%k', + _subst_format = ('%#', '%b', '%d', '%f', '%h', '%k', '%s', '%t', '%w', '%x', '%y', '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') _subst_format_str = " ".join(_subst_format) @@ -1744,11 +1748,14 @@ def getint_event(s): if any(isinstance(s, tuple) for s in args): args = [s[0] if isinstance(s, tuple) and len(s) == 1 else s for s in args] - nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args - # Missing: (a, c, d, m, o, v, B, R) + nsign, b, d, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args + # Missing: (a, c, m, o, v, B, R) e = Event() # serial field: valid for all events # number of button: ButtonPress and ButtonRelease events only + # detail: for Enter, Leave, FocusIn, FocusOut and ConfigureRequest + # events certain fixed strings (see Tcl/Tk documentation) + # user_data: data string from a virtual event or an empty string # height field: Configure, ConfigureRequest, Create, # ResizeRequest, and Expose events only # keycode field: KeyPress and KeyRelease events only @@ -1762,6 +1769,12 @@ def getint_event(s): # KeyRelease, and Motion events e.serial = getint(nsign) e.num = getint_event(b) + if T == EventType.VirtualEvent: + e.user_data = d + e.detail = '??' + else: + e.user_data = '??' + e.detail = d try: e.focus = getboolean(f) except TclError: pass e.height = getint_event(h) diff --git a/Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst b/Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst new file mode 100644 index 00000000000000..bf97bf0231fc0a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst @@ -0,0 +1,3 @@ +Add support for user data of Tk virtual events and detail for +``Enter``, ``Leave``, ``FocusIn``, ``FocusOut``, and +``ConfigureRequest`` events to :mod:`tkinter`. From 9b22261a86b54f198225426e86390ef8dd85e091 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 25 Feb 2026 13:37:59 +0100 Subject: [PATCH 233/498] GH-145000: Add a tool to record/check removed HTML IDs (#145001) --- Doc/.ruff.toml | 3 + Doc/Makefile | 6 ++ Doc/tools/check-html-ids.py | 181 ++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 Doc/tools/check-html-ids.py diff --git a/Doc/.ruff.toml b/Doc/.ruff.toml index 3e676e13c3f41a..6b573fd58d089b 100644 --- a/Doc/.ruff.toml +++ b/Doc/.ruff.toml @@ -32,6 +32,9 @@ ignore = [ "E501", # Ignore line length errors (we use auto-formatting) ] +[lint.per-file-ignores] +"tools/check-html-ids.py" = ["I001"] # Unsorted imports + [format] preview = true quote-style = "preserve" diff --git a/Doc/Makefile b/Doc/Makefile index 4d605980a62904..d39c2fe3c3f22a 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -336,3 +336,9 @@ autobuild-stable-html: exit 1;; \ esac @$(MAKE) autobuild-dev-html + +# Collect HTML IDs to a JSON document +.PHONY: html-ids +html-ids: + $(PYTHON) tools/check-html-ids.py collect build/html \ + -o build/html/html-ids.json.gz diff --git a/Doc/tools/check-html-ids.py b/Doc/tools/check-html-ids.py new file mode 100644 index 00000000000000..8e8e0a581df72d --- /dev/null +++ b/Doc/tools/check-html-ids.py @@ -0,0 +1,181 @@ +from compression import gzip +import concurrent.futures +from pathlib import Path +import html.parser +import functools +import argparse +import json +import sys +import re + + +IGNORED_ID_RE = re.compile( + r""" + index-\d+ + | id\d+ + | [_a-z]+_\d+ +""", + re.VERBOSE, +) + + +class IDGatherer(html.parser.HTMLParser): + def __init__(self, ids): + super().__init__() + self.__ids = ids + + def handle_starttag(self, tag, attrs): + for name, value in attrs: + if name == 'id': + if not IGNORED_ID_RE.fullmatch(value): + self.__ids.add(value) + + +def get_ids_from_file(path): + ids = set() + gatherer = IDGatherer(ids) + with path.open(encoding='utf-8') as file: + while chunk := file.read(4096): + gatherer.feed(chunk) + return ids + + +def gather_ids(htmldir, *, verbose_print): + if not htmldir.joinpath('objects.inv').exists(): + raise ValueError(f'{htmldir!r} is not a Sphinx HTML output directory') + + if sys._is_gil_enabled: + pool = concurrent.futures.ProcessPoolExecutor() + else: + pool = concurrent.futures.ThreadPoolExecutor() + tasks = {} + for path in htmldir.glob('**/*.html'): + relative_path = path.relative_to(htmldir) + if '_static' in relative_path.parts: + continue + if 'whatsnew' in relative_path.parts: + continue + tasks[relative_path] = pool.submit(get_ids_from_file, path=path) + + ids_by_page = {} + for relative_path, future in tasks.items(): + verbose_print(relative_path) + ids = future.result() + ids_by_page[str(relative_path)] = ids + verbose_print(f' - {len(ids)} ids found') + + common = set.intersection(*ids_by_page.values()) + verbose_print(f'Filtering out {len(common)} common ids') + for key, page_ids in ids_by_page.items(): + ids_by_page[key] = sorted(page_ids - common) + + return ids_by_page + + +def do_check(baseline, checked, excluded, *, verbose_print): + successful = True + for name, baseline_ids in sorted(baseline.items()): + try: + checked_ids = checked[name] + except KeyError: + successful = False + print(f'{name}: (page missing)') + print() + else: + missing_ids = set(baseline_ids) - set(checked_ids) + if missing_ids: + missing_ids = { + a + for a in missing_ids + if not IGNORED_ID_RE.fullmatch(a) + and (name, a) not in excluded + } + if missing_ids: + successful = False + for missing_id in sorted(missing_ids): + print(f'{name}: {missing_id}') + print() + return successful + + +def main(argv): + parser = argparse.ArgumentParser() + parser.add_argument( + '-v', + '--verbose', + action='store_true', + help='print out more information', + ) + subparsers = parser.add_subparsers(dest='command', required=True) + + collect = subparsers.add_parser( + 'collect', help='collect IDs from a set of HTML files' + ) + collect.add_argument( + 'htmldir', type=Path, help='directory with HTML documentation' + ) + collect.add_argument( + '-o', + '--outfile', + help='File to save the result in; default /html-ids.json.gz', + ) + + check = subparsers.add_parser('check', help='check two archives of IDs') + check.add_argument( + 'baseline_file', type=Path, help='file with baseline IDs' + ) + check.add_argument('checked_file', type=Path, help='file with checked IDs') + check.add_argument( + '-x', + '--exclude-file', + type=Path, + help='file with IDs to exclude from the check', + ) + + args = parser.parse_args(argv[1:]) + + if args.verbose: + verbose_print = functools.partial(print, file=sys.stderr) + else: + + def verbose_print(*args, **kwargs): + """do nothing""" + + if args.command == 'collect': + ids = gather_ids(args.htmldir, verbose_print=verbose_print) + if args.outfile is None: + args.outfile = args.htmldir / 'html-ids.json.gz' + with gzip.open(args.outfile, 'wt', encoding='utf-8') as zfile: + json.dump({'ids_by_page': ids}, zfile) + + if args.command == 'check': + with gzip.open(args.baseline_file) as zfile: + baseline = json.load(zfile)['ids_by_page'] + with gzip.open(args.checked_file) as zfile: + checked = json.load(zfile)['ids_by_page'] + excluded = set() + if args.exclude_file: + with open(args.exclude_file, encoding='utf-8') as file: + for line in file: + line = line.strip() + if line and not line.startswith('#'): + name, sep, excluded_id = line.partition(':') + if sep: + excluded.add((name.strip(), excluded_id.strip())) + if do_check(baseline, checked, excluded, verbose_print=verbose_print): + verbose_print('All OK') + else: + sys.stdout.flush() + print( + 'ERROR: Removed IDs found', + 'The above HTML IDs were removed from the documentation, ' + + 'resulting in broken links. Please add them back.', + sep='\n', + file=sys.stderr, + ) + if args.exclude_file: + print(f'Alternatively, add them to {args.exclude_file}.') + + +if __name__ == '__main__': + main(sys.argv) From 12828e5f98a47864e3f6d25fdd99c062fae28b1c Mon Sep 17 00:00:00 2001 From: Tadej Magajna Date: Wed, 25 Feb 2026 15:44:17 +0100 Subject: [PATCH 234/498] gh-85809: Ensure shutil.make_archive accepts path-like objects in all cases (GH-143668) --- Doc/library/shutil.rst | 21 +++++++++------ Lib/shutil.py | 7 +++-- Lib/test/test_shutil.py | 26 +++++++++++++++++++ ...6-01-10-22-58-30.gh-issue-85809.0eW4wt.rst | 1 + 4 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 22444c4d804265..0666fcfde61e61 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -618,8 +618,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. Create an archive file (such as zip or tar) and return its name. - *base_name* is the name of the file to create, including the path, minus - any format-specific extension. + *base_name* is a string or :term:`path-like object` specifying the name of + the file to create, including the path, minus any format-specific extension. *format* is the archive format: one of "zip" (if the :mod:`zlib` module is available), "tar", "gztar" (if the @@ -627,13 +627,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. available), "xztar" (if the :mod:`lzma` module is available), or "zstdtar" (if the :mod:`compression.zstd` module is available). - *root_dir* is a directory that will be the root directory of the - archive, all paths in the archive will be relative to it; for example, - we typically chdir into *root_dir* before creating the archive. + *root_dir* is a string or :term:`path-like object` specifying a directory + that will be the root directory of the archive, all paths in the archive + will be relative to it; for example, we typically chdir into *root_dir* + before creating the archive. - *base_dir* is the directory where we start archiving from; - i.e. *base_dir* will be the common prefix of all files and - directories in the archive. *base_dir* must be given relative + *base_dir* is a string or :term:`path-like object` specifying a directory + where we start archiving from; i.e. *base_dir* will be the common prefix of + all files and directories in the archive. *base_dir* must be given relative to *root_dir*. See :ref:`shutil-archiving-example-with-basedir` for how to use *base_dir* and *root_dir* together. @@ -668,6 +669,10 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. This function is now made thread-safe during creation of standard ``.zip`` and tar archives. + .. versionchanged:: next + Accepts a :term:`path-like object` for *base_name*, *root_dir* and + *base_dir*. + .. function:: get_archive_formats() Return a list of supported formats for archiving. diff --git a/Lib/shutil.py b/Lib/shutil.py index 8d8fe145567822..44ccdbb503d4fb 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1212,19 +1212,22 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, for arg, val in format_info[1]: kwargs[arg] = val + base_name = os.fspath(base_name) + if base_dir is None: base_dir = os.curdir + else: + base_dir = os.fspath(base_dir) supports_root_dir = getattr(func, 'supports_root_dir', False) save_cwd = None if root_dir is not None: + root_dir = os.fspath(root_dir) stmd = os.stat(root_dir).st_mode if not stat.S_ISDIR(stmd): raise NotADirectoryError(errno.ENOTDIR, 'Not a directory', root_dir) if supports_root_dir: - # Support path-like base_name here for backwards-compatibility. - base_name = os.fspath(base_name) kwargs['root_dir'] = root_dir else: save_cwd = os.getcwd() diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index ebb6cf88336249..a4bd113bc7f1fc 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -2042,6 +2042,32 @@ def test_make_zipfile_in_curdir(self): self.assertEqual(make_archive('test', 'zip'), 'test.zip') self.assertTrue(os.path.isfile('test.zip')) + def test_make_archive_pathlike_cwd_default(self): + called_args = [] + def archiver(base_name, base_dir, **kw): + called_args.append((base_name, kw.get('root_dir'))) + + register_archive_format('xxx', archiver, [], 'xxx file') + self.addCleanup(unregister_archive_format, 'xxx') + with no_chdir: + make_archive(FakePath('basename'), 'xxx') + self.assertEqual(called_args, [('basename', None)]) + + def test_make_archive_pathlike_cwd_supports_root_dir(self): + root_dir = self.mkdtemp() + called_args = [] + def archiver(base_name, base_dir, **kw): + called_args.append((base_name, base_dir, kw.get('root_dir'))) + archiver.supports_root_dir = True + + register_archive_format('xxx', archiver, [], 'xxx file') + self.addCleanup(unregister_archive_format, 'xxx') + with no_chdir: + make_archive(FakePath('basename'), 'xxx', + root_dir=FakePath(root_dir), + base_dir=FakePath('basedir')) + self.assertEqual(called_args, [('basename', 'basedir', root_dir)]) + def test_register_archive_format(self): self.assertRaises(TypeError, register_archive_format, 'xxx', 1) diff --git a/Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst b/Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst new file mode 100644 index 00000000000000..3993c7a91da138 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst @@ -0,0 +1 @@ +Added :term:`path-like object` support for :func:`shutil.make_archive`. From ae57dc6c0b7d265a959452bdd18a77d06038e2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Wed, 25 Feb 2026 15:39:45 +0000 Subject: [PATCH 235/498] Update status of blockers on combining pixi packges variant sources (#145222) --- Tools/pixi-packages/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/pixi-packages/README.md b/Tools/pixi-packages/README.md index 20bc18f4555fa0..4b44fd12150752 100644 --- a/Tools/pixi-packages/README.md +++ b/Tools/pixi-packages/README.md @@ -37,7 +37,7 @@ Each package definition is contained in a subdirectory, but they share the build - More package variants (such as UBSan) - Support for Windows - Using a single `pixi.toml` and `recipe.yaml` for all package variants is blocked on - [pixi-build-backends#532](https://github.com/prefix-dev/pixi-build-backends/pull/532) + [pixi#5364](https://github.com/prefix-dev/pixi/pull/5364) and [pixi#5248](https://github.com/prefix-dev/pixi/issues/5248) ## Troubleshooting From 017ccd3bf420b79333f79f44a470c9c30a09aadc Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Wed, 25 Feb 2026 16:49:46 +0100 Subject: [PATCH 236/498] gh-142518: Move thread safety sections into a new page (#144716) - Create a new page for thread safety notes for built-in types - Move thread safety notes for `list` into the new page - Move thread safety notes for `dict` into the new page --------- Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/index.rst | 1 + Doc/library/stdtypes.rst | 247 +-------------------------------- Doc/library/threadsafety.rst | 262 +++++++++++++++++++++++++++++++++++ 3 files changed, 269 insertions(+), 241 deletions(-) create mode 100644 Doc/library/threadsafety.rst diff --git a/Doc/library/index.rst b/Doc/library/index.rst index 163e1679c65ef8..8fc77be520d426 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -43,6 +43,7 @@ the `Python Package Index `_. constants.rst stdtypes.rst exceptions.rst + threadsafety.rst text.rst binary.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index b9b81a7d469d0d..21572d6dc71d84 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1449,111 +1449,10 @@ application). list appear empty for the duration, and raises :exc:`ValueError` if it can detect that the list has been mutated during a sort. -.. _thread-safety-list: - -.. rubric:: Thread safety for list objects - -Reading a single element from a :class:`list` is -:term:`atomic `: - -.. code-block:: - :class: green - - lst[i] # list.__getitem__ - -The following methods traverse the list and use :term:`atomic ` -reads of each item to perform their function. That means that they may -return results affected by concurrent modifications: - -.. code-block:: - :class: maybe - - item in lst - lst.index(item) - lst.count(item) - -All of the above operations avoid acquiring :term:`per-object locks -`. They do not block concurrent modifications. Other -operations that hold a lock will not block these from observing intermediate -states. - -All other operations from here on block using the :term:`per-object lock`. - -Writing a single item via ``lst[i] = x`` is safe to call from multiple -threads and will not corrupt the list. - -The following operations return new objects and appear -:term:`atomic ` to other threads: - -.. code-block:: - :class: good - - lst1 + lst2 # concatenates two lists into a new list - x * lst # repeats lst x times into a new list - lst.copy() # returns a shallow copy of the list - -The following methods that only operate on a single element with no shifting -required are :term:`atomic `: - -.. code-block:: - :class: good - - lst.append(x) # append to the end of the list, no shifting required - lst.pop() # pop element from the end of the list, no shifting required - -The :meth:`~list.clear` method is also :term:`atomic `. -Other threads cannot observe elements being removed. - -The :meth:`~list.sort` method is not :term:`atomic `. -Other threads cannot observe intermediate states during sorting, but the -list appears empty for the duration of the sort. - -The following operations may allow :term:`lock-free` operations to observe -intermediate states since they modify multiple elements in place: - -.. code-block:: - :class: maybe - - lst.insert(idx, item) # shifts elements - lst.pop(idx) # idx not at the end of the list, shifts elements - lst *= x # copies elements in place - -The :meth:`~list.remove` method may allow concurrent modifications since -element comparison may execute arbitrary Python code (via -:meth:`~object.__eq__`). - -:meth:`~list.extend` is safe to call from multiple threads. However, its -guarantees depend on the iterable passed to it. If it is a :class:`list`, a -:class:`tuple`, a :class:`set`, a :class:`frozenset`, a :class:`dict` or a -:ref:`dictionary view object ` (but not their subclasses), the -``extend`` operation is safe from concurrent modifications to the iterable. -Otherwise, an iterator is created which can be concurrently modified by -another thread. The same applies to inplace concatenation of a list with -other iterables when using ``lst += iterable``. - -Similarly, assigning to a list slice with ``lst[i:j] = iterable`` is safe -to call from multiple threads, but ``iterable`` is only locked when it is -also a :class:`list` (but not its subclasses). - -Operations that involve multiple accesses, as well as iteration, are never -atomic. For example: - -.. code-block:: - :class: bad - - # NOT atomic: read-modify-write - lst[i] = lst[i] + 1 - - # NOT atomic: check-then-act - if lst: - item = lst.pop() - - # NOT thread-safe: iteration while modifying - for item in lst: - process(item) # another thread may modify lst +.. seealso:: -Consider external synchronization when sharing :class:`list` instances -across threads. See :ref:`freethreading-python-howto` for more information. + For detailed information on thread-safety guarantees for :class:`list` + objects, see :ref:`thread-safety-list`. .. _typesseq-tuple: @@ -5601,144 +5500,10 @@ can be used interchangeably to index the same dictionary entry. :class:`frozendict` and :class:`types.MappingProxyType` can be used to create a read-only view of a :class:`dict`. -.. _thread-safety-dict: - -.. rubric:: Thread safety for dict objects - -Creating a dictionary with the :class:`dict` constructor is atomic when the -argument to it is a :class:`dict` or a :class:`tuple`. When using the -:meth:`dict.fromkeys` method, dictionary creation is atomic when the -argument is a :class:`dict`, :class:`tuple`, :class:`set` or -:class:`frozenset`. - -The following operations and functions are :term:`lock-free` and -:term:`atomic `. - -.. code-block:: - :class: good - - d[key] # dict.__getitem__ - d.get(key) # dict.get - key in d # dict.__contains__ - len(d) # dict.__len__ - -All other operations from here on hold the :term:`per-object lock`. - -Writing or removing a single item is safe to call from multiple threads -and will not corrupt the dictionary: - -.. code-block:: - :class: good - - d[key] = value # write - del d[key] # delete - d.pop(key) # remove and return - d.popitem() # remove and return last item - d.setdefault(key, v) # insert if missing - -These operations may compare keys using :meth:`~object.__eq__`, which can -execute arbitrary Python code. During such comparisons, the dictionary may -be modified by another thread. For built-in types like :class:`str`, -:class:`int`, and :class:`float`, that implement :meth:`~object.__eq__` in C, -the underlying lock is not released during comparisons and this is not a -concern. - -The following operations return new objects and hold the :term:`per-object lock` -for the duration of the operation: - -.. code-block:: - :class: good - - d.copy() # returns a shallow copy of the dictionary - d | other # merges two dicts into a new dict - d.keys() # returns a new dict_keys view object - d.values() # returns a new dict_values view object - d.items() # returns a new dict_items view object - -The :meth:`~dict.clear` method holds the lock for its duration. Other -threads cannot observe elements being removed. - -The following operations lock both dictionaries. For :meth:`~dict.update` -and ``|=``, this applies only when the other operand is a :class:`dict` -that uses the standard dict iterator (but not subclasses that override -iteration). For equality comparison, this applies to :class:`dict` and -its subclasses: - -.. code-block:: - :class: good - - d.update(other_dict) # both locked when other_dict is a dict - d |= other_dict # both locked when other_dict is a dict - d == other_dict # both locked for dict and subclasses - -All comparison operations also compare values using :meth:`~object.__eq__`, -so for non-built-in types the lock may be released during comparison. - -:meth:`~dict.fromkeys` locks both the new dictionary and the iterable -when the iterable is exactly a :class:`dict`, :class:`set`, or -:class:`frozenset` (not subclasses): - -.. code-block:: - :class: good - - dict.fromkeys(a_dict) # locks both - dict.fromkeys(a_set) # locks both - dict.fromkeys(a_frozenset) # locks both - -When updating from a non-dict iterable, only the target dictionary is -locked. The iterable may be concurrently modified by another thread: - -.. code-block:: - :class: maybe - - d.update(iterable) # iterable is not a dict: only d locked - d |= iterable # iterable is not a dict: only d locked - dict.fromkeys(iterable) # iterable is not a dict/set/frozenset: only result locked - -Operations that involve multiple accesses, as well as iteration, are never -atomic: - -.. code-block:: - :class: bad - - # NOT atomic: read-modify-write - d[key] = d[key] + 1 - - # NOT atomic: check-then-act (TOCTOU) - if key in d: - del d[key] - - # NOT thread-safe: iteration while modifying - for key, value in d.items(): - process(key) # another thread may modify d - -To avoid time-of-check to time-of-use (TOCTOU) issues, use atomic -operations or handle exceptions: - -.. code-block:: - :class: good - - # Use pop() with default instead of check-then-delete - d.pop(key, None) - - # Or handle the exception - try: - del d[key] - except KeyError: - pass - -To safely iterate over a dictionary that may be modified by another -thread, iterate over a copy: - -.. code-block:: - :class: good - - # Make a copy to iterate safely - for key, value in d.copy().items(): - process(key) +.. seealso:: -Consider external synchronization when sharing :class:`dict` instances -across threads. See :ref:`freethreading-python-howto` for more information. + For detailed information on thread-safety guarantees for :class:`dict` + objects, see :ref:`thread-safety-dict`. .. _dict-views: diff --git a/Doc/library/threadsafety.rst b/Doc/library/threadsafety.rst new file mode 100644 index 00000000000000..5b5949d4eff437 --- /dev/null +++ b/Doc/library/threadsafety.rst @@ -0,0 +1,262 @@ +.. _threadsafety: + +************************ +Thread Safety Guarantees +************************ + +This page documents thread-safety guarantees for built-in types in Python's +free-threaded build. The guarantees described here apply when using Python with +the :term:`GIL` disabled (free-threaded mode). When the GIL is enabled, most +operations are implicitly serialized. + +For general guidance on writing thread-safe code in free-threaded Python, see +:ref:`freethreading-python-howto`. + + +.. _thread-safety-list: + +Thread safety for list objects +============================== + +Reading a single element from a :class:`list` is +:term:`atomic `: + +.. code-block:: + :class: good + + lst[i] # list.__getitem__ + +The following methods traverse the list and use :term:`atomic ` +reads of each item to perform their function. That means that they may +return results affected by concurrent modifications: + +.. code-block:: + :class: maybe + + item in lst + lst.index(item) + lst.count(item) + +All of the above operations avoid acquiring :term:`per-object locks +`. They do not block concurrent modifications. Other +operations that hold a lock will not block these from observing intermediate +states. + +All other operations from here on block using the :term:`per-object lock`. + +Writing a single item via ``lst[i] = x`` is safe to call from multiple +threads and will not corrupt the list. + +The following operations return new objects and appear +:term:`atomic ` to other threads: + +.. code-block:: + :class: good + + lst1 + lst2 # concatenates two lists into a new list + x * lst # repeats lst x times into a new list + lst.copy() # returns a shallow copy of the list + +The following methods that only operate on a single element with no shifting +required are :term:`atomic `: + +.. code-block:: + :class: good + + lst.append(x) # append to the end of the list, no shifting required + lst.pop() # pop element from the end of the list, no shifting required + +The :meth:`~list.clear` method is also :term:`atomic `. +Other threads cannot observe elements being removed. + +The :meth:`~list.sort` method is not :term:`atomic `. +Other threads cannot observe intermediate states during sorting, but the +list appears empty for the duration of the sort. + +The following operations may allow :term:`lock-free` operations to observe +intermediate states since they modify multiple elements in place: + +.. code-block:: + :class: maybe + + lst.insert(idx, item) # shifts elements + lst.pop(idx) # idx not at the end of the list, shifts elements + lst *= x # copies elements in place + +The :meth:`~list.remove` method may allow concurrent modifications since +element comparison may execute arbitrary Python code (via +:meth:`~object.__eq__`). + +:meth:`~list.extend` is safe to call from multiple threads. However, its +guarantees depend on the iterable passed to it. If it is a :class:`list`, a +:class:`tuple`, a :class:`set`, a :class:`frozenset`, a :class:`dict` or a +:ref:`dictionary view object ` (but not their subclasses), the +``extend`` operation is safe from concurrent modifications to the iterable. +Otherwise, an iterator is created which can be concurrently modified by +another thread. The same applies to inplace concatenation of a list with +other iterables when using ``lst += iterable``. + +Similarly, assigning to a list slice with ``lst[i:j] = iterable`` is safe +to call from multiple threads, but ``iterable`` is only locked when it is +also a :class:`list` (but not its subclasses). + +Operations that involve multiple accesses, as well as iteration, are never +atomic. For example: + +.. code-block:: + :class: bad + + # NOT atomic: read-modify-write + lst[i] = lst[i] + 1 + + # NOT atomic: check-then-act + if lst: + item = lst.pop() + + # NOT thread-safe: iteration while modifying + for item in lst: + process(item) # another thread may modify lst + +Consider external synchronization when sharing :class:`list` instances +across threads. + + +.. _thread-safety-dict: + +Thread safety for dict objects +============================== + +Creating a dictionary with the :class:`dict` constructor is atomic when the +argument to it is a :class:`dict` or a :class:`tuple`. When using the +:meth:`dict.fromkeys` method, dictionary creation is atomic when the +argument is a :class:`dict`, :class:`tuple`, :class:`set` or +:class:`frozenset`. + +The following operations and functions are :term:`lock-free` and +:term:`atomic `. + +.. code-block:: + :class: good + + d[key] # dict.__getitem__ + d.get(key) # dict.get + key in d # dict.__contains__ + len(d) # dict.__len__ + +All other operations from here on hold the :term:`per-object lock`. + +Writing or removing a single item is safe to call from multiple threads +and will not corrupt the dictionary: + +.. code-block:: + :class: good + + d[key] = value # write + del d[key] # delete + d.pop(key) # remove and return + d.popitem() # remove and return last item + d.setdefault(key, v) # insert if missing + +These operations may compare keys using :meth:`~object.__eq__`, which can +execute arbitrary Python code. During such comparisons, the dictionary may +be modified by another thread. For built-in types like :class:`str`, +:class:`int`, and :class:`float`, that implement :meth:`~object.__eq__` in C, +the underlying lock is not released during comparisons and this is not a +concern. + +The following operations return new objects and hold the :term:`per-object lock` +for the duration of the operation: + +.. code-block:: + :class: good + + d.copy() # returns a shallow copy of the dictionary + d | other # merges two dicts into a new dict + d.keys() # returns a new dict_keys view object + d.values() # returns a new dict_values view object + d.items() # returns a new dict_items view object + +The :meth:`~dict.clear` method holds the lock for its duration. Other +threads cannot observe elements being removed. + +The following operations lock both dictionaries. For :meth:`~dict.update` +and ``|=``, this applies only when the other operand is a :class:`dict` +that uses the standard dict iterator (but not subclasses that override +iteration). For equality comparison, this applies to :class:`dict` and +its subclasses: + +.. code-block:: + :class: good + + d.update(other_dict) # both locked when other_dict is a dict + d |= other_dict # both locked when other_dict is a dict + d == other_dict # both locked for dict and subclasses + +All comparison operations also compare values using :meth:`~object.__eq__`, +so for non-built-in types the lock may be released during comparison. + +:meth:`~dict.fromkeys` locks both the new dictionary and the iterable +when the iterable is exactly a :class:`dict`, :class:`set`, or +:class:`frozenset` (not subclasses): + +.. code-block:: + :class: good + + dict.fromkeys(a_dict) # locks both + dict.fromkeys(a_set) # locks both + dict.fromkeys(a_frozenset) # locks both + +When updating from a non-dict iterable, only the target dictionary is +locked. The iterable may be concurrently modified by another thread: + +.. code-block:: + :class: maybe + + d.update(iterable) # iterable is not a dict: only d locked + d |= iterable # iterable is not a dict: only d locked + dict.fromkeys(iterable) # iterable is not a dict/set/frozenset: only result locked + +Operations that involve multiple accesses, as well as iteration, are never +atomic: + +.. code-block:: + :class: bad + + # NOT atomic: read-modify-write + d[key] = d[key] + 1 + + # NOT atomic: check-then-act (TOCTOU) + if key in d: + del d[key] + + # NOT thread-safe: iteration while modifying + for key, value in d.items(): + process(key) # another thread may modify d + +To avoid time-of-check to time-of-use (TOCTOU) issues, use atomic +operations or handle exceptions: + +.. code-block:: + :class: good + + # Use pop() with default instead of check-then-delete + d.pop(key, None) + + # Or handle the exception + try: + del d[key] + except KeyError: + pass + +To safely iterate over a dictionary that may be modified by another +thread, iterate over a copy: + +.. code-block:: + :class: good + + # Make a copy to iterate safely + for key, value in d.copy().items(): + process(key) + +Consider external synchronization when sharing :class:`dict` instances +across threads. From 80b2b8833830194fd18cf4e111c5d6d8a3e27b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Wed, 25 Feb 2026 15:57:06 +0000 Subject: [PATCH 237/498] Fix "lazy from (...) import (...)" tests (#145213) --- .../test_import/data/lazy_imports/global_filter_from.py | 8 ++++---- .../data/lazy_imports/global_filter_from_true.py | 9 +++++---- Lib/test/test_import/test_lazy_imports.py | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_from.py b/Lib/test/test_import/data/lazy_imports/global_filter_from.py index 733839d9c1e935..93a1280292f8af 100644 --- a/Lib/test/test_import/data/lazy_imports/global_filter_from.py +++ b/Lib/test/test_import/data/lazy_imports/global_filter_from.py @@ -1,11 +1,11 @@ -import importlib +import sys def filter(module_name, imported_name, from_list): assert module_name == __name__ assert imported_name == "test.test_import.data.lazy_imports.basic2" - assert from_list == ['f'] + assert from_list == ('f',) return False -importlib.set_lazy_imports(None, filter) +sys.set_lazy_imports_filter(filter) -lazy from import test.test_import.data.lazy_imports.basic2 import f +lazy from test.test_import.data.lazy_imports.basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py b/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py index c019f1ae8117a4..bc51215ae26ce4 100644 --- a/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py +++ b/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py @@ -1,11 +1,12 @@ -import importlib +import sys def filter(module_name, imported_name, from_list): assert module_name == __name__ assert imported_name == "test.test_import.data.lazy_imports.basic2" - assert from_list == ['f'] + assert from_list == ('f',) return True -importlib.set_lazy_imports(None, filter) +sys.set_lazy_imports("normal") +sys.set_lazy_imports_filter(filter) -lazy from import test.test_import.data.lazy_imports.basic2 import f +lazy from test.test_import.data.lazy_imports.basic2 import f diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py index 39d37f68e0b47b..a40e4892a78bb2 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_import/test_lazy_imports.py @@ -119,12 +119,12 @@ def test_global_filter_true(self): def test_global_filter_from(self): """Filter should work with 'from' imports.""" - import test.test_import.data.lazy_imports.global_filter + import test.test_import.data.lazy_imports.global_filter_from self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) def test_global_filter_from_true(self): """Filter returning True should allow lazy 'from' imports.""" - import test.test_import.data.lazy_imports.global_filter_true + import test.test_import.data.lazy_imports.global_filter_from_true self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) From 56b7dc4e9b5d20132be1e571e20efd8d1c9b8047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Wed, 25 Feb 2026 16:27:53 +0000 Subject: [PATCH 238/498] Fix compileall in lazy imports test data with bad syntax (#145221) --- .../lazy_imports/{ => badsyntax}/lazy_class_body.py | 0 .../{ => badsyntax}/lazy_future_import.py | 0 .../lazy_imports/{ => badsyntax}/lazy_import_func.py | 0 .../lazy_imports/{ => badsyntax}/lazy_try_except.py | 0 .../{ => badsyntax}/lazy_try_except_from.py | 0 .../{ => badsyntax}/lazy_try_except_from_star.py | 0 Lib/test/test_import/test_lazy_imports.py | 12 ++++++------ Makefile.pre.in | 1 + 8 files changed, 7 insertions(+), 6 deletions(-) rename Lib/test/test_import/data/lazy_imports/{ => badsyntax}/lazy_class_body.py (100%) rename Lib/test/test_import/data/lazy_imports/{ => badsyntax}/lazy_future_import.py (100%) rename Lib/test/test_import/data/lazy_imports/{ => badsyntax}/lazy_import_func.py (100%) rename Lib/test/test_import/data/lazy_imports/{ => badsyntax}/lazy_try_except.py (100%) rename Lib/test/test_import/data/lazy_imports/{ => badsyntax}/lazy_try_except_from.py (100%) rename Lib/test/test_import/data/lazy_imports/{ => badsyntax}/lazy_try_except_from_star.py (100%) diff --git a/Lib/test/test_import/data/lazy_imports/lazy_class_body.py b/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_class_body.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/lazy_class_body.py rename to Lib/test/test_import/data/lazy_imports/badsyntax/lazy_class_body.py diff --git a/Lib/test/test_import/data/lazy_imports/lazy_future_import.py b/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_future_import.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/lazy_future_import.py rename to Lib/test/test_import/data/lazy_imports/badsyntax/lazy_future_import.py diff --git a/Lib/test/test_import/data/lazy_imports/lazy_import_func.py b/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_import_func.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/lazy_import_func.py rename to Lib/test/test_import/data/lazy_imports/badsyntax/lazy_import_func.py diff --git a/Lib/test/test_import/data/lazy_imports/lazy_try_except.py b/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/lazy_try_except.py rename to Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except.py diff --git a/Lib/test/test_import/data/lazy_imports/lazy_try_except_from.py b/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/lazy_try_except_from.py rename to Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from.py diff --git a/Lib/test/test_import/data/lazy_imports/lazy_try_except_from_star.py b/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from_star.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/lazy_try_except_from_star.py rename to Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from_star.py diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py index a40e4892a78bb2..d4df772d2034d9 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_import/test_lazy_imports.py @@ -232,22 +232,22 @@ def tearDown(self): def test_lazy_try_except(self): """lazy import inside try/except should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.lazy_try_except + import test.test_import.data.lazy_imports.badsyntax.lazy_try_except def test_lazy_try_except_from(self): """lazy from import inside try/except should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.lazy_try_except_from + import test.test_import.data.lazy_imports.badsyntax.lazy_try_except_from def test_lazy_try_except_from_star(self): """lazy from import * should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.lazy_try_except_from_star + import test.test_import.data.lazy_imports.badsyntax.lazy_try_except_from_star def test_lazy_future_import(self): """lazy from __future__ import should raise SyntaxError.""" with self.assertRaises(SyntaxError) as cm: - import test.test_import.data.lazy_imports.lazy_future_import + import test.test_import.data.lazy_imports.badsyntax.lazy_future_import # Check we highlight 'lazy' (column offset 0, end offset 4) self.assertEqual(cm.exception.offset, 1) self.assertEqual(cm.exception.end_offset, 5) @@ -255,7 +255,7 @@ def test_lazy_future_import(self): def test_lazy_import_func(self): """lazy import inside function should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.lazy_import_func + import test.test_import.data.lazy_imports.badsyntax.lazy_import_func def test_lazy_import_exec_in_function(self): """lazy import via exec() inside a function should raise SyntaxError.""" @@ -1223,7 +1223,7 @@ def test_lazy_import_inside_class_raises_syntax_error(self): # PEP 810: "The soft keyword is only allowed at the global (module) level, # not inside functions, class bodies, try blocks, or import *" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.lazy_class_body + import test.test_import.data.lazy_imports.badsyntax.lazy_class_body class MixedLazyEagerImportTests(unittest.TestCase): diff --git a/Makefile.pre.in b/Makefile.pre.in index 122957dec29b6f..aba92666720d7d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2684,6 +2684,7 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_import/data/unwritable \ test/test_import/data/lazy_imports \ test/test_import/data/lazy_imports/pkg \ + test/test_import/data/lazy_imports/badsyntax \ test/test_importlib \ test/test_importlib/builtin \ test/test_importlib/extension \ From 277a03711b1d712c1a4881f07705498c07ebf957 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Thu, 26 Feb 2026 00:52:53 +0800 Subject: [PATCH 239/498] gh-145197: Fix JIT trace crash when recording function from cleared generator frame (GH-145220) --- Include/internal/pycore_opcode_metadata.h | 4 ++-- Include/internal/pycore_uop_metadata.h | 2 +- Lib/test/test_capi/test_opt.py | 22 +++++++++++++++++++ ...-02-25-15-02-08.gh-issue-145197.G6hAUk.rst | 1 + Python/bytecodes.c | 7 ++++-- Python/record_functions.c.h | 11 +++++----- 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index fa8337bd08d470..126bc7d7102925 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1179,7 +1179,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, - [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, @@ -1283,7 +1283,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, - [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index be06738b54ca67..33a4d17d766eb2 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -379,7 +379,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_RECORD_TOS] = HAS_RECORDS_VALUE_FLAG, [_RECORD_TOS_TYPE] = HAS_RECORDS_VALUE_FLAG, [_RECORD_NOS] = HAS_RECORDS_VALUE_FLAG, - [_RECORD_NOS_GEN_FUNC] = HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG, + [_RECORD_NOS_GEN_FUNC] = HAS_RECORDS_VALUE_FLAG, [_RECORD_4OS] = HAS_RECORDS_VALUE_FLAG, [_RECORD_CALLABLE] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG, [_RECORD_BOUND_METHOD] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG, diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index fe1b45608841a2..90e2ed20d1f6b3 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -4114,6 +4114,28 @@ def __init__(self, name): PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE="1") self.assertEqual(result[0].rc, 0, result) + def test_for_iter_gen_cleared_frame_does_not_crash(self): + # See: https://github.com/python/cpython/issues/145197 + result = script_helper.run_python_until_end('-c', textwrap.dedent(""" + def g(): + yield 1 + yield 2 + + for _ in range(4002): + for _ in g(): + pass + + for i in range(4002): + it = g() + if (i & 7) == 0: + next(it) + it.close() + for _ in it: + pass + """), + PYTHON_JIT="1", PYTHON_JIT_STRESS="1") + self.assertEqual(result[0].rc, 0, result) + def global_identity(x): return x diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst new file mode 100644 index 00000000000000..6d6afe5abfea9c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst @@ -0,0 +1 @@ +Fix JIT trace crash when recording function from cleared generator frame. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 36af61412b7417..41323c4f54d9ed 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -5730,8 +5730,11 @@ dummy_func( tier2 op(_RECORD_NOS_GEN_FUNC, (nos, tos -- nos, tos)) { PyObject *obj = PyStackRef_AsPyObjectBorrow(nos); if (PyGen_Check(obj)) { - PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe); - RECORD_VALUE(func); + PyGenObject *gen = (PyGenObject *)obj; + _PyStackRef func = gen->gi_iframe.f_funcobj; + if (!PyStackRef_IsNull(func)) { + RECORD_VALUE(PyStackRef_AsPyObjectBorrow(func)); + } } } diff --git a/Python/record_functions.c.h b/Python/record_functions.c.h index c6709f9a9d6bec..64cafcb326e111 100644 --- a/Python/record_functions.c.h +++ b/Python/record_functions.c.h @@ -32,11 +32,12 @@ void _PyOpcode_RecordFunction_NOS_GEN_FUNC(_PyInterpreterFrame *frame, _PyStackR nos = stack_pointer[-2]; PyObject *obj = PyStackRef_AsPyObjectBorrow(nos); if (PyGen_Check(obj)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe); - stack_pointer = _PyFrame_GetStackPointer(frame); - *recorded_value = (PyObject *)func; - Py_INCREF(*recorded_value); + PyGenObject *gen = (PyGenObject *)obj; + _PyStackRef func = gen->gi_iframe.f_funcobj; + if (!PyStackRef_IsNull(func)) { + *recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(func); + Py_INCREF(*recorded_value); + } } } From 7eb00ad23cf3795c42e9ac0a268387f8d6026ecd Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 25 Feb 2026 18:42:59 +0100 Subject: [PATCH 240/498] gh-144156: move news entry to Library (#145205) --- .../2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Misc/NEWS.d/next/{Core_and_Builtins => Library}/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst (99%) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst b/Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst similarity index 99% rename from Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst rename to Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst index c4a065528512e1..68e59a6276c092 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst +++ b/Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst @@ -1 +1 @@ -Fix the folding of headers by the :mod:`email` library when :rfc:`2047` encoded words are used. Now whitespace is correctly preserved and also correctly added between adjacent encoded words. The latter property was broken by the fix for gh-92081, which mostly fixed previous failures to preserve whitespace. +Fix the folding of headers by the :mod:`email` library when :rfc:`2047` encoded words are used. Now whitespace is correctly preserved and also correctly added between adjacent encoded words. The latter property was broken by the fix for gh-92081, which mostly fixed previous failures to preserve whitespace. From 43fdb7037e76c18d9545ac11b2f1e3e398152ada Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 25 Feb 2026 23:21:05 +0100 Subject: [PATCH 241/498] gh-145037: Fix Emscripten trampoline with emcc >= 4.0.19 (#145038) This undoes a change made as a part of PR 137470, for compatibility with EMSDK 4.0.19. It adds `emscripten_trampoline` field in `pycore_runtime_structs.h` and initializes it from JS initialization code with the wasm-gc based trampoline if possible. Otherwise we fall back to the JS trampoline. --- .../internal/pycore_emscripten_trampoline.h | 3 - Include/internal/pycore_runtime_structs.h | 10 ++ Python/emscripten_trampoline.c | 97 +++++++++++++++---- configure | 2 +- configure.ac | 2 +- 5 files changed, 90 insertions(+), 24 deletions(-) diff --git a/Include/internal/pycore_emscripten_trampoline.h b/Include/internal/pycore_emscripten_trampoline.h index 16916f1a8eb16c..e37c53a64f4a72 100644 --- a/Include/internal/pycore_emscripten_trampoline.h +++ b/Include/internal/pycore_emscripten_trampoline.h @@ -27,9 +27,6 @@ #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) -void -_Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime); - PyObject* _PyEM_TrampolineCall(PyCFunctionWithKeywords func, PyObject* self, diff --git a/Include/internal/pycore_runtime_structs.h b/Include/internal/pycore_runtime_structs.h index f48d203dda00fc..90e6625ad1fc9c 100644 --- a/Include/internal/pycore_runtime_structs.h +++ b/Include/internal/pycore_runtime_structs.h @@ -275,6 +275,16 @@ struct pyruntimestate { struct _types_runtime_state types; struct _Py_time_runtime_state time; +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) + // Used in "Python/emscripten_trampoline.c" to choose between wasm-gc + // trampoline and JavaScript trampoline. + PyObject* (*emscripten_trampoline)(int* success, + PyCFunctionWithKeywords func, + PyObject* self, + PyObject* args, + PyObject* kw); +#endif + /* All the objects that are shared by the runtime's interpreters. */ struct _Py_cached_objects cached_objects; struct _Py_static_objects static_objects; diff --git a/Python/emscripten_trampoline.c b/Python/emscripten_trampoline.c index d61146504d0959..1833311ca74d9d 100644 --- a/Python/emscripten_trampoline.c +++ b/Python/emscripten_trampoline.c @@ -2,20 +2,59 @@ #include // EM_JS, EM_JS_DEPS #include +#include "pycore_runtime.h" // _PyRuntime -EM_JS( -PyObject*, -_PyEM_TrampolineCall_inner, (int* success, - PyCFunctionWithKeywords func, - PyObject *arg1, - PyObject *arg2, - PyObject *arg3), { - // JavaScript fallback trampoline +// We use the _PyRuntime.emscripten_trampoline field to store a function pointer +// for a wasm-gc based trampoline if it works. Otherwise fall back to JS +// trampoline. The JS trampoline breaks stack switching but every runtime that +// supports stack switching also supports wasm-gc. +// +// We'd like to make the trampoline call into a direct call but currently we +// need to import the wasmTable to compile trampolineModule. emcc >= 4.0.19 +// defines the table in WebAssembly and exports it so we won't have access to it +// until after the main module is compiled. +// +// To fix this, one natural solution would be to pass a funcref to the +// trampoline instead of a table index. Several PRs would be needed to fix +// things in llvm and emscripten in order to make this possible. +// +// The performance costs of an extra call_indirect aren't that large anyways. +// The JIT should notice that the target is always the same and turn into a +// check +// +// if (call_target != expected) deoptimize; +// direct_call(call_target, args); + +// Offset of emscripten_trampoline in _PyRuntimeState. There's a couple of +// alternatives: +// +// 1. Just make emscripten_trampoline a real C global variable instead of a +// field of _PyRuntimeState. This would violate our rule against mutable +// globals. +// +// 2. #define a preprocessor constant equal to a hard coded number and make a +// _Static_assert(offsetof(_PyRuntimeState, emscripten_trampoline) == OURCONSTANT) +// This has the disadvantage that we have to update the hard coded constant +// when _PyRuntimeState changes +// +// So putting the mutable constant in _PyRuntime and using a immutable global to +// record the offset so we can access it from JS is probably the best way. +EMSCRIPTEN_KEEPALIVE const int _PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET = offsetof(_PyRuntimeState, emscripten_trampoline); + +typedef PyObject* (*TrampolineFunc)(int* success, + PyCFunctionWithKeywords func, + PyObject* self, + PyObject* args, + PyObject* kw); + +/** + * Backwards compatible trampoline works with all JS runtimes + */ +EM_JS(PyObject*, _PyEM_TrampolineCall_JS, (PyCFunctionWithKeywords func, PyObject *arg1, PyObject *arg2, PyObject *arg3), { return wasmTable.get(func)(arg1, arg2, arg3); } -// Try to replace the JS definition of _PyEM_TrampolineCall_inner with a wasm -// version. -(function () { +// Try to compile wasm-gc trampoline if possible. +function getPyEMTrampolinePtr() { // Starting with iOS 18.3.1, WebKit on iOS has an issue with the garbage // collector that breaks the call trampoline. See #130418 and // https://bugs.webkit.org/show_bug.cgi?id=293113 for details. @@ -27,19 +66,32 @@ _PyEM_TrampolineCall_inner, (int* success, (navigator.platform === 'MacIntel' && typeof navigator.maxTouchPoints !== 'undefined' && navigator.maxTouchPoints > 1) ); if (isIOS) { - return; + return 0; } + let trampolineModule; try { - const trampolineModule = getWasmTrampolineModule(); - const trampolineInstance = new WebAssembly.Instance(trampolineModule, { - env: { __indirect_function_table: wasmTable, memory: wasmMemory }, - }); - _PyEM_TrampolineCall_inner = trampolineInstance.exports.trampoline_call; + trampolineModule = getWasmTrampolineModule(); } catch (e) { // Compilation error due to missing wasm-gc support, fall back to JS // trampoline + return 0; } -})(); + const trampolineInstance = new WebAssembly.Instance(trampolineModule, { + env: { __indirect_function_table: wasmTable, memory: wasmMemory }, + }); + return addFunction(trampolineInstance.exports.trampoline_call); +} +// We have to be careful to work correctly with memory snapshots -- the value of +// _PyRuntimeState.emscripten_trampoline needs to reflect whether wasm-gc is +// available in the current runtime, not in the runtime the snapshot was taken +// in. This writes the appropriate value to +// _PyRuntimeState.emscripten_trampoline from JS startup code that runs every +// time, whether we are restoring a snapshot or not. +addOnPreRun(function setEmscriptenTrampoline() { + const ptr = getPyEMTrampolinePtr(); + const offset = HEAP32[__PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET / 4]; + HEAP32[(__PyRuntime + offset) / 4] = ptr; +}); ); PyObject* @@ -48,12 +100,19 @@ _PyEM_TrampolineCall(PyCFunctionWithKeywords func, PyObject* args, PyObject* kw) { + TrampolineFunc trampoline = _PyRuntime.emscripten_trampoline; + if (trampoline == 0) { + return _PyEM_TrampolineCall_JS(func, self, args, kw); + } int success = 1; - PyObject *result = _PyEM_TrampolineCall_inner(&success, func, self, args, kw); + PyObject *result = trampoline(&success, func, self, args, kw); if (!success) { PyErr_SetString(PyExc_SystemError, "Handler takes too many arguments"); } return result; } +#else +// This is exported so we need to define it even when it isn't used +__attribute__((used)) const int _PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET = 0; #endif diff --git a/configure b/configure index dd62fd90e38ee1..eca5f03cdcfb2d 100755 --- a/configure +++ b/configure @@ -9651,7 +9651,7 @@ fi as_fn_append LINKFORSHARED " -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js" as_fn_append LINKFORSHARED " -sEXPORTED_RUNTIME_METHODS=FS,callMain,ENV,HEAPU32,TTY" - as_fn_append LINKFORSHARED " -sEXPORTED_FUNCTIONS=_main,_Py_Version,__PyRuntime,_PyGILState_GetThisThreadState,__Py_DumpTraceback" + as_fn_append LINKFORSHARED " -sEXPORTED_FUNCTIONS=_main,_Py_Version,__PyRuntime,_PyGILState_GetThisThreadState,__Py_DumpTraceback,__PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET" as_fn_append LINKFORSHARED " -sSTACK_SIZE=5MB" as_fn_append LINKFORSHARED " -sTEXTDECODER=2" diff --git a/configure.ac b/configure.ac index 8b90d8ca896f0c..c21024a1e77433 100644 --- a/configure.ac +++ b/configure.ac @@ -2357,7 +2357,7 @@ AS_CASE([$ac_sys_system], dnl Include file system support AS_VAR_APPEND([LINKFORSHARED], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"]) AS_VAR_APPEND([LINKFORSHARED], [" -sEXPORTED_RUNTIME_METHODS=FS,callMain,ENV,HEAPU32,TTY"]) - AS_VAR_APPEND([LINKFORSHARED], [" -sEXPORTED_FUNCTIONS=_main,_Py_Version,__PyRuntime,_PyGILState_GetThisThreadState,__Py_DumpTraceback"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sEXPORTED_FUNCTIONS=_main,_Py_Version,__PyRuntime,_PyGILState_GetThisThreadState,__Py_DumpTraceback,__PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET"]) AS_VAR_APPEND([LINKFORSHARED], [" -sSTACK_SIZE=5MB"]) dnl Avoid bugs in JS fallback string decoding path AS_VAR_APPEND([LINKFORSHARED], [" -sTEXTDECODER=2"]) From 812ef66759f9fe27d68283d8e67d6cd3eb512be2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 26 Feb 2026 11:30:08 +0200 Subject: [PATCH 242/498] gh-145202: Fix crash in unicodedata's GraphemeBreakIterator and Segment (GH-145216) Remove the tp_clear slots and make Segment members read-only. Also add tests for reference loops involving GraphemeBreakIterator and Segment. --- Lib/test/test_unicodedata.py | 24 ++++++++++++++++++++++++ Modules/unicodedata.c | 20 ++------------------ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 30a26751d3ac54..8ecb0df2f8e5dd 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -12,7 +12,9 @@ import sys import unicodedata import unittest +import weakref from test.support import ( + gc_collect, open_urlresource, requires_resource, script_helper, @@ -1338,6 +1340,28 @@ def run_grapheme_break_tests(self, testdata): self.assertEqual([x.start for x in result], breaks[i:-1], comment) self.assertEqual([x.end for x in result], breaks[i+1:], comment) + def test_reference_loops(self): + # Test that reference loops involving GraphemeBreakIterator or + # Segment can be broken by the garbage collector. + class S(str): + pass + + s = S('abc') + s.ref = unicodedata.iter_graphemes(s) + wr = weakref.ref(s) + del s + self.assertIsNotNone(wr()) + gc_collect() + self.assertIsNone(wr()) + + s = S('abc') + s.ref = next(unicodedata.iter_graphemes(s)) + wr = weakref.ref(s) + del s + self.assertIsNotNone(wr()) + gc_collect() + self.assertIsNone(wr()) + if __name__ == "__main__": unittest.main() diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 401f64e7416944..2c67c23d98ed81 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1925,13 +1925,6 @@ Segment_traverse(PyObject *self, visitproc visit, void *arg) return 0; } -static int -Segment_clear(PyObject *self) -{ - Py_CLEAR(((SegmentObject *)self)->string); - return 0; -} - static PyObject * Segment_str(PyObject *self) { @@ -1947,9 +1940,9 @@ Segment_repr(PyObject *self) } static PyMemberDef Segment_members[] = { - {"start", Py_T_PYSSIZET, offsetof(SegmentObject, start), 0, + {"start", Py_T_PYSSIZET, offsetof(SegmentObject, start), Py_READONLY, PyDoc_STR("grapheme start")}, - {"end", Py_T_PYSSIZET, offsetof(SegmentObject, end), 0, + {"end", Py_T_PYSSIZET, offsetof(SegmentObject, end), Py_READONLY, PyDoc_STR("grapheme end")}, {NULL} /* Sentinel */ }; @@ -1957,7 +1950,6 @@ static PyMemberDef Segment_members[] = { static PyType_Slot Segment_slots[] = { {Py_tp_dealloc, Segment_dealloc}, {Py_tp_traverse, Segment_traverse}, - {Py_tp_clear, Segment_clear}, {Py_tp_str, Segment_str}, {Py_tp_repr, Segment_repr}, {Py_tp_members, Segment_members}, @@ -2001,13 +1993,6 @@ GBI_traverse(PyObject *self, visitproc visit, void *arg) return 0; } -static int -GBI_clear(PyObject *self) -{ - Py_CLEAR(((GraphemeBreakIterator *)self)->iter.str); - return 0; -} - static PyObject * GBI_iternext(PyObject *self) { @@ -2038,7 +2023,6 @@ static PyType_Slot GraphemeBreakIterator_slots[] = { {Py_tp_iter, PyObject_SelfIter}, {Py_tp_iternext, GBI_iternext}, {Py_tp_traverse, GBI_traverse}, - {Py_tp_clear, GBI_clear}, {0, 0}, }; From aa2c0c3acb0e648c055a1f8d373ea3e070f9a4a1 Mon Sep 17 00:00:00 2001 From: Adorilson Bezerra Date: Thu, 26 Feb 2026 13:41:49 +0000 Subject: [PATCH 243/498] gh-106318: Add examples for str.rjust() method (#143890) --- Doc/library/stdtypes.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 21572d6dc71d84..4451d485884987 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2504,6 +2504,19 @@ expression support in the :mod:`re` module). done using the specified *fillchar* (default is an ASCII space). The original string is returned if *width* is less than or equal to ``len(s)``. + For example: + + .. doctest:: + + >>> 'Python'.rjust(10) + ' Python' + >>> 'Python'.rjust(10, '.') + '....Python' + >>> 'Monty Python'.rjust(10, '.') + 'Monty Python' + + See also :meth:`ljust` and :meth:`zfill`. + .. method:: str.rpartition(sep, /) @@ -2828,13 +2841,17 @@ expression support in the :mod:`re` module). than before. The original string is returned if *width* is less than or equal to ``len(s)``. - For example:: + For example: + + .. doctest:: >>> "42".zfill(5) '00042' >>> "-42".zfill(5) '-0042' + See also :meth:`rjust`. + .. index:: single: ! formatted string literal From e234662f7fcc1b4ebd71d7bb9a03be83eaeb9dc2 Mon Sep 17 00:00:00 2001 From: Rajhans Jadhao Date: Thu, 26 Feb 2026 19:17:13 +0530 Subject: [PATCH 244/498] gh-144190: Clarify get_type_hints() instance behavior in docs (#144831) --- Doc/library/typing.rst | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index a0e396983885d2..ef44701bb251dd 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3353,8 +3353,8 @@ Introspection helpers .. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) - Return a dictionary containing type hints for a function, method, module - or class object. + Return a dictionary containing type hints for a function, method, module, + class object, or other callable object. This is often the same as ``obj.__annotations__``, but this function makes the following changes to the annotations dictionary: @@ -3395,6 +3395,13 @@ Introspection helpers :ref:`type aliases ` that include forward references, or with names imported under :data:`if TYPE_CHECKING `. + .. note:: + + Calling :func:`get_type_hints` on an instance is not supported. + To retrieve annotations for an instance, call + :func:`get_type_hints` on the instance's class instead + (for example, ``get_type_hints(type(obj))``). + .. versionchanged:: 3.9 Added ``include_extras`` parameter as part of :pep:`593`. See the documentation on :data:`Annotated` for more information. @@ -3404,6 +3411,11 @@ Introspection helpers if a default value equal to ``None`` was set. Now the annotation is returned unchanged. + .. versionchanged:: 3.14 + Calling :func:`get_type_hints` on instances is no longer supported. + Some instances were accepted in earlier versions as an undocumented + implementation detail. + .. function:: get_origin(tp) Get the unsubscripted version of a type: for a typing object of the form From 4401f23cbf67f286649aebc12633fe3f46ada0d1 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Thu, 26 Feb 2026 17:00:22 +0100 Subject: [PATCH 245/498] gh-141510: Update `PyDict_Copy` documentation with note on `frozendict` (GH-145249) --- Doc/c-api/dict.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 1d74140ea360ba..734462bc0051af 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -82,6 +82,9 @@ Dictionary objects Return a new dictionary that contains the same key-value pairs as *p*. + .. versionchanged:: next + If *p* is a subclass of :class:`frozendict`, the result will be a + :class:`frozendict` instance instead of a :class:`dict` instance. .. c:function:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) From c2d3d6b0dd87aaea2f3a72419e1d1488d3ab9503 Mon Sep 17 00:00:00 2001 From: Taegyun Kim Date: Thu, 26 Feb 2026 22:14:34 +0100 Subject: [PATCH 246/498] gh-144316: Fix missing exception in _remote_debugging with debug=False (#144442) --- .../2026-02-03-19-57-41.gh-issue-144316.wop870.rst | 1 + Modules/_remote_debugging/_remote_debugging.h | 12 ++++++++---- Modules/_remote_debugging/asyncio.c | 1 + Modules/_remote_debugging/code_objects.c | 3 +++ Modules/_remote_debugging/frames.c | 3 +++ Modules/_remote_debugging/module.c | 3 +++ Python/remote_debug.h | 3 ++- 7 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst b/Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst new file mode 100644 index 00000000000000..b9d0749f56ba6a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst @@ -0,0 +1 @@ +Fix crash in ``_remote_debugging`` that caused ``test_external_inspection`` to intermittently fail. Patch by Taegyun Kim. diff --git a/Modules/_remote_debugging/_remote_debugging.h b/Modules/_remote_debugging/_remote_debugging.h index 78add74423b608..7bcb2f483234ec 100644 --- a/Modules/_remote_debugging/_remote_debugging.h +++ b/Modules/_remote_debugging/_remote_debugging.h @@ -29,6 +29,7 @@ extern "C" { #include "internal/pycore_interpframe.h" // FRAME_OWNED_BY_INTERPRETER #include "internal/pycore_llist.h" // struct llist_node #include "internal/pycore_long.h" // _PyLong_GetZero +#include "internal/pycore_pyerrors.h" // _PyErr_FormatFromCause #include "internal/pycore_stackref.h" // Py_TAG_BITS #include "../../Python/remote_debug.h" @@ -173,10 +174,13 @@ typedef enum _WIN32_THREADSTATE { #define THREAD_STATUS_HAS_EXCEPTION (1 << 4) /* Exception cause macro */ -#define set_exception_cause(unwinder, exc_type, message) \ - if (unwinder->debug) { \ - _set_debug_exception_cause(exc_type, message); \ - } +#define set_exception_cause(unwinder, exc_type, message) \ + do { \ + assert(PyErr_Occurred() && "function returned -1 without setting exception"); \ + if (unwinder->debug) { \ + _set_debug_exception_cause(exc_type, message); \ + } \ + } while (0) /* ============================================================================ * TYPE DEFINITIONS diff --git a/Modules/_remote_debugging/asyncio.c b/Modules/_remote_debugging/asyncio.c index fc059659511fd8..69478634de6926 100644 --- a/Modules/_remote_debugging/asyncio.c +++ b/Modules/_remote_debugging/asyncio.c @@ -121,6 +121,7 @@ iterate_set_entries( // Validate mask and num_els to prevent huge loop iterations from garbage data if (mask < 0 || mask >= MAX_SET_TABLE_SIZE || num_els < 0 || num_els > mask + 1) { + PyErr_SetString(PyExc_RuntimeError, "Invalid set object (corrupted remote memory)"); set_exception_cause(unwinder, PyExc_RuntimeError, "Invalid set object (corrupted remote memory)"); return -1; diff --git a/Modules/_remote_debugging/code_objects.c b/Modules/_remote_debugging/code_objects.c index 9b7b4dc22b873b..91f7a02005391a 100644 --- a/Modules/_remote_debugging/code_objects.c +++ b/Modules/_remote_debugging/code_objects.c @@ -446,6 +446,9 @@ parse_code_object(RemoteUnwinderObject *unwinder, if (tlbc_entry) { // Validate index bounds (also catches negative values since tlbc_index is signed) if (ctx->tlbc_index < 0 || ctx->tlbc_index >= tlbc_entry->tlbc_array_size) { + PyErr_Format(PyExc_RuntimeError, + "Invalid tlbc_index %d (array size %zd, corrupted remote memory)", + ctx->tlbc_index, tlbc_entry->tlbc_array_size); set_exception_cause(unwinder, PyExc_RuntimeError, "Invalid tlbc_index (corrupted remote memory)"); goto error; diff --git a/Modules/_remote_debugging/frames.c b/Modules/_remote_debugging/frames.c index 02c48205b85a37..2ace0c0f7676ae 100644 --- a/Modules/_remote_debugging/frames.c +++ b/Modules/_remote_debugging/frames.c @@ -49,6 +49,8 @@ process_single_stack_chunk( // Size must be at least enough for the header and reasonably bounded if (actual_size <= offsetof(_PyStackChunk, data) || actual_size > MAX_STACK_CHUNK_SIZE) { PyMem_RawFree(this_chunk); + PyErr_Format(PyExc_RuntimeError, + "Invalid stack chunk size %zu (corrupted remote memory)", actual_size); set_exception_cause(unwinder, PyExc_RuntimeError, "Invalid stack chunk size (corrupted remote memory)"); return -1; @@ -244,6 +246,7 @@ parse_frame_from_chunks( ) { void *frame_ptr = find_frame_in_chunks(chunks, address); if (!frame_ptr) { + PyErr_Format(PyExc_RuntimeError, "Frame at address 0x%lx not found in stack chunks", address); set_exception_cause(unwinder, PyExc_RuntimeError, "Frame not found in stack chunks"); return -1; } diff --git a/Modules/_remote_debugging/module.c b/Modules/_remote_debugging/module.c index 26ebed13098f0e..040bd3db377315 100644 --- a/Modules/_remote_debugging/module.c +++ b/Modules/_remote_debugging/module.c @@ -595,6 +595,9 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self // Detect cycle: if current_tstate didn't advance, we have corrupted data if (current_tstate == prev_tstate) { Py_DECREF(interpreter_threads); + PyErr_Format(PyExc_RuntimeError, + "Thread list cycle detected at address 0x%lx (corrupted remote memory)", + current_tstate); set_exception_cause(self, PyExc_RuntimeError, "Thread list cycle detected (corrupted remote memory)"); Py_CLEAR(result); diff --git a/Python/remote_debug.h b/Python/remote_debug.h index 4ae1166e885485..7628fb04ba5bae 100644 --- a/Python/remote_debug.h +++ b/Python/remote_debug.h @@ -1302,6 +1302,7 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle, if (entry->data == NULL) { entry->data = PyMem_RawMalloc(page_size); if (entry->data == NULL) { + PyErr_NoMemory(); _set_debug_exception_cause(PyExc_MemoryError, "Cannot allocate %zu bytes for page cache entry " "during read from PID %d at address 0x%lx", @@ -1311,7 +1312,7 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle, } if (_Py_RemoteDebug_ReadRemoteMemory(handle, page_base, page_size, entry->data) < 0) { - // Try to just copy the exact ammount as a fallback + // Try to just copy the exact amount as a fallback PyErr_Clear(); goto fallback; } From f3a381e54fcabb2d8649cbfc2dff9933ee7c4d0b Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 27 Feb 2026 01:02:39 +0300 Subject: [PATCH 247/498] gh-141510: support frozendict's in the C decimal module (gh-145165) --- Lib/test/test_decimal.py | 6 ++++++ Modules/_decimal/_decimal.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index b520b062ebc685..fe8c8ce12da0bf 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -3963,15 +3963,21 @@ def test_flag_comparisons(self): d.update(c.flags) self.assertEqual(d, c.flags) self.assertEqual(c.flags, d) + self.assertEqual(frozendict(d), c.flags) + self.assertEqual(c.flags, frozendict(d)) d[Inexact] = True self.assertNotEqual(d, c.flags) self.assertNotEqual(c.flags, d) + self.assertNotEqual(frozendict(d), c.flags) + self.assertNotEqual(c.flags, frozendict(d)) # Invalid SignalDict d = {Inexact:False} self.assertNotEqual(d, c.flags) self.assertNotEqual(c.flags, d) + self.assertNotEqual(frozendict(d), c.flags) + self.assertNotEqual(c.flags, frozendict(d)) d = ["xyz"] self.assertNotEqual(d, c.flags) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index dcea4da8f24268..c42757e042e7ef 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -552,7 +552,7 @@ dict_as_flags(decimal_state *state, PyObject *val) uint32_t flags = 0; int x; - if (!PyDict_Check(val)) { + if (!PyAnyDict_Check(val)) { PyErr_SetString(PyExc_TypeError, "argument must be a signal dict"); return DEC_INVALID_SIGNALS; @@ -802,7 +802,7 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) if (PyDecSignalDict_Check(state, w)) { res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False; } - else if (PyDict_Check(w)) { + else if (PyAnyDict_Check(w)) { uint32_t flags = dict_as_flags(state, w); if (flags & DEC_ERRORS) { if (flags & DEC_INVALID_SIGNALS) { From 3fc945df22a169e039c3f21b44c0d08390a00c0c Mon Sep 17 00:00:00 2001 From: AdamKorcz <44787359+AdamKorcz@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:35:08 +0000 Subject: [PATCH 248/498] gh-144872: fix heap buffer overflow `_PyTokenizer_ensure_utf8` (#144807) --- Lib/test/test_source_encoding.py | 17 +++++++++++++++++ ...26-02-16-12-28-43.gh-issue-144872.k9_Q30.rst | 1 + Parser/tokenizer/helpers.c | 6 ++++-- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index 46b291192df429..8ac64b3105708f 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -65,6 +65,23 @@ def test_issue7820(self): # two bytes in common with the UTF-8 BOM self.assertRaises(SyntaxError, eval, b'\xef\xbb\x20') + def test_truncated_utf8_at_eof(self): + # Regression test for https://issues.oss-fuzz.com/issues/451112368 + # Truncated multi-byte UTF-8 sequences at end of input caused an + # out-of-bounds read in Parser/tokenizer/helpers.c:valid_utf8(). + truncated = [ + b'\xc2', # 2-byte lead, missing 1 continuation + b'\xdf', # 2-byte lead, missing 1 continuation + b'\xe0', # 3-byte lead, missing 2 continuations + b'\xe0\xa0', # 3-byte lead, missing 1 continuation + b'\xf0\x90', # 4-byte lead, missing 2 continuations + b'\xf0\x90\x80', # 4-byte lead, missing 1 continuation + b'\xf3', # 4-byte lead, missing 3 (the oss-fuzz reproducer) + ] + for seq in truncated: + with self.subTest(seq=seq): + self.assertRaises(SyntaxError, compile, seq, '', 'exec') + @support.requires_subprocess() def test_20731(self): sub = subprocess.Popen([sys.executable, diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst new file mode 100644 index 00000000000000..c06bf01baee6fd --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst @@ -0,0 +1 @@ +Fix heap buffer overflow in the parser found by OSS-Fuzz. diff --git a/Parser/tokenizer/helpers.c b/Parser/tokenizer/helpers.c index fda8216a3005b9..9542969ad3127b 100644 --- a/Parser/tokenizer/helpers.c +++ b/Parser/tokenizer/helpers.c @@ -494,9 +494,11 @@ valid_utf8(const unsigned char* s) return 0; } length = expected + 1; - for (; expected; expected--) - if (s[expected] < 0x80 || s[expected] >= 0xC0) + for (int i = 1; i <= expected; i++) { + if (s[i] < 0x80 || s[i] >= 0xC0) { return 0; + } + } return length; } From 06b0920f1292690a22ab2b271dfefe2c63cacf07 Mon Sep 17 00:00:00 2001 From: "A.Ibrahim" Date: Thu, 26 Feb 2026 23:40:25 +0000 Subject: [PATCH 249/498] gh-142787: Handle empty sqlite3 blob slices (#142824) --- Lib/test/test_sqlite3/test_dbapi.py | 5 +++++ .../Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst | 2 ++ Modules/_sqlite/blob.c | 4 ++++ 3 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 20e39f61e4dedb..73b40e82a96811 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -1379,6 +1379,11 @@ def test_blob_get_slice(self): def test_blob_get_empty_slice(self): self.assertEqual(self.blob[5:5], b"") + def test_blob_get_empty_slice_oob_indices(self): + self.cx.execute("insert into test(b) values (?)", (b"abc",)) + with self.cx.blobopen("test", "b", 2) as blob: + self.assertEqual(blob[5:-5], b"") + def test_blob_get_slice_negative_index(self): self.assertEqual(self.blob[5:-5], self.data[5:-5]) diff --git a/Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst b/Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst new file mode 100644 index 00000000000000..e928bd2cac72a8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst @@ -0,0 +1,2 @@ +Fix assertion failure in :mod:`sqlite3` blob subscript when slicing with +indices that result in an empty slice. diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c index 4a213f348881b9..8dad94556236bd 100644 --- a/Modules/_sqlite/blob.c +++ b/Modules/_sqlite/blob.c @@ -439,6 +439,10 @@ subscript_slice(pysqlite_Blob *self, PyObject *item) return NULL; } + if (len == 0) { + return PyBytes_FromStringAndSize(NULL, 0); + } + if (step == 1) { return read_multiple(self, len, start); } From 6ea84b2726bb6a1a8a6819d30c368ac34c50eabe Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 27 Feb 2026 10:02:19 +0200 Subject: [PATCH 250/498] Fix unlikely potential reference leak in _locale._getdefaultlocale (GH-145250) It occurs in a code which perhaps never executed. --- Modules/_localemodule.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 7174eebd0c94de..f0a418ee5024e3 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -567,7 +567,6 @@ _locale__getdefaultlocale_impl(PyObject *module) } /* cannot determine the language code (very unlikely) */ - Py_INCREF(Py_None); return Py_BuildValue("Os", Py_None, encoding); } #endif From 171e0facc4131f74baec38f58fb0971c52ac2c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=AF=E5=87=9B?= <34085039+mokurin000@users.noreply.github.com> Date: Fri, 27 Feb 2026 18:06:46 +0800 Subject: [PATCH 251/498] gh-123853: Cleanup Windows 95 locale fallback support (#144738) Closes #123853 --- Lib/locale.py | 4 ---- .../2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst | 1 + Modules/_localemodule.c | 11 ----------- 3 files changed, 1 insertion(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst diff --git a/Lib/locale.py b/Lib/locale.py index dea3ee55cf4d24..e7382796905ebd 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -570,10 +570,6 @@ def _getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): except (ImportError, AttributeError): pass else: - # make sure the code/encoding values are valid - if sys.platform == "win32" and code and code[:2] == "0x": - # map windows language identifier to language name - code = windows_locale.get(int(code, 0)) # ...add other platform-specific processing here, if # necessary... return code, encoding diff --git a/Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst b/Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst new file mode 100644 index 00000000000000..1babcbfd8e678a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst @@ -0,0 +1 @@ +Removed Windows 95 compatibility for :func:`locale.getdefaultlocale`. diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index f0a418ee5024e3..86a390e52a554b 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -555,17 +555,6 @@ _locale__getdefaultlocale_impl(PyObject *module) return Py_BuildValue("ss", locale, encoding); } - /* If we end up here, this windows version didn't know about - ISO639/ISO3166 names (it's probably Windows 95). Return the - Windows language identifier instead (a hexadecimal number) */ - - locale[0] = '0'; - locale[1] = 'x'; - if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, - locale+2, sizeof(locale)-2)) { - return Py_BuildValue("ss", locale, encoding); - } - /* cannot determine the language code (very unlikely) */ return Py_BuildValue("Os", Py_None, encoding); } From 98b1e519273dd28ce73cc21a636e2f3a937e1f8c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Fri, 27 Feb 2026 12:44:54 +0000 Subject: [PATCH 252/498] gh-145234: Normalize decoded CR in string tokenizer (#145281) --- Lib/test/test_py_compile.py | 8 ++++++++ .../2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst | 5 +++++ Parser/tokenizer/string_tokenizer.c | 13 +++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 66de61930968e4..da2d630d7ace7b 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -239,6 +239,14 @@ def test_quiet(self): with self.assertRaises(py_compile.PyCompileError): py_compile.compile(bad_coding, self.pyc_path, doraise=True, quiet=1) + def test_utf7_decoded_cr_compiles(self): + with open(self.source_path, 'wb') as file: + file.write(b"#coding=U7+AA0''\n") + + pyc_path = py_compile.compile(self.source_path, self.pyc_path, doraise=True) + self.assertEqual(pyc_path, self.pyc_path) + self.assertTrue(os.path.exists(self.pyc_path)) + class PyCompileTestsWithSourceEpoch(PyCompileTestsBase, unittest.TestCase, diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst new file mode 100644 index 00000000000000..caeffff0be8a85 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst @@ -0,0 +1,5 @@ +Fixed a ``SystemError`` in the parser when an encoding cookie (for example, +UTF-7) decodes to carriage returns (``\r``). Newlines are now normalized after +decoding in the string tokenizer. + +Patch by Pablo Galindo. diff --git a/Parser/tokenizer/string_tokenizer.c b/Parser/tokenizer/string_tokenizer.c index 7299ecf483ccd9..7f07cca37ee019 100644 --- a/Parser/tokenizer/string_tokenizer.c +++ b/Parser/tokenizer/string_tokenizer.c @@ -108,6 +108,19 @@ decode_str(const char *input, int single, struct tok_state *tok, int preserve_cr else if (!_PyTokenizer_ensure_utf8(str, tok, 1)) { return _PyTokenizer_error_ret(tok); } + if (utf8 != NULL) { + char *translated = _PyTokenizer_translate_newlines( + str, single, preserve_crlf, tok); + if (translated == NULL) { + Py_DECREF(utf8); + return _PyTokenizer_error_ret(tok); + } + PyMem_Free(tok->input); + tok->input = translated; + str = translated; + Py_CLEAR(utf8); + } + tok->str = str; assert(tok->decoding_buffer == NULL); tok->decoding_buffer = utf8; /* CAUTION */ return str; From dc1b56aa03a1764e7c6bbcbf190b1c293eb5c462 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 27 Feb 2026 10:11:52 -0500 Subject: [PATCH 253/498] gh-141004: Document missing type flags (GH-145127) --- Doc/c-api/typeobj.rst | 46 ++++++++++++++++++++++++ Tools/check-c-api-docs/ignored_c_api.txt | 3 -- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index bc134b5d00b4ad..87b488912653b9 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1499,6 +1499,52 @@ and :c:data:`PyType_Type` effectively act as defaults.) It will be removed in a future version of CPython + .. c:macro:: Py_TPFLAGS_HAVE_VERSION_TAG + + This is a :term:`soft deprecated` macro that does nothing. + Historically, this would indicate that the + :c:member:`~PyTypeObject.tp_version_tag` field was available and + initialized. + + + .. c:macro:: Py_TPFLAGS_INLINE_VALUES + + This bit indicates that instances of this type will have an "inline values" + array (containing the object's attributes) placed directly after the end + of the object. + + This requires that :c:macro:`Py_TPFLAGS_HAVE_GC` is set. + + **Inheritance:** + + This flag is not inherited. + + .. versionadded:: 3.13 + + + .. c:macro:: Py_TPFLAGS_IS_ABSTRACT + + This bit indicates that this is an abstract type and therefore cannot + be instantiated. + + **Inheritance:** + + This flag is not inherited. + + .. seealso:: + :mod:`abc` + + + .. c:macro:: Py_TPFLAGS_HAVE_STACKLESS_EXTENSION + + Internal. Do not set or unset this flag. + Historically, this was a reserved flag for use in Stackless Python. + + .. warning:: + This flag is present in header files, but is not be used. + This may be removed in a future version of CPython. + + .. c:member:: const char* PyTypeObject.tp_doc .. corresponding-type-slot:: Py_tp_doc diff --git a/Tools/check-c-api-docs/ignored_c_api.txt b/Tools/check-c-api-docs/ignored_c_api.txt index 7bf79872bd4630..02a3031e52fb8b 100644 --- a/Tools/check-c-api-docs/ignored_c_api.txt +++ b/Tools/check-c-api-docs/ignored_c_api.txt @@ -22,9 +22,6 @@ Py_HASH_EXTERNAL PyABIInfo_FREETHREADING_AGNOSTIC # object.h Py_INVALID_SIZE -Py_TPFLAGS_HAVE_VERSION_TAG -Py_TPFLAGS_INLINE_VALUES -Py_TPFLAGS_IS_ABSTRACT # pyexpat.h PyExpat_CAPI_MAGIC PyExpat_CAPSULE_NAME From 8775f900179aa21e6e9ec318dbb5c7cfd3561b66 Mon Sep 17 00:00:00 2001 From: Taegyun Kim Date: Fri, 27 Feb 2026 16:25:46 +0100 Subject: [PATCH 254/498] gh-144693: Clarify that `PyFrame_GetBack` does not raise exceptions (GH-144824) Co-authored-by: Sergey Miryanov Co-authored-by: Peter Bierma --- Doc/c-api/frame.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index fb17cf7f1da6b2..967cfc727655ec 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -50,6 +50,7 @@ See also :ref:`Reflection `. Return a :term:`strong reference`, or ``NULL`` if *frame* has no outer frame. + This raises no exceptions. .. versionadded:: 3.9 From a2497955387bc463f05111b803599a92dcfcae29 Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> Date: Fri, 27 Feb 2026 21:38:15 +0530 Subject: [PATCH 255/498] gh-145142: Make str.maketrans safe under free-threading (gh-145157) --- Lib/test/test_free_threading/test_str.py | 16 ++++ ...-02-23-23-18-28.gh-issue-145142.T-XbVe.rst | 2 + Objects/unicodeobject.c | 76 +++++++++++-------- 3 files changed, 63 insertions(+), 31 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst diff --git a/Lib/test/test_free_threading/test_str.py b/Lib/test/test_free_threading/test_str.py index 72044e979b0f48..9a1ce3620ac4b2 100644 --- a/Lib/test/test_free_threading/test_str.py +++ b/Lib/test/test_free_threading/test_str.py @@ -69,6 +69,22 @@ def reader_func(): for reader in readers: reader.join() + def test_maketrans_dict_concurrent_modification(self): + for _ in range(5): + d = {2000: 'a'} + + def work(dct): + for i in range(100): + str.maketrans(dct) + dct[2000 + i] = chr(i % 16) + dct.pop(2000 + i, None) + + threading_helper.run_concurrently( + work, + nthreads=5, + args=(d,), + ) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst new file mode 100644 index 00000000000000..5f6043cc3d9660 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst @@ -0,0 +1,2 @@ +Fix a crash in the free-threaded build when the dictionary argument to +:meth:`str.maketrans` is concurrently modified. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 988e5f95573fe1..213bae5ca86cd4 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13060,6 +13060,45 @@ unicode_swapcase_impl(PyObject *self) return case_operation(self, do_swapcase); } +static int +unicode_maketrans_from_dict(PyObject *x, PyObject *newdict) +{ + PyObject *key, *value; + Py_ssize_t i = 0; + int res; + while (PyDict_Next(x, &i, &key, &value)) { + if (PyUnicode_Check(key)) { + PyObject *newkey; + int kind; + const void *data; + if (PyUnicode_GET_LENGTH(key) != 1) { + PyErr_SetString(PyExc_ValueError, "string keys in translate" + "table must be of length 1"); + return -1; + } + kind = PyUnicode_KIND(key); + data = PyUnicode_DATA(key); + newkey = PyLong_FromLong(PyUnicode_READ(kind, data, 0)); + if (!newkey) + return -1; + res = PyDict_SetItem(newdict, newkey, value); + Py_DECREF(newkey); + if (res < 0) + return -1; + } + else if (PyLong_Check(key)) { + if (PyDict_SetItem(newdict, key, value) < 0) + return -1; + } + else { + PyErr_SetString(PyExc_TypeError, "keys in translate table must" + "be strings or integers"); + return -1; + } + } + return 0; +} + /*[clinic input] @staticmethod @@ -13145,9 +13184,6 @@ unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z) } } } else { - int kind; - const void *data; - /* x must be a dict */ if (!PyAnyDict_CheckExact(x)) { PyErr_SetString(PyExc_TypeError, "if you give only one argument " @@ -13155,34 +13191,12 @@ unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z) goto err; } /* copy entries into the new dict, converting string keys to int keys */ - while (PyDict_Next(x, &i, &key, &value)) { - if (PyUnicode_Check(key)) { - /* convert string keys to integer keys */ - PyObject *newkey; - if (PyUnicode_GET_LENGTH(key) != 1) { - PyErr_SetString(PyExc_ValueError, "string keys in translate " - "table must be of length 1"); - goto err; - } - kind = PyUnicode_KIND(key); - data = PyUnicode_DATA(key); - newkey = PyLong_FromLong(PyUnicode_READ(kind, data, 0)); - if (!newkey) - goto err; - res = PyDict_SetItem(new, newkey, value); - Py_DECREF(newkey); - if (res < 0) - goto err; - } else if (PyLong_Check(key)) { - /* just keep integer keys */ - if (PyDict_SetItem(new, key, value) < 0) - goto err; - } else { - PyErr_SetString(PyExc_TypeError, "keys in translate table must " - "be strings or integers"); - goto err; - } - } + int errcode; + Py_BEGIN_CRITICAL_SECTION(x); + errcode = unicode_maketrans_from_dict(x, new); + Py_END_CRITICAL_SECTION(); + if (errcode < 0) + goto err; } return new; err: From 11eec7a492670fff67fc083036d595f8498217db Mon Sep 17 00:00:00 2001 From: indoor47 Date: Fri, 27 Feb 2026 17:24:39 +0100 Subject: [PATCH 256/498] gh-145305: Update ocert.org URLs in docs from http to https (#145304) Co-authored-by: Adam (indoor47) --- Doc/reference/datamodel.rst | 2 +- Doc/using/cmdline.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 27aedfa878af9a..cf5a0e71a104eb 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2256,7 +2256,7 @@ Basic customization This is intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict insertion, *O*\ (*n*\ :sup:`2`) complexity. See - http://ocert.org/advisories/ocert-2011-003.html for details. + https://ocert.org/advisories/ocert-2011-003.html for details. Changing hash values affects the iteration order of sets. Python has never made guarantees about this ordering diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 2e7ea7b4fc4cba..93df4fcdc630a5 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -390,7 +390,7 @@ Miscellaneous options Hash randomization is intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict construction, *O*\ (*n*\ :sup:`2`) complexity. See - http://ocert.org/advisories/ocert-2011-003.html for details. + https://ocert.org/advisories/ocert-2011-003.html for details. :envvar:`PYTHONHASHSEED` allows you to set a fixed value for the hash seed secret. From 4d89056ed0f0975e786d859993786a33144cade5 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 27 Feb 2026 18:46:02 +0000 Subject: [PATCH 257/498] gh-76007: Deprecate `tarfile.version` (#145326) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Doc/deprecations/pending-removal-in-3.20.rst | 1 + Doc/whatsnew/3.15.rst | 1 + Lib/tarfile.py | 11 ++++++++++- Lib/test/test_tarfile.py | 10 ++++++++++ .../2026-02-27-18-04-51.gh-issue-76007.17idfK.rst | 2 ++ 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst index 4e4b2e1d5f8fff..8372432a34daa5 100644 --- a/Doc/deprecations/pending-removal-in-3.20.rst +++ b/Doc/deprecations/pending-removal-in-3.20.rst @@ -21,6 +21,7 @@ Pending removal in Python 3.20 - :mod:`re` - :mod:`socketserver` - :mod:`tabnanny` + - :mod:`tarfile` - :mod:`tkinter.font` - :mod:`tkinter.ttk` - :mod:`wsgiref.simple_server` diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 37ebdfee7915fe..163d50d7e20e20 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1549,6 +1549,7 @@ New deprecations - :mod:`re` - :mod:`socketserver` - :mod:`tabnanny` + - :mod:`tarfile` - :mod:`tkinter.font` - :mod:`tkinter.ttk` - :mod:`wsgiref.simple_server` diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 7db3a40c9b33cf..75984bf8b262b9 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -28,7 +28,6 @@ """Read from and write to tar format archives. """ -version = "0.9.0" __author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" __credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." @@ -3137,5 +3136,15 @@ def main(): if args.verbose: print('{!r} file created.'.format(tar_name)) + +def __getattr__(name): + if name == "version": + from warnings import _deprecated + + _deprecated("version", remove=(3, 20)) + return "0.9.0" # Do not change + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + if __name__ == '__main__': main() diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 9892005787c8a6..139840dd9c1f1b 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -4836,6 +4836,16 @@ def test_ignore_invalid_offset_headers(self): self.assertEqual(members[0].offset, expected_offset) +class TestModule(unittest.TestCase): + def test_deprecated_version(self): + with self.assertWarnsRegex( + DeprecationWarning, + "'version' is deprecated and slated for removal in Python 3.20", + ) as cm: + getattr(tarfile, "version") + self.assertEqual(cm.filename, __file__) + + def setUpModule(): os_helper.unlink(TEMPDIR) os.makedirs(TEMPDIR) diff --git a/Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst b/Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst new file mode 100644 index 00000000000000..4bb230dcb8473f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst @@ -0,0 +1,2 @@ +The ``version`` attribute of the :mod:`tarfile` module is deprecated and +slated for removal in Python 3.20. From 72eca2af59043c78647b0e6be3777a947ea9ef0f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 27 Feb 2026 14:09:05 -0500 Subject: [PATCH 258/498] gh-145230: Update lockbench (gh-145231) Remove PyThread_type_lock (now uses PyMutex internally). Add new benchmark options: - work_inside/work_outside: control work inside and outside the critical section to vary contention levels - num_locks: use multiple independent locks with threads assigned round-robin - total_iters: fixed iteration count per thread instead of time-based, useful for measuring fairness - num_acquisitions: lock acquisitions per loop iteration - random_locks: acquire random lock each iteration Also return elapsed time from benchmark_locks() and switch lockbench.py to use argparse. --- .../_testinternalcapi/clinic/test_lock.c.h | 79 +++++++-- Modules/_testinternalcapi/test_lock.c | 159 +++++++++++------- Tools/lockbench/lockbench.py | 81 ++++++--- 3 files changed, 227 insertions(+), 92 deletions(-) diff --git a/Modules/_testinternalcapi/clinic/test_lock.c.h b/Modules/_testinternalcapi/clinic/test_lock.c.h index 86875767343cd2..6e989a777ac7f0 100644 --- a/Modules/_testinternalcapi/clinic/test_lock.c.h +++ b/Modules/_testinternalcapi/clinic/test_lock.c.h @@ -6,8 +6,9 @@ preserve #include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_testinternalcapi_benchmark_locks__doc__, -"benchmark_locks($module, num_threads, use_pymutex=True,\n" -" critical_section_length=1, time_ms=1000, /)\n" +"benchmark_locks($module, num_threads, work_inside=1, work_outside=0,\n" +" time_ms=1000, num_acquisitions=1, total_iters=0,\n" +" num_locks=1, random_locks=False, /)\n" "--\n" "\n"); @@ -17,20 +18,26 @@ PyDoc_STRVAR(_testinternalcapi_benchmark_locks__doc__, static PyObject * _testinternalcapi_benchmark_locks_impl(PyObject *module, Py_ssize_t num_threads, - int use_pymutex, - int critical_section_length, - int time_ms); + int work_inside, int work_outside, + int time_ms, int num_acquisitions, + Py_ssize_t total_iters, + Py_ssize_t num_locks, + int random_locks); static PyObject * _testinternalcapi_benchmark_locks(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_ssize_t num_threads; - int use_pymutex = 1; - int critical_section_length = 1; + int work_inside = 1; + int work_outside = 0; int time_ms = 1000; + int num_acquisitions = 1; + Py_ssize_t total_iters = 0; + Py_ssize_t num_locks = 1; + int random_locks = 0; - if (!_PyArg_CheckPositional("benchmark_locks", nargs, 1, 4)) { + if (!_PyArg_CheckPositional("benchmark_locks", nargs, 1, 8)) { goto exit; } { @@ -48,15 +55,15 @@ _testinternalcapi_benchmark_locks(PyObject *module, PyObject *const *args, Py_ss if (nargs < 2) { goto skip_optional; } - use_pymutex = PyObject_IsTrue(args[1]); - if (use_pymutex < 0) { + work_inside = PyLong_AsInt(args[1]); + if (work_inside == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 3) { goto skip_optional; } - critical_section_length = PyLong_AsInt(args[2]); - if (critical_section_length == -1 && PyErr_Occurred()) { + work_outside = PyLong_AsInt(args[2]); + if (work_outside == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 4) { @@ -66,10 +73,54 @@ _testinternalcapi_benchmark_locks(PyObject *module, PyObject *const *args, Py_ss if (time_ms == -1 && PyErr_Occurred()) { goto exit; } + if (nargs < 5) { + goto skip_optional; + } + num_acquisitions = PyLong_AsInt(args[4]); + if (num_acquisitions == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 6) { + goto skip_optional; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[5]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + total_iters = ival; + } + if (nargs < 7) { + goto skip_optional; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[6]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + num_locks = ival; + } + if (nargs < 8) { + goto skip_optional; + } + random_locks = PyObject_IsTrue(args[7]); + if (random_locks < 0) { + goto exit; + } skip_optional: - return_value = _testinternalcapi_benchmark_locks_impl(module, num_threads, use_pymutex, critical_section_length, time_ms); + return_value = _testinternalcapi_benchmark_locks_impl(module, num_threads, work_inside, work_outside, time_ms, num_acquisitions, total_iters, num_locks, random_locks); exit: return return_value; } -/*[clinic end generated code: output=105105d759c0c271 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6cfed9fc081313ef input=a9049054013a1b77]*/ diff --git a/Modules/_testinternalcapi/test_lock.c b/Modules/_testinternalcapi/test_lock.c index ded76ca9fe6819..596120ef275196 100644 --- a/Modules/_testinternalcapi/test_lock.c +++ b/Modules/_testinternalcapi/test_lock.c @@ -194,65 +194,101 @@ test_lock_counter_slow(PyObject *self, PyObject *obj) Py_RETURN_NONE; } -struct bench_data_locks { - int stop; - int use_pymutex; - int critical_section_length; +struct bench_lock { char padding[200]; - PyThread_type_lock lock; PyMutex m; double value; - Py_ssize_t total_iters; +}; + +struct bench_config { + int stop; + int work_inside; + int work_outside; + int num_acquisitions; + int random_locks; + Py_ssize_t target_iters; + Py_ssize_t num_locks; + struct bench_lock *locks; }; struct bench_thread_data { - struct bench_data_locks *bench_data; + struct bench_config *config; + struct bench_lock *lock; + uint64_t rng_state; Py_ssize_t iters; PyEvent done; }; +static uint64_t +splitmix64(uint64_t *state) +{ + uint64_t z = (*state += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); +} + static void thread_benchmark_locks(void *arg) { - struct bench_thread_data *thread_data = arg; - struct bench_data_locks *bench_data = thread_data->bench_data; - int use_pymutex = bench_data->use_pymutex; - int critical_section_length = bench_data->critical_section_length; - + struct bench_thread_data *td = arg; + struct bench_config *config = td->config; + int work_inside = config->work_inside; + int work_outside = config->work_outside; + int num_acquisitions = config->num_acquisitions; + Py_ssize_t target_iters = config->target_iters; + uint64_t rng_state = td->rng_state; + + double local_value = 0.0; double my_value = 1.0; Py_ssize_t iters = 0; - while (!_Py_atomic_load_int_relaxed(&bench_data->stop)) { - if (use_pymutex) { - PyMutex_Lock(&bench_data->m); - for (int i = 0; i < critical_section_length; i++) { - bench_data->value += my_value; - my_value = bench_data->value; + for (;;) { + if (target_iters > 0) { + if (iters >= target_iters) { + break; } - PyMutex_Unlock(&bench_data->m); } - else { - PyThread_acquire_lock(bench_data->lock, 1); - for (int i = 0; i < critical_section_length; i++) { - bench_data->value += my_value; - my_value = bench_data->value; + else if (_Py_atomic_load_int_relaxed(&config->stop)) { + break; + } + struct bench_lock *lock = td->lock; + if (config->random_locks) { + uint32_t r = (uint32_t)splitmix64(&rng_state); + // Fast modulo reduction to pick a random lock, adapted from: + // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ + Py_ssize_t idx = ((uint64_t)r * (uint32_t)config->num_locks) >> 32; + lock = &config->locks[idx]; + } + for (int acq = 0; acq < num_acquisitions; acq++) { + PyMutex_Lock(&lock->m); + for (int i = 0; i < work_inside; i++) { + lock->value += my_value; + my_value = lock->value; } - PyThread_release_lock(bench_data->lock); + PyMutex_Unlock(&lock->m); } - iters++; + for (int i = 0; i < work_outside; i++) { + local_value += my_value; + my_value = local_value; + } + iters += num_acquisitions; } - thread_data->iters = iters; - _Py_atomic_add_ssize(&bench_data->total_iters, iters); - _PyEvent_Notify(&thread_data->done); + td->iters = iters; + _PyEvent_Notify(&td->done); } /*[clinic input] _testinternalcapi.benchmark_locks num_threads: Py_ssize_t - use_pymutex: bool = True - critical_section_length: int = 1 + work_inside: int = 1 + work_outside: int = 0 time_ms: int = 1000 + num_acquisitions: int = 1 + total_iters: Py_ssize_t = 0 + num_locks: Py_ssize_t = 1 + random_locks: bool = False / [clinic start generated code]*/ @@ -260,10 +296,12 @@ _testinternalcapi.benchmark_locks static PyObject * _testinternalcapi_benchmark_locks_impl(PyObject *module, Py_ssize_t num_threads, - int use_pymutex, - int critical_section_length, - int time_ms) -/*[clinic end generated code: output=381df8d7e9a74f18 input=f3aeaf688738c121]*/ + int work_inside, int work_outside, + int time_ms, int num_acquisitions, + Py_ssize_t total_iters, + Py_ssize_t num_locks, + int random_locks) +/*[clinic end generated code: output=6258dc9de8cb9af1 input=d622cf4e1c4d008b]*/ { // Run from Tools/lockbench/lockbench.py // Based on the WebKit lock benchmarks: @@ -271,24 +309,28 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module, // See also https://webkit.org/blog/6161/locking-in-webkit/ PyObject *thread_iters = NULL; PyObject *res = NULL; + struct bench_thread_data *thread_data = NULL; - struct bench_data_locks bench_data; - memset(&bench_data, 0, sizeof(bench_data)); - bench_data.use_pymutex = use_pymutex; - bench_data.critical_section_length = critical_section_length; - - bench_data.lock = PyThread_allocate_lock(); - if (bench_data.lock == NULL) { - return PyErr_NoMemory(); + struct bench_config config = { + .work_inside = work_inside, + .work_outside = work_outside, + .num_acquisitions = num_acquisitions, + .target_iters = total_iters, + .num_locks = num_locks, + .random_locks = random_locks, + }; + + config.locks = PyMem_Calloc(num_locks, sizeof(*config.locks)); + if (config.locks == NULL) { + PyErr_NoMemory(); + goto exit; } - struct bench_thread_data *thread_data = NULL; thread_data = PyMem_Calloc(num_threads, sizeof(*thread_data)); if (thread_data == NULL) { PyErr_NoMemory(); goto exit; } - thread_iters = PyList_New(num_threads); if (thread_iters == NULL) { goto exit; @@ -300,40 +342,43 @@ _testinternalcapi_benchmark_locks_impl(PyObject *module, } for (Py_ssize_t i = 0; i < num_threads; i++) { - thread_data[i].bench_data = &bench_data; + thread_data[i].config = &config; + thread_data[i].lock = &config.locks[i % num_locks]; + thread_data[i].rng_state = (uint64_t)i + 1; PyThread_start_new_thread(thread_benchmark_locks, &thread_data[i]); } - // Let the threads run for `time_ms` milliseconds - pysleep(time_ms); - _Py_atomic_store_int(&bench_data.stop, 1); + if (total_iters == 0) { + pysleep(time_ms); + _Py_atomic_store_int(&config.stop, 1); + } - // Wait for the threads to finish for (Py_ssize_t i = 0; i < num_threads; i++) { PyEvent_Wait(&thread_data[i].done); } - Py_ssize_t total_iters = bench_data.total_iters; if (PyTime_PerfCounter(&end) < 0) { goto exit; } - // Return the total number of acquisitions and the number of acquisitions - // for each thread. + Py_ssize_t sum_iters = 0; for (Py_ssize_t i = 0; i < num_threads; i++) { PyObject *iter = PyLong_FromSsize_t(thread_data[i].iters); if (iter == NULL) { goto exit; } PyList_SET_ITEM(thread_iters, i, iter); + sum_iters += thread_data[i].iters; } assert(end != start); - double rate = total_iters * 1e9 / (end - start); - res = Py_BuildValue("(dO)", rate, thread_iters); + PyTime_t elapsed_ns = end - start; + double rate = sum_iters * 1e9 / elapsed_ns; + res = Py_BuildValue("(dOL)", rate, thread_iters, + (long long)elapsed_ns); exit: - PyThread_free_lock(bench_data.lock); + PyMem_Free(config.locks); PyMem_Free(thread_data); Py_XDECREF(thread_iters); return res; @@ -344,7 +389,7 @@ test_lock_benchmark(PyObject *module, PyObject *obj) { // Just make sure the benchmark runs without crashing PyObject *res = _testinternalcapi_benchmark_locks_impl( - module, 1, 1, 1, 100); + module, 1, 1, 0, 100, 1, 0, 1, 0); if (res == NULL) { return NULL; } diff --git a/Tools/lockbench/lockbench.py b/Tools/lockbench/lockbench.py index 9833d703e00cbb..d2608797f3a4d5 100644 --- a/Tools/lockbench/lockbench.py +++ b/Tools/lockbench/lockbench.py @@ -1,14 +1,28 @@ -# Measure the performance of PyMutex and PyThread_type_lock locks -# with short critical sections. +# Measure the performance of PyMutex locks with short critical sections. # -# Usage: python Tools/lockbench/lockbench.py [CRITICAL_SECTION_LENGTH] +# Usage: python Tools/lockbench/lockbench.py [options] +# +# Options: +# --work-inside N Units of work inside the critical section (default: 1). +# --work-outside N Units of work outside the critical section (default: 0). +# Each unit of work is a dependent floating-point +# addition, which takes about 0.4 ns on modern +# Intel / AMD processors. +# --num-locks N Number of independent locks (default: 1). Threads are +# assigned to locks round-robin. +# --random-locks Each thread picks a random lock per acquisition instead +# of using a fixed assignment. Requires --num-locks > 1. +# --acquisitions N Lock acquisitions per loop iteration (default: 1). +# --total-iters N Fixed iterations per thread (default: 0 = time-based). +# Useful for measuring fairness: the benchmark runs until +# the slowest thread finishes. # # How to interpret the results: # # Acquisitions (kHz): Reports the total number of lock acquisitions in # thousands of acquisitions per second. This is the most important metric, # particularly for the 1 thread case because even in multithreaded programs, -# most locks acquisitions are not contended. Values for 2+ threads are +# most lock acquisitions are not contended. Values for 2+ threads are # only meaningful for `--disable-gil` builds, because the GIL prevents most # situations where there is lock contention with short critical sections. # @@ -19,14 +33,15 @@ # See https://en.wikipedia.org/wiki/Fairness_measure#Jain's_fairness_index from _testinternalcapi import benchmark_locks -import sys - -# Max number of threads to test -MAX_THREADS = 10 +import argparse -# How much "work" to do while holding the lock -CRITICAL_SECTION_LENGTH = 1 +def parse_threads(value): + if '-' in value: + lo, hi = value.split('-', 1) + lo, hi = int(lo), int(hi) + return range(lo, hi + 1) + return range(int(value), int(value) + 1) def jains_fairness(values): # Jain's fairness index @@ -34,20 +49,44 @@ def jains_fairness(values): return (sum(values) ** 2) / (len(values) * sum(x ** 2 for x in values)) def main(): - print("Lock Type Threads Acquisitions (kHz) Fairness") - for lock_type in ["PyMutex", "PyThread_type_lock"]: - use_pymutex = (lock_type == "PyMutex") - for num_threads in range(1, MAX_THREADS + 1): - acquisitions, thread_iters = benchmark_locks( - num_threads, use_pymutex, CRITICAL_SECTION_LENGTH) + parser = argparse.ArgumentParser(description="Benchmark PyMutex locks") + parser.add_argument("--work-inside", type=int, default=1, + help="units of work inside the critical section") + parser.add_argument("--work-outside", type=int, default=0, + help="units of work outside the critical section") + parser.add_argument("--acquisitions", type=int, default=1, + help="lock acquisitions per loop iteration") + parser.add_argument("--total-iters", type=int, default=0, + help="fixed iterations per thread (0 = time-based)") + parser.add_argument("--num-locks", type=int, default=1, + help="number of independent locks (round-robin assignment)") + parser.add_argument("--random-locks", action="store_true", + help="pick a random lock per acquisition") + parser.add_argument("threads", type=parse_threads, nargs='?', + default=range(1, 11), + help="Number of threads: N or MIN-MAX (default: 1-10)") + args = parser.parse_args() + + header = f"{'Threads': <10}{'Acq (kHz)': >12}{'Fairness': >10}" + if args.total_iters: + header += f"{'Wall (ms)': >12}" + print(header) + for num_threads in args.threads: + acquisitions, thread_iters, elapsed_ns = \ + benchmark_locks( + num_threads, args.work_inside, args.work_outside, + 1000, args.acquisitions, args.total_iters, + args.num_locks, args.random_locks) - acquisitions /= 1000 # report in kHz for readability - fairness = jains_fairness(thread_iters) + wall_ms = elapsed_ns / 1e6 + acquisitions /= 1000 # report in kHz for readability + fairness = jains_fairness(thread_iters) - print(f"{lock_type: <20}{num_threads: <18}{acquisitions: >5.0f}{fairness: >20.2f}") + line = f"{num_threads: <10}{acquisitions: >12.0f}{fairness: >10.2f}" + if args.total_iters: + line += f"{wall_ms: >12.1f}" + print(line) if __name__ == "__main__": - if len(sys.argv) > 1: - CRITICAL_SECTION_LENGTH = int(sys.argv[1]) main() From 180d58cbcc0f7f34d6ba6186abf9c6399bd12433 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Fri, 27 Feb 2026 16:23:12 -0800 Subject: [PATCH 259/498] GH-144533: Use wasmtime's --argv0 to auto-discover sysconfig in WASI builds (#145328) --- ...-02-27-18-10-02.gh-issue-144533.21fk9L.rst | 1 + Platforms/WASI/__main__.py | 19 +++---------------- 2 files changed, 4 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst diff --git a/Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst b/Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst new file mode 100644 index 00000000000000..d6e0201b90c550 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst @@ -0,0 +1 @@ +Use wasmtime's ``--argv0`` to auto-discover sysconfig in WASI builds diff --git a/Platforms/WASI/__main__.py b/Platforms/WASI/__main__.py index 8302432fd2f106..471ac3297b2702 100644 --- a/Platforms/WASI/__main__.py +++ b/Platforms/WASI/__main__.py @@ -317,21 +317,8 @@ def configure_wasi_python(context, working_dir): wasi_build_dir = working_dir.relative_to(CHECKOUT) - python_build_dir = BUILD_DIR / "build" - lib_dirs = list(python_build_dir.glob("lib.*")) - assert len(lib_dirs) == 1, ( - f"Expected a single lib.* directory in {python_build_dir}" - ) - lib_dir = os.fsdecode(lib_dirs[0]) - python_version = lib_dir.rpartition("-")[-1] - sysconfig_data_dir = ( - f"{wasi_build_dir}/build/lib.wasi-wasm32-{python_version}" - ) - - # Use PYTHONPATH to include sysconfig data which must be anchored to the - # WASI guest's `/` directory. args = { - "PYTHONPATH": f"/{sysconfig_data_dir}", + "ARGV0": f"/{wasi_build_dir}/python.wasm", "PYTHON_WASM": working_dir / "python.wasm", } # Check dynamically for wasmtime in case it was specified manually via @@ -421,8 +408,8 @@ def main(): default_host_triple = config["targets"]["host-triple"] default_host_runner = ( f"{WASMTIME_HOST_RUNNER_VAR} run " - # For setting PYTHONPATH to the sysconfig data directory. - "--env PYTHONPATH={PYTHONPATH} " + # Set argv0 so that getpath.py can auto-discover the sysconfig data directory + "--argv0 {ARGV0} " # Map the checkout to / to load the stdlib from /Lib. f"--dir {os.fsdecode(CHECKOUT)}::/ " # Flags involving --optimize, --codegen, --debug, --wasm, and --wasi can be kept From a66d51876d0cae6350d2a1729cabc5a56203cc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Sat, 28 Feb 2026 02:44:50 +0100 Subject: [PATCH 260/498] gh-145334: Make lazy import tests discoverable (#145336) --- .github/CODEOWNERS | 3 +- Lib/test/.ruff.toml | 5 +- .../lazy_imports/basic_compatibility_mode.py | 2 - .../basic_compatibility_mode_relative.py | 2 - .../basic_compatibility_mode_used.py | 3 - .../data/lazy_imports/basic_dir.py | 2 - .../data/lazy_imports/basic_from_unused.py | 1 - .../data/lazy_imports/basic_unused.py | 1 - .../data/lazy_imports/basic_used.py | 3 - .../lazy_imports/compatibility_mode_func.py | 5 - .../compatibility_mode_try_except.py | 5 - .../data/lazy_imports/dunder_lazy_import.py | 1 - .../lazy_imports/dunder_lazy_import_used.py | 3 - .../data/lazy_imports/eager_import_func.py | 3 - .../data/lazy_imports/global_off.py | 5 - .../data/lazy_imports/global_on.py | 5 - .../data/lazy_imports/lazy_compat_from.py | 6 - .../data/lazy_imports/lazy_import_pkg.py | 2 - .../data/lazy_imports/lazy_with.py | 3 - .../data/lazy_imports/lazy_with_from.py | 3 - .../data/lazy_imports/modules_dict.py | 5 - .../data/lazy_imports/modules_getattr.py | 5 - .../lazy_imports/modules_getattr_other.py | 5 - .../data/lazy_imports/try_except_eager.py | 4 - .../lazy_imports/try_except_eager_from.py | 4 - .../__init__.py} | 325 +++++++++--------- .../data}/badsyntax/lazy_class_body.py | 0 .../data}/badsyntax/lazy_future_import.py | 0 .../data}/badsyntax/lazy_import_func.py | 0 .../data}/badsyntax/lazy_try_except.py | 0 .../data}/badsyntax/lazy_try_except_from.py | 0 .../badsyntax/lazy_try_except_from_star.py | 0 .../data}/basic2.py | 0 .../data/basic_compatibility_mode.py | 2 + .../data/basic_compatibility_mode_relative.py | 2 + .../data/basic_compatibility_mode_used.py | 3 + Lib/test/test_lazy_import/data/basic_dir.py | 2 + .../data/basic_from_unused.py | 1 + .../test_lazy_import/data/basic_unused.py | 1 + Lib/test/test_lazy_import/data/basic_used.py | 3 + .../data}/broken_attr_module.py | 0 .../data}/broken_module.py | 0 .../data/compatibility_mode_func.py | 5 + .../data/compatibility_mode_try_except.py | 5 + .../data/dunder_lazy_import.py | 1 + .../data}/dunder_lazy_import_builtins.py | 2 +- .../data/dunder_lazy_import_used.py | 3 + .../data/eager_import_func.py | 3 + .../data}/global_filter.py | 4 +- .../data}/global_filter_from.py | 4 +- .../data}/global_filter_from_true.py | 4 +- .../data}/global_filter_true.py | 4 +- Lib/test/test_lazy_import/data/global_off.py | 5 + Lib/test/test_lazy_import/data/global_on.py | 5 + .../data}/globals_access.py | 2 +- .../test_lazy_import/data/lazy_compat_from.py | 6 + .../data}/lazy_get_value.py | 2 +- .../test_lazy_import/data/lazy_import_pkg.py | 2 + Lib/test/test_lazy_import/data/lazy_with.py | 3 + .../test_lazy_import/data/lazy_with_from.py | 3 + .../test_lazy_import/data/modules_dict.py | 5 + .../test_lazy_import/data/modules_getattr.py | 5 + .../data/modules_getattr_other.py | 5 + .../data}/multi_from_import.py | 2 +- .../data}/pkg/__init__.py | 0 .../data}/pkg/b.py | 0 .../data}/pkg/bar.py | 0 .../data}/pkg/c.py | 0 .../data}/relative_lazy.py | 0 .../data}/relative_lazy_from.py | 0 .../test_lazy_import/data/try_except_eager.py | 4 + .../data/try_except_eager_from.py | 4 + Lib/test/test_traceback.py | 12 +- Makefile.pre.in | 7 +- 74 files changed, 273 insertions(+), 259 deletions(-) delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_dir.py delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_from_unused.py delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_unused.py delete mode 100644 Lib/test/test_import/data/lazy_imports/basic_used.py delete mode 100644 Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py delete mode 100644 Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py delete mode 100644 Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py delete mode 100644 Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py delete mode 100644 Lib/test/test_import/data/lazy_imports/eager_import_func.py delete mode 100644 Lib/test/test_import/data/lazy_imports/global_off.py delete mode 100644 Lib/test/test_import/data/lazy_imports/global_on.py delete mode 100644 Lib/test/test_import/data/lazy_imports/lazy_compat_from.py delete mode 100644 Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py delete mode 100644 Lib/test/test_import/data/lazy_imports/lazy_with.py delete mode 100644 Lib/test/test_import/data/lazy_imports/lazy_with_from.py delete mode 100644 Lib/test/test_import/data/lazy_imports/modules_dict.py delete mode 100644 Lib/test/test_import/data/lazy_imports/modules_getattr.py delete mode 100644 Lib/test/test_import/data/lazy_imports/modules_getattr_other.py delete mode 100644 Lib/test/test_import/data/lazy_imports/try_except_eager.py delete mode 100644 Lib/test/test_import/data/lazy_imports/try_except_eager_from.py rename Lib/test/{test_import/test_lazy_imports.py => test_lazy_import/__init__.py} (82%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/badsyntax/lazy_class_body.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/badsyntax/lazy_future_import.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/badsyntax/lazy_import_func.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/badsyntax/lazy_try_except.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/badsyntax/lazy_try_except_from.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/badsyntax/lazy_try_except_from_star.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/basic2.py (100%) create mode 100644 Lib/test/test_lazy_import/data/basic_compatibility_mode.py create mode 100644 Lib/test/test_lazy_import/data/basic_compatibility_mode_relative.py create mode 100644 Lib/test/test_lazy_import/data/basic_compatibility_mode_used.py create mode 100644 Lib/test/test_lazy_import/data/basic_dir.py create mode 100644 Lib/test/test_lazy_import/data/basic_from_unused.py create mode 100644 Lib/test/test_lazy_import/data/basic_unused.py create mode 100644 Lib/test/test_lazy_import/data/basic_used.py rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/broken_attr_module.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/broken_module.py (100%) create mode 100644 Lib/test/test_lazy_import/data/compatibility_mode_func.py create mode 100644 Lib/test/test_lazy_import/data/compatibility_mode_try_except.py create mode 100644 Lib/test/test_lazy_import/data/dunder_lazy_import.py rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/dunder_lazy_import_builtins.py (76%) create mode 100644 Lib/test/test_lazy_import/data/dunder_lazy_import_used.py create mode 100644 Lib/test/test_lazy_import/data/eager_import_func.py rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/global_filter.py (52%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/global_filter_from.py (58%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/global_filter_from_true.py (61%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/global_filter_true.py (57%) create mode 100644 Lib/test/test_lazy_import/data/global_off.py create mode 100644 Lib/test/test_lazy_import/data/global_on.py rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/globals_access.py (72%) create mode 100644 Lib/test/test_lazy_import/data/lazy_compat_from.py rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/lazy_get_value.py (50%) create mode 100644 Lib/test/test_lazy_import/data/lazy_import_pkg.py create mode 100644 Lib/test/test_lazy_import/data/lazy_with.py create mode 100644 Lib/test/test_lazy_import/data/lazy_with_from.py create mode 100644 Lib/test/test_lazy_import/data/modules_dict.py create mode 100644 Lib/test/test_lazy_import/data/modules_getattr.py create mode 100644 Lib/test/test_lazy_import/data/modules_getattr_other.py rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/multi_from_import.py (64%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/pkg/__init__.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/pkg/b.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/pkg/bar.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/pkg/c.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/relative_lazy.py (100%) rename Lib/test/{test_import/data/lazy_imports => test_lazy_import/data}/relative_lazy_from.py (100%) create mode 100644 Lib/test/test_lazy_import/data/try_except_eager.py create mode 100644 Lib/test/test_lazy_import/data/try_except_eager_from.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f33196bb0eb168..0f5d830b512865 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -298,8 +298,7 @@ InternalDocs/jit.md @brandtbucher @savannahostrowski @diegorusso @AA-T # Lazy imports (PEP 810) Objects/lazyimportobject.c @yhg1s @DinoV @pablogsal Include/internal/pycore_lazyimportobject.h @yhg1s @DinoV @pablogsal -Lib/test/test_import/test_lazy_imports.py @yhg1s @DinoV @pablogsal -Lib/test/test_import/data/lazy_imports/ @yhg1s @DinoV @pablogsal +Lib/test/test_lazy_import @yhg1s @DinoV @pablogsal # Micro-op / μop / Tier 2 Optimiser Python/optimizer.c @markshannon @Fidget-Spinner diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml index b5be4c3afaf958..f3e6a46663e100 100644 --- a/Lib/test/.ruff.toml +++ b/Lib/test/.ruff.toml @@ -15,8 +15,9 @@ extend-exclude = [ # and tests re-use the same names as only the grammar is being checked. "test_grammar.py", # Lazy import syntax (PEP 810) is not yet supported by Ruff - "test_import/data/lazy_imports/*.py", - "test_import/data/lazy_imports/**/*.py", + "test_lazy_import/__init__.py", + "test_lazy_import/data/*.py", + "test_lazy_import/data/**/*.py", ] [lint] diff --git a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py deleted file mode 100644 index 5076fa4894ebd6..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode.py +++ /dev/null @@ -1,2 +0,0 @@ -__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] -import test.test_import.data.lazy_imports.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py deleted file mode 100644 index e37759348f3e91..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_relative.py +++ /dev/null @@ -1,2 +0,0 @@ -__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] -lazy from .basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py b/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py deleted file mode 100644 index 64f36645f68790..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_compatibility_mode_used.py +++ /dev/null @@ -1,3 +0,0 @@ -__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] -import test.test_import.data.lazy_imports.basic2 -test.test_import.data.lazy_imports.basic2.f() diff --git a/Lib/test/test_import/data/lazy_imports/basic_dir.py b/Lib/test/test_import/data/lazy_imports/basic_dir.py deleted file mode 100644 index ca9e29d3d9962e..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_dir.py +++ /dev/null @@ -1,2 +0,0 @@ -lazy import test.test_import.data.lazy_imports.basic2 -x = dir() diff --git a/Lib/test/test_import/data/lazy_imports/basic_from_unused.py b/Lib/test/test_import/data/lazy_imports/basic_from_unused.py deleted file mode 100644 index 686caa86a6caa7..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_from_unused.py +++ /dev/null @@ -1 +0,0 @@ -lazy from test.test_import.data.lazy_imports import basic2 diff --git a/Lib/test/test_import/data/lazy_imports/basic_unused.py b/Lib/test/test_import/data/lazy_imports/basic_unused.py deleted file mode 100644 index bf8ae4613e4478..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_unused.py +++ /dev/null @@ -1 +0,0 @@ -lazy import test.test_import.data.lazy_imports.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/basic_used.py b/Lib/test/test_import/data/lazy_imports/basic_used.py deleted file mode 100644 index 84e354750f8ea2..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/basic_used.py +++ /dev/null @@ -1,3 +0,0 @@ -lazy import test.test_import.data.lazy_imports.basic2 as basic2 - -basic2.f() diff --git a/Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py b/Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py deleted file mode 100644 index 307338a0886ac3..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/compatibility_mode_func.py +++ /dev/null @@ -1,5 +0,0 @@ -__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] -def f(): - import test.test_import.data.lazy_imports.basic2 - -f() diff --git a/Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py b/Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py deleted file mode 100644 index 6d54e69a9a4268..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/compatibility_mode_try_except.py +++ /dev/null @@ -1,5 +0,0 @@ -__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] -try: - import test.test_import.data.lazy_imports.basic2 -except: - pass diff --git a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py deleted file mode 100644 index 1a8a19c3c90814..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import.py +++ /dev/null @@ -1 +0,0 @@ -basic = __lazy_import__('test.test_import.data.lazy_imports.basic2') diff --git a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py b/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py deleted file mode 100644 index 2432ca17b16287..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_used.py +++ /dev/null @@ -1,3 +0,0 @@ -basic = __lazy_import__('test.test_import.data.lazy_imports', - fromlist=("basic2", )) -basic diff --git a/Lib/test/test_import/data/lazy_imports/eager_import_func.py b/Lib/test/test_import/data/lazy_imports/eager_import_func.py deleted file mode 100644 index 89e643ac183e9b..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/eager_import_func.py +++ /dev/null @@ -1,3 +0,0 @@ -def f(): - import test.test_import.data.lazy_imports.basic2 as basic2 - return basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_off.py b/Lib/test/test_import/data/lazy_imports/global_off.py deleted file mode 100644 index 4f202744a9ed42..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/global_off.py +++ /dev/null @@ -1,5 +0,0 @@ -import sys - -sys.set_lazy_imports("none") - -lazy import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_on.py b/Lib/test/test_import/data/lazy_imports/global_on.py deleted file mode 100644 index 3f8e1d2aa01380..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/global_on.py +++ /dev/null @@ -1,5 +0,0 @@ -import sys - -sys.set_lazy_imports("all") - -import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/lazy_compat_from.py b/Lib/test/test_import/data/lazy_imports/lazy_compat_from.py deleted file mode 100644 index f887f47b92c3f4..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/lazy_compat_from.py +++ /dev/null @@ -1,6 +0,0 @@ -# Test __lazy_modules__ with from imports -__lazy_modules__ = ['test.test_import.data.lazy_imports.basic2'] -from test.test_import.data.lazy_imports.basic2 import x, f - -def get_x(): - return x diff --git a/Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py b/Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py deleted file mode 100644 index 79aa9a567398bb..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/lazy_import_pkg.py +++ /dev/null @@ -1,2 +0,0 @@ -lazy import test.test_import.data.lazy_imports.pkg.bar -x = test.test_import.data.lazy_imports.pkg.bar.f diff --git a/Lib/test/test_import/data/lazy_imports/lazy_with.py b/Lib/test/test_import/data/lazy_imports/lazy_with.py deleted file mode 100644 index b383879936a219..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/lazy_with.py +++ /dev/null @@ -1,3 +0,0 @@ -import contextlib -with contextlib.nullcontext(): - lazy import test.test_import.data.lazy_imports.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/lazy_with_from.py b/Lib/test/test_import/data/lazy_imports/lazy_with_from.py deleted file mode 100644 index 7936326a9e3d35..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/lazy_with_from.py +++ /dev/null @@ -1,3 +0,0 @@ -import contextlib -with contextlib.nullcontext(): - lazy import test.test_import.data.lazy_imports.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/modules_dict.py b/Lib/test/test_import/data/lazy_imports/modules_dict.py deleted file mode 100644 index 327f866398c86d..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/modules_dict.py +++ /dev/null @@ -1,5 +0,0 @@ -lazy import test.test_import.data.lazy_imports.basic2 as basic2 - -import sys -mod = sys.modules[__name__] -x = mod.__dict__ diff --git a/Lib/test/test_import/data/lazy_imports/modules_getattr.py b/Lib/test/test_import/data/lazy_imports/modules_getattr.py deleted file mode 100644 index ae1d4bb3f976ea..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/modules_getattr.py +++ /dev/null @@ -1,5 +0,0 @@ -lazy import test.test_import.data.lazy_imports.basic2 as basic2 - -import sys -mod = sys.modules[__name__] -x = mod.basic2 diff --git a/Lib/test/test_import/data/lazy_imports/modules_getattr_other.py b/Lib/test/test_import/data/lazy_imports/modules_getattr_other.py deleted file mode 100644 index e4d83e6336db72..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/modules_getattr_other.py +++ /dev/null @@ -1,5 +0,0 @@ -lazy import test.test_import.data.lazy_imports.basic2 as basic2 - -import sys -mod = sys.modules[__name__] -x = mod.__name__ diff --git a/Lib/test/test_import/data/lazy_imports/try_except_eager.py b/Lib/test/test_import/data/lazy_imports/try_except_eager.py deleted file mode 100644 index 4cdaa9a9b48eae..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/try_except_eager.py +++ /dev/null @@ -1,4 +0,0 @@ -try: - import test.test_import.data.lazy_imports.basic2 -except: - pass diff --git a/Lib/test/test_import/data/lazy_imports/try_except_eager_from.py b/Lib/test/test_import/data/lazy_imports/try_except_eager_from.py deleted file mode 100644 index 6eadaaa71ca454..00000000000000 --- a/Lib/test/test_import/data/lazy_imports/try_except_eager_from.py +++ /dev/null @@ -1,4 +0,0 @@ -try: - from test.test_import.data.lazy_imports.basic2 import f -except: - pass diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_lazy_import/__init__.py similarity index 82% rename from Lib/test/test_import/test_lazy_imports.py rename to Lib/test/test_lazy_import/__init__.py index d4df772d2034d9..df19af05246dcd 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -11,6 +11,8 @@ import tempfile import os +from test import support + try: import _testcapi except ImportError: @@ -23,7 +25,7 @@ class LazyImportTests(unittest.TestCase): def tearDown(self): """Clean up any test modules from sys.modules.""" for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -32,58 +34,58 @@ def tearDown(self): def test_basic_unused(self): """Lazy imported module should not be loaded if never accessed.""" - import test.test_import.data.lazy_imports.basic_unused - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) - self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules) - self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"}) + import test.test_lazy_import.data.basic_unused + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) + self.assertIn("test.test_lazy_import.data", sys.lazy_modules) + self.assertEqual(sys.lazy_modules["test.test_lazy_import.data"], {"basic2"}) def test_sys_lazy_modules(self): try: - import test.test_import.data.lazy_imports.basic_from_unused + import test.test_lazy_import.data.basic_from_unused except ImportError as e: self.fail('lazy import failed') - self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules) - self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules) - self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"}) - test.test_import.data.lazy_imports.basic_from_unused.basic2 + self.assertFalse("test.test_lazy_import.data.basic2" in sys.modules) + self.assertIn("test.test_lazy_import.data", sys.lazy_modules) + self.assertEqual(sys.lazy_modules["test.test_lazy_import.data"], {"basic2"}) + test.test_lazy_import.data.basic_from_unused.basic2 self.assertNotIn("test.test_import.data", sys.lazy_modules) def test_basic_unused_use_externally(self): """Lazy import should load module when accessed from outside.""" - from test.test_import.data.lazy_imports import basic_unused + from test.test_lazy_import.data import basic_unused - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) - x = basic_unused.test.test_import.data.lazy_imports.basic2 - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) + x = basic_unused.test.test_lazy_import.data.basic2 + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_basic_from_unused_use_externally(self): """Lazy 'from' import should load when accessed from outside.""" - from test.test_import.data.lazy_imports import basic_from_unused + from test.test_lazy_import.data import basic_from_unused - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) x = basic_from_unused.basic2 - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_basic_unused_dir(self): """dir() on module should not trigger lazy import reification.""" - import test.test_import.data.lazy_imports.basic_unused + import test.test_lazy_import.data.basic_unused - x = dir(test.test_import.data.lazy_imports.basic_unused) + x = dir(test.test_lazy_import.data.basic_unused) self.assertIn("test", x) - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_basic_dir(self): """dir() at module scope should not trigger lazy import reification.""" - from test.test_import.data.lazy_imports import basic_dir + from test.test_lazy_import.data import basic_dir self.assertIn("test", basic_dir.x) - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_basic_used(self): """Lazy import should load when accessed within the module.""" - import test.test_import.data.lazy_imports.basic_used - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.basic_used + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) class GlobalLazyImportModeTests(unittest.TestCase): @@ -91,7 +93,7 @@ class GlobalLazyImportModeTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -99,33 +101,33 @@ def tearDown(self): def test_global_off(self): """Mode 'none' should disable lazy imports entirely.""" - import test.test_import.data.lazy_imports.global_off - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.global_off + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_global_on(self): """Mode 'all' should make regular imports lazy.""" - import test.test_import.data.lazy_imports.global_on - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.global_on + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_global_filter(self): """Filter returning False should prevent lazy loading.""" - import test.test_import.data.lazy_imports.global_filter - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.global_filter + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_global_filter_true(self): """Filter returning True should allow lazy loading.""" - import test.test_import.data.lazy_imports.global_filter_true - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.global_filter_true + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_global_filter_from(self): """Filter should work with 'from' imports.""" - import test.test_import.data.lazy_imports.global_filter_from - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.global_filter_from + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_global_filter_from_true(self): """Filter returning True should allow lazy 'from' imports.""" - import test.test_import.data.lazy_imports.global_filter_from_true - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.global_filter_from_true + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) class CompatibilityModeTests(unittest.TestCase): @@ -133,7 +135,7 @@ class CompatibilityModeTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -141,28 +143,28 @@ def tearDown(self): def test_compatibility_mode(self): """__lazy_modules__ should enable lazy imports for listed modules.""" - import test.test_import.data.lazy_imports.basic_compatibility_mode - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.basic_compatibility_mode + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_compatibility_mode_used(self): """Using a lazy import from __lazy_modules__ should load the module.""" - import test.test_import.data.lazy_imports.basic_compatibility_mode_used - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.basic_compatibility_mode_used + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_compatibility_mode_func(self): """Imports inside functions should be eager even in compatibility mode.""" - import test.test_import.data.lazy_imports.compatibility_mode_func - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.compatibility_mode_func + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_compatibility_mode_try_except(self): """Imports in try/except should be eager even in compatibility mode.""" - import test.test_import.data.lazy_imports.compatibility_mode_try_except - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.compatibility_mode_try_except + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_compatibility_mode_relative(self): """__lazy_modules__ should work with relative imports.""" - import test.test_import.data.lazy_imports.basic_compatibility_mode_relative - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.basic_compatibility_mode_relative + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) class ModuleIntrospectionTests(unittest.TestCase): @@ -170,7 +172,7 @@ class ModuleIntrospectionTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -178,18 +180,18 @@ def tearDown(self): def test_modules_dict(self): """Accessing module.__dict__ should not trigger reification.""" - import test.test_import.data.lazy_imports.modules_dict - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.modules_dict + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_modules_getattr(self): """Module __getattr__ for lazy import name should trigger reification.""" - import test.test_import.data.lazy_imports.modules_getattr - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.modules_getattr + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_modules_getattr_other(self): """Module __getattr__ for other names should not trigger reification.""" - import test.test_import.data.lazy_imports.modules_getattr_other - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.modules_getattr_other + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) class LazyImportTypeTests(unittest.TestCase): @@ -197,7 +199,7 @@ class LazyImportTypeTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -205,8 +207,8 @@ def tearDown(self): def test_lazy_value_resolve(self): """resolve() method should force the lazy import to load.""" - import test.test_import.data.lazy_imports.lazy_get_value - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.lazy_get_value + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_lazy_import_type_exposed(self): """LazyImportType should be exposed in types module.""" @@ -223,7 +225,7 @@ class SyntaxRestrictionTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -232,22 +234,22 @@ def tearDown(self): def test_lazy_try_except(self): """lazy import inside try/except should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.badsyntax.lazy_try_except + import test.test_lazy_import.data.badsyntax.lazy_try_except def test_lazy_try_except_from(self): """lazy from import inside try/except should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.badsyntax.lazy_try_except_from + import test.test_lazy_import.data.badsyntax.lazy_try_except_from def test_lazy_try_except_from_star(self): """lazy from import * should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.badsyntax.lazy_try_except_from_star + import test.test_lazy_import.data.badsyntax.lazy_try_except_from_star def test_lazy_future_import(self): """lazy from __future__ import should raise SyntaxError.""" with self.assertRaises(SyntaxError) as cm: - import test.test_import.data.lazy_imports.badsyntax.lazy_future_import + import test.test_lazy_import.data.badsyntax.lazy_future_import # Check we highlight 'lazy' (column offset 0, end offset 4) self.assertEqual(cm.exception.offset, 1) self.assertEqual(cm.exception.end_offset, 5) @@ -255,7 +257,7 @@ def test_lazy_future_import(self): def test_lazy_import_func(self): """lazy import inside function should raise SyntaxError.""" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.badsyntax.lazy_import_func + import test.test_lazy_import.data.badsyntax.lazy_import_func def test_lazy_import_exec_in_function(self): """lazy import via exec() inside a function should raise SyntaxError.""" @@ -268,6 +270,7 @@ def f(): f() self.assertIn("only allowed at module level", str(cm.exception)) + @support.requires_subprocess() def test_lazy_import_exec_at_module_level(self): """lazy import via exec() at module level should work.""" # exec() at module level (globals == locals) should allow lazy imports @@ -292,7 +295,7 @@ class EagerImportInLazyModeTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -301,21 +304,21 @@ def tearDown(self): def test_try_except_eager(self): """Imports in try/except should be eager even with mode='all'.""" sys.set_lazy_imports("all") - import test.test_import.data.lazy_imports.try_except_eager - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.try_except_eager + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_try_except_eager_from(self): """From imports in try/except should be eager even with mode='all'.""" sys.set_lazy_imports("all") - import test.test_import.data.lazy_imports.try_except_eager_from - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.try_except_eager_from + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_eager_import_func(self): """Imports inside functions should return modules, not proxies.""" sys.set_lazy_imports("all") - import test.test_import.data.lazy_imports.eager_import_func + import test.test_lazy_import.data.eager_import_func - f = test.test_import.data.lazy_imports.eager_import_func.f + f = test.test_lazy_import.data.eager_import_func.f self.assertEqual(type(f()), type(sys)) @@ -324,7 +327,7 @@ class WithStatementTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -332,13 +335,13 @@ def tearDown(self): def test_lazy_with(self): """lazy import with 'with' statement should work.""" - import test.test_import.data.lazy_imports.lazy_with - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.lazy_with + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_lazy_with_from(self): """lazy from import with 'with' statement should work.""" - import test.test_import.data.lazy_imports.lazy_with_from - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.lazy_with_from + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) class PackageTests(unittest.TestCase): @@ -346,7 +349,7 @@ class PackageTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -354,20 +357,20 @@ def tearDown(self): def test_lazy_import_pkg(self): """lazy import of package submodule should load the package.""" - import test.test_import.data.lazy_imports.lazy_import_pkg + import test.test_lazy_import.data.lazy_import_pkg - self.assertIn("test.test_import.data.lazy_imports.pkg", sys.modules) - self.assertIn("test.test_import.data.lazy_imports.pkg.bar", sys.modules) + self.assertIn("test.test_lazy_import.data.pkg", sys.modules) + self.assertIn("test.test_lazy_import.data.pkg.bar", sys.modules) def test_lazy_import_pkg_cross_import(self): """Cross-imports within package should preserve lazy imports.""" - import test.test_import.data.lazy_imports.pkg.c + import test.test_lazy_import.data.pkg.c - self.assertIn("test.test_import.data.lazy_imports.pkg", sys.modules) - self.assertIn("test.test_import.data.lazy_imports.pkg.c", sys.modules) - self.assertNotIn("test.test_import.data.lazy_imports.pkg.b", sys.modules) + self.assertIn("test.test_lazy_import.data.pkg", sys.modules) + self.assertIn("test.test_lazy_import.data.pkg.c", sys.modules) + self.assertNotIn("test.test_lazy_import.data.pkg.b", sys.modules) - g = test.test_import.data.lazy_imports.pkg.c.get_globals() + g = test.test_lazy_import.data.pkg.c.get_globals() self.assertEqual(type(g["x"]), int) self.assertEqual(type(g["b"]), types.LazyImportType) @@ -377,7 +380,7 @@ class DunderLazyImportTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -385,13 +388,13 @@ def tearDown(self): def test_dunder_lazy_import(self): """__lazy_import__ should create lazy import proxy.""" - import test.test_import.data.lazy_imports.dunder_lazy_import - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.dunder_lazy_import + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_dunder_lazy_import_used(self): """Using __lazy_import__ result should trigger module load.""" - import test.test_import.data.lazy_imports.dunder_lazy_import_used - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + import test.test_lazy_import.data.dunder_lazy_import_used + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_dunder_lazy_import_invalid_arguments(self): """__lazy_import__ should reject invalid arguments.""" @@ -406,9 +409,9 @@ def test_dunder_lazy_import_invalid_arguments(self): def test_dunder_lazy_import_builtins(self): """__lazy_import__ should use module's __builtins__ for __import__.""" - from test.test_import.data.lazy_imports import dunder_lazy_import_builtins + from test.test_lazy_import.data import dunder_lazy_import_builtins - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) self.assertEqual(dunder_lazy_import_builtins.basic.basic2, 42) @@ -417,7 +420,7 @@ class SysLazyImportsAPITests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -469,14 +472,15 @@ def test_lazy_modules_attribute_is_set(self): """sys.lazy_modules should be a set per PEP 810.""" self.assertIsInstance(sys.lazy_modules, dict) + @support.requires_subprocess() def test_lazy_modules_tracks_lazy_imports(self): """sys.lazy_modules should track lazily imported module names.""" code = textwrap.dedent(""" import sys initial_count = len(sys.lazy_modules) - import test.test_import.data.lazy_imports.basic_unused - assert "test.test_import.data.lazy_imports" in sys.lazy_modules - assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"} + import test.test_lazy_import.data.basic_unused + assert "test.test_lazy_import.data" in sys.lazy_modules + assert sys.lazy_modules["test.test_lazy_import.data"] == {"basic2"} assert len(sys.lazy_modules) > initial_count print("OK") """) @@ -489,6 +493,7 @@ def test_lazy_modules_tracks_lazy_imports(self): self.assertIn("OK", result.stdout) +@support.requires_subprocess() class ErrorHandlingTests(unittest.TestCase): """Tests for error handling during lazy import reification. @@ -498,7 +503,7 @@ class ErrorHandlingTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -510,10 +515,10 @@ def test_import_error_shows_chained_traceback(self): # AND where the access happened, per PEP 810 "Reification" section code = textwrap.dedent(""" import sys - lazy import test.test_import.data.lazy_imports.nonexistent_module + lazy import test.test_lazy_import.data.nonexistent_module try: - x = test.test_import.data.lazy_imports.nonexistent_module + x = test.test_lazy_import.data.nonexistent_module except ImportError as e: # Should have __cause__ showing the original error # The exception chain shows both where import was defined and where access happened @@ -533,7 +538,7 @@ def test_attribute_error_on_from_import_shows_chained_traceback(self): # Tests 'lazy from module import nonexistent' behavior code = textwrap.dedent(""" import sys - lazy from test.test_import.data.lazy_imports.basic2 import nonexistent_name + lazy from test.test_lazy_import.data.basic2 import nonexistent_name try: x = nonexistent_name @@ -560,11 +565,11 @@ def test_reification_retries_on_failure(self): import sys import types - lazy import test.test_import.data.lazy_imports.broken_module + lazy import test.test_lazy_import.data.broken_module # First access - should fail try: - x = test.test_import.data.lazy_imports.broken_module + x = test.test_lazy_import.data.broken_module except ValueError: pass @@ -574,7 +579,7 @@ def test_reification_retries_on_failure(self): # The root 'test' binding should still allow retry # Second access - should also fail (retry the import) try: - x = test.test_import.data.lazy_imports.broken_module + x = test.test_lazy_import.data.broken_module except ValueError: print("OK - retry worked") """) @@ -591,10 +596,10 @@ def test_error_during_module_execution_propagates(self): # Module that raises during import should propagate with chaining code = textwrap.dedent(""" import sys - lazy import test.test_import.data.lazy_imports.broken_module + lazy import test.test_lazy_import.data.broken_module try: - _ = test.test_import.data.lazy_imports.broken_module + _ = test.test_lazy_import.data.broken_module print("FAIL - should have raised") except ValueError as e: # The ValueError from the module should be the cause @@ -645,6 +650,7 @@ def hello(): self.assertIn("Error", result.stderr) +@support.requires_subprocess() class GlobalsAndDictTests(unittest.TestCase): """Tests for globals() and __dict__ behavior with lazy imports. @@ -655,7 +661,7 @@ class GlobalsAndDictTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -672,10 +678,10 @@ def test_globals_returns_lazy_proxy_when_accessed_from_function(self): import sys import types - lazy from test.test_import.data.lazy_imports.basic2 import x + lazy from test.test_lazy_import.data.basic2 import x # Check that module is not yet loaded - assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + assert 'test.test_lazy_import.data.basic2' not in sys.modules def check_lazy(): # Access through globals() from inside a function @@ -688,7 +694,7 @@ def check_lazy(): assert is_lazy, "Expected LazyImportType from function scope" # Module should STILL not be loaded - assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + assert 'test.test_lazy_import.data.basic2' not in sys.modules print("OK") """) result = subprocess.run( @@ -724,25 +730,25 @@ def test_globals_dict_access_returns_lazy_proxy_inline(self): def test_module_dict_returns_lazy_proxy_without_reifying(self): """module.__dict__ access should not trigger reification.""" - import test.test_import.data.lazy_imports.globals_access + import test.test_lazy_import.data.globals_access # Module not loaded yet via direct dict access - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) # Access via get_from_globals should return lazy proxy - lazy_obj = test.test_import.data.lazy_imports.globals_access.get_from_globals() + lazy_obj = test.test_lazy_import.data.globals_access.get_from_globals() self.assertEqual(type(lazy_obj), types.LazyImportType) - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) def test_direct_access_triggers_reification(self): """Direct name access (not through globals()) should trigger reification.""" - import test.test_import.data.lazy_imports.globals_access + import test.test_lazy_import.data.globals_access - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) # Direct access should reify - result = test.test_import.data.lazy_imports.globals_access.get_direct() - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + result = test.test_lazy_import.data.globals_access.get_direct() + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_resolve_method_forces_reification(self): """Calling resolve() on lazy proxy should force reification. @@ -754,9 +760,9 @@ def test_resolve_method_forces_reification(self): import sys import types - lazy from test.test_import.data.lazy_imports.basic2 import x + lazy from test.test_lazy_import.data.basic2 import x - assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + assert 'test.test_lazy_import.data.basic2' not in sys.modules def test_resolve(): g = globals() @@ -766,7 +772,7 @@ def test_resolve(): resolved = lazy_obj.resolve() # Now module should be loaded - assert 'test.test_import.data.lazy_imports.basic2' in sys.modules + assert 'test.test_lazy_import.data.basic2' in sys.modules assert resolved == 42 # x is 42 in basic2.py return True @@ -786,9 +792,9 @@ def test_add_lazy_to_globals(self): import sys import types - lazy from test.test_import.data.lazy_imports import basic2 + lazy from test.test_lazy_import.data import basic2 - assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + assert 'test.test_lazy_import.data.basic2' not in sys.modules class C: pass sneaky = C() @@ -814,6 +820,7 @@ def f(): self.assertIn("OK", result.stdout) +@support.requires_subprocess() class MultipleNameFromImportTests(unittest.TestCase): """Tests for lazy from ... import with multiple names. @@ -825,7 +832,7 @@ class MultipleNameFromImportTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -837,10 +844,10 @@ def test_accessing_one_name_leaves_others_as_proxies(self): import sys import types - lazy from test.test_import.data.lazy_imports.basic2 import f, x + lazy from test.test_lazy_import.data.basic2 import f, x # Neither should be loaded yet - assert 'test.test_import.data.lazy_imports.basic2' not in sys.modules + assert 'test.test_lazy_import.data.basic2' not in sys.modules g = globals() assert type(g['f']) is types.LazyImportType @@ -851,7 +858,7 @@ def test_accessing_one_name_leaves_others_as_proxies(self): assert value == 42 # Module is now loaded - assert 'test.test_import.data.lazy_imports.basic2' in sys.modules + assert 'test.test_lazy_import.data.basic2' in sys.modules # 'x' should be reified (int), 'f' should still be lazy proxy assert type(g['x']) is int, f"Expected int, got {type(g['x'])}" @@ -872,7 +879,7 @@ def test_all_names_reified_after_all_accessed(self): import sys import types - lazy from test.test_import.data.lazy_imports.basic2 import f, x + lazy from test.test_lazy_import.data.basic2 import f, x g = globals() @@ -894,6 +901,7 @@ def test_all_names_reified_after_all_accessed(self): self.assertIn("OK", result.stdout) +@support.requires_subprocess() class SysLazyModulesTrackingTests(unittest.TestCase): """Tests for sys.lazy_modules tracking behavior. @@ -902,7 +910,7 @@ class SysLazyModulesTrackingTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -918,18 +926,18 @@ def test_module_added_to_lazy_modules_on_lazy_import(self): initial_count = len(sys.lazy_modules) - lazy import test.test_import.data.lazy_imports.basic2 + lazy import test.test_lazy_import.data.basic2 # Should be in lazy_modules after lazy import - assert "test.test_import.data.lazy_imports" in sys.lazy_modules - assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"} + assert "test.test_lazy_import.data" in sys.lazy_modules + assert sys.lazy_modules["test.test_lazy_import.data"] == {"basic2"} assert len(sys.lazy_modules) > initial_count # Trigger reification - _ = test.test_import.data.lazy_imports.basic2.x + _ = test.test_lazy_import.data.basic2.x # Module should still be tracked (for diagnostics per PEP 810) - assert "test.test_import.data.lazy_imports" not in sys.lazy_modules + assert "test.test_lazy_import.data" not in sys.lazy_modules print("OK") """) result = subprocess.run( @@ -946,6 +954,7 @@ def test_lazy_modules_is_per_interpreter(self): self.assertIsInstance(sys.lazy_modules, dict) +@support.requires_subprocess() class CommandLineAndEnvVarTests(unittest.TestCase): """Tests for command-line and environment variable control. @@ -1000,11 +1009,11 @@ def test_cli_lazy_imports_normal_respects_lazy_keyword_only(self): # modules already loaded by the interpreter startup code = textwrap.dedent(""" import sys - import test.test_import.data.lazy_imports.basic2 # Should be eager - lazy import test.test_import.data.lazy_imports.pkg.b # Should be lazy + import test.test_lazy_import.data.basic2 # Should be eager + lazy import test.test_lazy_import.data.pkg.b # Should be lazy - eager_loaded = 'test.test_import.data.lazy_imports.basic2' in sys.modules - lazy_loaded = 'test.test_import.data.lazy_imports.pkg.b' in sys.modules + eager_loaded = 'test.test_lazy_import.data.basic2' in sys.modules + lazy_loaded = 'test.test_lazy_import.data.pkg.b' in sys.modules if eager_loaded and not lazy_loaded: print("OK") @@ -1107,6 +1116,7 @@ def test_sys_set_lazy_imports_overrides_cli(self): self.assertIn("EAGER", result.stdout) +@support.requires_subprocess() class FilterFunctionSignatureTests(unittest.TestCase): """Tests for the filter function signature per PEP 810. @@ -1115,7 +1125,7 @@ class FilterFunctionSignatureTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1212,7 +1222,7 @@ class AdditionalSyntaxRestrictionTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1223,9 +1233,10 @@ def test_lazy_import_inside_class_raises_syntax_error(self): # PEP 810: "The soft keyword is only allowed at the global (module) level, # not inside functions, class bodies, try blocks, or import *" with self.assertRaises(SyntaxError): - import test.test_import.data.lazy_imports.badsyntax.lazy_class_body + import test.test_lazy_import.data.badsyntax.lazy_class_body +@support.requires_subprocess() class MixedLazyEagerImportTests(unittest.TestCase): """Tests for mixing lazy and eager imports of the same module. @@ -1236,7 +1247,7 @@ class MixedLazyEagerImportTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1292,7 +1303,7 @@ class RelativeImportTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1300,26 +1311,26 @@ def tearDown(self): def test_relative_lazy_import(self): """lazy from . import submodule should work.""" - from test.test_import.data.lazy_imports import relative_lazy + from test.test_lazy_import.data import relative_lazy # basic2 should not be loaded yet - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) # Access triggers reification result = relative_lazy.get_basic2() - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) def test_relative_lazy_from_import(self): """lazy from .module import name should work.""" - from test.test_import.data.lazy_imports import relative_lazy_from + from test.test_lazy_import.data import relative_lazy_from # basic2 should not be loaded yet - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) # Access triggers reification result = relative_lazy_from.get_x() self.assertEqual(result, 42) - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) class LazyModulesCompatibilityFromImportTests(unittest.TestCase): @@ -1331,7 +1342,7 @@ class LazyModulesCompatibilityFromImportTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1339,17 +1350,18 @@ def tearDown(self): def test_lazy_modules_makes_from_imports_lazy(self): """__lazy_modules__ should make from imports of listed modules lazy.""" - from test.test_import.data.lazy_imports import lazy_compat_from + from test.test_lazy_import.data import lazy_compat_from # basic2 should not be loaded yet because it's in __lazy_modules__ - self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) # Access triggers reification result = lazy_compat_from.get_x() self.assertEqual(result, 42) - self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) +@support.requires_subprocess() class ImportStateAtReificationTests(unittest.TestCase): """Tests for import system state at reification time. @@ -1361,7 +1373,7 @@ class ImportStateAtReificationTests(unittest.TestCase): def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1408,12 +1420,13 @@ def test_sys_path_at_reification_time_is_used(self): self.assertIn("OK", result.stdout) +@support.requires_subprocess() class ThreadSafetyTests(unittest.TestCase): """Tests for thread-safety of lazy imports.""" def tearDown(self): for key in list(sys.modules.keys()): - if key.startswith('test.test_import.data.lazy_imports'): + if key.startswith('test.test_lazy_import.data'): del sys.modules[key] sys.set_lazy_imports_filter(None) @@ -1421,7 +1434,7 @@ def tearDown(self): def test_concurrent_lazy_import_reification(self): """Multiple threads racing to reify the same lazy import should succeed.""" - from test.test_import.data.lazy_imports import basic_unused + from test.test_lazy_import.data import basic_unused num_threads = 10 results = [None] * num_threads @@ -1431,7 +1444,7 @@ def test_concurrent_lazy_import_reification(self): def access_lazy_import(idx): try: barrier.wait() - module = basic_unused.test.test_import.data.lazy_imports.basic2 + module = basic_unused.test.test_lazy_import.data.basic2 results[idx] = module except Exception as e: errors.append((idx, e)) diff --git a/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_class_body.py b/Lib/test/test_lazy_import/data/badsyntax/lazy_class_body.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/badsyntax/lazy_class_body.py rename to Lib/test/test_lazy_import/data/badsyntax/lazy_class_body.py diff --git a/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_future_import.py b/Lib/test/test_lazy_import/data/badsyntax/lazy_future_import.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/badsyntax/lazy_future_import.py rename to Lib/test/test_lazy_import/data/badsyntax/lazy_future_import.py diff --git a/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_import_func.py b/Lib/test/test_lazy_import/data/badsyntax/lazy_import_func.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/badsyntax/lazy_import_func.py rename to Lib/test/test_lazy_import/data/badsyntax/lazy_import_func.py diff --git a/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except.py b/Lib/test/test_lazy_import/data/badsyntax/lazy_try_except.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except.py rename to Lib/test/test_lazy_import/data/badsyntax/lazy_try_except.py diff --git a/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from.py b/Lib/test/test_lazy_import/data/badsyntax/lazy_try_except_from.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from.py rename to Lib/test/test_lazy_import/data/badsyntax/lazy_try_except_from.py diff --git a/Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from_star.py b/Lib/test/test_lazy_import/data/badsyntax/lazy_try_except_from_star.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/badsyntax/lazy_try_except_from_star.py rename to Lib/test/test_lazy_import/data/badsyntax/lazy_try_except_from_star.py diff --git a/Lib/test/test_import/data/lazy_imports/basic2.py b/Lib/test/test_lazy_import/data/basic2.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/basic2.py rename to Lib/test/test_lazy_import/data/basic2.py diff --git a/Lib/test/test_lazy_import/data/basic_compatibility_mode.py b/Lib/test/test_lazy_import/data/basic_compatibility_mode.py new file mode 100644 index 00000000000000..33eeab8879c394 --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_compatibility_mode.py @@ -0,0 +1,2 @@ +__lazy_modules__ = ['test.test_lazy_import.data.basic2'] +import test.test_lazy_import.data.basic2 diff --git a/Lib/test/test_lazy_import/data/basic_compatibility_mode_relative.py b/Lib/test/test_lazy_import/data/basic_compatibility_mode_relative.py new file mode 100644 index 00000000000000..15c1ea77630b31 --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_compatibility_mode_relative.py @@ -0,0 +1,2 @@ +__lazy_modules__ = ['test.test_lazy_import.data.basic2'] +lazy from .basic2 import f diff --git a/Lib/test/test_lazy_import/data/basic_compatibility_mode_used.py b/Lib/test/test_lazy_import/data/basic_compatibility_mode_used.py new file mode 100644 index 00000000000000..78bb4ffa52314b --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_compatibility_mode_used.py @@ -0,0 +1,3 @@ +__lazy_modules__ = ['test.test_lazy_import.data.basic2'] +import test.test_lazy_import.data.basic2 +test.test_lazy_import.data.basic2.f() diff --git a/Lib/test/test_lazy_import/data/basic_dir.py b/Lib/test/test_lazy_import/data/basic_dir.py new file mode 100644 index 00000000000000..a88c8ed80a1dcf --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_dir.py @@ -0,0 +1,2 @@ +lazy import test.test_lazy_import.data.basic2 +x = dir() diff --git a/Lib/test/test_lazy_import/data/basic_from_unused.py b/Lib/test/test_lazy_import/data/basic_from_unused.py new file mode 100644 index 00000000000000..62fa04bc8faefd --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_from_unused.py @@ -0,0 +1 @@ +lazy from test.test_lazy_import.data import basic2 diff --git a/Lib/test/test_lazy_import/data/basic_unused.py b/Lib/test/test_lazy_import/data/basic_unused.py new file mode 100644 index 00000000000000..f3e502c59e7cdf --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_unused.py @@ -0,0 +1 @@ +lazy import test.test_lazy_import.data.basic2 diff --git a/Lib/test/test_lazy_import/data/basic_used.py b/Lib/test/test_lazy_import/data/basic_used.py new file mode 100644 index 00000000000000..7234bd2fe02a80 --- /dev/null +++ b/Lib/test/test_lazy_import/data/basic_used.py @@ -0,0 +1,3 @@ +lazy import test.test_lazy_import.data.basic2 as basic2 + +basic2.f() diff --git a/Lib/test/test_import/data/lazy_imports/broken_attr_module.py b/Lib/test/test_lazy_import/data/broken_attr_module.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/broken_attr_module.py rename to Lib/test/test_lazy_import/data/broken_attr_module.py diff --git a/Lib/test/test_import/data/lazy_imports/broken_module.py b/Lib/test/test_lazy_import/data/broken_module.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/broken_module.py rename to Lib/test/test_lazy_import/data/broken_module.py diff --git a/Lib/test/test_lazy_import/data/compatibility_mode_func.py b/Lib/test/test_lazy_import/data/compatibility_mode_func.py new file mode 100644 index 00000000000000..9405d2f832b8ee --- /dev/null +++ b/Lib/test/test_lazy_import/data/compatibility_mode_func.py @@ -0,0 +1,5 @@ +__lazy_modules__ = ['test.test_lazy_import.data.basic2'] +def f(): + import test.test_lazy_import.data.basic2 + +f() diff --git a/Lib/test/test_lazy_import/data/compatibility_mode_try_except.py b/Lib/test/test_lazy_import/data/compatibility_mode_try_except.py new file mode 100644 index 00000000000000..a746c4a34a50c9 --- /dev/null +++ b/Lib/test/test_lazy_import/data/compatibility_mode_try_except.py @@ -0,0 +1,5 @@ +__lazy_modules__ = ['test.test_lazy_import.data.basic2'] +try: + import test.test_lazy_import.data.basic2 +except: + pass diff --git a/Lib/test/test_lazy_import/data/dunder_lazy_import.py b/Lib/test/test_lazy_import/data/dunder_lazy_import.py new file mode 100644 index 00000000000000..c4f4d61623f956 --- /dev/null +++ b/Lib/test/test_lazy_import/data/dunder_lazy_import.py @@ -0,0 +1 @@ +basic = __lazy_import__('test.test_lazy_import.data.basic2') diff --git a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py b/Lib/test/test_lazy_import/data/dunder_lazy_import_builtins.py similarity index 76% rename from Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py rename to Lib/test/test_lazy_import/data/dunder_lazy_import_builtins.py index f1fed0fc31768e..8b6dbd7e3f684c 100644 --- a/Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py +++ b/Lib/test/test_lazy_import/data/dunder_lazy_import_builtins.py @@ -9,6 +9,6 @@ def myimport(*args): "__import__": myimport, } basic2 = 42 -basic = __lazy_import__("test.test_import.data.lazy_imports.basic2", +basic = __lazy_import__("test.test_lazy_import.data.basic2", globals=new_globals) basic diff --git a/Lib/test/test_lazy_import/data/dunder_lazy_import_used.py b/Lib/test/test_lazy_import/data/dunder_lazy_import_used.py new file mode 100644 index 00000000000000..42c026994b1094 --- /dev/null +++ b/Lib/test/test_lazy_import/data/dunder_lazy_import_used.py @@ -0,0 +1,3 @@ +basic = __lazy_import__('test.test_lazy_import.data', + fromlist=("basic2", )) +basic diff --git a/Lib/test/test_lazy_import/data/eager_import_func.py b/Lib/test/test_lazy_import/data/eager_import_func.py new file mode 100644 index 00000000000000..1f7130209d4b56 --- /dev/null +++ b/Lib/test/test_lazy_import/data/eager_import_func.py @@ -0,0 +1,3 @@ +def f(): + import test.test_lazy_import.data.basic2 as basic2 + return basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_filter.py b/Lib/test/test_lazy_import/data/global_filter.py similarity index 52% rename from Lib/test/test_import/data/lazy_imports/global_filter.py rename to Lib/test/test_lazy_import/data/global_filter.py index 72cb5f2ef5a02b..0e2311842dfcbd 100644 --- a/Lib/test/test_import/data/lazy_imports/global_filter.py +++ b/Lib/test/test_lazy_import/data/global_filter.py @@ -2,9 +2,9 @@ def filter(module_name, imported_name, from_list): assert module_name == __name__ - assert imported_name == "test.test_import.data.lazy_imports.basic2" + assert imported_name == "test.test_lazy_import.data.basic2" return False sys.set_lazy_imports_filter(filter) -lazy import test.test_import.data.lazy_imports.basic2 as basic2 +lazy import test.test_lazy_import.data.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_from.py b/Lib/test/test_lazy_import/data/global_filter_from.py similarity index 58% rename from Lib/test/test_import/data/lazy_imports/global_filter_from.py rename to Lib/test/test_lazy_import/data/global_filter_from.py index 93a1280292f8af..da9d22e87277f8 100644 --- a/Lib/test/test_import/data/lazy_imports/global_filter_from.py +++ b/Lib/test/test_lazy_import/data/global_filter_from.py @@ -2,10 +2,10 @@ def filter(module_name, imported_name, from_list): assert module_name == __name__ - assert imported_name == "test.test_import.data.lazy_imports.basic2" + assert imported_name == "test.test_lazy_import.data.basic2" assert from_list == ('f',) return False sys.set_lazy_imports_filter(filter) -lazy from test.test_import.data.lazy_imports.basic2 import f +lazy from test.test_lazy_import.data.basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py b/Lib/test/test_lazy_import/data/global_filter_from_true.py similarity index 61% rename from Lib/test/test_import/data/lazy_imports/global_filter_from_true.py rename to Lib/test/test_lazy_import/data/global_filter_from_true.py index bc51215ae26ce4..2d8b1de4c7c400 100644 --- a/Lib/test/test_import/data/lazy_imports/global_filter_from_true.py +++ b/Lib/test/test_lazy_import/data/global_filter_from_true.py @@ -2,11 +2,11 @@ def filter(module_name, imported_name, from_list): assert module_name == __name__ - assert imported_name == "test.test_import.data.lazy_imports.basic2" + assert imported_name == "test.test_lazy_import.data.basic2" assert from_list == ('f',) return True sys.set_lazy_imports("normal") sys.set_lazy_imports_filter(filter) -lazy from test.test_import.data.lazy_imports.basic2 import f +lazy from test.test_lazy_import.data.basic2 import f diff --git a/Lib/test/test_import/data/lazy_imports/global_filter_true.py b/Lib/test/test_lazy_import/data/global_filter_true.py similarity index 57% rename from Lib/test/test_import/data/lazy_imports/global_filter_true.py rename to Lib/test/test_lazy_import/data/global_filter_true.py index 4881b30fb02409..da4abeacf87cda 100644 --- a/Lib/test/test_import/data/lazy_imports/global_filter_true.py +++ b/Lib/test/test_lazy_import/data/global_filter_true.py @@ -2,10 +2,10 @@ def filter(module_name, imported_name, from_list): assert module_name == __name__ - assert imported_name == "test.test_import.data.lazy_imports.basic2" + assert imported_name == "test.test_lazy_import.data.basic2" return True sys.set_lazy_imports("normal") sys.set_lazy_imports_filter(filter) -lazy import test.test_import.data.lazy_imports.basic2 as basic2 +lazy import test.test_lazy_import.data.basic2 as basic2 diff --git a/Lib/test/test_lazy_import/data/global_off.py b/Lib/test/test_lazy_import/data/global_off.py new file mode 100644 index 00000000000000..95d1511dd93223 --- /dev/null +++ b/Lib/test/test_lazy_import/data/global_off.py @@ -0,0 +1,5 @@ +import sys + +sys.set_lazy_imports("none") + +lazy import test.test_lazy_import.data.basic2 as basic2 diff --git a/Lib/test/test_lazy_import/data/global_on.py b/Lib/test/test_lazy_import/data/global_on.py new file mode 100644 index 00000000000000..ddacab5468bab9 --- /dev/null +++ b/Lib/test/test_lazy_import/data/global_on.py @@ -0,0 +1,5 @@ +import sys + +sys.set_lazy_imports("all") + +import test.test_lazy_import.data.basic2 as basic2 diff --git a/Lib/test/test_import/data/lazy_imports/globals_access.py b/Lib/test/test_lazy_import/data/globals_access.py similarity index 72% rename from Lib/test/test_import/data/lazy_imports/globals_access.py rename to Lib/test/test_lazy_import/data/globals_access.py index c12c6a029c2b81..af6fc40115b21c 100644 --- a/Lib/test/test_import/data/lazy_imports/globals_access.py +++ b/Lib/test/test_lazy_import/data/globals_access.py @@ -1,5 +1,5 @@ # Test that globals() returns lazy proxy objects without reifying -lazy import test.test_import.data.lazy_imports.basic2 as basic2 +lazy import test.test_lazy_import.data.basic2 as basic2 def get_from_globals(): g = globals() diff --git a/Lib/test/test_lazy_import/data/lazy_compat_from.py b/Lib/test/test_lazy_import/data/lazy_compat_from.py new file mode 100644 index 00000000000000..d6f7ed9a78538b --- /dev/null +++ b/Lib/test/test_lazy_import/data/lazy_compat_from.py @@ -0,0 +1,6 @@ +# Test __lazy_modules__ with from imports +__lazy_modules__ = ['test.test_lazy_import.data.basic2'] +from test.test_lazy_import.data.basic2 import x, f + +def get_x(): + return x diff --git a/Lib/test/test_import/data/lazy_imports/lazy_get_value.py b/Lib/test/test_lazy_import/data/lazy_get_value.py similarity index 50% rename from Lib/test/test_import/data/lazy_imports/lazy_get_value.py rename to Lib/test/test_lazy_import/data/lazy_get_value.py index 0ff572fa1e398a..f216dc52f292fa 100644 --- a/Lib/test/test_import/data/lazy_imports/lazy_get_value.py +++ b/Lib/test/test_lazy_import/data/lazy_get_value.py @@ -1,4 +1,4 @@ -lazy import test.test_import.data.lazy_imports.basic2 as basic2 +lazy import test.test_lazy_import.data.basic2 as basic2 def f(): x = globals() diff --git a/Lib/test/test_lazy_import/data/lazy_import_pkg.py b/Lib/test/test_lazy_import/data/lazy_import_pkg.py new file mode 100644 index 00000000000000..f237b50fd422ff --- /dev/null +++ b/Lib/test/test_lazy_import/data/lazy_import_pkg.py @@ -0,0 +1,2 @@ +lazy import test.test_lazy_import.data.pkg.bar +x = test.test_lazy_import.data.pkg.bar.f diff --git a/Lib/test/test_lazy_import/data/lazy_with.py b/Lib/test/test_lazy_import/data/lazy_with.py new file mode 100644 index 00000000000000..30cf9d377624da --- /dev/null +++ b/Lib/test/test_lazy_import/data/lazy_with.py @@ -0,0 +1,3 @@ +import contextlib +with contextlib.nullcontext(): + lazy import test.test_lazy_import.data.basic2 diff --git a/Lib/test/test_lazy_import/data/lazy_with_from.py b/Lib/test/test_lazy_import/data/lazy_with_from.py new file mode 100644 index 00000000000000..794ba33f828596 --- /dev/null +++ b/Lib/test/test_lazy_import/data/lazy_with_from.py @@ -0,0 +1,3 @@ +import contextlib +with contextlib.nullcontext(): + lazy import test.test_lazy_import.data.basic2 as basic2 diff --git a/Lib/test/test_lazy_import/data/modules_dict.py b/Lib/test/test_lazy_import/data/modules_dict.py new file mode 100644 index 00000000000000..562a3b9a62f8d3 --- /dev/null +++ b/Lib/test/test_lazy_import/data/modules_dict.py @@ -0,0 +1,5 @@ +lazy import test.test_lazy_import.data.basic2 as basic2 + +import sys +mod = sys.modules[__name__] +x = mod.__dict__ diff --git a/Lib/test/test_lazy_import/data/modules_getattr.py b/Lib/test/test_lazy_import/data/modules_getattr.py new file mode 100644 index 00000000000000..f0b8e2bd0613b8 --- /dev/null +++ b/Lib/test/test_lazy_import/data/modules_getattr.py @@ -0,0 +1,5 @@ +lazy import test.test_lazy_import.data.basic2 as basic2 + +import sys +mod = sys.modules[__name__] +x = mod.basic2 diff --git a/Lib/test/test_lazy_import/data/modules_getattr_other.py b/Lib/test/test_lazy_import/data/modules_getattr_other.py new file mode 100644 index 00000000000000..642840c28722b3 --- /dev/null +++ b/Lib/test/test_lazy_import/data/modules_getattr_other.py @@ -0,0 +1,5 @@ +lazy import test.test_lazy_import.data.basic2 as basic2 + +import sys +mod = sys.modules[__name__] +x = mod.__name__ diff --git a/Lib/test/test_import/data/lazy_imports/multi_from_import.py b/Lib/test/test_lazy_import/data/multi_from_import.py similarity index 64% rename from Lib/test/test_import/data/lazy_imports/multi_from_import.py rename to Lib/test/test_lazy_import/data/multi_from_import.py index 96dc9757500549..dfd875975dd2f7 100644 --- a/Lib/test/test_import/data/lazy_imports/multi_from_import.py +++ b/Lib/test/test_lazy_import/data/multi_from_import.py @@ -1,5 +1,5 @@ # Test that lazy from import with multiple names only reifies accessed names -lazy from test.test_import.data.lazy_imports.basic2 import f, x +lazy from test.test_lazy_import.data.basic2 import f, x def get_globals(): return globals() diff --git a/Lib/test/test_import/data/lazy_imports/pkg/__init__.py b/Lib/test/test_lazy_import/data/pkg/__init__.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/pkg/__init__.py rename to Lib/test/test_lazy_import/data/pkg/__init__.py diff --git a/Lib/test/test_import/data/lazy_imports/pkg/b.py b/Lib/test/test_lazy_import/data/pkg/b.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/pkg/b.py rename to Lib/test/test_lazy_import/data/pkg/b.py diff --git a/Lib/test/test_import/data/lazy_imports/pkg/bar.py b/Lib/test/test_lazy_import/data/pkg/bar.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/pkg/bar.py rename to Lib/test/test_lazy_import/data/pkg/bar.py diff --git a/Lib/test/test_import/data/lazy_imports/pkg/c.py b/Lib/test/test_lazy_import/data/pkg/c.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/pkg/c.py rename to Lib/test/test_lazy_import/data/pkg/c.py diff --git a/Lib/test/test_import/data/lazy_imports/relative_lazy.py b/Lib/test/test_lazy_import/data/relative_lazy.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/relative_lazy.py rename to Lib/test/test_lazy_import/data/relative_lazy.py diff --git a/Lib/test/test_import/data/lazy_imports/relative_lazy_from.py b/Lib/test/test_lazy_import/data/relative_lazy_from.py similarity index 100% rename from Lib/test/test_import/data/lazy_imports/relative_lazy_from.py rename to Lib/test/test_lazy_import/data/relative_lazy_from.py diff --git a/Lib/test/test_lazy_import/data/try_except_eager.py b/Lib/test/test_lazy_import/data/try_except_eager.py new file mode 100644 index 00000000000000..90b4bc62898d2a --- /dev/null +++ b/Lib/test/test_lazy_import/data/try_except_eager.py @@ -0,0 +1,4 @@ +try: + import test.test_lazy_import.data.basic2 +except: + pass diff --git a/Lib/test/test_lazy_import/data/try_except_eager_from.py b/Lib/test/test_lazy_import/data/try_except_eager_from.py new file mode 100644 index 00000000000000..1e6c650d0d1c7d --- /dev/null +++ b/Lib/test/test_lazy_import/data/try_except_eager_from.py @@ -0,0 +1,4 @@ +try: + from test.test_lazy_import.data.basic2 import f +except: + pass diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 3896f34a34c8d6..2fbc2a041269f4 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -5383,8 +5383,8 @@ def test_attribute_error_does_not_reify_lazy_imports(self): # pkg.bar prints "BAR_MODULE_LOADED" when imported. # If lazy import is reified during suggestion computation, we'll see it. code = textwrap.dedent(""" - lazy import test.test_import.data.lazy_imports.pkg.bar - test.test_import.data.lazy_imports.pkg.nonexistent + lazy import test.test_lazy_import.data.pkg.bar + test.test_lazy_import.data.pkg.nonexistent """) rc, stdout, stderr = assert_python_failure('-c', code) self.assertNotIn(b"BAR_MODULE_LOADED", stdout) @@ -5393,9 +5393,9 @@ def test_traceback_formatting_does_not_reify_lazy_imports(self): """Formatting a traceback should not trigger lazy import reification.""" code = textwrap.dedent(""" import traceback - lazy import test.test_import.data.lazy_imports.pkg.bar + lazy import test.test_lazy_import.data.pkg.bar try: - test.test_import.data.lazy_imports.pkg.nonexistent + test.test_lazy_import.data.pkg.nonexistent except AttributeError: traceback.format_exc() print("OK") @@ -5407,9 +5407,9 @@ def test_traceback_formatting_does_not_reify_lazy_imports(self): def test_suggestion_still_works_for_non_lazy_attributes(self): """Suggestions should still work for non-lazy module attributes.""" code = textwrap.dedent(""" - lazy import test.test_import.data.lazy_imports.pkg.bar + lazy import test.test_lazy_import.data.pkg.bar # Typo for __name__ - test.test_import.data.lazy_imports.pkg.__nme__ + test.test_lazy_import.data.pkg.__nme__ """) rc, stdout, stderr = assert_python_failure('-c', code) self.assertIn(b"__name__", stderr) diff --git a/Makefile.pre.in b/Makefile.pre.in index aba92666720d7d..da8d5483fd32e8 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2682,9 +2682,6 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_import/data/package3 \ test/test_import/data/package4 \ test/test_import/data/unwritable \ - test/test_import/data/lazy_imports \ - test/test_import/data/lazy_imports/pkg \ - test/test_import/data/lazy_imports/badsyntax \ test/test_importlib \ test/test_importlib/builtin \ test/test_importlib/extension \ @@ -2725,6 +2722,10 @@ TESTSUBDIRS= idlelib/idle_test \ test/test_interpreters \ test/test_io \ test/test_json \ + test/test_lazy_import \ + test/test_lazy_import/data \ + test/test_lazy_import/data/pkg \ + test/test_lazy_import/data/badsyntax \ test/test_module \ test/test_multiprocessing_fork \ test/test_multiprocessing_forkserver \ From 2e2109d2248d9b59d1085d428831457c12cd32c0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 28 Feb 2026 03:48:35 +0200 Subject: [PATCH 261/498] gh-142927: Tachyon: Fix singular and plurals (#145329) --- Lib/profiling/sampling/sample.py | 3 ++- Lib/profiling/sampling/stack_collector.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/profiling/sampling/sample.py b/Lib/profiling/sampling/sample.py index c6abfb1c8ee885..6a76bbeeb24ee3 100644 --- a/Lib/profiling/sampling/sample.py +++ b/Lib/profiling/sampling/sample.py @@ -164,7 +164,8 @@ def sample(self, collector, duration_sec=None, *, async_aware=False): # Don't print stats for live mode (curses is handling display) is_live_mode = LiveStatsCollector is not None and isinstance(collector, LiveStatsCollector) if not is_live_mode: - print(f"Captured {num_samples:n} samples in {fmt(running_time_sec, 2)} seconds") + s = "" if num_samples == 1 else "s" + print(f"Captured {num_samples:n} sample{s} in {fmt(running_time_sec, 2)} seconds") print(f"Sample rate: {fmt(sample_rate, 2)} samples/sec") print(f"Error rate: {fmt(error_rate, 2)}") diff --git a/Lib/profiling/sampling/stack_collector.py b/Lib/profiling/sampling/stack_collector.py index 4e213cfe41ca24..5a3497a5408414 100644 --- a/Lib/profiling/sampling/stack_collector.py +++ b/Lib/profiling/sampling/stack_collector.py @@ -144,9 +144,13 @@ def export(self, filename): num_functions = len(flamegraph_data.get("children", [])) total_time = flamegraph_data.get("value", 0) string_count = len(self._string_table) + s1 = "" if num_functions == 1 else "s" + s2 = "" if total_time == 1 else "s" + s3 = "" if string_count == 1 else "s" print( - f"Flamegraph data: {num_functions} root functions, total samples: {total_time}, " - f"{string_count} unique strings" + f"Flamegraph data: {num_functions} root function{s1}, " + f"{total_time} total sample{s2}, " + f"{string_count} unique string{s3}" ) if num_functions == 0: From 09e8c382312b145b710dca7072ff2e13fe8c09ab Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sat, 28 Feb 2026 02:24:06 +0000 Subject: [PATCH 262/498] gh-145241: specialize SyntaxError for single trailing-comma with item (#145282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartosz Sławecki --- Grammar/python.gram | 2 + Lib/test/test_syntax.py | 24 ++ ...-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst | 3 + Parser/parser.c | 346 ++++++++++-------- 4 files changed, 221 insertions(+), 154 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index 1212e8640a1a9c..3a91d426c36501 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -1447,6 +1447,8 @@ invalid_import_from_targets: RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after 'import'") } invalid_with_stmt: + | ['async'] 'with' ','.(expression ['as' star_target])+ trailing=',' ':' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(trailing, "the last 'with' item has a trailing comma") } | ['async'] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } | ['async'] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } invalid_with_stmt_indent: diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index e48749626fccad..a3d485c998ac91 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2061,6 +2061,30 @@ Traceback (most recent call last): SyntaxError: trailing comma not allowed without surrounding parentheses +>>> with item,: pass +Traceback (most recent call last): +SyntaxError: the last 'with' item has a trailing comma + +>>> with item as x,: pass +Traceback (most recent call last): +SyntaxError: the last 'with' item has a trailing comma + +>>> with item1, item2,: pass +Traceback (most recent call last): +SyntaxError: the last 'with' item has a trailing comma + +>>> with item1 as x, item2,: pass +Traceback (most recent call last): +SyntaxError: the last 'with' item has a trailing comma + +>>> with item1 as x, item2 as y,: pass +Traceback (most recent call last): +SyntaxError: the last 'with' item has a trailing comma + +>>> with item1, item2 as y,: pass +Traceback (most recent call last): +SyntaxError: the last 'with' item has a trailing comma + >>> import a from b Traceback (most recent call last): SyntaxError: Did you mean to use 'from ... import ...' instead? diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst new file mode 100644 index 00000000000000..a3253132a577ba --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst @@ -0,0 +1,3 @@ +Specialized the parser error for when ``with`` items are followed +by a trailing comma (for example, ``with item,:``), raising a clearer +:exc:`SyntaxError` message. Patch by Pablo Galindo and Bartosz Sławecki. diff --git a/Parser/parser.c b/Parser/parser.c index 37c19c4c9020c8..f8d6d1ce89b54d 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -22,28 +22,28 @@ static KeywordToken *reserved_keywords[] = { (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) { - {"if", 695}, - {"as", 693}, - {"in", 708}, + {"if", 698}, + {"as", 696}, + {"in", 711}, {"or", 589}, {"is", 597}, {NULL, -1}, }, (KeywordToken[]) { {"del", 634}, - {"def", 712}, - {"for", 707}, - {"try", 669}, + {"def", 715}, + {"for", 710}, + {"try", 672}, {"and", 590}, - {"not", 716}, + {"not", 719}, {NULL, -1}, }, (KeywordToken[]) { {"from", 646}, {"pass", 527}, - {"with", 660}, - {"elif", 700}, - {"else", 699}, + {"with", 663}, + {"elif", 703}, + {"else", 702}, {"None", 628}, {"True", 627}, {NULL, -1}, @@ -52,9 +52,9 @@ static KeywordToken *reserved_keywords[] = { {"raise", 632}, {"yield", 588}, {"break", 528}, - {"async", 711}, - {"class", 714}, - {"while", 702}, + {"async", 714}, + {"class", 717}, + {"while", 705}, {"False", 629}, {"await", 598}, {NULL, -1}, @@ -64,12 +64,12 @@ static KeywordToken *reserved_keywords[] = { {"return", 522}, {"assert", 638}, {"global", 530}, - {"except", 690}, + {"except", 693}, {"lambda", 622}, {NULL, -1}, }, (KeywordToken[]) { - {"finally", 686}, + {"finally", 689}, {NULL, -1}, }, (KeywordToken[]) { @@ -1964,7 +1964,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); stmt_ty if_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 695) // token='if' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 698) // token='if' && (if_stmt_var = if_stmt_rule(p)) // if_stmt ) @@ -2048,7 +2048,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); stmt_ty try_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 669) // token='try' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 672) // token='try' && (try_stmt_var = try_stmt_rule(p)) // try_stmt ) @@ -2069,7 +2069,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); stmt_ty while_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 702) // token='while' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 705) // token='while' && (while_stmt_var = while_stmt_rule(p)) // while_stmt ) @@ -4525,7 +4525,7 @@ class_def_raw_rule(Parser *p) asdl_stmt_seq* c; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='class' + (_keyword = _PyPegen_expect_token(p, 717)) // token='class' && (a = _PyPegen_name_token(p)) // NAME && @@ -4692,7 +4692,7 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 712)) // token='def' + (_keyword = _PyPegen_expect_token(p, 715)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4753,9 +4753,9 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 712)) // token='def' + (_keyword_1 = _PyPegen_expect_token(p, 715)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -6093,7 +6093,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6138,7 +6138,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6233,7 +6233,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 700)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 703)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6278,7 +6278,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 700)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 703)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6359,7 +6359,7 @@ else_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword = _PyPegen_expect_token(p, 702)) // token='else' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6438,7 +6438,7 @@ while_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 702)) // token='while' + (_keyword = _PyPegen_expect_token(p, 705)) // token='while' && (a = named_expression_rule(p)) // named_expression && @@ -6538,11 +6538,11 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword = _PyPegen_expect_token(p, 710)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' && (_cut_var = 1) && @@ -6600,13 +6600,13 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 710)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_2 = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 711)) // token='in' && (_cut_var = 1) && @@ -6735,7 +6735,7 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword = _PyPegen_expect_token(p, 663)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -6786,7 +6786,7 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword = _PyPegen_expect_token(p, 663)) // token='with' && (a = (asdl_withitem_seq*)_gather_34_rule(p)) // ','.with_item+ && @@ -6835,9 +6835,9 @@ with_stmt_rule(Parser *p) asdl_withitem_seq* a; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 663)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -6887,9 +6887,9 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 663)) // token='with' && (a = (asdl_withitem_seq*)_gather_34_rule(p)) // ','.with_item+ && @@ -6975,7 +6975,7 @@ with_item_rule(Parser *p) if ( (e = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (t = star_target_rule(p)) // star_target && @@ -7100,7 +7100,7 @@ try_stmt_rule(Parser *p) asdl_stmt_seq* b; asdl_stmt_seq* f; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='try' + (_keyword = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7144,7 +7144,7 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='try' + (_keyword = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7192,7 +7192,7 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='try' + (_keyword = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7291,7 +7291,7 @@ except_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (e = expression_rule(p)) // expression && @@ -7335,11 +7335,11 @@ except_block_rule(Parser *p) expr_ty e; expr_ty t; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (e = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' && (t = _PyPegen_name_token(p)) // NAME && @@ -7381,7 +7381,7 @@ except_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (e = expressions_rule(p)) // expressions && @@ -7422,7 +7422,7 @@ except_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7534,7 +7534,7 @@ except_star_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -7581,13 +7581,13 @@ except_star_block_rule(Parser *p) expr_ty e; expr_ty t; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (e = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' && (t = _PyPegen_name_token(p)) // NAME && @@ -7630,7 +7630,7 @@ except_star_block_rule(Parser *p) asdl_stmt_seq* b; expr_ty e; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -7730,7 +7730,7 @@ finally_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 686)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 689)) // token='finally' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -8038,7 +8038,7 @@ guard_rule(Parser *p) Token * _keyword; expr_ty guard; if ( - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (guard = named_expression_rule(p)) // named_expression ) @@ -8233,7 +8233,7 @@ as_pattern_rule(Parser *p) if ( (pattern = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (target = pattern_capture_target_rule(p)) // pattern_capture_target ) @@ -11647,11 +11647,11 @@ if_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' && (c = expression_rule(p)) // expression ) @@ -12600,7 +12600,7 @@ inversion_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 716)) // token='not' + (_keyword = _PyPegen_expect_token(p, 719)) // token='not' && (a = inversion_rule(p)) // inversion ) @@ -13254,9 +13254,9 @@ notin_bitwise_or_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 716)) // token='not' + (_keyword = _PyPegen_expect_token(p, 719)) // token='not' && - (_keyword_1 = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -13302,7 +13302,7 @@ in_bitwise_or_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword = _PyPegen_expect_token(p, 711)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -13351,7 +13351,7 @@ isnot_bitwise_or_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 597)) // token='is' && - (_keyword_1 = _PyPegen_expect_token(p, 716)) // token='not' + (_keyword_1 = _PyPegen_expect_token(p, 719)) // token='not' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -18010,13 +18010,13 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 710)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_2 = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 711)) // token='in' && (_cut_var = 1) && @@ -18055,11 +18055,11 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword = _PyPegen_expect_token(p, 710)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' && (_cut_var = 1) && @@ -21386,11 +21386,11 @@ expression_without_invalid_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' && (c = expression_rule(p)) // expression ) @@ -21690,7 +21690,7 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && @@ -21723,11 +21723,11 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' && _PyPegen_lookahead_for_expr(0, expression_rule, p) ) @@ -21759,11 +21759,11 @@ invalid_expression_rule(Parser *p) if ( (a = (stmt_ty)_tmp_118_rule(p)) // pass_stmt | break_stmt | continue_stmt && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' && (c = simple_stmt_rule(p)) // simple_stmt ) @@ -21882,11 +21882,11 @@ invalid_if_expression_rule(Parser *p) if ( (disjunction_var = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' && (a = _PyPegen_expect_token(p, 16)) // token='*' ) @@ -21918,11 +21918,11 @@ invalid_if_expression_rule(Parser *p) if ( (disjunction_var = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 702)) // token='else' && (a = _PyPegen_expect_token(p, 35)) // token='**' ) @@ -24050,7 +24050,7 @@ invalid_with_item_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (a = expression_rule(p)) // expression && @@ -24100,13 +24100,13 @@ invalid_for_if_clause_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings void *_tmp_136_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword = _PyPegen_expect_token(p, 710)) // token='for' && (_tmp_136_var = _tmp_136_rule(p)) // bitwise_or ((',' bitwise_or))* ','? && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 708) // token='in' + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 711) // token='in' ) { D(fprintf(stderr, "%*c+ invalid_for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' (bitwise_or ((',' bitwise_or))* ','?) !'in'")); @@ -24152,9 +24152,9 @@ invalid_for_target_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings expr_ty a; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword = _PyPegen_expect_token(p, 710)) // token='for' && (a = star_expressions_rule(p)) // star_expressions ) @@ -24364,7 +24364,7 @@ invalid_dotted_as_name_rule(Parser *p) if ( (dotted_name_var = dotted_name_rule(p)) // dotted_name && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && _PyPegen_lookahead(0, _tmp_139_rule, p) && @@ -24415,7 +24415,7 @@ invalid_import_from_as_name_rule(Parser *p) if ( (name_var = _PyPegen_name_token(p)) // NAME && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && _PyPegen_lookahead(0, _tmp_139_rule, p) && @@ -24515,6 +24515,7 @@ invalid_import_from_targets_rule(Parser *p) } // invalid_with_stmt: +// | 'async'? 'with' ','.(expression ['as' star_target])+ ',' ':' // | 'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE // | 'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE static void * @@ -24529,6 +24530,43 @@ invalid_with_stmt_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; + { // 'async'? 'with' ','.(expression ['as' star_target])+ ',' ':' + if (p->error_indicator) { + p->level--; + 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_141_var; + Token * _keyword; + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * trailing; + if ( + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? + && + (_keyword = _PyPegen_expect_token(p, 663)) // token='with' + && + (_gather_141_var = _gather_141_rule(p)) // ','.(expression ['as' star_target])+ + && + (trailing = _PyPegen_expect_token(p, 12)) // token=',' + && + (_literal = _PyPegen_expect_token(p, 11)) // 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 = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( trailing , "the last 'with' item has a trailing comma" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ',' ':'")); + } { // 'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE if (p->error_indicator) { p->level--; @@ -24541,9 +24579,9 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword = _PyPegen_expect_token(p, 663)) // token='with' && (_gather_141_var = _gather_141_rule(p)) // ','.(expression ['as' star_target])+ && @@ -24579,9 +24617,9 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var_1); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword = _PyPegen_expect_token(p, 663)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -24641,9 +24679,9 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 660)) // token='with' + (a = _PyPegen_expect_token(p, 663)) // token='with' && (_gather_141_var = _gather_141_rule(p)) // ','.(expression ['as' star_target])+ && @@ -24684,9 +24722,9 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 660)) // token='with' + (a = _PyPegen_expect_token(p, 663)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -24749,7 +24787,7 @@ invalid_try_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 669)) // token='try' + (a = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24781,7 +24819,7 @@ invalid_try_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='try' + (_keyword = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24820,7 +24858,7 @@ invalid_try_stmt_rule(Parser *p) Token * b; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='try' + (_keyword = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24828,7 +24866,7 @@ invalid_try_stmt_rule(Parser *p) && (_loop1_36_var = _loop1_36_rule(p)) // except_block+ && - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (b = _PyPegen_expect_token(p, 16)) // token='*' && @@ -24867,7 +24905,7 @@ invalid_try_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings Token * a; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='try' + (_keyword = _PyPegen_expect_token(p, 672)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24875,7 +24913,7 @@ invalid_try_stmt_rule(Parser *p) && (_loop1_37_var = _loop1_37_rule(p)) // except_star_block+ && - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (_opt_var = _tmp_146_rule(p), !p->error_indicator) // [expression ['as' NAME]] && @@ -24932,7 +24970,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty expressions_var; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (a = expression_rule(p)) // expression && @@ -24940,7 +24978,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_keyword_1 = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -24972,7 +25010,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (expression_var = expression_rule(p)) // expression && @@ -25003,7 +25041,7 @@ invalid_except_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -25034,11 +25072,11 @@ invalid_except_stmt_rule(Parser *p) asdl_stmt_seq* block_var; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (expression_var = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' && (a = expression_rule(p)) // expression && @@ -25098,7 +25136,7 @@ invalid_except_star_stmt_rule(Parser *p) expr_ty expressions_var; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25108,7 +25146,7 @@ invalid_except_star_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_keyword_1 = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -25141,7 +25179,7 @@ invalid_except_star_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25175,7 +25213,7 @@ invalid_except_star_stmt_rule(Parser *p) void *_tmp_147_var; Token * a; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25209,13 +25247,13 @@ invalid_except_star_stmt_rule(Parser *p) asdl_stmt_seq* block_var; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (expression_var = expression_rule(p)) // expression && - (_keyword_1 = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword_1 = _PyPegen_expect_token(p, 696)) // token='as' && (a = expression_rule(p)) // expression && @@ -25266,7 +25304,7 @@ invalid_finally_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 686)) // token='finally' + (a = _PyPegen_expect_token(p, 689)) // token='finally' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -25322,7 +25360,7 @@ invalid_except_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (expression_var = expression_rule(p)) // expression && @@ -25358,7 +25396,7 @@ invalid_except_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -25414,7 +25452,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 690)) // token='except' + (a = _PyPegen_expect_token(p, 693)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -25691,7 +25729,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' ) @@ -25721,7 +25759,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (a = expression_rule(p)) // expression ) @@ -25937,7 +25975,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -25968,7 +26006,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty a_1; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 695)) // token='if' + (a = _PyPegen_expect_token(p, 698)) // token='if' && (a_1 = named_expression_rule(p)) // named_expression && @@ -26023,7 +26061,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 700)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 703)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26054,7 +26092,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 700)) // token='elif' + (a = _PyPegen_expect_token(p, 703)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26107,7 +26145,7 @@ invalid_else_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 699)) // token='else' + (a = _PyPegen_expect_token(p, 702)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -26140,13 +26178,13 @@ invalid_else_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword = _PyPegen_expect_token(p, 702)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (block_var = block_rule(p)) // block && - (_keyword_1 = _PyPegen_expect_token(p, 700)) // token='elif' + (_keyword_1 = _PyPegen_expect_token(p, 703)) // token='elif' ) { D(fprintf(stderr, "%*c+ invalid_else_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':' block 'elif'")); @@ -26193,7 +26231,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 702)) // token='while' + (_keyword = _PyPegen_expect_token(p, 705)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26224,7 +26262,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 702)) // token='while' + (a = _PyPegen_expect_token(p, 705)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -26283,13 +26321,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword = _PyPegen_expect_token(p, 710)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 711)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -26324,13 +26362,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 707)) // token='for' + (a = _PyPegen_expect_token(p, 710)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword = _PyPegen_expect_token(p, 708)) // token='in' + (_keyword = _PyPegen_expect_token(p, 711)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -26396,9 +26434,9 @@ invalid_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 712)) // token='def' + (a = _PyPegen_expect_token(p, 715)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -26455,9 +26493,9 @@ invalid_def_raw_rule(Parser *p) asdl_stmt_seq* block_var; expr_ty name_var; if ( - (_opt_var = _PyPegen_expect_token(p, 711), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 714), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 712)) // token='def' + (_keyword = _PyPegen_expect_token(p, 715)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -26521,7 +26559,7 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='class' + (_keyword = _PyPegen_expect_token(p, 717)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -26560,7 +26598,7 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 714)) // token='class' + (a = _PyPegen_expect_token(p, 717)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -28196,7 +28234,7 @@ invalid_arithmetic_rule(Parser *p) && (_tmp_157_var = _tmp_157_rule(p)) // '+' | '-' | '*' | '/' | '%' | '//' | '@' && - (a = _PyPegen_expect_token(p, 716)) // token='not' + (a = _PyPegen_expect_token(p, 719)) // token='not' && (b = inversion_rule(p)) // inversion ) @@ -28245,7 +28283,7 @@ invalid_factor_rule(Parser *p) if ( (_tmp_158_var = _tmp_158_rule(p)) // '+' | '-' | '~' && - (a = _PyPegen_expect_token(p, 716)) // token='not' + (a = _PyPegen_expect_token(p, 719)) // token='not' && (b = factor_rule(p)) // factor ) @@ -28668,7 +28706,7 @@ _tmp_6_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 712)) // token='def' + (_keyword = _PyPegen_expect_token(p, 715)) // token='def' ) { D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); @@ -28706,7 +28744,7 @@ _tmp_6_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -28744,7 +28782,7 @@ _tmp_7_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 714)) // token='class' + (_keyword = _PyPegen_expect_token(p, 717)) // token='class' ) { D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); @@ -28801,7 +28839,7 @@ _tmp_8_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 660)) // token='with' + (_keyword = _PyPegen_expect_token(p, 663)) // token='with' ) { D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); @@ -28820,7 +28858,7 @@ _tmp_8_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -28858,7 +28896,7 @@ _tmp_9_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 707)) // token='for' + (_keyword = _PyPegen_expect_token(p, 710)) // token='for' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); @@ -28877,7 +28915,7 @@ _tmp_9_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 711)) // token='async' + (_keyword = _PyPegen_expect_token(p, 714)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -29578,7 +29616,7 @@ _tmp_21_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -35550,7 +35588,7 @@ _tmp_117_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 699)) // token='else' + (_keyword = _PyPegen_expect_token(p, 702)) // token='else' ) { D(fprintf(stderr, "%*c+ _tmp_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); @@ -37213,7 +37251,7 @@ _tmp_144_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 690)) // token='except' + (_keyword = _PyPegen_expect_token(p, 693)) // token='except' ) { D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); @@ -37232,7 +37270,7 @@ _tmp_144_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 686)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 689)) // token='finally' ) { D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); @@ -38534,7 +38572,7 @@ _tmp_166_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 695)) // token='if' + (_keyword = _PyPegen_expect_token(p, 698)) // token='if' && (z = disjunction_rule(p)) // disjunction ) @@ -39270,7 +39308,7 @@ _tmp_180_rule(Parser *p) Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 693)) // token='as' + (_keyword = _PyPegen_expect_token(p, 696)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) From fdb4b3527f356a84bc00ca32516181016400e567 Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Sat, 28 Feb 2026 02:09:39 -0700 Subject: [PATCH 263/498] gh-145269: simplify bisect.bisect doc example (#145270) Co-authored-by: Pieter Eendebak --------- Co-authored-by: Pieter Eendebak --- Doc/library/bisect.rst | 6 +++--- Lib/test/test_bisect.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 7f75e85a7eb641..2c29a5ec992737 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -200,9 +200,9 @@ example uses :py:func:`~bisect.bisect` to look up a letter grade for an exam sco based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is a 'B', and so on:: - >>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'): - ... i = bisect(breakpoints, score) - ... return grades[i] + >>> def grade(score) + ... i = bisect([60, 70, 80, 90], score) + ... return "FDCBA"[i] ... >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] ['F', 'A', 'C', 'C', 'B', 'A', 'A'] diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index 97204d4cad3871..a7e1f533ff2adc 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -391,9 +391,9 @@ class TestErrorHandlingC(TestErrorHandling, unittest.TestCase): class TestDocExample: def test_grades(self): - def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'): - i = self.module.bisect(breakpoints, score) - return grades[i] + def grade(score): + i = self.module.bisect([60, 70, 80, 90], score) + return "FDCBA"[i] result = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] self.assertEqual(result, ['F', 'A', 'C', 'C', 'B', 'A', 'A']) From 61ebb9911bda6434eb4722310efcab5b5879f0f0 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 28 Feb 2026 13:07:35 +0000 Subject: [PATCH 264/498] Add Stan to 'Dates and times' reviewers (#145360) --- .github/CODEOWNERS | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0f5d830b512865..19cc7050a43f04 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -425,19 +425,19 @@ Lib/dataclasses.py @ericvsmith Lib/test/test_dataclasses/ @ericvsmith # Dates and times -Doc/**/*time.rst @pganssle @abalkin -Doc/library/datetime-* @pganssle -Doc/library/zoneinfo.rst @pganssle -Include/datetime.h @pganssle @abalkin -Include/internal/pycore_time.h @pganssle @abalkin -Lib/test/test_zoneinfo/ @pganssle -Lib/zoneinfo/ @pganssle -Lib/*time.py @pganssle @abalkin -Lib/test/datetimetester.py @pganssle @abalkin -Lib/test/test_*time.py @pganssle @abalkin -Modules/*zoneinfo* @pganssle -Modules/*time* @pganssle @abalkin -Python/pytime.c @pganssle @abalkin +Doc/**/*time.rst @pganssle @abalkin @StanFromIreland +Doc/library/datetime-* @pganssle @StanFromIreland +Doc/library/zoneinfo.rst @pganssle @StanFromIreland +Include/datetime.h @pganssle @abalkin @StanFromIreland +Include/internal/pycore_time.h @pganssle @abalkin @StanFromIreland +Lib/test/test_zoneinfo/ @pganssle @StanFromIreland +Lib/zoneinfo/ @pganssle @StanFromIreland +Lib/*time.py @pganssle @abalkin @StanFromIreland +Lib/test/datetimetester.py @pganssle @abalkin @StanFromIreland +Lib/test/test_*time.py @pganssle @abalkin @StanFromIreland +Modules/*zoneinfo* @pganssle @StanFromIreland +Modules/*time* @pganssle @abalkin @StanFromIreland +Python/pytime.c @pganssle @abalkin @StanFromIreland # Dbm Doc/library/dbm.rst @corona10 @erlend-aasland @serhiy-storchaka From 0598f4a8999b96409e0a2bf9c480afc76a876860 Mon Sep 17 00:00:00 2001 From: Maksym Kasimov <39828623+kasimov-maxim@users.noreply.github.com> Date: Sat, 28 Feb 2026 19:49:04 +0200 Subject: [PATCH 265/498] gh-142352: Fix `asyncio` `start_tls()` to transfer buffered data from StreamReader (#142354) Co-authored-by: Kumar Aditya --- Lib/asyncio/base_events.py | 11 +++++ Lib/test/test_asyncio/test_streams.py | 42 +++++++++++++++++++ ...2-06-16-14-18.gh-issue-142352.pW5HLX88.rst | 4 ++ 3 files changed, 57 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 6619c87bcf5b93..b565b1d8a9e226 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1345,6 +1345,17 @@ async def start_tls(self, transport, protocol, sslcontext, *, # have a chance to get called before "ssl_protocol.connection_made()". transport.pause_reading() + # gh-142352: move buffered StreamReader data to SSLProtocol + if server_side: + from .streams import StreamReaderProtocol + if isinstance(protocol, StreamReaderProtocol): + stream_reader = getattr(protocol, '_stream_reader', None) + if stream_reader is not None: + buffer = stream_reader._buffer + if buffer: + ssl_protocol._incoming.write(buffer) + buffer.clear() + transport.set_protocol(ssl_protocol) conmade_cb = self.call_soon(ssl_protocol.connection_made, transport) resume_cb = self.call_soon(transport.resume_reading) diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index f93ee54abc6469..cae8c7c6f7c94c 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -819,6 +819,48 @@ async def client(addr): self.assertEqual(msg1, b"hello world 1!\n") self.assertEqual(msg2, b"hello world 2!\n") + @unittest.skipIf(ssl is None, 'No ssl module') + def test_start_tls_buffered_data(self): + # gh-142352: test start_tls() with buffered data + + async def server_handler(client_reader, client_writer): + # Wait for TLS ClientHello to be buffered before start_tls(). + await client_reader._wait_for_data('test_start_tls_buffered_data'), + self.assertTrue(client_reader._buffer) + await client_writer.start_tls(test_utils.simple_server_sslcontext()) + + line = await client_reader.readline() + self.assertEqual(line, b"ping\n") + client_writer.write(b"pong\n") + await client_writer.drain() + client_writer.close() + await client_writer.wait_closed() + + async def client(addr): + reader, writer = await asyncio.open_connection(*addr) + await writer.start_tls(test_utils.simple_client_sslcontext()) + + writer.write(b"ping\n") + await writer.drain() + line = await reader.readline() + self.assertEqual(line, b"pong\n") + writer.close() + await writer.wait_closed() + + async def run_test(): + server = await asyncio.start_server( + server_handler, socket_helper.HOSTv4, 0) + server_addr = server.sockets[0].getsockname() + + await client(server_addr) + server.close() + await server.wait_closed() + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(run_test()) + self.assertEqual(messages, []) + def test_streamreader_constructor_without_loop(self): with self.assertRaisesRegex(RuntimeError, 'no current event loop'): asyncio.StreamReader() diff --git a/Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst b/Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst new file mode 100644 index 00000000000000..13e38b118175b4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst @@ -0,0 +1,4 @@ +Fix :meth:`asyncio.StreamWriter.start_tls` to transfer buffered data from +:class:`~asyncio.StreamReader` to the SSL layer, preventing data loss when +upgrading a connection to TLS mid-stream (e.g., when implementing PROXY +protocol support). From ef41f73611d413f81c5f3698398820fbf044c9b2 Mon Sep 17 00:00:00 2001 From: Thomas Kowalski Date: Sat, 28 Feb 2026 21:37:15 +0100 Subject: [PATCH 266/498] gh-145349: Do not install `ccache` (#145350) --- .github/workflows/build.yml | 14 -------------- .github/workflows/posix-deps-apt.sh | 1 - .github/workflows/reusable-san.yml | 3 --- .github/workflows/reusable-ubuntu.yml | 3 --- .github/workflows/reusable-wasi.yml | 2 -- 5 files changed, 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d777f35ac208fd..91235c0309d29f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -111,8 +111,6 @@ jobs: run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV" - name: Install dependencies run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Add ccache to PATH - run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Configure CPython run: | # Build Python with the libpython dynamic library @@ -299,9 +297,6 @@ jobs: - name: Install OpenSSL if: steps.cache-openssl.outputs.cache-hit != 'true' run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Configure CPython run: ./configure CFLAGS="-fdiagnostics-format=json" --config-cache --enable-slower-safety --with-pydebug --with-openssl="$OPENSSL_DIR" - name: Build CPython @@ -356,9 +351,6 @@ jobs: --base-directory "$MULTISSL_DIR" \ --awslc ${{ matrix.awslc_ver }} \ --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Configure CPython run: | ./configure CFLAGS="-fdiagnostics-format=json" \ @@ -459,9 +451,6 @@ jobs: - name: Install OpenSSL if: steps.cache-openssl.outputs.cache-hit != 'true' run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Setup directory envs for out-of-tree builds run: | echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV" @@ -577,9 +566,6 @@ jobs: - name: Install OpenSSL if: steps.cache-openssl.outputs.cache-hit != 'true' run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Configure CPython run: ./configure --config-cache --with-address-sanitizer --without-pymalloc --with-openssl="$OPENSSL_DIR" - name: Build CPython diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh index 0b64367e6c4562..a2fac7c66db1d9 100755 --- a/.github/workflows/posix-deps-apt.sh +++ b/.github/workflows/posix-deps-apt.sh @@ -4,7 +4,6 @@ apt-get update apt-get -yq install \ build-essential \ pkg-config \ - ccache \ cmake \ gdb \ lcov \ diff --git a/.github/workflows/reusable-san.yml b/.github/workflows/reusable-san.yml index 49876cf49260d9..b70f9b4b0d6259 100644 --- a/.github/workflows/reusable-san.yml +++ b/.github/workflows/reusable-san.yml @@ -66,9 +66,6 @@ jobs: env: SANITIZER: ${{ inputs.sanitizer }} SAN_LOG_OPTION: log_path=${{ github.workspace }}/san_log - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Configure CPython run: >- ./configure diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml index 4bb4f535acb360..9032ac016e4810 100644 --- a/.github/workflows/reusable-ubuntu.yml +++ b/.github/workflows/reusable-ubuntu.yml @@ -63,9 +63,6 @@ jobs: - name: Install OpenSSL if: steps.cache-openssl.outputs.cache-hit != 'true' run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: Setup directory envs for out-of-tree builds run: | echo "CPYTHON_RO_SRCDIR=$(realpath -m "${GITHUB_WORKSPACE}"/../cpython-ro-srcdir)" >> "$GITHUB_ENV" diff --git a/.github/workflows/reusable-wasi.yml b/.github/workflows/reusable-wasi.yml index 68c5ef14cfe212..fb62f0d5164e07 100644 --- a/.github/workflows/reusable-wasi.yml +++ b/.github/workflows/reusable-wasi.yml @@ -38,8 +38,6 @@ jobs: mkdir "${WASI_SDK_PATH}" && \ curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-arm64-linux.tar.gz" | \ tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip - - name: "Add ccache to PATH" - run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" - name: "Install Python" uses: actions/setup-python@v6 with: From f1446d39221b8fc0eb8224d91a020d5c8bc1cd70 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sat, 28 Feb 2026 15:12:05 -0600 Subject: [PATCH 267/498] Destroy the turtle window after its doctests finish (GH-125294) --- Doc/library/turtle.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 234042c661f51a..20c659756fe1c1 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -16,6 +16,9 @@ import os os.remove("my_drawing.ps") + # Destroy the turtle window after tests are complete + # Imported via star import in testsetup + bye() -------------- From 50c2e23f69943a6f70d98c4d0bcf1ac37bcaf0d3 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sat, 28 Feb 2026 16:14:46 -0600 Subject: [PATCH 268/498] gh-144551: Update Android builds to use OpenSSL 3.5.5 (GH-145371) --- Android/android.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Android/android.py b/Android/android.py index 0a894a958a0165..b644be9cc64c7a 100755 --- a/Android/android.py +++ b/Android/android.py @@ -208,7 +208,7 @@ def make_build_python(context): def unpack_deps(host, prefix_dir): os.chdir(prefix_dir) deps_url = "https://github.com/beeware/cpython-android-source-deps/releases/download" - for name_ver in ["bzip2-1.0.8-3", "libffi-3.4.4-3", "openssl-3.0.19-1", + for name_ver in ["bzip2-1.0.8-3", "libffi-3.4.4-3", "openssl-3.5.5-0", "sqlite-3.50.4-0", "xz-5.4.6-1", "zstd-1.5.7-1"]: filename = f"{name_ver}-{host}.tar.gz" download(f"{deps_url}/{name_ver}/{filename}") From a1ec7467874207957519bb53e16efdaa7e03cb5b Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sat, 28 Feb 2026 16:26:47 -0600 Subject: [PATCH 269/498] gh-144551: Update iOS builds to use OpenSSL 3.5.5 (GH-145372) --- Apple/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apple/__main__.py b/Apple/__main__.py index 253bdfaab5520c..3261f368a88fc0 100644 --- a/Apple/__main__.py +++ b/Apple/__main__.py @@ -316,7 +316,7 @@ def unpack_deps( for name_ver in [ "BZip2-1.0.8-2", "libFFI-3.4.7-2", - "OpenSSL-3.0.19-1", + "OpenSSL-3.5.5-1", "XZ-5.6.4-2", "mpdecimal-4.0.0-2", "zstd-1.5.7-1", From 3484ef60039be38096ef617ba096970809917d03 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 28 Feb 2026 19:52:04 -0800 Subject: [PATCH 270/498] gh-145033: Implement PEP 747 (#145034) --- Doc/library/typing.rst | 29 ++++++++ Doc/whatsnew/3.15.rst | 19 +++++ Lib/test/test_typing.py | 72 ++++++++++++++++++- Lib/typing.py | 36 +++++++++- ...-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst | 2 + 5 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index ef44701bb251dd..09e9103e1b80d0 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1524,6 +1524,35 @@ These can be used as types in annotations. They all support subscription using .. versionadded:: 3.9 +.. data:: TypeForm + + A special form representing the value that results from evaluating a + type expression. + + This value encodes the information supplied in the type expression, and + it represents the type described by that type expression. + + When used in a type expression, ``TypeForm`` describes a set of type form + objects. It accepts a single type argument, which must be a valid type + expression. ``TypeForm[T]`` describes the set of all type form objects that + represent the type ``T`` or types assignable to ``T``. + + ``TypeForm(obj)`` simply returns ``obj`` unchanged. This is useful for + explicitly marking a value as a type form for static type checkers. + + Example:: + + from typing import Any, TypeForm + + def cast[T](typ: TypeForm[T], value: Any) -> T: ... + + reveal_type(cast(int, "x")) # Revealed type is "int" + + See :pep:`747` for details. + + .. versionadded:: 3.15 + + .. data:: TypeIs Special typing construct for marking user-defined type predicate functions. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 163d50d7e20e20..63ef5f84301794 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1431,6 +1431,25 @@ threading typing ------ +* :pep:`747`: Add :data:`~typing.TypeForm`, a new special form for annotating + values that are themselves type expressions. + ``TypeForm[T]`` means "a type form object describing ``T`` (or a type + assignable to ``T``)". At runtime, ``TypeForm(x)`` simply returns ``x``, + which allows explicit annotation of type-form values without changing + behavior. + + This helps libraries that accept user-provided type expressions + (for example ``int``, ``str | None``, :class:`~typing.TypedDict` + classes, or ``list[int]``) expose precise signatures: + + .. code-block:: python + + from typing import Any, TypeForm + + def cast[T](typ: TypeForm[T], value: Any) -> T: ... + + (Contributed by Jelle Zijlstra in :gh:`145033`.) + * The undocumented keyword argument syntax for creating :class:`~typing.NamedTuple` classes (for example, ``Point = NamedTuple("Point", x=int, y=int)``) is no longer supported. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 50938eadc8f9f3..c6f08ff8a052ab 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -42,7 +42,7 @@ from typing import Self, LiteralString from typing import TypeAlias from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs -from typing import TypeGuard, TypeIs, NoDefault +from typing import TypeForm, TypeGuard, TypeIs, NoDefault import abc import textwrap import typing @@ -5890,6 +5890,7 @@ def test_subclass_special_form(self): Final[int], Literal[1, 2], Concatenate[int, ParamSpec("P")], + TypeForm[int], TypeGuard[int], TypeIs[range], ): @@ -7358,6 +7359,7 @@ class C(Generic[T]): pass self.assertEqual(get_args(Required[int]), (int,)) self.assertEqual(get_args(NotRequired[int]), (int,)) self.assertEqual(get_args(TypeAlias), ()) + self.assertEqual(get_args(TypeForm[int]), (int,)) self.assertEqual(get_args(TypeGuard[int]), (int,)) self.assertEqual(get_args(TypeIs[range]), (range,)) Ts = TypeVarTuple('Ts') @@ -10646,6 +10648,72 @@ def test_no_isinstance(self): issubclass(int, TypeIs) +class TypeFormTests(BaseTestCase): + def test_basics(self): + TypeForm[int] # OK + self.assertEqual(TypeForm[int], TypeForm[int]) + + def foo(arg) -> TypeForm[int]: ... + self.assertEqual(gth(foo), {'return': TypeForm[int]}) + + with self.assertRaises(TypeError): + TypeForm[int, str] + + def test_repr(self): + self.assertEqual(repr(TypeForm), 'typing.TypeForm') + cv = TypeForm[int] + self.assertEqual(repr(cv), 'typing.TypeForm[int]') + cv = TypeForm[Employee] + self.assertEqual(repr(cv), 'typing.TypeForm[%s.Employee]' % __name__) + cv = TypeForm[tuple[int]] + self.assertEqual(repr(cv), 'typing.TypeForm[tuple[int]]') + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(TypeForm)): + pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class D(type(TypeForm[int])): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeForm'): + class E(TypeForm): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeForm\[int\]'): + class F(TypeForm[int]): + pass + + def test_call(self): + objs = [ + 1, + "int", + int, + tuple[int, str], + Tuple[int, str], + ] + for obj in objs: + with self.subTest(obj=obj): + self.assertIs(TypeForm(obj), obj) + + with self.assertRaises(TypeError): + TypeForm() + with self.assertRaises(TypeError): + TypeForm("too", "many") + + def test_cannot_init_type(self): + with self.assertRaises(TypeError): + type(TypeForm)() + with self.assertRaises(TypeError): + type(TypeForm[Optional[int]])() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, TypeForm[int]) + with self.assertRaises(TypeError): + issubclass(int, TypeForm) + + SpecialAttrsP = typing.ParamSpec('SpecialAttrsP') SpecialAttrsT = typing.TypeVar('SpecialAttrsT', int, float, complex) @@ -10747,6 +10815,7 @@ def test_special_attrs(self): typing.Never: 'Never', typing.Optional: 'Optional', typing.TypeAlias: 'TypeAlias', + typing.TypeForm: 'TypeForm', typing.TypeGuard: 'TypeGuard', typing.TypeIs: 'TypeIs', typing.TypeVar: 'TypeVar', @@ -10761,6 +10830,7 @@ def test_special_attrs(self): typing.Literal[1, 2]: 'Literal', typing.Literal[True, 2]: 'Literal', typing.Optional[Any]: 'Union', + typing.TypeForm[Any]: 'TypeForm', typing.TypeGuard[Any]: 'TypeGuard', typing.TypeIs[Any]: 'TypeIs', typing.Union[Any]: 'Any', diff --git a/Lib/typing.py b/Lib/typing.py index 2dfa6d3b1499ca..e78fb8b71a996c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -155,6 +155,7 @@ 'Text', 'TYPE_CHECKING', 'TypeAlias', + 'TypeForm', 'TypeGuard', 'TypeIs', 'TypeAliasType', @@ -588,6 +589,13 @@ def __getitem__(self, parameters): return self._getitem(self, *parameters) +class _TypeFormForm(_SpecialForm, _root=True): + # TypeForm(X) is equivalent to X but indicates to the type checker + # that the object is a TypeForm. + def __call__(self, obj, /): + return obj + + class _AnyMeta(type): def __instancecheck__(self, obj): if self is Any: @@ -895,6 +903,31 @@ def func1(val: list[object]): return _GenericAlias(self, (item,)) +@_TypeFormForm +def TypeForm(self, parameters): + """A special form representing the value that results from the evaluation + of a type expression. + + This value encodes the information supplied in the type expression, and it + represents the type described by that type expression. + + When used in a type expression, TypeForm describes a set of type form + objects. It accepts a single type argument, which must be a valid type + expression. ``TypeForm[T]`` describes the set of all type form objects that + represent the type T or types that are assignable to T. + + Usage:: + + def cast[T](typ: TypeForm[T], value: Any) -> T: ... + + reveal_type(cast(int, "x")) # int + + See PEP 747 for more information. + """ + item = _type_check(parameters, f'{self} accepts only single type.') + return _GenericAlias(self, (item,)) + + @_SpecialForm def TypeIs(self, parameters): """Special typing construct for marking user-defined type predicate functions. @@ -1348,10 +1381,11 @@ class _GenericAlias(_BaseGenericAlias, _root=True): # A = Callable[[], None] # _CallableGenericAlias # B = Callable[[T], None] # _CallableGenericAlias # C = B[int] # _CallableGenericAlias - # * Parameterized `Final`, `ClassVar`, `TypeGuard`, and `TypeIs`: + # * Parameterized `Final`, `ClassVar`, `TypeForm`, `TypeGuard`, and `TypeIs`: # # All _GenericAlias # Final[int] # ClassVar[float] + # TypeForm[bytes] # TypeGuard[bool] # TypeIs[range] diff --git a/Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst b/Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst new file mode 100644 index 00000000000000..6f496bb30e1686 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst @@ -0,0 +1,2 @@ +Add :data:`typing.TypeForm`, implementing :pep:`747`. Patch by Jelle +Zijlstra. From c9b96b1e6fea13dc2879dcc626015c06dc0056ac Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 1 Mar 2026 03:18:23 -0600 Subject: [PATCH 271/498] gh-136728: Combine OpenSSL and AWS-LC CI configurations (#144805) --- .github/workflows/build.yml | 116 +++++++++++------------------------- Tools/ssl/multissltests.py | 5 +- 2 files changed, 39 insertions(+), 82 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 91235c0309d29f..c017ee04d67f07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -253,8 +253,8 @@ jobs: os: ${{ matrix.os }} test-opts: ${{ matrix.test-opts || '' }} - build-ubuntu-ssltests-openssl: - name: 'Ubuntu SSL tests with OpenSSL' + build-ubuntu-ssltests: + name: 'Ubuntu SSL tests' runs-on: ${{ matrix.os }} timeout-minutes: 60 needs: build-context @@ -263,16 +263,25 @@ jobs: fail-fast: false matrix: os: [ubuntu-24.04] - # Keep 1.1.1w in our list despite it being upstream EOL and otherwise - # unsupported as it most resembles other 1.1.1-work-a-like ssl APIs - # supported by important vendors such as AWS-LC. - openssl_ver: [1.1.1w, 3.0.19, 3.3.6, 3.4.4, 3.5.5, 3.6.1] - # See Tools/ssl/make_ssl_data.py for notes on adding a new version + ssllib: + # See Tools/ssl/make_ssl_data.py for notes on adding a new version + ## OpenSSL + # Keep 1.1.1w in our list despite it being upstream EOL and otherwise + # unsupported as it most resembles other 1.1.1-work-a-like ssl APIs + # supported by important vendors such as AWS-LC. + - { name: openssl, version: 1.1.1w } + - { name: openssl, version: 3.0.19 } + - { name: openssl, version: 3.3.6 } + - { name: openssl, version: 3.4.4 } + - { name: openssl, version: 3.5.5 } + - { name: openssl, version: 3.6.1 } + ## AWS-LC + - { name: aws-lc, version: 1.68.0 } env: - OPENSSL_VER: ${{ matrix.openssl_ver }} + SSLLIB_VER: ${{ matrix.ssllib.version }} MULTISSL_DIR: ${{ github.workspace }}/multissl - OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} - LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib + SSLLIB_DIR: ${{ github.workspace }}/multissl/${{ matrix.ssllib.name }}/${{ matrix.ssllib.version }} + LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/${{ matrix.ssllib.name }}/${{ matrix.ssllib.version }}/lib steps: - uses: actions/checkout@v6 with: @@ -283,73 +292,19 @@ jobs: run: echo "::add-matcher::.github/problem-matchers/gcc.json" - name: Install dependencies run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Configure OpenSSL env vars - run: | - echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV" - echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> "$GITHUB_ENV" - echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> "$GITHUB_ENV" - - name: 'Restore OpenSSL build' - id: cache-openssl - uses: actions/cache@v5 - with: - path: ./multissl/openssl/${{ env.OPENSSL_VER }} - key: ${{ matrix.os }}-multissl-openssl-${{ env.OPENSSL_VER }} - - name: Install OpenSSL - if: steps.cache-openssl.outputs.cache-hit != 'true' - run: python3 Tools/ssl/multissltests.py --steps=library --base-directory "$MULTISSL_DIR" --openssl "$OPENSSL_VER" --system Linux - - name: Configure CPython - run: ./configure CFLAGS="-fdiagnostics-format=json" --config-cache --enable-slower-safety --with-pydebug --with-openssl="$OPENSSL_DIR" - - name: Build CPython - run: make -j4 - - name: Display build info - run: make pythoninfo - - name: SSL tests - run: ./python Lib/test/ssltests.py - - build-ubuntu-ssltests-awslc: - name: 'Ubuntu SSL tests with AWS-LC' - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - needs: build-context - if: needs.build-context.outputs.run-ubuntu == 'true' - strategy: - fail-fast: false - matrix: - os: [ubuntu-24.04] - awslc_ver: [1.55.0] - env: - AWSLC_VER: ${{ matrix.awslc_ver}} - MULTISSL_DIR: ${{ github.workspace }}/multissl - OPENSSL_DIR: ${{ github.workspace }}/multissl/aws-lc/${{ matrix.awslc_ver }} - LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/aws-lc/${{ matrix.awslc_ver }}/lib - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Runner image version - run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV" - - name: Register gcc problem matcher - run: echo "::add-matcher::.github/problem-matchers/gcc.json" - - name: Install dependencies - run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Configure SSL lib env vars - run: | - echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV" - echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/aws-lc/${AWSLC_VER}" >> "$GITHUB_ENV" - echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/aws-lc/${AWSLC_VER}/lib" >> "$GITHUB_ENV" - - name: 'Restore AWS-LC build' - id: cache-aws-lc + - name: 'Restore SSL library build' + id: cache-ssl-lib uses: actions/cache@v5 with: - path: ./multissl/aws-lc/${{ matrix.awslc_ver }} - key: ${{ matrix.os }}-multissl-aws-lc-${{ matrix.awslc_ver }} - - name: Install AWS-LC - if: steps.cache-aws-lc.outputs.cache-hit != 'true' + path: ./multissl/${{ matrix.ssllib.name }}/${{ matrix.ssllib.version }} + key: ${{ matrix.os }}-multissl-${{ matrix.ssllib.name }}-${{ matrix.ssllib.version }} + - name: Install SSL Library + if: steps.cache-ssl-lib.outputs.cache-hit != 'true' run: | python3 Tools/ssl/multissltests.py \ --steps=library \ --base-directory "$MULTISSL_DIR" \ - --awslc ${{ matrix.awslc_ver }} \ + '--${{ matrix.ssllib.name }}' '${{ matrix.ssllib.version }}' \ --system Linux - name: Configure CPython run: | @@ -357,15 +312,17 @@ jobs: --config-cache \ --enable-slower-safety \ --with-pydebug \ - --with-openssl="$OPENSSL_DIR" \ + --with-openssl="$SSLLIB_DIR" \ --with-builtin-hashlib-hashes=blake2 \ --with-ssl-default-suites=openssl - name: Build CPython - run: make -j + run: make -j4 - name: Display build info run: make pythoninfo - - name: Verify python is linked to AWS-LC - run: ./python -c 'import ssl; print(ssl.OPENSSL_VERSION)' | grep AWS-LC + - name: Verify python is linked to the right lib + run: | + ./python -c 'import ssl; print(ssl.OPENSSL_VERSION)' \ + | grep -iE '${{ matrix.ssllib.name }}.*${{ matrix.ssllib.version }}' - name: SSL tests run: ./python Lib/test/ssltests.py @@ -691,8 +648,7 @@ jobs: - build-windows-msi - build-macos - build-ubuntu - - build-ubuntu-ssltests-awslc - - build-ubuntu-ssltests-openssl + - build-ubuntu-ssltests - build-ios - build-wasi - test-hypothesis @@ -709,8 +665,7 @@ jobs: allowed-failures: >- build-android, build-windows-msi, - build-ubuntu-ssltests-awslc, - build-ubuntu-ssltests-openssl, + build-ubuntu-ssltests, test-hypothesis, cifuzz, allowed-skips: >- @@ -741,8 +696,7 @@ jobs: !fromJSON(needs.build-context.outputs.run-ubuntu) && ' build-ubuntu, - build-ubuntu-ssltests-awslc, - build-ubuntu-ssltests-openssl, + build-ubuntu-ssltests, test-hypothesis, build-asan, build-san, diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index a08e0518f457f5..3b4507c6771b69 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -64,7 +64,7 @@ ] AWSLC_RECENT_VERSIONS = [ - "1.55.0", + "1.68.0", ] # store files in ../multissl @@ -108,7 +108,10 @@ ).format(LIBRESSL_RECENT_VERSIONS, LIBRESSL_OLD_VERSIONS) ) parser.add_argument( + '--aws-lc', + # Soft-deprecated alias '--awslc', + dest='awslc', nargs='+', default=(), help=( From 6c417e44c995eb57e8266e18eb8aeeb2ba0e61ac Mon Sep 17 00:00:00 2001 From: edson duarte Date: Sun, 1 Mar 2026 08:59:02 -0300 Subject: [PATCH 272/498] gh-140715: Improve class reference links on datetime.rst (#123980) Co-authored-by: Erlend E. Aasland Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/datetime.rst | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index f27844c98ccff6..ebe3c3576c0979 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -60,7 +60,7 @@ understand and to work with, at the cost of ignoring some aspects of reality. For applications requiring aware objects, :class:`.datetime` and :class:`.time` objects have an optional time zone information attribute, :attr:`!tzinfo`, that -can be set to an instance of a subclass of the abstract :class:`tzinfo` class. +can be set to an instance of a subclass of the abstract :class:`!tzinfo` class. These :class:`tzinfo` objects capture information about the offset from UTC time, the time zone name, and whether daylight saving time is in effect. @@ -432,9 +432,9 @@ objects (see below). .. versionchanged:: 3.2 Floor division and true division of a :class:`timedelta` object by another - :class:`timedelta` object are now supported, as are remainder operations and + :class:`!timedelta` object are now supported, as are remainder operations and the :func:`divmod` function. True division and multiplication of a - :class:`timedelta` object by a :class:`float` object are now supported. + :class:`!timedelta` object by a :class:`float` object are now supported. :class:`timedelta` objects support equality and order comparisons. @@ -705,7 +705,7 @@ Notes: In other words, ``date1 < date2`` if and only if ``date1.toordinal() < date2.toordinal()``. - Order comparison between a :class:`!date` object that is not also a + Order comparison between a :class:`date` object that is not also a :class:`.datetime` instance and a :class:`!datetime` object raises :exc:`TypeError`. @@ -921,7 +921,7 @@ from a :class:`date` object and a :class:`.time` object. Like a :class:`date` object, :class:`.datetime` assumes the current Gregorian calendar extended in both directions; like a :class:`.time` object, -:class:`.datetime` assumes there are exactly 3600\*24 seconds in every day. +:class:`!datetime` assumes there are exactly 3600\*24 seconds in every day. Constructor: @@ -1097,7 +1097,7 @@ Other constructors, all class methods: are equal to the given :class:`.time` object's. If the *tzinfo* argument is provided, its value is used to set the :attr:`.tzinfo` attribute of the result, otherwise the :attr:`~.time.tzinfo` attribute of the *time* argument - is used. If the *date* argument is a :class:`.datetime` object, its time components + is used. If the *date* argument is a :class:`!datetime` object, its time components and :attr:`.tzinfo` attributes are ignored. For any :class:`.datetime` object ``d``, @@ -1303,7 +1303,7 @@ Supported operations: datetime, and no time zone adjustments are done even if the input is aware. (3) - Subtraction of a :class:`.datetime` from a :class:`.datetime` is defined only if + Subtraction of a :class:`.datetime` from a :class:`!datetime` is defined only if both operands are naive, or if both are aware. If one is aware and the other is naive, :exc:`TypeError` is raised. @@ -1321,7 +1321,7 @@ Supported operations: :class:`.datetime` objects are equal if they represent the same date and time, taking into account the time zone. - Naive and aware :class:`!datetime` objects are never equal. + Naive and aware :class:`.datetime` objects are never equal. If both comparands are aware, and have the same :attr:`!tzinfo` attribute, the :attr:`!tzinfo` and :attr:`~.datetime.fold` attributes are ignored and @@ -1329,7 +1329,7 @@ Supported operations: If both comparands are aware and have different :attr:`~.datetime.tzinfo` attributes, the comparison acts as comparands were first converted to UTC datetimes except that the implementation never overflows. - :class:`!datetime` instances in a repeated interval are never equal to + :class:`.datetime` instances in a repeated interval are never equal to :class:`!datetime` instances in other time zone. (5) @@ -1529,7 +1529,7 @@ Instance methods: Naive :class:`.datetime` instances are assumed to represent local time and this method relies on platform C functions to perform - the conversion. Since :class:`.datetime` supports a wider range of + the conversion. Since :class:`!datetime` supports a wider range of values than the platform C functions on many platforms, this method may raise :exc:`OverflowError` or :exc:`OSError` for times far in the past or far in the future. @@ -1995,7 +1995,7 @@ Instance methods: Return a new :class:`.time` with the same values, but with specified parameters updated. Note that ``tzinfo=None`` can be specified to create a - naive :class:`.time` from an aware :class:`.time`, without conversion of the + naive :class:`!time` from an aware :class:`!time`, without conversion of the time data. :class:`.time` objects are also supported by generic function @@ -2139,14 +2139,14 @@ Examples of working with a :class:`.time` object:: An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the constructors for :class:`.datetime` and :class:`.time` objects. The latter objects - view their attributes as being in local time, and the :class:`tzinfo` object + view their attributes as being in local time, and the :class:`!tzinfo` object supports methods revealing offset of local time from UTC, the name of the time zone, and DST offset, all relative to a date or time object passed to them. You need to derive a concrete subclass, and (at least) supply implementations of the standard :class:`tzinfo` methods needed by the :class:`.datetime` methods you use. The :mod:`!datetime` module provides - :class:`timezone`, a simple concrete subclass of :class:`tzinfo` which can + :class:`timezone`, a simple concrete subclass of :class:`!tzinfo` which can represent time zones with fixed offset from UTC such as UTC itself or North American EST and EDT. @@ -2209,11 +2209,11 @@ Examples of working with a :class:`.time` object:: ``tz.utcoffset(dt) - tz.dst(dt)`` must return the same result for every :class:`.datetime` *dt* with ``dt.tzinfo == - tz``. For sane :class:`tzinfo` subclasses, this expression yields the time + tz``. For sane :class:`!tzinfo` subclasses, this expression yields the time zone's "standard offset", which should not depend on the date or the time, but only on geographic location. The implementation of :meth:`datetime.astimezone` relies on this, but cannot detect violations; it's the programmer's - responsibility to ensure it. If a :class:`tzinfo` subclass cannot guarantee + responsibility to ensure it. If a :class:`!tzinfo` subclass cannot guarantee this, it may be able to override the default implementation of :meth:`tzinfo.fromutc` to work correctly with :meth:`~.datetime.astimezone` regardless. @@ -2250,17 +2250,17 @@ Examples of working with a :class:`.time` object:: valid replies. Return ``None`` if a string name isn't known. Note that this is a method rather than a fixed string primarily because some :class:`tzinfo` subclasses will wish to return different names depending on the specific value - of *dt* passed, especially if the :class:`tzinfo` class is accounting for + of *dt* passed, especially if the :class:`!tzinfo` class is accounting for daylight time. The default implementation of :meth:`tzname` raises :exc:`NotImplementedError`. These methods are called by a :class:`.datetime` or :class:`.time` object, in -response to their methods of the same names. A :class:`.datetime` object passes -itself as the argument, and a :class:`.time` object passes ``None`` as the +response to their methods of the same names. A :class:`!datetime` object passes +itself as the argument, and a :class:`!time` object passes ``None`` as the argument. A :class:`tzinfo` subclass's methods should therefore be prepared to -accept a *dt* argument of ``None``, or of class :class:`.datetime`. +accept a *dt* argument of ``None``, or of class :class:`!datetime`. When ``None`` is passed, it's up to the class designer to decide the best response. For example, returning ``None`` is appropriate if the class wishes to @@ -2268,10 +2268,10 @@ say that time objects don't participate in the :class:`tzinfo` protocols. It may be more useful for ``utcoffset(None)`` to return the standard UTC offset, as there is no other convention for discovering the standard offset. -When a :class:`.datetime` object is passed in response to a :class:`.datetime` +When a :class:`.datetime` object is passed in response to a :class:`!datetime` method, ``dt.tzinfo`` is the same object as *self*. :class:`tzinfo` methods can -rely on this, unless user code calls :class:`tzinfo` methods directly. The -intent is that the :class:`tzinfo` methods interpret *dt* as being in local +rely on this, unless user code calls :class:`!tzinfo` methods directly. The +intent is that the :class:`!tzinfo` methods interpret *dt* as being in local time, and not need worry about objects in other time zones. There is one more :class:`tzinfo` method that a subclass may wish to override: @@ -2381,7 +2381,7 @@ Note that the :class:`.datetime` instances that differ only by the value of the Applications that can't bear wall-time ambiguities should explicitly check the value of the :attr:`~.datetime.fold` attribute or avoid using hybrid :class:`tzinfo` subclasses; there are no ambiguities when using :class:`timezone`, -or any other fixed-offset :class:`tzinfo` subclass (such as a class representing +or any other fixed-offset :class:`!tzinfo` subclass (such as a class representing only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). .. seealso:: From 976808505a123539baeab517a87a7b2a5c7f2386 Mon Sep 17 00:00:00 2001 From: Thomas Kowalski Date: Sun, 1 Mar 2026 16:24:42 +0100 Subject: [PATCH 273/498] gh-145351: use `--no-install-recommends` (#145352) --- .github/workflows/posix-deps-apt.sh | 4 ++-- .github/workflows/regen-abidump.sh | 2 +- .github/workflows/reusable-docs.yml | 2 +- .github/workflows/reusable-ubuntu.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh index a2fac7c66db1d9..7994a01ee4624e 100755 --- a/.github/workflows/posix-deps-apt.sh +++ b/.github/workflows/posix-deps-apt.sh @@ -1,7 +1,7 @@ #!/bin/sh apt-get update -apt-get -yq install \ +apt-get -yq --no-install-recommends install \ build-essential \ pkg-config \ cmake \ @@ -31,4 +31,4 @@ apt-get -yq install \ # https://deb.sury.org/ sudo add-apt-repository ppa:ondrej/php apt-get update -apt-get -yq install libmpdec-dev +apt-get -yq --no-install-recommends install libmpdec-dev diff --git a/.github/workflows/regen-abidump.sh b/.github/workflows/regen-abidump.sh index 251bb3857ecfcb..75a1a72e370202 100644 --- a/.github/workflows/regen-abidump.sh +++ b/.github/workflows/regen-abidump.sh @@ -2,7 +2,7 @@ set -ex export DEBIAN_FRONTEND=noninteractive ./.github/workflows/posix-deps-apt.sh -apt-get install -yq abigail-tools python3 +apt-get install -yq --no-install-recommends abigail-tools python3 export CFLAGS="-g3 -O0" ./configure --enable-shared && make make regen-abidump diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index fc68c040fca059..c1e58fd44d3790 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -92,7 +92,7 @@ jobs: restore-keys: | ubuntu-doc- - name: 'Install Dependencies' - run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican + run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install --no-install-recommends wamerican - name: 'Configure CPython' run: ./configure --with-pydebug - name: 'Build CPython' diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml index 9032ac016e4810..6464590dee4776 100644 --- a/.github/workflows/reusable-ubuntu.yml +++ b/.github/workflows/reusable-ubuntu.yml @@ -47,7 +47,7 @@ jobs: if: ${{ fromJSON(inputs.bolt-optimizations) }} run: | sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh 19 - sudo apt-get install bolt-19 + sudo apt-get install --no-install-recommends bolt-19 echo PATH="$(llvm-config-19 --bindir):$PATH" >> $GITHUB_ENV - name: Configure OpenSSL env vars run: | From 41fa2dbc0ef5232efae42630119ba20a2efb3ad7 Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Mon, 2 Mar 2026 00:48:13 +0900 Subject: [PATCH 274/498] gh-137829: Fix shelve tests for backend compatibility (#137879) --- Lib/test/test_shelve.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_shelve.py b/Lib/test/test_shelve.py index 64609ab9dd9a62..5f6a030e018f96 100644 --- a/Lib/test/test_shelve.py +++ b/Lib/test/test_shelve.py @@ -5,7 +5,7 @@ import pickle import os -from test.support import import_helper, os_helper +from test.support import import_helper, os_helper, subTests from collections.abc import MutableMapping from test.test_dbm import dbm_iterator @@ -173,6 +173,8 @@ def test_custom_serializer_and_deserializer(self): def serializer(obj, protocol): if isinstance(obj, (bytes, bytearray, str)): if protocol == 5: + if isinstance(obj, bytearray): + return bytes(obj) # DBM backends expect bytes return obj return type(obj).__name__ elif isinstance(obj, array.array): @@ -222,22 +224,31 @@ def deserializer(data): s["array_data"], array_data.tobytes().decode() ) - def test_custom_incomplete_serializer_and_deserializer(self): - dbm_sqlite3 = import_helper.import_module("dbm.sqlite3") - os.mkdir(self.dirname) - self.addCleanup(os_helper.rmtree, self.dirname) + @subTests("serialized", [None, ["invalid type"]]) + def test_custom_invalid_serializer(self, serialized): + test_dir = f"{self.dirname}_{id(serialized)}" + os.mkdir(test_dir) + self.addCleanup(os_helper.rmtree, test_dir) + test_fn = os.path.join(test_dir, "shelftemp.db") - with self.assertRaises(dbm_sqlite3.error): - def serializer(obj, protocol=None): - pass + def serializer(obj, protocol=None): + return serialized - def deserializer(data): - return data.decode("utf-8") + def deserializer(data): + return data.decode("utf-8") - with shelve.open(self.fn, serializer=serializer, + # Since the serializer returns an invalid type or None, + # dbm.error is raised by dbm.sqlite3 and TypeError is raised + # by other backends. + with self.assertRaises((TypeError, dbm.error)): + with shelve.open(test_fn, serializer=serializer, deserializer=deserializer) as s: s["foo"] = "bar" + def test_custom_incomplete_deserializer(self): + os.mkdir(self.dirname) + self.addCleanup(os_helper.rmtree, self.dirname) + def serializer(obj, protocol=None): return type(obj).__name__.encode("utf-8") @@ -352,7 +363,7 @@ def type_name_len(obj): self.assertEqual(s["bytearray_data"], "bytearray") self.assertEqual(s["array_data"], "array") - def test_custom_incomplete_serializer_and_deserializer_bsd_db_shelf(self): + def test_custom_incomplete_deserializer_bsd_db_shelf(self): berkeleydb = import_helper.import_module("berkeleydb") os.mkdir(self.dirname) self.addCleanup(os_helper.rmtree, self.dirname) @@ -370,6 +381,11 @@ def deserializer(data): self.assertIsNone(s["foo"]) self.assertNotEqual(s["foo"], "bar") + def test_custom_incomplete_serializer_bsd_db_shelf(self): + berkeleydb = import_helper.import_module("berkeleydb") + os.mkdir(self.dirname) + self.addCleanup(os_helper.rmtree, self.dirname) + def serializer(obj, protocol=None): pass From c9a5d9aae48a9faa553a5e8137ff1b5e261f6bf6 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 1 Mar 2026 19:48:28 +0000 Subject: [PATCH 275/498] gh-100538: Add workflow to verify bundled libexpat (GH-145359) Add workflow to verify bundled libexpat. --- .github/workflows/verify-expat.yml | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/verify-expat.yml diff --git a/.github/workflows/verify-expat.yml b/.github/workflows/verify-expat.yml new file mode 100644 index 00000000000000..6b12b95cb11ff2 --- /dev/null +++ b/.github/workflows/verify-expat.yml @@ -0,0 +1,32 @@ +name: Verify bundled libexpat + +on: + workflow_dispatch: + push: + paths: + - 'Modules/expat/**' + - '.github/workflows/verify-expat.yml' + pull_request: + paths: + - 'Modules/expat/**' + - '.github/workflows/verify-expat.yml' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + verify: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: Download and verify bundled libexpat files + run: | + ./Modules/expat/refresh.sh + git diff --exit-code Modules/expat/ From 3b276f3f59aba213dce4bd995d4fe66620003e90 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 2 Mar 2026 11:47:32 +0100 Subject: [PATCH 276/498] gh-144748: Make PyErr_CheckSignals raise the exception scheduled by PyThreadState_SetAsyncExc (GH-145178) Co-authored-by: Peter Bierma --- Doc/c-api/exceptions.rst | 5 ++ Doc/c-api/threads.rst | 29 ++++++++---- Include/internal/pycore_ceval.h | 3 ++ Lib/test/test_threading.py | 47 +++++++++++++++++++ ...-02-24-14-46-05.gh-issue-144748.uhnFtE.rst | 2 + Modules/Setup.stdlib.in | 2 +- Modules/_testlimitedcapi.c | 3 ++ Modules/_testlimitedcapi/parts.h | 1 + Modules/_testlimitedcapi/threadstate.c | 25 ++++++++++ Modules/signalmodule.c | 16 +++++-- PCbuild/_testlimitedcapi.vcxproj | 1 + PCbuild/_testlimitedcapi.vcxproj.filters | 1 + Python/ceval_gil.c | 21 +++++++-- 13 files changed, 138 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst create mode 100644 Modules/_testlimitedcapi/threadstate.c diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 72b013612d77f5..aef191d3a29ac6 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -699,6 +699,8 @@ Signal Handling - Executing a pending :ref:`remote debugger ` script. + - Raise the exception set by :c:func:`PyThreadState_SetAsyncExc`. + If any handler raises an exception, immediately return ``-1`` with that exception set. Any remaining interruptions are left to be processed on the next @@ -714,6 +716,9 @@ Signal Handling This function may now execute a remote debugger script, if remote debugging is enabled. + .. versionchanged:: next + The exception set by :c:func:`PyThreadState_SetAsyncExc` is now raised. + .. c:function:: void PyErr_SetInterrupt() diff --git a/Doc/c-api/threads.rst b/Doc/c-api/threads.rst index 46e713f4b5f96f..41c7fbda2302cf 100644 --- a/Doc/c-api/threads.rst +++ b/Doc/c-api/threads.rst @@ -699,13 +699,25 @@ pointer and a void pointer argument. .. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) - Asynchronously raise an exception in a thread. The *id* argument is the thread - id of the target thread; *exc* is the exception object to be raised. This - function does not steal any references to *exc*. To prevent naive misuse, you - must write your own C extension to call this. Must be called with an :term:`attached thread state`. - Returns the number of thread states modified; this is normally one, but will be - zero if the thread id isn't found. If *exc* is ``NULL``, the pending - exception (if any) for the thread is cleared. This raises no exceptions. + Schedule an exception to be raised asynchronously in a thread. + If the thread has a previously scheduled exception, it is overwritten. + + The *id* argument is the thread id of the target thread, as returned by + :c:func:`PyThread_get_thread_ident`. + *exc* is the class of the exception to be raised, or ``NULL`` to clear + the pending exception (if any). + + Return the number of affected thread states. + This is normally ``1`` if *id* is found, even when no change was + made (the given *exc* was already pending, or *exc* is ``NULL`` but + no exception is pending). + If the thread id isn't found, return ``0``. This raises no exceptions. + + To prevent naive misuse, you must write your own C extension to call this. + This function must be called with an :term:`attached thread state`. + This function does not steal any references to *exc*. + This function does not necessarily interrupt system calls such as + :py:func:`~time.sleep`. .. versionchanged:: 3.7 The type of the *id* parameter changed from :c:expr:`long` to @@ -743,7 +755,8 @@ Operating system thread APIs :term:`attached thread state`. .. seealso:: - :py:func:`threading.get_ident` + :py:func:`threading.get_ident` and :py:attr:`threading.Thread.ident` + expose this identifier to Python. .. c:function:: PyObject *PyThread_GetInfo(void) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 1ee1f830827576..f27ec4350bb2c8 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -286,6 +286,9 @@ PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func); and asynchronous exception */ PyAPI_FUNC(int) _Py_HandlePending(PyThreadState *tstate); +/* Raise exception set by PyThreadState_SetAsyncExc, if any */ +PyAPI_FUNC(int) _PyEval_RaiseAsyncExc(PyThreadState *tstate); + extern PyObject * _PyEval_GetFrameLocals(void); typedef PyObject *(*conversion_func)(PyObject *); diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index bdfd03b1e58f62..0ca91ce0d7899d 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -412,6 +412,53 @@ def run(self): t.join() # else the thread is still running, and we have no way to kill it + @cpython_only + @unittest.skipUnless(hasattr(signal, "pthread_kill"), "need pthread_kill") + @unittest.skipUnless(hasattr(signal, "SIGUSR1"), "need SIGUSR1") + def test_PyThreadState_SetAsyncExc_interrupts_sleep(self): + _testcapi = import_module("_testlimitedcapi") + + worker_started = threading.Event() + + class InjectedException(Exception): + """Custom exception for testing""" + + caught_exception = None + + def catch_exception(): + nonlocal caught_exception + day_as_seconds = 60 * 60 * 24 + try: + worker_started.set() + time.sleep(day_as_seconds) + except InjectedException as exc: + caught_exception = exc + + thread = threading.Thread(target=catch_exception) + thread.start() + worker_started.wait() + + signal.signal(signal.SIGUSR1, lambda sig, frame: None) + + result = _testcapi.threadstate_set_async_exc( + thread.ident, InjectedException) + self.assertEqual(result, 1) + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if not thread.is_alive(): + break + try: + signal.pthread_kill(thread.ident, signal.SIGUSR1) + except OSError: + # The thread might have terminated between the is_alive check + # and the pthread_kill + break + + thread.join() + signal.signal(signal.SIGUSR1, signal.SIG_DFL) + + self.assertIsInstance(caught_exception, InjectedException) + def test_limbo_cleanup(self): # Issue 7481: Failure to start thread should cleanup the limbo map. def fail_new_thread(*args, **kwargs): diff --git a/Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst b/Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst new file mode 100644 index 00000000000000..bda7003be94e54 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst @@ -0,0 +1,2 @@ +:c:func:`PyErr_CheckSignals` now raises the exception scheduled by +:c:func:`PyThreadState_SetAsyncExc`, if any. diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 1dd0512832adf7..39be41d9d2a426 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -176,7 +176,7 @@ @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c _testinternalcapi/complex.c _testinternalcapi/interpreter.c @MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c _testcapi/bytes.c _testcapi/object.c _testcapi/modsupport.c _testcapi/monitoring.c _testcapi/config.c _testcapi/import.c _testcapi/frame.c _testcapi/type.c _testcapi/function.c _testcapi/module.c -@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/import.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c _testlimitedcapi/version.c _testlimitedcapi/file.c +@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/import.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/threadstate.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c _testlimitedcapi/version.c _testlimitedcapi/file.c @MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c @MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c diff --git a/Modules/_testlimitedcapi.c b/Modules/_testlimitedcapi.c index 4dae99ec92a085..d3eb02d4727347 100644 --- a/Modules/_testlimitedcapi.c +++ b/Modules/_testlimitedcapi.c @@ -77,6 +77,9 @@ PyInit__testlimitedcapi(void) if (_PyTestLimitedCAPI_Init_Sys(mod) < 0) { return NULL; } + if (_PyTestLimitedCAPI_Init_ThreadState(mod) < 0) { + return NULL; + } if (_PyTestLimitedCAPI_Init_Tuple(mod) < 0) { return NULL; } diff --git a/Modules/_testlimitedcapi/parts.h b/Modules/_testlimitedcapi/parts.h index 60f6f03011a65c..1cbb4f5659af0f 100644 --- a/Modules/_testlimitedcapi/parts.h +++ b/Modules/_testlimitedcapi/parts.h @@ -38,6 +38,7 @@ int _PyTestLimitedCAPI_Init_Long(PyObject *module); int _PyTestLimitedCAPI_Init_PyOS(PyObject *module); int _PyTestLimitedCAPI_Init_Set(PyObject *module); int _PyTestLimitedCAPI_Init_Sys(PyObject *module); +int _PyTestLimitedCAPI_Init_ThreadState(PyObject *module); int _PyTestLimitedCAPI_Init_Tuple(PyObject *module); int _PyTestLimitedCAPI_Init_Unicode(PyObject *module); int _PyTestLimitedCAPI_Init_VectorcallLimited(PyObject *module); diff --git a/Modules/_testlimitedcapi/threadstate.c b/Modules/_testlimitedcapi/threadstate.c new file mode 100644 index 00000000000000..f2539d97150d69 --- /dev/null +++ b/Modules/_testlimitedcapi/threadstate.c @@ -0,0 +1,25 @@ +#include "parts.h" +#include "util.h" + +static PyObject * +threadstate_set_async_exc(PyObject *module, PyObject *args) +{ + unsigned long id; + PyObject *exc; + if (!PyArg_ParseTuple(args, "kO", &id, &exc)) { + return NULL; + } + int result = PyThreadState_SetAsyncExc(id, exc); + return PyLong_FromLong(result); +} + +static PyMethodDef test_methods[] = { + {"threadstate_set_async_exc", threadstate_set_async_exc, METH_VARARGS, NULL}, + {NULL}, +}; + +int +_PyTestLimitedCAPI_Init_ThreadState(PyObject *m) +{ + return PyModule_AddFunctions(m, test_methods); +} diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 4d0e224ff757e7..5060e4097d33c9 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1781,20 +1781,28 @@ PyErr_CheckSignals(void) Python code to ensure signals are handled. Checking for the GC here allows long running native code to clean cycles created using the C-API even if it doesn't run the evaluation loop */ - if (_Py_eval_breaker_bit_is_set(tstate, _PY_GC_SCHEDULED_BIT)) { + uintptr_t breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); + if (breaker & _PY_GC_SCHEDULED_BIT) { _Py_unset_eval_breaker_bit(tstate, _PY_GC_SCHEDULED_BIT); _Py_RunGC(tstate); } + if (breaker & _PY_ASYNC_EXCEPTION_BIT) { + if (_PyEval_RaiseAsyncExc(tstate) < 0) { + return -1; + } + } #if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG) _PyRunRemoteDebugger(tstate); #endif - if (!_Py_ThreadCanHandleSignals(tstate->interp)) { - return 0; + if (_Py_ThreadCanHandleSignals(tstate->interp)) { + if (_PyErr_CheckSignalsTstate(tstate) < 0) { + return -1; + } } - return _PyErr_CheckSignalsTstate(tstate); + return 0; } diff --git a/PCbuild/_testlimitedcapi.vcxproj b/PCbuild/_testlimitedcapi.vcxproj index 36c41fc9824fda..935467dfcb3283 100644 --- a/PCbuild/_testlimitedcapi.vcxproj +++ b/PCbuild/_testlimitedcapi.vcxproj @@ -110,6 +110,7 @@ + diff --git a/PCbuild/_testlimitedcapi.vcxproj.filters b/PCbuild/_testlimitedcapi.vcxproj.filters index 62ecb2f70ffa2d..5e0a0f65cfcc3d 100644 --- a/PCbuild/_testlimitedcapi.vcxproj.filters +++ b/PCbuild/_testlimitedcapi.vcxproj.filters @@ -26,6 +26,7 @@ + diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index 88cc66e97f3424..2425bc1b39f0dc 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -1423,11 +1423,7 @@ _Py_HandlePending(PyThreadState *tstate) /* Check for asynchronous exception. */ if ((breaker & _PY_ASYNC_EXCEPTION_BIT) != 0) { - _Py_unset_eval_breaker_bit(tstate, _PY_ASYNC_EXCEPTION_BIT); - PyObject *exc = _Py_atomic_exchange_ptr(&tstate->async_exc, NULL); - if (exc != NULL) { - _PyErr_SetNone(tstate, exc); - Py_DECREF(exc); + if (_PyEval_RaiseAsyncExc(tstate) < 0) { return -1; } } @@ -1438,3 +1434,18 @@ _Py_HandlePending(PyThreadState *tstate) return 0; } + +int +_PyEval_RaiseAsyncExc(PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(tstate == _PyThreadState_GET()); + _Py_unset_eval_breaker_bit(tstate, _PY_ASYNC_EXCEPTION_BIT); + PyObject *exc = _Py_atomic_exchange_ptr(&tstate->async_exc, NULL); + if (exc != NULL) { + _PyErr_SetNone(tstate, exc); + Py_DECREF(exc); + return -1; + } + return 0; +} From 8bcb3eaa67959ec32bc4d683a79a0a67885925db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Mon, 2 Mar 2026 12:01:32 +0100 Subject: [PATCH 277/498] gh-144851: Fix `__lazy_import__` crash with user-defined filters (#144852) --- Lib/test/test_lazy_import/__init__.py | 5 +++++ Python/import.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index df19af05246dcd..5d30ec2299789b 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -391,6 +391,11 @@ def test_dunder_lazy_import(self): import test.test_lazy_import.data.dunder_lazy_import self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) + def test_dunder_lazy_import_with_custom_filter(self): + sys.set_lazy_imports_filter(lambda importer, imported, fromlist: False) + import test.test_lazy_import.data.dunder_lazy_import + self.assertIn("test.test_lazy_import.data.basic2", sys.modules) + def test_dunder_lazy_import_used(self): """Using __lazy_import__ result should trigger module load.""" import test.test_lazy_import.data.dunder_lazy_import_used diff --git a/Python/import.c b/Python/import.c index 4c234a4a70437c..dfc4d5707bfdba 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4512,6 +4512,10 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate, assert(!PyErr_Occurred()); modname = Py_NewRef(Py_None); } + if (fromlist == NULL) { + assert(!PyErr_Occurred()); + fromlist = Py_NewRef(Py_None); + } PyObject *args[] = {modname, name, fromlist}; PyObject *res = PyObject_Vectorcall(filter, args, 3, NULL); From e54225545866d780b12d8e70c33d25fc13b2c3a9 Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Mon, 2 Mar 2026 08:56:28 -0300 Subject: [PATCH 278/498] gh-144835: Added missing explanations for some parameters in glob and iglob. (#144836) * Added missing explanations for some parameters in glob and iglob. * News entry. * Added proper 'func' indication in News file. * Consistent use of backticks. * Improved wording. * consistent wording between the two docstrings --------- Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com> --- Lib/glob.py | 27 ++++++++++++++++--- ...-02-15-12-02-20.gh-issue-144835.w_oS_J.rst | 2 ++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst diff --git a/Lib/glob.py b/Lib/glob.py index c2f8ce279aba64..575e4bcba5be0d 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -15,7 +15,7 @@ def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False): - """Return a list of paths matching a pathname pattern. + """Return a list of paths matching a `pathname` pattern. The pattern may contain simple shell-style wildcards a la fnmatch. Unlike fnmatch, filenames starting with a @@ -25,6 +25,15 @@ def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, The order of the returned list is undefined. Sort it if you need a particular order. + If `root_dir` is not None, it should be a path-like object specifying the + root directory for searching. It has the same effect as changing the + current directory before calling it (without actually + changing it). If pathname is relative, the result will contain + paths relative to `root_dir`. + + If `dir_fd` is not None, it should be a file descriptor referring to a + directory, and paths will then be relative to that directory. + If `include_hidden` is true, the patterns '*', '?', '**' will match hidden directories. @@ -36,7 +45,7 @@ def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False): - """Return an iterator which yields the paths matching a pathname pattern. + """Return an iterator which yields the paths matching a `pathname` pattern. The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a @@ -46,7 +55,19 @@ def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, The order of the returned paths is undefined. Sort them if you need a particular order. - If recursive is true, the pattern '**' will match any files and + If `root_dir` is not None, it should be a path-like object specifying + the root directory for searching. It has the same effect as changing + the current directory before calling it (without actually + changing it). If pathname is relative, the result will contain + paths relative to `root_dir`. + + If `dir_fd` is not None, it should be a file descriptor referring to a + directory, and paths will then be relative to that directory. + + If `include_hidden` is true, the patterns '*', '?', '**' will match hidden + directories. + + If `recursive` is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ sys.audit("glob.glob", pathname, recursive) diff --git a/Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst b/Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst new file mode 100644 index 00000000000000..9d603b51c48a93 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst @@ -0,0 +1,2 @@ +Added missing explanations for some parameters in :func:`glob.glob` and +:func:`glob.iglob`. From b611db491d16ebbb4c833e9a184bb987e41f9fbe Mon Sep 17 00:00:00 2001 From: zhong <60600792+superboy-zjc@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:30:38 +0800 Subject: [PATCH 279/498] gh-142781: Fix type confusion in zoneinfo weak cache (GH-142925) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Lib/test/test_zoneinfo/test_zoneinfo.py | 38 +++++++++++++++++++ ...-12-18-00-14-16.gh-issue-142781.gcOeYF.rst | 2 + Modules/_zoneinfo.c | 11 +++++- 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index 581072d0701d65..a5dea802a9898d 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -1577,6 +1577,44 @@ class EvilZoneInfo(self.klass): class CZoneInfoCacheTest(ZoneInfoCacheTest): module = c_zoneinfo + def test_inconsistent_weak_cache_get(self): + class Cache: + def get(self, key, default=None): + return 1337 + + class ZI(self.klass): + pass + # Class attribute must be set after class creation + # to override zoneinfo.ZoneInfo.__init_subclass__. + ZI._weak_cache = Cache() + + with self.assertRaises(RuntimeError) as te: + ZI("America/Los_Angeles") + self.assertEqual( + str(te.exception), + "Unexpected instance of int in ZI weak cache for key 'America/Los_Angeles'" + ) + + def test_inconsistent_weak_cache_setdefault(self): + class Cache: + def get(self, key, default=None): + return default + def setdefault(self, key, value): + return 1337 + + class ZI(self.klass): + pass + # Class attribute must be set after class creation + # to override zoneinfo.ZoneInfo.__init_subclass__. + ZI._weak_cache = Cache() + + with self.assertRaises(RuntimeError) as te: + ZI("America/Los_Angeles") + self.assertEqual( + str(te.exception), + "Unexpected instance of int in ZI weak cache for key 'America/Los_Angeles'" + ) + class ZoneInfoPickleTest(TzPathUserMixin, ZoneInfoTestBase): module = py_zoneinfo diff --git a/Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst b/Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst new file mode 100644 index 00000000000000..772e05766c5c69 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst @@ -0,0 +1,2 @@ +:mod:`zoneinfo`: fix a crash when instantiating :class:`~zoneinfo.ZoneInfo` +objects for which the internal class-level cache is inconsistent. diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index e07dfd19efa06d..39671d1ab51dfa 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -335,6 +335,7 @@ zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key) return NULL; } + ((PyZoneInfo_ZoneInfo *)tmp)->source = SOURCE_CACHE; instance = PyObject_CallMethod(weak_cache, "setdefault", "OO", key, tmp); Py_DECREF(tmp); @@ -342,7 +343,15 @@ zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key) Py_DECREF(weak_cache); return NULL; } - ((PyZoneInfo_ZoneInfo *)instance)->source = SOURCE_CACHE; + } + + if (!PyObject_TypeCheck(instance, type)) { + PyErr_Format(PyExc_RuntimeError, + "Unexpected instance of %T in %s weak cache for key %R", + instance, _PyType_Name(type), key); + Py_DECREF(instance); + Py_DECREF(weak_cache); + return NULL; } update_strong_cache(state, type, key, instance); From 201d251567738c234081329a244449e08fa86245 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 2 Mar 2026 10:54:26 -0500 Subject: [PATCH 280/498] DOC: clarify and expand documentation about PYTHONUSERBASE and PYTHONNOUSERSITE (#144637) --- Doc/library/site.rst | 3 ++- Doc/library/sys_path_init.rst | 25 ++++++++++++++----------- Doc/using/cmdline.rst | 8 ++++++-- Lib/site.py | 6 ++++-- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Doc/library/site.rst b/Doc/library/site.rst index 4686c9fc92ced2..04895ae4ec524b 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -64,7 +64,8 @@ When running under a :ref:`virtual environment ` to :data:`sys.path`. + This is equivalent to the :option:`-s` option. If this is set, Python won't + add the :data:`user site-packages directory ` to + :data:`sys.path`. .. seealso:: @@ -964,6 +965,9 @@ conflict. and :ref:`installation paths ` for ``python -m pip install --user``. + To disable the user site-packages, see :envvar:`PYTHONNOUSERSITE` or the :option:`-s` + option. + .. seealso:: :pep:`370` -- Per user site-packages directory diff --git a/Lib/site.py b/Lib/site.py index 1b7a656551b853..5f09a7dd8c91c0 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -18,9 +18,11 @@ it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains -the key "include-system-site-packages" set to anything other than "false" +the key "include-system-site-packages" is set to "true" (case-insensitive), the system-level prefixes will still also be -searched for site-packages; otherwise they won't. +searched for site-packages; otherwise they won't. If the system-level +prefixes are not included then the user site prefixes are also implicitly +not searched for site-packages. All of the resulting site-specific directories, if they exist, are appended to sys.path, and also inspected for path configuration From 1cf5abedeb97ff6ed222afd28e650b9ecc384094 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 2 Mar 2026 16:10:15 +0000 Subject: [PATCH 281/498] gh-145307: Defer loading psapi.dll until ctypes.util.dllist() is called. (GH-145308) --- Lib/ctypes/util.py | 26 ++++++++++++------- ...-02-27-10-57-20.gh-issue-145307.ueoT7j.rst | 2 ++ 2 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 378f12167c6842..3b21658433b2ed 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -85,15 +85,10 @@ def find_library(name): wintypes.DWORD, ) - _psapi = ctypes.WinDLL('psapi', use_last_error=True) - _enum_process_modules = _psapi["EnumProcessModules"] - _enum_process_modules.restype = wintypes.BOOL - _enum_process_modules.argtypes = ( - wintypes.HANDLE, - ctypes.POINTER(wintypes.HMODULE), - wintypes.DWORD, - wintypes.LPDWORD, - ) + # gh-145307: We defer loading psapi.dll until _get_module_handles is called. + # Loading additional DLLs at startup for functionality that may never be + # used is wasteful. + _enum_process_modules = None def _get_module_filename(module: wintypes.HMODULE): name = (wintypes.WCHAR * 32767)() # UNICODE_STRING_MAX_CHARS @@ -101,8 +96,19 @@ def _get_module_filename(module: wintypes.HMODULE): return name.value return None - def _get_module_handles(): + global _enum_process_modules + if _enum_process_modules is None: + _psapi = ctypes.WinDLL('psapi', use_last_error=True) + _enum_process_modules = _psapi["EnumProcessModules"] + _enum_process_modules.restype = wintypes.BOOL + _enum_process_modules.argtypes = ( + wintypes.HANDLE, + ctypes.POINTER(wintypes.HMODULE), + wintypes.DWORD, + wintypes.LPDWORD, + ) + process = _get_current_process() space_needed = wintypes.DWORD() n = 1024 diff --git a/Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst b/Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst new file mode 100644 index 00000000000000..6f039197962e10 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst @@ -0,0 +1,2 @@ +Defers loading of the ``psapi.dll`` module until it is used by +:func:`ctypes.util.dllist`. From 107863ee17788e83ffa63368a33f7afe6f7a1410 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Tue, 3 Mar 2026 01:02:38 +0800 Subject: [PATCH 282/498] gh-144569: Avoid creating temporary objects in `BINARY_SLICE` for list, tuple, and unicode (GH-144590) * Scalar replacement of BINARY_SLICE for list, tuple, and unicode --- Include/cpython/ceval.h | 3 + Include/internal/pycore_list.h | 1 + Include/internal/pycore_tuple.h | 1 + Include/internal/pycore_unicodeobject.h | 1 + ...-02-08-13-14-00.gh-issue-144569.pjlJVe.rst | 1 + Modules/_testinternalcapi/test_cases.c.h | 55 +++++++++---- Objects/listobject.c | 24 ++++++ Objects/tupleobject.c | 19 +++++ Objects/unicodeobject.c | 12 +++ Python/bytecodes.c | 29 +++++-- Python/ceval.c | 44 ++++++---- Python/executor_cases.c.h | 82 ++++++++++++++----- Python/generated_cases.c.h | 55 +++++++++---- 13 files changed, 253 insertions(+), 74 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index ca8109e3248a8d..bbab8d35b75cb2 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -23,6 +23,9 @@ _PyEval_RequestCodeExtraIndex(freefunc f) { PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) _PyEval_UnpackIndices(PyObject *, PyObject *, + Py_ssize_t, + Py_ssize_t *, Py_ssize_t *); // Trampoline API diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h index b39639a9063260..6b92dc5d111f3b 100644 --- a/Include/internal/pycore_list.h +++ b/Include/internal/pycore_list.h @@ -14,6 +14,7 @@ extern "C" { PyAPI_FUNC(PyObject*) _PyList_Extend(PyListObject *, PyObject *); PyAPI_FUNC(PyObject) *_PyList_SliceSubscript(PyObject*, PyObject*); +PyAPI_FUNC(PyObject *) _PyList_BinarySlice(PyObject *, PyObject *, PyObject *); extern void _PyList_DebugMallocStats(FILE *out); // _PyList_GetItemRef should be used only when the object is known as a list // because it doesn't raise TypeError when the object is not a list, whereas PyList_GetItemRef does. diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index 46db02593ad106..00562bef769920 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -25,6 +25,7 @@ extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *); PyAPI_FUNC(PyObject *)_PyTuple_FromStackRefStealOnSuccess(const union _PyStackRef *, Py_ssize_t); PyAPI_FUNC(PyObject *)_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyTuple_BinarySlice(PyObject *, PyObject *, PyObject *); typedef struct { PyObject_HEAD diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 97dda73f9b584d..af6cb84e9ff905 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -32,6 +32,7 @@ extern PyObject* _PyUnicode_ResizeCompact( PyObject *unicode, Py_ssize_t length); extern PyObject* _PyUnicode_GetEmpty(void); +PyAPI_FUNC(PyObject*) _PyUnicode_BinarySlice(PyObject *, PyObject *, PyObject *); /* Generic helper macro to convert characters of different types. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst new file mode 100644 index 00000000000000..bdd0d6c2f7b944 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst @@ -0,0 +1 @@ +Optimize ``BINARY_SLICE`` for list, tuple, and unicode by avoiding temporary ``slice`` object creation. diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 395c429f7ef3db..79320a4bff17fb 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -1396,28 +1396,53 @@ stop = stack_pointer[-1]; start = stack_pointer[-2]; container = stack_pointer[-3]; - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *slice = _PyBuildSlice_ConsumeRefs(PyStackRef_AsPyObjectSteal(start), - PyStackRef_AsPyObjectSteal(stop)); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyObject *container_o = PyStackRef_AsPyObjectBorrow(container); + PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); + PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *res_o; - if (slice == NULL) { - res_o = NULL; + if (PyList_CheckExact(container_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyList_BinarySlice(container_o, start_o, stop_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } - else { - stack_pointer += -2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + else if (PyTuple_CheckExact(container_o)) { _PyFrame_SetStackPointer(frame, stack_pointer); - res_o = PyObject_GetItem(PyStackRef_AsPyObjectBorrow(container), slice); - Py_DECREF(slice); + res_o = _PyTuple_BinarySlice(container_o, start_o, stop_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += 2; } - stack_pointer += -3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + else if (PyUnicode_CheckExact(container_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyUnicode_BinarySlice(container_o, start_o, stop_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + PyObject *slice = PySlice_New(start_o, stop_o, NULL); + if (slice == NULL) { + res_o = NULL; + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = PyObject_GetItem(container_o, slice); + Py_DECREF(slice); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + } _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(container); + _PyStackRef tmp = stop; + stop = PyStackRef_NULL; + stack_pointer[-1] = stop; + PyStackRef_CLOSE(tmp); + tmp = start; + start = PyStackRef_NULL; + stack_pointer[-2] = start; + PyStackRef_CLOSE(tmp); + tmp = container; + container = PyStackRef_NULL; + stack_pointer[-3] = container; + PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (res_o == NULL) { JUMP_TO_LABEL(error); } diff --git a/Objects/listobject.c b/Objects/listobject.c index 4a98c8e54ab03f..3921b7cd7b69bc 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -716,6 +716,30 @@ list_slice_lock_held(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) return (PyObject *)np; } +PyObject * +_PyList_BinarySlice(PyObject *container, PyObject *start, PyObject *stop) +{ + assert(PyList_CheckExact(container)); + Py_ssize_t istart = 0; + Py_ssize_t istop = PY_SSIZE_T_MAX; + /* Unpack the index values before acquiring the lock, since + * _PyEval_SliceIndex may call __index__ which could execute + * arbitrary Python code. */ + if (!_PyEval_SliceIndex(start, &istart)) { + return NULL; + } + if (!_PyEval_SliceIndex(stop, &istop)) { + return NULL; + } + PyObject *ret; + Py_BEGIN_CRITICAL_SECTION(container); + Py_ssize_t len = Py_SIZE(container); + PySlice_AdjustIndices(len, &istart, &istop, 1); + ret = list_slice_lock_held((PyListObject *)container, istart, istop); + Py_END_CRITICAL_SECTION(); + return ret; +} + PyObject * PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 169ac69701da11..3c68955495d566 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -472,6 +472,25 @@ tuple_slice(PyTupleObject *a, Py_ssize_t ilow, return PyTuple_FromArray(a->ob_item + ilow, ihigh - ilow); } +PyObject * +_PyTuple_BinarySlice(PyObject *container, PyObject *start, PyObject *stop) +{ + assert(PyTuple_CheckExact(container)); + Py_ssize_t len = Py_SIZE(container); + Py_ssize_t istart, istop; + if (!_PyEval_UnpackIndices(start, stop, len, &istart, &istop)) { + return NULL; + } + if (istart == 0 && istop == len) { + return Py_NewRef(container); + } + if (istop < istart) { + istop = istart; + } + return PyTuple_FromArray(((PyTupleObject *)container)->ob_item + istart, + istop - istart); +} + PyObject * PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j) { diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 213bae5ca86cd4..7aa85a942e449e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -12312,6 +12312,18 @@ _PyUnicode_XStrip(PyObject *self, int striptype, PyObject *sepobj) return PyUnicode_Substring(self, i, j); } +PyObject* +_PyUnicode_BinarySlice(PyObject *container, PyObject *start_o, PyObject *stop_o) +{ + assert(PyUnicode_CheckExact(container)); + Py_ssize_t len = PyUnicode_GET_LENGTH(container); + Py_ssize_t istart, istop; + if (!_PyEval_UnpackIndices(start_o, stop_o, len, &istart, &istop)) { + return NULL; + } + return PyUnicode_Substring(container, istart, istop); +} + PyObject* PyUnicode_Substring(PyObject *self, Py_ssize_t start, Py_ssize_t end) { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 41323c4f54d9ed..8caad077ec07ec 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -866,19 +866,30 @@ dummy_func( } op(_BINARY_SLICE, (container, start, stop -- res)) { - PyObject *slice = _PyBuildSlice_ConsumeRefs(PyStackRef_AsPyObjectSteal(start), - PyStackRef_AsPyObjectSteal(stop)); + PyObject *container_o = PyStackRef_AsPyObjectBorrow(container); + PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); + PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *res_o; - // Can't use ERROR_IF() here, because we haven't - // DECREF'ed container yet, and we still own slice. - if (slice == NULL) { - res_o = NULL; + if (PyList_CheckExact(container_o)) { + res_o = _PyList_BinarySlice(container_o, start_o, stop_o); + } + else if (PyTuple_CheckExact(container_o)) { + res_o = _PyTuple_BinarySlice(container_o, start_o, stop_o); + } + else if (PyUnicode_CheckExact(container_o)) { + res_o = _PyUnicode_BinarySlice(container_o, start_o, stop_o); } else { - res_o = PyObject_GetItem(PyStackRef_AsPyObjectBorrow(container), slice); - Py_DECREF(slice); + PyObject *slice = PySlice_New(start_o, stop_o, NULL); + if (slice == NULL) { + res_o = NULL; + } + else { + res_o = PyObject_GetItem(container_o, slice); + Py_DECREF(slice); + } } - PyStackRef_CLOSE(container); + DECREF_INPUTS(); ERROR_IF(res_o == NULL); res = PyStackRef_FromPyObjectSteal(res_o); } diff --git a/Python/ceval.c b/Python/ceval.c index 2cd7c7bfd28d09..3ad46cf1ec85ff 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1,6 +1,7 @@ /* Execute compiled code */ #include "ceval.h" +#include "pycore_long.h" int Py_GetRecursionLimit(void) @@ -2883,23 +2884,10 @@ PyEval_GetFuncDesc(PyObject *func) int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) { - PyThreadState *tstate = _PyThreadState_GET(); - if (!Py_IsNone(v)) { - Py_ssize_t x; - if (_PyIndex_Check(v)) { - x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && _PyErr_Occurred(tstate)) - return 0; - } - else { - _PyErr_SetString(tstate, PyExc_TypeError, - "slice indices must be integers or " - "None or have an __index__ method"); - return 0; - } - *pi = x; + if (Py_IsNone(v)) { + return 1; } - return 1; + return _PyEval_SliceIndexNotNone(v, pi); } int @@ -2907,6 +2895,10 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) { PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t x; + if (PyLong_CheckExact(v) && _PyLong_IsCompact((PyLongObject *)v)) { + *pi = _PyLong_CompactValue((PyLongObject *)v); + return 1; + } if (_PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); if (x == -1 && _PyErr_Occurred(tstate)) @@ -2922,6 +2914,26 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) return 1; } +int +_PyEval_UnpackIndices(PyObject *start, PyObject *stop, + Py_ssize_t len, + Py_ssize_t *istart, Py_ssize_t *istop) +{ + if (len < 0) { + return 0; + } + *istart = 0; + *istop = PY_SSIZE_T_MAX; + if (!_PyEval_SliceIndex(start, istart)) { + return 0; + } + if (!_PyEval_SliceIndex(stop, istop)) { + return 0; + } + PySlice_AdjustIndices(len, istart, istop, 1); + return 1; +} + PyObject * _PyEval_ImportName(PyThreadState *tstate, PyObject *builtins, PyObject *globals, PyObject *locals, PyObject *name, diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 4a67ede8a02265..6708a9282077c4 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5198,33 +5198,77 @@ stop = _stack_item_2; start = _stack_item_1; container = _stack_item_0; - stack_pointer[0] = container; - stack_pointer[1] = start; - stack_pointer[2] = stop; - stack_pointer += 3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *slice = _PyBuildSlice_ConsumeRefs(PyStackRef_AsPyObjectSteal(start), - PyStackRef_AsPyObjectSteal(stop)); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyObject *container_o = PyStackRef_AsPyObjectBorrow(container); + PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); + PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *res_o; - if (slice == NULL) { - res_o = NULL; + if (PyList_CheckExact(container_o)) { + stack_pointer[0] = container; + stack_pointer[1] = start; + stack_pointer[2] = stop; + stack_pointer += 3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyList_BinarySlice(container_o, start_o, stop_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } - else { - stack_pointer += -2; + else if (PyTuple_CheckExact(container_o)) { + stack_pointer[0] = container; + stack_pointer[1] = start; + stack_pointer[2] = stop; + stack_pointer += 3; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); - res_o = PyObject_GetItem(PyStackRef_AsPyObjectBorrow(container), slice); - Py_DECREF(slice); + res_o = _PyTuple_BinarySlice(container_o, start_o, stop_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += 2; } - stack_pointer += -3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + else if (PyUnicode_CheckExact(container_o)) { + stack_pointer[0] = container; + stack_pointer[1] = start; + stack_pointer[2] = stop; + stack_pointer += 3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyUnicode_BinarySlice(container_o, start_o, stop_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + PyObject *slice = PySlice_New(start_o, stop_o, NULL); + if (slice == NULL) { + res_o = NULL; + } + else { + stack_pointer[0] = container; + stack_pointer[1] = start; + stack_pointer[2] = stop; + stack_pointer += 3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = PyObject_GetItem(container_o, slice); + Py_DECREF(slice); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -3; + } + stack_pointer += 3; + } _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(container); + _PyStackRef tmp = stop; + stop = PyStackRef_NULL; + stack_pointer[-3] = container; + stack_pointer[-2] = start; + stack_pointer[-1] = stop; + PyStackRef_CLOSE(tmp); + tmp = start; + start = PyStackRef_NULL; + stack_pointer[-2] = start; + PyStackRef_CLOSE(tmp); + tmp = container; + container = PyStackRef_NULL; + stack_pointer[-3] = container; + PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (res_o == NULL) { SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 12362943465e3d..42098c59040f07 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1396,28 +1396,53 @@ stop = stack_pointer[-1]; start = stack_pointer[-2]; container = stack_pointer[-3]; - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *slice = _PyBuildSlice_ConsumeRefs(PyStackRef_AsPyObjectSteal(start), - PyStackRef_AsPyObjectSteal(stop)); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyObject *container_o = PyStackRef_AsPyObjectBorrow(container); + PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); + PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); PyObject *res_o; - if (slice == NULL) { - res_o = NULL; + if (PyList_CheckExact(container_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyList_BinarySlice(container_o, start_o, stop_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } - else { - stack_pointer += -2; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + else if (PyTuple_CheckExact(container_o)) { _PyFrame_SetStackPointer(frame, stack_pointer); - res_o = PyObject_GetItem(PyStackRef_AsPyObjectBorrow(container), slice); - Py_DECREF(slice); + res_o = _PyTuple_BinarySlice(container_o, start_o, stop_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += 2; } - stack_pointer += -3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + else if (PyUnicode_CheckExact(container_o)) { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = _PyUnicode_BinarySlice(container_o, start_o, stop_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + else { + PyObject *slice = PySlice_New(start_o, stop_o, NULL); + if (slice == NULL) { + res_o = NULL; + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + res_o = PyObject_GetItem(container_o, slice); + Py_DECREF(slice); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + } _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(container); + _PyStackRef tmp = stop; + stop = PyStackRef_NULL; + stack_pointer[-1] = stop; + PyStackRef_CLOSE(tmp); + tmp = start; + start = PyStackRef_NULL; + stack_pointer[-2] = start; + PyStackRef_CLOSE(tmp); + tmp = container; + container = PyStackRef_NULL; + stack_pointer[-3] = container; + PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (res_o == NULL) { JUMP_TO_LABEL(error); } From 02288bf0225bea892eaab0d3e13c271761849e22 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 2 Mar 2026 12:25:13 -0500 Subject: [PATCH 283/498] gh-130555: Fix use-after-free in dict.clear() with embedded values (gh-145268) --- Lib/test/test_dict.py | 63 +++++++++++++++++++ ...-02-26-12-00-00.gh-issue-130555.TMSOIu.rst | 3 + Objects/dictobject.c | 31 ++++++--- 3 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 8a4e19c95a36ef..f28155fe50148d 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1680,6 +1680,69 @@ def test_hash_collision_remove_add(self): self.assertEqual(len(d), len(items), d) self.assertEqual(d, dict(items)) + def test_clear_reentrant_embedded(self): + # gh-130555: dict.clear() must be safe when values are embedded + # in an object and a destructor mutates the dict. + class MyObj: pass + class ClearOnDelete: + def __del__(self): + nonlocal x + del x + + x = MyObj() + x.a = ClearOnDelete() + + d = x.__dict__ + d.clear() + + def test_clear_reentrant_cycle(self): + # gh-130555: dict.clear() must be safe for embedded dicts when the + # object is part of a reference cycle and the last reference to the + # dict is via the cycle. + class MyObj: pass + obj = MyObj() + obj.f = obj + obj.attr = "attr" + + d = obj.__dict__ + del obj + + d.clear() + + def test_clear_reentrant_force_combined(self): + # gh-130555: dict.clear() must be safe when a destructor forces the + # dict from embedded/split to combined (setting ma_values to NULL). + class MyObj: pass + class ForceConvert: + def __del__(self): + d[1] = "trigger" + + x = MyObj() + x.a = ForceConvert() + x.b = "other" + + d = x.__dict__ + d.clear() + + def test_clear_reentrant_delete(self): + # gh-130555: dict.clear() must be safe when a destructor deletes + # a key from the same embedded dict. + class MyObj: pass + class DelKey: + def __del__(self): + try: + del d['b'] + except KeyError: + pass + + x = MyObj() + x.a = DelKey() + x.b = "value_b" + x.c = "value_c" + + d = x.__dict__ + d.clear() + class CAPITest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst new file mode 100644 index 00000000000000..5a2106480fb843 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst @@ -0,0 +1,3 @@ +Fix use-after-free in :meth:`dict.clear` when the dictionary values are +embedded in an object and a destructor causes re-entrant mutation of the +dictionary. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 35ca9933bfa8ae..bcd3c862fd59b2 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2969,6 +2969,21 @@ _PyDict_DelItemIf(PyObject *op, PyObject *key, return res; } +static void +clear_embedded_values(PyDictValues *values, Py_ssize_t nentries) +{ + PyObject *refs[SHARED_KEYS_MAX_SIZE]; + assert(nentries <= SHARED_KEYS_MAX_SIZE); + for (Py_ssize_t i = 0; i < nentries; i++) { + refs[i] = values->values[i]; + values->values[i] = NULL; + } + values->size = 0; + for (Py_ssize_t i = 0; i < nentries; i++) { + Py_XDECREF(refs[i]); + } +} + static void clear_lock_held(PyObject *op) { @@ -2997,20 +3012,18 @@ clear_lock_held(PyObject *op) assert(oldkeys->dk_refcnt == 1); dictkeys_decref(oldkeys, IS_DICT_SHARED(mp)); } + else if (oldvalues->embedded) { + clear_embedded_values(oldvalues, oldkeys->dk_nentries); + } else { + set_values(mp, NULL); + set_keys(mp, Py_EMPTY_KEYS); n = oldkeys->dk_nentries; for (i = 0; i < n; i++) { Py_CLEAR(oldvalues->values[i]); } - if (oldvalues->embedded) { - oldvalues->size = 0; - } - else { - set_values(mp, NULL); - set_keys(mp, Py_EMPTY_KEYS); - free_values(oldvalues, IS_DICT_SHARED(mp)); - dictkeys_decref(oldkeys, false); - } + free_values(oldvalues, IS_DICT_SHARED(mp)); + dictkeys_decref(oldkeys, false); } ASSERT_CONSISTENT(mp); } From 5c3a47b94a39f87c36b1f36704d80775802ad034 Mon Sep 17 00:00:00 2001 From: AN Long Date: Tue, 3 Mar 2026 03:07:49 +0900 Subject: [PATCH 284/498] gh-145335: Fix crash when passing -1 as fd in os.pathconf (#145390) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Lib/test/test_os/test_os.py | 10 ++++++++++ .../2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst | 2 ++ Modules/posixmodule.c | 9 +++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py index 82c55c8ba33065..1f241609da80cd 100644 --- a/Lib/test/test_os/test_os.py +++ b/Lib/test/test_os/test_os.py @@ -2778,6 +2778,16 @@ def test_fpathconf_bad_fd(self): self.check(os.pathconf, "PC_NAME_MAX") self.check(os.fpathconf, "PC_NAME_MAX") + @unittest.skipUnless(hasattr(os, 'pathconf'), 'test needs os.pathconf()') + @unittest.skipIf( + support.linked_to_musl(), + 'musl fpathconf ignores the file descriptor and returns a constant', + ) + def test_pathconf_negative_fd_uses_fd_semantics(self): + with self.assertRaises(OSError) as ctx: + os.pathconf(-1, 1) + self.assertEqual(ctx.exception.errno, errno.EBADF) + @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()') def test_ftruncate(self): self.check(os.truncate, 0) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst new file mode 100644 index 00000000000000..42ed85c7da31ac --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst @@ -0,0 +1,2 @@ +Fix a crash in :func:`os.pathconf` when called with ``-1`` as the path +argument. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8d38e034aa6b5e..b82f08e7dc4291 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1280,6 +1280,8 @@ get_posix_state(PyObject *module) * Contains a file descriptor if path.accept_fd was true * and the caller provided a signed integer instead of any * sort of string. + * path.is_fd + * True if path was provided as a file descriptor. * * WARNING: if your "path" parameter is optional, and is * unspecified, path_converter will never get called. @@ -1332,6 +1334,7 @@ typedef struct { const wchar_t *wide; const char *narrow; int fd; + bool is_fd; int value_error; Py_ssize_t length; PyObject *object; @@ -1341,7 +1344,7 @@ typedef struct { #define PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, \ make_wide, suppress_value_error, allow_fd) \ {function_name, argument_name, nullable, nonstrict, make_wide, \ - suppress_value_error, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL} + suppress_value_error, allow_fd, NULL, NULL, -1, false, 0, 0, NULL, NULL} #ifdef MS_WINDOWS #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ nonstrict, suppress_value_error, allow_fd) \ @@ -1475,6 +1478,7 @@ path_converter(PyObject *o, void *p) } path->wide = NULL; path->narrow = NULL; + path->is_fd = true; goto success_exit; } else { @@ -14328,8 +14332,9 @@ os_pathconf_impl(PyObject *module, path_t *path, int name) errno = 0; #ifdef HAVE_FPATHCONF - if (path->fd != -1) + if (path->is_fd) { limit = fpathconf(path->fd, name); + } else #endif limit = pathconf(path->narrow, name); From 3ab39d2308c591b8dcee60e5e733ab0b5e5d8ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 2 Mar 2026 18:51:45 +0000 Subject: [PATCH 285/498] GH-145273: warn when we can't find the standard library (#145274) --- Lib/test/support/__init__.py | 5 ++-- Lib/test/test_embed.py | 30 ++++++++++++++++--- ...-02-26-20-51-54.gh-issue-145273.B5QcUp.rst | 2 ++ Modules/getpath.py | 23 ++++++++++++-- 4 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 307bac65ae50a8..d4d3c7f1aefa66 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1716,9 +1716,10 @@ def _platform_specific(self): )) self._env = {k.upper(): os.getenv(k) for k in os.environ} - self._env["PYTHONHOME"] = os.path.dirname(self.real) + home = os.path.dirname(self.real) if sysconfig.is_python_build(): - self._env["PYTHONPATH"] = STDLIB_DIR + home = os.path.join(home, sysconfig.get_config_var('VPATH')) + self._env["PYTHONHOME"] = home else: def _platform_specific(self): pass diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 35246d7c484439..b3f0cb5d35de5d 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1491,8 +1491,12 @@ def test_init_setpythonhome(self): } self.default_program_name(config) env = {'TESTHOME': home, 'PYTHONPATH': paths_str} + # When running from source, TESTHOME will be the build directory, which + # isn't a valid home unless _is_python_build is set. getpath will then + # fail to find the standard library and show a warning, so we need to + # ignore stderr. self.check_all_configs("test_init_setpythonhome", config, - api=API_COMPAT, env=env) + api=API_COMPAT, env=env, ignore_stderr=True) def test_init_is_python_build_with_home(self): # Test _Py_path_config._is_python_build configuration (gh-91985) @@ -1528,15 +1532,26 @@ def test_init_is_python_build_with_home(self): 'exec_prefix': exec_prefix, 'base_exec_prefix': exec_prefix, 'pythonpath_env': paths_str, - 'stdlib_dir': stdlib, + 'stdlib_dir': stdlib, # Only correct on _is_python_build==0! } # The code above is taken from test_init_setpythonhome() env = {'TESTHOME': home, 'PYTHONPATH': paths_str} env['NEGATIVE_ISPYTHONBUILD'] = '1' config['_is_python_build'] = 0 + # This configuration doesn't set a valid stdlibdir/plststdlibdir because + # with _is_python_build=0 getpath doesn't check for the build directory + # landmarks in PYTHONHOME/Py_SetPythonHome. + # getpath correctly shows a warning, which messes up check_all_configs, + # so we need to ignore stderr. self.check_all_configs("test_init_is_python_build", config, - api=API_COMPAT, env=env) + api=API_COMPAT, env=env, ignore_stderr=True) + + # config['stdlib_dir'] = os.path.join(home, 'Lib') + # FIXME: This test does not check if stdlib_dir is calculated correctly. + # test_init_is_python_build runs the initialization twice, + # setting stdlib_dir in _Py_path_config on the first run, which + # then overrides the stdlib_dir calculation (as of GH-108730). env['NEGATIVE_ISPYTHONBUILD'] = '0' config['_is_python_build'] = 1 @@ -1551,8 +1566,14 @@ def test_init_is_python_build_with_home(self): expected_paths[0] = self.module_search_paths(prefix=prefix)[0] config.update(prefix=prefix, base_prefix=prefix, exec_prefix=exec_prefix, base_exec_prefix=exec_prefix) + # This also shows the bad stdlib warning, getpath is run twice. The + # first time with _is_python_build=0, which results in the warning just + # as explained above. However, the second time a valid standard library + # should be found, but the stdlib_dir is cached in _Py_path_config from + # the first run, which ovewrites it, so it also shows the warning. + # Also ignore stderr. self.check_all_configs("test_init_is_python_build", config, - api=API_COMPAT, env=env) + api=API_COMPAT, env=env, ignore_stderr=True) def copy_paths_by_env(self, config): all_configs = self._get_expected_config() @@ -1612,6 +1633,7 @@ def test_init_pybuilddir_win32(self): prefix = os.path.normpath(os.path.join(tmpdir, vpath)) # The stdlib dir is dirname(executable) + VPATH + 'Lib' stdlibdir = os.path.normpath(os.path.join(tmpdir, vpath, 'Lib')) + os.mkdir(stdlibdir) filename = os.path.join(tmpdir, 'pybuilddir.txt') with open(filename, "w", encoding="utf8") as fp: diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst new file mode 100644 index 00000000000000..8d9e4a872d0d7a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst @@ -0,0 +1,2 @@ +A warning is now shown during :ref:`sys-path-init` if it can't find a valid +standard library. diff --git a/Modules/getpath.py b/Modules/getpath.py index ceb605a75c85f4..e06297b7b63a7b 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -236,6 +236,7 @@ def search_up(prefix, *landmarks, test=isfile): real_executable_dir = None platstdlib_dir = None +stdlib_zip = None # ****************************************************************************** # CALCULATE program_name @@ -697,12 +698,13 @@ def search_up(prefix, *landmarks, test=isfile): library_dir = dirname(library) else: library_dir = executable_dir - pythonpath.append(joinpath(library_dir, ZIP_LANDMARK)) + stdlib_zip = joinpath(library_dir, ZIP_LANDMARK) elif build_prefix: # QUIRK: POSIX uses the default prefix when in the build directory - pythonpath.append(joinpath(PREFIX, ZIP_LANDMARK)) + stdlib_zip = joinpath(PREFIX, ZIP_LANDMARK) else: - pythonpath.append(joinpath(base_prefix, ZIP_LANDMARK)) + stdlib_zip = joinpath(base_prefix, ZIP_LANDMARK) + pythonpath.append(stdlib_zip) if os_name == 'nt' and use_environment and winreg: # QUIRK: Windows also lists paths in the registry. Paths are stored @@ -767,6 +769,21 @@ def search_up(prefix, *landmarks, test=isfile): config['module_search_paths_set'] = 1 +# ****************************************************************************** +# SANITY CHECKS +# ****************************************************************************** + +# Warn if the standard library is missing +if not stdlib_zip or not isfile(stdlib_zip): + home_hint = f"The Python 'home' directory was set to {home!r}, is this correct?" + if not stdlib_dir or not isdir(stdlib_dir): + hint = home_hint if home else f'sys.prefix is set to {prefix}, is this correct?' + warn('WARN: Could not find the standard library directory! ' + hint) + elif (not platstdlib_dir and not build_prefix) or not isdir(platstdlib_dir): + hint = home_hint if home else f'sys.exec_prefix is set to {exec_prefix}, is this correct?' + warn('WARN: Could not find the platform standard library directory! ' + hint) + + # ****************************************************************************** # POSIX prefix/exec_prefix QUIRKS # ****************************************************************************** From eb611a8515d8d7af714b57a5f955a98011000d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 2 Mar 2026 19:19:05 +0000 Subject: [PATCH 286/498] GH-145275: add -X pathconfig_warnings and PYTHON_PATHCONFIG_WARNINGS (#145277) --- Doc/using/cmdline.rst | 15 ++++++++ ...-02-26-21-07-38.gh-issue-145275.qE-3O1.rst | 3 ++ Python/initconfig.c | 34 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index f4085ff842aea9..84b8575284b793 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -687,6 +687,13 @@ Miscellaneous options .. versionadded:: 3.14 + * :samp:`-X pathconfig_warnings={0,1}` if true (``1``) then + :ref:`sys-path-init` is allowed to log warnings into stderr. + If false (``0``) suppress these warnings. Set to true by default. + See also :envvar:`PYTHON_PATHCONFIG_WARNINGS`. + + .. versionadded:: next + * :samp:`-X tlbc={0,1}` enables (1, the default) or disables (0) thread-local bytecode in builds configured with :option:`--disable-gil`. When disabled, this also disables the specializing interpreter. See also @@ -1354,6 +1361,14 @@ conflict. .. versionadded:: 3.14 +.. envvar:: PYTHON_PATHCONFIG_WARNINGS + + If true (``1``) then :ref:`sys-path-init` is allowed to log warnings into + stderr. If false (``0``) suppress these warnings. Set to true by default. + See also :option:`-X pathconfig_warnings<-X>`. + + .. versionadded:: next + .. envvar:: PYTHON_JIT On builds where experimental just-in-time compilation is available, this diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst new file mode 100644 index 00000000000000..1723a7c8c10717 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst @@ -0,0 +1,3 @@ +Added the :option:`-X pathconfig_warnings<-X>` and +:envvar:`PYTHON_PATHCONFIG_WARNINGS` options, allowing to disable warnings +from :ref:`sys-path-init`. diff --git a/Python/initconfig.c b/Python/initconfig.c index 5ffee9eaf9f550..57629ff8c57380 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -357,6 +357,9 @@ The following implementation-specific options are available:\n\ use module globals, which is not concurrent-safe; set to true for\n\ free-threaded builds and false otherwise; also\n\ PYTHON_CONTEXT_AWARE_WARNINGS\n\ +-X pathconfig_warnings=[0|1]: if true (1) then path configuration is allowed\n\ + to log warnings into stderr; if false (0) suppress these warnings;\n\ + set to true by default; also PYTHON_PATHCONFIG_WARNINGS\n\ -X tracemalloc[=N]: trace Python memory allocations; N sets a traceback limit\n \ of N frames (default: 1); also PYTHONTRACEMALLOC=N\n\ -X utf8[=0|1]: enable (1) or disable (0) UTF-8 mode; also PYTHONUTF8\n\ @@ -2350,6 +2353,32 @@ config_init_lazy_imports(PyConfig *config) return _PyStatus_OK(); } +static PyStatus +config_init_pathconfig_warnings(PyConfig *config) +{ + const char *env = config_get_env(config, "PYTHON_PATHCONFIG_WARNINGS"); + if (env) { + int enabled; + if (_Py_str_to_int(env, &enabled) < 0 || (enabled < 0) || (enabled > 1)) { + return _PyStatus_ERR( + "PYTHON_PATHCONFIG_WARNINGS=N: N is missing or invalid"); + } + config->pathconfig_warnings = enabled; + } + + const wchar_t *xoption = config_get_xoption(config, L"pathconfig_warnings"); + if (xoption) { + int enabled; + const wchar_t *sep = wcschr(xoption, L'='); + if (!sep || (config_wstr_to_int(sep + 1, &enabled) < 0) || (enabled < 0) || (enabled > 1)) { + return _PyStatus_ERR( + "-X pathconfig_warnings=n: n is missing or invalid"); + } + config->pathconfig_warnings = enabled; + } + return _PyStatus_OK(); +} + static PyStatus config_read_complex_options(PyConfig *config) { @@ -2446,6 +2475,11 @@ config_read_complex_options(PyConfig *config) return status; } + status = config_init_pathconfig_warnings(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); } From 592e8f0865cfd5af65fbcdbd185c3dd576c838e7 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 2 Mar 2026 14:32:06 -0500 Subject: [PATCH 287/498] gh-130327: Always traverse managed dictionaries, even when inline values are available (#130469) --- Lib/test/test_dict.py | 20 +++++++++++++++++++ ...-02-19-21-06-30.gh-issue-130327.z3TaR8.rst | 2 ++ Objects/dictobject.c | 17 +++++++++------- 3 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index f28155fe50148d..162b0b38f8555d 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1569,6 +1569,26 @@ def make_pairs(): self.assertEqual(d.get(key3_3), 44) self.assertGreaterEqual(eq_count, 1) + def test_overwrite_managed_dict(self): + # GH-130327: Overwriting an object's managed dictionary with another object's + # skipped traversal in favor of inline values, causing the GC to believe that + # the __dict__ wasn't reachable. + import gc + + class Shenanigans: + pass + + to_be_deleted = Shenanigans() + to_be_deleted.attr = "whatever" + holds_reference = Shenanigans() + holds_reference.__dict__ = to_be_deleted.__dict__ + holds_reference.ref = {"circular": to_be_deleted, "data": 42} + + del to_be_deleted + gc.collect() + self.assertEqual(holds_reference.ref['data'], 42) + self.assertEqual(holds_reference.attr, "whatever") + def test_unhashable_key(self): d = {'a': 1} key = [1, 2, 3] diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst new file mode 100644 index 00000000000000..9b9a282b5ab414 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst @@ -0,0 +1,2 @@ +Fix erroneous clearing of an object's :attr:`~object.__dict__` if +overwritten at runtime. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index bcd3c862fd59b2..5894fdb614ebdc 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4825,10 +4825,8 @@ dict_traverse(PyObject *op, visitproc visit, void *arg) if (DK_IS_UNICODE(keys)) { if (_PyDict_HasSplitTable(mp)) { - if (!mp->ma_values->embedded) { - for (i = 0; i < n; i++) { - Py_VISIT(mp->ma_values->values[i]); - } + for (i = 0; i < n; i++) { + Py_VISIT(mp->ma_values->values[i]); } } else { @@ -7413,16 +7411,21 @@ PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return 0; } - if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + PyDictObject *dict = _PyObject_ManagedDictPointer(obj)->dict; + if (dict != NULL) { + // GH-130327: If there's a managed dictionary available, we should + // *always* traverse it. The dict is responsible for traversing the + // inline values if it points to them. + Py_VISIT(dict); + } + else if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { PyDictValues *values = _PyObject_InlineValues(obj); if (values->valid) { for (Py_ssize_t i = 0; i < values->capacity; i++) { Py_VISIT(values->values[i]); } - return 0; } } - Py_VISIT(_PyObject_ManagedDictPointer(obj)->dict); return 0; } From f8d2f9fe67f8ab279cf7c5f6fa6a4feb588ce8f0 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:45:03 +0000 Subject: [PATCH 288/498] gh-145118: Add `frozendict` support to `type()` (#145124) --- Lib/test/test_builtin.py | 6 ++++ ...-02-22-19-05-03.gh-issue-145118.bU6Sic.rst | 1 + Objects/typeobject.c | 28 +++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 7b69374b1868d1..eabfdcd447f2bb 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2993,6 +2993,12 @@ def test_type_doc(self): A.__doc__ = doc self.assertEqual(A.__doc__, doc) + def test_type_frozendict(self): + A = type('A', (), frozendict({'x': 4, 'y': 2})) + self.assertEqual(A.x, 4) + self.assertEqual(A.y, 2) + self.assertEqual(A.__name__, 'A') + def test_bad_args(self): with self.assertRaises(TypeError): type() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst new file mode 100644 index 00000000000000..24507d4a411f85 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst @@ -0,0 +1 @@ +:func:`type` now accepts :class:`frozendict` as an argument. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ad26339c9c34df..d77d981085f4da 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4872,9 +4872,21 @@ type_new_get_slots(type_new_ctx *ctx, PyObject *dict) static PyTypeObject* type_new_init(type_new_ctx *ctx) { - PyObject *dict = PyDict_Copy(ctx->orig_dict); - if (dict == NULL) { - goto error; + PyObject *dict; + if (PyFrozenDict_Check(ctx->orig_dict)) { + dict = PyDict_New(); + if (dict == NULL) { + goto error; + } + if (PyDict_Merge(dict, ctx->orig_dict, 1) < 0) { + goto error; + } + } + else { + dict = PyDict_Copy(ctx->orig_dict); + if (dict == NULL) { + goto error; + } } if (type_new_get_slots(ctx, dict) < 0) { @@ -5037,13 +5049,19 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) /* Parse arguments: (name, bases, dict) */ PyObject *name, *bases, *orig_dict; - if (!PyArg_ParseTuple(args, "UO!O!:type.__new__", + if (!PyArg_ParseTuple(args, "UO!O:type.__new__", &name, &PyTuple_Type, &bases, - &PyDict_Type, &orig_dict)) + &orig_dict)) { return NULL; } + if (!PyAnyDict_Check(orig_dict)) { + PyErr_Format(PyExc_TypeError, + "type.__new__() argument 3 must be dict or frozendict, not %T", + orig_dict); + return NULL; + } type_new_ctx ctx = { .metatype = metatype, From 539a985faca498e345e471476cb377c1c57ea07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 2 Mar 2026 20:23:22 +0000 Subject: [PATCH 289/498] GH-145273: drop build_prefix check from missing stdlib warning (#145437) --- Makefile.pre.in | 2 +- Modules/getpath.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index da8d5483fd32e8..120a6add38507f 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1004,7 +1004,7 @@ platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt # or removed in case of failure. pybuilddir.txt: $(PYTHON_FOR_BUILD_DEPS) @echo "none" > ./pybuilddir.txt - $(RUNSHARED) $(PYTHON_FOR_BUILD) -S -m sysconfig --generate-posix-vars ;\ + $(RUNSHARED) $(PYTHON_FOR_BUILD) -S -X pathconfig_warnings=0 -m sysconfig --generate-posix-vars ;\ if test $$? -ne 0 ; then \ echo "generate-posix-vars failed" ; \ rm -f ./pybuilddir.txt ; \ diff --git a/Modules/getpath.py b/Modules/getpath.py index e06297b7b63a7b..20e050787700bf 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -779,7 +779,7 @@ def search_up(prefix, *landmarks, test=isfile): if not stdlib_dir or not isdir(stdlib_dir): hint = home_hint if home else f'sys.prefix is set to {prefix}, is this correct?' warn('WARN: Could not find the standard library directory! ' + hint) - elif (not platstdlib_dir and not build_prefix) or not isdir(platstdlib_dir): + elif not platstdlib_dir or not isdir(platstdlib_dir): hint = home_hint if home else f'sys.exec_prefix is set to {exec_prefix}, is this correct?' warn('WARN: Could not find the platform standard library directory! ' + hint) From f739e2ca62497d15a90ea56f2a92ce0fe85ea85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 2 Mar 2026 20:48:07 +0000 Subject: [PATCH 290/498] Add `sysconfig[VPATH]` to `test.pythoninfo` (#145434) --- Lib/test/pythoninfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index fdd8989f9cb3f8..6df59946574a17 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -539,6 +539,7 @@ def collect_sysconfig(info_add): 'SHELL', 'SOABI', 'TEST_MODULES', + 'VAPTH', 'abs_builddir', 'abs_srcdir', 'prefix', From 9124bc194a03cfde7dfa7ab78e00e0191dc443b4 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Mon, 2 Mar 2026 13:10:26 -0800 Subject: [PATCH 291/498] Hide "object" prefix on dunders in contextlib docs & selectivly link some more (#145436) --- Doc/library/contextlib.rst | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index eec9ed1ba2581e..5c6403879ab505 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -21,9 +21,9 @@ Functions and classes provided: .. class:: AbstractContextManager An :term:`abstract base class` for classes that implement - :meth:`object.__enter__` and :meth:`object.__exit__`. A default - implementation for :meth:`object.__enter__` is provided which returns - ``self`` while :meth:`object.__exit__` is an abstract method which by default + :meth:`~object.__enter__` and :meth:`~object.__exit__`. A default + implementation for :meth:`~object.__enter__` is provided which returns + ``self`` while :meth:`~object.__exit__` is an abstract method which by default returns ``None``. See also the definition of :ref:`typecontextmanager`. .. versionadded:: 3.6 @@ -32,9 +32,9 @@ Functions and classes provided: .. class:: AbstractAsyncContextManager An :term:`abstract base class` for classes that implement - :meth:`object.__aenter__` and :meth:`object.__aexit__`. A default - implementation for :meth:`object.__aenter__` is provided which returns - ``self`` while :meth:`object.__aexit__` is an abstract method which by default + :meth:`~object.__aenter__` and :meth:`~object.__aexit__`. A default + implementation for :meth:`~object.__aenter__` is provided which returns + ``self`` while :meth:`~object.__aexit__` is an abstract method which by default returns ``None``. See also the definition of :ref:`async-context-managers`. @@ -228,7 +228,7 @@ Functions and classes provided: .. function:: nullcontext(enter_result=None) - Return a context manager that returns *enter_result* from ``__enter__``, but + Return a context manager that returns *enter_result* from :meth:`~object.__enter__`, but otherwise does nothing. It is intended to be used as a stand-in for an optional context manager, for example:: @@ -335,7 +335,7 @@ Functions and classes provided: For example, the output of :func:`help` normally is sent to *sys.stdout*. You can capture that output in a string by redirecting the output to an :class:`io.StringIO` object. The replacement stream is returned from the - ``__enter__`` method and so is available as the target of the + :meth:`~object.__enter__` method and so is available as the target of the :keyword:`with` statement:: with redirect_stdout(io.StringIO()) as f: @@ -396,7 +396,8 @@ Functions and classes provided: A base class that enables a context manager to also be used as a decorator. Context managers inheriting from ``ContextDecorator`` have to implement - ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional + :meth:`~object.__enter__` and :meth:`~object.__exit__` as normal. + ``__exit__`` retains its optional exception handling even when used as a decorator. ``ContextDecorator`` is used by :func:`contextmanager`, so you get this @@ -710,9 +711,9 @@ context management protocol. Catching exceptions from ``__enter__`` methods ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -It is occasionally desirable to catch exceptions from an ``__enter__`` +It is occasionally desirable to catch exceptions from an :meth:`~object.__enter__` method implementation, *without* inadvertently catching exceptions from -the :keyword:`with` statement body or the context manager's ``__exit__`` +the :keyword:`with` statement body or the context manager's :meth:`~object.__exit__` method. By using :class:`ExitStack` the steps in the context management protocol can be separated slightly in order to allow this:: From 46c5c57226862bc078bcdf0c9f5b40951b8615a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 2 Mar 2026 21:11:27 +0000 Subject: [PATCH 292/498] GH-145273: skip stdlib warning on module_search_paths_set (#145442) --- Modules/getpath.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/getpath.py b/Modules/getpath.py index 20e050787700bf..2f4d635a29585c 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -773,8 +773,10 @@ def search_up(prefix, *landmarks, test=isfile): # SANITY CHECKS # ****************************************************************************** -# Warn if the standard library is missing -if not stdlib_zip or not isfile(stdlib_zip): +# Warn if the standard library is missing, unless pythonpath_was_set was set, as +# that skips parts of the stdlib directories calculation — assume the provided +# pythonpath is correct. This is how subinterpreters initialize the path for eg. +if not py_setpath and not pythonpath_was_set and (not stdlib_zip or not isfile(stdlib_zip)): home_hint = f"The Python 'home' directory was set to {home!r}, is this correct?" if not stdlib_dir or not isdir(stdlib_dir): hint = home_hint if home else f'sys.prefix is set to {prefix}, is this correct?' From ea90b032a016122e7871e91c5210f3b4e68768b4 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Mon, 2 Mar 2026 21:39:07 +0000 Subject: [PATCH 293/498] gh-117865: Speedup import of `inspect` module (#144756) Co-authored-by: Alex Waygood --- Lib/inspect.py | 8 ++++---- Lib/test/test_inspect/test_inspect.py | 9 +++++++++ .../2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index 5d8ebb3dd54000..dfc5503dee536e 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -153,9 +153,9 @@ import itertools import linecache import os -import re +lazy import re import sys -import tokenize +lazy import tokenize import token import types import functools @@ -163,9 +163,9 @@ from keyword import iskeyword from operator import attrgetter from collections import namedtuple, OrderedDict -from weakref import ref as make_weakref +from _weakref import ref as make_weakref -# Create constants for the compiler flags in Include/code.h +# Create constants for the compiler flags in Include/cpython/code.h # We try to get them from dis to avoid duplication mod_dict = globals() for k, v in dis.COMPILER_FLAG_NAMES.items(): diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 4ad32c649ea83c..68ea62f565d824 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -173,6 +173,15 @@ def __get__(self, instance, owner): return self.func.__get__(instance, owner) +class TestImportTime(unittest.TestCase): + + @cpython_only + def test_lazy_import(self): + import_helper.ensure_lazy_imports( + "inspect", {"re", "tokenize"} + ) + + class TestPredicates(IsTestBase): def test_excluding_predicates(self): diff --git a/Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst b/Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst new file mode 100644 index 00000000000000..f45f6682869eb1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst @@ -0,0 +1 @@ +Reduce the import time of :mod:`inspect` module by ~20%. From 6908372fb8182be5849aa3c4b141c821b303ab61 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Tue, 3 Mar 2026 09:58:38 +0900 Subject: [PATCH 294/498] gh-145214: Narrow _GUARD_TOS_ANY_{SET,DICT} by using probable type (gh-145215) --- Include/internal/pycore_optimizer.h | 1 + Include/internal/pycore_uop_ids.h | 2066 ++++++++++++------------ Include/internal/pycore_uop_metadata.h | 84 + Python/bytecodes.c | 20 + Python/executor_cases.c.h | 340 ++++ Python/optimizer_analysis.c | 1 + Python/optimizer_bytecodes.c | 120 +- Python/optimizer_cases.c.h | 129 +- Python/optimizer_symbols.c | 28 + 9 files changed, 1728 insertions(+), 1061 deletions(-) diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index d9f7f59de1798e..c63f0167a0f64a 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -310,6 +310,7 @@ extern void _Py_uop_sym_set_recorded_type(JitOptContext *ctx, JitOptRef sym, PyT extern void _Py_uop_sym_set_recorded_gen_func(JitOptContext *ctx, JitOptRef ref, PyFunctionObject *value); extern PyCodeObject *_Py_uop_sym_get_probable_func_code(JitOptRef sym); extern PyObject *_Py_uop_sym_get_probable_value(JitOptRef sym); +extern PyTypeObject *_Py_uop_sym_get_probable_type(JitOptRef sym); extern JitOptRef *_Py_uop_sym_set_stack_depth(JitOptContext *ctx, int stack_depth, JitOptRef *current_sp); extern void _Py_uop_abstractcontext_init(JitOptContext *ctx, _PyBloomFilter *dependencies); diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 760fe86783fb8a..38f290df2c770f 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -177,29 +177,33 @@ extern "C" { #define _GUARD_THIRD_NULL 432 #define _GUARD_TOS_ANY_DICT 433 #define _GUARD_TOS_ANY_SET 434 -#define _GUARD_TOS_FLOAT 435 -#define _GUARD_TOS_INT 436 -#define _GUARD_TOS_LIST 437 -#define _GUARD_TOS_OVERFLOWED 438 -#define _GUARD_TOS_SLICE 439 -#define _GUARD_TOS_TUPLE 440 -#define _GUARD_TOS_UNICODE 441 -#define _GUARD_TYPE_VERSION 442 -#define _GUARD_TYPE_VERSION_AND_LOCK 443 -#define _HANDLE_PENDING_AND_DEOPT 444 +#define _GUARD_TOS_DICT 435 +#define _GUARD_TOS_FLOAT 436 +#define _GUARD_TOS_FROZENDICT 437 +#define _GUARD_TOS_FROZENSET 438 +#define _GUARD_TOS_INT 439 +#define _GUARD_TOS_LIST 440 +#define _GUARD_TOS_OVERFLOWED 441 +#define _GUARD_TOS_SET 442 +#define _GUARD_TOS_SLICE 443 +#define _GUARD_TOS_TUPLE 444 +#define _GUARD_TOS_UNICODE 445 +#define _GUARD_TYPE_VERSION 446 +#define _GUARD_TYPE_VERSION_AND_LOCK 447 +#define _HANDLE_PENDING_AND_DEOPT 448 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 445 -#define _INIT_CALL_PY_EXACT_ARGS 446 -#define _INIT_CALL_PY_EXACT_ARGS_0 447 -#define _INIT_CALL_PY_EXACT_ARGS_1 448 -#define _INIT_CALL_PY_EXACT_ARGS_2 449 -#define _INIT_CALL_PY_EXACT_ARGS_3 450 -#define _INIT_CALL_PY_EXACT_ARGS_4 451 -#define _INSERT_1_LOAD_CONST_INLINE 452 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW 453 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW 454 -#define _INSERT_NULL 455 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 449 +#define _INIT_CALL_PY_EXACT_ARGS 450 +#define _INIT_CALL_PY_EXACT_ARGS_0 451 +#define _INIT_CALL_PY_EXACT_ARGS_1 452 +#define _INIT_CALL_PY_EXACT_ARGS_2 453 +#define _INIT_CALL_PY_EXACT_ARGS_3 454 +#define _INIT_CALL_PY_EXACT_ARGS_4 455 +#define _INSERT_1_LOAD_CONST_INLINE 456 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW 457 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW 458 +#define _INSERT_NULL 459 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -209,1054 +213,1070 @@ extern "C" { #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE -#define _IS_NONE 456 -#define _IS_OP 457 -#define _ITER_CHECK_LIST 458 -#define _ITER_CHECK_RANGE 459 -#define _ITER_CHECK_TUPLE 460 -#define _ITER_JUMP_LIST 461 -#define _ITER_JUMP_RANGE 462 -#define _ITER_JUMP_TUPLE 463 -#define _ITER_NEXT_LIST 464 -#define _ITER_NEXT_LIST_TIER_TWO 465 -#define _ITER_NEXT_RANGE 466 -#define _ITER_NEXT_TUPLE 467 +#define _IS_NONE 460 +#define _IS_OP 461 +#define _ITER_CHECK_LIST 462 +#define _ITER_CHECK_RANGE 463 +#define _ITER_CHECK_TUPLE 464 +#define _ITER_JUMP_LIST 465 +#define _ITER_JUMP_RANGE 466 +#define _ITER_JUMP_TUPLE 467 +#define _ITER_NEXT_LIST 468 +#define _ITER_NEXT_LIST_TIER_TWO 469 +#define _ITER_NEXT_RANGE 470 +#define _ITER_NEXT_TUPLE 471 #define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT -#define _JUMP_TO_TOP 468 +#define _JUMP_TO_TOP 472 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 469 -#define _LOAD_ATTR_CLASS 470 +#define _LOAD_ATTR 473 +#define _LOAD_ATTR_CLASS 474 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 471 -#define _LOAD_ATTR_METHOD_LAZY_DICT 472 -#define _LOAD_ATTR_METHOD_NO_DICT 473 -#define _LOAD_ATTR_METHOD_WITH_VALUES 474 -#define _LOAD_ATTR_MODULE 475 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 476 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 477 -#define _LOAD_ATTR_PROPERTY_FRAME 478 -#define _LOAD_ATTR_SLOT 479 -#define _LOAD_ATTR_WITH_HINT 480 +#define _LOAD_ATTR_INSTANCE_VALUE 475 +#define _LOAD_ATTR_METHOD_LAZY_DICT 476 +#define _LOAD_ATTR_METHOD_NO_DICT 477 +#define _LOAD_ATTR_METHOD_WITH_VALUES 478 +#define _LOAD_ATTR_MODULE 479 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 480 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 481 +#define _LOAD_ATTR_PROPERTY_FRAME 482 +#define _LOAD_ATTR_SLOT 483 +#define _LOAD_ATTR_WITH_HINT 484 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 481 +#define _LOAD_BYTECODE 485 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 482 -#define _LOAD_CONST_INLINE_BORROW 483 -#define _LOAD_CONST_UNDER_INLINE 484 -#define _LOAD_CONST_UNDER_INLINE_BORROW 485 +#define _LOAD_CONST_INLINE 486 +#define _LOAD_CONST_INLINE_BORROW 487 +#define _LOAD_CONST_UNDER_INLINE 488 +#define _LOAD_CONST_UNDER_INLINE_BORROW 489 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 486 -#define _LOAD_FAST_0 487 -#define _LOAD_FAST_1 488 -#define _LOAD_FAST_2 489 -#define _LOAD_FAST_3 490 -#define _LOAD_FAST_4 491 -#define _LOAD_FAST_5 492 -#define _LOAD_FAST_6 493 -#define _LOAD_FAST_7 494 +#define _LOAD_FAST 490 +#define _LOAD_FAST_0 491 +#define _LOAD_FAST_1 492 +#define _LOAD_FAST_2 493 +#define _LOAD_FAST_3 494 +#define _LOAD_FAST_4 495 +#define _LOAD_FAST_5 496 +#define _LOAD_FAST_6 497 +#define _LOAD_FAST_7 498 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 495 -#define _LOAD_FAST_BORROW_0 496 -#define _LOAD_FAST_BORROW_1 497 -#define _LOAD_FAST_BORROW_2 498 -#define _LOAD_FAST_BORROW_3 499 -#define _LOAD_FAST_BORROW_4 500 -#define _LOAD_FAST_BORROW_5 501 -#define _LOAD_FAST_BORROW_6 502 -#define _LOAD_FAST_BORROW_7 503 +#define _LOAD_FAST_BORROW 499 +#define _LOAD_FAST_BORROW_0 500 +#define _LOAD_FAST_BORROW_1 501 +#define _LOAD_FAST_BORROW_2 502 +#define _LOAD_FAST_BORROW_3 503 +#define _LOAD_FAST_BORROW_4 504 +#define _LOAD_FAST_BORROW_5 505 +#define _LOAD_FAST_BORROW_6 506 +#define _LOAD_FAST_BORROW_7 507 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 504 -#define _LOAD_GLOBAL_BUILTINS 505 -#define _LOAD_GLOBAL_MODULE 506 +#define _LOAD_GLOBAL 508 +#define _LOAD_GLOBAL_BUILTINS 509 +#define _LOAD_GLOBAL_MODULE 510 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 507 -#define _LOAD_SMALL_INT_0 508 -#define _LOAD_SMALL_INT_1 509 -#define _LOAD_SMALL_INT_2 510 -#define _LOAD_SMALL_INT_3 511 -#define _LOAD_SPECIAL 512 +#define _LOAD_SMALL_INT 511 +#define _LOAD_SMALL_INT_0 512 +#define _LOAD_SMALL_INT_1 513 +#define _LOAD_SMALL_INT_2 514 +#define _LOAD_SMALL_INT_3 515 +#define _LOAD_SPECIAL 516 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 513 +#define _MAKE_CALLARGS_A_TUPLE 517 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 514 +#define _MAKE_WARM 518 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 515 -#define _MAYBE_EXPAND_METHOD_KW 516 -#define _MONITOR_CALL 517 -#define _MONITOR_CALL_KW 518 -#define _MONITOR_JUMP_BACKWARD 519 -#define _MONITOR_RESUME 520 +#define _MAYBE_EXPAND_METHOD 519 +#define _MAYBE_EXPAND_METHOD_KW 520 +#define _MONITOR_CALL 521 +#define _MONITOR_CALL_KW 522 +#define _MONITOR_JUMP_BACKWARD 523 +#define _MONITOR_RESUME 524 #define _NOP NOP -#define _POP_CALL 521 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 522 -#define _POP_CALL_ONE 523 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 524 -#define _POP_CALL_TWO 525 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 526 +#define _POP_CALL 525 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 526 +#define _POP_CALL_ONE 527 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 528 +#define _POP_CALL_TWO 529 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 530 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 527 -#define _POP_JUMP_IF_TRUE 528 +#define _POP_JUMP_IF_FALSE 531 +#define _POP_JUMP_IF_TRUE 532 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 529 -#define _POP_TOP_INT 530 -#define _POP_TOP_LOAD_CONST_INLINE 531 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 532 -#define _POP_TOP_NOP 533 -#define _POP_TOP_UNICODE 534 -#define _POP_TWO 535 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 536 +#define _POP_TOP_FLOAT 533 +#define _POP_TOP_INT 534 +#define _POP_TOP_LOAD_CONST_INLINE 535 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 536 +#define _POP_TOP_NOP 537 +#define _POP_TOP_UNICODE 538 +#define _POP_TWO 539 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 540 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 537 +#define _PUSH_FRAME 541 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 538 -#define _PY_FRAME_EX 539 -#define _PY_FRAME_GENERAL 540 -#define _PY_FRAME_KW 541 -#define _QUICKEN_RESUME 542 -#define _RECORD_4OS 543 -#define _RECORD_BOUND_METHOD 544 -#define _RECORD_CALLABLE 545 -#define _RECORD_CODE 546 -#define _RECORD_NOS 547 -#define _RECORD_NOS_GEN_FUNC 548 -#define _RECORD_TOS 549 -#define _RECORD_TOS_TYPE 550 -#define _REPLACE_WITH_TRUE 551 +#define _PUSH_NULL_CONDITIONAL 542 +#define _PY_FRAME_EX 543 +#define _PY_FRAME_GENERAL 544 +#define _PY_FRAME_KW 545 +#define _QUICKEN_RESUME 546 +#define _RECORD_4OS 547 +#define _RECORD_BOUND_METHOD 548 +#define _RECORD_CALLABLE 549 +#define _RECORD_CODE 550 +#define _RECORD_NOS 551 +#define _RECORD_NOS_GEN_FUNC 552 +#define _RECORD_TOS 553 +#define _RECORD_TOS_TYPE 554 +#define _REPLACE_WITH_TRUE 555 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 552 -#define _SEND 553 -#define _SEND_GEN_FRAME 554 +#define _SAVE_RETURN_OFFSET 556 +#define _SEND 557 +#define _SEND_GEN_FRAME 558 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 555 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 556 -#define _SPILL_OR_RELOAD 557 -#define _START_EXECUTOR 558 -#define _STORE_ATTR 559 -#define _STORE_ATTR_INSTANCE_VALUE 560 -#define _STORE_ATTR_SLOT 561 -#define _STORE_ATTR_WITH_HINT 562 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 559 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 560 +#define _SPILL_OR_RELOAD 561 +#define _START_EXECUTOR 562 +#define _STORE_ATTR 563 +#define _STORE_ATTR_INSTANCE_VALUE 564 +#define _STORE_ATTR_SLOT 565 +#define _STORE_ATTR_WITH_HINT 566 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 563 -#define _STORE_SUBSCR 564 -#define _STORE_SUBSCR_DICT 565 -#define _STORE_SUBSCR_LIST_INT 566 -#define _SWAP 567 -#define _SWAP_2 568 -#define _SWAP_3 569 -#define _SWAP_FAST 570 -#define _SWAP_FAST_0 571 -#define _SWAP_FAST_1 572 -#define _SWAP_FAST_2 573 -#define _SWAP_FAST_3 574 -#define _SWAP_FAST_4 575 -#define _SWAP_FAST_5 576 -#define _SWAP_FAST_6 577 -#define _SWAP_FAST_7 578 -#define _TIER2_RESUME_CHECK 579 -#define _TO_BOOL 580 +#define _STORE_SLICE 567 +#define _STORE_SUBSCR 568 +#define _STORE_SUBSCR_DICT 569 +#define _STORE_SUBSCR_LIST_INT 570 +#define _SWAP 571 +#define _SWAP_2 572 +#define _SWAP_3 573 +#define _SWAP_FAST 574 +#define _SWAP_FAST_0 575 +#define _SWAP_FAST_1 576 +#define _SWAP_FAST_2 577 +#define _SWAP_FAST_3 578 +#define _SWAP_FAST_4 579 +#define _SWAP_FAST_5 580 +#define _SWAP_FAST_6 581 +#define _SWAP_FAST_7 582 +#define _TIER2_RESUME_CHECK 583 +#define _TO_BOOL 584 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 581 -#define _TO_BOOL_LIST 582 +#define _TO_BOOL_INT 585 +#define _TO_BOOL_LIST 586 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 583 +#define _TO_BOOL_STR 587 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 584 -#define _UNARY_NEGATIVE 585 +#define _UNARY_INVERT 588 +#define _UNARY_NEGATIVE 589 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 586 -#define _UNPACK_SEQUENCE_LIST 587 -#define _UNPACK_SEQUENCE_TUPLE 588 -#define _UNPACK_SEQUENCE_TWO_TUPLE 589 +#define _UNPACK_SEQUENCE 590 +#define _UNPACK_SEQUENCE_LIST 591 +#define _UNPACK_SEQUENCE_TUPLE 592 +#define _UNPACK_SEQUENCE_TWO_TUPLE 593 #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 589 -#define _BINARY_OP_r23 590 -#define _BINARY_OP_ADD_FLOAT_r03 591 -#define _BINARY_OP_ADD_FLOAT_r13 592 -#define _BINARY_OP_ADD_FLOAT_r23 593 -#define _BINARY_OP_ADD_INT_r03 594 -#define _BINARY_OP_ADD_INT_r13 595 -#define _BINARY_OP_ADD_INT_r23 596 -#define _BINARY_OP_ADD_UNICODE_r03 597 -#define _BINARY_OP_ADD_UNICODE_r13 598 -#define _BINARY_OP_ADD_UNICODE_r23 599 -#define _BINARY_OP_EXTEND_r23 600 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 601 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 602 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 603 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 604 -#define _BINARY_OP_MULTIPLY_INT_r03 605 -#define _BINARY_OP_MULTIPLY_INT_r13 606 -#define _BINARY_OP_MULTIPLY_INT_r23 607 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 608 -#define _BINARY_OP_SUBSCR_DICT_r23 609 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 610 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 611 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 612 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 613 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 614 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 615 -#define _BINARY_OP_SUBSCR_STR_INT_r23 616 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 617 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 618 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 619 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 620 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 621 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 622 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 623 -#define _BINARY_OP_SUBTRACT_INT_r03 624 -#define _BINARY_OP_SUBTRACT_INT_r13 625 -#define _BINARY_OP_SUBTRACT_INT_r23 626 -#define _BINARY_SLICE_r31 627 -#define _BUILD_INTERPOLATION_r01 628 -#define _BUILD_LIST_r01 629 -#define _BUILD_MAP_r01 630 -#define _BUILD_SET_r01 631 -#define _BUILD_SLICE_r01 632 -#define _BUILD_STRING_r01 633 -#define _BUILD_TEMPLATE_r21 634 -#define _BUILD_TUPLE_r01 635 -#define _CALL_BUILTIN_CLASS_r01 636 -#define _CALL_BUILTIN_FAST_r01 637 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 638 -#define _CALL_BUILTIN_O_r03 639 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 640 -#define _CALL_INTRINSIC_1_r11 641 -#define _CALL_INTRINSIC_2_r21 642 -#define _CALL_ISINSTANCE_r31 643 -#define _CALL_KW_NON_PY_r11 644 -#define _CALL_LEN_r33 645 -#define _CALL_LIST_APPEND_r03 646 -#define _CALL_LIST_APPEND_r13 647 -#define _CALL_LIST_APPEND_r23 648 -#define _CALL_LIST_APPEND_r33 649 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 650 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 651 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 652 -#define _CALL_METHOD_DESCRIPTOR_O_r03 653 -#define _CALL_NON_PY_GENERAL_r01 654 -#define _CALL_STR_1_r32 655 -#define _CALL_TUPLE_1_r32 656 -#define _CALL_TYPE_1_r02 657 -#define _CALL_TYPE_1_r12 658 -#define _CALL_TYPE_1_r22 659 -#define _CALL_TYPE_1_r32 660 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 661 -#define _CHECK_ATTR_CLASS_r01 662 -#define _CHECK_ATTR_CLASS_r11 663 -#define _CHECK_ATTR_CLASS_r22 664 -#define _CHECK_ATTR_CLASS_r33 665 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 666 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 667 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 668 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 669 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 670 -#define _CHECK_EG_MATCH_r22 671 -#define _CHECK_EXC_MATCH_r22 672 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 673 -#define _CHECK_FUNCTION_VERSION_r00 674 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 675 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 676 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 677 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 678 -#define _CHECK_FUNCTION_VERSION_KW_r11 679 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 680 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 681 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 682 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 683 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 684 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 685 -#define _CHECK_IS_PY_CALLABLE_EX_r03 686 -#define _CHECK_IS_PY_CALLABLE_EX_r13 687 -#define _CHECK_IS_PY_CALLABLE_EX_r23 688 -#define _CHECK_IS_PY_CALLABLE_EX_r33 689 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 690 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 691 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 692 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 693 -#define _CHECK_METHOD_VERSION_r00 694 -#define _CHECK_METHOD_VERSION_KW_r11 695 -#define _CHECK_PEP_523_r00 696 -#define _CHECK_PEP_523_r11 697 -#define _CHECK_PEP_523_r22 698 -#define _CHECK_PEP_523_r33 699 -#define _CHECK_PERIODIC_r00 700 -#define _CHECK_PERIODIC_AT_END_r00 701 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 702 -#define _CHECK_RECURSION_REMAINING_r00 703 -#define _CHECK_RECURSION_REMAINING_r11 704 -#define _CHECK_RECURSION_REMAINING_r22 705 -#define _CHECK_RECURSION_REMAINING_r33 706 -#define _CHECK_STACK_SPACE_r00 707 -#define _CHECK_STACK_SPACE_OPERAND_r00 708 -#define _CHECK_STACK_SPACE_OPERAND_r11 709 -#define _CHECK_STACK_SPACE_OPERAND_r22 710 -#define _CHECK_STACK_SPACE_OPERAND_r33 711 -#define _CHECK_VALIDITY_r00 712 -#define _CHECK_VALIDITY_r11 713 -#define _CHECK_VALIDITY_r22 714 -#define _CHECK_VALIDITY_r33 715 -#define _COLD_DYNAMIC_EXIT_r00 716 -#define _COLD_EXIT_r00 717 -#define _COMPARE_OP_r21 718 -#define _COMPARE_OP_FLOAT_r03 719 -#define _COMPARE_OP_FLOAT_r13 720 -#define _COMPARE_OP_FLOAT_r23 721 -#define _COMPARE_OP_INT_r23 722 -#define _COMPARE_OP_STR_r23 723 -#define _CONTAINS_OP_r23 724 -#define _CONTAINS_OP_DICT_r23 725 -#define _CONTAINS_OP_SET_r23 726 -#define _CONVERT_VALUE_r11 727 -#define _COPY_r01 728 -#define _COPY_1_r02 729 -#define _COPY_1_r12 730 -#define _COPY_1_r23 731 -#define _COPY_2_r03 732 -#define _COPY_2_r13 733 -#define _COPY_2_r23 734 -#define _COPY_3_r03 735 -#define _COPY_3_r13 736 -#define _COPY_3_r23 737 -#define _COPY_3_r33 738 -#define _COPY_FREE_VARS_r00 739 -#define _COPY_FREE_VARS_r11 740 -#define _COPY_FREE_VARS_r22 741 -#define _COPY_FREE_VARS_r33 742 -#define _CREATE_INIT_FRAME_r01 743 -#define _DELETE_ATTR_r10 744 -#define _DELETE_DEREF_r00 745 -#define _DELETE_FAST_r00 746 -#define _DELETE_GLOBAL_r00 747 -#define _DELETE_NAME_r00 748 -#define _DELETE_SUBSCR_r20 749 -#define _DEOPT_r00 750 -#define _DEOPT_r10 751 -#define _DEOPT_r20 752 -#define _DEOPT_r30 753 -#define _DICT_MERGE_r10 754 -#define _DICT_UPDATE_r10 755 -#define _DO_CALL_r01 756 -#define _DO_CALL_FUNCTION_EX_r31 757 -#define _DO_CALL_KW_r11 758 -#define _DYNAMIC_EXIT_r00 759 -#define _DYNAMIC_EXIT_r10 760 -#define _DYNAMIC_EXIT_r20 761 -#define _DYNAMIC_EXIT_r30 762 -#define _END_FOR_r10 763 -#define _END_SEND_r21 764 -#define _ERROR_POP_N_r00 765 -#define _EXIT_INIT_CHECK_r10 766 -#define _EXIT_TRACE_r00 767 -#define _EXIT_TRACE_r10 768 -#define _EXIT_TRACE_r20 769 -#define _EXIT_TRACE_r30 770 -#define _EXPAND_METHOD_r00 771 -#define _EXPAND_METHOD_KW_r11 772 -#define _FATAL_ERROR_r00 773 -#define _FATAL_ERROR_r11 774 -#define _FATAL_ERROR_r22 775 -#define _FATAL_ERROR_r33 776 -#define _FORMAT_SIMPLE_r11 777 -#define _FORMAT_WITH_SPEC_r21 778 -#define _FOR_ITER_r23 779 -#define _FOR_ITER_GEN_FRAME_r03 780 -#define _FOR_ITER_GEN_FRAME_r13 781 -#define _FOR_ITER_GEN_FRAME_r23 782 -#define _FOR_ITER_TIER_TWO_r23 783 -#define _GET_AITER_r11 784 -#define _GET_ANEXT_r12 785 -#define _GET_AWAITABLE_r11 786 -#define _GET_ITER_r12 787 -#define _GET_LEN_r12 788 -#define _GET_YIELD_FROM_ITER_r11 789 -#define _GUARD_BINARY_OP_EXTEND_r22 790 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 791 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 792 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 793 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 794 -#define _GUARD_BIT_IS_SET_POP_r00 795 -#define _GUARD_BIT_IS_SET_POP_r10 796 -#define _GUARD_BIT_IS_SET_POP_r21 797 -#define _GUARD_BIT_IS_SET_POP_r32 798 -#define _GUARD_BIT_IS_SET_POP_4_r00 799 -#define _GUARD_BIT_IS_SET_POP_4_r10 800 -#define _GUARD_BIT_IS_SET_POP_4_r21 801 -#define _GUARD_BIT_IS_SET_POP_4_r32 802 -#define _GUARD_BIT_IS_SET_POP_5_r00 803 -#define _GUARD_BIT_IS_SET_POP_5_r10 804 -#define _GUARD_BIT_IS_SET_POP_5_r21 805 -#define _GUARD_BIT_IS_SET_POP_5_r32 806 -#define _GUARD_BIT_IS_SET_POP_6_r00 807 -#define _GUARD_BIT_IS_SET_POP_6_r10 808 -#define _GUARD_BIT_IS_SET_POP_6_r21 809 -#define _GUARD_BIT_IS_SET_POP_6_r32 810 -#define _GUARD_BIT_IS_SET_POP_7_r00 811 -#define _GUARD_BIT_IS_SET_POP_7_r10 812 -#define _GUARD_BIT_IS_SET_POP_7_r21 813 -#define _GUARD_BIT_IS_SET_POP_7_r32 814 -#define _GUARD_BIT_IS_UNSET_POP_r00 815 -#define _GUARD_BIT_IS_UNSET_POP_r10 816 -#define _GUARD_BIT_IS_UNSET_POP_r21 817 -#define _GUARD_BIT_IS_UNSET_POP_r32 818 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 819 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 820 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 821 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 822 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 823 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 824 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 825 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 826 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 827 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 828 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 829 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 830 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 831 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 832 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 833 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 834 -#define _GUARD_CALLABLE_ISINSTANCE_r03 835 -#define _GUARD_CALLABLE_ISINSTANCE_r13 836 -#define _GUARD_CALLABLE_ISINSTANCE_r23 837 -#define _GUARD_CALLABLE_ISINSTANCE_r33 838 -#define _GUARD_CALLABLE_LEN_r03 839 -#define _GUARD_CALLABLE_LEN_r13 840 -#define _GUARD_CALLABLE_LEN_r23 841 -#define _GUARD_CALLABLE_LEN_r33 842 -#define _GUARD_CALLABLE_LIST_APPEND_r03 843 -#define _GUARD_CALLABLE_LIST_APPEND_r13 844 -#define _GUARD_CALLABLE_LIST_APPEND_r23 845 -#define _GUARD_CALLABLE_LIST_APPEND_r33 846 -#define _GUARD_CALLABLE_STR_1_r03 847 -#define _GUARD_CALLABLE_STR_1_r13 848 -#define _GUARD_CALLABLE_STR_1_r23 849 -#define _GUARD_CALLABLE_STR_1_r33 850 -#define _GUARD_CALLABLE_TUPLE_1_r03 851 -#define _GUARD_CALLABLE_TUPLE_1_r13 852 -#define _GUARD_CALLABLE_TUPLE_1_r23 853 -#define _GUARD_CALLABLE_TUPLE_1_r33 854 -#define _GUARD_CALLABLE_TYPE_1_r03 855 -#define _GUARD_CALLABLE_TYPE_1_r13 856 -#define _GUARD_CALLABLE_TYPE_1_r23 857 -#define _GUARD_CALLABLE_TYPE_1_r33 858 -#define _GUARD_CODE_VERSION_r00 859 -#define _GUARD_CODE_VERSION_r11 860 -#define _GUARD_CODE_VERSION_r22 861 -#define _GUARD_CODE_VERSION_r33 862 -#define _GUARD_DORV_NO_DICT_r01 863 -#define _GUARD_DORV_NO_DICT_r11 864 -#define _GUARD_DORV_NO_DICT_r22 865 -#define _GUARD_DORV_NO_DICT_r33 866 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 867 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 868 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 869 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 870 -#define _GUARD_GLOBALS_VERSION_r00 871 -#define _GUARD_GLOBALS_VERSION_r11 872 -#define _GUARD_GLOBALS_VERSION_r22 873 -#define _GUARD_GLOBALS_VERSION_r33 874 -#define _GUARD_IP_RETURN_GENERATOR_r00 875 -#define _GUARD_IP_RETURN_GENERATOR_r11 876 -#define _GUARD_IP_RETURN_GENERATOR_r22 877 -#define _GUARD_IP_RETURN_GENERATOR_r33 878 -#define _GUARD_IP_RETURN_VALUE_r00 879 -#define _GUARD_IP_RETURN_VALUE_r11 880 -#define _GUARD_IP_RETURN_VALUE_r22 881 -#define _GUARD_IP_RETURN_VALUE_r33 882 -#define _GUARD_IP_YIELD_VALUE_r00 883 -#define _GUARD_IP_YIELD_VALUE_r11 884 -#define _GUARD_IP_YIELD_VALUE_r22 885 -#define _GUARD_IP_YIELD_VALUE_r33 886 -#define _GUARD_IP__PUSH_FRAME_r00 887 -#define _GUARD_IP__PUSH_FRAME_r11 888 -#define _GUARD_IP__PUSH_FRAME_r22 889 -#define _GUARD_IP__PUSH_FRAME_r33 890 -#define _GUARD_IS_FALSE_POP_r00 891 -#define _GUARD_IS_FALSE_POP_r10 892 -#define _GUARD_IS_FALSE_POP_r21 893 -#define _GUARD_IS_FALSE_POP_r32 894 -#define _GUARD_IS_NONE_POP_r00 895 -#define _GUARD_IS_NONE_POP_r10 896 -#define _GUARD_IS_NONE_POP_r21 897 -#define _GUARD_IS_NONE_POP_r32 898 -#define _GUARD_IS_NOT_NONE_POP_r10 899 -#define _GUARD_IS_TRUE_POP_r00 900 -#define _GUARD_IS_TRUE_POP_r10 901 -#define _GUARD_IS_TRUE_POP_r21 902 -#define _GUARD_IS_TRUE_POP_r32 903 -#define _GUARD_KEYS_VERSION_r01 904 -#define _GUARD_KEYS_VERSION_r11 905 -#define _GUARD_KEYS_VERSION_r22 906 -#define _GUARD_KEYS_VERSION_r33 907 -#define _GUARD_NOS_ANY_DICT_r02 908 -#define _GUARD_NOS_ANY_DICT_r12 909 -#define _GUARD_NOS_ANY_DICT_r22 910 -#define _GUARD_NOS_ANY_DICT_r33 911 -#define _GUARD_NOS_COMPACT_ASCII_r02 912 -#define _GUARD_NOS_COMPACT_ASCII_r12 913 -#define _GUARD_NOS_COMPACT_ASCII_r22 914 -#define _GUARD_NOS_COMPACT_ASCII_r33 915 -#define _GUARD_NOS_DICT_r02 916 -#define _GUARD_NOS_DICT_r12 917 -#define _GUARD_NOS_DICT_r22 918 -#define _GUARD_NOS_DICT_r33 919 -#define _GUARD_NOS_FLOAT_r02 920 -#define _GUARD_NOS_FLOAT_r12 921 -#define _GUARD_NOS_FLOAT_r22 922 -#define _GUARD_NOS_FLOAT_r33 923 -#define _GUARD_NOS_INT_r02 924 -#define _GUARD_NOS_INT_r12 925 -#define _GUARD_NOS_INT_r22 926 -#define _GUARD_NOS_INT_r33 927 -#define _GUARD_NOS_LIST_r02 928 -#define _GUARD_NOS_LIST_r12 929 -#define _GUARD_NOS_LIST_r22 930 -#define _GUARD_NOS_LIST_r33 931 -#define _GUARD_NOS_NOT_NULL_r02 932 -#define _GUARD_NOS_NOT_NULL_r12 933 -#define _GUARD_NOS_NOT_NULL_r22 934 -#define _GUARD_NOS_NOT_NULL_r33 935 -#define _GUARD_NOS_NULL_r02 936 -#define _GUARD_NOS_NULL_r12 937 -#define _GUARD_NOS_NULL_r22 938 -#define _GUARD_NOS_NULL_r33 939 -#define _GUARD_NOS_OVERFLOWED_r02 940 -#define _GUARD_NOS_OVERFLOWED_r12 941 -#define _GUARD_NOS_OVERFLOWED_r22 942 -#define _GUARD_NOS_OVERFLOWED_r33 943 -#define _GUARD_NOS_TUPLE_r02 944 -#define _GUARD_NOS_TUPLE_r12 945 -#define _GUARD_NOS_TUPLE_r22 946 -#define _GUARD_NOS_TUPLE_r33 947 -#define _GUARD_NOS_UNICODE_r02 948 -#define _GUARD_NOS_UNICODE_r12 949 -#define _GUARD_NOS_UNICODE_r22 950 -#define _GUARD_NOS_UNICODE_r33 951 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 952 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 953 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 954 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 955 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 956 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 957 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 958 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 959 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 960 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 961 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 962 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 963 -#define _GUARD_THIRD_NULL_r03 964 -#define _GUARD_THIRD_NULL_r13 965 -#define _GUARD_THIRD_NULL_r23 966 -#define _GUARD_THIRD_NULL_r33 967 -#define _GUARD_TOS_ANY_DICT_r01 968 -#define _GUARD_TOS_ANY_DICT_r11 969 -#define _GUARD_TOS_ANY_DICT_r22 970 -#define _GUARD_TOS_ANY_DICT_r33 971 -#define _GUARD_TOS_ANY_SET_r01 972 -#define _GUARD_TOS_ANY_SET_r11 973 -#define _GUARD_TOS_ANY_SET_r22 974 -#define _GUARD_TOS_ANY_SET_r33 975 -#define _GUARD_TOS_FLOAT_r01 976 -#define _GUARD_TOS_FLOAT_r11 977 -#define _GUARD_TOS_FLOAT_r22 978 -#define _GUARD_TOS_FLOAT_r33 979 -#define _GUARD_TOS_INT_r01 980 -#define _GUARD_TOS_INT_r11 981 -#define _GUARD_TOS_INT_r22 982 -#define _GUARD_TOS_INT_r33 983 -#define _GUARD_TOS_LIST_r01 984 -#define _GUARD_TOS_LIST_r11 985 -#define _GUARD_TOS_LIST_r22 986 -#define _GUARD_TOS_LIST_r33 987 -#define _GUARD_TOS_OVERFLOWED_r01 988 -#define _GUARD_TOS_OVERFLOWED_r11 989 -#define _GUARD_TOS_OVERFLOWED_r22 990 -#define _GUARD_TOS_OVERFLOWED_r33 991 -#define _GUARD_TOS_SLICE_r01 992 -#define _GUARD_TOS_SLICE_r11 993 -#define _GUARD_TOS_SLICE_r22 994 -#define _GUARD_TOS_SLICE_r33 995 -#define _GUARD_TOS_TUPLE_r01 996 -#define _GUARD_TOS_TUPLE_r11 997 -#define _GUARD_TOS_TUPLE_r22 998 -#define _GUARD_TOS_TUPLE_r33 999 -#define _GUARD_TOS_UNICODE_r01 1000 -#define _GUARD_TOS_UNICODE_r11 1001 -#define _GUARD_TOS_UNICODE_r22 1002 -#define _GUARD_TOS_UNICODE_r33 1003 -#define _GUARD_TYPE_VERSION_r01 1004 -#define _GUARD_TYPE_VERSION_r11 1005 -#define _GUARD_TYPE_VERSION_r22 1006 -#define _GUARD_TYPE_VERSION_r33 1007 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1008 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1009 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1010 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1011 -#define _HANDLE_PENDING_AND_DEOPT_r00 1012 -#define _HANDLE_PENDING_AND_DEOPT_r10 1013 -#define _HANDLE_PENDING_AND_DEOPT_r20 1014 -#define _HANDLE_PENDING_AND_DEOPT_r30 1015 -#define _IMPORT_FROM_r12 1016 -#define _IMPORT_NAME_r21 1017 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1018 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1019 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1020 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1021 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1022 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1023 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1024 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1025 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1026 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1027 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1028 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1029 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1030 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1031 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1032 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1033 -#define _INSERT_NULL_r10 1034 -#define _INSTRUMENTED_FOR_ITER_r23 1035 -#define _INSTRUMENTED_INSTRUCTION_r00 1036 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1037 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1038 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1039 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1040 -#define _INSTRUMENTED_LINE_r00 1041 -#define _INSTRUMENTED_NOT_TAKEN_r00 1042 -#define _INSTRUMENTED_NOT_TAKEN_r11 1043 -#define _INSTRUMENTED_NOT_TAKEN_r22 1044 -#define _INSTRUMENTED_NOT_TAKEN_r33 1045 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1046 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1047 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1048 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1049 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1050 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1051 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1052 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1053 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1054 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1055 -#define _IS_NONE_r11 1056 -#define _IS_OP_r03 1057 -#define _IS_OP_r13 1058 -#define _IS_OP_r23 1059 -#define _ITER_CHECK_LIST_r02 1060 -#define _ITER_CHECK_LIST_r12 1061 -#define _ITER_CHECK_LIST_r22 1062 -#define _ITER_CHECK_LIST_r33 1063 -#define _ITER_CHECK_RANGE_r02 1064 -#define _ITER_CHECK_RANGE_r12 1065 -#define _ITER_CHECK_RANGE_r22 1066 -#define _ITER_CHECK_RANGE_r33 1067 -#define _ITER_CHECK_TUPLE_r02 1068 -#define _ITER_CHECK_TUPLE_r12 1069 -#define _ITER_CHECK_TUPLE_r22 1070 -#define _ITER_CHECK_TUPLE_r33 1071 -#define _ITER_JUMP_LIST_r02 1072 -#define _ITER_JUMP_LIST_r12 1073 -#define _ITER_JUMP_LIST_r22 1074 -#define _ITER_JUMP_LIST_r33 1075 -#define _ITER_JUMP_RANGE_r02 1076 -#define _ITER_JUMP_RANGE_r12 1077 -#define _ITER_JUMP_RANGE_r22 1078 -#define _ITER_JUMP_RANGE_r33 1079 -#define _ITER_JUMP_TUPLE_r02 1080 -#define _ITER_JUMP_TUPLE_r12 1081 -#define _ITER_JUMP_TUPLE_r22 1082 -#define _ITER_JUMP_TUPLE_r33 1083 -#define _ITER_NEXT_LIST_r23 1084 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1085 -#define _ITER_NEXT_RANGE_r03 1086 -#define _ITER_NEXT_RANGE_r13 1087 -#define _ITER_NEXT_RANGE_r23 1088 -#define _ITER_NEXT_TUPLE_r03 1089 -#define _ITER_NEXT_TUPLE_r13 1090 -#define _ITER_NEXT_TUPLE_r23 1091 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1092 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1093 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1094 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1095 -#define _JUMP_TO_TOP_r00 1096 -#define _LIST_APPEND_r10 1097 -#define _LIST_EXTEND_r10 1098 -#define _LOAD_ATTR_r10 1099 -#define _LOAD_ATTR_CLASS_r11 1100 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1101 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1102 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1103 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1104 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1105 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1106 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1107 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1108 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1109 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1110 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1111 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1112 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1113 -#define _LOAD_ATTR_MODULE_r12 1114 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1115 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1116 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1117 -#define _LOAD_ATTR_SLOT_r02 1118 -#define _LOAD_ATTR_SLOT_r12 1119 -#define _LOAD_ATTR_SLOT_r23 1120 -#define _LOAD_ATTR_WITH_HINT_r12 1121 -#define _LOAD_BUILD_CLASS_r01 1122 -#define _LOAD_BYTECODE_r00 1123 -#define _LOAD_COMMON_CONSTANT_r01 1124 -#define _LOAD_COMMON_CONSTANT_r12 1125 -#define _LOAD_COMMON_CONSTANT_r23 1126 -#define _LOAD_CONST_r01 1127 -#define _LOAD_CONST_r12 1128 -#define _LOAD_CONST_r23 1129 -#define _LOAD_CONST_INLINE_r01 1130 -#define _LOAD_CONST_INLINE_r12 1131 -#define _LOAD_CONST_INLINE_r23 1132 -#define _LOAD_CONST_INLINE_BORROW_r01 1133 -#define _LOAD_CONST_INLINE_BORROW_r12 1134 -#define _LOAD_CONST_INLINE_BORROW_r23 1135 -#define _LOAD_CONST_UNDER_INLINE_r02 1136 -#define _LOAD_CONST_UNDER_INLINE_r12 1137 -#define _LOAD_CONST_UNDER_INLINE_r23 1138 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1139 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1140 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1141 -#define _LOAD_DEREF_r01 1142 -#define _LOAD_FAST_r01 1143 -#define _LOAD_FAST_r12 1144 -#define _LOAD_FAST_r23 1145 -#define _LOAD_FAST_0_r01 1146 -#define _LOAD_FAST_0_r12 1147 -#define _LOAD_FAST_0_r23 1148 -#define _LOAD_FAST_1_r01 1149 -#define _LOAD_FAST_1_r12 1150 -#define _LOAD_FAST_1_r23 1151 -#define _LOAD_FAST_2_r01 1152 -#define _LOAD_FAST_2_r12 1153 -#define _LOAD_FAST_2_r23 1154 -#define _LOAD_FAST_3_r01 1155 -#define _LOAD_FAST_3_r12 1156 -#define _LOAD_FAST_3_r23 1157 -#define _LOAD_FAST_4_r01 1158 -#define _LOAD_FAST_4_r12 1159 -#define _LOAD_FAST_4_r23 1160 -#define _LOAD_FAST_5_r01 1161 -#define _LOAD_FAST_5_r12 1162 -#define _LOAD_FAST_5_r23 1163 -#define _LOAD_FAST_6_r01 1164 -#define _LOAD_FAST_6_r12 1165 -#define _LOAD_FAST_6_r23 1166 -#define _LOAD_FAST_7_r01 1167 -#define _LOAD_FAST_7_r12 1168 -#define _LOAD_FAST_7_r23 1169 -#define _LOAD_FAST_AND_CLEAR_r01 1170 -#define _LOAD_FAST_AND_CLEAR_r12 1171 -#define _LOAD_FAST_AND_CLEAR_r23 1172 -#define _LOAD_FAST_BORROW_r01 1173 -#define _LOAD_FAST_BORROW_r12 1174 -#define _LOAD_FAST_BORROW_r23 1175 -#define _LOAD_FAST_BORROW_0_r01 1176 -#define _LOAD_FAST_BORROW_0_r12 1177 -#define _LOAD_FAST_BORROW_0_r23 1178 -#define _LOAD_FAST_BORROW_1_r01 1179 -#define _LOAD_FAST_BORROW_1_r12 1180 -#define _LOAD_FAST_BORROW_1_r23 1181 -#define _LOAD_FAST_BORROW_2_r01 1182 -#define _LOAD_FAST_BORROW_2_r12 1183 -#define _LOAD_FAST_BORROW_2_r23 1184 -#define _LOAD_FAST_BORROW_3_r01 1185 -#define _LOAD_FAST_BORROW_3_r12 1186 -#define _LOAD_FAST_BORROW_3_r23 1187 -#define _LOAD_FAST_BORROW_4_r01 1188 -#define _LOAD_FAST_BORROW_4_r12 1189 -#define _LOAD_FAST_BORROW_4_r23 1190 -#define _LOAD_FAST_BORROW_5_r01 1191 -#define _LOAD_FAST_BORROW_5_r12 1192 -#define _LOAD_FAST_BORROW_5_r23 1193 -#define _LOAD_FAST_BORROW_6_r01 1194 -#define _LOAD_FAST_BORROW_6_r12 1195 -#define _LOAD_FAST_BORROW_6_r23 1196 -#define _LOAD_FAST_BORROW_7_r01 1197 -#define _LOAD_FAST_BORROW_7_r12 1198 -#define _LOAD_FAST_BORROW_7_r23 1199 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1200 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1201 -#define _LOAD_FAST_CHECK_r01 1202 -#define _LOAD_FAST_CHECK_r12 1203 -#define _LOAD_FAST_CHECK_r23 1204 -#define _LOAD_FAST_LOAD_FAST_r02 1205 -#define _LOAD_FAST_LOAD_FAST_r13 1206 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1207 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1208 -#define _LOAD_GLOBAL_r00 1209 -#define _LOAD_GLOBAL_BUILTINS_r01 1210 -#define _LOAD_GLOBAL_MODULE_r01 1211 -#define _LOAD_LOCALS_r01 1212 -#define _LOAD_LOCALS_r12 1213 -#define _LOAD_LOCALS_r23 1214 -#define _LOAD_NAME_r01 1215 -#define _LOAD_SMALL_INT_r01 1216 -#define _LOAD_SMALL_INT_r12 1217 -#define _LOAD_SMALL_INT_r23 1218 -#define _LOAD_SMALL_INT_0_r01 1219 -#define _LOAD_SMALL_INT_0_r12 1220 -#define _LOAD_SMALL_INT_0_r23 1221 -#define _LOAD_SMALL_INT_1_r01 1222 -#define _LOAD_SMALL_INT_1_r12 1223 -#define _LOAD_SMALL_INT_1_r23 1224 -#define _LOAD_SMALL_INT_2_r01 1225 -#define _LOAD_SMALL_INT_2_r12 1226 -#define _LOAD_SMALL_INT_2_r23 1227 -#define _LOAD_SMALL_INT_3_r01 1228 -#define _LOAD_SMALL_INT_3_r12 1229 -#define _LOAD_SMALL_INT_3_r23 1230 -#define _LOAD_SPECIAL_r00 1231 -#define _LOAD_SUPER_ATTR_ATTR_r31 1232 -#define _LOAD_SUPER_ATTR_METHOD_r32 1233 -#define _MAKE_CALLARGS_A_TUPLE_r33 1234 -#define _MAKE_CELL_r00 1235 -#define _MAKE_FUNCTION_r11 1236 -#define _MAKE_WARM_r00 1237 -#define _MAKE_WARM_r11 1238 -#define _MAKE_WARM_r22 1239 -#define _MAKE_WARM_r33 1240 -#define _MAP_ADD_r20 1241 -#define _MATCH_CLASS_r31 1242 -#define _MATCH_KEYS_r23 1243 -#define _MATCH_MAPPING_r02 1244 -#define _MATCH_MAPPING_r12 1245 -#define _MATCH_MAPPING_r23 1246 -#define _MATCH_SEQUENCE_r02 1247 -#define _MATCH_SEQUENCE_r12 1248 -#define _MATCH_SEQUENCE_r23 1249 -#define _MAYBE_EXPAND_METHOD_r00 1250 -#define _MAYBE_EXPAND_METHOD_KW_r11 1251 -#define _MONITOR_CALL_r00 1252 -#define _MONITOR_CALL_KW_r11 1253 -#define _MONITOR_JUMP_BACKWARD_r00 1254 -#define _MONITOR_JUMP_BACKWARD_r11 1255 -#define _MONITOR_JUMP_BACKWARD_r22 1256 -#define _MONITOR_JUMP_BACKWARD_r33 1257 -#define _MONITOR_RESUME_r00 1258 -#define _NOP_r00 1259 -#define _NOP_r11 1260 -#define _NOP_r22 1261 -#define _NOP_r33 1262 -#define _POP_CALL_r20 1263 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1264 -#define _POP_CALL_ONE_r30 1265 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1266 -#define _POP_CALL_TWO_r30 1267 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1268 -#define _POP_EXCEPT_r10 1269 -#define _POP_ITER_r20 1270 -#define _POP_JUMP_IF_FALSE_r00 1271 -#define _POP_JUMP_IF_FALSE_r10 1272 -#define _POP_JUMP_IF_FALSE_r21 1273 -#define _POP_JUMP_IF_FALSE_r32 1274 -#define _POP_JUMP_IF_TRUE_r00 1275 -#define _POP_JUMP_IF_TRUE_r10 1276 -#define _POP_JUMP_IF_TRUE_r21 1277 -#define _POP_JUMP_IF_TRUE_r32 1278 -#define _POP_TOP_r10 1279 -#define _POP_TOP_FLOAT_r00 1280 -#define _POP_TOP_FLOAT_r10 1281 -#define _POP_TOP_FLOAT_r21 1282 -#define _POP_TOP_FLOAT_r32 1283 -#define _POP_TOP_INT_r00 1284 -#define _POP_TOP_INT_r10 1285 -#define _POP_TOP_INT_r21 1286 -#define _POP_TOP_INT_r32 1287 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1288 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1289 -#define _POP_TOP_NOP_r00 1290 -#define _POP_TOP_NOP_r10 1291 -#define _POP_TOP_NOP_r21 1292 -#define _POP_TOP_NOP_r32 1293 -#define _POP_TOP_UNICODE_r00 1294 -#define _POP_TOP_UNICODE_r10 1295 -#define _POP_TOP_UNICODE_r21 1296 -#define _POP_TOP_UNICODE_r32 1297 -#define _POP_TWO_r20 1298 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1299 -#define _PUSH_EXC_INFO_r02 1300 -#define _PUSH_EXC_INFO_r12 1301 -#define _PUSH_EXC_INFO_r23 1302 -#define _PUSH_FRAME_r10 1303 -#define _PUSH_NULL_r01 1304 -#define _PUSH_NULL_r12 1305 -#define _PUSH_NULL_r23 1306 -#define _PUSH_NULL_CONDITIONAL_r00 1307 -#define _PY_FRAME_EX_r31 1308 -#define _PY_FRAME_GENERAL_r01 1309 -#define _PY_FRAME_KW_r11 1310 -#define _QUICKEN_RESUME_r00 1311 -#define _QUICKEN_RESUME_r11 1312 -#define _QUICKEN_RESUME_r22 1313 -#define _QUICKEN_RESUME_r33 1314 -#define _REPLACE_WITH_TRUE_r02 1315 -#define _REPLACE_WITH_TRUE_r12 1316 -#define _REPLACE_WITH_TRUE_r23 1317 -#define _RESUME_CHECK_r00 1318 -#define _RESUME_CHECK_r11 1319 -#define _RESUME_CHECK_r22 1320 -#define _RESUME_CHECK_r33 1321 -#define _RETURN_GENERATOR_r01 1322 -#define _RETURN_VALUE_r11 1323 -#define _SAVE_RETURN_OFFSET_r00 1324 -#define _SAVE_RETURN_OFFSET_r11 1325 -#define _SAVE_RETURN_OFFSET_r22 1326 -#define _SAVE_RETURN_OFFSET_r33 1327 -#define _SEND_r22 1328 -#define _SEND_GEN_FRAME_r22 1329 -#define _SETUP_ANNOTATIONS_r00 1330 -#define _SET_ADD_r10 1331 -#define _SET_FUNCTION_ATTRIBUTE_r01 1332 -#define _SET_FUNCTION_ATTRIBUTE_r11 1333 -#define _SET_FUNCTION_ATTRIBUTE_r21 1334 -#define _SET_FUNCTION_ATTRIBUTE_r32 1335 -#define _SET_IP_r00 1336 -#define _SET_IP_r11 1337 -#define _SET_IP_r22 1338 -#define _SET_IP_r33 1339 -#define _SET_UPDATE_r10 1340 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1341 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1342 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1343 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1344 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1345 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1346 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1347 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1348 -#define _SPILL_OR_RELOAD_r01 1349 -#define _SPILL_OR_RELOAD_r02 1350 -#define _SPILL_OR_RELOAD_r03 1351 -#define _SPILL_OR_RELOAD_r10 1352 -#define _SPILL_OR_RELOAD_r12 1353 -#define _SPILL_OR_RELOAD_r13 1354 -#define _SPILL_OR_RELOAD_r20 1355 -#define _SPILL_OR_RELOAD_r21 1356 -#define _SPILL_OR_RELOAD_r23 1357 -#define _SPILL_OR_RELOAD_r30 1358 -#define _SPILL_OR_RELOAD_r31 1359 -#define _SPILL_OR_RELOAD_r32 1360 -#define _START_EXECUTOR_r00 1361 -#define _STORE_ATTR_r20 1362 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1363 -#define _STORE_ATTR_SLOT_r21 1364 -#define _STORE_ATTR_WITH_HINT_r21 1365 -#define _STORE_DEREF_r10 1366 -#define _STORE_FAST_LOAD_FAST_r11 1367 -#define _STORE_FAST_STORE_FAST_r20 1368 -#define _STORE_GLOBAL_r10 1369 -#define _STORE_NAME_r10 1370 -#define _STORE_SLICE_r30 1371 -#define _STORE_SUBSCR_r30 1372 -#define _STORE_SUBSCR_DICT_r31 1373 -#define _STORE_SUBSCR_LIST_INT_r32 1374 -#define _SWAP_r11 1375 -#define _SWAP_2_r02 1376 -#define _SWAP_2_r12 1377 -#define _SWAP_2_r22 1378 -#define _SWAP_2_r33 1379 -#define _SWAP_3_r03 1380 -#define _SWAP_3_r13 1381 -#define _SWAP_3_r23 1382 -#define _SWAP_3_r33 1383 -#define _SWAP_FAST_r01 1384 -#define _SWAP_FAST_r11 1385 -#define _SWAP_FAST_r22 1386 -#define _SWAP_FAST_r33 1387 -#define _SWAP_FAST_0_r01 1388 -#define _SWAP_FAST_0_r11 1389 -#define _SWAP_FAST_0_r22 1390 -#define _SWAP_FAST_0_r33 1391 -#define _SWAP_FAST_1_r01 1392 -#define _SWAP_FAST_1_r11 1393 -#define _SWAP_FAST_1_r22 1394 -#define _SWAP_FAST_1_r33 1395 -#define _SWAP_FAST_2_r01 1396 -#define _SWAP_FAST_2_r11 1397 -#define _SWAP_FAST_2_r22 1398 -#define _SWAP_FAST_2_r33 1399 -#define _SWAP_FAST_3_r01 1400 -#define _SWAP_FAST_3_r11 1401 -#define _SWAP_FAST_3_r22 1402 -#define _SWAP_FAST_3_r33 1403 -#define _SWAP_FAST_4_r01 1404 -#define _SWAP_FAST_4_r11 1405 -#define _SWAP_FAST_4_r22 1406 -#define _SWAP_FAST_4_r33 1407 -#define _SWAP_FAST_5_r01 1408 -#define _SWAP_FAST_5_r11 1409 -#define _SWAP_FAST_5_r22 1410 -#define _SWAP_FAST_5_r33 1411 -#define _SWAP_FAST_6_r01 1412 -#define _SWAP_FAST_6_r11 1413 -#define _SWAP_FAST_6_r22 1414 -#define _SWAP_FAST_6_r33 1415 -#define _SWAP_FAST_7_r01 1416 -#define _SWAP_FAST_7_r11 1417 -#define _SWAP_FAST_7_r22 1418 -#define _SWAP_FAST_7_r33 1419 -#define _TIER2_RESUME_CHECK_r00 1420 -#define _TIER2_RESUME_CHECK_r11 1421 -#define _TIER2_RESUME_CHECK_r22 1422 -#define _TIER2_RESUME_CHECK_r33 1423 -#define _TO_BOOL_r11 1424 -#define _TO_BOOL_BOOL_r01 1425 -#define _TO_BOOL_BOOL_r11 1426 -#define _TO_BOOL_BOOL_r22 1427 -#define _TO_BOOL_BOOL_r33 1428 -#define _TO_BOOL_INT_r02 1429 -#define _TO_BOOL_INT_r12 1430 -#define _TO_BOOL_INT_r23 1431 -#define _TO_BOOL_LIST_r02 1432 -#define _TO_BOOL_LIST_r12 1433 -#define _TO_BOOL_LIST_r23 1434 -#define _TO_BOOL_NONE_r01 1435 -#define _TO_BOOL_NONE_r11 1436 -#define _TO_BOOL_NONE_r22 1437 -#define _TO_BOOL_NONE_r33 1438 -#define _TO_BOOL_STR_r02 1439 -#define _TO_BOOL_STR_r12 1440 -#define _TO_BOOL_STR_r23 1441 -#define _TRACE_RECORD_r00 1442 -#define _UNARY_INVERT_r12 1443 -#define _UNARY_NEGATIVE_r12 1444 -#define _UNARY_NOT_r01 1445 -#define _UNARY_NOT_r11 1446 -#define _UNARY_NOT_r22 1447 -#define _UNARY_NOT_r33 1448 -#define _UNPACK_EX_r10 1449 -#define _UNPACK_SEQUENCE_r10 1450 -#define _UNPACK_SEQUENCE_LIST_r10 1451 -#define _UNPACK_SEQUENCE_TUPLE_r10 1452 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1453 -#define _WITH_EXCEPT_START_r33 1454 -#define _YIELD_VALUE_r11 1455 -#define MAX_UOP_REGS_ID 1455 +#define MAX_UOP_ID 593 +#define _BINARY_OP_r23 594 +#define _BINARY_OP_ADD_FLOAT_r03 595 +#define _BINARY_OP_ADD_FLOAT_r13 596 +#define _BINARY_OP_ADD_FLOAT_r23 597 +#define _BINARY_OP_ADD_INT_r03 598 +#define _BINARY_OP_ADD_INT_r13 599 +#define _BINARY_OP_ADD_INT_r23 600 +#define _BINARY_OP_ADD_UNICODE_r03 601 +#define _BINARY_OP_ADD_UNICODE_r13 602 +#define _BINARY_OP_ADD_UNICODE_r23 603 +#define _BINARY_OP_EXTEND_r23 604 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 605 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 606 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 607 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 608 +#define _BINARY_OP_MULTIPLY_INT_r03 609 +#define _BINARY_OP_MULTIPLY_INT_r13 610 +#define _BINARY_OP_MULTIPLY_INT_r23 611 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 612 +#define _BINARY_OP_SUBSCR_DICT_r23 613 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 614 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 615 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 616 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 617 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 618 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 619 +#define _BINARY_OP_SUBSCR_STR_INT_r23 620 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 621 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 622 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 623 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 624 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 625 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 626 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 627 +#define _BINARY_OP_SUBTRACT_INT_r03 628 +#define _BINARY_OP_SUBTRACT_INT_r13 629 +#define _BINARY_OP_SUBTRACT_INT_r23 630 +#define _BINARY_SLICE_r31 631 +#define _BUILD_INTERPOLATION_r01 632 +#define _BUILD_LIST_r01 633 +#define _BUILD_MAP_r01 634 +#define _BUILD_SET_r01 635 +#define _BUILD_SLICE_r01 636 +#define _BUILD_STRING_r01 637 +#define _BUILD_TEMPLATE_r21 638 +#define _BUILD_TUPLE_r01 639 +#define _CALL_BUILTIN_CLASS_r01 640 +#define _CALL_BUILTIN_FAST_r01 641 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 642 +#define _CALL_BUILTIN_O_r03 643 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 644 +#define _CALL_INTRINSIC_1_r11 645 +#define _CALL_INTRINSIC_2_r21 646 +#define _CALL_ISINSTANCE_r31 647 +#define _CALL_KW_NON_PY_r11 648 +#define _CALL_LEN_r33 649 +#define _CALL_LIST_APPEND_r03 650 +#define _CALL_LIST_APPEND_r13 651 +#define _CALL_LIST_APPEND_r23 652 +#define _CALL_LIST_APPEND_r33 653 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 654 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 655 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 656 +#define _CALL_METHOD_DESCRIPTOR_O_r03 657 +#define _CALL_NON_PY_GENERAL_r01 658 +#define _CALL_STR_1_r32 659 +#define _CALL_TUPLE_1_r32 660 +#define _CALL_TYPE_1_r02 661 +#define _CALL_TYPE_1_r12 662 +#define _CALL_TYPE_1_r22 663 +#define _CALL_TYPE_1_r32 664 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 665 +#define _CHECK_ATTR_CLASS_r01 666 +#define _CHECK_ATTR_CLASS_r11 667 +#define _CHECK_ATTR_CLASS_r22 668 +#define _CHECK_ATTR_CLASS_r33 669 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 670 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 671 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 672 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 673 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 674 +#define _CHECK_EG_MATCH_r22 675 +#define _CHECK_EXC_MATCH_r22 676 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 677 +#define _CHECK_FUNCTION_VERSION_r00 678 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 679 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 680 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 681 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 682 +#define _CHECK_FUNCTION_VERSION_KW_r11 683 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 684 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 685 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 686 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 687 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 688 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 689 +#define _CHECK_IS_PY_CALLABLE_EX_r03 690 +#define _CHECK_IS_PY_CALLABLE_EX_r13 691 +#define _CHECK_IS_PY_CALLABLE_EX_r23 692 +#define _CHECK_IS_PY_CALLABLE_EX_r33 693 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 694 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 695 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 696 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 697 +#define _CHECK_METHOD_VERSION_r00 698 +#define _CHECK_METHOD_VERSION_KW_r11 699 +#define _CHECK_PEP_523_r00 700 +#define _CHECK_PEP_523_r11 701 +#define _CHECK_PEP_523_r22 702 +#define _CHECK_PEP_523_r33 703 +#define _CHECK_PERIODIC_r00 704 +#define _CHECK_PERIODIC_AT_END_r00 705 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 706 +#define _CHECK_RECURSION_REMAINING_r00 707 +#define _CHECK_RECURSION_REMAINING_r11 708 +#define _CHECK_RECURSION_REMAINING_r22 709 +#define _CHECK_RECURSION_REMAINING_r33 710 +#define _CHECK_STACK_SPACE_r00 711 +#define _CHECK_STACK_SPACE_OPERAND_r00 712 +#define _CHECK_STACK_SPACE_OPERAND_r11 713 +#define _CHECK_STACK_SPACE_OPERAND_r22 714 +#define _CHECK_STACK_SPACE_OPERAND_r33 715 +#define _CHECK_VALIDITY_r00 716 +#define _CHECK_VALIDITY_r11 717 +#define _CHECK_VALIDITY_r22 718 +#define _CHECK_VALIDITY_r33 719 +#define _COLD_DYNAMIC_EXIT_r00 720 +#define _COLD_EXIT_r00 721 +#define _COMPARE_OP_r21 722 +#define _COMPARE_OP_FLOAT_r03 723 +#define _COMPARE_OP_FLOAT_r13 724 +#define _COMPARE_OP_FLOAT_r23 725 +#define _COMPARE_OP_INT_r23 726 +#define _COMPARE_OP_STR_r23 727 +#define _CONTAINS_OP_r23 728 +#define _CONTAINS_OP_DICT_r23 729 +#define _CONTAINS_OP_SET_r23 730 +#define _CONVERT_VALUE_r11 731 +#define _COPY_r01 732 +#define _COPY_1_r02 733 +#define _COPY_1_r12 734 +#define _COPY_1_r23 735 +#define _COPY_2_r03 736 +#define _COPY_2_r13 737 +#define _COPY_2_r23 738 +#define _COPY_3_r03 739 +#define _COPY_3_r13 740 +#define _COPY_3_r23 741 +#define _COPY_3_r33 742 +#define _COPY_FREE_VARS_r00 743 +#define _COPY_FREE_VARS_r11 744 +#define _COPY_FREE_VARS_r22 745 +#define _COPY_FREE_VARS_r33 746 +#define _CREATE_INIT_FRAME_r01 747 +#define _DELETE_ATTR_r10 748 +#define _DELETE_DEREF_r00 749 +#define _DELETE_FAST_r00 750 +#define _DELETE_GLOBAL_r00 751 +#define _DELETE_NAME_r00 752 +#define _DELETE_SUBSCR_r20 753 +#define _DEOPT_r00 754 +#define _DEOPT_r10 755 +#define _DEOPT_r20 756 +#define _DEOPT_r30 757 +#define _DICT_MERGE_r10 758 +#define _DICT_UPDATE_r10 759 +#define _DO_CALL_r01 760 +#define _DO_CALL_FUNCTION_EX_r31 761 +#define _DO_CALL_KW_r11 762 +#define _DYNAMIC_EXIT_r00 763 +#define _DYNAMIC_EXIT_r10 764 +#define _DYNAMIC_EXIT_r20 765 +#define _DYNAMIC_EXIT_r30 766 +#define _END_FOR_r10 767 +#define _END_SEND_r21 768 +#define _ERROR_POP_N_r00 769 +#define _EXIT_INIT_CHECK_r10 770 +#define _EXIT_TRACE_r00 771 +#define _EXIT_TRACE_r10 772 +#define _EXIT_TRACE_r20 773 +#define _EXIT_TRACE_r30 774 +#define _EXPAND_METHOD_r00 775 +#define _EXPAND_METHOD_KW_r11 776 +#define _FATAL_ERROR_r00 777 +#define _FATAL_ERROR_r11 778 +#define _FATAL_ERROR_r22 779 +#define _FATAL_ERROR_r33 780 +#define _FORMAT_SIMPLE_r11 781 +#define _FORMAT_WITH_SPEC_r21 782 +#define _FOR_ITER_r23 783 +#define _FOR_ITER_GEN_FRAME_r03 784 +#define _FOR_ITER_GEN_FRAME_r13 785 +#define _FOR_ITER_GEN_FRAME_r23 786 +#define _FOR_ITER_TIER_TWO_r23 787 +#define _GET_AITER_r11 788 +#define _GET_ANEXT_r12 789 +#define _GET_AWAITABLE_r11 790 +#define _GET_ITER_r12 791 +#define _GET_LEN_r12 792 +#define _GET_YIELD_FROM_ITER_r11 793 +#define _GUARD_BINARY_OP_EXTEND_r22 794 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 795 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 796 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 797 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 798 +#define _GUARD_BIT_IS_SET_POP_r00 799 +#define _GUARD_BIT_IS_SET_POP_r10 800 +#define _GUARD_BIT_IS_SET_POP_r21 801 +#define _GUARD_BIT_IS_SET_POP_r32 802 +#define _GUARD_BIT_IS_SET_POP_4_r00 803 +#define _GUARD_BIT_IS_SET_POP_4_r10 804 +#define _GUARD_BIT_IS_SET_POP_4_r21 805 +#define _GUARD_BIT_IS_SET_POP_4_r32 806 +#define _GUARD_BIT_IS_SET_POP_5_r00 807 +#define _GUARD_BIT_IS_SET_POP_5_r10 808 +#define _GUARD_BIT_IS_SET_POP_5_r21 809 +#define _GUARD_BIT_IS_SET_POP_5_r32 810 +#define _GUARD_BIT_IS_SET_POP_6_r00 811 +#define _GUARD_BIT_IS_SET_POP_6_r10 812 +#define _GUARD_BIT_IS_SET_POP_6_r21 813 +#define _GUARD_BIT_IS_SET_POP_6_r32 814 +#define _GUARD_BIT_IS_SET_POP_7_r00 815 +#define _GUARD_BIT_IS_SET_POP_7_r10 816 +#define _GUARD_BIT_IS_SET_POP_7_r21 817 +#define _GUARD_BIT_IS_SET_POP_7_r32 818 +#define _GUARD_BIT_IS_UNSET_POP_r00 819 +#define _GUARD_BIT_IS_UNSET_POP_r10 820 +#define _GUARD_BIT_IS_UNSET_POP_r21 821 +#define _GUARD_BIT_IS_UNSET_POP_r32 822 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 823 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 824 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 825 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 826 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 827 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 828 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 829 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 830 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 831 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 832 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 833 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 834 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 835 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 836 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 837 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 838 +#define _GUARD_CALLABLE_ISINSTANCE_r03 839 +#define _GUARD_CALLABLE_ISINSTANCE_r13 840 +#define _GUARD_CALLABLE_ISINSTANCE_r23 841 +#define _GUARD_CALLABLE_ISINSTANCE_r33 842 +#define _GUARD_CALLABLE_LEN_r03 843 +#define _GUARD_CALLABLE_LEN_r13 844 +#define _GUARD_CALLABLE_LEN_r23 845 +#define _GUARD_CALLABLE_LEN_r33 846 +#define _GUARD_CALLABLE_LIST_APPEND_r03 847 +#define _GUARD_CALLABLE_LIST_APPEND_r13 848 +#define _GUARD_CALLABLE_LIST_APPEND_r23 849 +#define _GUARD_CALLABLE_LIST_APPEND_r33 850 +#define _GUARD_CALLABLE_STR_1_r03 851 +#define _GUARD_CALLABLE_STR_1_r13 852 +#define _GUARD_CALLABLE_STR_1_r23 853 +#define _GUARD_CALLABLE_STR_1_r33 854 +#define _GUARD_CALLABLE_TUPLE_1_r03 855 +#define _GUARD_CALLABLE_TUPLE_1_r13 856 +#define _GUARD_CALLABLE_TUPLE_1_r23 857 +#define _GUARD_CALLABLE_TUPLE_1_r33 858 +#define _GUARD_CALLABLE_TYPE_1_r03 859 +#define _GUARD_CALLABLE_TYPE_1_r13 860 +#define _GUARD_CALLABLE_TYPE_1_r23 861 +#define _GUARD_CALLABLE_TYPE_1_r33 862 +#define _GUARD_CODE_VERSION_r00 863 +#define _GUARD_CODE_VERSION_r11 864 +#define _GUARD_CODE_VERSION_r22 865 +#define _GUARD_CODE_VERSION_r33 866 +#define _GUARD_DORV_NO_DICT_r01 867 +#define _GUARD_DORV_NO_DICT_r11 868 +#define _GUARD_DORV_NO_DICT_r22 869 +#define _GUARD_DORV_NO_DICT_r33 870 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 871 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 872 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 873 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 874 +#define _GUARD_GLOBALS_VERSION_r00 875 +#define _GUARD_GLOBALS_VERSION_r11 876 +#define _GUARD_GLOBALS_VERSION_r22 877 +#define _GUARD_GLOBALS_VERSION_r33 878 +#define _GUARD_IP_RETURN_GENERATOR_r00 879 +#define _GUARD_IP_RETURN_GENERATOR_r11 880 +#define _GUARD_IP_RETURN_GENERATOR_r22 881 +#define _GUARD_IP_RETURN_GENERATOR_r33 882 +#define _GUARD_IP_RETURN_VALUE_r00 883 +#define _GUARD_IP_RETURN_VALUE_r11 884 +#define _GUARD_IP_RETURN_VALUE_r22 885 +#define _GUARD_IP_RETURN_VALUE_r33 886 +#define _GUARD_IP_YIELD_VALUE_r00 887 +#define _GUARD_IP_YIELD_VALUE_r11 888 +#define _GUARD_IP_YIELD_VALUE_r22 889 +#define _GUARD_IP_YIELD_VALUE_r33 890 +#define _GUARD_IP__PUSH_FRAME_r00 891 +#define _GUARD_IP__PUSH_FRAME_r11 892 +#define _GUARD_IP__PUSH_FRAME_r22 893 +#define _GUARD_IP__PUSH_FRAME_r33 894 +#define _GUARD_IS_FALSE_POP_r00 895 +#define _GUARD_IS_FALSE_POP_r10 896 +#define _GUARD_IS_FALSE_POP_r21 897 +#define _GUARD_IS_FALSE_POP_r32 898 +#define _GUARD_IS_NONE_POP_r00 899 +#define _GUARD_IS_NONE_POP_r10 900 +#define _GUARD_IS_NONE_POP_r21 901 +#define _GUARD_IS_NONE_POP_r32 902 +#define _GUARD_IS_NOT_NONE_POP_r10 903 +#define _GUARD_IS_TRUE_POP_r00 904 +#define _GUARD_IS_TRUE_POP_r10 905 +#define _GUARD_IS_TRUE_POP_r21 906 +#define _GUARD_IS_TRUE_POP_r32 907 +#define _GUARD_KEYS_VERSION_r01 908 +#define _GUARD_KEYS_VERSION_r11 909 +#define _GUARD_KEYS_VERSION_r22 910 +#define _GUARD_KEYS_VERSION_r33 911 +#define _GUARD_NOS_ANY_DICT_r02 912 +#define _GUARD_NOS_ANY_DICT_r12 913 +#define _GUARD_NOS_ANY_DICT_r22 914 +#define _GUARD_NOS_ANY_DICT_r33 915 +#define _GUARD_NOS_COMPACT_ASCII_r02 916 +#define _GUARD_NOS_COMPACT_ASCII_r12 917 +#define _GUARD_NOS_COMPACT_ASCII_r22 918 +#define _GUARD_NOS_COMPACT_ASCII_r33 919 +#define _GUARD_NOS_DICT_r02 920 +#define _GUARD_NOS_DICT_r12 921 +#define _GUARD_NOS_DICT_r22 922 +#define _GUARD_NOS_DICT_r33 923 +#define _GUARD_NOS_FLOAT_r02 924 +#define _GUARD_NOS_FLOAT_r12 925 +#define _GUARD_NOS_FLOAT_r22 926 +#define _GUARD_NOS_FLOAT_r33 927 +#define _GUARD_NOS_INT_r02 928 +#define _GUARD_NOS_INT_r12 929 +#define _GUARD_NOS_INT_r22 930 +#define _GUARD_NOS_INT_r33 931 +#define _GUARD_NOS_LIST_r02 932 +#define _GUARD_NOS_LIST_r12 933 +#define _GUARD_NOS_LIST_r22 934 +#define _GUARD_NOS_LIST_r33 935 +#define _GUARD_NOS_NOT_NULL_r02 936 +#define _GUARD_NOS_NOT_NULL_r12 937 +#define _GUARD_NOS_NOT_NULL_r22 938 +#define _GUARD_NOS_NOT_NULL_r33 939 +#define _GUARD_NOS_NULL_r02 940 +#define _GUARD_NOS_NULL_r12 941 +#define _GUARD_NOS_NULL_r22 942 +#define _GUARD_NOS_NULL_r33 943 +#define _GUARD_NOS_OVERFLOWED_r02 944 +#define _GUARD_NOS_OVERFLOWED_r12 945 +#define _GUARD_NOS_OVERFLOWED_r22 946 +#define _GUARD_NOS_OVERFLOWED_r33 947 +#define _GUARD_NOS_TUPLE_r02 948 +#define _GUARD_NOS_TUPLE_r12 949 +#define _GUARD_NOS_TUPLE_r22 950 +#define _GUARD_NOS_TUPLE_r33 951 +#define _GUARD_NOS_UNICODE_r02 952 +#define _GUARD_NOS_UNICODE_r12 953 +#define _GUARD_NOS_UNICODE_r22 954 +#define _GUARD_NOS_UNICODE_r33 955 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 956 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 957 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 958 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 959 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 960 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 961 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 962 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 963 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 964 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 965 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 966 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 967 +#define _GUARD_THIRD_NULL_r03 968 +#define _GUARD_THIRD_NULL_r13 969 +#define _GUARD_THIRD_NULL_r23 970 +#define _GUARD_THIRD_NULL_r33 971 +#define _GUARD_TOS_ANY_DICT_r01 972 +#define _GUARD_TOS_ANY_DICT_r11 973 +#define _GUARD_TOS_ANY_DICT_r22 974 +#define _GUARD_TOS_ANY_DICT_r33 975 +#define _GUARD_TOS_ANY_SET_r01 976 +#define _GUARD_TOS_ANY_SET_r11 977 +#define _GUARD_TOS_ANY_SET_r22 978 +#define _GUARD_TOS_ANY_SET_r33 979 +#define _GUARD_TOS_DICT_r01 980 +#define _GUARD_TOS_DICT_r11 981 +#define _GUARD_TOS_DICT_r22 982 +#define _GUARD_TOS_DICT_r33 983 +#define _GUARD_TOS_FLOAT_r01 984 +#define _GUARD_TOS_FLOAT_r11 985 +#define _GUARD_TOS_FLOAT_r22 986 +#define _GUARD_TOS_FLOAT_r33 987 +#define _GUARD_TOS_FROZENDICT_r01 988 +#define _GUARD_TOS_FROZENDICT_r11 989 +#define _GUARD_TOS_FROZENDICT_r22 990 +#define _GUARD_TOS_FROZENDICT_r33 991 +#define _GUARD_TOS_FROZENSET_r01 992 +#define _GUARD_TOS_FROZENSET_r11 993 +#define _GUARD_TOS_FROZENSET_r22 994 +#define _GUARD_TOS_FROZENSET_r33 995 +#define _GUARD_TOS_INT_r01 996 +#define _GUARD_TOS_INT_r11 997 +#define _GUARD_TOS_INT_r22 998 +#define _GUARD_TOS_INT_r33 999 +#define _GUARD_TOS_LIST_r01 1000 +#define _GUARD_TOS_LIST_r11 1001 +#define _GUARD_TOS_LIST_r22 1002 +#define _GUARD_TOS_LIST_r33 1003 +#define _GUARD_TOS_OVERFLOWED_r01 1004 +#define _GUARD_TOS_OVERFLOWED_r11 1005 +#define _GUARD_TOS_OVERFLOWED_r22 1006 +#define _GUARD_TOS_OVERFLOWED_r33 1007 +#define _GUARD_TOS_SET_r01 1008 +#define _GUARD_TOS_SET_r11 1009 +#define _GUARD_TOS_SET_r22 1010 +#define _GUARD_TOS_SET_r33 1011 +#define _GUARD_TOS_SLICE_r01 1012 +#define _GUARD_TOS_SLICE_r11 1013 +#define _GUARD_TOS_SLICE_r22 1014 +#define _GUARD_TOS_SLICE_r33 1015 +#define _GUARD_TOS_TUPLE_r01 1016 +#define _GUARD_TOS_TUPLE_r11 1017 +#define _GUARD_TOS_TUPLE_r22 1018 +#define _GUARD_TOS_TUPLE_r33 1019 +#define _GUARD_TOS_UNICODE_r01 1020 +#define _GUARD_TOS_UNICODE_r11 1021 +#define _GUARD_TOS_UNICODE_r22 1022 +#define _GUARD_TOS_UNICODE_r33 1023 +#define _GUARD_TYPE_VERSION_r01 1024 +#define _GUARD_TYPE_VERSION_r11 1025 +#define _GUARD_TYPE_VERSION_r22 1026 +#define _GUARD_TYPE_VERSION_r33 1027 +#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1028 +#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1029 +#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1030 +#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1031 +#define _HANDLE_PENDING_AND_DEOPT_r00 1032 +#define _HANDLE_PENDING_AND_DEOPT_r10 1033 +#define _HANDLE_PENDING_AND_DEOPT_r20 1034 +#define _HANDLE_PENDING_AND_DEOPT_r30 1035 +#define _IMPORT_FROM_r12 1036 +#define _IMPORT_NAME_r21 1037 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1038 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1039 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1040 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1041 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1042 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1043 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1044 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1045 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1046 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1047 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1048 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1049 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1050 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1051 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1052 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1053 +#define _INSERT_NULL_r10 1054 +#define _INSTRUMENTED_FOR_ITER_r23 1055 +#define _INSTRUMENTED_INSTRUCTION_r00 1056 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1057 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1058 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1059 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1060 +#define _INSTRUMENTED_LINE_r00 1061 +#define _INSTRUMENTED_NOT_TAKEN_r00 1062 +#define _INSTRUMENTED_NOT_TAKEN_r11 1063 +#define _INSTRUMENTED_NOT_TAKEN_r22 1064 +#define _INSTRUMENTED_NOT_TAKEN_r33 1065 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1066 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1067 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1068 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1069 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1070 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1071 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1072 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1073 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1074 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1075 +#define _IS_NONE_r11 1076 +#define _IS_OP_r03 1077 +#define _IS_OP_r13 1078 +#define _IS_OP_r23 1079 +#define _ITER_CHECK_LIST_r02 1080 +#define _ITER_CHECK_LIST_r12 1081 +#define _ITER_CHECK_LIST_r22 1082 +#define _ITER_CHECK_LIST_r33 1083 +#define _ITER_CHECK_RANGE_r02 1084 +#define _ITER_CHECK_RANGE_r12 1085 +#define _ITER_CHECK_RANGE_r22 1086 +#define _ITER_CHECK_RANGE_r33 1087 +#define _ITER_CHECK_TUPLE_r02 1088 +#define _ITER_CHECK_TUPLE_r12 1089 +#define _ITER_CHECK_TUPLE_r22 1090 +#define _ITER_CHECK_TUPLE_r33 1091 +#define _ITER_JUMP_LIST_r02 1092 +#define _ITER_JUMP_LIST_r12 1093 +#define _ITER_JUMP_LIST_r22 1094 +#define _ITER_JUMP_LIST_r33 1095 +#define _ITER_JUMP_RANGE_r02 1096 +#define _ITER_JUMP_RANGE_r12 1097 +#define _ITER_JUMP_RANGE_r22 1098 +#define _ITER_JUMP_RANGE_r33 1099 +#define _ITER_JUMP_TUPLE_r02 1100 +#define _ITER_JUMP_TUPLE_r12 1101 +#define _ITER_JUMP_TUPLE_r22 1102 +#define _ITER_JUMP_TUPLE_r33 1103 +#define _ITER_NEXT_LIST_r23 1104 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1105 +#define _ITER_NEXT_RANGE_r03 1106 +#define _ITER_NEXT_RANGE_r13 1107 +#define _ITER_NEXT_RANGE_r23 1108 +#define _ITER_NEXT_TUPLE_r03 1109 +#define _ITER_NEXT_TUPLE_r13 1110 +#define _ITER_NEXT_TUPLE_r23 1111 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1112 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1113 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1114 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1115 +#define _JUMP_TO_TOP_r00 1116 +#define _LIST_APPEND_r10 1117 +#define _LIST_EXTEND_r10 1118 +#define _LOAD_ATTR_r10 1119 +#define _LOAD_ATTR_CLASS_r11 1120 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1121 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1122 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1123 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1124 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1125 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1126 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1127 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1128 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1129 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1130 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1131 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1132 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1133 +#define _LOAD_ATTR_MODULE_r12 1134 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1135 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1136 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1137 +#define _LOAD_ATTR_SLOT_r02 1138 +#define _LOAD_ATTR_SLOT_r12 1139 +#define _LOAD_ATTR_SLOT_r23 1140 +#define _LOAD_ATTR_WITH_HINT_r12 1141 +#define _LOAD_BUILD_CLASS_r01 1142 +#define _LOAD_BYTECODE_r00 1143 +#define _LOAD_COMMON_CONSTANT_r01 1144 +#define _LOAD_COMMON_CONSTANT_r12 1145 +#define _LOAD_COMMON_CONSTANT_r23 1146 +#define _LOAD_CONST_r01 1147 +#define _LOAD_CONST_r12 1148 +#define _LOAD_CONST_r23 1149 +#define _LOAD_CONST_INLINE_r01 1150 +#define _LOAD_CONST_INLINE_r12 1151 +#define _LOAD_CONST_INLINE_r23 1152 +#define _LOAD_CONST_INLINE_BORROW_r01 1153 +#define _LOAD_CONST_INLINE_BORROW_r12 1154 +#define _LOAD_CONST_INLINE_BORROW_r23 1155 +#define _LOAD_CONST_UNDER_INLINE_r02 1156 +#define _LOAD_CONST_UNDER_INLINE_r12 1157 +#define _LOAD_CONST_UNDER_INLINE_r23 1158 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1159 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1160 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1161 +#define _LOAD_DEREF_r01 1162 +#define _LOAD_FAST_r01 1163 +#define _LOAD_FAST_r12 1164 +#define _LOAD_FAST_r23 1165 +#define _LOAD_FAST_0_r01 1166 +#define _LOAD_FAST_0_r12 1167 +#define _LOAD_FAST_0_r23 1168 +#define _LOAD_FAST_1_r01 1169 +#define _LOAD_FAST_1_r12 1170 +#define _LOAD_FAST_1_r23 1171 +#define _LOAD_FAST_2_r01 1172 +#define _LOAD_FAST_2_r12 1173 +#define _LOAD_FAST_2_r23 1174 +#define _LOAD_FAST_3_r01 1175 +#define _LOAD_FAST_3_r12 1176 +#define _LOAD_FAST_3_r23 1177 +#define _LOAD_FAST_4_r01 1178 +#define _LOAD_FAST_4_r12 1179 +#define _LOAD_FAST_4_r23 1180 +#define _LOAD_FAST_5_r01 1181 +#define _LOAD_FAST_5_r12 1182 +#define _LOAD_FAST_5_r23 1183 +#define _LOAD_FAST_6_r01 1184 +#define _LOAD_FAST_6_r12 1185 +#define _LOAD_FAST_6_r23 1186 +#define _LOAD_FAST_7_r01 1187 +#define _LOAD_FAST_7_r12 1188 +#define _LOAD_FAST_7_r23 1189 +#define _LOAD_FAST_AND_CLEAR_r01 1190 +#define _LOAD_FAST_AND_CLEAR_r12 1191 +#define _LOAD_FAST_AND_CLEAR_r23 1192 +#define _LOAD_FAST_BORROW_r01 1193 +#define _LOAD_FAST_BORROW_r12 1194 +#define _LOAD_FAST_BORROW_r23 1195 +#define _LOAD_FAST_BORROW_0_r01 1196 +#define _LOAD_FAST_BORROW_0_r12 1197 +#define _LOAD_FAST_BORROW_0_r23 1198 +#define _LOAD_FAST_BORROW_1_r01 1199 +#define _LOAD_FAST_BORROW_1_r12 1200 +#define _LOAD_FAST_BORROW_1_r23 1201 +#define _LOAD_FAST_BORROW_2_r01 1202 +#define _LOAD_FAST_BORROW_2_r12 1203 +#define _LOAD_FAST_BORROW_2_r23 1204 +#define _LOAD_FAST_BORROW_3_r01 1205 +#define _LOAD_FAST_BORROW_3_r12 1206 +#define _LOAD_FAST_BORROW_3_r23 1207 +#define _LOAD_FAST_BORROW_4_r01 1208 +#define _LOAD_FAST_BORROW_4_r12 1209 +#define _LOAD_FAST_BORROW_4_r23 1210 +#define _LOAD_FAST_BORROW_5_r01 1211 +#define _LOAD_FAST_BORROW_5_r12 1212 +#define _LOAD_FAST_BORROW_5_r23 1213 +#define _LOAD_FAST_BORROW_6_r01 1214 +#define _LOAD_FAST_BORROW_6_r12 1215 +#define _LOAD_FAST_BORROW_6_r23 1216 +#define _LOAD_FAST_BORROW_7_r01 1217 +#define _LOAD_FAST_BORROW_7_r12 1218 +#define _LOAD_FAST_BORROW_7_r23 1219 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1220 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1221 +#define _LOAD_FAST_CHECK_r01 1222 +#define _LOAD_FAST_CHECK_r12 1223 +#define _LOAD_FAST_CHECK_r23 1224 +#define _LOAD_FAST_LOAD_FAST_r02 1225 +#define _LOAD_FAST_LOAD_FAST_r13 1226 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1227 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1228 +#define _LOAD_GLOBAL_r00 1229 +#define _LOAD_GLOBAL_BUILTINS_r01 1230 +#define _LOAD_GLOBAL_MODULE_r01 1231 +#define _LOAD_LOCALS_r01 1232 +#define _LOAD_LOCALS_r12 1233 +#define _LOAD_LOCALS_r23 1234 +#define _LOAD_NAME_r01 1235 +#define _LOAD_SMALL_INT_r01 1236 +#define _LOAD_SMALL_INT_r12 1237 +#define _LOAD_SMALL_INT_r23 1238 +#define _LOAD_SMALL_INT_0_r01 1239 +#define _LOAD_SMALL_INT_0_r12 1240 +#define _LOAD_SMALL_INT_0_r23 1241 +#define _LOAD_SMALL_INT_1_r01 1242 +#define _LOAD_SMALL_INT_1_r12 1243 +#define _LOAD_SMALL_INT_1_r23 1244 +#define _LOAD_SMALL_INT_2_r01 1245 +#define _LOAD_SMALL_INT_2_r12 1246 +#define _LOAD_SMALL_INT_2_r23 1247 +#define _LOAD_SMALL_INT_3_r01 1248 +#define _LOAD_SMALL_INT_3_r12 1249 +#define _LOAD_SMALL_INT_3_r23 1250 +#define _LOAD_SPECIAL_r00 1251 +#define _LOAD_SUPER_ATTR_ATTR_r31 1252 +#define _LOAD_SUPER_ATTR_METHOD_r32 1253 +#define _MAKE_CALLARGS_A_TUPLE_r33 1254 +#define _MAKE_CELL_r00 1255 +#define _MAKE_FUNCTION_r11 1256 +#define _MAKE_WARM_r00 1257 +#define _MAKE_WARM_r11 1258 +#define _MAKE_WARM_r22 1259 +#define _MAKE_WARM_r33 1260 +#define _MAP_ADD_r20 1261 +#define _MATCH_CLASS_r31 1262 +#define _MATCH_KEYS_r23 1263 +#define _MATCH_MAPPING_r02 1264 +#define _MATCH_MAPPING_r12 1265 +#define _MATCH_MAPPING_r23 1266 +#define _MATCH_SEQUENCE_r02 1267 +#define _MATCH_SEQUENCE_r12 1268 +#define _MATCH_SEQUENCE_r23 1269 +#define _MAYBE_EXPAND_METHOD_r00 1270 +#define _MAYBE_EXPAND_METHOD_KW_r11 1271 +#define _MONITOR_CALL_r00 1272 +#define _MONITOR_CALL_KW_r11 1273 +#define _MONITOR_JUMP_BACKWARD_r00 1274 +#define _MONITOR_JUMP_BACKWARD_r11 1275 +#define _MONITOR_JUMP_BACKWARD_r22 1276 +#define _MONITOR_JUMP_BACKWARD_r33 1277 +#define _MONITOR_RESUME_r00 1278 +#define _NOP_r00 1279 +#define _NOP_r11 1280 +#define _NOP_r22 1281 +#define _NOP_r33 1282 +#define _POP_CALL_r20 1283 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1284 +#define _POP_CALL_ONE_r30 1285 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1286 +#define _POP_CALL_TWO_r30 1287 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1288 +#define _POP_EXCEPT_r10 1289 +#define _POP_ITER_r20 1290 +#define _POP_JUMP_IF_FALSE_r00 1291 +#define _POP_JUMP_IF_FALSE_r10 1292 +#define _POP_JUMP_IF_FALSE_r21 1293 +#define _POP_JUMP_IF_FALSE_r32 1294 +#define _POP_JUMP_IF_TRUE_r00 1295 +#define _POP_JUMP_IF_TRUE_r10 1296 +#define _POP_JUMP_IF_TRUE_r21 1297 +#define _POP_JUMP_IF_TRUE_r32 1298 +#define _POP_TOP_r10 1299 +#define _POP_TOP_FLOAT_r00 1300 +#define _POP_TOP_FLOAT_r10 1301 +#define _POP_TOP_FLOAT_r21 1302 +#define _POP_TOP_FLOAT_r32 1303 +#define _POP_TOP_INT_r00 1304 +#define _POP_TOP_INT_r10 1305 +#define _POP_TOP_INT_r21 1306 +#define _POP_TOP_INT_r32 1307 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1308 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1309 +#define _POP_TOP_NOP_r00 1310 +#define _POP_TOP_NOP_r10 1311 +#define _POP_TOP_NOP_r21 1312 +#define _POP_TOP_NOP_r32 1313 +#define _POP_TOP_UNICODE_r00 1314 +#define _POP_TOP_UNICODE_r10 1315 +#define _POP_TOP_UNICODE_r21 1316 +#define _POP_TOP_UNICODE_r32 1317 +#define _POP_TWO_r20 1318 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1319 +#define _PUSH_EXC_INFO_r02 1320 +#define _PUSH_EXC_INFO_r12 1321 +#define _PUSH_EXC_INFO_r23 1322 +#define _PUSH_FRAME_r10 1323 +#define _PUSH_NULL_r01 1324 +#define _PUSH_NULL_r12 1325 +#define _PUSH_NULL_r23 1326 +#define _PUSH_NULL_CONDITIONAL_r00 1327 +#define _PY_FRAME_EX_r31 1328 +#define _PY_FRAME_GENERAL_r01 1329 +#define _PY_FRAME_KW_r11 1330 +#define _QUICKEN_RESUME_r00 1331 +#define _QUICKEN_RESUME_r11 1332 +#define _QUICKEN_RESUME_r22 1333 +#define _QUICKEN_RESUME_r33 1334 +#define _REPLACE_WITH_TRUE_r02 1335 +#define _REPLACE_WITH_TRUE_r12 1336 +#define _REPLACE_WITH_TRUE_r23 1337 +#define _RESUME_CHECK_r00 1338 +#define _RESUME_CHECK_r11 1339 +#define _RESUME_CHECK_r22 1340 +#define _RESUME_CHECK_r33 1341 +#define _RETURN_GENERATOR_r01 1342 +#define _RETURN_VALUE_r11 1343 +#define _SAVE_RETURN_OFFSET_r00 1344 +#define _SAVE_RETURN_OFFSET_r11 1345 +#define _SAVE_RETURN_OFFSET_r22 1346 +#define _SAVE_RETURN_OFFSET_r33 1347 +#define _SEND_r22 1348 +#define _SEND_GEN_FRAME_r22 1349 +#define _SETUP_ANNOTATIONS_r00 1350 +#define _SET_ADD_r10 1351 +#define _SET_FUNCTION_ATTRIBUTE_r01 1352 +#define _SET_FUNCTION_ATTRIBUTE_r11 1353 +#define _SET_FUNCTION_ATTRIBUTE_r21 1354 +#define _SET_FUNCTION_ATTRIBUTE_r32 1355 +#define _SET_IP_r00 1356 +#define _SET_IP_r11 1357 +#define _SET_IP_r22 1358 +#define _SET_IP_r33 1359 +#define _SET_UPDATE_r10 1360 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1361 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1362 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1363 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1364 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1365 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1366 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1367 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1368 +#define _SPILL_OR_RELOAD_r01 1369 +#define _SPILL_OR_RELOAD_r02 1370 +#define _SPILL_OR_RELOAD_r03 1371 +#define _SPILL_OR_RELOAD_r10 1372 +#define _SPILL_OR_RELOAD_r12 1373 +#define _SPILL_OR_RELOAD_r13 1374 +#define _SPILL_OR_RELOAD_r20 1375 +#define _SPILL_OR_RELOAD_r21 1376 +#define _SPILL_OR_RELOAD_r23 1377 +#define _SPILL_OR_RELOAD_r30 1378 +#define _SPILL_OR_RELOAD_r31 1379 +#define _SPILL_OR_RELOAD_r32 1380 +#define _START_EXECUTOR_r00 1381 +#define _STORE_ATTR_r20 1382 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1383 +#define _STORE_ATTR_SLOT_r21 1384 +#define _STORE_ATTR_WITH_HINT_r21 1385 +#define _STORE_DEREF_r10 1386 +#define _STORE_FAST_LOAD_FAST_r11 1387 +#define _STORE_FAST_STORE_FAST_r20 1388 +#define _STORE_GLOBAL_r10 1389 +#define _STORE_NAME_r10 1390 +#define _STORE_SLICE_r30 1391 +#define _STORE_SUBSCR_r30 1392 +#define _STORE_SUBSCR_DICT_r31 1393 +#define _STORE_SUBSCR_LIST_INT_r32 1394 +#define _SWAP_r11 1395 +#define _SWAP_2_r02 1396 +#define _SWAP_2_r12 1397 +#define _SWAP_2_r22 1398 +#define _SWAP_2_r33 1399 +#define _SWAP_3_r03 1400 +#define _SWAP_3_r13 1401 +#define _SWAP_3_r23 1402 +#define _SWAP_3_r33 1403 +#define _SWAP_FAST_r01 1404 +#define _SWAP_FAST_r11 1405 +#define _SWAP_FAST_r22 1406 +#define _SWAP_FAST_r33 1407 +#define _SWAP_FAST_0_r01 1408 +#define _SWAP_FAST_0_r11 1409 +#define _SWAP_FAST_0_r22 1410 +#define _SWAP_FAST_0_r33 1411 +#define _SWAP_FAST_1_r01 1412 +#define _SWAP_FAST_1_r11 1413 +#define _SWAP_FAST_1_r22 1414 +#define _SWAP_FAST_1_r33 1415 +#define _SWAP_FAST_2_r01 1416 +#define _SWAP_FAST_2_r11 1417 +#define _SWAP_FAST_2_r22 1418 +#define _SWAP_FAST_2_r33 1419 +#define _SWAP_FAST_3_r01 1420 +#define _SWAP_FAST_3_r11 1421 +#define _SWAP_FAST_3_r22 1422 +#define _SWAP_FAST_3_r33 1423 +#define _SWAP_FAST_4_r01 1424 +#define _SWAP_FAST_4_r11 1425 +#define _SWAP_FAST_4_r22 1426 +#define _SWAP_FAST_4_r33 1427 +#define _SWAP_FAST_5_r01 1428 +#define _SWAP_FAST_5_r11 1429 +#define _SWAP_FAST_5_r22 1430 +#define _SWAP_FAST_5_r33 1431 +#define _SWAP_FAST_6_r01 1432 +#define _SWAP_FAST_6_r11 1433 +#define _SWAP_FAST_6_r22 1434 +#define _SWAP_FAST_6_r33 1435 +#define _SWAP_FAST_7_r01 1436 +#define _SWAP_FAST_7_r11 1437 +#define _SWAP_FAST_7_r22 1438 +#define _SWAP_FAST_7_r33 1439 +#define _TIER2_RESUME_CHECK_r00 1440 +#define _TIER2_RESUME_CHECK_r11 1441 +#define _TIER2_RESUME_CHECK_r22 1442 +#define _TIER2_RESUME_CHECK_r33 1443 +#define _TO_BOOL_r11 1444 +#define _TO_BOOL_BOOL_r01 1445 +#define _TO_BOOL_BOOL_r11 1446 +#define _TO_BOOL_BOOL_r22 1447 +#define _TO_BOOL_BOOL_r33 1448 +#define _TO_BOOL_INT_r02 1449 +#define _TO_BOOL_INT_r12 1450 +#define _TO_BOOL_INT_r23 1451 +#define _TO_BOOL_LIST_r02 1452 +#define _TO_BOOL_LIST_r12 1453 +#define _TO_BOOL_LIST_r23 1454 +#define _TO_BOOL_NONE_r01 1455 +#define _TO_BOOL_NONE_r11 1456 +#define _TO_BOOL_NONE_r22 1457 +#define _TO_BOOL_NONE_r33 1458 +#define _TO_BOOL_STR_r02 1459 +#define _TO_BOOL_STR_r12 1460 +#define _TO_BOOL_STR_r23 1461 +#define _TRACE_RECORD_r00 1462 +#define _UNARY_INVERT_r12 1463 +#define _UNARY_NEGATIVE_r12 1464 +#define _UNARY_NOT_r01 1465 +#define _UNARY_NOT_r11 1466 +#define _UNARY_NOT_r22 1467 +#define _UNARY_NOT_r33 1468 +#define _UNPACK_EX_r10 1469 +#define _UNPACK_SEQUENCE_r10 1470 +#define _UNPACK_SEQUENCE_LIST_r10 1471 +#define _UNPACK_SEQUENCE_TUPLE_r10 1472 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1473 +#define _WITH_EXCEPT_START_r33 1474 +#define _YIELD_VALUE_r11 1475 +#define MAX_UOP_REGS_ID 1475 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 33a4d17d766eb2..c08f1e24fd1c12 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -129,6 +129,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_GUARD_NOS_DICT] = HAS_EXIT_FLAG, [_GUARD_NOS_ANY_DICT] = HAS_EXIT_FLAG, [_GUARD_TOS_ANY_DICT] = HAS_EXIT_FLAG, + [_GUARD_TOS_DICT] = HAS_EXIT_FLAG, + [_GUARD_TOS_FROZENDICT] = HAS_EXIT_FLAG, [_BINARY_OP_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_BINARY_OP_SUBSCR_CHECK_FUNC] = HAS_DEOPT_FLAG, [_BINARY_OP_SUBSCR_INIT_CALL] = 0, @@ -211,6 +213,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_IS_OP] = HAS_ARG_FLAG, [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_GUARD_TOS_ANY_SET] = HAS_DEOPT_FLAG, + [_GUARD_TOS_SET] = HAS_DEOPT_FLAG, + [_GUARD_TOS_FROZENSET] = HAS_DEOPT_FLAG, [_CONTAINS_OP_SET] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CONTAINS_OP_DICT] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CHECK_EG_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -1245,6 +1249,24 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { 3, 3, _GUARD_TOS_ANY_DICT_r33 }, }, }, + [_GUARD_TOS_DICT] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _GUARD_TOS_DICT_r01 }, + { 1, 1, _GUARD_TOS_DICT_r11 }, + { 2, 2, _GUARD_TOS_DICT_r22 }, + { 3, 3, _GUARD_TOS_DICT_r33 }, + }, + }, + [_GUARD_TOS_FROZENDICT] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _GUARD_TOS_FROZENDICT_r01 }, + { 1, 1, _GUARD_TOS_FROZENDICT_r11 }, + { 2, 2, _GUARD_TOS_FROZENDICT_r22 }, + { 3, 3, _GUARD_TOS_FROZENDICT_r33 }, + }, + }, [_BINARY_OP_SUBSCR_DICT] = { .best = { 2, 2, 2, 2 }, .entries = { @@ -1983,6 +2005,24 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { 3, 3, _GUARD_TOS_ANY_SET_r33 }, }, }, + [_GUARD_TOS_SET] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _GUARD_TOS_SET_r01 }, + { 1, 1, _GUARD_TOS_SET_r11 }, + { 2, 2, _GUARD_TOS_SET_r22 }, + { 3, 3, _GUARD_TOS_SET_r33 }, + }, + }, + [_GUARD_TOS_FROZENSET] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _GUARD_TOS_FROZENSET_r01 }, + { 1, 1, _GUARD_TOS_FROZENSET_r11 }, + { 2, 2, _GUARD_TOS_FROZENSET_r22 }, + { 3, 3, _GUARD_TOS_FROZENSET_r33 }, + }, + }, [_CONTAINS_OP_SET] = { .best = { 2, 2, 2, 2 }, .entries = { @@ -3742,6 +3782,14 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_GUARD_TOS_ANY_DICT_r11] = _GUARD_TOS_ANY_DICT, [_GUARD_TOS_ANY_DICT_r22] = _GUARD_TOS_ANY_DICT, [_GUARD_TOS_ANY_DICT_r33] = _GUARD_TOS_ANY_DICT, + [_GUARD_TOS_DICT_r01] = _GUARD_TOS_DICT, + [_GUARD_TOS_DICT_r11] = _GUARD_TOS_DICT, + [_GUARD_TOS_DICT_r22] = _GUARD_TOS_DICT, + [_GUARD_TOS_DICT_r33] = _GUARD_TOS_DICT, + [_GUARD_TOS_FROZENDICT_r01] = _GUARD_TOS_FROZENDICT, + [_GUARD_TOS_FROZENDICT_r11] = _GUARD_TOS_FROZENDICT, + [_GUARD_TOS_FROZENDICT_r22] = _GUARD_TOS_FROZENDICT, + [_GUARD_TOS_FROZENDICT_r33] = _GUARD_TOS_FROZENDICT, [_BINARY_OP_SUBSCR_DICT_r23] = _BINARY_OP_SUBSCR_DICT, [_BINARY_OP_SUBSCR_CHECK_FUNC_r23] = _BINARY_OP_SUBSCR_CHECK_FUNC, [_BINARY_OP_SUBSCR_INIT_CALL_r01] = _BINARY_OP_SUBSCR_INIT_CALL, @@ -3863,6 +3911,14 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_GUARD_TOS_ANY_SET_r11] = _GUARD_TOS_ANY_SET, [_GUARD_TOS_ANY_SET_r22] = _GUARD_TOS_ANY_SET, [_GUARD_TOS_ANY_SET_r33] = _GUARD_TOS_ANY_SET, + [_GUARD_TOS_SET_r01] = _GUARD_TOS_SET, + [_GUARD_TOS_SET_r11] = _GUARD_TOS_SET, + [_GUARD_TOS_SET_r22] = _GUARD_TOS_SET, + [_GUARD_TOS_SET_r33] = _GUARD_TOS_SET, + [_GUARD_TOS_FROZENSET_r01] = _GUARD_TOS_FROZENSET, + [_GUARD_TOS_FROZENSET_r11] = _GUARD_TOS_FROZENSET, + [_GUARD_TOS_FROZENSET_r22] = _GUARD_TOS_FROZENSET, + [_GUARD_TOS_FROZENSET_r33] = _GUARD_TOS_FROZENSET, [_CONTAINS_OP_SET_r23] = _CONTAINS_OP_SET, [_CONTAINS_OP_DICT_r23] = _CONTAINS_OP_DICT, [_CHECK_EG_MATCH_r22] = _CHECK_EG_MATCH, @@ -4816,11 +4872,26 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_TOS_ANY_SET_r11] = "_GUARD_TOS_ANY_SET_r11", [_GUARD_TOS_ANY_SET_r22] = "_GUARD_TOS_ANY_SET_r22", [_GUARD_TOS_ANY_SET_r33] = "_GUARD_TOS_ANY_SET_r33", + [_GUARD_TOS_DICT] = "_GUARD_TOS_DICT", + [_GUARD_TOS_DICT_r01] = "_GUARD_TOS_DICT_r01", + [_GUARD_TOS_DICT_r11] = "_GUARD_TOS_DICT_r11", + [_GUARD_TOS_DICT_r22] = "_GUARD_TOS_DICT_r22", + [_GUARD_TOS_DICT_r33] = "_GUARD_TOS_DICT_r33", [_GUARD_TOS_FLOAT] = "_GUARD_TOS_FLOAT", [_GUARD_TOS_FLOAT_r01] = "_GUARD_TOS_FLOAT_r01", [_GUARD_TOS_FLOAT_r11] = "_GUARD_TOS_FLOAT_r11", [_GUARD_TOS_FLOAT_r22] = "_GUARD_TOS_FLOAT_r22", [_GUARD_TOS_FLOAT_r33] = "_GUARD_TOS_FLOAT_r33", + [_GUARD_TOS_FROZENDICT] = "_GUARD_TOS_FROZENDICT", + [_GUARD_TOS_FROZENDICT_r01] = "_GUARD_TOS_FROZENDICT_r01", + [_GUARD_TOS_FROZENDICT_r11] = "_GUARD_TOS_FROZENDICT_r11", + [_GUARD_TOS_FROZENDICT_r22] = "_GUARD_TOS_FROZENDICT_r22", + [_GUARD_TOS_FROZENDICT_r33] = "_GUARD_TOS_FROZENDICT_r33", + [_GUARD_TOS_FROZENSET] = "_GUARD_TOS_FROZENSET", + [_GUARD_TOS_FROZENSET_r01] = "_GUARD_TOS_FROZENSET_r01", + [_GUARD_TOS_FROZENSET_r11] = "_GUARD_TOS_FROZENSET_r11", + [_GUARD_TOS_FROZENSET_r22] = "_GUARD_TOS_FROZENSET_r22", + [_GUARD_TOS_FROZENSET_r33] = "_GUARD_TOS_FROZENSET_r33", [_GUARD_TOS_INT] = "_GUARD_TOS_INT", [_GUARD_TOS_INT_r01] = "_GUARD_TOS_INT_r01", [_GUARD_TOS_INT_r11] = "_GUARD_TOS_INT_r11", @@ -4836,6 +4907,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_TOS_OVERFLOWED_r11] = "_GUARD_TOS_OVERFLOWED_r11", [_GUARD_TOS_OVERFLOWED_r22] = "_GUARD_TOS_OVERFLOWED_r22", [_GUARD_TOS_OVERFLOWED_r33] = "_GUARD_TOS_OVERFLOWED_r33", + [_GUARD_TOS_SET] = "_GUARD_TOS_SET", + [_GUARD_TOS_SET_r01] = "_GUARD_TOS_SET_r01", + [_GUARD_TOS_SET_r11] = "_GUARD_TOS_SET_r11", + [_GUARD_TOS_SET_r22] = "_GUARD_TOS_SET_r22", + [_GUARD_TOS_SET_r33] = "_GUARD_TOS_SET_r33", [_GUARD_TOS_SLICE] = "_GUARD_TOS_SLICE", [_GUARD_TOS_SLICE_r01] = "_GUARD_TOS_SLICE_r01", [_GUARD_TOS_SLICE_r11] = "_GUARD_TOS_SLICE_r11", @@ -5607,6 +5683,10 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _GUARD_TOS_ANY_DICT: return 0; + case _GUARD_TOS_DICT: + return 0; + case _GUARD_TOS_FROZENDICT: + return 0; case _BINARY_OP_SUBSCR_DICT: return 2; case _BINARY_OP_SUBSCR_CHECK_FUNC: @@ -5771,6 +5851,10 @@ int _PyUop_num_popped(int opcode, int oparg) return 2; case _GUARD_TOS_ANY_SET: return 0; + case _GUARD_TOS_SET: + return 0; + case _GUARD_TOS_FROZENSET: + return 0; case _CONTAINS_OP_SET: return 2; case _CONTAINS_OP_DICT: diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 8caad077ec07ec..8a748fec9e4201 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1082,6 +1082,16 @@ dummy_func( EXIT_IF(!PyAnyDict_CheckExact(o)); } + op(_GUARD_TOS_DICT, (tos -- tos)) { + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + EXIT_IF(!PyDict_CheckExact(o)); + } + + op(_GUARD_TOS_FROZENDICT, (tos -- tos)) { + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + EXIT_IF(!PyFrozenDict_CheckExact(o)); + } + macro(BINARY_OP_SUBSCR_DICT) = _GUARD_NOS_ANY_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP; @@ -2931,6 +2941,16 @@ dummy_func( DEOPT_IF(!PyAnySet_CheckExact(o)); } + op(_GUARD_TOS_SET, (tos -- tos)) { + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + DEOPT_IF(!PySet_CheckExact(o)); + } + + op(_GUARD_TOS_FROZENSET, (tos -- tos)) { + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + DEOPT_IF(!PyFrozenSet_CheckExact(o)); + } + macro(CONTAINS_OP_SET) = _GUARD_TOS_ANY_SET + unused/1 + _CONTAINS_OP_SET + POP_TOP + POP_TOP; op(_CONTAINS_OP_SET, (left, right -- b, l, r)) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 6708a9282077c4..09004545267026 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -6221,6 +6221,176 @@ break; } + case _GUARD_TOS_DICT_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + tos = stack_pointer[-1]; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_DICT_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + tos = _stack_item_0; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_DICT_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + tos = _stack_item_1; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_DICT_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + tos = _stack_item_2; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENDICT_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + tos = stack_pointer[-1]; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENDICT_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + tos = _stack_item_0; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENDICT_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + tos = _stack_item_1; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENDICT_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + tos = _stack_item_2; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenDict_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _BINARY_OP_SUBSCR_DICT_r23: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); @@ -10470,6 +10640,176 @@ break; } + case _GUARD_TOS_SET_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + tos = stack_pointer[-1]; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PySet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_SET_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + tos = _stack_item_0; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PySet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_SET_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + tos = _stack_item_1; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PySet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_SET_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + tos = _stack_item_2; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PySet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENSET_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + tos = stack_pointer[-1]; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenSet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENSET_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + tos = _stack_item_0; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenSet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = tos; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENSET_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + tos = _stack_item_1; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenSet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = tos; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _GUARD_TOS_FROZENSET_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef tos; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + tos = _stack_item_2; + PyObject *o = PyStackRef_AsPyObjectBorrow(tos); + if (!PyFrozenSet_CheckExact(o)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = tos; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _CONTAINS_OP_SET_r23: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 45dd42c96064bc..a5ed5953ec082c 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -262,6 +262,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr, #define sym_new_null _Py_uop_sym_new_null #define sym_has_type _Py_uop_sym_has_type #define sym_get_type _Py_uop_sym_get_type +#define sym_get_probable_type _Py_uop_sym_get_probable_type #define sym_matches_type _Py_uop_sym_matches_type #define sym_matches_type_version _Py_uop_sym_matches_type_version #define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 3dd5d65702b47f..2f52837f058113 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -46,6 +46,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; #define sym_set_recorded_gen_func(SYM, VAL) _Py_uop_sym_set_recorded_gen_func(ctx, SYM, VAL) #define sym_get_probable_func_code _Py_uop_sym_get_probable_func_code #define sym_get_probable_value _Py_uop_sym_get_probable_value +#define sym_get_probable_type _Py_uop_sym_get_probable_type #define sym_set_stack_depth(DEPTH, SP) _Py_uop_sym_set_stack_depth(ctx, DEPTH, SP) extern int @@ -1324,28 +1325,36 @@ dummy_func(void) { if (sym_matches_type(tos, &PyList_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PyList_Type); + else { + sym_set_type(tos, &PyList_Type); + } } op(_GUARD_NOS_LIST, (nos, unused -- nos, unused)) { if (sym_matches_type(nos, &PyList_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(nos, &PyList_Type); + else { + sym_set_type(nos, &PyList_Type); + } } op(_GUARD_TOS_TUPLE, (tos -- tos)) { if (sym_matches_type(tos, &PyTuple_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PyTuple_Type); + else { + sym_set_type(tos, &PyTuple_Type); + } } op(_GUARD_NOS_TUPLE, (nos, unused -- nos, unused)) { if (sym_matches_type(nos, &PyTuple_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(nos, &PyTuple_Type); + else { + sym_set_type(nos, &PyTuple_Type); + } } op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) { @@ -1359,7 +1368,6 @@ dummy_func(void) { PyTypeObject *tp = sym_get_type(nos); if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { ADD_OP(_NOP, 0, 0); - sym_set_type(nos, tp); } } @@ -1367,65 +1375,133 @@ dummy_func(void) { PyTypeObject *tp = sym_get_type(tos); if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { ADD_OP(_NOP, 0, 0); - sym_set_type(tos, tp); + } + else { + // Narrowing the guard based on the probable type. + tp = sym_get_probable_type(tos); + if (tp == &PyDict_Type) { + ADD_OP(_GUARD_TOS_DICT, 0, 0); + } + else if (tp == &PyFrozenDict_Type) { + ADD_OP(_GUARD_TOS_FROZENDICT, 0, 0); + } + } + } + + op(_GUARD_TOS_DICT, (tos -- tos)) { + if (sym_matches_type(tos, &PyDict_Type)) { + ADD_OP(_NOP, 0, 0); + } + else { + sym_set_type(tos, &PyDict_Type); + } + } + + op(_GUARD_TOS_FROZENDICT, (tos -- tos)) { + if (sym_matches_type(tos, &PyFrozenDict_Type)) { + ADD_OP(_NOP, 0, 0); + } + else { + sym_set_type(tos, &PyFrozenDict_Type); } } op(_GUARD_TOS_ANY_SET, (tos -- tos)) { - if (sym_matches_type(tos, &PySet_Type) || - sym_matches_type(tos, &PyFrozenSet_Type)) - { + PyTypeObject *tp = sym_get_type(tos); + if (tp == &PySet_Type || tp == &PyFrozenSet_Type) { + ADD_OP(_NOP, 0, 0); + } + else { + // Narrowing the guard based on the probable type. + tp = sym_get_probable_type(tos); + if (tp == &PySet_Type) { + ADD_OP(_GUARD_TOS_SET, 0, 0); + } + else if (tp == &PyFrozenSet_Type) { + ADD_OP(_GUARD_TOS_FROZENSET, 0, 0); + } + } + } + + op(_GUARD_TOS_SET, (tos -- tos)) { + if (sym_matches_type(tos, &PySet_Type)) { + ADD_OP(_NOP, 0, 0); + } + else { + sym_set_type(tos, &PySet_Type); + } + } + + op(_GUARD_TOS_FROZENSET, (tos -- tos)) { + if (sym_matches_type(tos, &PyFrozenSet_Type)) { ADD_OP(_NOP, 0, 0); } + else { + sym_set_type(tos, &PyFrozenSet_Type); + } } op(_GUARD_TOS_SLICE, (tos -- tos)) { if (sym_matches_type(tos, &PySlice_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PySlice_Type); + else { + sym_set_type(tos, &PySlice_Type); + } } op(_GUARD_NOS_NULL, (null, unused -- null, unused)) { if (sym_is_null(null)) { ADD_OP(_NOP, 0, 0); } - sym_set_null(null); + else { + sym_set_null(null); + } } op(_GUARD_NOS_NOT_NULL, (nos, unused -- nos, unused)) { if (sym_is_not_null(nos)) { ADD_OP(_NOP, 0, 0); } - sym_set_non_null(nos); + else { + sym_set_non_null(nos); + } } op(_GUARD_THIRD_NULL, (null, unused, unused -- null, unused, unused)) { if (sym_is_null(null)) { ADD_OP(_NOP, 0, 0); } - sym_set_null(null); + else { + sym_set_null(null); + } } op(_GUARD_CALLABLE_TYPE_1, (callable, unused, unused -- callable, unused, unused)) { if (sym_get_const(ctx, callable) == (PyObject *)&PyType_Type) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, (PyObject *)&PyType_Type); + else { + sym_set_const(callable, (PyObject *)&PyType_Type); + } } op(_GUARD_CALLABLE_TUPLE_1, (callable, unused, unused -- callable, unused, unused)) { if (sym_get_const(ctx, callable) == (PyObject *)&PyTuple_Type) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, (PyObject *)&PyTuple_Type); + else { + sym_set_const(callable, (PyObject *)&PyTuple_Type); + } } op(_GUARD_CALLABLE_STR_1, (callable, unused, unused -- callable, unused, unused)) { if (sym_get_const(ctx, callable) == (PyObject *)&PyUnicode_Type) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, (PyObject *)&PyUnicode_Type); + else { + sym_set_const(callable, (PyObject *)&PyUnicode_Type); + } } op(_CALL_LEN, (callable, null, arg -- res, a, c)) { @@ -1484,7 +1560,9 @@ dummy_func(void) { if (sym_get_const(ctx, callable) == len) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, len); + else { + sym_set_const(callable, len); + } } op(_GUARD_CALLABLE_ISINSTANCE, (callable, unused, unused, unused -- callable, unused, unused, unused)) { @@ -1492,7 +1570,9 @@ dummy_func(void) { if (sym_get_const(ctx, callable) == isinstance) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, isinstance); + else { + sym_set_const(callable, isinstance); + } } op(_GUARD_CALLABLE_LIST_APPEND, (callable, unused, unused -- callable, unused, unused)) { @@ -1500,7 +1580,9 @@ dummy_func(void) { if (sym_get_const(ctx, callable) == list_append) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, list_append); + else { + sym_set_const(callable, list_append); + } } op(_BINARY_SLICE, (container, start, stop -- res)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index f2616eddbb758a..c35c77ed442d7a 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -355,7 +355,9 @@ if (sym_matches_type(nos, &PyList_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(nos, &PyList_Type); + else { + sym_set_type(nos, &PyList_Type); + } break; } @@ -365,7 +367,9 @@ if (sym_matches_type(tos, &PyList_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PyList_Type); + else { + sym_set_type(tos, &PyList_Type); + } break; } @@ -375,7 +379,9 @@ if (sym_matches_type(tos, &PySlice_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PySlice_Type); + else { + sym_set_type(tos, &PySlice_Type); + } break; } @@ -1023,7 +1029,9 @@ if (sym_matches_type(nos, &PyTuple_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(nos, &PyTuple_Type); + else { + sym_set_type(nos, &PyTuple_Type); + } break; } @@ -1033,7 +1041,9 @@ if (sym_matches_type(tos, &PyTuple_Type)) { ADD_OP(_NOP, 0, 0); } - sym_set_type(tos, &PyTuple_Type); + else { + sym_set_type(tos, &PyTuple_Type); + } break; } @@ -1107,7 +1117,6 @@ PyTypeObject *tp = sym_get_type(nos); if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { ADD_OP(_NOP, 0, 0); - sym_set_type(nos, tp); } break; } @@ -1118,7 +1127,39 @@ PyTypeObject *tp = sym_get_type(tos); if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) { ADD_OP(_NOP, 0, 0); - sym_set_type(tos, tp); + } + else { + tp = sym_get_probable_type(tos); + if (tp == &PyDict_Type) { + ADD_OP(_GUARD_TOS_DICT, 0, 0); + } + else if (tp == &PyFrozenDict_Type) { + ADD_OP(_GUARD_TOS_FROZENDICT, 0, 0); + } + } + break; + } + + case _GUARD_TOS_DICT: { + JitOptRef tos; + tos = stack_pointer[-1]; + if (sym_matches_type(tos, &PyDict_Type)) { + ADD_OP(_NOP, 0, 0); + } + else { + sym_set_type(tos, &PyDict_Type); + } + break; + } + + case _GUARD_TOS_FROZENDICT: { + JitOptRef tos; + tos = stack_pointer[-1]; + if (sym_matches_type(tos, &PyFrozenDict_Type)) { + ADD_OP(_NOP, 0, 0); + } + else { + sym_set_type(tos, &PyFrozenDict_Type); } break; } @@ -2430,11 +2471,43 @@ case _GUARD_TOS_ANY_SET: { JitOptRef tos; tos = stack_pointer[-1]; - if (sym_matches_type(tos, &PySet_Type) || - sym_matches_type(tos, &PyFrozenSet_Type)) - { + PyTypeObject *tp = sym_get_type(tos); + if (tp == &PySet_Type || tp == &PyFrozenSet_Type) { + ADD_OP(_NOP, 0, 0); + } + else { + tp = sym_get_probable_type(tos); + if (tp == &PySet_Type) { + ADD_OP(_GUARD_TOS_SET, 0, 0); + } + else if (tp == &PyFrozenSet_Type) { + ADD_OP(_GUARD_TOS_FROZENSET, 0, 0); + } + } + break; + } + + case _GUARD_TOS_SET: { + JitOptRef tos; + tos = stack_pointer[-1]; + if (sym_matches_type(tos, &PySet_Type)) { ADD_OP(_NOP, 0, 0); } + else { + sym_set_type(tos, &PySet_Type); + } + break; + } + + case _GUARD_TOS_FROZENSET: { + JitOptRef tos; + tos = stack_pointer[-1]; + if (sym_matches_type(tos, &PyFrozenSet_Type)) { + ADD_OP(_NOP, 0, 0); + } + else { + sym_set_type(tos, &PyFrozenSet_Type); + } break; } @@ -3071,7 +3144,9 @@ if (sym_is_null(null)) { ADD_OP(_NOP, 0, 0); } - sym_set_null(null); + else { + sym_set_null(null); + } break; } @@ -3081,7 +3156,9 @@ if (sym_is_not_null(nos)) { ADD_OP(_NOP, 0, 0); } - sym_set_non_null(nos); + else { + sym_set_non_null(nos); + } break; } @@ -3091,7 +3168,9 @@ if (sym_is_null(null)) { ADD_OP(_NOP, 0, 0); } - sym_set_null(null); + else { + sym_set_null(null); + } break; } @@ -3101,7 +3180,9 @@ if (sym_get_const(ctx, callable) == (PyObject *)&PyType_Type) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, (PyObject *)&PyType_Type); + else { + sym_set_const(callable, (PyObject *)&PyType_Type); + } break; } @@ -3134,7 +3215,9 @@ if (sym_get_const(ctx, callable) == (PyObject *)&PyUnicode_Type) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, (PyObject *)&PyUnicode_Type); + else { + sym_set_const(callable, (PyObject *)&PyUnicode_Type); + } break; } @@ -3164,7 +3247,9 @@ if (sym_get_const(ctx, callable) == (PyObject *)&PyTuple_Type) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, (PyObject *)&PyTuple_Type); + else { + sym_set_const(callable, (PyObject *)&PyTuple_Type); + } break; } @@ -3307,7 +3392,9 @@ if (sym_get_const(ctx, callable) == len) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, len); + else { + sym_set_const(callable, len); + } break; } @@ -3368,7 +3455,9 @@ if (sym_get_const(ctx, callable) == isinstance) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, isinstance); + else { + sym_set_const(callable, isinstance); + } break; } @@ -3403,7 +3492,9 @@ if (sym_get_const(ctx, callable) == list_append) { ADD_OP(_NOP, 0, 0); } - sym_set_const(callable, list_append); + else { + sym_set_const(callable, list_append); + } break; } diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c index dcbe093fd6d74c..fd784aa11e4b89 100644 --- a/Python/optimizer_symbols.c +++ b/Python/optimizer_symbols.c @@ -688,6 +688,34 @@ _Py_uop_sym_get_type(JitOptRef ref) Py_UNREACHABLE(); } +PyTypeObject * +_Py_uop_sym_get_probable_type(JitOptRef ref) +{ + JitOptSymbol *sym = PyJitRef_Unwrap(ref); + JitSymType tag = sym->tag; + switch(tag) { + case JIT_SYM_NULL_TAG: + case JIT_SYM_BOTTOM_TAG: + case JIT_SYM_NON_NULL_TAG: + case JIT_SYM_UNKNOWN_TAG: + case JIT_SYM_TYPE_VERSION_TAG: + case JIT_SYM_TUPLE_TAG: + case JIT_SYM_PREDICATE_TAG: + case JIT_SYM_TRUTHINESS_TAG: + case JIT_SYM_COMPACT_INT: + case JIT_SYM_KNOWN_CLASS_TAG: + case JIT_SYM_KNOWN_VALUE_TAG: + return _Py_uop_sym_get_type(ref); + case JIT_SYM_RECORDED_GEN_FUNC_TAG: + return NULL; + case JIT_SYM_RECORDED_VALUE_TAG: + return Py_TYPE(sym->recorded_value.value); + case JIT_SYM_RECORDED_TYPE_TAG: + return sym->recorded_type.type; + } + Py_UNREACHABLE(); +} + unsigned int _Py_uop_sym_get_type_version(JitOptRef ref) { From f1de65b3669226d563802a32b78a2294e971151a Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 3 Mar 2026 11:47:02 +0100 Subject: [PATCH 295/498] gh-145455: Show output of blurb & sphinx-build version commands (GH-145457) In gh-145455, an outdated dependency caused an import error that was not printed out (`2>&1`); the message instead said that the tools are missing. Don't redirect stderr, to show warnings and failures. Also, switch `blurb` to output a version on a single line (`--version` rather than `help`), and, and don't redirect stdout either. This results in two version info lines being printed out. These get drowned in typical Sphinx output, and can be helpful when debugging. --- Doc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Makefile b/Doc/Makefile index d39c2fe3c3f22a..5b7fdf8ec08ed4 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -58,7 +58,7 @@ build: @if [ -f ../Misc/NEWS ] ; then \ echo "Using existing Misc/NEWS file"; \ cp ../Misc/NEWS build/NEWS; \ - elif $(BLURB) help >/dev/null 2>&1 && $(SPHINXBUILD) --version >/dev/null 2>&1; then \ + elif $(BLURB) --version && $(SPHINXBUILD) --version ; then \ if [ -d ../Misc/NEWS.d ]; then \ echo "Building NEWS from Misc/NEWS.d with blurb"; \ $(BLURB) merge -f build/NEWS; \ From c9d123482acebcf725c847bd6f8354bdd9314189 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 3 Mar 2026 12:15:32 +0100 Subject: [PATCH 296/498] gh-144995: Optimize memoryview == memoryview (#144996) Optimize memoryview comparison: a memoryview is equal to itself, there is no need to compare values, except if it uses float format. Benchmark comparing 1 MiB: from timeit import timeit with open("/dev/random", 'br') as fp: data = fp.read(2**20) view = memoryview(data) LOOPS = 1_000 b = timeit('x == x', number=LOOPS, globals={'x': data}) m = timeit('x == x', number=LOOPS, globals={'x': view}) print("bytes %f seconds" % b) print("mview %f seconds" % m) print("=> %f time slower" % (m / b)) Result before the change: bytes 0.000026 seconds mview 1.445791 seconds => 55660.873940 time slower Result after the change: bytes 0.000026 seconds mview 0.000028 seconds => 1.104382 time slower This missed optimization was discovered by Pierre-Yves David while working on Mercurial. Co-authored-by: Pieter Eendebak --- Lib/test/test_memoryview.py | 61 +++++++++++++++++++ ...-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst | 2 + Objects/memoryobject.c | 24 ++++++++ 3 files changed, 87 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py index 656318668e6d6e..0f7dc15b8c6f2c 100644 --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -575,6 +575,67 @@ def test_array_assign(self): m[:] = new_a self.assertEqual(a, new_a) + def test_compare_equal(self): + # A memoryview is equal to itself: there is no need to compare + # individual values. This is not true for float values since they can + # be NaN, and NaN is not equal to itself. + + def check_equal(view, is_equal): + self.assertEqual(view == view, is_equal) + self.assertEqual(view != view, not is_equal) + + # Comparison with a different memoryview doesn't use + # the optimization and should give the same result. + view2 = memoryview(view) + self.assertEqual(view2 == view, is_equal) + self.assertEqual(view2 != view2, not is_equal) + + # Test integer formats + for int_format in 'bBhHiIlLqQ': + with self.subTest(format=int_format): + a = array.array(int_format, [1, 2, 3]) + m = memoryview(a) + check_equal(m, True) + + if int_format in 'bB': + m2 = m.cast('@' + m.format) + check_equal(m2, True) + + # Test 'c' format + a = array.array('B', [1, 2, 3]) + m = memoryview(a.tobytes()).cast('c') + check_equal(m, True) + + # Test 'n' and 'N' formats + if struct.calcsize('L') == struct.calcsize('N'): + int_format = 'L' + elif struct.calcsize('Q') == struct.calcsize('N'): + int_format = 'Q' + else: + int_format = None + if int_format: + a = array.array(int_format, [1, 2, 3]) + m = memoryview(a.tobytes()).cast('N') + check_equal(m, True) + m = memoryview(a.tobytes()).cast('n') + check_equal(m, True) + + # Test '?' format + m = memoryview(b'\0\1\2').cast('?') + check_equal(m, True) + + # Test float formats + for float_format in 'fd': + with self.subTest(format=float_format): + a = array.array(float_format, [1.0, 2.0, float('nan')]) + m = memoryview(a) + # nan is not equal to nan + check_equal(m, False) + + a = array.array(float_format, [1.0, 2.0, 3.0]) + m = memoryview(a) + check_equal(m, True) + class BytesMemorySliceTest(unittest.TestCase, BaseMemorySliceTests, BaseBytesMemoryTests): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst new file mode 100644 index 00000000000000..83d84b9505c5a5 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst @@ -0,0 +1,2 @@ +Optimize :class:`memoryview` comparison: a :class:`memoryview` is equal to +itself, there is no need to compare values. Patch by Victor Stinner. diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index f3b7e4a396b4a1..0ad4f02d80bf50 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -3122,6 +3122,30 @@ memory_richcompare(PyObject *v, PyObject *w, int op) } vv = VIEW_ADDR(v); + // For formats supported by the struct module a memoryview is equal to + // itself: there is no need to compare individual values. + // This is not true for float values since they can be NaN, and NaN + // is not equal to itself. So only use this optimization on format known to + // not use floats. + if (v == w) { + const char *format = vv->format; + if (format != NULL) { + if (*format == '@') { + format++; + } + // Include only formats known by struct, exclude float formats + // "d" (double), "f" (float) and "e" (16-bit float). + // Do not optimize "P" format. + if (format[0] != 0 + && strchr("bBchHiIlLnNqQ?", format[0]) != NULL + && format[1] == 0) + { + equal = 1; + goto result; + } + } + } + if (PyMemoryView_Check(w)) { if (BASE_INACCESSIBLE(w)) { equal = (v == w); From a929e80b9e5aa5aa23bd3fb3397dfc0ac605c067 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:10:34 +0000 Subject: [PATCH 297/498] Add `PyExc_OverflowError` to the list of possible exceptions in `fuzz_ast_literal_eval` fuzzer (GH-145429) --- Modules/_xxtestfuzz/fuzzer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 0cbe10c79ab4a6..14da472c1bb110 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -428,6 +428,7 @@ static int fuzz_ast_literal_eval(const char* data, size_t size) { PyErr_ExceptionMatches(PyExc_TypeError) || PyErr_ExceptionMatches(PyExc_SyntaxError) || PyErr_ExceptionMatches(PyExc_MemoryError) || + PyErr_ExceptionMatches(PyExc_OverflowError) || PyErr_ExceptionMatches(PyExc_RecursionError)) ) { PyErr_Clear(); From db41717cd50af6db7d496b0aa282b1f3370327c6 Mon Sep 17 00:00:00 2001 From: "Michiel W. Beijen" Date: Tue, 3 Mar 2026 13:44:56 +0100 Subject: [PATCH 298/498] GH-145450: Document missing `wave.Wave_write` getter methods (GH-145451) --- Doc/library/wave.rst | 37 +++++++++++++++++++ ...-03-03-08-18-00.gh-issue-145450.VI7GXj.rst | 1 + 2 files changed, 38 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index 6e61a1a44ad232..ff020b52da3f23 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -181,11 +181,21 @@ Wave_write Objects Set the number of channels. + .. method:: getnchannels() + + Return the number of channels. + + .. method:: setsampwidth(n) Set the sample width to *n* bytes. + .. method:: getsampwidth() + + Return the sample width in bytes. + + .. method:: setframerate(n) Set the frame rate to *n*. @@ -195,6 +205,11 @@ Wave_write Objects integer. + .. method:: getframerate() + + Return the frame rate. + + .. method:: setnframes(n) Set the number of frames to *n*. This will be changed later if the number @@ -202,12 +217,27 @@ Wave_write Objects raise an error if the output stream is not seekable). + .. method:: getnframes() + + Return the number of audio frames written so far. + + .. method:: setcomptype(type, name) Set the compression type and description. At the moment, only compression type ``NONE`` is supported, meaning no compression. + .. method:: getcomptype() + + Return the compression type (``'NONE'``). + + + .. method:: getcompname() + + Return the human-readable compression type name. + + .. method:: setparams(tuple) The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype, @@ -215,6 +245,13 @@ Wave_write Objects parameters. + .. method:: getparams() + + Return a :func:`~collections.namedtuple` + ``(nchannels, sampwidth, framerate, nframes, comptype, compname)`` + containing the current output parameters. + + .. method:: tell() Return current position in the file, with the same disclaimer for the diff --git a/Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst b/Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst new file mode 100644 index 00000000000000..681c932b34a05d --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst @@ -0,0 +1 @@ +Document missing public :class:`wave.Wave_write` getter methods. From 52c8efa87d028e57895d6a44f22caeb99a589711 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 3 Mar 2026 13:57:08 +0100 Subject: [PATCH 299/498] gh-145335: Fix os functions when passing fd -1 as path (#145439) os.listdir(-1) and os.scandir(-1) now fail with OSError(errno.EBADF) rather than listing the current directory. os.listxattr(-1) now fails with OSError(errno.EBADF) rather than listing extended attributes of the current directory. --- Doc/library/os.rst | 12 ++++ Lib/test/test_os/test_os.py | 51 ++++++++++++++ ...-03-02-20-08-09.gh-issue-145335.lVTBvd.rst | 5 ++ Modules/posixmodule.c | 67 ++++++++++--------- 4 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 7418f3a8bacb0f..a22afdec516bb4 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2409,6 +2409,10 @@ features: .. versionchanged:: 3.6 Accepts a :term:`path-like object`. + .. versionchanged:: next + ``os.listdir(-1)`` now fails with ``OSError(errno.EBADF)`` rather than + listing the current directory. + .. function:: listdrives() @@ -2939,6 +2943,10 @@ features: .. versionchanged:: 3.7 Added support for :ref:`file descriptors ` on Unix. + .. versionchanged:: next + ``os.scandir(-1)`` now fails with ``OSError(errno.EBADF)`` rather than + listing the current directory. + .. class:: DirEntry @@ -4574,6 +4582,10 @@ These functions are all available on Linux only. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. + .. versionchanged:: next + ``os.listxattr(-1)`` now fails with ``OSError(errno.EBADF)`` rather than + listing extended attributes of the current directory. + .. function:: removexattr(path, attribute, *, follow_symlinks=True) diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py index 1f241609da80cd..3cab8ff9536d23 100644 --- a/Lib/test/test_os/test_os.py +++ b/Lib/test/test_os/test_os.py @@ -2784,10 +2784,61 @@ def test_fpathconf_bad_fd(self): 'musl fpathconf ignores the file descriptor and returns a constant', ) def test_pathconf_negative_fd_uses_fd_semantics(self): + if os.pathconf not in os.supports_fd: + self.skipTest('needs fpathconf()') + with self.assertRaises(OSError) as ctx: os.pathconf(-1, 1) self.assertEqual(ctx.exception.errno, errno.EBADF) + @support.subTests("fd", [-1, -5]) + def test_negative_fd_ebadf(self, fd): + tests = [(os.stat, fd)] + if hasattr(os, "statx"): + tests.append((os.statx, fd, 0)) + if os.chdir in os.supports_fd: + tests.append((os.chdir, fd)) + if os.chmod in os.supports_fd: + tests.append((os.chmod, fd, 0o777)) + if hasattr(os, "chown") and os.chown in os.supports_fd: + tests.append((os.chown, fd, 0, 0)) + if os.listdir in os.supports_fd: + tests.append((os.listdir, fd)) + if os.utime in os.supports_fd: + tests.append((os.utime, fd, (0, 0))) + if hasattr(os, "truncate") and os.truncate in os.supports_fd: + tests.append((os.truncate, fd, 0)) + if hasattr(os, 'statvfs') and os.statvfs in os.supports_fd: + tests.append((os.statvfs, fd)) + if hasattr(os, "setxattr"): + tests.append((os.getxattr, fd, b"user.test")) + tests.append((os.setxattr, fd, b"user.test", b"1")) + tests.append((os.removexattr, fd, b"user.test")) + tests.append((os.listxattr, fd)) + if os.scandir in os.supports_fd: + tests.append((os.scandir, fd)) + + for func, *args in tests: + with self.subTest(func=func, args=args): + with self.assertRaises(OSError) as ctx: + func(*args) + self.assertEqual(ctx.exception.errno, errno.EBADF) + + if hasattr(os, "execve") and os.execve in os.supports_fd: + # glibc fails with EINVAL, musl fails with EBADF + with self.assertRaises(OSError) as ctx: + os.execve(fd, [sys.executable, "-c", "pass"], os.environ) + self.assertIn(ctx.exception.errno, (errno.EBADF, errno.EINVAL)) + + if support.MS_WINDOWS: + import nt + self.assertFalse(nt._path_exists(fd)) + self.assertFalse(nt._path_lexists(fd)) + self.assertFalse(nt._path_isdir(fd)) + self.assertFalse(nt._path_isfile(fd)) + self.assertFalse(nt._path_islink(fd)) + self.assertFalse(nt._path_isjunction(fd)) + @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()') def test_ftruncate(self): self.check(os.truncate, 0) diff --git a/Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst b/Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst new file mode 100644 index 00000000000000..53033b06c2fae0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst @@ -0,0 +1,5 @@ +``os.listdir(-1)`` and ``os.scandir(-1)`` now fail with +``OSError(errno.EBADF)`` rather than listing the current directory. +``os.listxattr(-1)`` now fails with ``OSError(errno.EBADF)`` rather than +listing extended attributes of the current directory. Patch by Victor +Stinner. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b82f08e7dc4291..aa3d682a19bc9c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1638,10 +1638,10 @@ dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd) } static int -fd_and_follow_symlinks_invalid(const char *function_name, int fd, +fd_and_follow_symlinks_invalid(const char *function_name, int is_fd, int follow_symlinks) { - if ((fd >= 0) && (!follow_symlinks)) { + if (is_fd && (!follow_symlinks)) { PyErr_Format(PyExc_ValueError, "%s: cannot use fd and follow_symlinks together", function_name); @@ -2880,12 +2880,13 @@ posix_do_stat(PyObject *module, const char *function_name, path_t *path, if (path_and_dir_fd_invalid("stat", path, dir_fd) || dir_fd_and_fd_invalid("stat", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks)) + fd_and_follow_symlinks_invalid("stat", path->is_fd, follow_symlinks)) return NULL; Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) + if (path->is_fd) { result = FSTAT(path->fd, &st); + } #ifdef MS_WINDOWS else if (follow_symlinks) result = win32_stat(path->wide, &st); @@ -3647,7 +3648,7 @@ os_statx_impl(PyObject *module, path_t *path, unsigned int mask, int flags, { if (path_and_dir_fd_invalid("statx", path, dir_fd) || dir_fd_and_fd_invalid("statx", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("statx", path->fd, follow_symlinks)) { + fd_and_follow_symlinks_invalid("statx", path->is_fd, follow_symlinks)) { return NULL; } @@ -3677,7 +3678,7 @@ os_statx_impl(PyObject *module, path_t *path, unsigned int mask, int flags, int result; Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) { + if (path->is_fd) { result = statx(path->fd, "", flags | AT_EMPTY_PATH, mask, &v->stx); } else { @@ -3934,7 +3935,7 @@ os_chdir_impl(PyObject *module, path_t *path) result = !win32_wchdir(path->wide); #else #ifdef HAVE_FCHDIR - if (path->fd != -1) + if (path->is_fd) result = fchdir(path->fd); else #endif @@ -4090,7 +4091,7 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, #ifdef MS_WINDOWS result = 0; Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) { + if (path->is_fd) { result = win32_fchmod(path->fd, mode); } else if (follow_symlinks) { @@ -4113,8 +4114,9 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHMOD - if (path->fd != -1) + if (path->is_fd) { result = fchmod(path->fd, mode); + } else #endif /* HAVE_CHMOD */ #ifdef HAVE_LCHMOD @@ -4511,7 +4513,7 @@ os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, return NULL; #endif if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks)) + fd_and_follow_symlinks_invalid("chown", path->is_fd, follow_symlinks)) return NULL; if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, @@ -4521,7 +4523,7 @@ os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHOWN - if (path->fd != -1) + if (path->is_fd) result = fchown(path->fd, uid, gid); else #endif @@ -4999,7 +5001,7 @@ _posix_listdir(path_t *path, PyObject *list) errno = 0; #ifdef HAVE_FDOPENDIR - if (path->fd != -1) { + if (path->is_fd) { if (HAVE_FDOPENDIR_RUNTIME) { /* closedir() closes the FD, so we duplicate it */ fd = _Py_dup(path->fd); @@ -5898,7 +5900,7 @@ _testFileExists(path_t *path, BOOL followLinks) } Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) { + if (path->is_fd) { HANDLE hfile = _Py_get_osfhandle_noraise(path->fd); if (hfile != INVALID_HANDLE_VALUE) { if (GetFileType(hfile) != FILE_TYPE_UNKNOWN || !GetLastError()) { @@ -5924,7 +5926,7 @@ _testFileType(path_t *path, int testedType) } Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) { + if (path->is_fd) { HANDLE hfile = _Py_get_osfhandle_noraise(path->fd); if (hfile != INVALID_HANDLE_VALUE) { result = _testFileTypeByHandle(hfile, testedType, TRUE); @@ -7141,7 +7143,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, if (path_and_dir_fd_invalid("utime", path, dir_fd) || dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) + fd_and_follow_symlinks_invalid("utime", path->is_fd, follow_symlinks)) return NULL; #if !defined(HAVE_UTIMENSAT) @@ -7200,7 +7202,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, #endif #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) - if (path->fd != -1) + if (path->is_fd) result = utime_fd(&utime, path->fd); else #endif @@ -7569,7 +7571,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_FEXECVE - if (path->fd > -1) + if (path->is_fd) fexecve(path->fd, argvlist, envlist); else #endif @@ -13355,7 +13357,7 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) int fd; #endif - if (path->fd != -1) + if (path->is_fd) return os_ftruncate_impl(module, path->fd, length); if (PySys_Audit("os.truncate", "On", path->object, length) < 0) { @@ -14052,7 +14054,7 @@ os_statvfs_impl(PyObject *module, path_t *path) struct statfs st; Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) { + if (path->is_fd) { result = fstatfs(path->fd, &st); } else @@ -14070,7 +14072,7 @@ os_statvfs_impl(PyObject *module, path_t *path) Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FSTATVFS - if (path->fd != -1) { + if (path->is_fd) { result = fstatvfs(path->fd, &st); } else @@ -15410,7 +15412,7 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, int follow_symlinks) /*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/ { - if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) + if (fd_and_follow_symlinks_invalid("getxattr", path->is_fd, follow_symlinks)) return NULL; if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) { @@ -15432,7 +15434,7 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, void *ptr = PyBytesWriter_GetData(writer); Py_BEGIN_ALLOW_THREADS; - if (path->fd >= 0) + if (path->is_fd) result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size); else if (follow_symlinks) result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); @@ -15481,7 +15483,7 @@ os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, { ssize_t result; - if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) + if (fd_and_follow_symlinks_invalid("setxattr", path->is_fd, follow_symlinks)) return NULL; if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object, @@ -15490,7 +15492,7 @@ os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, } Py_BEGIN_ALLOW_THREADS; - if (path->fd > -1) + if (path->is_fd) result = fsetxattr(path->fd, attribute->narrow, value->buf, value->len, flags); else if (follow_symlinks) @@ -15534,7 +15536,7 @@ os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, { ssize_t result; - if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) + if (fd_and_follow_symlinks_invalid("removexattr", path->is_fd, follow_symlinks)) return NULL; if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) { @@ -15542,7 +15544,7 @@ os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, } Py_BEGIN_ALLOW_THREADS; - if (path->fd > -1) + if (path->is_fd) result = fremovexattr(path->fd, attribute->narrow); else if (follow_symlinks) result = removexattr(path->narrow, attribute->narrow); @@ -15584,7 +15586,7 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) const char *name; char *buffer = NULL; - if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) + if (fd_and_follow_symlinks_invalid("listxattr", path->is_fd, follow_symlinks)) goto exit; if (PySys_Audit("os.listxattr", "(O)", @@ -15611,7 +15613,7 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) } Py_BEGIN_ALLOW_THREADS; - if (path->fd > -1) + if (path->is_fd) length = flistxattr(path->fd, buffer, buffer_size); else if (follow_symlinks) length = listxattr(name, buffer, buffer_size); @@ -16664,7 +16666,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, entry->stat = NULL; entry->lstat = NULL; - if (path->fd != -1) { + if (path->is_fd) { entry->dir_fd = path->fd; joined_path = NULL; } @@ -16689,7 +16691,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, if (!entry->name) goto error; - if (path->fd != -1) { + if (path->is_fd) { entry->path = Py_NewRef(entry->name); } else if (!entry->path) @@ -16813,8 +16815,9 @@ ScandirIterator_closedir(ScandirIterator *iterator) iterator->dirp = NULL; Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FDOPENDIR - if (iterator->path.fd != -1) + if (iterator->path.is_fd) { rewinddir(dirp); + } #endif closedir(dirp); Py_END_ALLOW_THREADS @@ -17034,7 +17037,7 @@ os_scandir_impl(PyObject *module, path_t *path) #else /* POSIX */ errno = 0; #ifdef HAVE_FDOPENDIR - if (iterator->path.fd != -1) { + if (iterator->path.is_fd) { if (HAVE_FDOPENDIR_RUNTIME) { /* closedir() closes the FD, so we duplicate it */ fd = _Py_dup(iterator->path.fd); From 671a953dd65292a5b69ba7393666ddcac93dbc44 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:46:02 -0500 Subject: [PATCH 300/498] gh-144475: Fix reference management in partial_repr (GH-145362) --- Lib/test/test_functools.py | 52 ++++++++++++++++++ ...-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 3 + Modules/_functoolsmodule.c | 55 +++++++++++-------- 3 files changed, 86 insertions(+), 24 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 86652b7fa4d6df..dda42cb33072c3 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -514,6 +514,58 @@ def test_partial_genericalias(self): self.assertEqual(alias.__args__, (int,)) self.assertEqual(alias.__parameters__, ()) + # GH-144475: Tests that the partial object does not change until repr finishes + def test_repr_safety_against_reentrant_mutation(self): + g_partial = None + + class Function: + def __init__(self, name): + self.name = name + + def __call__(self): + return None + + def __repr__(self): + return f"Function({self.name})" + + class EvilObject: + def __init__(self): + self.triggered = False + + def __repr__(self): + if not self.triggered and g_partial is not None: + self.triggered = True + new_args_tuple = (None,) + new_keywords_dict = {"keyword": None} + new_tuple_state = (Function("new_function"), new_args_tuple, new_keywords_dict, None) + g_partial.__setstate__(new_tuple_state) + gc.collect() + return f"EvilObject" + + trigger = EvilObject() + func = Function("old_function") + + g_partial = functools.partial(func, None, trigger=trigger) + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), None, trigger=EvilObject)") + + trigger.triggered = False + g_partial = functools.partial(func, trigger, arg=None) + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), EvilObject, arg=None)") + + + trigger.triggered = False + g_partial = functools.partial(func, trigger, None) + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), EvilObject, None)") + + trigger.triggered = False + g_partial = functools.partial(func, trigger=trigger, arg=None) + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), trigger=EvilObject, arg=None)") + + trigger.triggered = False + g_partial = functools.partial(func, trigger, None, None, None, None, arg=None) + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), EvilObject, None, None, None, None, arg=None)") + + @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst new file mode 100644 index 00000000000000..b458399bb40640 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -0,0 +1,3 @@ +Calling :func:`repr` on :func:`functools.partial` is now safer +when the partial object's internal attributes are replaced while +the string representation is being generated. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 5773083ff68b46..5286be0b715fff 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -688,65 +688,72 @@ partial_repr(PyObject *self) { partialobject *pto = partialobject_CAST(self); PyObject *result = NULL; - PyObject *arglist; - PyObject *mod; - PyObject *name; + PyObject *arglist = NULL; + PyObject *mod = NULL; + PyObject *name = NULL; Py_ssize_t i, n; PyObject *key, *value; int status; status = Py_ReprEnter(self); if (status != 0) { - if (status < 0) + if (status < 0) { return NULL; + } return PyUnicode_FromString("..."); } + /* Reference arguments in case they change */ + PyObject *fn = Py_NewRef(pto->fn); + PyObject *args = Py_NewRef(pto->args); + PyObject *kw = Py_NewRef(pto->kw); + assert(PyTuple_Check(args)); + assert(PyDict_Check(kw)); arglist = Py_GetConstant(Py_CONSTANT_EMPTY_STR); - if (arglist == NULL) + if (arglist == NULL) { goto done; + } /* Pack positional arguments */ - assert(PyTuple_Check(pto->args)); - n = PyTuple_GET_SIZE(pto->args); + n = PyTuple_GET_SIZE(args); for (i = 0; i < n; i++) { Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, - PyTuple_GET_ITEM(pto->args, i))); - if (arglist == NULL) + PyTuple_GET_ITEM(args, i))); + if (arglist == NULL) { goto done; + } } /* Pack keyword arguments */ - assert (PyDict_Check(pto->kw)); - for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { + for (i = 0; PyDict_Next(kw, &i, &key, &value);) { /* Prevent key.__str__ from deleting the value. */ Py_INCREF(value); Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist, key, value)); Py_DECREF(value); - if (arglist == NULL) + if (arglist == NULL) { goto done; + } } mod = PyType_GetModuleName(Py_TYPE(pto)); if (mod == NULL) { - goto error; + goto done; } + name = PyType_GetQualName(Py_TYPE(pto)); if (name == NULL) { - Py_DECREF(mod); - goto error; + goto done; } - result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, pto->fn, arglist); - Py_DECREF(mod); - Py_DECREF(name); - Py_DECREF(arglist); - done: + result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, fn, arglist); +done: + Py_XDECREF(name); + Py_XDECREF(mod); + Py_XDECREF(arglist); + Py_DECREF(fn); + Py_DECREF(args); + Py_DECREF(kw); Py_ReprLeave(self); return result; - error: - Py_DECREF(arglist); - Py_ReprLeave(self); - return NULL; } /* Pickle strategy: From 246227392cacf4f31f933a671264f55897d93a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Tue, 3 Mar 2026 14:35:48 +0000 Subject: [PATCH 301/498] Add myself to initialization and import machinery codeowners (#145473) --- .github/CODEOWNERS | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 19cc7050a43f04..5bf60348f68250 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -260,33 +260,33 @@ Include/pyhash.h @gpshead @picnixz Python/pyhash.c @gpshead @picnixz # The import system (including importlib) -**/*import* @brettcannon @ericsnowcurrently @ncoghlan @warsaw -Python/import.c @brettcannon @ericsnowcurrently @ncoghlan @warsaw @kumaraditya303 +**/*import* @brettcannon @ericsnowcurrently @ncoghlan @warsaw @FFY00 +Python/import.c @brettcannon @ericsnowcurrently @ncoghlan @warsaw @FFY00 @kumaraditya303 **/*freeze* @ericsnowcurrently **/*frozen* @ericsnowcurrently **/*modsupport* @ericsnowcurrently -**/*modulefinder* @ericsnowcurrently +**/*modulefinder* @ericsnowcurrently @FFY00 **/*moduleobject* @ericsnowcurrently **/*multiphase* @ericsnowcurrently -**/*pkgutil* @ericsnowcurrently +**/*pkgutil* @ericsnowcurrently @FFY00 **/*pythonrun* @ericsnowcurrently -**/*runpy* @ericsnowcurrently +**/*runpy* @ericsnowcurrently @FFY00 **/*singlephase* @ericsnowcurrently Doc/c-api/module.rst @ericsnowcurrently Lib/test/test_module/ @ericsnowcurrently -Python/dynload_*.c @ericsnowcurrently +Python/dynload_*.c @ericsnowcurrently @FFY00 # Initialisation -**/*initconfig* @ericsnowcurrently -**/*pathconfig* @ericsnowcurrently -**/*preconfig* @ericsnowcurrently +**/*initconfig* @ericsnowcurrently @FFY00 +**/*pathconfig* @ericsnowcurrently @FFY00 +**/*preconfig* @ericsnowcurrently @FFY00 Doc/library/sys_path_init.rst @FFY00 Doc/c-api/init_config.rst @FFY00 # Interpreter main program -Modules/main.c @ericsnowcurrently -Programs/_bootstrap_python.c @ericsnowcurrently -Programs/python.c @ericsnowcurrently +Modules/main.c @ericsnowcurrently @FFY00 +Programs/_bootstrap_python.c @ericsnowcurrently @FFY00 +Programs/python.c @ericsnowcurrently @FFY00 # JIT .github/workflows/jit.yml @savannahostrowski @@ -316,8 +316,8 @@ Tools/peg_generator/ @pablogsal @lysnikolaou # Runtime state/lifecycle **/*gil* @ericsnowcurrently -**/*pylifecycle* @ericsnowcurrently @ZeroIntensity -**/*pystate* @ericsnowcurrently @ZeroIntensity +**/*pylifecycle* @ericsnowcurrently @ZeroIntensity @FFY00 +**/*pystate* @ericsnowcurrently @ZeroIntensity @FFY00 Include/internal/pycore_*_init.h @ericsnowcurrently Include/internal/pycore_*_state.h @ericsnowcurrently Include/internal/pycore_atexit.h @ericsnowcurrently @@ -505,13 +505,13 @@ Lib/idlelib/ @terryjreedy Lib/turtledemo/ @terryjreedy # importlib.metadata -Doc/library/importlib.metadata.rst @jaraco @warsaw -Lib/importlib/metadata/ @jaraco @warsaw -Lib/test/test_importlib/metadata/ @jaraco @warsaw +Doc/library/importlib.metadata.rst @jaraco @warsaw @FFY00 +Lib/importlib/metadata/ @jaraco @warsaw @FFY00 +Lib/test/test_importlib/metadata/ @jaraco @warsaw @FFY00 # importlib.resources -Doc/library/importlib.resources.abc.rst @jaraco @warsaw -Doc/library/importlib.resources.rst @jaraco @warsaw +Doc/library/importlib.resources.abc.rst @jaraco @warsaw @FFY00 +Doc/library/importlib.resources.rst @jaraco @warsaw @FFY00 Lib/importlib/resources/ @jaraco @warsaw @FFY00 Lib/test/test_importlib/resources/ @jaraco @warsaw @FFY00 From bd13cc09faaef01635aea85130f33aa8cbb8b177 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 3 Mar 2026 07:23:30 -0800 Subject: [PATCH 302/498] gh-145376: Fix various reference leaks (GH-145377) --- .../2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst | 1 + Modules/main.c | 1 + Python/crossinterp.c | 1 + Python/import.c | 1 + Python/pythonrun.c | 1 + Python/sysmodule.c | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst new file mode 100644 index 00000000000000..a5a6908757e458 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst @@ -0,0 +1 @@ +Fix reference leaks in various unusual error scenarios. diff --git a/Modules/main.c b/Modules/main.c index 74e48c94732565..95ba541d98c2e8 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -506,6 +506,7 @@ pymain_run_interactive_hook(int *exitcode) } if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) { + Py_DECREF(hook); goto error; } diff --git a/Python/crossinterp.c b/Python/crossinterp.c index 6365b995a0d3f7..c8a80e7a986008 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -609,6 +609,7 @@ check_missing___main___attr(PyObject *exc) // Get the error message. PyObject *args = PyException_GetArgs(exc); if (args == NULL || args == Py_None || PyObject_Size(args) < 1) { + Py_XDECREF(args); assert(!PyErr_Occurred()); return 0; } diff --git a/Python/import.c b/Python/import.c index dfc4d5707bfdba..3ed808f67f4149 100644 --- a/Python/import.c +++ b/Python/import.c @@ -5642,6 +5642,7 @@ _imp__set_lazy_attributes_impl(PyObject *module, PyObject *modobj, module_dict = get_mod_dict(modobj); if (module_dict == NULL || !PyDict_CheckExact(module_dict)) { + Py_DECREF(lazy_submodules); goto done; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ec8c2d12ab27fc..043bdf3433ab57 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1145,6 +1145,7 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) "traceback", "_print_exception_bltin"); if (print_exception_fn == NULL || !PyCallable_Check(print_exception_fn)) { + Py_XDECREF(print_exception_fn); goto fallback; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 28b2108940c853..55b4072213d3c2 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1762,7 +1762,7 @@ sys_getwindowsversion_impl(PyObject *module) PyObject *realVersion = _sys_getwindowsversion_from_kernel32(); if (!realVersion) { if (!PyErr_ExceptionMatches(PyExc_WindowsError)) { - return NULL; + goto error; } PyErr_Clear(); From 34df70c83c0055b204fcb10f7e63dbab6d7ecdbb Mon Sep 17 00:00:00 2001 From: Victorien <65306057+Viicos@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:05:14 +0000 Subject: [PATCH 303/498] Reference `memoryview.tolist` as a method (#145412) --- Doc/library/stdtypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 4451d485884987..76a4367dd2dcd5 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4536,7 +4536,7 @@ copying. types such as :class:`bytes` and :class:`bytearray`, an element is a single byte, but other types such as :class:`array.array` may have bigger elements. - ``len(view)`` is equal to the length of :class:`~memoryview.tolist`, which + ``len(view)`` is equal to the length of :meth:`~memoryview.tolist`, which is the nested list representation of the view. If ``view.ndim = 1``, this is equal to the number of elements in the view. From e6c3c04fab43057baf70b4f24b57a4679d646d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Tue, 3 Mar 2026 17:14:12 +0100 Subject: [PATCH 304/498] gh-145452: Initialize `PyLazyImport_Type` during interpreter startup (#145453) Co-authored-by: Victor Stinner --- Lib/test/test_lazy_import/__init__.py | 11 +++++++++++ Objects/object.c | 2 ++ 2 files changed, 13 insertions(+) diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 5d30ec2299789b..a4180f05dbbafc 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -12,6 +12,7 @@ import os from test import support +from test.support.script_helper import assert_python_ok try: import _testcapi @@ -219,6 +220,16 @@ def test_lazy_import_type_cant_construct(self): """LazyImportType should not be directly constructible.""" self.assertRaises(TypeError, types.LazyImportType, {}, "module") + @support.requires_subprocess() + def test_lazy_import_type_attributes_accessible(self): + """Check that static PyLazyImport_Type is initialized at startup.""" + code = textwrap.dedent(""" + lazy import json + print(globals()["json"].resolve) + """) + proc = assert_python_ok("-c", code) + self.assertIn(b" Date: Wed, 4 Mar 2026 02:48:03 +0800 Subject: [PATCH 305/498] gh-135883: Fix sqlite3 CLI history scrolling with colored prompts (#135884) --- Lib/sqlite3/__main__.py | 7 +++++-- Lib/test/test_sqlite3/test_cli.py | 12 ++++++++---- .../2025-06-24-19-07-18.gh-issue-135883.38cePA.rst | 2 ++ 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py index b3746ed757332f..8805442b69e080 100644 --- a/Lib/sqlite3/__main__.py +++ b/Lib/sqlite3/__main__.py @@ -133,8 +133,11 @@ def main(*args): theme = get_theme() s = theme.syntax - sys.ps1 = f"{s.prompt}sqlite> {s.reset}" - sys.ps2 = f"{s.prompt} ... {s.reset}" + # Use RL_PROMPT_START_IGNORE (\001) and RL_PROMPT_END_IGNORE (\002) to + # bracket non-printing characters. This tells readline to ignore them + # when calculating screen space for redisplay during history scrolling. + sys.ps1 = f"\001{s.prompt}\002sqlite> \001{s.reset}\002" + sys.ps2 = f"\001{s.prompt}\002 ... \001{s.reset}\002" con = sqlite3.connect(args.filename, isolation_level=None) try: diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py index 98aadaa829a969..1fc0236780fa8b 100644 --- a/Lib/test/test_sqlite3/test_cli.py +++ b/Lib/test/test_sqlite3/test_cli.py @@ -80,8 +80,8 @@ def test_cli_on_disk_db(self): @force_not_colorized_test_class class InteractiveSession(unittest.TestCase): MEMORY_DB_MSG = "Connected to a transient in-memory database" - PS1 = "sqlite> " - PS2 = "... " + PS1 = "\001\002sqlite> \001\002" + PS2 = "\001\002 ... \001\002" def run_cli(self, *args, commands=()): with ( @@ -202,8 +202,8 @@ def test_interact_on_disk_file(self): def test_color(self): with unittest.mock.patch("_colorize.can_colorize", return_value=True): out, err = self.run_cli(commands="TEXT\n") - self.assertIn("\x1b[1;35msqlite> \x1b[0m", out) - self.assertIn("\x1b[1;35m ... \x1b[0m\x1b", out) + self.assertIn("\x01\x1b[1;35m\x02sqlite> \x01\x1b[0m\x02", out) + self.assertIn("\x01\x1b[1;35m\x02 ... \x01\x1b[0m\x02\x01\x1b", out) out, err = self.run_cli(commands=("sel;",)) self.assertIn('\x1b[1;35mOperationalError (SQLITE_ERROR)\x1b[0m: ' '\x1b[35mnear "sel": syntax error\x1b[0m', err) @@ -212,6 +212,10 @@ def test_color(self): @requires_subprocess() @force_not_colorized_test_class class Completion(unittest.TestCase): + # run_pty() creates a real terminal environment, where sqlite3 CLI + # SqliteInteractiveConsole invokes GNU Readline for input. Readline's + # _rl_strip_prompt() strips \001 and \002 from the output, so test + # assertions use the plain prompt. PS1 = "sqlite> " @classmethod diff --git a/Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst b/Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst new file mode 100644 index 00000000000000..8f3efceaae1d91 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst @@ -0,0 +1,2 @@ +Fix :mod:`sqlite3`'s :ref:`interactive shell ` keeping part of +previous commands when scrolling history. From 15f6479c415cc6cd219cd25c1d94bab17d720cbc Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 3 Mar 2026 15:48:43 -0500 Subject: [PATCH 306/498] Docs: use a Sphinx extension to eliminate excessive links (#145130) --- Doc/conf.py | 1 + Doc/requirements.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Doc/conf.py b/Doc/conf.py index d7effe2572ec44..545049bb460419 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -43,6 +43,7 @@ # Skip if downstream redistributors haven't installed them _OPTIONAL_EXTENSIONS = ( + 'linklint.ext', 'notfound.extension', 'sphinxext.opengraph', ) diff --git a/Doc/requirements.txt b/Doc/requirements.txt index d0107744ecbe85..536ae57e4efc29 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -18,4 +18,6 @@ sphinx-notfound-page~=1.0.0 # to install that as well. python-docs-theme>=2023.3.1,!=2023.7 +linklint + -c constraints.txt From dc12d1999b88e84d5a6b8e491be468b73379e54b Mon Sep 17 00:00:00 2001 From: Justin Kunimune Date: Tue, 3 Mar 2026 16:41:26 -0500 Subject: [PATCH 307/498] Fix incorrect statement about argparse.ArgumentParser.add_argument() (#145479) Co-authored-by: Savannah Ostrowski --- Doc/library/argparse.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index ca4f439c345f32..8f31e815e0eb4b 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -739,9 +739,9 @@ By default, :mod:`!argparse` automatically handles the internal naming and display names of arguments, simplifying the process without requiring additional configuration. As such, you do not need to specify the dest_ and metavar_ parameters. -The dest_ parameter defaults to the argument name with underscores ``_`` -replacing hyphens ``-`` . The metavar_ parameter defaults to the -upper-cased name. For example:: +For optional arguments, the dest_ parameter defaults to the argument name, with +underscores ``_`` replacing hyphens ``-``. The metavar_ parameter defaults to +the upper-cased name. For example:: >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo-bar') From 31343cf2bc5f7209fa965558265555973323c2f9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 4 Mar 2026 11:00:08 +0100 Subject: [PATCH 308/498] gh-142417: Restore private _Py_InitializeMain() function (#145472) This reverts commit 07c3518ffb27875b14a0f1637aa85f773ff2f9ff. Co-authored-by: Petr Viktorin --- Doc/c-api/init_config.rst | 94 +++++++++++++++++-- Doc/whatsnew/3.15.rst | 4 + Include/cpython/pylifecycle.h | 3 + Lib/test/test_embed.py | 18 ++++ ...-03-03-14-59-57.gh-issue-142417.HiNP5j.rst | 2 + Programs/_testembed.c | 28 ++++++ Python/pylifecycle.c | 12 +++ 7 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index a143274bfe69e2..f6dc604a609cb1 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -2299,13 +2299,91 @@ Py_GetArgcArgv() See also :c:member:`PyConfig.orig_argv` member. -Delaying main module execution -============================== -In some embedding use cases, it may be desirable to separate interpreter initialization -from the execution of the main module. +Multi-Phase Initialization Private Provisional API +================================================== -This separation can be achieved by setting ``PyConfig.run_command`` to the empty -string during initialization (to prevent the interpreter from dropping into the -interactive prompt), and then subsequently executing the desired main module -code using ``__main__.__dict__`` as the global namespace. +This section is a private provisional API introducing multi-phase +initialization, the core feature of :pep:`432`: + +* "Core" initialization phase, "bare minimum Python": + + * Builtin types; + * Builtin exceptions; + * Builtin and frozen modules; + * The :mod:`sys` module is only partially initialized + (ex: :data:`sys.path` doesn't exist yet). + +* "Main" initialization phase, Python is fully initialized: + + * Install and configure :mod:`importlib`; + * Apply the :ref:`Path Configuration `; + * Install signal handlers; + * Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout` + and :data:`sys.path`); + * Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`; + * Import the :mod:`site` module; + * etc. + +Private provisional API: + +.. c:member:: int PyConfig._init_main + + If set to ``0``, :c:func:`Py_InitializeFromConfig` stops at the "Core" + initialization phase. + +.. c:function:: PyStatus _Py_InitializeMain(void) + + Move to the "Main" initialization phase, finish the Python initialization. + +No module is imported during the "Core" phase and the ``importlib`` module is +not configured: the :ref:`Path Configuration ` is only +applied during the "Main" phase. It may allow to customize Python in Python to +override or tune the :ref:`Path Configuration `, maybe +install a custom :data:`sys.meta_path` importer or an import hook, etc. + +It may become possible to calculate the :ref:`Path Configuration +` in Python, after the Core phase and before the Main phase, +which is one of the :pep:`432` motivation. + +The "Core" phase is not properly defined: what should be and what should +not be available at this phase is not specified yet. The API is marked +as private and provisional: the API can be modified or even be removed +anytime until a proper public API is designed. + +Example running Python code between "Core" and "Main" initialization +phases:: + + void init_python(void) + { + PyStatus status; + + PyConfig config; + PyConfig_InitPythonConfig(&config); + config._init_main = 0; + + /* ... customize 'config' configuration ... */ + + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + /* Use sys.stderr because sys.stdout is only created + by _Py_InitializeMain() */ + int res = PyRun_SimpleString( + "import sys; " + "print('Run Python code before _Py_InitializeMain', " + "file=sys.stderr)"); + if (res < 0) { + exit(1); + } + + /* ... put more configuration code here ... */ + + status = _Py_InitializeMain(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + } diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 63ef5f84301794..fff2168be72604 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1664,6 +1664,10 @@ New features * Add :c:func:`PyUnstable_SetImmortal` C-API function to mark objects as :term:`immortal`. (Contributed by Kumar Aditya in :gh:`143300`.) +* Restore private provisional ``_Py_InitializeMain()`` function removed in + Python 3.14. + (Contributed by Victor Stinner in :gh:`142417`.) + Changed C APIs -------------- diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 86ce6e6f79824a..e46dfe59ec4630 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -25,6 +25,9 @@ PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs( PyAPI_FUNC(PyStatus) Py_InitializeFromConfig( const PyConfig *config); +// Python 3.8 provisional API (PEP 587) +PyAPI_FUNC(PyStatus) _Py_InitializeMain(void); + PyAPI_FUNC(int) Py_RunMain(void); diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index b3f0cb5d35de5d..45d0d8308dbdea 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1319,6 +1319,24 @@ def test_init_run_main(self): } self.check_all_configs("test_init_run_main", config, api=API_PYTHON) + def test_init_main(self): + code = ('import _testinternalcapi, json; ' + 'print(json.dumps(_testinternalcapi.get_configs()))') + config = { + 'argv': ['-c', 'arg2'], + 'orig_argv': ['python3', + '-c', code, + 'arg2'], + 'program_name': './python3', + 'run_command': code + '\n', + 'parse_argv': True, + '_init_main': False, + 'sys_path_0': '', + } + self.check_all_configs("test_init_main", config, + api=API_PYTHON, + stderr="Run Python code before _Py_InitializeMain") + def test_init_parse_argv(self): config = { 'parse_argv': True, diff --git a/Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst b/Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst new file mode 100644 index 00000000000000..943be5b4533d9e --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst @@ -0,0 +1,2 @@ +Restore private provisional ``_Py_InitializeMain()`` function removed in +Python 3.14. Patch by Victor Stinner. diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 38f546b976cac3..d4d2a7131ccb1f 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1991,6 +1991,33 @@ static int test_init_run_main(void) } +static int test_init_main(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + configure_init_main(&config); + config._init_main = 0; + init_from_config_clear(&config); + + /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */ + int res = PyRun_SimpleString( + "import sys; " + "print('Run Python code before _Py_InitializeMain', " + "file=sys.stderr)"); + if (res < 0) { + exit(1); + } + + PyStatus status = _Py_InitializeMain(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + return Py_RunMain(); +} + + static int test_run_main(void) { PyConfig config; @@ -2649,6 +2676,7 @@ static struct TestCase TestCases[] = { {"test_preinit_parse_argv", test_preinit_parse_argv}, {"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv}, {"test_init_run_main", test_init_run_main}, + {"test_init_main", test_init_main}, {"test_init_sys_add", test_init_sys_add}, {"test_init_setpath", test_init_setpath}, {"test_init_setpath_config", test_init_setpath_config}, diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7dfeb5b847b254..711e7bc89b71c0 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1530,6 +1530,18 @@ Py_Initialize(void) } +PyStatus +_Py_InitializeMain(void) +{ + PyStatus status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + PyThreadState *tstate = _PyThreadState_GET(); + return pyinit_main(tstate); +} + + static void finalize_modules_delete_special(PyThreadState *tstate, int verbose) { From 45e9343d7eed1d9e784e731cc9af853fa8649e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 4 Mar 2026 13:59:50 +0100 Subject: [PATCH 309/498] GH-144739: Skip test_pyexpat.MemoryProtectionTest based on expat compile-time version, not runtime (#144740) --- Lib/test/test_pyexpat.py | 4 +++- .../next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 74a75458289b4d..31bcee293b2b69 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -1069,7 +1069,9 @@ def test_set_maximum_amplification__amplification_not_exceeded(self): self.assertIsNotNone(parser.Parse(payload, True)) -@unittest.skipIf(expat.version_info < (2, 7, 2), "requires Expat >= 2.7.2") +@unittest.skipIf(not hasattr(expat.XMLParserType, + "SetAllocTrackerMaximumAmplification"), + "requires Python compiled with Expat >= 2.7.2") class MemoryProtectionTest(AttackProtectionTestBase, unittest.TestCase): # NOTE: with the default Expat configuration, the billion laughs protection diff --git a/Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst b/Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst new file mode 100644 index 00000000000000..8c46ff133f9433 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst @@ -0,0 +1,3 @@ +When Python was compiled with system expat older then 2.7.2 but tests run +with newer expat, still skip +:class:`!test.test_pyexpat.MemoryProtectionTest`. From 3fe7849d9a50075901195602bb7143b93537289a Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 4 Mar 2026 14:21:10 +0100 Subject: [PATCH 310/498] gh-145376: Fix refleak in error path of time_tzset (GH-145477) --- Modules/timemodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 3946d18479e253..a3260e0f15ab99 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1170,7 +1170,8 @@ time_tzset(PyObject *self, PyObject *unused) /* Reset timezone, altzone, daylight and tzname */ if (init_timezone(m) < 0) { - return NULL; + Py_DECREF(m); + return NULL; } Py_DECREF(m); if (PyErr_Occurred()) From f9dac4e2ebbb913479bf882f0ac582040ba54ea3 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 4 Mar 2026 14:32:14 +0100 Subject: [PATCH 311/498] gh-145376: Avoid reference leaks in failure path of _functoolsmodule.c method partial_new (GH-145423) --- Modules/_functoolsmodule.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 5286be0b715fff..336a2e57ec0179 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -252,6 +252,11 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) } PyObject *item; PyObject *tot_args = PyTuple_New(tot_nargs); + if (tot_args == NULL) { + Py_DECREF(new_args); + Py_DECREF(pto); + return NULL; + } for (Py_ssize_t i = 0, j = 0; i < tot_nargs; i++) { if (i < npargs) { item = PyTuple_GET_ITEM(pto_args, i); From 18aec59fe5bbae9225951ca4d69bfca17eba82d8 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 4 Mar 2026 14:34:24 +0100 Subject: [PATCH 312/498] gh-145376: Fix refleak in unusual error path in BaseExceptionGroup_new (GH-145474) --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 499fb2b34b34a8..f5edc286243ee1 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -912,7 +912,7 @@ BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds) exceptions = PySequence_Tuple(exceptions); if (!exceptions) { - return NULL; + goto error; } /* We are now holding a ref to the exceptions tuple */ From a00392349c8cccdf2fe720fe46e504699f584f02 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 4 Mar 2026 18:29:02 +0100 Subject: [PATCH 313/498] gh-144741: Fix test_frame_pointer_unwind for libpython (#145499) Fix test_frame_pointer_unwind when Python is built with --enable-shared. Classify also libpython frames as "python". --- .../next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst | 3 +++ Modules/_testinternalcapi.c | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst diff --git a/Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst b/Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst new file mode 100644 index 00000000000000..be3092f1c2592a --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst @@ -0,0 +1,3 @@ +Fix ``test_frame_pointer_unwind`` when Python is built with +:option:`--enable-shared`. Classify also libpython frames as ``"python"``. +Patch by Victor Stinner. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 22cfa3f58a9d83..998bf5e592e8ee 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -196,6 +196,10 @@ classify_address(uintptr_t addr, int jit_enabled, PyInterpreterState *interp) if (strncmp(base, "python", 6) == 0) { return "python"; } + // Match "libpython3.15.so.1.0" + if (strncmp(base, "libpython", 9) == 0) { + return "python"; + } return "other"; } #ifdef _Py_JIT From 6cdbd7bc5d4ee63459d03a944477ea8671a05198 Mon Sep 17 00:00:00 2001 From: Itamar Oren Date: Wed, 4 Mar 2026 10:06:49 -0800 Subject: [PATCH 314/498] gh-122941: Fix test_launcher sporadic failures via py.ini isolation (GH-145090) Adds _PYLAUNCHER_INIDIR as a private variable since the launcher is deprecated and not getting new features. --- Lib/test/test_launcher.py | 17 ++++++++++++----- PC/launcher2.c | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index caa1603c78eb01..c522bc1c2c093c 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -227,6 +227,8 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non "PYLAUNCHER_LIMIT_TO_COMPANY": "", **{k.upper(): v for k, v in (env or {}).items()}, } + if ini_dir := getattr(self, '_ini_dir', None): + env.setdefault("_PYLAUNCHER_INIDIR", ini_dir) if not argv: argv = [self.py_exe, *args] with subprocess.Popen( @@ -262,11 +264,14 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=Non return data def py_ini(self, content): - local_appdata = os.environ.get("LOCALAPPDATA") - if not local_appdata: - raise unittest.SkipTest("LOCALAPPDATA environment variable is " - "missing or empty") - return PreservePyIni(Path(local_appdata) / "py.ini", content) + ini_dir = getattr(self, '_ini_dir', None) + if not ini_dir: + local_appdata = os.environ.get("LOCALAPPDATA") + if not local_appdata: + raise unittest.SkipTest("LOCALAPPDATA environment variable is " + "missing or empty") + ini_dir = local_appdata + return PreservePyIni(Path(ini_dir) / "py.ini", content) @contextlib.contextmanager def script(self, content, encoding="utf-8"): @@ -302,6 +307,8 @@ def setUpClass(cls): p = subprocess.check_output("reg query HKCU\\Software\\Python /s") #print(p.decode('mbcs')) + cls._ini_dir = tempfile.mkdtemp() + cls.addClassCleanup(shutil.rmtree, cls._ini_dir, ignore_errors=True) @classmethod def tearDownClass(cls): diff --git a/PC/launcher2.c b/PC/launcher2.c index 832935c5cc6c1c..4dd18c8eb5462e 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -922,6 +922,20 @@ _readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, in { wchar_t iniPath[MAXLEN]; int n; + // Check for _PYLAUNCHER_INIDIR override (used for test isolation) + DWORD len = GetEnvironmentVariableW(L"_PYLAUNCHER_INIDIR", iniPath, MAXLEN); + if (len && len < MAXLEN) { + if (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 n; + } + } + // When _PYLAUNCHER_INIDIR is set, skip the default locations + return 0; + } 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); From 8a7eb8b2ab2d9bf20f2fdc77177f735331fa9a72 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Wed, 4 Mar 2026 13:32:43 -0500 Subject: [PATCH 315/498] gh-145500: Delete _PyType_GetMRO (gh-145501) --- Include/internal/pycore_typeobject.h | 1 - Objects/typeobject.c | 22 ---------------------- 2 files changed, 23 deletions(-) diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 8af317d54c0bda..9c8b00550e3980 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -96,7 +96,6 @@ PyAPI_FUNC(PyObject *) _PyType_LookupSubclasses(PyTypeObject *); PyAPI_FUNC(PyObject *) _PyType_InitSubclasses(PyTypeObject *); extern PyObject * _PyType_GetBases(PyTypeObject *type); -extern PyObject * _PyType_GetMRO(PyTypeObject *type); extern PyObject* _PyType_GetSubclasses(PyTypeObject *); extern int _PyType_HasSubclasses(PyTypeObject *); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d77d981085f4da..c5e94a8668fef2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -651,28 +651,6 @@ lookup_tp_mro(PyTypeObject *self) return self->tp_mro; } -PyObject * -_PyType_GetMRO(PyTypeObject *self) -{ -#ifdef Py_GIL_DISABLED - PyObject *mro = _Py_atomic_load_ptr_relaxed(&self->tp_mro); - if (mro == NULL) { - return NULL; - } - if (_Py_TryIncrefCompare(&self->tp_mro, mro)) { - return mro; - } - - BEGIN_TYPE_LOCK(); - mro = lookup_tp_mro(self); - Py_XINCREF(mro); - END_TYPE_LOCK(); - return mro; -#else - return Py_XNewRef(lookup_tp_mro(self)); -#endif -} - static inline void set_tp_mro(PyTypeObject *self, PyObject *mro, int initial) { From 95f56b120623f17990be81379661de270e95e3c5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 4 Mar 2026 20:11:00 +0100 Subject: [PATCH 316/498] gh-141510: Return frozendict unmodified in PyDict_Copy() (#145505) Add also the internal _PyDict_CopyAsDict() function. --- Include/internal/pycore_dict.h | 2 ++ Lib/test/test_capi/test_dict.py | 16 +++++++---- Objects/dictobject.c | 50 +++++++++++++++++++++++---------- Objects/typeobject.c | 18 ++---------- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 59e88be6aeec12..1aeec32f55a7f3 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -160,6 +160,8 @@ extern void _PyDict_Clear_LockHeld(PyObject *op); PyAPI_FUNC(void) _PyDict_EnsureSharedOnRead(PyDictObject *mp); #endif +extern PyObject* _PyDict_CopyAsDict(PyObject *op); + #define DKIX_EMPTY (-1) #define DKIX_DUMMY (-2) /* Used internally */ #define DKIX_ERROR (-3) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index d9de9bb4c8125d..561e1ea4d52846 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -98,14 +98,18 @@ def test_dict_copy(self): # Test PyDict_Copy() copy = _testlimitedcapi.dict_copy for dict_type in ANYDICT_TYPES: - if issubclass(dict_type, frozendict): - expected_type = frozendict - else: - expected_type = dict dct = dict_type({1: 2}) dct_copy = copy(dct) - self.assertIs(type(dct_copy), expected_type) - self.assertEqual(dct_copy, dct) + if dict_type == frozendict: + expected_type = frozendict + self.assertIs(dct_copy, dct) + else: + if issubclass(dict_type, frozendict): + expected_type = frozendict + else: + expected_type = dict + self.assertIs(type(dct_copy), expected_type) + self.assertEqual(dct_copy, dct) for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: self.assertRaises(SystemError, copy, test_type()) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 5894fdb614ebdc..0f123c3c2bb994 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4235,9 +4235,6 @@ static PyObject * dict_copy_impl(PyDictObject *self) /*[clinic end generated code: output=ffb782cf970a5c39 input=73935f042b639de4]*/ { - if (PyFrozenDict_CheckExact(self)) { - return Py_NewRef(self); - } return PyDict_Copy((PyObject *)self); } @@ -4263,18 +4260,17 @@ copy_values(PyDictValues *values) } static PyObject * -copy_lock_held(PyObject *o) +copy_lock_held(PyObject *o, int as_frozendict) { PyObject *copy; PyDictObject *mp; - int frozendict = PyFrozenDict_Check(o); ASSERT_DICT_LOCKED(o); mp = (PyDictObject *)o; if (mp->ma_used == 0) { /* The dict is empty; just return a new dict. */ - if (frozendict) { + if (as_frozendict) { return PyFrozenDict_New(NULL); } else { @@ -4288,7 +4284,7 @@ copy_lock_held(PyObject *o) if (newvalues == NULL) { return PyErr_NoMemory(); } - if (frozendict) { + if (as_frozendict) { split_copy = (PyDictObject *)PyObject_GC_New(PyFrozenDictObject, &PyFrozenDict_Type); } @@ -4307,7 +4303,7 @@ copy_lock_held(PyObject *o) split_copy->ma_used = mp->ma_used; split_copy->_ma_watcher_tag = 0; dictkeys_incref(mp->ma_keys); - if (frozendict) { + if (as_frozendict) { PyFrozenDictObject *frozen = (PyFrozenDictObject *)split_copy; frozen->ma_hash = -1; } @@ -4318,7 +4314,7 @@ copy_lock_held(PyObject *o) if (Py_TYPE(mp)->tp_iter == dict_iter && mp->ma_values == NULL && (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3) && - !frozendict) + !as_frozendict) { /* Use fast-copy if: @@ -4350,7 +4346,7 @@ copy_lock_held(PyObject *o) return (PyObject *)new; } - if (frozendict) { + if (as_frozendict) { copy = PyFrozenDict_New(NULL); } else { @@ -4364,6 +4360,19 @@ copy_lock_held(PyObject *o) return NULL; } +// Similar to PyDict_Copy(), but copy also frozendict. +static PyObject * +_PyDict_Copy(PyObject *o) +{ + assert(PyAnyDict_Check(o)); + + PyObject *res; + Py_BEGIN_CRITICAL_SECTION(o); + res = copy_lock_held(o, PyFrozenDict_Check(o)); + Py_END_CRITICAL_SECTION(); + return res; +} + PyObject * PyDict_Copy(PyObject *o) { @@ -4372,11 +4381,22 @@ PyDict_Copy(PyObject *o) return NULL; } - PyObject *res; - Py_BEGIN_CRITICAL_SECTION(o); + if (PyFrozenDict_CheckExact(o)) { + return Py_NewRef(o); + } + + return _PyDict_Copy(o); +} - res = copy_lock_held(o); +// Similar to PyDict_Copy(), but return a dict if the argument is a frozendict. +PyObject* +_PyDict_CopyAsDict(PyObject *o) +{ + assert(PyAnyDict_Check(o)); + PyObject *res; + Py_BEGIN_CRITICAL_SECTION(o); + res = copy_lock_held(o, 0); Py_END_CRITICAL_SECTION(); return res; } @@ -4925,7 +4945,7 @@ dict_or(PyObject *self, PyObject *other) if (!PyAnyDict_Check(self) || !PyAnyDict_Check(other)) { Py_RETURN_NOTIMPLEMENTED; } - PyObject *new = PyDict_Copy(self); + PyObject *new = _PyDict_Copy(self); if (new == NULL) { return NULL; } @@ -6479,7 +6499,7 @@ dictitems_xor_lock_held(PyObject *d1, PyObject *d2) ASSERT_DICT_LOCKED(d1); ASSERT_DICT_LOCKED(d2); - PyObject *temp_dict = copy_lock_held(d1); + PyObject *temp_dict = copy_lock_held(d1, PyFrozenDict_Check(d1)); if (temp_dict == NULL) { return NULL; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c5e94a8668fef2..1fdd3cbdaaa639 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4850,21 +4850,9 @@ type_new_get_slots(type_new_ctx *ctx, PyObject *dict) static PyTypeObject* type_new_init(type_new_ctx *ctx) { - PyObject *dict; - if (PyFrozenDict_Check(ctx->orig_dict)) { - dict = PyDict_New(); - if (dict == NULL) { - goto error; - } - if (PyDict_Merge(dict, ctx->orig_dict, 1) < 0) { - goto error; - } - } - else { - dict = PyDict_Copy(ctx->orig_dict); - if (dict == NULL) { - goto error; - } + PyObject *dict = _PyDict_CopyAsDict(ctx->orig_dict); + if (dict == NULL) { + goto error; } if (type_new_get_slots(ctx, dict) < 0) { From 0a51113a4901502e1e14c892e4c31768a14faa60 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 4 Mar 2026 20:49:20 +0100 Subject: [PATCH 317/498] gh-141510: Optimize PyDict_Copy() for frozendict (#145509) Implement fast-path for frozendict in PyDict_Copy(). --- Objects/dictobject.c | 58 +++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 0f123c3c2bb994..2552216152f98d 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -896,24 +896,20 @@ free_values(PyDictValues *values, bool use_qsbr) PyMem_Free(values); } -/* Consumes a reference to the keys object */ -static PyObject * -new_dict(PyDictKeysObject *keys, PyDictValues *values, - Py_ssize_t used, int free_values_on_failure) +static inline PyObject * +new_dict_impl(PyDictObject *mp, PyDictKeysObject *keys, + PyDictValues *values, Py_ssize_t used, + int free_values_on_failure) { assert(keys != NULL); - PyDictObject *mp = _Py_FREELIST_POP(PyDictObject, dicts); if (mp == NULL) { - mp = PyObject_GC_New(PyDictObject, &PyDict_Type); - if (mp == NULL) { - dictkeys_decref(keys, false); - if (free_values_on_failure) { - free_values(values, false); - } - return NULL; + dictkeys_decref(keys, false); + if (free_values_on_failure) { + free_values(values, false); } + return NULL; } - assert(Py_IS_TYPE(mp, &PyDict_Type)); + mp->ma_keys = keys; mp->ma_values = values; mp->ma_used = used; @@ -923,6 +919,29 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, return (PyObject *)mp; } +/* Consumes a reference to the keys object */ +static PyObject * +new_dict(PyDictKeysObject *keys, PyDictValues *values, + Py_ssize_t used, int free_values_on_failure) +{ + PyDictObject *mp = _Py_FREELIST_POP(PyDictObject, dicts); + if (mp == NULL) { + mp = PyObject_GC_New(PyDictObject, &PyDict_Type); + } + assert(mp == NULL || Py_IS_TYPE(mp, &PyDict_Type)); + + return new_dict_impl(mp, keys, values, used, free_values_on_failure); +} + +/* Consumes a reference to the keys object */ +static PyObject * +new_frozendict(PyDictKeysObject *keys, PyDictValues *values, + Py_ssize_t used, int free_values_on_failure) +{ + PyDictObject *mp = PyObject_GC_New(PyDictObject, &PyFrozenDict_Type); + return new_dict_impl(mp, keys, values, used, free_values_on_failure); +} + static PyObject * new_dict_with_shared_keys(PyDictKeysObject *keys) { @@ -4313,8 +4332,7 @@ copy_lock_held(PyObject *o, int as_frozendict) if (Py_TYPE(mp)->tp_iter == dict_iter && mp->ma_values == NULL && - (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3) && - !as_frozendict) + (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3)) { /* Use fast-copy if: @@ -4334,9 +4352,15 @@ copy_lock_held(PyObject *o, int as_frozendict) if (keys == NULL) { return NULL; } - PyDictObject *new = (PyDictObject *)new_dict(keys, NULL, 0, 0); + PyDictObject *new; + if (as_frozendict) { + new = (PyDictObject *)new_frozendict(keys, NULL, 0, 0); + } + else { + new = (PyDictObject *)new_dict(keys, NULL, 0, 0); + } if (new == NULL) { - /* In case of an error, `new_dict()` takes care of + /* In case of an error, new_dict()/new_frozendict() takes care of cleaning up `keys`. */ return NULL; } From a51b1b512de1d56b3714b65628a2eae2b07e535e Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 4 Mar 2026 19:55:52 +0000 Subject: [PATCH 318/498] gh-145506: Fixes CVE-2026-2297 by ensuring SourcelessFileLoader uses io.open_code (GH-145507) --- Lib/importlib/_bootstrap_external.py | 2 +- .../Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 213190d2098e75..a1cb729efb7fef 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -918,7 +918,7 @@ def get_filename(self, fullname): def get_data(self, path): """Return the data from path as raw bytes.""" - if isinstance(self, (SourceLoader, ExtensionFileLoader)): + if isinstance(self, (SourceLoader, SourcelessFileLoader, ExtensionFileLoader)): with _io.open_code(str(path)) as file: return file.read() else: diff --git a/Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst b/Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst new file mode 100644 index 00000000000000..dcdb44d4fae4e5 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst @@ -0,0 +1,2 @@ +Fixes :cve:`2026-2297` by ensuring that ``SourcelessFileLoader`` uses +:func:`io.open_code` when opening ``.pyc`` files. From ae208d5665453aca414d87fb1894bf0bbb677003 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 4 Mar 2026 20:43:44 +0000 Subject: [PATCH 319/498] Fix bugs in `compute-changes.py` logic for CIFuzz (#145232) --- Lib/test/test_tools/test_compute_changes.py | 24 +++++++++++---------- Tools/build/compute-changes.py | 8 ++++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_tools/test_compute_changes.py b/Lib/test/test_tools/test_compute_changes.py index b20ff975fc2834..c4e3ffdb4de6cf 100644 --- a/Lib/test/test_tools/test_compute_changes.py +++ b/Lib/test/test_tools/test_compute_changes.py @@ -6,7 +6,8 @@ from pathlib import Path from unittest.mock import patch -from test.test_tools import skip_if_missing, imports_under_tool +from test.support import os_helper +from test.test_tools import basepath, skip_if_missing, imports_under_tool skip_if_missing("build") @@ -15,6 +16,7 @@ compute_changes = importlib.import_module("compute-changes") process_changed_files = compute_changes.process_changed_files +is_fuzzable_library_file = compute_changes.is_fuzzable_library_file Outputs = compute_changes.Outputs ANDROID_DIRS = compute_changes.ANDROID_DIRS IOS_DIRS = compute_changes.IOS_DIRS @@ -45,16 +47,16 @@ def test_docs(self): self.assertFalse(result.run_tests) def test_ci_fuzz_stdlib(self): - for p in LIBRARY_FUZZER_PATHS: - with self.subTest(p=p): - if p.is_dir(): - f = p / "file" - elif p.is_file(): - f = p - else: - continue - result = process_changed_files({f}) - self.assertTrue(result.run_ci_fuzz_stdlib) + with os_helper.change_cwd(basepath): + for p in LIBRARY_FUZZER_PATHS: + with self.subTest(p=p): + if p.is_dir(): + f = p / "file" + elif p.is_file(): + f = p + result = process_changed_files({f}) + self.assertTrue(result.run_ci_fuzz_stdlib) + self.assertTrue(is_fuzzable_library_file(f)) def test_android(self): for d in ANDROID_DIRS: diff --git a/Tools/build/compute-changes.py b/Tools/build/compute-changes.py index 67d2b060969660..981e00e28b42a7 100644 --- a/Tools/build/compute-changes.py +++ b/Tools/build/compute-changes.py @@ -68,7 +68,8 @@ Path("Lib/encodings/"), Path("Modules/_codecsmodule.c"), Path("Modules/cjkcodecs/"), - Path("Modules/unicodedata*"), + Path("Modules/unicodedata.c"), + Path("Modules/unicodedata_db.h"), # difflib Path("Lib/difflib.py"), # email @@ -116,10 +117,10 @@ class Outputs: def compute_changes() -> None: - target_branch, head_ref = git_refs() + target_ref, head_ref = git_refs() if os.environ.get("GITHUB_EVENT_NAME", "") == "pull_request": # Getting changed files only makes sense on a pull request - files = get_changed_files(target_branch, head_ref) + files = get_changed_files(target_ref, head_ref) outputs = process_changed_files(files) else: # Otherwise, just run the tests @@ -132,6 +133,7 @@ def compute_changes() -> None: run_wasi=True, run_windows_tests=True, ) + target_branch = target_ref.removeprefix("origin/") outputs = process_target_branch(outputs, target_branch) if outputs.run_tests: From b63dc8abdf7b985bb23d212862baf29736888394 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 4 Mar 2026 13:27:23 -0800 Subject: [PATCH 320/498] Refactor `Platforms/WASI/__main__.py` for lazy importing and future new subcommands (#145404) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .pre-commit-config.yaml | 8 + Platforms/WASI/.ruff.toml | 2 + Platforms/WASI/__main__.py | 463 ++++--------------------------------- Platforms/WASI/_build.py | 413 +++++++++++++++++++++++++++++++++ 4 files changed, 462 insertions(+), 424 deletions(-) create mode 100644 Platforms/WASI/_build.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1dcb50e31d9a68..4893ec28f23e5a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,10 @@ repos: name: Run Ruff (lint) on Lib/test/ args: [--exit-non-zero-on-fix] files: ^Lib/test/ + - id: ruff-check + name: Run Ruff (lint) on Platforms/WASI/ + args: [--exit-non-zero-on-fix, --config=Platforms/WASI/.ruff.toml] + files: ^Platforms/WASI/ - id: ruff-check name: Run Ruff (lint) on Tools/build/ args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml] @@ -42,6 +46,10 @@ repos: name: Run Ruff (format) on Doc/ args: [--exit-non-zero-on-fix] files: ^Doc/ + - id: ruff-format + name: Run Ruff (format) on Platforms/WASI/ + args: [--exit-non-zero-on-fix, --config=Platforms/WASI/.ruff.toml] + files: ^Platforms/WASI/ - id: ruff-format name: Run Ruff (format) on Tools/build/check_warnings.py args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml] diff --git a/Platforms/WASI/.ruff.toml b/Platforms/WASI/.ruff.toml index 3d8e59fa3f22c4..492713c1520000 100644 --- a/Platforms/WASI/.ruff.toml +++ b/Platforms/WASI/.ruff.toml @@ -1,5 +1,7 @@ extend = "../../.ruff.toml" # Inherit the project-wide settings +target-version = "py314" + [format] preview = true docstring-code-format = true diff --git a/Platforms/WASI/__main__.py b/Platforms/WASI/__main__.py index 471ac3297b2702..b8513a004f18e5 100644 --- a/Platforms/WASI/__main__.py +++ b/Platforms/WASI/__main__.py @@ -1,417 +1,23 @@ #!/usr/bin/env python3 +__lazy_modules__ = ["_build"] + import argparse -import contextlib -import functools import os - -import tomllib - -try: - from os import process_cpu_count as cpu_count -except ImportError: - from os import cpu_count import pathlib -import shutil -import subprocess -import sys -import sysconfig -import tempfile - -CHECKOUT = HERE = pathlib.Path(__file__).parent - -while CHECKOUT != CHECKOUT.parent: - if (CHECKOUT / "configure").is_file(): - break - CHECKOUT = CHECKOUT.parent -else: - raise FileNotFoundError( - "Unable to find the root of the CPython checkout by looking for 'configure'" - ) - -CROSS_BUILD_DIR = CHECKOUT / "cross-build" -# Build platform can also be found via `config.guess`. -BUILD_DIR = CROSS_BUILD_DIR / sysconfig.get_config_var("BUILD_GNU_TYPE") - -LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local" -LOCAL_SETUP_MARKER = ( - b"# Generated by Platforms/WASI .\n" - b"# Required to statically build extension modules." -) - -WASI_SDK_VERSION = 29 - -WASMTIME_VAR_NAME = "WASMTIME" -WASMTIME_HOST_RUNNER_VAR = f"{{{WASMTIME_VAR_NAME}}}" - - -def separator(): - """Print a separator line across the terminal width.""" - try: - tput_output = subprocess.check_output( - ["tput", "cols"], encoding="utf-8" - ) - except subprocess.CalledProcessError: - terminal_width = 80 - else: - terminal_width = int(tput_output.strip()) - print("⎯" * terminal_width) - - -def log(emoji, message, *, spacing=None): - """Print a notification with an emoji. - - If 'spacing' is None, calculate the spacing based on the number of code points - in the emoji as terminals "eat" a space when the emoji has multiple code points. - """ - if spacing is None: - spacing = " " if len(emoji) == 1 else " " - print("".join([emoji, spacing, message])) - - -def updated_env(updates={}): - """Create a new dict representing the environment to use. - - The changes made to the execution environment are printed out. - """ - env_defaults = {} - # https://reproducible-builds.org/docs/source-date-epoch/ - git_epoch_cmd = ["git", "log", "-1", "--pretty=%ct"] - try: - epoch = subprocess.check_output( - git_epoch_cmd, encoding="utf-8" - ).strip() - env_defaults["SOURCE_DATE_EPOCH"] = epoch - except subprocess.CalledProcessError: - pass # Might be building from a tarball. - # This layering lets SOURCE_DATE_EPOCH from os.environ takes precedence. - environment = env_defaults | os.environ | updates - - env_diff = {} - for key, value in environment.items(): - if os.environ.get(key) != value: - env_diff[key] = value - - env_vars = ( - f"\n {key}={item}" for key, item in sorted(env_diff.items()) - ) - log("🌎", f"Environment changes:{''.join(env_vars)}") - - return environment - - -def subdir(working_dir, *, clean_ok=False): - """Decorator to change to a working directory.""" - - def decorator(func): - @functools.wraps(func) - def wrapper(context): - nonlocal working_dir - - if callable(working_dir): - working_dir = working_dir(context) - separator() - log("📁", os.fsdecode(working_dir)) - if ( - clean_ok - and getattr(context, "clean", False) - and working_dir.exists() - ): - log("🚮", "Deleting directory (--clean)...") - shutil.rmtree(working_dir) - - working_dir.mkdir(parents=True, exist_ok=True) - - with contextlib.chdir(working_dir): - return func(context, working_dir) - - return wrapper - - return decorator - - -def call(command, *, context=None, quiet=False, logdir=None, **kwargs): - """Execute a command. - - If 'quiet' is true, then redirect stdout and stderr to a temporary file. - """ - if context is not None: - quiet = context.quiet - logdir = context.logdir - elif quiet and logdir is None: - raise ValueError("When quiet is True, logdir must be specified") - - log("❯", " ".join(map(str, command)), spacing=" ") - if not quiet: - stdout = None - stderr = None - else: - stdout = tempfile.NamedTemporaryFile( - "w", - encoding="utf-8", - delete=False, - dir=logdir, - prefix="cpython-wasi-", - suffix=".log", - ) - stderr = subprocess.STDOUT - log("📝", f"Logging output to {stdout.name} (--quiet)...") - - subprocess.check_call(command, **kwargs, stdout=stdout, stderr=stderr) - - -def build_python_path(): - """The path to the build Python binary.""" - binary = BUILD_DIR / "python" - if not binary.is_file(): - binary = binary.with_suffix(".exe") - if not binary.is_file(): - raise FileNotFoundError( - f"Unable to find `python(.exe)` in {BUILD_DIR}" - ) - - return binary - - -def build_python_is_pydebug(): - """Find out if the build Python is a pydebug build.""" - test = "import sys, test.support; sys.exit(test.support.Py_DEBUG)" - result = subprocess.run( - [build_python_path(), "-c", test], - capture_output=True, - ) - return bool(result.returncode) +import _build -@subdir(BUILD_DIR, clean_ok=True) -def configure_build_python(context, working_dir): - """Configure the build/host Python.""" - if LOCAL_SETUP.exists(): - if LOCAL_SETUP.read_bytes() == LOCAL_SETUP_MARKER: - log("👍", f"{LOCAL_SETUP} exists ...") - else: - log("⚠️", f"{LOCAL_SETUP} exists, but has unexpected contents") - else: - log("📝", f"Creating {LOCAL_SETUP} ...") - LOCAL_SETUP.write_bytes(LOCAL_SETUP_MARKER) - - configure = [os.path.relpath(CHECKOUT / "configure", working_dir)] - if context.args: - configure.extend(context.args) - - call(configure, context=context) - - -@subdir(BUILD_DIR) -def make_build_python(context, working_dir): - """Make/build the build Python.""" - call(["make", "--jobs", str(cpu_count()), "all"], context=context) - - binary = build_python_path() - cmd = [ - binary, - "-c", - "import sys; " - "print(f'{sys.version_info.major}.{sys.version_info.minor}')", - ] - version = subprocess.check_output(cmd, encoding="utf-8").strip() - - log("🎉", f"{binary} {version}") - - -def find_wasi_sdk(config): - """Find the path to the WASI SDK.""" - wasi_sdk_path = None - wasi_sdk_version = config["targets"]["wasi-sdk"] - - if wasi_sdk_path_env_var := os.environ.get("WASI_SDK_PATH"): - wasi_sdk_path = pathlib.Path(wasi_sdk_path_env_var) - else: - opt_path = pathlib.Path("/opt") - # WASI SDK versions have a ``.0`` suffix, but it's a constant; the WASI SDK team - # has said they don't plan to ever do a point release and all of their Git tags - # lack the ``.0`` suffix. - # Starting with WASI SDK 23, the tarballs went from containing a directory named - # ``wasi-sdk-{WASI_SDK_VERSION}.0`` to e.g. - # ``wasi-sdk-{WASI_SDK_VERSION}.0-x86_64-linux``. - potential_sdks = [ - path - for path in opt_path.glob(f"wasi-sdk-{wasi_sdk_version}.0*") - if path.is_dir() - ] - if len(potential_sdks) == 1: - wasi_sdk_path = potential_sdks[0] - elif (default_path := opt_path / "wasi-sdk").is_dir(): - wasi_sdk_path = default_path - - # Starting with WASI SDK 25, a VERSION file is included in the root - # of the SDK directory that we can read to warn folks when they are using - # an unsupported version. - if wasi_sdk_path and (version_file := wasi_sdk_path / "VERSION").is_file(): - version_details = version_file.read_text(encoding="utf-8") - found_version = version_details.splitlines()[0] - # Make sure there's a trailing dot to avoid false positives if somehow the - # supported version is a prefix of the found version (e.g. `25` and `2567`). - if not found_version.startswith(f"{wasi_sdk_version}."): - major_version = found_version.partition(".")[0] - log( - "⚠️", - f" Found WASI SDK {major_version}, " - f"but WASI SDK {wasi_sdk_version} is the supported version", - ) - - return wasi_sdk_path - - -def wasi_sdk_env(context): - """Calculate environment variables for building with wasi-sdk.""" - wasi_sdk_path = context.wasi_sdk_path - sysroot = wasi_sdk_path / "share" / "wasi-sysroot" - env = { - "CC": "clang", - "CPP": "clang-cpp", - "CXX": "clang++", - "AR": "llvm-ar", - "RANLIB": "ranlib", - } - - for env_var, binary_name in list(env.items()): - env[env_var] = os.fsdecode(wasi_sdk_path / "bin" / binary_name) - - if not wasi_sdk_path.name.startswith("wasi-sdk"): - for compiler in ["CC", "CPP", "CXX"]: - env[compiler] += f" --sysroot={sysroot}" - - env["PKG_CONFIG_PATH"] = "" - env["PKG_CONFIG_LIBDIR"] = os.pathsep.join( - map( - os.fsdecode, - [sysroot / "lib" / "pkgconfig", sysroot / "share" / "pkgconfig"], - ) - ) - env["PKG_CONFIG_SYSROOT_DIR"] = os.fsdecode(sysroot) - - env["WASI_SDK_PATH"] = os.fsdecode(wasi_sdk_path) - env["WASI_SYSROOT"] = os.fsdecode(sysroot) - - env["PATH"] = os.pathsep.join([ - os.fsdecode(wasi_sdk_path / "bin"), - os.environ["PATH"], - ]) - - return env - - -@subdir(lambda context: CROSS_BUILD_DIR / context.host_triple, clean_ok=True) -def configure_wasi_python(context, working_dir): - """Configure the WASI/host build.""" - if not context.wasi_sdk_path or not context.wasi_sdk_path.exists(): - raise ValueError( - "WASI-SDK not found; " - "download from " - "https://github.com/WebAssembly/wasi-sdk and/or " - "specify via $WASI_SDK_PATH or --wasi-sdk" - ) - - config_site = os.fsdecode(HERE / "config.site-wasm32-wasi") - - wasi_build_dir = working_dir.relative_to(CHECKOUT) - - args = { - "ARGV0": f"/{wasi_build_dir}/python.wasm", - "PYTHON_WASM": working_dir / "python.wasm", - } - # Check dynamically for wasmtime in case it was specified manually via - # `--host-runner`. - if WASMTIME_HOST_RUNNER_VAR in context.host_runner: - if wasmtime := shutil.which("wasmtime"): - args[WASMTIME_VAR_NAME] = wasmtime - else: - raise FileNotFoundError( - "wasmtime not found; download from " - "https://github.com/bytecodealliance/wasmtime" - ) - host_runner = context.host_runner.format_map(args) - env_additions = {"CONFIG_SITE": config_site, "HOSTRUNNER": host_runner} - build_python = os.fsdecode(build_python_path()) - # The path to `configure` MUST be relative, else `python.wasm` is unable - # to find the stdlib due to Python not recognizing that it's being - # executed from within a checkout. - configure = [ - os.path.relpath(CHECKOUT / "configure", working_dir), - f"--host={context.host_triple}", - f"--build={BUILD_DIR.name}", - f"--with-build-python={build_python}", - ] - if build_python_is_pydebug(): - configure.append("--with-pydebug") - if context.args: - configure.extend(context.args) - call( - configure, - env=updated_env(env_additions | wasi_sdk_env(context)), - context=context, - ) - - python_wasm = working_dir / "python.wasm" - exec_script = working_dir / "python.sh" - with exec_script.open("w", encoding="utf-8") as file: - file.write(f'#!/bin/sh\nexec {host_runner} {python_wasm} "$@"\n') - exec_script.chmod(0o755) - log("🏃", f"Created {exec_script} (--host-runner)... ") - sys.stdout.flush() - - -@subdir(lambda context: CROSS_BUILD_DIR / context.host_triple) -def make_wasi_python(context, working_dir): - """Run `make` for the WASI/host build.""" - call( - ["make", "--jobs", str(cpu_count()), "all"], - env=updated_env(), - context=context, - ) - - exec_script = working_dir / "python.sh" - call([exec_script, "--version"], quiet=False) - log( - "🎉", - f"Use `{exec_script.relative_to(context.init_dir)}` " - "to run CPython w/ the WASI host specified by --host-runner", - ) - - -def clean_contents(context): - """Delete all files created by this script.""" - if CROSS_BUILD_DIR.exists(): - log("🧹", f"Deleting {CROSS_BUILD_DIR} ...") - shutil.rmtree(CROSS_BUILD_DIR) - - if LOCAL_SETUP.exists(): - if LOCAL_SETUP.read_bytes() == LOCAL_SETUP_MARKER: - log("🧹", f"Deleting generated {LOCAL_SETUP} ...") - - -def build_steps(*steps): - """Construct a command from other steps.""" - - def builder(context): - for step in steps: - step(context) - - return builder +HERE = pathlib.Path(__file__).parent def main(): - with (HERE / "config.toml").open("rb") as file: - config = tomllib.load(file) - default_wasi_sdk = find_wasi_sdk(config) - default_host_triple = config["targets"]["host-triple"] default_host_runner = ( - f"{WASMTIME_HOST_RUNNER_VAR} run " - # Set argv0 so that getpath.py can auto-discover the sysconfig data directory + "{WASMTIME} run " + # Set argv0 so that getpath.py can auto-discover the sysconfig data directory. "--argv0 {ARGV0} " # Map the checkout to / to load the stdlib from /Lib. - f"--dir {os.fsdecode(CHECKOUT)}::/ " + "--dir {CHECKOUT}::/ " # Flags involving --optimize, --codegen, --debug, --wasm, and --wasi can be kept # in a config file. # We are using such a file to act as defaults in case a user wants to override @@ -419,9 +25,8 @@ def main(): # post-build so that they immediately apply to the Makefile instead of having to # regenerate it, and allow for easy copying of the settings for anyone else who # may want to use them. - f"--config {os.fsdecode(HERE / 'wasmtime.toml')}" + "--config {WASMTIME_CONFIG_PATH}" ) - default_logdir = pathlib.Path(tempfile.gettempdir()) parser = argparse.ArgumentParser() subcommands = parser.add_subparsers(dest="subcommand") @@ -470,8 +75,8 @@ def main(): subcommand.add_argument( "--logdir", type=pathlib.Path, - default=default_logdir, - help=f"Directory to store log files; defaults to {default_logdir}", + default=None, + help="Directory to store log files", ) for subcommand in ( configure_build, @@ -501,8 +106,9 @@ def main(): "--wasi-sdk", type=pathlib.Path, dest="wasi_sdk_path", - default=default_wasi_sdk, - help=f"Path to the WASI SDK; defaults to {default_wasi_sdk}", + default=None, + help="Path to the WASI SDK; defaults to WASI_SDK_PATH environment variable " + "or the appropriate version found in /opt", ) subcommand.add_argument( "--host-runner", @@ -516,28 +122,37 @@ def main(): subcommand.add_argument( "--host-triple", action="store", - default=default_host_triple, + default=None, help="The target triple for the WASI host build; " - f"defaults to {default_host_triple}", + f"defaults to the value found in {os.fsdecode(HERE / 'config.toml')}", ) context = parser.parse_args() - context.init_dir = pathlib.Path().absolute() - - build_build_python = build_steps(configure_build_python, make_build_python) - build_wasi_python = build_steps(configure_wasi_python, make_wasi_python) - dispatch = { - "configure-build-python": configure_build_python, - "make-build-python": make_build_python, - "build-python": build_build_python, - "configure-host": configure_wasi_python, - "make-host": make_wasi_python, - "build-host": build_wasi_python, - "build": build_steps(build_build_python, build_wasi_python), - "clean": clean_contents, - } - dispatch[context.subcommand](context) + match context.subcommand: + case "configure-build-python": + _build.configure_build_python(context) + case "make-build-python": + _build.make_build_python(context) + case "build-python": + _build.configure_build_python(context) + _build.make_build_python(context) + case "configure-host": + _build.configure_wasi_python(context) + case "make-host": + _build.make_wasi_python(context) + case "build-host": + _build.configure_wasi_python(context) + _build.make_wasi_python(context) + case "build": + _build.configure_build_python(context) + _build.make_build_python(context) + _build.configure_wasi_python(context) + _build.make_wasi_python(context) + case "clean": + _build.clean_contents(context) + case _: + raise ValueError(f"Unknown subcommand {context.subcommand!r}") if __name__ == "__main__": diff --git a/Platforms/WASI/_build.py b/Platforms/WASI/_build.py new file mode 100644 index 00000000000000..76d2853163baa9 --- /dev/null +++ b/Platforms/WASI/_build.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python3 + +__lazy_modules__ = ["shutil", "sys", "tempfile", "tomllib"] + +import contextlib +import functools +import os +import pathlib +import shutil +import subprocess +import sys +import sysconfig +import tempfile +import tomllib + +try: + from os import process_cpu_count as cpu_count +except ImportError: + from os import cpu_count + + +CHECKOUT = HERE = pathlib.Path(__file__).parent + +while CHECKOUT != CHECKOUT.parent: + if (CHECKOUT / "configure").is_file(): + break + CHECKOUT = CHECKOUT.parent +else: + raise FileNotFoundError( + "Unable to find the root of the CPython checkout by looking for 'configure'" + ) + +CROSS_BUILD_DIR = CHECKOUT / "cross-build" +# Build platform can also be found via `config.guess`. +BUILD_DIR = CROSS_BUILD_DIR / sysconfig.get_config_var("BUILD_GNU_TYPE") + +LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local" +LOCAL_SETUP_MARKER = ( + b"# Generated by Platforms/WASI .\n" + b"# Required to statically build extension modules." +) + +WASMTIME_VAR_NAME = "WASMTIME" +WASMTIME_HOST_RUNNER_VAR = f"{{{WASMTIME_VAR_NAME}}}" + + +def separator(): + """Print a separator line across the terminal width.""" + try: + tput_output = subprocess.check_output( + ["tput", "cols"], encoding="utf-8" + ) + except subprocess.CalledProcessError: + terminal_width = 80 + else: + terminal_width = int(tput_output.strip()) + print("⎯" * terminal_width) + + +def log(emoji, message, *, spacing=None): + """Print a notification with an emoji. + + If 'spacing' is None, calculate the spacing based on the number of code points + in the emoji as terminals "eat" a space when the emoji has multiple code points. + """ + if spacing is None: + spacing = " " if len(emoji) == 1 else " " + print("".join([emoji, spacing, message])) + + +def updated_env(updates={}): + """Create a new dict representing the environment to use. + + The changes made to the execution environment are printed out. + """ + env_defaults = {} + # https://reproducible-builds.org/docs/source-date-epoch/ + git_epoch_cmd = ["git", "log", "-1", "--pretty=%ct"] + try: + epoch = subprocess.check_output( + git_epoch_cmd, encoding="utf-8" + ).strip() + env_defaults["SOURCE_DATE_EPOCH"] = epoch + except subprocess.CalledProcessError: + pass # Might be building from a tarball. + # This layering lets SOURCE_DATE_EPOCH from os.environ takes precedence. + environment = env_defaults | os.environ | updates + + env_diff = {} + for key, value in environment.items(): + if os.environ.get(key) != value: + env_diff[key] = value + + env_vars = [ + f"\n {key}={item}" for key, item in sorted(env_diff.items()) + ] + log("🌎", f"Environment changes:{''.join(env_vars)}") + + return environment + + +def subdir(working_dir, *, clean_ok=False): + """Decorator to change to a working directory.""" + + def decorator(func): + @functools.wraps(func) + def wrapper(context): + nonlocal working_dir + + if callable(working_dir): + working_dir = working_dir(context) + separator() + log("📁", os.fsdecode(working_dir)) + if ( + clean_ok + and getattr(context, "clean", False) + and working_dir.exists() + ): + log("🚮", "Deleting directory (--clean)...") + shutil.rmtree(working_dir) + + working_dir.mkdir(parents=True, exist_ok=True) + + with contextlib.chdir(working_dir): + return func(context, working_dir) + + return wrapper + + return decorator + + +def call(command, *, context=None, quiet=False, **kwargs): + """Execute a command. + + If 'quiet' is true, then redirect stdout and stderr to a temporary file. + """ + if context is not None: + quiet = context.quiet + + log("❯", " ".join(map(str, command)), spacing=" ") + if not quiet: + stdout = None + stderr = None + else: + if (logdir := getattr(context, "logdir", None)) is None: + logdir = pathlib.Path(tempfile.gettempdir()) + stdout = tempfile.NamedTemporaryFile( + "w", + encoding="utf-8", + delete=False, + dir=logdir, + prefix="cpython-wasi-", + suffix=".log", + ) + stderr = subprocess.STDOUT + log("📝", f"Logging output to {stdout.name} (--quiet)...") + + subprocess.check_call(command, **kwargs, stdout=stdout, stderr=stderr) + + +def build_python_path(): + """The path to the build Python binary.""" + binary = BUILD_DIR / "python" + if not binary.is_file(): + binary = binary.with_suffix(".exe") + if not binary.is_file(): + raise FileNotFoundError( + f"Unable to find `python(.exe)` in {BUILD_DIR}" + ) + + return binary + + +def build_python_is_pydebug(): + """Find out if the build Python is a pydebug build.""" + test = "import sys, test.support; sys.exit(test.support.Py_DEBUG)" + result = subprocess.run( + [build_python_path(), "-c", test], + capture_output=True, + ) + return bool(result.returncode) + + +@subdir(BUILD_DIR, clean_ok=True) +def configure_build_python(context, working_dir): + """Configure the build/host Python.""" + if LOCAL_SETUP.exists(): + if LOCAL_SETUP.read_bytes() == LOCAL_SETUP_MARKER: + log("👍", f"{LOCAL_SETUP} exists ...") + else: + log("⚠️", f"{LOCAL_SETUP} exists, but has unexpected contents") + else: + log("📝", f"Creating {LOCAL_SETUP} ...") + LOCAL_SETUP.write_bytes(LOCAL_SETUP_MARKER) + + configure = [os.path.relpath(CHECKOUT / "configure", working_dir)] + if context.args: + configure.extend(context.args) + + call(configure, context=context) + + +@subdir(BUILD_DIR) +def make_build_python(context, working_dir): + """Make/build the build Python.""" + call(["make", "--jobs", str(cpu_count()), "all"], context=context) + + binary = build_python_path() + cmd = [ + binary, + "-c", + "import sys; " + "print(f'{sys.version_info.major}.{sys.version_info.minor}')", + ] + version = subprocess.check_output(cmd, encoding="utf-8").strip() + + log("🎉", f"{binary} {version}") + + +def wasi_sdk(context): + """Find the path to the WASI SDK.""" + if wasi_sdk_path := context.wasi_sdk_path: + if not wasi_sdk_path.exists(): + raise ValueError( + "WASI SDK not found; " + "download from " + "https://github.com/WebAssembly/wasi-sdk and/or " + "specify via $WASI_SDK_PATH or --wasi-sdk" + ) + return wasi_sdk_path + + with (HERE / "config.toml").open("rb") as file: + config = tomllib.load(file) + wasi_sdk_version = config["targets"]["wasi-sdk"] + + if wasi_sdk_path_env_var := os.environ.get("WASI_SDK_PATH"): + wasi_sdk_path = pathlib.Path(wasi_sdk_path_env_var) + if not wasi_sdk_path.exists(): + raise ValueError( + f"WASI SDK not found at $WASI_SDK_PATH ({wasi_sdk_path})" + ) + else: + opt_path = pathlib.Path("/opt") + # WASI SDK versions have a ``.0`` suffix, but it's a constant; the WASI SDK team + # has said they don't plan to ever do a point release and all of their Git tags + # lack the ``.0`` suffix. + # Starting with WASI SDK 23, the tarballs went from containing a directory named + # ``wasi-sdk-{WASI_SDK_VERSION}.0`` to e.g. + # ``wasi-sdk-{WASI_SDK_VERSION}.0-x86_64-linux``. + potential_sdks = [ + path + for path in opt_path.glob(f"wasi-sdk-{wasi_sdk_version}.0*") + if path.is_dir() + ] + if len(potential_sdks) == 1: + wasi_sdk_path = potential_sdks[0] + elif (default_path := opt_path / "wasi-sdk").is_dir(): + wasi_sdk_path = default_path + + # Starting with WASI SDK 25, a VERSION file is included in the root + # of the SDK directory that we can read to warn folks when they are using + # an unsupported version. + if wasi_sdk_path and (version_file := wasi_sdk_path / "VERSION").is_file(): + version_details = version_file.read_text(encoding="utf-8") + found_version = version_details.splitlines()[0] + # Make sure there's a trailing dot to avoid false positives if somehow the + # supported version is a prefix of the found version (e.g. `25` and `2567`). + if not found_version.startswith(f"{wasi_sdk_version}."): + major_version = found_version.partition(".")[0] + log( + "⚠️", + f" Found WASI SDK {major_version}, " + f"but WASI SDK {wasi_sdk_version} is the supported version", + ) + + # Cache the result. + context.wasi_sdk_path = wasi_sdk_path + return wasi_sdk_path + + +def wasi_sdk_env(context): + """Calculate environment variables for building with wasi-sdk.""" + wasi_sdk_path = wasi_sdk(context) + sysroot = wasi_sdk_path / "share" / "wasi-sysroot" + env = { + "CC": "clang", + "CPP": "clang-cpp", + "CXX": "clang++", + "AR": "llvm-ar", + "RANLIB": "ranlib", + } + + for env_var, binary_name in list(env.items()): + env[env_var] = os.fsdecode(wasi_sdk_path / "bin" / binary_name) + + if not wasi_sdk_path.name.startswith("wasi-sdk"): + for compiler in ["CC", "CPP", "CXX"]: + env[compiler] += f" --sysroot={sysroot}" + + env["PKG_CONFIG_PATH"] = "" + env["PKG_CONFIG_LIBDIR"] = os.pathsep.join( + map( + os.fsdecode, + [sysroot / "lib" / "pkgconfig", sysroot / "share" / "pkgconfig"], + ) + ) + env["PKG_CONFIG_SYSROOT_DIR"] = os.fsdecode(sysroot) + + env["WASI_SDK_PATH"] = os.fsdecode(wasi_sdk_path) + env["WASI_SYSROOT"] = os.fsdecode(sysroot) + + env["PATH"] = os.pathsep.join([ + os.fsdecode(wasi_sdk_path / "bin"), + os.environ["PATH"], + ]) + + return env + + +def host_triple(context): + """Determine the target triple for the WASI host build.""" + if context.host_triple: + return context.host_triple + + with (HERE / "config.toml").open("rb") as file: + config = tomllib.load(file) + + # Cache the result. + context.host_triple = config["targets"]["host-triple"] + return context.host_triple + + +@subdir(lambda context: CROSS_BUILD_DIR / host_triple(context), clean_ok=True) +def configure_wasi_python(context, working_dir): + """Configure the WASI/host build.""" + config_site = os.fsdecode(HERE / "config.site-wasm32-wasi") + + wasi_build_dir = working_dir.relative_to(CHECKOUT) + + args = { + "WASMTIME": "wasmtime", + "ARGV0": f"/{wasi_build_dir}/python.wasm", + "CHECKOUT": os.fsdecode(CHECKOUT), + "WASMTIME_CONFIG_PATH": os.fsdecode(HERE / "wasmtime.toml"), + } + # Check dynamically for wasmtime in case it was specified manually via + # `--host-runner`. + if "{WASMTIME}" in context.host_runner: + if wasmtime := shutil.which("wasmtime"): + args["WASMTIME"] = wasmtime + else: + raise FileNotFoundError( + "wasmtime not found; download from " + "https://github.com/bytecodealliance/wasmtime" + ) + host_runner = context.host_runner.format_map(args) + env_additions = {"CONFIG_SITE": config_site, "HOSTRUNNER": host_runner} + build_python = os.fsdecode(build_python_path()) + # The path to `configure` MUST be relative, else `python.wasm` is unable + # to find the stdlib due to Python not recognizing that it's being + # executed from within a checkout. + configure = [ + os.path.relpath(CHECKOUT / "configure", working_dir), + f"--host={host_triple(context)}", + f"--build={BUILD_DIR.name}", + f"--with-build-python={build_python}", + ] + if build_python_is_pydebug(): + configure.append("--with-pydebug") + if context.args: + configure.extend(context.args) + call( + configure, + env=updated_env(env_additions | wasi_sdk_env(context)), + context=context, + ) + + python_wasm = working_dir / "python.wasm" + exec_script = working_dir / "python.sh" + with exec_script.open("w", encoding="utf-8") as file: + file.write(f'#!/bin/sh\nexec {host_runner} {python_wasm} "$@"\n') + exec_script.chmod(0o755) + log("🏃", f"Created {exec_script} (--host-runner)... ") + sys.stdout.flush() + + +@subdir(lambda context: CROSS_BUILD_DIR / host_triple(context)) +def make_wasi_python(context, working_dir): + """Run `make` for the WASI/host build.""" + call( + ["make", "--jobs", str(cpu_count()), "all"], + env=updated_env(), + context=context, + ) + + exec_script = working_dir / "python.sh" + call([exec_script, "--version"], quiet=False) + log( + "🎉", + f"Use `{exec_script.relative_to(pathlib.Path().absolute())}` " + "to run CPython w/ the WASI host specified by --host-runner", + ) + + +def clean_contents(context): + """Delete all files created by this script.""" + if CROSS_BUILD_DIR.exists(): + log("🧹", f"Deleting {CROSS_BUILD_DIR} ...") + shutil.rmtree(CROSS_BUILD_DIR) + + if LOCAL_SETUP.exists(): + if LOCAL_SETUP.read_bytes() == LOCAL_SETUP_MARKER: + log("🧹", f"Deleting generated {LOCAL_SETUP} ...") From 4ebaf3f4596adfb4d508e2278cb9a08b39480d50 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 4 Mar 2026 13:27:47 -0800 Subject: [PATCH 321/498] Use bytecodealliance/setup-wasi-sdk-action to install the WASI SDK (#145445) --- .github/workflows/reusable-wasi.yml | 31 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/reusable-wasi.yml b/.github/workflows/reusable-wasi.yml index fb62f0d5164e07..8d76679a400c7f 100644 --- a/.github/workflows/reusable-wasi.yml +++ b/.github/workflows/reusable-wasi.yml @@ -13,8 +13,6 @@ jobs: timeout-minutes: 60 env: WASMTIME_VERSION: 38.0.3 - WASI_SDK_VERSION: 30 - WASI_SDK_PATH: /opt/wasi-sdk CROSS_BUILD_PYTHON: cross-build/build CROSS_BUILD_WASI: cross-build/wasm32-wasip1 steps: @@ -26,18 +24,23 @@ jobs: uses: bytecodealliance/actions/wasmtime/setup@v1 with: version: ${{ env.WASMTIME_VERSION }} - - name: "Restore WASI SDK" - id: cache-wasi-sdk - uses: actions/cache@v5 - with: - path: ${{ env.WASI_SDK_PATH }} - key: ${{ runner.os }}-wasi-sdk-${{ env.WASI_SDK_VERSION }} - - name: "Install WASI SDK" # Hard-coded to x64. - if: steps.cache-wasi-sdk.outputs.cache-hit != 'true' + - name: "Read WASI SDK version" + id: wasi-sdk-version run: | - mkdir "${WASI_SDK_PATH}" && \ - curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-arm64-linux.tar.gz" | \ - tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip + import tomllib + from pathlib import Path + import os + config = tomllib.loads(Path("Platforms/WASI/config.toml").read_text()) + version = config["targets"]["wasi-sdk"] + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"version={version}\n") + shell: python + - name: "Install WASI SDK" + id: install-wasi-sdk + uses: bytecodealliance/setup-wasi-sdk-action@b2de090b44eb70013ee96b393727d473b35e1728 + with: + version: ${{ steps.wasi-sdk-version.outputs.version }} + add-to-path: false - name: "Install Python" uses: actions/setup-python@v6 with: @@ -51,6 +54,8 @@ jobs: - name: "Configure host" # `--with-pydebug` inferred from configure-build-python run: python3 Platforms/WASI configure-host -- --config-cache + env: + WASI_SDK_PATH: ${{ steps.install-wasi-sdk.outputs.wasi-sdk-path }} - name: "Make host" run: python3 Platforms/WASI make-host - name: "Display build info" From 1aa1d76b7f2b5d4f767029d6d531f126e2857187 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 4 Mar 2026 23:45:43 +0100 Subject: [PATCH 322/498] gh-145376: Fix reference leaks in deque (#145421) Fix a reference leak if newblock() fails in _collections.deque. --- Modules/_collectionsmodule.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 72865f87fc484f..c3d63c8aab4b47 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -342,8 +342,10 @@ deque_append_lock_held(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) { if (deque->rightindex == BLOCKLEN - 1) { block *b = newblock(deque); - if (b == NULL) + if (b == NULL) { + Py_DECREF(item); return -1; + } b->leftlink = deque->rightblock; CHECK_END(deque->rightblock->rightlink); deque->rightblock->rightlink = b; @@ -389,8 +391,10 @@ deque_appendleft_lock_held(dequeobject *deque, PyObject *item, { if (deque->leftindex == 0) { block *b = newblock(deque); - if (b == NULL) + if (b == NULL) { + Py_DECREF(item); return -1; + } b->rightlink = deque->leftblock; CHECK_END(deque->leftblock->leftlink); deque->leftblock->leftlink = b; @@ -564,7 +568,6 @@ deque_extendleft_impl(dequeobject *deque, PyObject *iterable) iternext = *Py_TYPE(it)->tp_iternext; while ((item = iternext(it)) != NULL) { if (deque_appendleft_lock_held(deque, item, maxlen) == -1) { - Py_DECREF(item); Py_DECREF(it); return NULL; } From 72b3e374a32989a07bbab057695942b2cc23a294 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 00:57:54 +0100 Subject: [PATCH 323/498] gh-141510: Add frozendict support to python-gdb.py (#145511) --- Lib/test/test_gdb/test_pretty_print.py | 9 ++++++++- Tools/gdb/libpython.py | 13 ++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_gdb/test_pretty_print.py b/Lib/test/test_gdb/test_pretty_print.py index dfc77d65ab16a4..db3064e3df54c2 100644 --- a/Lib/test/test_gdb/test_pretty_print.py +++ b/Lib/test/test_gdb/test_pretty_print.py @@ -82,7 +82,14 @@ def test_dicts(self): self.assertGdbRepr({}) self.assertGdbRepr({'foo': 'bar'}, "{'foo': 'bar'}") # Python preserves insertion order since 3.6 - self.assertGdbRepr({'foo': 'bar', 'douglas': 42}, "{'foo': 'bar', 'douglas': 42}") + self.assertGdbRepr({'foo': 'bar', 'douglas': 42}, + "{'foo': 'bar', 'douglas': 42}") + + # frozendict + self.assertGdbRepr(frozendict(), + "frozendict({})") + self.assertGdbRepr(frozendict({'foo': 'bar', 'douglas': 42}), + "frozendict({'foo': 'bar', 'douglas': 42})") def test_lists(self): 'Verify the pretty-printing of lists' diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index a85195dcd1016a..ba52ea2a30e0be 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -352,6 +352,7 @@ def subclass_from_type(cls, t): 'frame': PyFrameObjectPtr, 'set' : PySetObjectPtr, 'frozenset' : PySetObjectPtr, + 'frozendict' : PyDictObjectPtr, 'builtin_function_or_method' : PyCFunctionObjectPtr, 'method-wrapper': wrapperobject, } @@ -815,12 +816,20 @@ def proxyval(self, visited): return result def write_repr(self, out, visited): + tp_name = self.safe_tp_name() + is_frozendict = (tp_name == "frozendict") + # Guard against infinite loops: if self.as_address() in visited: - out.write('{...}') + if is_frozendict: + out.write(tp_name + '({...})') + else: + out.write('{...}') return visited.add(self.as_address()) + if is_frozendict: + out.write(tp_name + '(') out.write('{') first = True for pyop_key, pyop_value in self.iteritems(): @@ -831,6 +840,8 @@ def write_repr(self, out, visited): out.write(': ') pyop_value.write_repr(out, visited) out.write('}') + if is_frozendict: + out.write(')') @staticmethod def _get_entries(keys): From 8b5431367042672d5c6f83e8329e199b79aa02f9 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 5 Mar 2026 09:07:47 +0900 Subject: [PATCH 324/498] gh-144991: Use runtime JIT threshold in _testinternalcapi (gh-145496) --- Include/internal/pycore_interp_structs.h | 2 +- Modules/_testinternalcapi.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 1e69c64bcd1fc0..776fb9575c2365 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -496,7 +496,7 @@ struct _py_func_state { /* For now we hard-code this to a value for which we are confident all the static builtin types will fit (for all builds). */ -#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 201 +#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 202 #define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10 #define _Py_MAX_MANAGED_STATIC_TYPES \ (_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES + _Py_MAX_MANAGED_STATIC_EXT_TYPES) diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 998bf5e592e8ee..b6ed0b8902354e 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -2970,6 +2970,8 @@ static PyMethodDef module_functions[] = { static int module_exec(PyObject *module) { + PyInterpreterState *interp = PyInterpreterState_Get(); + if (_PyTestInternalCapi_Init_Lock(module) < 0) { return 1; } @@ -3011,9 +3013,10 @@ module_exec(PyObject *module) return 1; } + // + 1 more due to one loop spent on tracing. + unsigned long threshold = interp->opt_config.jump_backward_initial_value + 2; if (PyModule_Add(module, "TIER2_THRESHOLD", - // + 1 more due to one loop spent on tracing. - PyLong_FromLong(JUMP_BACKWARD_INITIAL_VALUE + 2)) < 0) { + PyLong_FromUnsignedLong(threshold)) < 0) { return 1; } From 6acaf659ef0fdee131bc02f0b58685da039b5855 Mon Sep 17 00:00:00 2001 From: krylosov-aa Date: Thu, 5 Mar 2026 06:48:25 +0300 Subject: [PATCH 325/498] gh-145301: Fix double-free in hashlib and hmac module initialization (GH-145321) gh-145301: Fix double-free in hashlib and hmac initialization --- ...-02-27-19-00-26.gh-issue-145301.2Wih4b.rst | 2 ++ ...-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst | 2 ++ Modules/_hashopenssl.c | 2 +- Modules/hmacmodule.c | 23 +++++++++++-------- 4 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst create mode 100644 Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst diff --git a/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst b/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst new file mode 100644 index 00000000000000..7aeb6a1145ab4c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst @@ -0,0 +1,2 @@ +:mod:`hashlib`: fix a crash when the initialization of the underlying C +extension module fails. diff --git a/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst b/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst new file mode 100644 index 00000000000000..436ff316b2c327 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst @@ -0,0 +1,2 @@ +:mod:`hmac`: fix a crash when the initialization of the underlying C +extension module fails. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 77832a768e0cbc..e19eb1abcf2c4d 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -268,7 +268,7 @@ py_hashentry_table_new(void) { if (h->py_alias != NULL) { if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) { - PyMem_Free(entry); + /* entry is already in ht, will be freed by _Py_hashtable_destroy() */ goto error; } entry->refcnt++; diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index f074f24807703c..7a040103bcb234 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -1453,16 +1453,19 @@ py_hmac_hinfo_ht_new(void) assert(value->display_name == NULL); value->refcnt = 0; -#define Py_HMAC_HINFO_LINK(KEY) \ - do { \ - int rc = py_hmac_hinfo_ht_add(table, KEY, value); \ - if (rc < 0) { \ - PyMem_Free(value); \ - goto error; \ - } \ - else if (rc == 1) { \ - value->refcnt++; \ - } \ +#define Py_HMAC_HINFO_LINK(KEY) \ + do { \ + int rc = py_hmac_hinfo_ht_add(table, (KEY), value); \ + if (rc < 0) { \ + /* entry may already be in ht, freed upon exit */ \ + if (value->refcnt == 0) { \ + PyMem_Free(value); \ + } \ + goto error; \ + } \ + else if (rc == 1) { \ + value->refcnt++; \ + } \ } while (0) Py_HMAC_HINFO_LINK(e->name); Py_HMAC_HINFO_LINK(e->hashlib_name); From 0eaf260d79f8547b02d8e80d760b11e821928fde Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Thu, 5 Mar 2026 11:21:49 +0100 Subject: [PATCH 326/498] gh-145376: Fix refleak and null pointer deref in unusual error path of datetime module (GH-145476) --- Modules/_datetimemodule.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 8f64e572bd6086..6b23a5c637a308 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -3822,9 +3822,26 @@ iso_calendar_date_new_impl(PyTypeObject *type, int year, int week, return NULL; } - PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year)); - PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week)); - PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday)); + PyObject *year_object = PyLong_FromLong(year); + if (year_object == NULL) { + Py_DECREF(self); + return NULL; + } + PyTuple_SET_ITEM(self, 0, year_object); + + PyObject *week_object = PyLong_FromLong(week); + if (week_object == NULL) { + Py_DECREF(self); + return NULL; + } + PyTuple_SET_ITEM(self, 1, week_object); + + PyObject *weekday_object = PyLong_FromLong(weekday); + if (weekday_object == NULL) { + Py_DECREF(self); + return NULL; + } + PyTuple_SET_ITEM(self, 2, weekday_object); return (PyObject *)self; } @@ -6891,9 +6908,9 @@ datetime_datetime_astimezone_impl(PyDateTime_DateTime *self, goto naive; } else if (!PyDelta_Check(offset)) { + PyErr_Format(PyExc_TypeError, "utcoffset() returned %T," + " expected timedelta or None", offset); Py_DECREF(offset); - PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s," - " expected timedelta or None", Py_TYPE(offset)->tp_name); return NULL; } /* result = self - offset */ From 23a4e3ba3c44b423eff635672c56d614f5ea3899 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 5 Mar 2026 12:29:34 +0100 Subject: [PATCH 327/498] gh-145335: Skip Emscripten for os.execve() test (#145528) Emscripten's os.execve() always fails with ENOEXEC. Co-authored-by: Victor Stinner --- Lib/test/test_os/test_os.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py index 3cab8ff9536d23..06f69caad12bc8 100644 --- a/Lib/test/test_os/test_os.py +++ b/Lib/test/test_os/test_os.py @@ -2824,7 +2824,8 @@ def test_negative_fd_ebadf(self, fd): func(*args) self.assertEqual(ctx.exception.errno, errno.EBADF) - if hasattr(os, "execve") and os.execve in os.supports_fd: + if (hasattr(os, "execve") and os.execve in os.supports_fd + and support.has_subprocess_support): # glibc fails with EINVAL, musl fails with EBADF with self.assertRaises(OSError) as ctx: os.execve(fd, [sys.executable, "-c", "pass"], os.environ) From 0fe20fc1703c52c0b2597d70df6cad9b3e4056f0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 12:31:29 +0100 Subject: [PATCH 328/498] gh-141510: Don't accept frozendict in PyDict_Watch() (#145529) Don't accept frozendict in PyDict_Watch() and PyDict_Unwatch(). A frozendict cannot be modified, so it's not useful to watch for modifications. --- Lib/test/test_capi/test_watchers.py | 5 +++-- Objects/dictobject.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index bef72032513da5..67595e3550b0ff 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -176,8 +176,9 @@ def test_watch_unassigned_watcher_id(self): def test_unwatch_non_dict(self): with self.watcher() as wid: - with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): - self.unwatch(wid, 1) + for wrong_type in (frozendict(), 5, [123], object()): + with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): + self.unwatch(wid, wrong_type) def test_unwatch_out_of_range_watcher_id(self): d = {} diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 2552216152f98d..e0127f04249f6b 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -7912,7 +7912,7 @@ validate_watcher_id(PyInterpreterState *interp, int watcher_id) int PyDict_Watch(int watcher_id, PyObject* dict) { - if (!PyAnyDict_Check(dict)) { + if (!PyDict_Check(dict)) { PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); return -1; } @@ -7927,7 +7927,7 @@ PyDict_Watch(int watcher_id, PyObject* dict) int PyDict_Unwatch(int watcher_id, PyObject* dict) { - if (!PyAnyDict_Check(dict)) { + if (!PyDict_Check(dict)) { PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); return -1; } From 2acfad9d57a5f4f184410b438ca4432e47ed99dc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 12:32:32 +0100 Subject: [PATCH 329/498] gh-82626: Schedule removal of bool used as file descriptor (#145469) --- Doc/deprecations/pending-removal-in-3.18.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/deprecations/pending-removal-in-3.18.rst b/Doc/deprecations/pending-removal-in-3.18.rst index 3e799219478424..eb42fe9919eaeb 100644 --- a/Doc/deprecations/pending-removal-in-3.18.rst +++ b/Doc/deprecations/pending-removal-in-3.18.rst @@ -1,6 +1,9 @@ Pending removal in Python 3.18 ------------------------------ +* No longer accept a boolean value when a file descriptor is expected. + (Contributed by Serhiy Storchaka in :gh:`82626`.) + * :mod:`decimal`: * The non-standard and undocumented :class:`~decimal.Decimal` format From c8aa8de9a5ad4df58ac0ffeae897e1258728b7eb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 12:33:13 +0100 Subject: [PATCH 330/498] gh-141510: Use frozendict in the _opcode_metadata (#144910) Enhance py_metadata_generator.py to skip duplicates. Co-authored-by: Donghee Na --- Lib/_opcode_metadata.py | 732 +++++++++--------- .../cases_generator/py_metadata_generator.py | 28 +- 2 files changed, 383 insertions(+), 377 deletions(-) diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 8f14d81a43ee75..6e37288c32dd9a 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -2,375 +2,373 @@ # from: # Python/bytecodes.c # Do not edit! -_specializations = { - "RESUME": [ - "RESUME_CHECK", - ], - "TO_BOOL": [ - "TO_BOOL_ALWAYS_TRUE", - "TO_BOOL_BOOL", - "TO_BOOL_INT", - "TO_BOOL_LIST", - "TO_BOOL_NONE", - "TO_BOOL_STR", - ], - "BINARY_OP": [ - "BINARY_OP_MULTIPLY_INT", - "BINARY_OP_ADD_INT", - "BINARY_OP_SUBTRACT_INT", - "BINARY_OP_MULTIPLY_FLOAT", - "BINARY_OP_ADD_FLOAT", - "BINARY_OP_SUBTRACT_FLOAT", - "BINARY_OP_ADD_UNICODE", - "BINARY_OP_SUBSCR_LIST_INT", - "BINARY_OP_SUBSCR_LIST_SLICE", - "BINARY_OP_SUBSCR_TUPLE_INT", - "BINARY_OP_SUBSCR_STR_INT", - "BINARY_OP_SUBSCR_USTR_INT", - "BINARY_OP_SUBSCR_DICT", - "BINARY_OP_SUBSCR_GETITEM", - "BINARY_OP_INPLACE_ADD_UNICODE", - "BINARY_OP_EXTEND", - "BINARY_OP_INPLACE_ADD_UNICODE", - ], - "STORE_SUBSCR": [ - "STORE_SUBSCR_DICT", - "STORE_SUBSCR_LIST_INT", - ], - "SEND": [ - "SEND_GEN", - ], - "UNPACK_SEQUENCE": [ - "UNPACK_SEQUENCE_TWO_TUPLE", - "UNPACK_SEQUENCE_TUPLE", - "UNPACK_SEQUENCE_LIST", - ], - "STORE_ATTR": [ - "STORE_ATTR_INSTANCE_VALUE", - "STORE_ATTR_SLOT", - "STORE_ATTR_WITH_HINT", - ], - "LOAD_GLOBAL": [ - "LOAD_GLOBAL_MODULE", - "LOAD_GLOBAL_BUILTIN", - ], - "LOAD_SUPER_ATTR": [ - "LOAD_SUPER_ATTR_ATTR", - "LOAD_SUPER_ATTR_METHOD", - ], - "LOAD_ATTR": [ - "LOAD_ATTR_INSTANCE_VALUE", - "LOAD_ATTR_MODULE", - "LOAD_ATTR_WITH_HINT", - "LOAD_ATTR_SLOT", - "LOAD_ATTR_CLASS", - "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK", - "LOAD_ATTR_PROPERTY", - "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", - "LOAD_ATTR_METHOD_WITH_VALUES", - "LOAD_ATTR_METHOD_NO_DICT", - "LOAD_ATTR_METHOD_LAZY_DICT", - "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", - "LOAD_ATTR_NONDESCRIPTOR_NO_DICT", - ], - "COMPARE_OP": [ - "COMPARE_OP_FLOAT", - "COMPARE_OP_INT", - "COMPARE_OP_STR", - ], - "CONTAINS_OP": [ - "CONTAINS_OP_SET", - "CONTAINS_OP_DICT", - ], - "JUMP_BACKWARD": [ - "JUMP_BACKWARD_NO_JIT", - "JUMP_BACKWARD_JIT", - ], - "FOR_ITER": [ - "FOR_ITER_LIST", - "FOR_ITER_TUPLE", - "FOR_ITER_RANGE", - "FOR_ITER_GEN", - ], - "CALL": [ - "CALL_BOUND_METHOD_EXACT_ARGS", - "CALL_PY_EXACT_ARGS", - "CALL_TYPE_1", - "CALL_STR_1", - "CALL_TUPLE_1", - "CALL_BUILTIN_CLASS", - "CALL_BUILTIN_O", - "CALL_BUILTIN_FAST", - "CALL_BUILTIN_FAST_WITH_KEYWORDS", - "CALL_LEN", - "CALL_ISINSTANCE", - "CALL_LIST_APPEND", - "CALL_METHOD_DESCRIPTOR_O", - "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - "CALL_METHOD_DESCRIPTOR_NOARGS", - "CALL_METHOD_DESCRIPTOR_FAST", - "CALL_ALLOC_AND_ENTER_INIT", - "CALL_PY_GENERAL", - "CALL_BOUND_METHOD_GENERAL", - "CALL_NON_PY_GENERAL", - ], - "CALL_KW": [ - "CALL_KW_BOUND_METHOD", - "CALL_KW_PY", - "CALL_KW_NON_PY", - ], - "CALL_FUNCTION_EX": [ - "CALL_EX_PY", - "CALL_EX_NON_PY_GENERAL", - ], -} +_specializations = frozendict( + RESUME=( + "RESUME_CHECK", + ), + TO_BOOL=( + "TO_BOOL_ALWAYS_TRUE", + "TO_BOOL_BOOL", + "TO_BOOL_INT", + "TO_BOOL_LIST", + "TO_BOOL_NONE", + "TO_BOOL_STR", + ), + BINARY_OP=( + "BINARY_OP_MULTIPLY_INT", + "BINARY_OP_ADD_INT", + "BINARY_OP_SUBTRACT_INT", + "BINARY_OP_MULTIPLY_FLOAT", + "BINARY_OP_ADD_FLOAT", + "BINARY_OP_SUBTRACT_FLOAT", + "BINARY_OP_ADD_UNICODE", + "BINARY_OP_SUBSCR_LIST_INT", + "BINARY_OP_SUBSCR_LIST_SLICE", + "BINARY_OP_SUBSCR_TUPLE_INT", + "BINARY_OP_SUBSCR_STR_INT", + "BINARY_OP_SUBSCR_USTR_INT", + "BINARY_OP_SUBSCR_DICT", + "BINARY_OP_SUBSCR_GETITEM", + "BINARY_OP_INPLACE_ADD_UNICODE", + "BINARY_OP_EXTEND", + ), + STORE_SUBSCR=( + "STORE_SUBSCR_DICT", + "STORE_SUBSCR_LIST_INT", + ), + SEND=( + "SEND_GEN", + ), + UNPACK_SEQUENCE=( + "UNPACK_SEQUENCE_TWO_TUPLE", + "UNPACK_SEQUENCE_TUPLE", + "UNPACK_SEQUENCE_LIST", + ), + STORE_ATTR=( + "STORE_ATTR_INSTANCE_VALUE", + "STORE_ATTR_SLOT", + "STORE_ATTR_WITH_HINT", + ), + LOAD_GLOBAL=( + "LOAD_GLOBAL_MODULE", + "LOAD_GLOBAL_BUILTIN", + ), + LOAD_SUPER_ATTR=( + "LOAD_SUPER_ATTR_ATTR", + "LOAD_SUPER_ATTR_METHOD", + ), + LOAD_ATTR=( + "LOAD_ATTR_INSTANCE_VALUE", + "LOAD_ATTR_MODULE", + "LOAD_ATTR_WITH_HINT", + "LOAD_ATTR_SLOT", + "LOAD_ATTR_CLASS", + "LOAD_ATTR_CLASS_WITH_METACLASS_CHECK", + "LOAD_ATTR_PROPERTY", + "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", + "LOAD_ATTR_METHOD_WITH_VALUES", + "LOAD_ATTR_METHOD_NO_DICT", + "LOAD_ATTR_METHOD_LAZY_DICT", + "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", + "LOAD_ATTR_NONDESCRIPTOR_NO_DICT", + ), + COMPARE_OP=( + "COMPARE_OP_FLOAT", + "COMPARE_OP_INT", + "COMPARE_OP_STR", + ), + CONTAINS_OP=( + "CONTAINS_OP_SET", + "CONTAINS_OP_DICT", + ), + JUMP_BACKWARD=( + "JUMP_BACKWARD_NO_JIT", + "JUMP_BACKWARD_JIT", + ), + FOR_ITER=( + "FOR_ITER_LIST", + "FOR_ITER_TUPLE", + "FOR_ITER_RANGE", + "FOR_ITER_GEN", + ), + CALL=( + "CALL_BOUND_METHOD_EXACT_ARGS", + "CALL_PY_EXACT_ARGS", + "CALL_TYPE_1", + "CALL_STR_1", + "CALL_TUPLE_1", + "CALL_BUILTIN_CLASS", + "CALL_BUILTIN_O", + "CALL_BUILTIN_FAST", + "CALL_BUILTIN_FAST_WITH_KEYWORDS", + "CALL_LEN", + "CALL_ISINSTANCE", + "CALL_LIST_APPEND", + "CALL_METHOD_DESCRIPTOR_O", + "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", + "CALL_METHOD_DESCRIPTOR_NOARGS", + "CALL_METHOD_DESCRIPTOR_FAST", + "CALL_ALLOC_AND_ENTER_INIT", + "CALL_PY_GENERAL", + "CALL_BOUND_METHOD_GENERAL", + "CALL_NON_PY_GENERAL", + ), + CALL_KW=( + "CALL_KW_BOUND_METHOD", + "CALL_KW_PY", + "CALL_KW_NON_PY", + ), + CALL_FUNCTION_EX=( + "CALL_EX_PY", + "CALL_EX_NON_PY_GENERAL", + ), +) -_specialized_opmap = { - 'BINARY_OP_ADD_FLOAT': 129, - 'BINARY_OP_ADD_INT': 130, - 'BINARY_OP_ADD_UNICODE': 131, - 'BINARY_OP_EXTEND': 132, - 'BINARY_OP_INPLACE_ADD_UNICODE': 3, - 'BINARY_OP_INPLACE_ADD_UNICODE': 3, - 'BINARY_OP_MULTIPLY_FLOAT': 133, - 'BINARY_OP_MULTIPLY_INT': 134, - 'BINARY_OP_SUBSCR_DICT': 135, - 'BINARY_OP_SUBSCR_GETITEM': 136, - 'BINARY_OP_SUBSCR_LIST_INT': 137, - 'BINARY_OP_SUBSCR_LIST_SLICE': 138, - 'BINARY_OP_SUBSCR_STR_INT': 139, - 'BINARY_OP_SUBSCR_TUPLE_INT': 140, - 'BINARY_OP_SUBSCR_USTR_INT': 141, - 'BINARY_OP_SUBTRACT_FLOAT': 142, - 'BINARY_OP_SUBTRACT_INT': 143, - 'CALL_ALLOC_AND_ENTER_INIT': 144, - 'CALL_BOUND_METHOD_EXACT_ARGS': 145, - 'CALL_BOUND_METHOD_GENERAL': 146, - 'CALL_BUILTIN_CLASS': 147, - 'CALL_BUILTIN_FAST': 148, - 'CALL_BUILTIN_FAST_WITH_KEYWORDS': 149, - 'CALL_BUILTIN_O': 150, - 'CALL_EX_NON_PY_GENERAL': 151, - 'CALL_EX_PY': 152, - 'CALL_ISINSTANCE': 153, - 'CALL_KW_BOUND_METHOD': 154, - 'CALL_KW_NON_PY': 155, - 'CALL_KW_PY': 156, - 'CALL_LEN': 157, - 'CALL_LIST_APPEND': 158, - 'CALL_METHOD_DESCRIPTOR_FAST': 159, - 'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 160, - 'CALL_METHOD_DESCRIPTOR_NOARGS': 161, - 'CALL_METHOD_DESCRIPTOR_O': 162, - 'CALL_NON_PY_GENERAL': 163, - 'CALL_PY_EXACT_ARGS': 164, - 'CALL_PY_GENERAL': 165, - 'CALL_STR_1': 166, - 'CALL_TUPLE_1': 167, - 'CALL_TYPE_1': 168, - 'COMPARE_OP_FLOAT': 169, - 'COMPARE_OP_INT': 170, - 'COMPARE_OP_STR': 171, - 'CONTAINS_OP_DICT': 172, - 'CONTAINS_OP_SET': 173, - 'FOR_ITER_GEN': 174, - 'FOR_ITER_LIST': 175, - 'FOR_ITER_RANGE': 176, - 'FOR_ITER_TUPLE': 177, - 'JUMP_BACKWARD_JIT': 178, - 'JUMP_BACKWARD_NO_JIT': 179, - 'LOAD_ATTR_CLASS': 180, - 'LOAD_ATTR_CLASS_WITH_METACLASS_CHECK': 181, - 'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 182, - 'LOAD_ATTR_INSTANCE_VALUE': 183, - 'LOAD_ATTR_METHOD_LAZY_DICT': 184, - 'LOAD_ATTR_METHOD_NO_DICT': 185, - 'LOAD_ATTR_METHOD_WITH_VALUES': 186, - 'LOAD_ATTR_MODULE': 187, - 'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 188, - 'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 189, - 'LOAD_ATTR_PROPERTY': 190, - 'LOAD_ATTR_SLOT': 191, - 'LOAD_ATTR_WITH_HINT': 192, - 'LOAD_GLOBAL_BUILTIN': 193, - 'LOAD_GLOBAL_MODULE': 194, - 'LOAD_SUPER_ATTR_ATTR': 195, - 'LOAD_SUPER_ATTR_METHOD': 196, - 'RESUME_CHECK': 197, - 'SEND_GEN': 198, - 'STORE_ATTR_INSTANCE_VALUE': 199, - 'STORE_ATTR_SLOT': 200, - 'STORE_ATTR_WITH_HINT': 201, - 'STORE_SUBSCR_DICT': 202, - 'STORE_SUBSCR_LIST_INT': 203, - 'TO_BOOL_ALWAYS_TRUE': 204, - 'TO_BOOL_BOOL': 205, - 'TO_BOOL_INT': 206, - 'TO_BOOL_LIST': 207, - 'TO_BOOL_NONE': 208, - 'TO_BOOL_STR': 209, - 'UNPACK_SEQUENCE_LIST': 210, - 'UNPACK_SEQUENCE_TUPLE': 211, - 'UNPACK_SEQUENCE_TWO_TUPLE': 212, -} +_specialized_opmap = frozendict( + BINARY_OP_ADD_FLOAT=129, + BINARY_OP_ADD_INT=130, + BINARY_OP_ADD_UNICODE=131, + BINARY_OP_EXTEND=132, + BINARY_OP_INPLACE_ADD_UNICODE=3, + BINARY_OP_MULTIPLY_FLOAT=133, + BINARY_OP_MULTIPLY_INT=134, + BINARY_OP_SUBSCR_DICT=135, + BINARY_OP_SUBSCR_GETITEM=136, + BINARY_OP_SUBSCR_LIST_INT=137, + BINARY_OP_SUBSCR_LIST_SLICE=138, + BINARY_OP_SUBSCR_STR_INT=139, + BINARY_OP_SUBSCR_TUPLE_INT=140, + BINARY_OP_SUBSCR_USTR_INT=141, + BINARY_OP_SUBTRACT_FLOAT=142, + BINARY_OP_SUBTRACT_INT=143, + CALL_ALLOC_AND_ENTER_INIT=144, + CALL_BOUND_METHOD_EXACT_ARGS=145, + CALL_BOUND_METHOD_GENERAL=146, + CALL_BUILTIN_CLASS=147, + CALL_BUILTIN_FAST=148, + CALL_BUILTIN_FAST_WITH_KEYWORDS=149, + CALL_BUILTIN_O=150, + CALL_EX_NON_PY_GENERAL=151, + CALL_EX_PY=152, + CALL_ISINSTANCE=153, + CALL_KW_BOUND_METHOD=154, + CALL_KW_NON_PY=155, + CALL_KW_PY=156, + CALL_LEN=157, + CALL_LIST_APPEND=158, + CALL_METHOD_DESCRIPTOR_FAST=159, + CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS=160, + CALL_METHOD_DESCRIPTOR_NOARGS=161, + CALL_METHOD_DESCRIPTOR_O=162, + CALL_NON_PY_GENERAL=163, + CALL_PY_EXACT_ARGS=164, + CALL_PY_GENERAL=165, + CALL_STR_1=166, + CALL_TUPLE_1=167, + CALL_TYPE_1=168, + COMPARE_OP_FLOAT=169, + COMPARE_OP_INT=170, + COMPARE_OP_STR=171, + CONTAINS_OP_DICT=172, + CONTAINS_OP_SET=173, + FOR_ITER_GEN=174, + FOR_ITER_LIST=175, + FOR_ITER_RANGE=176, + FOR_ITER_TUPLE=177, + JUMP_BACKWARD_JIT=178, + JUMP_BACKWARD_NO_JIT=179, + LOAD_ATTR_CLASS=180, + LOAD_ATTR_CLASS_WITH_METACLASS_CHECK=181, + LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN=182, + LOAD_ATTR_INSTANCE_VALUE=183, + LOAD_ATTR_METHOD_LAZY_DICT=184, + LOAD_ATTR_METHOD_NO_DICT=185, + LOAD_ATTR_METHOD_WITH_VALUES=186, + LOAD_ATTR_MODULE=187, + LOAD_ATTR_NONDESCRIPTOR_NO_DICT=188, + LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES=189, + LOAD_ATTR_PROPERTY=190, + LOAD_ATTR_SLOT=191, + LOAD_ATTR_WITH_HINT=192, + LOAD_GLOBAL_BUILTIN=193, + LOAD_GLOBAL_MODULE=194, + LOAD_SUPER_ATTR_ATTR=195, + LOAD_SUPER_ATTR_METHOD=196, + RESUME_CHECK=197, + SEND_GEN=198, + STORE_ATTR_INSTANCE_VALUE=199, + STORE_ATTR_SLOT=200, + STORE_ATTR_WITH_HINT=201, + STORE_SUBSCR_DICT=202, + STORE_SUBSCR_LIST_INT=203, + TO_BOOL_ALWAYS_TRUE=204, + TO_BOOL_BOOL=205, + TO_BOOL_INT=206, + TO_BOOL_LIST=207, + TO_BOOL_NONE=208, + TO_BOOL_STR=209, + UNPACK_SEQUENCE_LIST=210, + UNPACK_SEQUENCE_TUPLE=211, + UNPACK_SEQUENCE_TWO_TUPLE=212, +) -opmap = { - 'CACHE': 0, - 'RESERVED': 17, - 'RESUME': 128, - 'INSTRUMENTED_LINE': 253, - 'ENTER_EXECUTOR': 254, - 'TRACE_RECORD': 255, - 'BINARY_SLICE': 1, - 'BUILD_TEMPLATE': 2, - 'CALL_FUNCTION_EX': 4, - 'CHECK_EG_MATCH': 5, - 'CHECK_EXC_MATCH': 6, - 'CLEANUP_THROW': 7, - 'DELETE_SUBSCR': 8, - 'END_FOR': 9, - 'END_SEND': 10, - 'EXIT_INIT_CHECK': 11, - 'FORMAT_SIMPLE': 12, - 'FORMAT_WITH_SPEC': 13, - 'GET_AITER': 14, - 'GET_ANEXT': 15, - 'GET_ITER': 16, - 'GET_LEN': 18, - 'GET_YIELD_FROM_ITER': 19, - 'INTERPRETER_EXIT': 20, - 'LOAD_BUILD_CLASS': 21, - 'LOAD_LOCALS': 22, - 'MAKE_FUNCTION': 23, - 'MATCH_KEYS': 24, - 'MATCH_MAPPING': 25, - 'MATCH_SEQUENCE': 26, - 'NOP': 27, - 'NOT_TAKEN': 28, - 'POP_EXCEPT': 29, - 'POP_ITER': 30, - 'POP_TOP': 31, - 'PUSH_EXC_INFO': 32, - 'PUSH_NULL': 33, - 'RETURN_GENERATOR': 34, - 'RETURN_VALUE': 35, - 'SETUP_ANNOTATIONS': 36, - 'STORE_SLICE': 37, - 'STORE_SUBSCR': 38, - 'TO_BOOL': 39, - 'UNARY_INVERT': 40, - 'UNARY_NEGATIVE': 41, - 'UNARY_NOT': 42, - 'WITH_EXCEPT_START': 43, - 'BINARY_OP': 44, - 'BUILD_INTERPOLATION': 45, - 'BUILD_LIST': 46, - 'BUILD_MAP': 47, - 'BUILD_SET': 48, - 'BUILD_SLICE': 49, - 'BUILD_STRING': 50, - 'BUILD_TUPLE': 51, - 'CALL': 52, - 'CALL_INTRINSIC_1': 53, - 'CALL_INTRINSIC_2': 54, - 'CALL_KW': 55, - 'COMPARE_OP': 56, - 'CONTAINS_OP': 57, - 'CONVERT_VALUE': 58, - 'COPY': 59, - 'COPY_FREE_VARS': 60, - 'DELETE_ATTR': 61, - 'DELETE_DEREF': 62, - 'DELETE_FAST': 63, - 'DELETE_GLOBAL': 64, - 'DELETE_NAME': 65, - 'DICT_MERGE': 66, - 'DICT_UPDATE': 67, - 'END_ASYNC_FOR': 68, - 'EXTENDED_ARG': 69, - 'FOR_ITER': 70, - 'GET_AWAITABLE': 71, - 'IMPORT_FROM': 72, - 'IMPORT_NAME': 73, - 'IS_OP': 74, - 'JUMP_BACKWARD': 75, - 'JUMP_BACKWARD_NO_INTERRUPT': 76, - 'JUMP_FORWARD': 77, - 'LIST_APPEND': 78, - 'LIST_EXTEND': 79, - 'LOAD_ATTR': 80, - 'LOAD_COMMON_CONSTANT': 81, - 'LOAD_CONST': 82, - 'LOAD_DEREF': 83, - 'LOAD_FAST': 84, - 'LOAD_FAST_AND_CLEAR': 85, - 'LOAD_FAST_BORROW': 86, - 'LOAD_FAST_BORROW_LOAD_FAST_BORROW': 87, - 'LOAD_FAST_CHECK': 88, - 'LOAD_FAST_LOAD_FAST': 89, - 'LOAD_FROM_DICT_OR_DEREF': 90, - 'LOAD_FROM_DICT_OR_GLOBALS': 91, - 'LOAD_GLOBAL': 92, - 'LOAD_NAME': 93, - 'LOAD_SMALL_INT': 94, - 'LOAD_SPECIAL': 95, - 'LOAD_SUPER_ATTR': 96, - 'MAKE_CELL': 97, - 'MAP_ADD': 98, - 'MATCH_CLASS': 99, - 'POP_JUMP_IF_FALSE': 100, - 'POP_JUMP_IF_NONE': 101, - 'POP_JUMP_IF_NOT_NONE': 102, - 'POP_JUMP_IF_TRUE': 103, - 'RAISE_VARARGS': 104, - 'RERAISE': 105, - 'SEND': 106, - 'SET_ADD': 107, - 'SET_FUNCTION_ATTRIBUTE': 108, - 'SET_UPDATE': 109, - 'STORE_ATTR': 110, - 'STORE_DEREF': 111, - 'STORE_FAST': 112, - 'STORE_FAST_LOAD_FAST': 113, - 'STORE_FAST_STORE_FAST': 114, - 'STORE_GLOBAL': 115, - 'STORE_NAME': 116, - 'SWAP': 117, - 'UNPACK_EX': 118, - 'UNPACK_SEQUENCE': 119, - 'YIELD_VALUE': 120, - 'INSTRUMENTED_END_FOR': 233, - 'INSTRUMENTED_POP_ITER': 234, - 'INSTRUMENTED_END_SEND': 235, - 'INSTRUMENTED_FOR_ITER': 236, - 'INSTRUMENTED_INSTRUCTION': 237, - 'INSTRUMENTED_JUMP_FORWARD': 238, - 'INSTRUMENTED_NOT_TAKEN': 239, - 'INSTRUMENTED_POP_JUMP_IF_TRUE': 240, - 'INSTRUMENTED_POP_JUMP_IF_FALSE': 241, - 'INSTRUMENTED_POP_JUMP_IF_NONE': 242, - 'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 243, - 'INSTRUMENTED_RESUME': 244, - 'INSTRUMENTED_RETURN_VALUE': 245, - 'INSTRUMENTED_YIELD_VALUE': 246, - 'INSTRUMENTED_END_ASYNC_FOR': 247, - 'INSTRUMENTED_LOAD_SUPER_ATTR': 248, - 'INSTRUMENTED_CALL': 249, - 'INSTRUMENTED_CALL_KW': 250, - 'INSTRUMENTED_CALL_FUNCTION_EX': 251, - 'INSTRUMENTED_JUMP_BACKWARD': 252, - 'ANNOTATIONS_PLACEHOLDER': 256, - 'JUMP': 257, - 'JUMP_IF_FALSE': 258, - 'JUMP_IF_TRUE': 259, - 'JUMP_NO_INTERRUPT': 260, - 'LOAD_CLOSURE': 261, - 'POP_BLOCK': 262, - 'SETUP_CLEANUP': 263, - 'SETUP_FINALLY': 264, - 'SETUP_WITH': 265, - 'STORE_FAST_MAYBE_NULL': 266, -} +opmap = frozendict( + CACHE=0, + RESERVED=17, + RESUME=128, + INSTRUMENTED_LINE=253, + ENTER_EXECUTOR=254, + TRACE_RECORD=255, + BINARY_SLICE=1, + BUILD_TEMPLATE=2, + CALL_FUNCTION_EX=4, + CHECK_EG_MATCH=5, + CHECK_EXC_MATCH=6, + CLEANUP_THROW=7, + DELETE_SUBSCR=8, + END_FOR=9, + END_SEND=10, + EXIT_INIT_CHECK=11, + FORMAT_SIMPLE=12, + FORMAT_WITH_SPEC=13, + GET_AITER=14, + GET_ANEXT=15, + GET_ITER=16, + GET_LEN=18, + GET_YIELD_FROM_ITER=19, + INTERPRETER_EXIT=20, + LOAD_BUILD_CLASS=21, + LOAD_LOCALS=22, + MAKE_FUNCTION=23, + MATCH_KEYS=24, + MATCH_MAPPING=25, + MATCH_SEQUENCE=26, + NOP=27, + NOT_TAKEN=28, + POP_EXCEPT=29, + POP_ITER=30, + POP_TOP=31, + PUSH_EXC_INFO=32, + PUSH_NULL=33, + RETURN_GENERATOR=34, + RETURN_VALUE=35, + SETUP_ANNOTATIONS=36, + STORE_SLICE=37, + STORE_SUBSCR=38, + TO_BOOL=39, + UNARY_INVERT=40, + UNARY_NEGATIVE=41, + UNARY_NOT=42, + WITH_EXCEPT_START=43, + BINARY_OP=44, + BUILD_INTERPOLATION=45, + BUILD_LIST=46, + BUILD_MAP=47, + BUILD_SET=48, + BUILD_SLICE=49, + BUILD_STRING=50, + BUILD_TUPLE=51, + CALL=52, + CALL_INTRINSIC_1=53, + CALL_INTRINSIC_2=54, + CALL_KW=55, + COMPARE_OP=56, + CONTAINS_OP=57, + CONVERT_VALUE=58, + COPY=59, + COPY_FREE_VARS=60, + DELETE_ATTR=61, + DELETE_DEREF=62, + DELETE_FAST=63, + DELETE_GLOBAL=64, + DELETE_NAME=65, + DICT_MERGE=66, + DICT_UPDATE=67, + END_ASYNC_FOR=68, + EXTENDED_ARG=69, + FOR_ITER=70, + GET_AWAITABLE=71, + IMPORT_FROM=72, + IMPORT_NAME=73, + IS_OP=74, + JUMP_BACKWARD=75, + JUMP_BACKWARD_NO_INTERRUPT=76, + JUMP_FORWARD=77, + LIST_APPEND=78, + LIST_EXTEND=79, + LOAD_ATTR=80, + LOAD_COMMON_CONSTANT=81, + LOAD_CONST=82, + LOAD_DEREF=83, + LOAD_FAST=84, + LOAD_FAST_AND_CLEAR=85, + LOAD_FAST_BORROW=86, + LOAD_FAST_BORROW_LOAD_FAST_BORROW=87, + LOAD_FAST_CHECK=88, + LOAD_FAST_LOAD_FAST=89, + LOAD_FROM_DICT_OR_DEREF=90, + LOAD_FROM_DICT_OR_GLOBALS=91, + LOAD_GLOBAL=92, + LOAD_NAME=93, + LOAD_SMALL_INT=94, + LOAD_SPECIAL=95, + LOAD_SUPER_ATTR=96, + MAKE_CELL=97, + MAP_ADD=98, + MATCH_CLASS=99, + POP_JUMP_IF_FALSE=100, + POP_JUMP_IF_NONE=101, + POP_JUMP_IF_NOT_NONE=102, + POP_JUMP_IF_TRUE=103, + RAISE_VARARGS=104, + RERAISE=105, + SEND=106, + SET_ADD=107, + SET_FUNCTION_ATTRIBUTE=108, + SET_UPDATE=109, + STORE_ATTR=110, + STORE_DEREF=111, + STORE_FAST=112, + STORE_FAST_LOAD_FAST=113, + STORE_FAST_STORE_FAST=114, + STORE_GLOBAL=115, + STORE_NAME=116, + SWAP=117, + UNPACK_EX=118, + UNPACK_SEQUENCE=119, + YIELD_VALUE=120, + INSTRUMENTED_END_FOR=233, + INSTRUMENTED_POP_ITER=234, + INSTRUMENTED_END_SEND=235, + INSTRUMENTED_FOR_ITER=236, + INSTRUMENTED_INSTRUCTION=237, + INSTRUMENTED_JUMP_FORWARD=238, + INSTRUMENTED_NOT_TAKEN=239, + INSTRUMENTED_POP_JUMP_IF_TRUE=240, + INSTRUMENTED_POP_JUMP_IF_FALSE=241, + INSTRUMENTED_POP_JUMP_IF_NONE=242, + INSTRUMENTED_POP_JUMP_IF_NOT_NONE=243, + INSTRUMENTED_RESUME=244, + INSTRUMENTED_RETURN_VALUE=245, + INSTRUMENTED_YIELD_VALUE=246, + INSTRUMENTED_END_ASYNC_FOR=247, + INSTRUMENTED_LOAD_SUPER_ATTR=248, + INSTRUMENTED_CALL=249, + INSTRUMENTED_CALL_KW=250, + INSTRUMENTED_CALL_FUNCTION_EX=251, + INSTRUMENTED_JUMP_BACKWARD=252, + ANNOTATIONS_PLACEHOLDER=256, + JUMP=257, + JUMP_IF_FALSE=258, + JUMP_IF_TRUE=259, + JUMP_NO_INTERRUPT=260, + LOAD_CLOSURE=261, + POP_BLOCK=262, + SETUP_CLEANUP=263, + SETUP_FINALLY=264, + SETUP_WITH=265, + STORE_FAST_MAYBE_NULL=266, +) HAVE_ARGUMENT = 43 MIN_INSTRUMENTED_OPCODE = 233 diff --git a/Tools/cases_generator/py_metadata_generator.py b/Tools/cases_generator/py_metadata_generator.py index 3ec06faf338488..6df72de44e78cb 100644 --- a/Tools/cases_generator/py_metadata_generator.py +++ b/Tools/cases_generator/py_metadata_generator.py @@ -30,35 +30,43 @@ def get_specialized(analysis: Analysis) -> set[str]: def generate_specializations(analysis: Analysis, out: CWriter) -> None: - out.emit("_specializations = {\n") + out.emit("_specializations = frozendict(\n") for family in analysis.families.values(): - out.emit(f'"{family.name}": [\n') + out.emit(f'{family.name}=(\n') + seen = set() for member in family.members: + if member.name in seen: + continue + seen.add(member.name) out.emit(f' "{member.name}",\n') - out.emit("],\n") - out.emit("}\n\n") + out.emit("),\n") + out.emit(")\n\n") def generate_specialized_opmap(analysis: Analysis, out: CWriter) -> None: - out.emit("_specialized_opmap = {\n") + out.emit("_specialized_opmap = frozendict(\n") names = [] + seen = set() for family in analysis.families.values(): for member in family.members: if member.name == family.name: continue + if member.name in seen: + continue + seen.add(member.name) names.append(member.name) for name in sorted(names): - out.emit(f"'{name}': {analysis.opmap[name]},\n") - out.emit("}\n\n") + out.emit(f"{name}={analysis.opmap[name]},\n") + out.emit(")\n\n") def generate_opmap(analysis: Analysis, out: CWriter) -> None: specialized = get_specialized(analysis) - out.emit("opmap = {\n") + out.emit("opmap = frozendict(\n") for inst, op in analysis.opmap.items(): if inst not in specialized: - out.emit(f"'{inst}': {analysis.opmap[inst]},\n") - out.emit("}\n\n") + out.emit(f"{inst}={analysis.opmap[inst]},\n") + out.emit(")\n\n") def generate_py_metadata( From c0ecf211b26978859c5112458bcd01d883e04b42 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 12:35:43 +0100 Subject: [PATCH 331/498] gh-145055: Accept frozendict for globals in exec() and eval() (#145072) --- Doc/library/functions.rst | 10 +++++++- Include/internal/pycore_dict.h | 4 +-- Lib/test/test_builtin.py | 25 +++++++++++++++++++ ...-02-21-12-16-46.gh-issue-145055.VyT-zI.rst | 2 ++ Objects/codeobject.c | 2 +- Objects/dictobject.c | 2 +- Objects/funcobject.c | 2 +- Python/_warnings.c | 9 ++++--- Python/bltinmodule.c | 14 ++++++----- Python/ceval.c | 8 ++++-- Python/import.c | 5 ++-- Python/pythonrun.c | 5 ++-- 12 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 65b8ffdb23111d..d9a2eff667ebe1 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -594,7 +594,7 @@ are always available. They are listed here in alphabetical order. :param globals: The global namespace (default: ``None``). - :type globals: :class:`dict` | ``None`` + :type globals: :class:`dict` | :class:`frozendict` | ``None`` :param locals: The local namespace (default: ``None``). @@ -660,6 +660,10 @@ are always available. They are listed here in alphabetical order. The semantics of the default *locals* namespace have been adjusted as described for the :func:`locals` builtin. + .. versionchanged:: next + + *globals* can now be a :class:`frozendict`. + .. index:: pair: built-in function; exec .. function:: exec(source, /, globals=None, locals=None, *, closure=None) @@ -737,6 +741,10 @@ are always available. They are listed here in alphabetical order. The semantics of the default *locals* namespace have been adjusted as described for the :func:`locals` builtin. + .. versionchanged:: next + + *globals* can now be a :class:`frozendict`. + .. function:: filter(function, iterable, /) diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 1aeec32f55a7f3..a2c5ee41c37784 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -372,7 +372,7 @@ _PyDict_UniqueId(PyDictObject *mp) static inline void _Py_INCREF_DICT(PyObject *op) { - assert(PyDict_Check(op)); + assert(PyAnyDict_Check(op)); Py_ssize_t id = _PyDict_UniqueId((PyDictObject *)op); _Py_THREAD_INCREF_OBJECT(op, id); } @@ -380,7 +380,7 @@ _Py_INCREF_DICT(PyObject *op) static inline void _Py_DECREF_DICT(PyObject *op) { - assert(PyDict_Check(op)); + assert(PyAnyDict_Check(op)); Py_ssize_t id = _PyDict_UniqueId((PyDictObject *)op); _Py_THREAD_DECREF_OBJECT(op, id); } diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index eabfdcd447f2bb..844656eb0e2c2e 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -784,6 +784,16 @@ def __getitem__(self, key): raise ValueError self.assertRaises(ValueError, eval, "foo", {}, X()) + def test_eval_frozendict(self): + ns = frozendict(x=1, data=[], __builtins__=__builtins__) + eval("data.append(x)", ns, ns) + self.assertEqual(ns['data'], [1]) + + ns = frozendict() + errmsg = "cannot assign __builtins__ to frozendict globals" + with self.assertRaisesRegex(TypeError, errmsg): + eval("", ns, ns) + def test_eval_kwargs(self): data = {"A_GLOBAL_VALUE": 456} self.assertEqual(eval("globals()['A_GLOBAL_VALUE']", globals=data), 456) @@ -882,6 +892,21 @@ def test_exec(self): del l['__builtins__'] self.assertEqual((g, l), ({'a': 1}, {'b': 2})) + def test_exec_frozendict(self): + ns = frozendict(x=1, data=[], __builtins__=__builtins__) + exec("data.append(x)", ns, ns) + self.assertEqual(ns['data'], [1]) + + ns = frozendict(__builtins__=__builtins__) + errmsg = "'frozendict' object does not support item assignment" + with self.assertRaisesRegex(TypeError, errmsg): + exec("x = 1", ns, ns) + + ns = frozendict() + errmsg = "cannot assign __builtins__ to frozendict globals" + with self.assertRaisesRegex(TypeError, errmsg): + exec("", ns, ns) + def test_exec_kwargs(self): g = {} exec('global z\nz = 1', globals=g) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst new file mode 100644 index 00000000000000..c9daaa27717ed0 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst @@ -0,0 +1,2 @@ +:func:`exec` and :func:`eval` now accept :class:`frozendict` for *globals*. +Patch by Victor Stinner. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 520190824fbf1a..d26516f7c2ff66 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1830,7 +1830,7 @@ identify_unbound_names(PyThreadState *tstate, PyCodeObject *co, assert(attrnames != NULL); assert(PySet_Check(attrnames)); assert(PySet_GET_SIZE(attrnames) == 0 || counts != NULL); - assert(globalsns == NULL || PyDict_Check(globalsns)); + assert(globalsns == NULL || PyAnyDict_Check(globalsns)); assert(builtinsns == NULL || PyDict_Check(builtinsns)); assert(counts == NULL || counts->total == 0); struct co_unbound_counts unbound = {0}; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e0127f04249f6b..14019e4f1d926f 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2687,7 +2687,7 @@ _PyDict_LoadGlobalStackRef(PyDictObject *globals, PyDictObject *builtins, PyObje PyObject * _PyDict_LoadBuiltinsFromGlobals(PyObject *globals) { - if (!PyDict_Check(globals)) { + if (!PyAnyDict_Check(globals)) { PyErr_BadInternalCall(); return NULL; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index efe27a2b70c4de..fc32826fb3a861 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -150,7 +150,7 @@ PyObject * PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) { assert(globals != NULL); - assert(PyDict_Check(globals)); + assert(PyAnyDict_Check(globals)); _Py_INCREF_DICT(globals); PyCodeObject *code_obj = (PyCodeObject *)code; diff --git a/Python/_warnings.c b/Python/_warnings.c index d44d414bc93a04..0ea785772f03b9 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1045,7 +1045,7 @@ setup_context(Py_ssize_t stack_level, /* Setup registry. */ assert(globals != NULL); - assert(PyDict_Check(globals)); + assert(PyAnyDict_Check(globals)); int rc = PyDict_GetItemRef(globals, &_Py_ID(__warningregistry__), registry); if (rc < 0) { @@ -1269,10 +1269,11 @@ warnings_warn_explicit_impl(PyObject *module, PyObject *message, } if (module_globals && module_globals != Py_None) { - if (!PyDict_Check(module_globals)) { + if (!PyAnyDict_Check(module_globals)) { PyErr_Format(PyExc_TypeError, - "module_globals must be a dict, not '%.200s'", - Py_TYPE(module_globals)->tp_name); + "module_globals must be a dict or a frozendict, " + "not %T", + module_globals); return NULL; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 301125051f3b0e..fc69f6372028a6 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1040,10 +1040,11 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); return NULL; } - if (globals != Py_None && !PyDict_Check(globals)) { + if (globals != Py_None && !PyAnyDict_Check(globals)) { PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ? - "globals must be a real dict; try eval(expr, {}, mapping)" - : "globals must be a dict"); + "globals must be a real dict or a frozendict; " + "try eval(expr, {}, mapping)" + : "globals must be a dict or a frozendict"); return NULL; } @@ -1197,9 +1198,10 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, locals = Py_NewRef(globals); } - if (!PyDict_Check(globals)) { - PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s", - Py_TYPE(globals)->tp_name); + if (!PyAnyDict_Check(globals)) { + PyErr_Format(PyExc_TypeError, + "exec() globals must be a dict or a frozendict, not %T", + globals); goto error; } if (!PyMapping_Check(locals)) { diff --git a/Python/ceval.c b/Python/ceval.c index 3ad46cf1ec85ff..1e5142f4b456a1 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2718,7 +2718,7 @@ static PyObject * get_globals_builtins(PyObject *globals) { PyObject *builtins = NULL; - if (PyDict_Check(globals)) { + if (PyAnyDict_Check(globals)) { if (PyDict_GetItemRef(globals, &_Py_ID(__builtins__), &builtins) < 0) { return NULL; } @@ -2743,6 +2743,10 @@ set_globals_builtins(PyObject *globals, PyObject *builtins) } else { if (PyObject_SetItem(globals, &_Py_ID(__builtins__), builtins) < 0) { + if (PyFrozenDict_Check(globals)) { + PyErr_SetString(PyExc_TypeError, + "cannot assign __builtins__ to frozendict globals"); + } return -1; } } @@ -3584,7 +3588,7 @@ _PyEval_GetANext(PyObject *aiter) void _PyEval_LoadGlobalStackRef(PyObject *globals, PyObject *builtins, PyObject *name, _PyStackRef *writeto) { - if (PyDict_CheckExact(globals) && PyDict_CheckExact(builtins)) { + if (PyAnyDict_CheckExact(globals) && PyAnyDict_CheckExact(builtins)) { _PyDict_LoadGlobalStackRef((PyDictObject *)globals, (PyDictObject *)builtins, name, writeto); diff --git a/Python/import.c b/Python/import.c index 3ed808f67f4149..34224f4c6d6514 100644 --- a/Python/import.c +++ b/Python/import.c @@ -3728,8 +3728,9 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals"); goto error; } - if (!PyDict_Check(globals)) { - _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); + if (!PyAnyDict_Check(globals)) { + _PyErr_SetString(tstate, PyExc_TypeError, + "globals must be a dict or a frozendict"); goto error; } if (PyDict_GetItemRef(globals, &_Py_ID(__package__), &package) < 0) { diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 043bdf3433ab57..a21f494dc69d82 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1348,8 +1348,9 @@ static PyObject * run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, PyObject *locals) { /* Set globals['__builtins__'] if it doesn't exist */ - if (!globals || !PyDict_Check(globals)) { - PyErr_SetString(PyExc_SystemError, "globals must be a real dict"); + if (!globals || !PyAnyDict_Check(globals)) { + PyErr_SetString(PyExc_SystemError, + "globals must be a real dict or a real frozendict"); return NULL; } int has_builtins = PyDict_ContainsString(globals, "__builtins__"); From 7bdfce0d3a1696ed08ffa16e4574428ef09a6b40 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 12:55:28 +0100 Subject: [PATCH 332/498] gh-145056: Accept frozendict in xml.etree (#145508) Element and SubElement of xml.etree.ElementTree now also accept frozendict for attrib. Export _PyDict_CopyAsDict() function. --- Doc/library/xml.etree.elementtree.rst | 6 ++++++ Include/internal/pycore_dict.h | 3 ++- Lib/test/test_xml_etree.py | 11 +++++++++-- Lib/xml/etree/ElementTree.py | 4 ++-- Modules/_elementtree.c | 26 +++++++++++++++++--------- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index e021a81d2a2b87..45abf5b1e736b3 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -702,6 +702,9 @@ Functions attributes. *extra* contains additional attributes, given as keyword arguments. Returns an element instance. + .. versionchanged:: next + *attrib* can now be a :class:`frozendict`. + .. function:: tostring(element, encoding="us-ascii", method="xml", *, \ xml_declaration=None, default_namespace=None, \ @@ -887,6 +890,9 @@ Element Objects an optional dictionary, containing element attributes. *extra* contains additional attributes, given as keyword arguments. + .. versionchanged:: next + *attrib* can now be a :class:`frozendict`. + .. attribute:: tag diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index a2c5ee41c37784..6d7d68eda84c5a 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -160,7 +160,8 @@ extern void _PyDict_Clear_LockHeld(PyObject *op); PyAPI_FUNC(void) _PyDict_EnsureSharedOnRead(PyDictObject *mp); #endif -extern PyObject* _PyDict_CopyAsDict(PyObject *op); +// Export for '_elementtree' shared extension +PyAPI_FUNC(PyObject*) _PyDict_CopyAsDict(PyObject *op); #define DKIX_EMPTY (-1) #define DKIX_DUMMY (-2) /* Used internally */ diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 93162f52ba0344..5b06e422672b1d 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -4472,6 +4472,9 @@ def test_issue14818(self): ET.Element('a', dict(href="#"), id="foo"), ET.Element('a', href="#", id="foo"), ET.Element('a', dict(href="#", id="foo"), href="#", id="foo"), + ET.Element('a', frozendict(href="#", id="foo")), + ET.Element('a', frozendict(href="#"), id="foo"), + ET.Element('a', attrib=frozendict(href="#", id="foo")), ] for e in elements: self.assertEqual(e.tag, 'a') @@ -4479,10 +4482,14 @@ def test_issue14818(self): e2 = ET.SubElement(elements[0], 'foobar', attrib={'key1': 'value1'}) self.assertEqual(e2.attrib['key1'], 'value1') + e3 = ET.SubElement(elements[0], 'foobar', + attrib=frozendict({'key1': 'value1'})) + self.assertEqual(e3.attrib['key1'], 'value1') - with self.assertRaisesRegex(TypeError, 'must be dict, not str'): + errmsg = 'must be dict or frozendict, not str' + with self.assertRaisesRegex(TypeError, errmsg): ET.Element('a', "I'm not a dict") - with self.assertRaisesRegex(TypeError, 'must be dict, not str'): + with self.assertRaisesRegex(TypeError, errmsg): ET.Element('a', attrib="I'm not a dict") # -------------------------------------------------------------------- diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index e3d81a2c4560d9..57c5b64ea3ba70 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -165,8 +165,8 @@ class Element: """ def __init__(self, tag, attrib={}, **extra): - if not isinstance(attrib, dict): - raise TypeError("attrib must be dict, not %s" % ( + if not isinstance(attrib, (dict, frozendict)): + raise TypeError("attrib must be dict or frozendict, not %s" % ( attrib.__class__.__name__,)) self.tag = tag self.attrib = {**attrib, **extra} diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index f60a4c295e6495..e0bc69c5fe22f8 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -16,6 +16,7 @@ #endif #include "Python.h" +#include "pycore_dict.h" // _PyDict_CopyAsDict() #include "pycore_pyhash.h" // _Py_HashSecret #include "pycore_weakref.h" // FT_CLEAR_WEAKREFS() @@ -382,13 +383,14 @@ get_attrib_from_keywords(PyObject *kwds) /* If attrib was found in kwds, copy its value and remove it from * kwds */ - if (!PyDict_Check(attrib)) { - PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s", - Py_TYPE(attrib)->tp_name); + if (!PyAnyDict_Check(attrib)) { + PyErr_Format(PyExc_TypeError, + "attrib must be dict or frozendict, not %T", + attrib); Py_DECREF(attrib); return NULL; } - Py_SETREF(attrib, PyDict_Copy(attrib)); + Py_SETREF(attrib, _PyDict_CopyAsDict(attrib)); } else { attrib = PyDict_New(); @@ -416,12 +418,18 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) PyObject *attrib = NULL; ElementObject *self_elem; - if (!PyArg_ParseTuple(args, "O|O!:Element", &tag, &PyDict_Type, &attrib)) + if (!PyArg_ParseTuple(args, "O|O:Element", &tag, &attrib)) return -1; + if (attrib != NULL && !PyAnyDict_Check(attrib)) { + PyErr_Format(PyExc_TypeError, + "Element() argument 2 must be dict or frozendict, not %T", + attrib); + return -1; + } if (attrib) { /* attrib passed as positional arg */ - attrib = PyDict_Copy(attrib); + attrib = _PyDict_CopyAsDict(attrib); if (!attrib) return -1; if (kwds) { @@ -2111,10 +2119,10 @@ static int element_attrib_setter(PyObject *op, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - if (!PyDict_Check(value)) { + if (!PyAnyDict_Check(value)) { PyErr_Format(PyExc_TypeError, - "attrib must be dict, not %.200s", - Py_TYPE(value)->tp_name); + "attrib must be dict or frozendict, not %T", + value); return -1; } ElementObject *self = _Element_CAST(op); From 11840ca99ae809c1c8401b4f34d2820de55e27a0 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Thu, 5 Mar 2026 14:23:06 +0200 Subject: [PATCH 333/498] gh-140681: Freeze pre-commit hooks and update zizmor links (#140682) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/actionlint.yaml | 4 ---- .github/zizmor.yml | 2 +- .pre-commit-config.yaml | 18 +++++++++--------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 675712d65d4c95..eacfff24889021 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -1,7 +1,3 @@ -self-hosted-runner: - # Pending https://github.com/rhysd/actionlint/pull/615 - labels: ["windows-2025-vs2026"] - config-variables: null paths: diff --git a/.github/zizmor.yml b/.github/zizmor.yml index fab3abcb355dfe..8b7b4de0fc8f31 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -1,5 +1,5 @@ # Configuration for the zizmor static analysis tool, run via prek in CI -# https://woodruffw.github.io/zizmor/configuration/ +# https://docs.zizmor.sh/configuration/ rules: dangerous-triggers: ignore: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4893ec28f23e5a..dfd18182105e11 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.0 + rev: a27a2e47c7751b639d2b5badf0ef6ff11fee893f # frozen: v0.15.4 hooks: - id: ruff-check name: Run Ruff (lint) on Apple/ @@ -60,20 +60,20 @@ repos: files: ^Tools/wasm/ - repo: https://github.com/psf/black-pre-commit-mirror - rev: 26.1.0 + rev: ea488cebbfd88a5f50b8bd95d5c829d0bb76feb8 # frozen: 26.1.0 hooks: - id: black name: Run Black on Tools/jit/ files: ^Tools/jit/ - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.5.6 + rev: ad1b27d73581aa16cca06fc4a0761fc563ffe8e8 # frozen: v1.5.6 hooks: - id: remove-tabs types: [python] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 + rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: - id: check-case-conflict - id: check-merge-conflict @@ -91,24 +91,24 @@ repos: files: '^\.github/CODEOWNERS|\.(gram)$' - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.36.1 + rev: 9f48a48aa91a6040d749ad68ec70907d907a5a7f # frozen: 0.37.0 hooks: - id: check-dependabot - id: check-github-workflows - id: check-readthedocs - repo: https://github.com/rhysd/actionlint - rev: v1.7.10 + rev: 393031adb9afb225ee52ae2ccd7a5af5525e03e8 # frozen: v1.7.11 hooks: - id: actionlint - - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: v1.22.0 + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: b546b77c44c466a54a42af5499dcc0dcc1a3193f # frozen: v1.22.0 hooks: - id: zizmor - repo: https://github.com/sphinx-contrib/sphinx-lint - rev: v1.0.2 + rev: c883505f64b59c3c5c9375191e4ad9f98e727ccd # frozen: v1.0.2 hooks: - id: sphinx-lint args: [--enable=default-role] From 2cd0ddfe04afbe38bfbe73de1050ea5d1185f4b6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 14:14:04 +0100 Subject: [PATCH 334/498] gh-141510: Fix frozendict.items() ^ frozendict.items() (#145535) Add non-regression tests. --- Lib/test/test_dict.py | 13 +++++++++++++ Objects/dictobject.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 162b0b38f8555d..45448d1264a53e 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1848,11 +1848,19 @@ def test_merge(self): frozendict({'x': 1, 'y': 2})) self.assertEqual(frozendict(x=1, y=2) | frozendict(y=5), frozendict({'x': 1, 'y': 5})) + self.assertEqual(FrozenDict(x=1, y=2) | FrozenDict(y=5), + frozendict({'x': 1, 'y': 5})) + fd = frozendict(x=1, y=2) self.assertIs(fd | frozendict(), fd) self.assertIs(fd | {}, fd) self.assertIs(frozendict() | fd, fd) + fd = FrozenDict(x=1, y=2) + self.assertEqual(fd | frozendict(), fd) + self.assertEqual(fd | {}, fd) + self.assertEqual(frozendict() | fd, fd) + def test_update(self): # test "a |= b" operator d = frozendict(x=1) @@ -1863,6 +1871,11 @@ def test_update(self): self.assertEqual(d, frozendict({'x': 1, 'y': 2})) self.assertEqual(copy, frozendict({'x': 1})) + def test_items_xor(self): + # test "a ^ b" operator on items views + res = frozendict(a=1, b=2).items() ^ frozendict(b=2, c=3).items() + self.assertEqual(res, {('a', 1), ('c', 3)}) + def test_repr(self): d = frozendict() self.assertEqual(repr(d), "frozendict()") diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 14019e4f1d926f..d86ab2634a9b13 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -6523,7 +6523,7 @@ dictitems_xor_lock_held(PyObject *d1, PyObject *d2) ASSERT_DICT_LOCKED(d1); ASSERT_DICT_LOCKED(d2); - PyObject *temp_dict = copy_lock_held(d1, PyFrozenDict_Check(d1)); + PyObject *temp_dict = copy_lock_held(d1, 0); if (temp_dict == NULL) { return NULL; } From dbe0007ab2ff679c85d88e62fb875437b2dc2522 Mon Sep 17 00:00:00 2001 From: Shrey Naithani Date: Thu, 5 Mar 2026 19:49:49 +0530 Subject: [PATCH 335/498] gh-145417: Do not preserve SELinux context when copying venv scripts (#145454) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Miro Hrončok Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Victor Stinner --- Lib/test/test_venv.py | 12 +++++++++++- Lib/venv/__init__.py | 2 +- .../2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 68bcf535eada10..78461abcd69f33 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -11,12 +11,12 @@ import os.path import pathlib import re +import shlex import shutil import subprocess import sys import sysconfig import tempfile -import shlex from test.support import (captured_stdout, captured_stderr, skip_if_broken_multiprocessing_synchronize, verbose, requires_subprocess, is_android, is_apple_mobile, @@ -373,6 +373,16 @@ def create_contents(self, paths, filename): with open(fn, 'wb') as f: f.write(b'Still here?') + @unittest.skipUnless(hasattr(os, 'listxattr'), 'test requires os.listxattr') + def test_install_scripts_selinux(self): + """ + gh-145417: Test that install_scripts does not copy SELinux context + when copying scripts. + """ + with patch('os.listxattr') as listxattr_mock: + venv.create(self.env_dir) + listxattr_mock.assert_not_called() + def test_overwrite_existing(self): """ Test creating environment in an existing directory. diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 19eddde700bcf9..21f82125f5a7c4 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -581,7 +581,7 @@ def skip_file(f): 'may be binary: %s', srcfile, e) continue if new_data == data: - shutil.copy2(srcfile, dstfile) + shutil.copy(srcfile, dstfile) else: with open(dstfile, 'wb') as f: f.write(new_data) diff --git a/Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst b/Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst new file mode 100644 index 00000000000000..17d62df72ce1ae --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst @@ -0,0 +1,4 @@ +:mod:`venv`: Prevent incorrect preservation of SELinux context +when copying the ``Activate.ps1`` script. The script inherited +the SELinux security context of the system template directory, +rather than the destination project directory. From 0c29f83caa053c437131972147935c02e4e06630 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 15:26:54 +0100 Subject: [PATCH 336/498] gh-141510: No longer accept frozendict in PyDict_Copy() (#145542) Rename _PyDict_Copy() to anydict_copy(). Replace PyObject_IsInstance(op, &PyFrozenDict_Type) with PyFrozenDict_Check(). --- Doc/c-api/dict.rst | 4 --- Lib/test/test_capi/test_dict.py | 16 +++------ Objects/clinic/dictobject.c.h | 20 ++++++++++- Objects/dictobject.c | 64 ++++++++++++++++++++++----------- 4 files changed, 66 insertions(+), 38 deletions(-) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 734462bc0051af..371761573e97de 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -82,10 +82,6 @@ Dictionary objects Return a new dictionary that contains the same key-value pairs as *p*. - .. versionchanged:: next - If *p* is a subclass of :class:`frozendict`, the result will be a - :class:`frozendict` instance instead of a :class:`dict` instance. - .. c:function:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) Insert *val* into the dictionary *p* with a key of *key*. *key* must be diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index 561e1ea4d52846..5bdf74ef73ab54 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -97,21 +97,13 @@ def test_dictproxy_new(self): def test_dict_copy(self): # Test PyDict_Copy() copy = _testlimitedcapi.dict_copy - for dict_type in ANYDICT_TYPES: + for dict_type in DICT_TYPES: dct = dict_type({1: 2}) dct_copy = copy(dct) - if dict_type == frozendict: - expected_type = frozendict - self.assertIs(dct_copy, dct) - else: - if issubclass(dict_type, frozendict): - expected_type = frozendict - else: - expected_type = dict - self.assertIs(type(dct_copy), expected_type) - self.assertEqual(dct_copy, dct) + self.assertIs(type(dct_copy), dict) + self.assertEqual(dct_copy, dct) - for test_type in NOT_ANYDICT_TYPES + OTHER_TYPES: + for test_type in NOT_DICT_TYPES + OTHER_TYPES: self.assertRaises(SystemError, copy, test_type()) self.assertRaises(SystemError, copy, NULL) diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index abf6b38449fcb0..15b8705d9c78e3 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -323,4 +323,22 @@ dict_values(PyObject *self, PyObject *Py_UNUSED(ignored)) { return dict_values_impl((PyDictObject *)self); } -/*[clinic end generated code: output=9007b74432217017 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(frozendict_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a shallow copy of the frozendict."); + +#define FROZENDICT_COPY_METHODDEF \ + {"copy", (PyCFunction)frozendict_copy, METH_NOARGS, frozendict_copy__doc__}, + +static PyObject * +frozendict_copy_impl(PyFrozenDictObject *self); + +static PyObject * +frozendict_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return frozendict_copy_impl((PyFrozenDictObject *)self); +} +/*[clinic end generated code: output=f4c88a3464928ae3 input=a9049054013a1b77]*/ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index d86ab2634a9b13..61fde37f8d4fff 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -146,8 +146,9 @@ static int dict_merge_from_seq2(PyObject *d, PyObject *seq2, int override); /*[clinic input] class dict "PyDictObject *" "&PyDict_Type" +class frozendict "PyFrozenDictObject *" "&PyFrozenDict_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5dfa93bac68e7c54]*/ /* @@ -2406,7 +2407,7 @@ dict_unhashable_type(PyObject *op, PyObject *key) } const char *errmsg; - if (PyObject_IsInstance(op, (PyObject*)&PyFrozenDict_Type)) { + if (PyFrozenDict_Check(op)) { errmsg = "cannot use '%T' as a frozendict key (%S)"; } else { @@ -4384,35 +4385,37 @@ copy_lock_held(PyObject *o, int as_frozendict) return NULL; } -// Similar to PyDict_Copy(), but copy also frozendict. -static PyObject * -_PyDict_Copy(PyObject *o) +PyObject * +PyDict_Copy(PyObject *o) { - assert(PyAnyDict_Check(o)); + if (o == NULL || !PyDict_Check(o)) { + PyErr_BadInternalCall(); + return NULL; + } PyObject *res; Py_BEGIN_CRITICAL_SECTION(o); - res = copy_lock_held(o, PyFrozenDict_Check(o)); + res = copy_lock_held(o, 0); Py_END_CRITICAL_SECTION(); return res; } -PyObject * -PyDict_Copy(PyObject *o) +// Similar to PyDict_Copy(), but return a frozendict if the argument +// is a frozendict. +static PyObject * +anydict_copy(PyObject *o) { - if (o == NULL || !PyAnyDict_Check(o)) { - PyErr_BadInternalCall(); - return NULL; - } - - if (PyFrozenDict_CheckExact(o)) { - return Py_NewRef(o); - } + assert(PyAnyDict_Check(o)); - return _PyDict_Copy(o); + PyObject *res; + Py_BEGIN_CRITICAL_SECTION(o); + res = copy_lock_held(o, PyFrozenDict_Check(o)); + Py_END_CRITICAL_SECTION(); + return res; } -// Similar to PyDict_Copy(), but return a dict if the argument is a frozendict. +// Similar to PyDict_Copy(), but accept also frozendict: +// convert frozendict to a new dict. PyObject* _PyDict_CopyAsDict(PyObject *o) { @@ -4969,7 +4972,7 @@ dict_or(PyObject *self, PyObject *other) if (!PyAnyDict_Check(self) || !PyAnyDict_Check(other)) { Py_RETURN_NOTIMPLEMENTED; } - PyObject *new = _PyDict_Copy(self); + PyObject *new = anydict_copy(self); if (new == NULL) { return NULL; } @@ -8057,7 +8060,7 @@ static PyMethodDef frozendict_methods[] = { DICT_ITEMS_METHODDEF DICT_VALUES_METHODDEF DICT_FROMKEYS_METHODDEF - DICT_COPY_METHODDEF + FROZENDICT_COPY_METHODDEF DICT___REVERSED___METHODDEF {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {"__getnewargs__", frozendict_getnewargs, METH_NOARGS}, @@ -8182,6 +8185,25 @@ PyFrozenDict_New(PyObject *iterable) } } +/*[clinic input] +frozendict.copy + +Return a shallow copy of the frozendict. +[clinic start generated code]*/ + +static PyObject * +frozendict_copy_impl(PyFrozenDictObject *self) +/*[clinic end generated code: output=e580fd91d9fc2cf7 input=35f6abeaa08fd4bc]*/ +{ + assert(PyFrozenDict_Check(self)); + + if (PyFrozenDict_CheckExact(self)) { + return Py_NewRef(self); + } + + return anydict_copy((PyObject*)self); +} + PyTypeObject PyFrozenDict_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) From 37e421bb4330c184114aa6a23998dba9bd8d3bc5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Mar 2026 17:44:58 +0100 Subject: [PATCH 337/498] gh-141510: Complete What's New in Python 3.15 for frozendict (#145537) Mention updated stdlib modules and built-in functions. Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/functions.rst | 4 ++++ Doc/library/stdtypes.rst | 4 ++++ Doc/whatsnew/3.15.rst | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index d9a2eff667ebe1..af53b57dc9d2a7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -2099,6 +2099,10 @@ are always available. They are listed here in alphabetical order. Subclasses of :class:`!type` which don't override ``type.__new__`` may no longer use the one-argument form to get the type of an object. + .. versionchanged:: next + + *dict* can now be a :class:`frozendict`. + .. function:: vars() vars(object, /) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 76a4367dd2dcd5..c930b876b3ccbf 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2385,6 +2385,10 @@ expression support in the :mod:`re` module). the same position in *to*. If there is a third argument, it must be a string, whose characters will be mapped to ``None`` in the result. + .. versionchanged:: next + + *dict* can now be a :class:`frozendict`. + .. method:: str.partition(sep, /) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index fff2168be72604..0b5902bb013436 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -211,6 +211,13 @@ For example:: >>> a == b True +The following standard library modules have been updated to accept +:class:`!frozendict`: :mod:`copy`, :mod:`decimal`, :mod:`json`, :mod:`marshal`, +:mod:`pickle`, :mod:`pprint` and :mod:`xml.etree.ElementTree`. + +:func:`eval` and :func:`exec` accept :class:`!frozendict` for *globals*, and +:func:`type` and :meth:`str.maketrans` accept :class:`!frozendict` for *dict*. + .. seealso:: :pep:`814` for the full specification and rationale. (Contributed by Victor Stinner and Donghee Na in :gh:`141510`.) From e0945443a0abdee56a51a5cb82a31edba5f1adab Mon Sep 17 00:00:00 2001 From: Yash Kaushik Date: Thu, 5 Mar 2026 23:18:48 +0530 Subject: [PATCH 338/498] doc: Clarify logger creation example in logging HOWTO (GH-145540) --- Doc/howto/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index b7225ff1c2cbfc..454e2f4930e724 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -28,7 +28,7 @@ When to use logging ^^^^^^^^^^^^^^^^^^^ You can access logging functionality by creating a logger via ``logger = -getLogger(__name__)``, and then calling the logger's :meth:`~Logger.debug`, +logging.getLogger(__name__)``, and then calling the logger's :meth:`~Logger.debug`, :meth:`~Logger.info`, :meth:`~Logger.warning`, :meth:`~Logger.error` and :meth:`~Logger.critical` methods. To determine when to use logging, and to see which logger methods to use when, see the table below. It states, for each of a From 7232883adfc28f94a62d2e79c897db59711702d7 Mon Sep 17 00:00:00 2001 From: Alex Malyshev Date: Thu, 5 Mar 2026 14:03:30 -0500 Subject: [PATCH 339/498] gh-145557: Check ctypes is available in test_external_inspection (#145558) Currently TestGetStackTrace.test_self_trace_after_ctypes_import() will fail if the _ctypes extension is not built. Make it match test_ctypes by skipping the test in that case. --- Lib/test/test_external_inspection.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/test/test_external_inspection.py b/Lib/test/test_external_inspection.py index 890aa584cd192c..ec7192b1b89184 100644 --- a/Lib/test/test_external_inspection.py +++ b/Lib/test/test_external_inspection.py @@ -17,6 +17,7 @@ requires_gil_enabled, requires_remote_subprocess_debugging, ) +from test.support.import_helper import import_module from test.support.script_helper import make_script from test.support.socket_helper import find_unused_port @@ -529,6 +530,10 @@ def test_self_trace_after_ctypes_import(self): The remote debugging code must skip these uninitialized duplicate mappings and find the real PyRuntime. See gh-144563. """ + + # Skip the test if the _ctypes module is missing. + import_module("_ctypes") + # Run the test in a subprocess to avoid side effects script = textwrap.dedent("""\ import os From c3fb0d9d96902774c08b199dda0479a8d31398a5 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 6 Mar 2026 01:42:41 +0100 Subject: [PATCH 340/498] gh-145177: Support multiple Emscripten versions for Emscripten buildbot (#145180) Adds an `--emsdk-cache` argument to the Emscripten build script and an emscripten_version.txt file. If the `--emsdk-cache` argument is passed, the build script will look in `emscripten_version.txt` to get the expected emsdk version is installed in a folder called e.g., 4.0.12 in the directory indicated by the `--emsdk-cache` argument, and run the build with that Emscripten tooling activated. --- Tools/wasm/emscripten/__main__.py | 76 ++++++++++++++++++-- Tools/wasm/emscripten/emscripten_version.txt | 1 + 2 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 Tools/wasm/emscripten/emscripten_version.txt diff --git a/Tools/wasm/emscripten/__main__.py b/Tools/wasm/emscripten/__main__.py index c88e9edba6d230..856a7f8252bb7c 100644 --- a/Tools/wasm/emscripten/__main__.py +++ b/Tools/wasm/emscripten/__main__.py @@ -22,6 +22,7 @@ EMSCRIPTEN_DIR = Path(__file__).parent CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent +EMSCRIPTEN_VERSION_FILE = EMSCRIPTEN_DIR / "emscripten_version.txt" CROSS_BUILD_DIR = CHECKOUT / "cross-build" NATIVE_BUILD_DIR = CROSS_BUILD_DIR / "build" @@ -36,7 +37,56 @@ LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n" -def updated_env(updates={}): +@functools.cache +def get_required_emscripten_version(): + """Read the required emscripten version from emscripten_version.txt.""" + return EMSCRIPTEN_VERSION_FILE.read_text().strip() + + +@functools.cache +def get_emsdk_activate_path(emsdk_cache): + required_version = get_required_emscripten_version() + return Path(emsdk_cache) / required_version / "emsdk_env.sh" + + +def validate_emsdk_version(emsdk_cache): + """Validate that the emsdk cache contains the required emscripten version.""" + required_version = get_required_emscripten_version() + emsdk_env = get_emsdk_activate_path(emsdk_cache) + if not emsdk_env.is_file(): + print( + f"Required emscripten version {required_version} not found in {emsdk_cache}", + file=sys.stderr, + ) + sys.exit(1) + print(f"✅ Emscripten version {required_version} found in {emsdk_cache}") + + +def parse_env(text): + result = {} + for line in text.splitlines(): + key, val = line.split("=", 1) + result[key] = val + return result + + +@functools.cache +def get_emsdk_environ(emsdk_cache): + """Returns os.environ updated by sourcing emsdk_env.sh""" + if not emsdk_cache: + return os.environ + env_text = subprocess.check_output( + [ + "bash", + "-c", + f"EMSDK_QUIET=1 source {get_emsdk_activate_path(emsdk_cache)} && env", + ], + text=True, + ) + return parse_env(env_text) + + +def updated_env(updates, emsdk_cache): """Create a new dict representing the environment to use. The changes made to the execution environment are printed out. @@ -52,8 +102,7 @@ def updated_env(updates={}): except subprocess.CalledProcessError: pass # Might be building from a tarball. # This layering lets SOURCE_DATE_EPOCH from os.environ takes precedence. - environment = env_defaults | os.environ | updates - + environment = env_defaults | get_emsdk_environ(emsdk_cache) | updates env_diff = {} for key, value in environment.items(): if os.environ.get(key) != value: @@ -204,7 +253,7 @@ def make_emscripten_libffi(context, working_dir): ) call( [EMSCRIPTEN_DIR / "make_libffi.sh"], - env=updated_env({"PREFIX": PREFIX_DIR}), + env=updated_env({"PREFIX": PREFIX_DIR}, context.emsdk_cache), cwd=libffi_dir, quiet=context.quiet, ) @@ -231,6 +280,7 @@ def make_mpdec(context, working_dir): ], cwd=mpdec_dir, quiet=context.quiet, + env=updated_env({}, context.emsdk_cache), ) call( ["make", "install"], @@ -300,7 +350,7 @@ def configure_emscripten_python(context, working_dir): configure.extend(context.args) call( configure, - env=updated_env(env_additions), + env=updated_env(env_additions, context.emsdk_cache), quiet=context.quiet, ) @@ -358,7 +408,7 @@ def make_emscripten_python(context, working_dir): """Run `make` for the emscripten/host build.""" call( ["make", "--jobs", str(cpu_count()), "all"], - env=updated_env(), + env=updated_env({}, context.emsdk_cache), quiet=context.quiet, ) @@ -439,6 +489,14 @@ def main(): dest="quiet", help="Redirect output from subprocesses to a log file", ) + subcommand.add_argument( + "--emsdk-cache", + action="store", + default=None, + dest="emsdk_cache", + help="Path to emsdk cache directory. If provided, validates that " + "the required emscripten version is installed.", + ) for subcommand in configure_build, configure_host: subcommand.add_argument( "--clean", @@ -463,6 +521,12 @@ def main(): context = parser.parse_args() + if context.emsdk_cache: + validate_emsdk_version(context.emsdk_cache) + context.emsdk_cache = Path(context.emsdk_cache).absolute() + else: + print("Build will use EMSDK from current environment.") + dispatch = { "make-libffi": make_emscripten_libffi, "make-mpdec": make_mpdec, diff --git a/Tools/wasm/emscripten/emscripten_version.txt b/Tools/wasm/emscripten/emscripten_version.txt new file mode 100644 index 00000000000000..4c05e4ef57dbf8 --- /dev/null +++ b/Tools/wasm/emscripten/emscripten_version.txt @@ -0,0 +1 @@ +4.0.12 From 4fce98a920f47504e834057cd6606bad9b591ea9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Mar 2026 10:23:11 +0100 Subject: [PATCH 341/498] gh-141510: Change marshal version to 6 (#145551) Fix SliceTestCase: test also that version 4 fails with ValueError. --- Doc/library/marshal.rst | 11 +++++++++-- Include/cpython/marshal.h | 2 +- Lib/test/test_marshal.py | 11 ++++++++++- .../2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst | 2 ++ Programs/_freeze_module.c | 2 +- Python/marshal.c | 6 ++++++ 6 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index ed182ea24e8f3c..25902622b8730b 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -51,8 +51,9 @@ this module. The following types are supported: * Strings (:class:`str`) and :class:`bytes`. :term:`Bytes-like objects ` like :class:`bytearray` are marshalled as :class:`!bytes`. -* Containers: :class:`tuple`, :class:`list`, :class:`set`, :class:`frozenset`, - and (since :data:`version` 5), :class:`slice`. +* Containers: :class:`tuple`, :class:`list`, :class:`dict`, :class:`frozendict` + (since :data:`version` 6), :class:`set`, :class:`frozenset`, and + :class:`slice` (since :data:`version` 5). It should be understood that these are supported only if the values contained therein are themselves supported. Recursive containers are supported since :data:`version` 3. @@ -71,6 +72,10 @@ this module. The following types are supported: Added format version 5, which allows marshalling slices. +.. versionchanged:: next + + Added format version 6, which allows marshalling :class:`frozendict`. + The module defines these functions: @@ -173,6 +178,8 @@ In addition, the following constants are defined: 4 Python 3.4 Efficient representation of short strings ------- --------------- ---------------------------------------------------- 5 Python 3.14 Support for :class:`slice` objects + ------- --------------- ---------------------------------------------------- + 6 Python 3.15 Support for :class:`frozendict` objects ======= =============== ==================================================== diff --git a/Include/cpython/marshal.h b/Include/cpython/marshal.h index 6c1f7f96b6a2e8..159459fcaec3d9 100644 --- a/Include/cpython/marshal.h +++ b/Include/cpython/marshal.h @@ -6,7 +6,7 @@ PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(const char *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); -#define Py_MARSHAL_VERSION 5 +#define Py_MARSHAL_VERSION 6 PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 28f24d0fc59cb0..78db4219e2997c 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -570,6 +570,15 @@ def testDict(self): self.helper(dictobj) self.helper3(dictobj) + def testFrozenDict(self): + for obj in self.keys: + dictobj = frozendict({"hello": obj, "goodbye": obj, obj: "hello"}) + self.helper(dictobj) + + for version in range(6): + with self.assertRaises(ValueError): + marshal.dumps(dictobj, version) + def testModule(self): with open(__file__, "rb") as f: code = f.read() @@ -635,7 +644,7 @@ def test_slice(self): with self.subTest(obj=str(obj)): self.helper(obj) - for version in range(4): + for version in range(5): with self.assertRaises(ValueError): marshal.dumps(obj, version) diff --git a/Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst b/Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst new file mode 100644 index 00000000000000..280a7b3632ddae --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst @@ -0,0 +1,2 @@ +:mod:`marshal` now supports :class:`frozendict` objects. The marshal format +version was increased to 6. Patch by Victor Stinner. diff --git a/Programs/_freeze_module.c b/Programs/_freeze_module.c index a5809b37b6b493..27a60171f3eca8 100644 --- a/Programs/_freeze_module.c +++ b/Programs/_freeze_module.c @@ -134,7 +134,7 @@ compile_and_marshal(const char *name, const char *text) return NULL; } - assert(Py_MARSHAL_VERSION >= 5); + assert(Py_MARSHAL_VERSION >= 6); PyObject *marshalled = PyMarshal_WriteObjectToString(code, Py_MARSHAL_VERSION); Py_CLEAR(code); if (marshalled == NULL) { diff --git a/Python/marshal.c b/Python/marshal.c index a71909f103ebfc..59db6456552c35 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -580,6 +580,12 @@ w_complex_object(PyObject *v, char flag, WFILE *p) Py_ssize_t pos; PyObject *key, *value; if (PyFrozenDict_CheckExact(v)) { + if (p->version < 6) { + w_byte(TYPE_UNKNOWN, p); + p->error = WFERR_UNMARSHALLABLE; + return; + } + W_TYPE(TYPE_FROZENDICT, p); } else { From 349639cfa46180b18c2a3299db08cff253c7a959 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Mar 2026 10:25:09 +0100 Subject: [PATCH 342/498] gh-141510: Use frozendict in the stdlib (#144909) Co-authored-by: Donghee Na --- Lib/functools.py | 4 +- Lib/gettext.py | 5 +- Lib/json/decoder.py | 4 +- Lib/json/tool.py | 4 +- Lib/opcode.py | 152 ++++++++++++++++++++++---------------------- Lib/optparse.py | 10 +-- Lib/platform.py | 8 +-- Lib/plistlib.py | 2 +- Lib/ssl.py | 3 +- Lib/symtable.py | 2 +- Lib/tarfile.py | 4 +- 11 files changed, 101 insertions(+), 97 deletions(-) diff --git a/Lib/functools.py b/Lib/functools.py index 9bc2ee7e8c894c..cd374631f16792 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -170,7 +170,7 @@ def _lt_from_ge(self, other): return op_result return not op_result -_convert = { +_convert = frozendict({ '__lt__': [('__gt__', _gt_from_lt), ('__le__', _le_from_lt), ('__ge__', _ge_from_lt)], @@ -183,7 +183,7 @@ def _lt_from_ge(self, other): '__ge__': [('__le__', _le_from_ge), ('__gt__', _gt_from_ge), ('__lt__', _lt_from_ge)] -} +}) def total_ordering(cls): """Class decorator that fills in missing ordering methods""" diff --git a/Lib/gettext.py b/Lib/gettext.py index 6c11ab2b1eb570..2f77f0e849e9ae 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -111,8 +111,9 @@ def _error(value): ('+', '-'), ('*', '/', '%'), ) -_binary_ops = {op: i for i, ops in enumerate(_binary_ops, 1) for op in ops} -_c2py_ops = {'||': 'or', '&&': 'and', '/': '//'} +_binary_ops = frozendict({op: i for i, ops in enumerate(_binary_ops, 1) + for op in ops}) +_c2py_ops = frozendict({'||': 'or', '&&': 'and', '/': '//'}) def _parse(tokens, priority=-1): diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index 92ad6352557640..4cd6f8367a1349 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -43,11 +43,11 @@ def __reduce__(self): return self.__class__, (self.msg, self.doc, self.pos) -_CONSTANTS = { +_CONSTANTS = frozendict({ '-Infinity': NegInf, 'Infinity': PosInf, 'NaN': NaN, -} +}) HEXDIGITS = re.compile(r'[0-9A-Fa-f]{4}', FLAGS) diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 050c2fe2161e3e..e0b944b197d38b 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -22,13 +22,13 @@ (?Pnull) ''', re.VERBOSE) -_group_to_theme_color = { +_group_to_theme_color = frozendict({ "key": "definition", "string": "string", "number": "number", "boolean": "keyword", "null": "keyword", -} +}) def _colorize_json(json_str, theme): diff --git a/Lib/opcode.py b/Lib/opcode.py index f016b8dc4a50b2..165f42baed94e3 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -46,81 +46,81 @@ hascompare = [opmap["COMPARE_OP"]] -_cache_format = { - "LOAD_GLOBAL": { - "counter": 1, - "index": 1, - "module_keys_version": 1, - "builtin_keys_version": 1, - }, - "BINARY_OP": { - "counter": 1, - "descr": 4, - }, - "UNPACK_SEQUENCE": { - "counter": 1, - }, - "COMPARE_OP": { - "counter": 1, - }, - "CONTAINS_OP": { - "counter": 1, - }, - "FOR_ITER": { - "counter": 1, - }, - "LOAD_SUPER_ATTR": { - "counter": 1, - }, - "LOAD_ATTR": { - "counter": 1, - "version": 2, - "keys_version": 2, - "descr": 4, - }, - "STORE_ATTR": { - "counter": 1, - "version": 2, - "index": 1, - }, - "CALL": { - "counter": 1, - "func_version": 2, - }, - "CALL_KW": { - "counter": 1, - "func_version": 2, - }, - "CALL_FUNCTION_EX": { - "counter": 1, - }, - "STORE_SUBSCR": { - "counter": 1, - }, - "SEND": { - "counter": 1, - }, - "JUMP_BACKWARD": { - "counter": 1, - }, - "TO_BOOL": { - "counter": 1, - "version": 2, - }, - "POP_JUMP_IF_TRUE": { - "counter": 1, - }, - "POP_JUMP_IF_FALSE": { - "counter": 1, - }, - "POP_JUMP_IF_NONE": { - "counter": 1, - }, - "POP_JUMP_IF_NOT_NONE": { - "counter": 1, - }, -} +_cache_format = frozendict( + LOAD_GLOBAL=frozendict( + counter=1, + index=1, + module_keys_version=1, + builtin_keys_version=1, + ), + BINARY_OP=frozendict( + counter=1, + descr=4, + ), + UNPACK_SEQUENCE=frozendict( + counter=1, + ), + COMPARE_OP=frozendict( + counter=1, + ), + CONTAINS_OP=frozendict( + counter=1, + ), + FOR_ITER=frozendict( + counter=1, + ), + LOAD_SUPER_ATTR=frozendict( + counter=1, + ), + LOAD_ATTR=frozendict( + counter=1, + version=2, + keys_version=2, + descr=4, + ), + STORE_ATTR=frozendict( + counter=1, + version=2, + index=1, + ), + CALL=frozendict( + counter=1, + func_version=2, + ), + CALL_KW=frozendict( + counter=1, + func_version=2, + ), + CALL_FUNCTION_EX=frozendict( + counter=1, + ), + STORE_SUBSCR=frozendict( + counter=1, + ), + SEND=frozendict( + counter=1, + ), + JUMP_BACKWARD=frozendict( + counter=1, + ), + TO_BOOL=frozendict( + counter=1, + version=2, + ), + POP_JUMP_IF_TRUE=frozendict( + counter=1, + ), + POP_JUMP_IF_FALSE=frozendict( + counter=1, + ), + POP_JUMP_IF_NONE=frozendict( + counter=1, + ), + POP_JUMP_IF_NOT_NONE=frozendict( + counter=1, + ), +) -_inline_cache_entries = { +_inline_cache_entries = frozendict({ name : sum(value.values()) for (name, value) in _cache_format.items() -} +}) diff --git a/Lib/optparse.py b/Lib/optparse.py index 5ff7f74754f9c1..de1082442ef7f2 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -407,10 +407,12 @@ def _parse_num(val, type): def _parse_int(val): return _parse_num(val, int) -_builtin_cvt = { "int" : (_parse_int, _("integer")), - "long" : (_parse_int, _("integer")), - "float" : (float, _("floating-point")), - "complex" : (complex, _("complex")) } +_builtin_cvt = frozendict({ + "int": (_parse_int, _("integer")), + "long": (_parse_int, _("integer")), + "float": (float, _("floating-point")), + "complex": (complex, _("complex")), +}) def check_builtin(option, opt, value): (cvt, what) = _builtin_cvt[option.type] diff --git a/Lib/platform.py b/Lib/platform.py index 3a71b669985f13..9d7aa5c66a91cb 100644 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -127,7 +127,7 @@ # Based on the description of the PHP's version_compare(): # http://php.net/manual/en/function.version-compare.php -_ver_stages = { +_ver_stages = frozendict({ # any string not found in this dict, will get 0 assigned 'dev': 10, 'alpha': 20, 'a': 20, @@ -136,7 +136,7 @@ 'RC': 50, 'rc': 50, # number, will get 100 assigned 'pl': 200, 'p': 200, -} +}) def _comparable_version(version): @@ -705,11 +705,11 @@ def _syscmd_file(target, default=''): # Default values for architecture; non-empty strings override the # defaults given as parameters -_default_architecture = { +_default_architecture = frozendict({ 'win32': ('', 'WindowsPE'), 'win16': ('', 'Windows'), 'dos': ('', 'MSDOS'), -} +}) def architecture(executable=sys.executable, bits='', linkage=''): diff --git a/Lib/plistlib.py b/Lib/plistlib.py index cae38672f641b7..3c6a6b7bdc44d2 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -453,7 +453,7 @@ class InvalidFileException (ValueError): def __init__(self, message="Invalid file"): ValueError.__init__(self, message) -_BINARY_FORMAT = {1: 'B', 2: 'H', 4: 'L', 8: 'Q'} +_BINARY_FORMAT = frozendict({1: 'B', 2: 'H', 4: 'L', 8: 'Q'}) _undefined = object() diff --git a/Lib/ssl.py b/Lib/ssl.py index 612b32cd0765ec..896db17baeb3db 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -150,7 +150,8 @@ source=_ssl) PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS -_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} +_PROTOCOL_NAMES = frozendict({ + value: name for name, value in _SSLMethod.__members__.items()}) _SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None) diff --git a/Lib/symtable.py b/Lib/symtable.py index 45610fd5612995..c7152a70f5aa0b 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -414,7 +414,7 @@ def get_namespace(self): _flags = [('USE', USE)] _flags.extend(kv for kv in globals().items() if kv[0].startswith('DEF_')) _scopes_names = ('FREE', 'LOCAL', 'GLOBAL_IMPLICIT', 'GLOBAL_EXPLICIT', 'CELL') -_scopes_value_to_name = {globals()[n]: n for n in _scopes_names} +_scopes_value_to_name = frozendict({globals()[n]: n for n in _scopes_names}) def main(args): diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 75984bf8b262b9..7abda3653e764b 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -859,11 +859,11 @@ def data_filter(member, dest_path): return member.replace(**new_attrs, deep=False) return member -_NAMED_FILTERS = { +_NAMED_FILTERS = frozendict({ "fully_trusted": fully_trusted_filter, "tar": tar_filter, "data": data_filter, -} +}) #------------------ # Exported Classes From d3b6faf9758dce236d45c708a450437cdc3e97cd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:18:11 +0200 Subject: [PATCH 343/498] Docs: `import datetime as dt` in examples (#145315) --- Doc/includes/tzinfo_examples.py | 127 ++++++------- Doc/library/datetime.rst | 303 +++++++++++++++++--------------- 2 files changed, 224 insertions(+), 206 deletions(-) diff --git a/Doc/includes/tzinfo_examples.py b/Doc/includes/tzinfo_examples.py index 1fa6e615e46a76..762b1b62fc871d 100644 --- a/Doc/includes/tzinfo_examples.py +++ b/Doc/includes/tzinfo_examples.py @@ -1,68 +1,70 @@ -from datetime import tzinfo, timedelta, datetime - -ZERO = timedelta(0) -HOUR = timedelta(hours=1) -SECOND = timedelta(seconds=1) +import datetime as dt # A class capturing the platform's idea of local time. # (May result in wrong values on historical times in # timezones where UTC offset and/or the DST rules had # changed in the past.) -import time as _time +import time + +ZERO = dt.timedelta(0) +HOUR = dt.timedelta(hours=1) +SECOND = dt.timedelta(seconds=1) -STDOFFSET = timedelta(seconds = -_time.timezone) -if _time.daylight: - DSTOFFSET = timedelta(seconds = -_time.altzone) +STDOFFSET = dt.timedelta(seconds=-time.timezone) +if time.daylight: + DSTOFFSET = dt.timedelta(seconds=-time.altzone) else: DSTOFFSET = STDOFFSET DSTDIFF = DSTOFFSET - STDOFFSET -class LocalTimezone(tzinfo): - def fromutc(self, dt): - assert dt.tzinfo is self - stamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECOND - args = _time.localtime(stamp)[:6] +class LocalTimezone(dt.tzinfo): + + def fromutc(self, when): + assert when.tzinfo is self + stamp = (when - dt.datetime(1970, 1, 1, tzinfo=self)) // SECOND + args = time.localtime(stamp)[:6] dst_diff = DSTDIFF // SECOND # Detect fold - fold = (args == _time.localtime(stamp - dst_diff)) - return datetime(*args, microsecond=dt.microsecond, - tzinfo=self, fold=fold) + fold = (args == time.localtime(stamp - dst_diff)) + return dt.datetime(*args, microsecond=when.microsecond, + tzinfo=self, fold=fold) - def utcoffset(self, dt): - if self._isdst(dt): + def utcoffset(self, when): + if self._isdst(when): return DSTOFFSET else: return STDOFFSET - def dst(self, dt): - if self._isdst(dt): + def dst(self, when): + if self._isdst(when): return DSTDIFF else: return ZERO - def tzname(self, dt): - return _time.tzname[self._isdst(dt)] + def tzname(self, when): + return time.tzname[self._isdst(when)] - def _isdst(self, dt): - tt = (dt.year, dt.month, dt.day, - dt.hour, dt.minute, dt.second, - dt.weekday(), 0, 0) - stamp = _time.mktime(tt) - tt = _time.localtime(stamp) + def _isdst(self, when): + tt = (when.year, when.month, when.day, + when.hour, when.minute, when.second, + when.weekday(), 0, 0) + stamp = time.mktime(tt) + tt = time.localtime(stamp) return tt.tm_isdst > 0 + Local = LocalTimezone() # A complete implementation of current DST rules for major US time zones. -def first_sunday_on_or_after(dt): - days_to_go = 6 - dt.weekday() +def first_sunday_on_or_after(when): + days_to_go = 6 - when.weekday() if days_to_go: - dt += timedelta(days_to_go) - return dt + when += dt.timedelta(days_to_go) + return when # US DST Rules @@ -75,21 +77,22 @@ def first_sunday_on_or_after(dt): # # In the US, since 2007, DST starts at 2am (standard time) on the second # Sunday in March, which is the first Sunday on or after Mar 8. -DSTSTART_2007 = datetime(1, 3, 8, 2) +DSTSTART_2007 = dt.datetime(1, 3, 8, 2) # and ends at 2am (DST time) on the first Sunday of Nov. -DSTEND_2007 = datetime(1, 11, 1, 2) +DSTEND_2007 = dt.datetime(1, 11, 1, 2) # From 1987 to 2006, DST used to start at 2am (standard time) on the first # Sunday in April and to end at 2am (DST time) on the last # Sunday of October, which is the first Sunday on or after Oct 25. -DSTSTART_1987_2006 = datetime(1, 4, 1, 2) -DSTEND_1987_2006 = datetime(1, 10, 25, 2) +DSTSTART_1987_2006 = dt.datetime(1, 4, 1, 2) +DSTEND_1987_2006 = dt.datetime(1, 10, 25, 2) # From 1967 to 1986, DST used to start at 2am (standard time) on the last # Sunday in April (the one on or after April 24) and to end at 2am (DST time) # on the last Sunday of October, which is the first Sunday # on or after Oct 25. -DSTSTART_1967_1986 = datetime(1, 4, 24, 2) +DSTSTART_1967_1986 = dt.datetime(1, 4, 24, 2) DSTEND_1967_1986 = DSTEND_1987_2006 + def us_dst_range(year): # Find start and end times for US DST. For years before 1967, return # start = end for no DST. @@ -100,17 +103,17 @@ def us_dst_range(year): elif 1966 < year < 1987: dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986 else: - return (datetime(year, 1, 1), ) * 2 + return (dt.datetime(year, 1, 1), ) * 2 start = first_sunday_on_or_after(dststart.replace(year=year)) end = first_sunday_on_or_after(dstend.replace(year=year)) return start, end -class USTimeZone(tzinfo): +class USTimeZone(dt.tzinfo): def __init__(self, hours, reprname, stdname, dstname): - self.stdoffset = timedelta(hours=hours) + self.stdoffset = dt.timedelta(hours=hours) self.reprname = reprname self.stdname = stdname self.dstname = dstname @@ -118,45 +121,45 @@ def __init__(self, hours, reprname, stdname, dstname): def __repr__(self): return self.reprname - def tzname(self, dt): - if self.dst(dt): + def tzname(self, when): + if self.dst(when): return self.dstname else: return self.stdname - def utcoffset(self, dt): - return self.stdoffset + self.dst(dt) + def utcoffset(self, when): + return self.stdoffset + self.dst(when) - def dst(self, dt): - if dt is None or dt.tzinfo is None: + def dst(self, when): + if when is None or when.tzinfo is None: # An exception may be sensible here, in one or both cases. # It depends on how you want to treat them. The default # fromutc() implementation (called by the default astimezone() - # implementation) passes a datetime with dt.tzinfo is self. + # implementation) passes a datetime with when.tzinfo is self. return ZERO - assert dt.tzinfo is self - start, end = us_dst_range(dt.year) + assert when.tzinfo is self + start, end = us_dst_range(when.year) # Can't compare naive to aware objects, so strip the timezone from - # dt first. - dt = dt.replace(tzinfo=None) - if start + HOUR <= dt < end - HOUR: + # when first. + when = when.replace(tzinfo=None) + if start + HOUR <= when < end - HOUR: # DST is in effect. return HOUR - if end - HOUR <= dt < end: - # Fold (an ambiguous hour): use dt.fold to disambiguate. - return ZERO if dt.fold else HOUR - if start <= dt < start + HOUR: + if end - HOUR <= when < end: + # Fold (an ambiguous hour): use when.fold to disambiguate. + return ZERO if when.fold else HOUR + if start <= when < start + HOUR: # Gap (a non-existent hour): reverse the fold rule. - return HOUR if dt.fold else ZERO + return HOUR if when.fold else ZERO # DST is off. return ZERO - def fromutc(self, dt): - assert dt.tzinfo is self - start, end = us_dst_range(dt.year) + def fromutc(self, when): + assert when.tzinfo is self + start, end = us_dst_range(when.year) start = start.replace(tzinfo=self) end = end.replace(tzinfo=self) - std_time = dt + self.stdoffset + std_time = when + self.stdoffset dst_time = std_time + HOUR if end <= dst_time < end + HOUR: # Repeated hour diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index ebe3c3576c0979..73217136f14472 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -230,8 +230,8 @@ A :class:`timedelta` object represents a duration, the difference between two *days*, *seconds* and *microseconds* are "merged" and normalized into those three resulting attributes:: - >>> from datetime import timedelta - >>> delta = timedelta( + >>> import datetime as dt + >>> delta = dt.timedelta( ... days=50, ... seconds=27, ... microseconds=10, @@ -244,6 +244,12 @@ A :class:`timedelta` object represents a duration, the difference between two >>> delta datetime.timedelta(days=64, seconds=29156, microseconds=10) + .. tip:: + ``import datetime as dt`` instead of ``import datetime`` or + ``from datetime import datetime`` to avoid confusion between the module + and the class. See `How I Import Python’s datetime Module + `__. + If any argument is a float and there are fractional microseconds, the fractional microseconds left over from all arguments are combined and their sum is rounded to the nearest microsecond using @@ -257,8 +263,8 @@ A :class:`timedelta` object represents a duration, the difference between two Note that normalization of negative values may be surprising at first. For example:: - >>> from datetime import timedelta - >>> d = timedelta(microseconds=-1) + >>> import datetime as dt + >>> d = dt.timedelta(microseconds=-1) >>> (d.days, d.seconds, d.microseconds) (-1, 86399, 999999) @@ -321,8 +327,8 @@ Instance attributes (read-only): .. doctest:: - >>> from datetime import timedelta - >>> duration = timedelta(seconds=11235813) + >>> import datetime as dt + >>> duration = dt.timedelta(seconds=11235813) >>> duration.days, duration.seconds (130, 3813) >>> duration.total_seconds() @@ -461,10 +467,10 @@ Examples of usage: :class:`!timedelta` An additional example of normalization:: >>> # Components of another_year add up to exactly 365 days - >>> from datetime import timedelta - >>> year = timedelta(days=365) - >>> another_year = timedelta(weeks=40, days=84, hours=23, - ... minutes=50, seconds=600) + >>> import datetime as dt + >>> year = dt.timedelta(days=365) + >>> another_year = dt.timedelta(weeks=40, days=84, hours=23, + ... minutes=50, seconds=600) >>> year == another_year True >>> year.total_seconds() @@ -472,8 +478,8 @@ An additional example of normalization:: Examples of :class:`timedelta` arithmetic:: - >>> from datetime import timedelta - >>> year = timedelta(days=365) + >>> import datetime as dt + >>> year = dt.timedelta(days=365) >>> ten_years = 10 * year >>> ten_years datetime.timedelta(days=3650) @@ -565,12 +571,12 @@ Other constructors, all class methods: Examples:: - >>> from datetime import date - >>> date.fromisoformat('2019-12-04') + >>> import datetime as dt + >>> dt.date.fromisoformat('2019-12-04') datetime.date(2019, 12, 4) - >>> date.fromisoformat('20191204') + >>> dt.date.fromisoformat('20191204') datetime.date(2019, 12, 4) - >>> date.fromisoformat('2021-W01-1') + >>> dt.date.fromisoformat('2021-W01-1') datetime.date(2021, 1, 4) .. versionadded:: 3.7 @@ -611,9 +617,9 @@ Other constructors, all class methods: .. doctest:: - >>> from datetime import date + >>> import datetime as dt >>> date_string = "02/29" - >>> when = date.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug. + >>> when = dt.date.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug. >>> when.strftime("%B %d") # doctest: +SKIP 'February 29' @@ -728,8 +734,8 @@ Instance methods: Example:: - >>> from datetime import date - >>> d = date(2002, 12, 31) + >>> import datetime as dt + >>> d = dt.date(2002, 12, 31) >>> d.replace(day=26) datetime.date(2002, 12, 26) @@ -787,10 +793,10 @@ Instance methods: For example, 2004 begins on a Thursday, so the first week of ISO year 2004 begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004:: - >>> from datetime import date - >>> date(2003, 12, 29).isocalendar() + >>> import datetime as dt + >>> dt.date(2003, 12, 29).isocalendar() datetime.IsoCalendarDate(year=2004, week=1, weekday=1) - >>> date(2004, 1, 4).isocalendar() + >>> dt.date(2004, 1, 4).isocalendar() datetime.IsoCalendarDate(year=2004, week=1, weekday=7) .. versionchanged:: 3.9 @@ -801,8 +807,8 @@ Instance methods: Return a string representing the date in ISO 8601 format, ``YYYY-MM-DD``:: - >>> from datetime import date - >>> date(2002, 12, 4).isoformat() + >>> import datetime as dt + >>> dt.date(2002, 12, 4).isoformat() '2002-12-04' @@ -815,8 +821,8 @@ Instance methods: Return a string representing the date:: - >>> from datetime import date - >>> date(2002, 12, 4).ctime() + >>> import datetime as dt + >>> dt.date(2002, 12, 4).ctime() 'Wed Dec 4 00:00:00 2002' ``d.ctime()`` is equivalent to:: @@ -849,13 +855,13 @@ Examples of usage: :class:`!date` Example of counting days to an event:: >>> import time - >>> from datetime import date - >>> today = date.today() + >>> import datetime as dt + >>> today = dt.date.today() >>> today datetime.date(2007, 12, 5) - >>> today == date.fromtimestamp(time.time()) + >>> today == dt.date.fromtimestamp(time.time()) True - >>> my_birthday = date(today.year, 6, 24) + >>> my_birthday = dt.date(today.year, 6, 24) >>> if my_birthday < today: ... my_birthday = my_birthday.replace(year=today.year + 1) ... @@ -869,8 +875,8 @@ More examples of working with :class:`date`: .. doctest:: - >>> from datetime import date - >>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001 + >>> import datetime as dt + >>> d = dt.date.fromordinal(730920) # 730920th day after 1. 1. 0001 >>> d datetime.date(2002, 3, 11) @@ -1123,24 +1129,24 @@ Other constructors, all class methods: Examples:: - >>> from datetime import datetime - >>> datetime.fromisoformat('2011-11-04') + >>> import datetime as dt + >>> dt.datetime.fromisoformat('2011-11-04') datetime.datetime(2011, 11, 4, 0, 0) - >>> datetime.fromisoformat('20111104') + >>> dt.datetime.fromisoformat('20111104') datetime.datetime(2011, 11, 4, 0, 0) - >>> datetime.fromisoformat('2011-11-04T00:05:23') + >>> dt.datetime.fromisoformat('2011-11-04T00:05:23') datetime.datetime(2011, 11, 4, 0, 5, 23) - >>> datetime.fromisoformat('2011-11-04T00:05:23Z') + >>> dt.datetime.fromisoformat('2011-11-04T00:05:23Z') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc) - >>> datetime.fromisoformat('20111104T000523') + >>> dt.datetime.fromisoformat('20111104T000523') datetime.datetime(2011, 11, 4, 0, 5, 23) - >>> datetime.fromisoformat('2011-W01-2T00:05:23.283') + >>> dt.datetime.fromisoformat('2011-W01-2T00:05:23.283') datetime.datetime(2011, 1, 4, 0, 5, 23, 283000) - >>> datetime.fromisoformat('2011-11-04 00:05:23.283') + >>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000) - >>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00') + >>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283+00:00') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc) - >>> datetime.fromisoformat('2011-11-04T00:05:23+04:00') # doctest: +NORMALIZE_WHITESPACE + >>> dt.datetime.fromisoformat('2011-11-04T00:05:23+04:00') # doctest: +NORMALIZE_WHITESPACE datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400))) @@ -1187,9 +1193,9 @@ Other constructors, all class methods: .. doctest:: - >>> from datetime import datetime + >>> import datetime as dt >>> date_string = "02/29" - >>> when = datetime.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug. + >>> when = dt.datetime.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug. >>> when.strftime("%B %d") # doctest: +SKIP 'February 29' @@ -1599,24 +1605,24 @@ Instance methods: Examples:: - >>> from datetime import datetime, timezone - >>> datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat() + >>> import datetime as dt + >>> dt.datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat() '2019-05-18T15:17:08.132263' - >>> datetime(2019, 5, 18, 15, 17, tzinfo=timezone.utc).isoformat() + >>> dt.datetime(2019, 5, 18, 15, 17, tzinfo=dt.timezone.utc).isoformat() '2019-05-18T15:17:00+00:00' The optional argument *sep* (default ``'T'``) is a one-character separator, placed between the date and time portions of the result. For example:: - >>> from datetime import tzinfo, timedelta, datetime - >>> class TZ(tzinfo): + >>> import datetime as dt + >>> class TZ(dt.tzinfo): ... """A time zone with an arbitrary, constant -06:39 offset.""" - ... def utcoffset(self, dt): - ... return timedelta(hours=-6, minutes=-39) + ... def utcoffset(self, when): + ... return dt.timedelta(hours=-6, minutes=-39) ... - >>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') + >>> dt.datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') '2002-12-25 00:00:00-06:39' - >>> datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat() + >>> dt.datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat() '2009-11-27T00:00:00.000100-06:39' The optional argument *timespec* specifies the number of additional @@ -1640,11 +1646,11 @@ Instance methods: :exc:`ValueError` will be raised on an invalid *timespec* argument:: - >>> from datetime import datetime - >>> datetime.now().isoformat(timespec='minutes') # doctest: +SKIP + >>> import datetime as dt + >>> dt.datetime.now().isoformat(timespec='minutes') # doctest: +SKIP '2002-12-25T00:00' - >>> dt = datetime(2015, 1, 1, 12, 30, 59, 0) - >>> dt.isoformat(timespec='microseconds') + >>> my_datetime = dt.datetime(2015, 1, 1, 12, 30, 59, 0) + >>> my_datetime.isoformat(timespec='microseconds') '2015-01-01T12:30:59.000000' .. versionchanged:: 3.6 @@ -1661,8 +1667,8 @@ Instance methods: Return a string representing the date and time:: - >>> from datetime import datetime - >>> datetime(2002, 12, 4, 20, 30, 40).ctime() + >>> import datetime as dt + >>> dt.datetime(2002, 12, 4, 20, 30, 40).ctime() 'Wed Dec 4 20:30:40 2002' The output string will *not* include time zone information, regardless @@ -1699,27 +1705,27 @@ Examples of working with :class:`.datetime` objects: .. doctest:: - >>> from datetime import datetime, date, time, timezone + >>> import datetime as dt >>> # Using datetime.combine() - >>> d = date(2005, 7, 14) - >>> t = time(12, 30) - >>> datetime.combine(d, t) + >>> d = dt.date(2005, 7, 14) + >>> t = dt.time(12, 30) + >>> dt.datetime.combine(d, t) datetime.datetime(2005, 7, 14, 12, 30) >>> # Using datetime.now() - >>> datetime.now() # doctest: +SKIP + >>> dt.datetime.now() # doctest: +SKIP datetime.datetime(2007, 12, 6, 16, 29, 43, 79043) # GMT +1 - >>> datetime.now(timezone.utc) # doctest: +SKIP + >>> dt.datetime.now(dt.timezone.utc) # doctest: +SKIP datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc) >>> # Using datetime.strptime() - >>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") - >>> dt + >>> my_datetime = dt.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") + >>> my_datetime datetime.datetime(2006, 11, 21, 16, 30) >>> # Using datetime.timetuple() to get tuple of all attributes - >>> tt = dt.timetuple() + >>> tt = my_datetime.timetuple() >>> for it in tt: # doctest: +SKIP ... print(it) ... @@ -1734,7 +1740,7 @@ Examples of working with :class:`.datetime` objects: -1 # dst - method tzinfo.dst() returned None >>> # Date in ISO format - >>> ic = dt.isocalendar() + >>> ic = my_datetime.isocalendar() >>> for it in ic: # doctest: +SKIP ... print(it) ... @@ -1743,55 +1749,55 @@ Examples of working with :class:`.datetime` objects: 2 # ISO weekday >>> # Formatting a datetime - >>> dt.strftime("%A, %d. %B %Y %I:%M%p") + >>> my_datetime.strftime("%A, %d. %B %Y %I:%M%p") 'Tuesday, 21. November 2006 04:30PM' - >>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time") + >>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(my_datetime, "day", "month", "time") 'The day is 21, the month is November, the time is 04:30PM.' The example below defines a :class:`tzinfo` subclass capturing time zone information for Kabul, Afghanistan, which used +4 UTC until 1945 and then +4:30 UTC thereafter:: - from datetime import timedelta, datetime, tzinfo, timezone + import datetime as dt - class KabulTz(tzinfo): + class KabulTz(dt.tzinfo): # Kabul used +4 until 1945, when they moved to +4:30 - UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc) + UTC_MOVE_DATE = dt.datetime(1944, 12, 31, 20, tzinfo=dt.timezone.utc) - def utcoffset(self, dt): - if dt.year < 1945: - return timedelta(hours=4) - elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30): + def utcoffset(self, when): + if when.year < 1945: + return dt.timedelta(hours=4) + elif (1945, 1, 1, 0, 0) <= when.timetuple()[:5] < (1945, 1, 1, 0, 30): # An ambiguous ("imaginary") half-hour range representing # a 'fold' in time due to the shift from +4 to +4:30. - # If dt falls in the imaginary range, use fold to decide how - # to resolve. See PEP495. - return timedelta(hours=4, minutes=(30 if dt.fold else 0)) + # If when falls in the imaginary range, use fold to decide how + # to resolve. See PEP 495. + return dt.timedelta(hours=4, minutes=(30 if when.fold else 0)) else: - return timedelta(hours=4, minutes=30) + return dt.timedelta(hours=4, minutes=30) - def fromutc(self, dt): + def fromutc(self, when): # Follow same validations as in datetime.tzinfo - if not isinstance(dt, datetime): + if not isinstance(when, dt.datetime): raise TypeError("fromutc() requires a datetime argument") - if dt.tzinfo is not self: - raise ValueError("dt.tzinfo is not self") + if when.tzinfo is not self: + raise ValueError("when.tzinfo is not self") # A custom implementation is required for fromutc as # the input to this function is a datetime with utc values # but with a tzinfo set to self. # See datetime.astimezone or fromtimestamp. - if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE: - return dt + timedelta(hours=4, minutes=30) + if when.replace(tzinfo=dt.timezone.utc) >= self.UTC_MOVE_DATE: + return when + dt.timedelta(hours=4, minutes=30) else: - return dt + timedelta(hours=4) + return when + dt.timedelta(hours=4) - def dst(self, dt): + def dst(self, when): # Kabul does not observe daylight saving time. - return timedelta(0) + return dt.timedelta(0) - def tzname(self, dt): - if dt >= self.UTC_MOVE_DATE: + def tzname(self, when): + if when >= self.UTC_MOVE_DATE: return "+04:30" return "+04" @@ -1800,17 +1806,17 @@ Usage of ``KabulTz`` from above:: >>> tz1 = KabulTz() >>> # Datetime before the change - >>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1) + >>> dt1 = dt.datetime(1900, 11, 21, 16, 30, tzinfo=tz1) >>> print(dt1.utcoffset()) 4:00:00 >>> # Datetime after the change - >>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1) + >>> dt2 = dt.datetime(2006, 6, 14, 13, 0, tzinfo=tz1) >>> print(dt2.utcoffset()) 4:30:00 >>> # Convert datetime to another time zone - >>> dt3 = dt2.astimezone(timezone.utc) + >>> dt3 = dt2.astimezone(dt.timezone.utc) >>> dt3 datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc) >>> dt2 @@ -1946,22 +1952,22 @@ Other constructors: .. doctest:: - >>> from datetime import time - >>> time.fromisoformat('04:23:01') + >>> import datetime as dt + >>> dt.time.fromisoformat('04:23:01') datetime.time(4, 23, 1) - >>> time.fromisoformat('T04:23:01') + >>> dt.time.fromisoformat('T04:23:01') datetime.time(4, 23, 1) - >>> time.fromisoformat('T042301') + >>> dt.time.fromisoformat('T042301') datetime.time(4, 23, 1) - >>> time.fromisoformat('04:23:01.000384') + >>> dt.time.fromisoformat('04:23:01.000384') datetime.time(4, 23, 1, 384) - >>> time.fromisoformat('04:23:01,000384') + >>> dt.time.fromisoformat('04:23:01,000384') datetime.time(4, 23, 1, 384) - >>> time.fromisoformat('04:23:01+04:00') + >>> dt.time.fromisoformat('04:23:01+04:00') datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400))) - >>> time.fromisoformat('04:23:01Z') + >>> dt.time.fromisoformat('04:23:01Z') datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc) - >>> time.fromisoformat('04:23:01+00:00') + >>> dt.time.fromisoformat('04:23:01+00:00') datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc) @@ -2036,13 +2042,13 @@ Instance methods: Example:: - >>> from datetime import time - >>> time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes') + >>> import datetime as dt + >>> dt.time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes') '12:34' - >>> dt = time(hour=12, minute=34, second=56, microsecond=0) - >>> dt.isoformat(timespec='microseconds') + >>> my_time = dt.time(hour=12, minute=34, second=56, microsecond=0) + >>> my_time.isoformat(timespec='microseconds') '12:34:56.000000' - >>> dt.isoformat(timespec='auto') + >>> my_time.isoformat(timespec='auto') '12:34:56' .. versionchanged:: 3.6 @@ -2100,18 +2106,18 @@ Examples of usage: :class:`!time` Examples of working with a :class:`.time` object:: - >>> from datetime import time, tzinfo, timedelta - >>> class TZ1(tzinfo): - ... def utcoffset(self, dt): - ... return timedelta(hours=1) - ... def dst(self, dt): - ... return timedelta(0) - ... def tzname(self,dt): + >>> import datetime as dt + >>> class TZ1(dt.tzinfo): + ... def utcoffset(self, when): + ... return dt.timedelta(hours=1) + ... def dst(self, when): + ... return dt.timedelta(0) + ... def tzname(self, when): ... return "+01:00" ... def __repr__(self): ... return f"{self.__class__.__name__}()" ... - >>> t = time(12, 10, 30, tzinfo=TZ1()) + >>> t = dt.time(12, 10, 30, tzinfo=TZ1()) >>> t datetime.time(12, 10, 30, tzinfo=TZ1()) >>> t.isoformat() @@ -2219,21 +2225,25 @@ Examples of working with a :class:`.time` object:: Most implementations of :meth:`dst` will probably look like one of these two:: - def dst(self, dt): + import datetime as dt + + def dst(self, when): # a fixed-offset class: doesn't account for DST - return timedelta(0) + return dt.timedelta(0) or:: - def dst(self, dt): + import datetime as dt + + def dst(self, when): # Code to set dston and dstoff to the time zone's DST - # transition times based on the input dt.year, and expressed + # transition times based on the input when.year, and expressed # in standard local time. - if dston <= dt.replace(tzinfo=None) < dstoff: - return timedelta(hours=1) + if dston <= when.replace(tzinfo=None) < dstoff: + return dt.timedelta(hours=1) else: - return timedelta(0) + return dt.timedelta(0) The default implementation of :meth:`dst` raises :exc:`NotImplementedError`. @@ -2299,20 +2309,22 @@ There is one more :class:`tzinfo` method that a subclass may wish to override: Skipping code for error cases, the default :meth:`fromutc` implementation acts like:: - def fromutc(self, dt): - # raise ValueError error if dt.tzinfo is not self - dtoff = dt.utcoffset() - dtdst = dt.dst() + import datetime as dt + + def fromutc(self, when): + # raise ValueError error if when.tzinfo is not self + dtoff = when.utcoffset() + dtdst = when.dst() # raise ValueError if dtoff is None or dtdst is None delta = dtoff - dtdst # this is self's standard offset if delta: - dt += delta # convert to standard local time - dtdst = dt.dst() + when += delta # convert to standard local time + dtdst = when.dst() # raise ValueError if dtdst is None if dtdst: - return dt + dtdst + return when + dtdst else: - return dt + return when In the following :download:`tzinfo_examples.py <../includes/tzinfo_examples.py>` file there are some examples of @@ -2339,9 +2351,9 @@ When DST starts (the "start" line), the local wall clock leaps from 1:59 to ``astimezone(Eastern)`` won't deliver a result with ``hour == 2`` on the day DST begins. For example, at the Spring forward transition of 2016, we get:: - >>> from datetime import datetime, timezone + >>> import datetime as dt >>> from tzinfo_examples import HOUR, Eastern - >>> u0 = datetime(2016, 3, 13, 5, tzinfo=timezone.utc) + >>> u0 = dt.datetime(2016, 3, 13, 5, tzinfo=dt.timezone.utc) >>> for i in range(4): ... u = u0 + i*HOUR ... t = u.astimezone(Eastern) @@ -2364,7 +2376,9 @@ form 5:MM and 6:MM both map to 1:MM when converted to Eastern, but earlier times have the :attr:`~.datetime.fold` attribute set to 0 and the later times have it set to 1. For example, at the Fall back transition of 2016, we get:: - >>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc) + >>> import datetime as dt + >>> from tzinfo_examples import HOUR, Eastern + >>> u0 = dt.datetime(2016, 11, 6, 4, tzinfo=dt.timezone.utc) >>> for i in range(4): ... u = u0 + i*HOUR ... t = u.astimezone(Eastern) @@ -2515,8 +2529,9 @@ versus :meth:`~.datetime.strptime`: These methods accept format codes that can be used to parse and format dates:: - >>> datetime.strptime('31/01/22 23:59:59.999999', - ... '%d/%m/%y %H:%M:%S.%f') + >>> import datetime as dt + >>> dt.datetime.strptime('31/01/22 23:59:59.999999', + ... '%d/%m/%y %H:%M:%S.%f') datetime.datetime(2022, 1, 31, 23, 59, 59, 999999) >>> _.strftime('%a %d %b %Y, %I:%M%p') 'Mon 31 Jan 2022, 11:59PM' @@ -2745,13 +2760,13 @@ in the format string will be pulled from the default value. .. doctest:: - >>> from datetime import datetime + >>> import datetime as dt >>> value = "2/29" - >>> datetime.strptime(value, "%m/%d") + >>> dt.datetime.strptime(value, "%m/%d") Traceback (most recent call last): ... ValueError: day 29 must be in range 1..28 for month 2 in year 1900 - >>> datetime.strptime(f"1904 {value}", "%Y %m/%d") + >>> dt.datetime.strptime(f"1904 {value}", "%Y %m/%d") datetime.datetime(1904, 2, 29, 0, 0) Using ``datetime.strptime(date_string, format)`` is equivalent to:: @@ -2897,7 +2912,7 @@ Notes: .. doctest:: >>> month_day = "02/29" - >>> datetime.strptime(f"{month_day};1984", "%m/%d;%Y") # No leap year bug. + >>> dt.datetime.strptime(f"{month_day};1984", "%m/%d;%Y") # No leap year bug. datetime.datetime(1984, 2, 29, 0, 0) .. deprecated-removed:: 3.13 3.15 @@ -2908,7 +2923,7 @@ Notes: .. rubric:: Footnotes -.. [#] If, that is, we ignore the effects of Relativity +.. [#] If, that is, we ignore the effects of relativity. .. [#] This matches the definition of the "proleptic Gregorian" calendar in Dershowitz and Reingold's book *Calendrical Calculations*, From d931725bc850cd096f6703bc285e885f1e015f05 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Fri, 6 Mar 2026 13:22:21 +0100 Subject: [PATCH 344/498] gh-144370: Disallow usage of control characters in status in wsgiref.handlers for security (#144371) Disallow usage of control characters in status in wsgiref.handlers to prevent HTTP header injections. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Victor Stinner --- Lib/test/test_wsgiref.py | 19 +++++++++++++++++++ Lib/wsgiref/handlers.py | 4 +++- Misc/ACKS | 1 + ...-01-31-21-56-54.gh-issue-144370.fp9m8t.rst | 2 ++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index a7a5c5ba33d493..3379df37d38ca8 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -855,6 +855,25 @@ def write(self, b): self.assertIsNotNone(h.status) self.assertIsNotNone(h.environ) + def testRaisesControlCharacters(self): + for c0 in control_characters_c0(): + with self.subTest(c0): + base = BaseHandler() + with self.assertRaises(ValueError): + base.start_response(c0, [('x', 'y')]) + + base = BaseHandler() + with self.assertRaises(ValueError): + base.start_response('200 OK', [(c0, 'y')]) + + # HTAB (\x09) is allowed in header values, but not in names. + base = BaseHandler() + if c0 != "\t": + with self.assertRaises(ValueError): + base.start_response('200 OK', [('x', c0)]) + else: + base.start_response('200 OK', [('x', c0)]) + class TestModule(unittest.TestCase): def test_deprecated__version__(self): diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index 9353fb678625b3..b82862deea7d74 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -1,7 +1,7 @@ """Base classes for server/gateway implementations""" from .util import FileWrapper, guess_scheme, is_hop_by_hop -from .headers import Headers +from .headers import Headers, _name_disallowed_re import sys, os, time @@ -250,6 +250,8 @@ def start_response(self, status, headers,exc_info=None): return self.write def _validate_status(self, status): + if _name_disallowed_re.search(status): + raise ValueError("Control characters are not allowed in status") if len(status) < 4: raise AssertionError("Status must be at least 4 characters") if not status[:3].isdigit(): diff --git a/Misc/ACKS b/Misc/ACKS index e38bda37bfa92d..88c0a68f1e6c87 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1086,6 +1086,7 @@ Wolfgang Langner Detlef Lannert Rémi Lapeyre Soren Larsen +Seth Michael Larson Amos Latteier Keenan Lau Piers Lauder diff --git a/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst b/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst new file mode 100644 index 00000000000000..2d13a0611322c5 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst @@ -0,0 +1,2 @@ +Disallow usage of control characters in status in :mod:`wsgiref.handlers` to prevent HTTP header injections. +Patch by Benedikt Johannes. From 6c8c72f7feb4207c62ac857443943e61977d6a94 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Mar 2026 16:51:36 +0100 Subject: [PATCH 345/498] gh-145548: Use VMADDR_CID_LOCAL in VSOCK socket tests (#145589) Prefer VMADDR_CID_LOCAL instead of VMADDR_CID_ANY for bind() in the server. Skip the test if bind() fails with EADDRNOTAVAIL. Log vsock CID in test.pythoninfo. --- Lib/test/pythoninfo.py | 4 ++++ Lib/test/test_socket.py | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 6df59946574a17..219fbb4bb1bbe2 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -751,6 +751,10 @@ def collect_test_socket(info_add): if name.startswith('HAVE_')] copy_attributes(info_add, test_socket, 'test_socket.%s', attributes) + # Get IOCTL_VM_SOCKETS_GET_LOCAL_CID of /dev/vsock + cid = test_socket.get_cid() + info_add('test_socket.get_cid', cid) + def collect_support(info_add): try: diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 9ad5b29ea58ecb..9e03069494345b 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -563,8 +563,8 @@ def clientTearDown(self): @unittest.skipIf(WSL, 'VSOCK does not work on Microsoft WSL') @unittest.skipUnless(HAVE_SOCKET_VSOCK, 'VSOCK sockets required for this test.') -@unittest.skipUnless(get_cid() != 2, # VMADDR_CID_HOST - "This test can only be run on a virtual guest.") +@unittest.skipIf(get_cid() == getattr(socket, 'VMADDR_CID_HOST', 2), + "This test can only be run on a virtual guest.") class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): def __init__(self, methodName='runTest'): @@ -574,7 +574,16 @@ def __init__(self, methodName='runTest'): def setUp(self): self.serv = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) self.addCleanup(self.serv.close) - self.serv.bind((socket.VMADDR_CID_ANY, VSOCKPORT)) + cid = get_cid() + if cid in (socket.VMADDR_CID_HOST, socket.VMADDR_CID_ANY): + cid = socket.VMADDR_CID_LOCAL + try: + self.serv.bind((cid, VSOCKPORT)) + except OSError as exc: + if exc.errno == errno.EADDRNOTAVAIL: + self.skipTest(f"bind() failed with {exc!r}") + else: + raise self.serv.listen() self.serverExplicitReady() self.serv.settimeout(support.LOOPBACK_TIMEOUT) From b28e5f58ebf8d9badcc893cd189cb1575d4e3614 Mon Sep 17 00:00:00 2001 From: Andrew Barnes Date: Fri, 6 Mar 2026 11:10:12 -0500 Subject: [PATCH 346/498] gh-69223: Document that add_argument() returns an Action object (#145538) --- Doc/library/argparse.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 8f31e815e0eb4b..5a463ee9821d61 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -698,6 +698,8 @@ The add_argument() method * deprecated_ - Whether or not use of the argument is deprecated. + The method returns an :class:`Action` object representing the argument. + The following sections describe how each of these are used. From 1d091a336e60b703a7d7ae4124f652eabe144f4e Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 6 Mar 2026 12:01:06 -0500 Subject: [PATCH 347/498] gh-145566: Skip stop-the-world when reassigning `__class__` on newly created objects (gh-145567) --- ...26-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst | 2 ++ Objects/typeobject.c | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst new file mode 100644 index 00000000000000..723b81ddc5f897 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst @@ -0,0 +1,2 @@ +In the free threading build, skip the stop-the-world pause when reassigning +``__class__`` on a newly created object. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1fdd3cbdaaa639..27ec8bb40a929f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7568,7 +7568,11 @@ object_set_class_world_stopped(PyObject *self, PyTypeObject *newto) assert(_PyObject_GetManagedDict(self) == dict); - if (_PyDict_DetachFromObject(dict, self) < 0) { + int err; + Py_BEGIN_CRITICAL_SECTION(dict); + err = _PyDict_DetachFromObject(dict, self); + Py_END_CRITICAL_SECTION(); + if (err < 0) { return -1; } @@ -7608,10 +7612,15 @@ object_set_class(PyObject *self, PyObject *value, void *closure) return -1; } - types_stop_world(); + int unique = _PyObject_IsUniquelyReferenced(self); + if (!unique) { + types_stop_world(); + } PyTypeObject *oldto = Py_TYPE(self); int res = object_set_class_world_stopped(self, newto); - types_start_world(); + if (!unique) { + types_start_world(); + } if (res == 0) { if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) { Py_DECREF(oldto); From c1d77683213c400fca144692654845e6f5418981 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 6 Mar 2026 21:00:06 +0100 Subject: [PATCH 348/498] gh-145376: Fix crashes in `md5module.c` and `hmacmodule.c` (#145422) Fix a possible NULL pointer dereference in `md5module.c` and a double-free in `hmacmodule.c`. Those crashes only occur in error paths taken when the interpreter fails to allocate memory. --- .../Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst | 2 ++ Modules/hmacmodule.c | 4 ++-- Modules/md5module.c | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst diff --git a/Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst b/Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst new file mode 100644 index 00000000000000..b6dbda0427181d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst @@ -0,0 +1,2 @@ +Fix double free and null pointer dereference in unusual error scenarios +in :mod:`hashlib` and :mod:`hmac` modules. diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index 7a040103bcb234..1a212fa3d37e18 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -1378,7 +1378,6 @@ static void py_hmac_hinfo_ht_free(void *hinfo) { py_hmac_hinfo *entry = (py_hmac_hinfo *)hinfo; - assert(entry->display_name != NULL); if (--(entry->refcnt) == 0) { Py_CLEAR(entry->display_name); PyMem_Free(hinfo); @@ -1477,7 +1476,8 @@ py_hmac_hinfo_ht_new(void) e->hashlib_name == NULL ? e->name : e->hashlib_name ); if (value->display_name == NULL) { - PyMem_Free(value); + /* 'value' is owned by the table (refcnt > 0), + so _Py_hashtable_destroy() will free it. */ goto error; } } diff --git a/Modules/md5module.c b/Modules/md5module.c index 56e9faf4c62002..e598b1fe67240d 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -87,7 +87,10 @@ static void MD5_dealloc(PyObject *op) { MD5object *ptr = _MD5object_CAST(op); - Hacl_Hash_MD5_free(ptr->hash_state); + if (ptr->hash_state != NULL) { + Hacl_Hash_MD5_free(ptr->hash_state); + ptr->hash_state = NULL; + } PyTypeObject *tp = Py_TYPE(op); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); From 9159287f58f7a5a7e59edffaf3094ea62e1633eb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Mar 2026 22:57:44 +0100 Subject: [PATCH 349/498] gh-144175: Add PyArg_ParseArray() function (#144283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PyArg_ParseArray() and PyArg_ParseArrayAndKeywords() functions to parse arguments of functions using the METH_FASTCALL calling convention. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/c-api/arg.rst | 22 +++ Doc/whatsnew/3.15.rst | 5 + Include/cpython/modsupport.h | 13 ++ Lib/test/test_capi/test_modsupport.py | 19 +++ ...-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst | 3 + Modules/_testcapi/modsupport.c | 28 ++++ Python/getargs.c | 128 ++++++++++++++++-- 7 files changed, 204 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index fd6be6a9b67a03..4a3a6347239c4f 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -516,6 +516,28 @@ API Functions } +.. c:function:: int PyArg_ParseArray(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) + + Parse the parameters of a function that takes only array parameters into + local variables (that is, a function using the :c:macro:`METH_FASTCALL` + calling convention). + Returns true on success; on failure, it returns false and raises the + appropriate exception. + + .. versionadded:: next + + +.. c:function:: int PyArg_ParseArrayAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, const char *format, const char * const *kwlist, ...) + + Parse the parameters of a function that takes both array and keyword + parameters into local variables (that is, a function using the + :c:macro:`METH_FASTCALL` ``|`` :c:macro:`METH_KEYWORDS` calling convention). + Returns true on success; on failure, it returns false and raises the + appropriate exception. + + .. versionadded:: next + + .. c:function:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) A simpler form of parameter retrieval which does not use a format string to diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 0b5902bb013436..42b6171c1a83a2 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1607,6 +1607,11 @@ C API changes New features ------------ +* Add :c:func:`PyArg_ParseArray` and :c:func:`PyArg_ParseArrayAndKeywords` + functions to parse arguments of functions using the :c:macro:`METH_FASTCALL` + calling convention. + (Contributed by Victor Stinner in :gh:`144175`.) + * Add the following functions for the new :class:`frozendict` type: * :c:func:`PyAnyDict_Check` diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h index 6134442106474f..b9f253e06b31c9 100644 --- a/Include/cpython/modsupport.h +++ b/Include/cpython/modsupport.h @@ -2,6 +2,19 @@ # error "this header file must not be included directly" #endif +PyAPI_FUNC(int) PyArg_ParseArray( + PyObject *const *args, + Py_ssize_t nargs, + const char *format, + ...); +PyAPI_FUNC(int) PyArg_ParseArrayAndKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames, + const char *format, + const char * const *kwlist, + ...); + // A data structure that can be used to run initialization code once in a // thread-safe manner. The C++11 equivalent is std::call_once. typedef struct { diff --git a/Lib/test/test_capi/test_modsupport.py b/Lib/test/test_capi/test_modsupport.py index 1520489f843826..29bebf847aaba2 100644 --- a/Lib/test/test_capi/test_modsupport.py +++ b/Lib/test/test_capi/test_modsupport.py @@ -152,3 +152,22 @@ def test_negative_freethreading(self, modname, minor, build): msg = "only compatible with free-threaded CPython" with self.assertRaisesRegex(ImportError, msg): _testcapi.pyabiinfo_check(modname, 1, minor, ft_flag, build, 0) + + +class TestModsupport(unittest.TestCase): + def test_pyarg_parsearray(self): + func = _testcapi.pyarg_parsearray + self.assertEqual(func(1, 2), (1, 2, 0)) + self.assertEqual(func(1, 2, 3), (1, 2, 3)) + self.assertRaises(TypeError, func, 1) + self.assertRaises(TypeError, func, "str", 2) + + def test_funcandkeywords(self): + func = _testcapi.pyarg_parsearrayandkeywords + self.assertEqual(func(1, 2), (1, 2, 0)) + self.assertEqual(func(1, 2, 3), (1, 2, 3)) + self.assertEqual(func(1, b=2), (1, 2, 0)) + self.assertEqual(func(1, b=2, c=3), (1, 2, 3)) + self.assertRaises(TypeError, func, 1) + self.assertRaises(TypeError, func, "str", 2) + self.assertRaises(TypeError, func, 1, z=2) diff --git a/Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst b/Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst new file mode 100644 index 00000000000000..da1e489bb3d2e5 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst @@ -0,0 +1,3 @@ +Add :c:func:`PyArg_ParseArray` and :c:func:`PyArg_ParseArrayAndKeywords` +functions to parse arguments of functions using the :c:macro:`METH_FASTCALL` +calling convention. Patch by Victor Stinner. diff --git a/Modules/_testcapi/modsupport.c b/Modules/_testcapi/modsupport.c index 6746eb9eb1e94a..151e4aa19afe11 100644 --- a/Modules/_testcapi/modsupport.c +++ b/Modules/_testcapi/modsupport.c @@ -25,8 +25,36 @@ pyabiinfo_check(PyObject *Py_UNUSED(module), PyObject *args) Py_RETURN_NONE; } +static PyObject * +pyarg_parsearray(PyObject* self, PyObject* const* args, Py_ssize_t nargs) +{ + int a, b, c = 0; + if (!PyArg_ParseArray(args, nargs, "ii|i", &a, &b, &c)) { + return NULL; + } + return Py_BuildValue("iii", a, b, c); +} + +static PyObject * +pyarg_parsearrayandkeywords(PyObject* self, PyObject* const* args, + Py_ssize_t nargs, PyObject* kwnames) +{ + int a, b, c = 0; + const char *kwlist[] = {"a", "b", "c", NULL}; + if (!PyArg_ParseArrayAndKeywords(args, nargs, kwnames, + "ii|i", kwlist, + &a, &b, &c)) { + return NULL; + } + return Py_BuildValue("iii", a, b, c); +} + static PyMethodDef TestMethods[] = { {"pyabiinfo_check", pyabiinfo_check, METH_VARARGS}, + {"pyarg_parsearray", _PyCFunction_CAST(pyarg_parsearray), METH_FASTCALL}, + {"pyarg_parsearrayandkeywords", + _PyCFunction_CAST(pyarg_parsearrayandkeywords), + METH_FASTCALL | METH_KEYWORDS}, {NULL}, }; diff --git a/Python/getargs.c b/Python/getargs.c index c119ca5c35398b..31cd4ad3f652d9 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -57,8 +57,15 @@ static const char *convertsimple(PyObject *, const char **, va_list *, int, static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **); static int getbuffer(PyObject *, Py_buffer *, const char**); -static int vgetargskeywords(PyObject *, PyObject *, - const char *, const char * const *, va_list *, int); +static int +vgetargskeywords(PyObject *args, PyObject *kwargs, + const char *format, const char * const *kwlist, + va_list *p_va, int flags); +static int +vgetargskeywords_impl(PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + const char *format, const char * const *kwlist, + va_list *p_va, int flags); static int vgetargskeywordsfast(PyObject *, PyObject *, struct _PyArg_Parser *, va_list *, int); static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, @@ -129,6 +136,40 @@ _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, . return retval; } +int +PyArg_ParseArray(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) +{ + va_list va; + va_start(va, format); + int retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0); + va_end(va); + return retval; +} + +int +PyArg_ParseArrayAndKeywords(PyObject *const *args, Py_ssize_t nargs, + PyObject *kwnames, + const char *format, + const char * const *kwlist, ...) +{ + if ((args == NULL && nargs != 0) || + (kwnames != NULL && !PyTuple_Check(kwnames)) || + format == NULL || + kwlist == NULL) + { + PyErr_BadInternalCall(); + return 0; + } + + va_list va; + va_start(va, kwlist); + int retval = vgetargskeywords_impl(args, nargs, NULL, kwnames, format, + kwlist, &va, 0); + va_end(va); + return retval; +} + + int PyArg_VaParse(PyObject *args, const char *format, va_list va) { @@ -1612,11 +1653,27 @@ PyArg_ValidateKeywordArguments(PyObject *kwargs) static PyObject * new_kwtuple(const char * const *keywords, int total, int pos); +static PyObject* +find_keyword_str(PyObject *kwnames, PyObject *const *kwstack, const char *key) +{ + Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); + for (Py_ssize_t i = 0; i < nkwargs; i++) { + PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); + assert(PyUnicode_Check(kwname)); + if (PyUnicode_EqualToUTF8(kwname, key)) { + return Py_NewRef(kwstack[i]); + } + } + return NULL; +} + #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':') static int -vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, - const char * const *kwlist, va_list *p_va, int flags) +vgetargskeywords_impl(PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + const char *format, const char * const *kwlist, + va_list *p_va, int flags) { char msgbuf[512]; int levels[32]; @@ -1625,16 +1682,18 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, int max = INT_MAX; int i, pos, len; int skip = 0; - Py_ssize_t nargs, nkwargs; + Py_ssize_t nkwargs; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; + PyObject * const *kwstack = NULL; freelist.entries = static_entries; freelist.first_available = 0; freelist.entries_malloced = 0; - assert(args != NULL && PyTuple_Check(args)); + assert(args != NULL || nargs == 0); assert(kwargs == NULL || PyDict_Check(kwargs)); + assert(kwnames == NULL || PyTuple_Check(kwnames)); assert(format != NULL); assert(kwlist != NULL); assert(p_va != NULL); @@ -1672,8 +1731,16 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, freelist.entries_malloced = 1; } - nargs = PyTuple_GET_SIZE(args); - nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); + if (kwargs != NULL) { + nkwargs = PyDict_GET_SIZE(kwargs); + } + else if (kwnames != NULL) { + nkwargs = PyTuple_GET_SIZE(kwnames); + kwstack = args + nargs; + } + else { + nkwargs = 0; + } if (nargs + nkwargs > len) { /* Adding "keyword" (when nargs == 0) prevents producing wrong error messages in some special cases (see bpo-31229). */ @@ -1757,11 +1824,16 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, if (!skip) { PyObject *current_arg; if (i < nargs) { - current_arg = Py_NewRef(PyTuple_GET_ITEM(args, i)); + current_arg = Py_NewRef(args[i]); } else if (nkwargs && i >= pos) { - if (PyDict_GetItemStringRef(kwargs, kwlist[i], ¤t_arg) < 0) { - return cleanreturn(0, &freelist); + if (kwargs != NULL) { + if (PyDict_GetItemStringRef(kwargs, kwlist[i], ¤t_arg) < 0) { + return cleanreturn(0, &freelist); + } + } + else { + current_arg = find_keyword_str(kwnames, kwstack, kwlist[i]); } if (current_arg) { --nkwargs; @@ -1846,8 +1918,13 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, /* make sure there are no arguments given by name and position */ for (i = pos; i < nargs; i++) { PyObject *current_arg; - if (PyDict_GetItemStringRef(kwargs, kwlist[i], ¤t_arg) < 0) { - return cleanreturn(0, &freelist); + if (kwargs != NULL) { + if (PyDict_GetItemStringRef(kwargs, kwlist[i], ¤t_arg) < 0) { + return cleanreturn(0, &freelist); + } + } + else { + current_arg = find_keyword_str(kwnames, kwstack, kwlist[i]); } if (current_arg) { Py_DECREF(current_arg); @@ -1863,7 +1940,20 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, } /* make sure there are no extraneous keyword arguments */ j = 0; - while (PyDict_Next(kwargs, &j, &key, NULL)) { + while (1) { + if (kwargs != NULL) { + if (!PyDict_Next(kwargs, &j, &key, NULL)) { + break; + } + } + else { + if (j >= nkwargs) { + break; + } + key = PyTuple_GET_ITEM(kwnames, j); + j++; + } + int match = 0; if (!PyUnicode_Check(key)) { PyErr_SetString(PyExc_TypeError, @@ -1921,6 +2011,16 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, return cleanreturn(1, &freelist); } +static int +vgetargskeywords(PyObject *argstuple, PyObject *kwargs, + const char *format, const char * const *kwlist, + va_list *p_va, int flags) +{ + PyObject *const *args = _PyTuple_ITEMS(argstuple); + Py_ssize_t nargs = PyTuple_GET_SIZE(argstuple); + return vgetargskeywords_impl(args, nargs, kwargs, NULL, + format, kwlist, p_va, flags); +} static int scan_keywords(const char * const *keywords, int *ptotal, int *pposonly) From 46761c976060c3e9ddbd33ea64601b54a97ddbe0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 7 Mar 2026 17:14:44 +0900 Subject: [PATCH 350/498] gh-116738: Make mmap.set_name thread-safe (#145555) * Add critical section around mmap.set_name to make it thread-safe * Add news entry * Apply suggestion from @aisk --- .../2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst | 2 ++ Modules/clinic/mmapmodule.c.h | 4 +++- Modules/mmapmodule.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst new file mode 100644 index 00000000000000..212fd7b02902e9 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst @@ -0,0 +1,2 @@ +Make :meth:`!mmap.mmap.set_name` thread-safe on the :term:`free threaded ` build. diff --git a/Modules/clinic/mmapmodule.c.h b/Modules/clinic/mmapmodule.c.h index db640800ad780f..98c5bf6a2fb146 100644 --- a/Modules/clinic/mmapmodule.c.h +++ b/Modules/clinic/mmapmodule.c.h @@ -556,7 +556,9 @@ mmap_mmap_set_name(PyObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = mmap_mmap_set_name_impl((mmap_object *)self, name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -879,4 +881,4 @@ mmap_mmap_madvise(PyObject *self, PyObject *const *args, Py_ssize_t nargs) #ifndef MMAP_MMAP_MADVISE_METHODDEF #define MMAP_MMAP_MADVISE_METHODDEF #endif /* !defined(MMAP_MMAP_MADVISE_METHODDEF) */ -/*[clinic end generated code: output=8389e3c8e3db3a78 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1122b93314aebc5c input=a9049054013a1b77]*/ diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 16e3c0ecefd05d..61d8a043a04ce2 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1122,6 +1122,7 @@ mmap_mmap_seek_impl(mmap_object *self, Py_ssize_t dist, int how) } /*[clinic input] +@critical_section mmap.mmap.set_name name: str @@ -1131,7 +1132,7 @@ mmap.mmap.set_name static PyObject * mmap_mmap_set_name_impl(mmap_object *self, const char *name) -/*[clinic end generated code: output=1edaf4fd51277760 input=6c7dd91cad205f07]*/ +/*[clinic end generated code: output=1edaf4fd51277760 input=7c0e2a17ca6d1adc]*/ { #if defined(MAP_ANONYMOUS) && defined(__linux__) const char *prefix = "cpython:mmap:"; From 0aeaaafac476119f242fe717ce60d2070172127b Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 7 Mar 2026 10:05:08 +0100 Subject: [PATCH 351/498] gh-145376: Fix refleak in `queuemodule.c` out-of-memory path (#145543) --- Modules/_queuemodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index a45959346bc1f2..f2246dd36cf110 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -165,6 +165,7 @@ RingBuf_Put(RingBuf *buf, PyObject *item) // Buffer is full, grow it. if (resize_ringbuf(buf, buf->items_cap * 2) < 0) { PyErr_NoMemory(); + Py_DECREF(item); return -1; } } From 2cf6b2caade94e75f10363df6f432a3e6515be6c Mon Sep 17 00:00:00 2001 From: Ramin Farajpour Cami Date: Sat, 7 Mar 2026 17:01:45 +0330 Subject: [PATCH 352/498] gh-145623: Fix crashes on uninitialized struct.Struct objects (gh-145624) --- Lib/test/test_struct.py | 2 ++ .../Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst | 3 +++ Modules/_struct.c | 2 ++ 3 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index aa793a2c223de9..4cbfd7ad8b1e48 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -836,6 +836,8 @@ def test_operations_on_half_initialized_Struct(self): self.assertRaises(RuntimeError, S.unpack, spam) self.assertRaises(RuntimeError, S.unpack_from, spam) self.assertRaises(RuntimeError, getattr, S, 'format') + self.assertRaises(RuntimeError, S.__sizeof__) + self.assertRaises(RuntimeError, repr, S) self.assertEqual(S.size, -1) diff --git a/Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst b/Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst new file mode 100644 index 00000000000000..77b43e79e35860 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst @@ -0,0 +1,3 @@ +Fix crash in :mod:`struct` when calling :func:`repr` or +``__sizeof__()`` on an uninitialized :class:`struct.Struct` +object created via ``Struct.__new__()`` without calling ``__init__()``. diff --git a/Modules/_struct.c b/Modules/_struct.c index ae8a8ffb3c005a..dcc3c7ec63e9e0 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -2382,6 +2382,7 @@ static PyObject * Struct___sizeof___impl(PyStructObject *self) /*[clinic end generated code: output=2d0d78900b4cdb4e input=faca5925c1f1ffd0]*/ { + ENSURE_STRUCT_IS_READY(self); size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) { size += sizeof(formatcode); @@ -2393,6 +2394,7 @@ static PyObject * s_repr(PyObject *op) { PyStructObject *self = PyStructObject_CAST(op); + ENSURE_STRUCT_IS_READY(self); PyObject* fmt = PyUnicode_FromStringAndSize( PyBytes_AS_STRING(self->s_format), PyBytes_GET_SIZE(self->s_format)); if (fmt == NULL) { From 149c4657507d17f78dd0938419a5a24ed71dc07e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 7 Mar 2026 16:53:13 +0200 Subject: [PATCH 353/498] Fix bug notifier for issues with no body text (#145603) --- .github/workflows/new-bugs-announce-notifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/new-bugs-announce-notifier.yml b/.github/workflows/new-bugs-announce-notifier.yml index b25750f0897de2..9ee38a4fd1cefc 100644 --- a/.github/workflows/new-bugs-announce-notifier.yml +++ b/.github/workflows/new-bugs-announce-notifier.yml @@ -44,7 +44,7 @@ jobs: // We need to truncate the body size, because the max size for // the whole payload is 16kb. We want to be safe and assume that // body can take up to ~8kb of space. - body : issue.data.body.substring(0, 8000) + body : (issue.data.body || "").substring(0, 8000) }; const data = { From 5a15a52dd1dee37af4f2b3a6b15a9f5735f75c6e Mon Sep 17 00:00:00 2001 From: James Date: Sun, 8 Mar 2026 18:41:47 -0400 Subject: [PATCH 354/498] gh-145642: Docs: Avoid warning for invalid escape sequence in tutorial (#145643) * Match tutorial output to real interpreter output * Avoid invalid escape sequence in example Co-authored-by: Ned Batchelder --------- Co-authored-by: Ned Batchelder --- Doc/tutorial/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index deabac5253051c..7778e37a9adaa9 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -184,11 +184,11 @@ If you don't want characters prefaced by ``\`` to be interpreted as special characters, you can use *raw strings* by adding an ``r`` before the first quote:: - >>> print('C:\some\name') # here \n means newline! - C:\some + >>> print('C:\this\name') # here \t means tab, \n means newline + C: his ame - >>> print(r'C:\some\name') # note the r before the quote - C:\some\name + >>> print(r'C:\this\name') # note the r before the quote + C:\this\name There is one subtle aspect to raw strings: a raw string may not end in an odd number of ``\`` characters; see From 015613384fea7a00bb2077760e325e5baab6814b Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 9 Mar 2026 03:25:21 +0100 Subject: [PATCH 355/498] gh-145219: Add Emscripten cross-build and clean configurability (#145581) Modifies the Emscripten build script to allow for custom cross-build directory names, and to only clean Emscripten-specific paths (optionally including the build python). Co-authored-by: Russell Keith-Magee --- .gitignore | 2 +- Tools/wasm/emscripten/__main__.py | 103 ++++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index e234d86e8d5532..f9d2cdfc32b383 100644 --- a/.gitignore +++ b/.gitignore @@ -137,7 +137,7 @@ Tools/unicode/data/ /config.status /config.status.lineno /.ccache -/cross-build/ +/cross-build*/ /jit_stencils*.h /platform /profile-clean-stamp diff --git a/Tools/wasm/emscripten/__main__.py b/Tools/wasm/emscripten/__main__.py index 856a7f8252bb7c..14d32279a8c4fa 100644 --- a/Tools/wasm/emscripten/__main__.py +++ b/Tools/wasm/emscripten/__main__.py @@ -24,14 +24,25 @@ CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent EMSCRIPTEN_VERSION_FILE = EMSCRIPTEN_DIR / "emscripten_version.txt" -CROSS_BUILD_DIR = CHECKOUT / "cross-build" -NATIVE_BUILD_DIR = CROSS_BUILD_DIR / "build" +DEFAULT_CROSS_BUILD_DIR = CHECKOUT / "cross-build" HOST_TRIPLE = "wasm32-emscripten" -DOWNLOAD_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "build" -HOST_BUILD_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "build" -HOST_DIR = HOST_BUILD_DIR / "python" -PREFIX_DIR = CROSS_BUILD_DIR / HOST_TRIPLE / "prefix" + +def get_build_paths(cross_build_dir=None): + """Compute all build paths from the given cross-build directory.""" + if cross_build_dir is None: + cross_build_dir = DEFAULT_CROSS_BUILD_DIR + cross_build_dir = Path(cross_build_dir).absolute() + host_triple_dir = cross_build_dir / HOST_TRIPLE + return { + "cross_build_dir": cross_build_dir, + "native_build_dir": cross_build_dir / "build", + "host_triple_dir": host_triple_dir, + "host_build_dir": host_triple_dir / "build", + "host_dir": host_triple_dir / "build" / "python", + "prefix_dir": host_triple_dir / "prefix", + } + LOCAL_SETUP = CHECKOUT / "Modules" / "Setup.local" LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n" @@ -115,12 +126,17 @@ def updated_env(updates, emsdk_cache): return environment -def subdir(working_dir, *, clean_ok=False): - """Decorator to change to a working directory.""" +def subdir(path_key, *, clean_ok=False): + """Decorator to change to a working directory. + + path_key is a key into context.build_paths, used to resolve the working + directory at call time. + """ def decorator(func): @functools.wraps(func) def wrapper(context): + working_dir = context.build_paths[path_key] try: tput_output = subprocess.check_output( ["tput", "cols"], encoding="utf-8" @@ -177,20 +193,21 @@ def build_platform(): return sysconfig.get_config_var("BUILD_GNU_TYPE") -def build_python_path(): +def build_python_path(context): """The path to the build Python binary.""" - binary = NATIVE_BUILD_DIR / "python" + native_build_dir = context.build_paths["native_build_dir"] + binary = native_build_dir / "python" if not binary.is_file(): binary = binary.with_suffix(".exe") if not binary.is_file(): raise FileNotFoundError( - f"Unable to find `python(.exe)` in {NATIVE_BUILD_DIR}" + f"Unable to find `python(.exe)` in {native_build_dir}" ) return binary -@subdir(NATIVE_BUILD_DIR, clean_ok=True) +@subdir("native_build_dir", clean_ok=True) def configure_build_python(context, working_dir): """Configure the build/host Python.""" if LOCAL_SETUP.exists(): @@ -206,12 +223,12 @@ def configure_build_python(context, working_dir): call(configure, quiet=context.quiet) -@subdir(NATIVE_BUILD_DIR) +@subdir("native_build_dir") def make_build_python(context, working_dir): """Make/build the build Python.""" call(["make", "--jobs", str(cpu_count()), "all"], quiet=context.quiet) - binary = build_python_path() + binary = build_python_path(context) cmd = [ binary, "-c", @@ -241,7 +258,7 @@ def download_and_unpack(working_dir: Path, url: str, expected_shasum: str): shutil.unpack_archive(tmp_file.name, working_dir) -@subdir(HOST_BUILD_DIR, clean_ok=True) +@subdir("host_build_dir", clean_ok=True) def make_emscripten_libffi(context, working_dir): ver = "3.4.6" libffi_dir = working_dir / f"libffi-{ver}" @@ -253,13 +270,15 @@ def make_emscripten_libffi(context, working_dir): ) call( [EMSCRIPTEN_DIR / "make_libffi.sh"], - env=updated_env({"PREFIX": PREFIX_DIR}, context.emsdk_cache), + env=updated_env( + {"PREFIX": context.build_paths["prefix_dir"]}, context.emsdk_cache + ), cwd=libffi_dir, quiet=context.quiet, ) -@subdir(HOST_BUILD_DIR, clean_ok=True) +@subdir("host_build_dir", clean_ok=True) def make_mpdec(context, working_dir): ver = "4.0.1" mpdec_dir = working_dir / f"mpdecimal-{ver}" @@ -275,7 +294,7 @@ def make_mpdec(context, working_dir): mpdec_dir / "configure", "CFLAGS=-fPIC", "--prefix", - PREFIX_DIR, + context.build_paths["prefix_dir"], "--disable-shared", ], cwd=mpdec_dir, @@ -289,14 +308,15 @@ def make_mpdec(context, working_dir): ) -@subdir(HOST_DIR, clean_ok=True) +@subdir("host_dir", clean_ok=True) def configure_emscripten_python(context, working_dir): """Configure the emscripten/host build.""" + paths = context.build_paths config_site = os.fsdecode(EMSCRIPTEN_DIR / "config.site-wasm32-emscripten") emscripten_build_dir = working_dir.relative_to(CHECKOUT) - python_build_dir = NATIVE_BUILD_DIR / "build" + python_build_dir = paths["native_build_dir"] / "build" lib_dirs = list(python_build_dir.glob("lib.*")) assert len(lib_dirs) == 1, ( f"Expected a single lib.* directory in {python_build_dir}" @@ -322,13 +342,13 @@ def configure_emscripten_python(context, working_dir): capture_output=True, ) host_runner = res.stdout.strip() - pkg_config_path_dir = (PREFIX_DIR / "lib/pkgconfig/").resolve() + pkg_config_path_dir = (paths["prefix_dir"] / "lib/pkgconfig/").resolve() env_additions = { "CONFIG_SITE": config_site, "HOSTRUNNER": host_runner, "EM_PKG_CONFIG_PATH": str(pkg_config_path_dir), } - build_python = os.fsdecode(build_python_path()) + build_python = os.fsdecode(build_python_path(context)) configure = [ "emconfigure", os.path.relpath(CHECKOUT / "configure", working_dir), @@ -342,7 +362,7 @@ def configure_emscripten_python(context, working_dir): "--disable-ipv6", "--enable-big-digits=30", "--enable-wasm-dynamic-linking", - f"--prefix={PREFIX_DIR}", + f"--prefix={paths['prefix_dir']}", ] if pydebug: configure.append("--with-pydebug") @@ -403,7 +423,7 @@ def configure_emscripten_python(context, working_dir): sys.stdout.flush() -@subdir(HOST_DIR) +@subdir("host_dir") def make_emscripten_python(context, working_dir): """Run `make` for the emscripten/host build.""" call( @@ -432,9 +452,17 @@ def build_all(context): def clean_contents(context): """Delete all files created by this script.""" - if CROSS_BUILD_DIR.exists(): - print(f"🧹 Deleting {CROSS_BUILD_DIR} ...") - shutil.rmtree(CROSS_BUILD_DIR) + if context.target in {"all", "build"}: + build_dir = context.build_paths["native_build_dir"] + if build_dir.exists(): + print(f"🧹 Deleting {build_dir} ...") + shutil.rmtree(build_dir) + + if context.target in {"all", "host"}: + host_triple_dir = context.build_paths["host_triple_dir"] + if host_triple_dir.exists(): + print(f"🧹 Deleting {host_triple_dir} ...") + shutil.rmtree(host_triple_dir) if LOCAL_SETUP.exists(): with LOCAL_SETUP.open("rb") as file: @@ -472,6 +500,17 @@ def main(): clean = subcommands.add_parser( "clean", help="Delete files and directories created by this script" ) + clean.add_argument( + "target", + nargs="?", + default="host", + choices=["all", "host", "build"], + help=( + "What should be cleaned. 'build' for just the build platform, or " + "'host' for the host platform, or 'all' for both. Defaults to 'host'." + ), + ) + for subcommand in ( build, configure_build, @@ -489,6 +528,14 @@ def main(): dest="quiet", help="Redirect output from subprocesses to a log file", ) + subcommand.add_argument( + "--cross-build-dir", + action="store", + default=None, + dest="cross_build_dir", + help="Path to the cross-build directory " + f"(default: {DEFAULT_CROSS_BUILD_DIR})", + ) subcommand.add_argument( "--emsdk-cache", action="store", @@ -521,6 +568,8 @@ def main(): context = parser.parse_args() + context.build_paths = get_build_paths(context.cross_build_dir) + if context.emsdk_cache: validate_emsdk_version(context.emsdk_cache) context.emsdk_cache = Path(context.emsdk_cache).absolute() From b4460925a48f41497857fa2b20fbfb33836ceed8 Mon Sep 17 00:00:00 2001 From: Chris Eibl <138194463+chris-eibl@users.noreply.github.com> Date: Mon, 9 Mar 2026 10:23:34 +0100 Subject: [PATCH 356/498] Fix intermittent `test_ci_fuzz_stdlib` failures (GH-145641) --- Lib/test/test_tools/test_compute_changes.py | 2 ++ Tools/build/compute-changes.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_tools/test_compute_changes.py b/Lib/test/test_tools/test_compute_changes.py index c4e3ffdb4de6cf..351fb06a885006 100644 --- a/Lib/test/test_tools/test_compute_changes.py +++ b/Lib/test/test_tools/test_compute_changes.py @@ -54,6 +54,8 @@ def test_ci_fuzz_stdlib(self): f = p / "file" elif p.is_file(): f = p + else: + self.fail(f"LIBRARY_FUZZER_PATHS contains an invalid entry: {p!r}") result = process_changed_files({f}) self.assertTrue(result.run_ci_fuzz_stdlib) self.assertTrue(is_fuzzable_library_file(f)) diff --git a/Tools/build/compute-changes.py b/Tools/build/compute-changes.py index 981e00e28b42a7..4d92b083026b27 100644 --- a/Tools/build/compute-changes.py +++ b/Tools/build/compute-changes.py @@ -90,7 +90,7 @@ # tarfile Path("Lib/tarfile.py"), # tomllib - Path("Modules/tomllib/"), + Path("Lib/tomllib/"), # xml Path("Lib/xml/"), Path("Lib/_markupbase.py"), From 201e18312c01178b34b77a989c7bee7db5f469fe Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 9 Mar 2026 13:50:45 +0100 Subject: [PATCH 357/498] gh-145376: Fix reference leaks in _lprof.c (#145539) --- Modules/_lsprof.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 025a3fac46e59b..a2d1aefb1611b3 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -702,6 +702,7 @@ PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObje if (PyCFunction_Check(meth)) { return (PyObject*)((PyCFunctionObject *)meth); } + Py_DECREF(meth); } return NULL; } @@ -961,6 +962,8 @@ profiler_traverse(PyObject *op, visitproc visit, void *arg) ProfilerObject *self = ProfilerObject_CAST(op); Py_VISIT(Py_TYPE(op)); Py_VISIT(self->externalTimer); + Py_VISIT(self->missing); + return 0; } @@ -979,6 +982,7 @@ profiler_dealloc(PyObject *op) flush_unmatched(self); clearEntries(self); + Py_XDECREF(self->missing); Py_XDECREF(self->externalTimer); PyTypeObject *tp = Py_TYPE(self); tp->tp_free(self); @@ -1017,7 +1021,7 @@ profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit, if (!monitoring) { return -1; } - self->missing = PyObject_GetAttrString(monitoring, "MISSING"); + Py_XSETREF(self->missing, PyObject_GetAttrString(monitoring, "MISSING")); if (!self->missing) { Py_DECREF(monitoring); return -1; From 8060aa5d7dd02c22a987e23cf5dbb7049b50b042 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 9 Mar 2026 14:17:27 +0100 Subject: [PATCH 358/498] gh-145376: Fix various refleaks in Objects/ (#145609) --- Modules/_cursesmodule.c | 5 +++++ Modules/binascii.c | 2 +- Objects/genericaliasobject.c | 3 +++ Objects/object.c | 5 +++-- Objects/structseq.c | 3 ++- Objects/typevarobject.c | 3 +-- Objects/unicodeobject.c | 2 +- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 61464348d6fab8..dd96f9aa62b85b 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -1112,11 +1112,13 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, attr_old = getattrs(self->win); if (curses_wattrset(self, attr, "addstr") < 0) { curses_release_wstr(strtype, wstr); + Py_XDECREF(bytesobj); return NULL; } } #ifdef HAVE_NCURSESW if (strtype == 2) { + assert(bytesobj == NULL); if (use_xy) { rtn = mvwaddwstr(self->win,y,x,wstr); funcname = "mvwaddwstr"; @@ -1130,6 +1132,7 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, else #endif { + assert(wstr == NULL); const char *str = PyBytes_AS_STRING(bytesobj); if (use_xy) { rtn = mvwaddstr(self->win,y,x,str); @@ -1210,6 +1213,7 @@ _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, attr_old = getattrs(self->win); if (curses_wattrset(self, attr, "addnstr") < 0) { curses_release_wstr(strtype, wstr); + Py_XDECREF(bytesobj); return NULL; } } @@ -2212,6 +2216,7 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, attr_old = getattrs(self->win); if (curses_wattrset(self, attr, "insstr") < 0) { curses_release_wstr(strtype, wstr); + Py_XDECREF(bytesobj); return NULL; } } diff --git a/Modules/binascii.c b/Modules/binascii.c index e6cd64338064b3..3f3695d50f2754 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -924,7 +924,7 @@ binascii_a2b_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, } unsigned char *bin_data = PyBytesWriter_GetData(writer); if (bin_data == NULL) { - return NULL; + goto error; } uint32_t leftchar = 0; diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 119dd4b5c2dd00..7aef56cf4e93b8 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -299,6 +299,8 @@ subs_tvars(PyObject *obj, PyObject *params, &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg)); if (j < 0) { + Py_DECREF(subparams); + Py_DECREF(subargs); return NULL; } continue; @@ -455,6 +457,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje if (is_args_list) { args = tuple_args = PySequence_Tuple(args); if (args == NULL) { + Py_DECREF(item); return NULL; } } diff --git a/Objects/object.c b/Objects/object.c index b537c0d104e58c..e405963614689f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1295,6 +1295,7 @@ _PyObject_SetAttributeErrorContext(PyObject* v, PyObject* name) // Augment the exception with the name and object if (PyObject_SetAttr(exc, &_Py_ID(name), name) || PyObject_SetAttr(exc, &_Py_ID(obj), v)) { + Py_DECREF(exc); return 1; } restore: @@ -3077,9 +3078,9 @@ Py_ReprEnter(PyObject *obj) list = PyList_New(0); if (list == NULL) return -1; - if (PyDict_SetItem(dict, &_Py_ID(Py_Repr), list) < 0) + if (_PyDict_SetItem_Take2((PyDictObject *)dict, &_Py_ID(Py_Repr), list) < 0) { return -1; - Py_DECREF(list); + } } i = PyList_GET_SIZE(list); while (--i >= 0) { diff --git a/Objects/structseq.c b/Objects/structseq.c index 7a159338b9ba8a..b8bb041f0cff21 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -515,7 +515,8 @@ initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict, } if (_PyTuple_Resize(&keys, k) == -1) { - goto error; + assert(keys == NULL); + return -1; } if (PyDict_SetItemString(dict, match_args_key, keys) < 0) { diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 2ec546aff52c0a..0a260f4c10278c 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -2305,13 +2305,12 @@ generic_class_getitem(PyObject *cls, PyObject *args, PyObject *kwargs) PyObject * _Py_subscript_generic(PyThreadState* unused, PyObject *params) { - params = unpack_typevartuples(params); - PyInterpreterState *interp = _PyInterpreterState_GET(); if (interp->cached_objects.generic_type == NULL) { PyErr_SetString(PyExc_SystemError, "Cannot find Generic type"); return NULL; } + params = unpack_typevartuples(params); PyObject *args[2] = {(PyObject *)interp->cached_objects.generic_type, params}; PyObject *result = call_typing_func_object("_GenericAlias", args, 2); Py_DECREF(params); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7aa85a942e449e..7756f1a8482477 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5220,7 +5220,7 @@ unicode_decode_utf8_impl(_PyUnicodeWriter *writer, } if (_PyUnicodeWriter_Prepare(writer, end - s, 127) < 0) { - return -1; + goto onError; } } } From 886bc6e14bf01b615ffa328cd1acb46f9513a7fe Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 9 Mar 2026 14:19:36 +0100 Subject: [PATCH 359/498] gh-145376: Fix various reference leaks in Objects/ and Modules/ (#145385) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Modules/itertoolsmodule.c | 25 ++++++++++++++----------- Objects/enumobject.c | 12 +++++++----- Objects/listobject.c | 4 +++- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index ff0e2fd2b3569d..bc25bf6bfc1bd2 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3531,23 +3531,26 @@ count_traverse(PyObject *op, visitproc visit, void *arg) static PyObject * count_nextlong(countobject *lz) { - PyObject *long_cnt; - PyObject *stepped_up; - - long_cnt = lz->long_cnt; - if (long_cnt == NULL) { + if (lz->long_cnt == NULL) { /* Switch to slow_mode */ - long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX); - if (long_cnt == NULL) + lz->long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX); + if (lz->long_cnt == NULL) { return NULL; + } } - assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL); + assert(lz->cnt == PY_SSIZE_T_MAX && lz->long_cnt != NULL); + + // We hold one reference to "result" (a.k.a. the old value of + // lz->long_cnt); we'll either return it or keep it in lz->long_cnt. + PyObject *result = lz->long_cnt; - stepped_up = PyNumber_Add(long_cnt, lz->long_step); - if (stepped_up == NULL) + PyObject *stepped_up = PyNumber_Add(result, lz->long_step); + if (stepped_up == NULL) { return NULL; + } lz->long_cnt = stepped_up; - return long_cnt; + + return result; } static PyObject * diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 814ce4f919514b..70e7cce6aba008 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -178,14 +178,16 @@ enum_traverse(PyObject *op, visitproc visit, void *arg) static inline PyObject * increment_longindex_lock_held(enumobject *en) { - PyObject *next_index = en->en_longindex; - if (next_index == NULL) { - next_index = PyLong_FromSsize_t(PY_SSIZE_T_MAX); - if (next_index == NULL) { + if (en->en_longindex == NULL) { + en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX); + if (en->en_longindex == NULL) { return NULL; } } - assert(next_index != NULL); + assert(en->en_longindex != NULL); + // We hold one reference to "next_index" (a.k.a. the old value of + // en->en_longindex); we'll either return it or keep it in en->en_longindex + PyObject *next_index = en->en_longindex; PyObject *stepped_up = PyNumber_Add(next_index, en->one); if (stepped_up == NULL) { return NULL; diff --git a/Objects/listobject.c b/Objects/listobject.c index 3921b7cd7b69bc..7fc21907fefd31 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -4294,7 +4294,9 @@ listiter_reduce_general(void *_it, int forward) } /* empty iterator, create an empty list */ list = PyList_New(0); - if (list == NULL) + if (list == NULL) { + Py_DECREF(iter); return NULL; + } return Py_BuildValue("N(N)", iter, list); } From 3a0c716ad4922a84c407b69f8fca10f070007356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 9 Mar 2026 13:28:00 +0000 Subject: [PATCH 360/498] GH-145278: freeze encodings (partially) and linecache (#145279) --- Makefile.pre.in | 20 +++++++++++++++++++ ...-02-26-21-22-34.gh-issue-145278.DHkYqt.rst | 4 ++++ PCbuild/_freeze_module.vcxproj | 20 +++++++++++++++++++ PCbuild/_freeze_module.vcxproj.filters | 12 +++++++++++ Python/frozen.c | 10 ++++++++++ Tools/build/freeze_modules.py | 10 ++++++---- 6 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst diff --git a/Makefile.pre.in b/Makefile.pre.in index 120a6add38507f..4c2426ed283d43 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1729,6 +1729,9 @@ FROZEN_FILES_IN = \ Lib/zipimport.py \ Lib/abc.py \ Lib/codecs.py \ + Lib/encodings/__init__.py \ + Lib/encodings/aliases.py \ + Lib/encodings/utf_8.py \ Lib/io.py \ Lib/_collections_abc.py \ Lib/_sitebuiltins.py \ @@ -1738,6 +1741,7 @@ FROZEN_FILES_IN = \ Lib/os.py \ Lib/site.py \ Lib/stat.py \ + Lib/linecache.py \ Lib/importlib/util.py \ Lib/importlib/machinery.py \ Lib/runpy.py \ @@ -1754,6 +1758,9 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/zipimport.h \ Python/frozen_modules/abc.h \ Python/frozen_modules/codecs.h \ + Python/frozen_modules/encodings.h \ + Python/frozen_modules/encodings.aliases.h \ + Python/frozen_modules/encodings.utf_8.h \ Python/frozen_modules/io.h \ Python/frozen_modules/_collections_abc.h \ Python/frozen_modules/_sitebuiltins.h \ @@ -1763,6 +1770,7 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/os.h \ Python/frozen_modules/site.h \ Python/frozen_modules/stat.h \ + Python/frozen_modules/linecache.h \ Python/frozen_modules/importlib.util.h \ Python/frozen_modules/importlib.machinery.h \ Python/frozen_modules/runpy.h \ @@ -1802,6 +1810,15 @@ Python/frozen_modules/abc.h: Lib/abc.py $(FREEZE_MODULE_DEPS) Python/frozen_modules/codecs.h: Lib/codecs.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) codecs $(srcdir)/Lib/codecs.py Python/frozen_modules/codecs.h +Python/frozen_modules/encodings.h: Lib/encodings/__init__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings $(srcdir)/Lib/encodings/__init__.py Python/frozen_modules/encodings.h + +Python/frozen_modules/encodings.aliases.h: Lib/encodings/aliases.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings.aliases $(srcdir)/Lib/encodings/aliases.py Python/frozen_modules/encodings.aliases.h + +Python/frozen_modules/encodings.utf_8.h: Lib/encodings/utf_8.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings.utf_8 $(srcdir)/Lib/encodings/utf_8.py Python/frozen_modules/encodings.utf_8.h + Python/frozen_modules/io.h: Lib/io.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) io $(srcdir)/Lib/io.py Python/frozen_modules/io.h @@ -1829,6 +1846,9 @@ Python/frozen_modules/site.h: Lib/site.py $(FREEZE_MODULE_DEPS) Python/frozen_modules/stat.h: Lib/stat.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) stat $(srcdir)/Lib/stat.py Python/frozen_modules/stat.h +Python/frozen_modules/linecache.h: Lib/linecache.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) linecache $(srcdir)/Lib/linecache.py Python/frozen_modules/linecache.h + Python/frozen_modules/importlib.util.h: Lib/importlib/util.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) importlib.util $(srcdir)/Lib/importlib/util.py Python/frozen_modules/importlib.util.h diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst new file mode 100644 index 00000000000000..6b6a9eb9813663 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst @@ -0,0 +1,4 @@ +The :mod:`encodings` is now partially frozen, including +the ``aliases`` and ``utf_8`` submodules. + +The :mod:`linecache` is now frozen. diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index cb806459596084..40946cafd16b75 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -310,6 +310,21 @@ $(IntDir)codecs.g.h $(GeneratedFrozenModulesDir)Python\frozen_modules\codecs.h + + encodings + $(IntDir)encodings.g.h + $(GeneratedFrozenModulesDir)Python\frozen_modules\encodings.h + + + encodings.aliases + $(IntDir)encodings.aliases.g.h + $(GeneratedFrozenModulesDir)Python\frozen_modules\encodings.aliases.h + + + encodings.utf_8 + $(IntDir)encodings.utf_8.g.h + $(GeneratedFrozenModulesDir)Python\frozen_modules\encodings.utf_8.h + io $(IntDir)io.g.h @@ -355,6 +370,11 @@ $(IntDir)stat.g.h $(GeneratedFrozenModulesDir)Python\frozen_modules\stat.h + + linecache + $(IntDir)linecache.g.h + $(GeneratedFrozenModulesDir)Python\frozen_modules\linecache.h + importlib.util $(IntDir)importlib.util.g.h diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 6dcf0e8712903a..a0e36a4c526ede 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -537,6 +537,15 @@ Python Files + + Python Files + + + Python Files + + + Python Files + Python Files @@ -564,6 +573,9 @@ Python Files + + Python Files + Python Files diff --git a/Python/frozen.c b/Python/frozen.c index 15d256b6743e0a..72a291d0d43f1d 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -46,6 +46,9 @@ #include "frozen_modules/zipimport.h" #include "frozen_modules/abc.h" #include "frozen_modules/codecs.h" +#include "frozen_modules/encodings.h" +#include "frozen_modules/encodings.aliases.h" +#include "frozen_modules/encodings.utf_8.h" #include "frozen_modules/io.h" #include "frozen_modules/_collections_abc.h" #include "frozen_modules/_sitebuiltins.h" @@ -55,6 +58,7 @@ #include "frozen_modules/os.h" #include "frozen_modules/site.h" #include "frozen_modules/stat.h" +#include "frozen_modules/linecache.h" #include "frozen_modules/importlib.util.h" #include "frozen_modules/importlib.machinery.h" #include "frozen_modules/runpy.h" @@ -76,6 +80,9 @@ static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), false}, {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), false}, + {"encodings", _Py_M__encodings, (int)sizeof(_Py_M__encodings), true}, + {"encodings.aliases", _Py_M__encodings_aliases, (int)sizeof(_Py_M__encodings_aliases), false}, + {"encodings.utf_8", _Py_M__encodings_utf_8, (int)sizeof(_Py_M__encodings_utf_8), false}, {"io", _Py_M__io, (int)sizeof(_Py_M__io), false}, /* stdlib - startup, with site */ @@ -88,6 +95,9 @@ static const struct _frozen stdlib_modules[] = { {"site", _Py_M__site, (int)sizeof(_Py_M__site), false}, {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat), false}, + /* pythonrun - interactive */ + {"linecache", _Py_M__linecache, (int)sizeof(_Py_M__linecache), false}, + /* runpy - run module with -m */ {"importlib.util", _Py_M__importlib_util, (int)sizeof(_Py_M__importlib_util), false}, {"importlib.machinery", _Py_M__importlib_machinery, (int)sizeof(_Py_M__importlib_machinery), false}, diff --git a/Tools/build/freeze_modules.py b/Tools/build/freeze_modules.py index 3c43f7e3bbe8ca..0d1f5968d2a9e9 100644 --- a/Tools/build/freeze_modules.py +++ b/Tools/build/freeze_modules.py @@ -50,10 +50,9 @@ ('stdlib - startup, without site (python -S)', [ 'abc', 'codecs', - # For now we do not freeze the encodings, due # to the noise all - # those extra modules add to the text printed during the build. - # (See https://github.com/python/cpython/pull/28398#pullrequestreview-756856469.) - #'', + '', + 'encodings.aliases', + 'encodings.utf_8', 'io', ]), ('stdlib - startup, with site', [ @@ -66,6 +65,9 @@ 'site', 'stat', ]), + ('pythonrun - interactive', [ + 'linecache', + ]), ('runpy - run module with -m', [ "importlib.util", "importlib.machinery", From 44855458a423569eaea3df53fd5a0c0032da932d Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 9 Mar 2026 14:32:28 +0100 Subject: [PATCH 361/498] Document that PyType_GetModule returns a borrowed ref (GH-145612) --- Doc/c-api/type.rst | 4 ++++ Doc/data/refcounts.dat | 3 +++ 2 files changed, 7 insertions(+) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 8cadf26cee3027..c9bb5c3f09ac18 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -274,6 +274,10 @@ Type Objects Return the module object associated with the given type when the type was created using :c:func:`PyType_FromModuleAndSpec`. + The returned reference is :term:`borrowed ` from *type*, + and will be valid as long as you hold a reference to *type*. + Do not release it with :c:func:`Py_DECREF` or similar. + If no module is associated with the given type, sets :py:class:`TypeError` and returns ``NULL``. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 64399f6ab1ff26..01b064f3e617ff 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -2427,6 +2427,9 @@ PyType_GetFlags:PyTypeObject*:type:0: PyType_GetName:PyObject*::+1: PyType_GetName:PyTypeObject*:type:0: +PyType_GetModule:PyObject*::0: +PyType_GetModule:PyTypeObject*:type:0: + PyType_GetModuleByToken:PyObject*::+1: PyType_GetModuleByToken:PyTypeObject*:type:0: PyType_GetModuleByToken:PyModuleDef*:def:: From 39aa415296c9ebb488eaf5952be00ef2d7ab306f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 9 Mar 2026 14:53:52 +0100 Subject: [PATCH 362/498] gh-145376: Fix _cursesmodule.c build on FreeBSD/macOS (#145669) --- Modules/_cursesmodule.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index dd96f9aa62b85b..fe9d6fe2763f36 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -1132,7 +1132,9 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, else #endif { +#ifdef HAVE_NCURSESW assert(wstr == NULL); +#endif const char *str = PyBytes_AS_STRING(bytesobj); if (use_xy) { rtn = mvwaddstr(self->win,y,x,str); From d64f83d07bf587dfd6e4ff9ad9d44541064d5f1c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 9 Mar 2026 15:02:06 +0100 Subject: [PATCH 363/498] gh-78773: Improve ctypes dynamic library loading docs (GH-145313) --- Doc/library/ctypes.rst | 250 ++++++++++++++++++++++------------------- 1 file changed, 133 insertions(+), 117 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index c23e81e29df0f5..fcbe2122d9f1a7 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -20,10 +20,6 @@ used to wrap these libraries in pure Python. ctypes tutorial --------------- -Note: The code samples in this tutorial use :mod:`doctest` to make sure that -they actually work. Since some code samples behave differently under Linux, -Windows, or macOS, they contain doctest directives in comments. - Note: Some code samples reference the ctypes :class:`c_int` type. On platforms where ``sizeof(long) == sizeof(int)`` it is an alias to :class:`c_long`. So, you should not be confused if :class:`c_long` is printed if you would expect @@ -34,13 +30,16 @@ So, you should not be confused if :class:`c_long` is printed if you would expect Loading dynamic link libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:mod:`!ctypes` exports the *cdll*, and on Windows *windll* and *oledll* +:mod:`!ctypes` exports the :py:data:`~ctypes.cdll`, and on Windows +:py:data:`~ctypes.windll` and :py:data:`~ctypes.oledll` objects, for loading dynamic link libraries. -You load libraries by accessing them as attributes of these objects. *cdll* -loads libraries which export functions using the standard ``cdecl`` calling -convention, while *windll* libraries call functions using the ``stdcall`` -calling convention. *oledll* also uses the ``stdcall`` calling convention, and +You load libraries by accessing them as attributes of these objects. +:py:data:`!cdll` loads libraries which export functions using the +standard ``cdecl`` calling convention, while :py:data:`!windll` +libraries call functions using the ``stdcall`` +calling convention. +:py:data:`~oledll` also uses the ``stdcall`` calling convention, and assumes the functions return a Windows :c:type:`!HRESULT` error code. The error code is used to automatically raise an :class:`OSError` exception when the function call fails. @@ -70,11 +69,13 @@ Windows appends the usual ``.dll`` file suffix automatically. being used by Python. Where possible, use native Python functionality, or else import and use the ``msvcrt`` module. -On Linux, it is required to specify the filename *including* the extension to +Other systems require the filename *including* the extension to load a library, so attribute access can not be used to load libraries. Either the :meth:`~LibraryLoader.LoadLibrary` method of the dll loaders should be used, -or you should load the library by creating an instance of CDLL by calling -the constructor:: +or you should load the library by creating an instance of :py:class:`CDLL` +by calling the constructor. + +For example, on Linux:: >>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX @@ -83,7 +84,14 @@ the constructor:: >>> -.. XXX Add section for macOS. +On macOS:: + + >>> cdll.LoadLibrary("libc.dylib") # doctest: +MACOS + + >>> libc = CDLL("libc.dylib") # doctest: +MACOS + >>> libc # doctest: +MACOS + + .. _ctypes-accessing-functions-from-loaded-dlls: @@ -1456,14 +1464,82 @@ Loading shared libraries ^^^^^^^^^^^^^^^^^^^^^^^^ There are several ways to load shared libraries into the Python process. One -way is to instantiate one of the following classes: +way is to instantiate :py:class:`CDLL` or one of its subclasses: .. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) - Instances of this class represent loaded shared libraries. Functions in these - libraries use the standard C calling convention, and are assumed to return - :c:expr:`int`. + Represents a loaded shared library. + + Functions in this library use the standard C calling convention, and are + assumed to return :c:expr:`int`. + The Python :term:`global interpreter lock` is released before calling any + function exported by these libraries, and reacquired afterwards. + For different function behavior, use a subclass: :py:class:`~ctypes.OleDLL`, + :py:class:`~ctypes.WinDLL`, or :py:class:`~ctypes.PyDLL`. + + If you have an existing :py:attr:`handle ` to an already + loaded shared library, it can be passed as the *handle* argument to wrap + the opened library in a new :py:class:`!CDLL` object. + In this case, *name* is only used to set the :py:attr:`~ctypes.CDLL._name` + attribute, but it may be adjusted and/or validated. + + If *handle* is ``None``, the underlying platform's :manpage:`dlopen(3)` or + :c:func:`!LoadLibrary` function is used to load the library into + the process, and to get a handle to it. + + *name* is the pathname of the shared library to open. + If *name* does not contain a path separator, the library is found + in a platform-specific way. + + On non-Windows systems, *name* can be ``None``. In this case, + :c:func:`!dlopen` is called with ``NULL``, which opens the main program + as a "library". + (Some systems do the same is *name* is empty; ``None``/``NULL`` is more + portable.) + + .. admonition:: CPython implementation detail + + Since CPython is linked to ``libc``, a ``None`` *name* is often used + to access the C standard library:: + + >>> printf = ctypes.CDLL(None).printf + >>> printf.argtypes = [ctypes.c_char_p] + >>> printf(b"hello\n") + hello + 6 + + To access the Python C API, prefer :py:data:`ctypes.pythonapi` which + works across platforms. + + The *mode* parameter can be used to specify how the library is loaded. For + details, consult the :manpage:`dlopen(3)` manpage. On Windows, *mode* is + ignored. On posix systems, RTLD_NOW is always added, and is not + configurable. + + The *use_errno* parameter, when set to true, enables a ctypes mechanism that + allows accessing the system :data:`errno` error number in a safe way. + :mod:`!ctypes` maintains a thread-local copy of the system's :data:`errno` + variable; if you call foreign functions created with ``use_errno=True`` then the + :data:`errno` value before the function call is swapped with the ctypes private + copy, the same happens immediately after the function call. + + The function :func:`ctypes.get_errno` returns the value of the ctypes private + copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy + to a new value and returns the former value. + + The *use_last_error* parameter, when set to true, enables the same mechanism for + the Windows error code which is managed by the :func:`GetLastError` and + :func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and + :func:`ctypes.set_last_error` are used to request and change the ctypes private + copy of the windows error code. + + The *winmode* parameter is used on Windows to specify how the library is loaded + (since *mode* is ignored). It takes any value that is valid for the Win32 API + ``LoadLibraryEx`` flags parameter. When omitted, the default is to use the + flags that result in the most secure DLL load, which avoids issues such as DLL + hijacking. Passing the full path to the DLL is the safest way to ensure the + correct library and dependencies are loaded. On Windows creating a :class:`CDLL` instance may fail even if the DLL name exists. When a dependent DLL of the loaded DLL is not found, a @@ -1475,20 +1551,47 @@ way is to instantiate one of the following classes: DLLs and determine which one is not found using Windows debugging and tracing tools. + .. seealso:: + + `Microsoft DUMPBIN tool `_ + -- A tool to find DLL dependents. + + .. versionchanged:: 3.8 + Added *winmode* parameter. + .. versionchanged:: 3.12 The *name* parameter can now be a :term:`path-like object`. -.. seealso:: + Instances of this class have no public methods. Functions exported by the + shared library can be accessed as attributes or by index. Please note that + accessing the function through an attribute caches the result and therefore + accessing it repeatedly returns the same object each time. On the other hand, + accessing it through an index returns a new object each time:: + + >>> from ctypes import CDLL + >>> libc = CDLL("libc.so.6") # On Linux + >>> libc.time == libc.time + True + >>> libc['time'] == libc['time'] + False + + The following public attributes are available. Their name starts with an + underscore to not clash with exported function names: + + .. attribute:: _handle + + The system handle used to access the library. - `Microsoft DUMPBIN tool `_ - -- A tool to find DLL dependents. + .. attribute:: _name + The name of the library passed in the constructor. -.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) +.. class:: OleDLL - Instances of this class represent loaded shared libraries, - functions in these libraries use the ``stdcall`` calling convention, and are + See :py:class:`~ctypes.CDLL`, the superclass, for common information. + + Functions in this library use the ``stdcall`` calling convention, and are assumed to return the windows specific :class:`HRESULT` code. :class:`HRESULT` values contain information specifying whether the function call failed or succeeded, together with additional error code. If the return value signals a @@ -1500,133 +1603,51 @@ way is to instantiate one of the following classes: :exc:`WindowsError` used to be raised, which is now an alias of :exc:`OSError`. - .. versionchanged:: 3.12 - - The *name* parameter can now be a :term:`path-like object`. +.. class:: WinDLL -.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) + See :py:class:`~ctypes.CDLL`, the superclass, for common information. - Instances of this class represent loaded shared libraries, - functions in these libraries use the ``stdcall`` calling convention, and are + Functions in these libraries use the ``stdcall`` calling convention, and are assumed to return :c:expr:`int` by default. .. availability:: Windows - .. versionchanged:: 3.12 +.. class:: PyDLL - The *name* parameter can now be a :term:`path-like object`. + See :py:class:`~ctypes.CDLL`, the superclass, for common information. - -The Python :term:`global interpreter lock` is released before calling any -function exported by these libraries, and reacquired afterwards. - - -.. class:: PyDLL(name, mode=DEFAULT_MODE, handle=None) - - Instances of this class behave like :class:`CDLL` instances, except that the + When functions in this library are called, the Python GIL is *not* released during the function call, and after the function execution the Python error flag is checked. If the error flag is set, a Python exception is raised. - Thus, this is only useful to call Python C api functions directly. - - .. versionchanged:: 3.12 - - The *name* parameter can now be a :term:`path-like object`. - -All these classes can be instantiated by calling them with at least one -argument, the pathname of the shared library. If you have an existing handle to -an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platform's :c:func:`!dlopen` or -:c:func:`!LoadLibrary` function is used to load the library into -the process, and to get a handle to it. - -The *mode* parameter can be used to specify how the library is loaded. For -details, consult the :manpage:`dlopen(3)` manpage. On Windows, *mode* is -ignored. On posix systems, RTLD_NOW is always added, and is not -configurable. - -The *use_errno* parameter, when set to true, enables a ctypes mechanism that -allows accessing the system :data:`errno` error number in a safe way. -:mod:`!ctypes` maintains a thread-local copy of the system's :data:`errno` -variable; if you call foreign functions created with ``use_errno=True`` then the -:data:`errno` value before the function call is swapped with the ctypes private -copy, the same happens immediately after the function call. - -The function :func:`ctypes.get_errno` returns the value of the ctypes private -copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy -to a new value and returns the former value. - -The *use_last_error* parameter, when set to true, enables the same mechanism for -the Windows error code which is managed by the :func:`GetLastError` and -:func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and -:func:`ctypes.set_last_error` are used to request and change the ctypes private -copy of the windows error code. - -The *winmode* parameter is used on Windows to specify how the library is loaded -(since *mode* is ignored). It takes any value that is valid for the Win32 API -``LoadLibraryEx`` flags parameter. When omitted, the default is to use the -flags that result in the most secure DLL load, which avoids issues such as DLL -hijacking. Passing the full path to the DLL is the safest way to ensure the -correct library and dependencies are loaded. - -.. versionchanged:: 3.8 - Added *winmode* parameter. + Thus, this is only useful to call Python C API functions directly. .. data:: RTLD_GLOBAL - :noindex: Flag to use as *mode* parameter. On platforms where this flag is not available, it is defined as the integer zero. .. data:: RTLD_LOCAL - :noindex: Flag to use as *mode* parameter. On platforms where this is not available, it is the same as *RTLD_GLOBAL*. .. data:: DEFAULT_MODE - :noindex: The default mode which is used to load shared libraries. On OSX 10.3, this is *RTLD_GLOBAL*, otherwise it is the same as *RTLD_LOCAL*. -Instances of these classes have no public methods. Functions exported by the -shared library can be accessed as attributes or by index. Please note that -accessing the function through an attribute caches the result and therefore -accessing it repeatedly returns the same object each time. On the other hand, -accessing it through an index returns a new object each time:: - - >>> from ctypes import CDLL - >>> libc = CDLL("libc.so.6") # On Linux - >>> libc.time == libc.time - True - >>> libc['time'] == libc['time'] - False - -The following public attributes are available, their name starts with an -underscore to not clash with exported function names: - - -.. attribute:: PyDLL._handle - - The system handle used to access the library. - - -.. attribute:: PyDLL._name - - The name of the library passed in the constructor. Shared libraries can also be loaded by using one of the prefabricated objects, which are instances of the :class:`LibraryLoader` class, either by calling the :meth:`~LibraryLoader.LoadLibrary` method, or by retrieving the library as attribute of the loader instance. - .. class:: LibraryLoader(dlltype) Class which loads shared libraries. *dlltype* should be one of the @@ -1645,13 +1666,11 @@ attribute of the loader instance. These prefabricated library loaders are available: .. data:: cdll - :noindex: Creates :class:`CDLL` instances. .. data:: windll - :noindex: Creates :class:`WinDLL` instances. @@ -1659,7 +1678,6 @@ These prefabricated library loaders are available: .. data:: oledll - :noindex: Creates :class:`OleDLL` instances. @@ -1667,7 +1685,6 @@ These prefabricated library loaders are available: .. data:: pydll - :noindex: Creates :class:`PyDLL` instances. @@ -1676,7 +1693,6 @@ For accessing the C Python api directly, a ready-to-use Python shared library object is available: .. data:: pythonapi - :noindex: An instance of :class:`PyDLL` that exposes Python C API functions as attributes. Note that all these functions are assumed to return C From 1564e231aae7afad5b9b19a277d1efff2b840ad2 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 9 Mar 2026 15:07:23 +0100 Subject: [PATCH 364/498] gh-145541: Fix `InvalidStateError` in `BaseSubprocessTransport._call_connection_lost()` (#145554) --- Lib/asyncio/base_subprocess.py | 4 +-- Lib/test/test_asyncio/test_subprocess.py | 31 +++++++++++++++++++ ...-03-05-19-01-28.gh-issue-145551.gItPRl.rst | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index 321a4e5d5d18fb..224b1883808a41 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -265,7 +265,7 @@ def _try_finish(self): # to avoid hanging forever in self._wait as otherwise _exit_waiters # would never be woken up, we wake them up here. for waiter in self._exit_waiters: - if not waiter.cancelled(): + if not waiter.done(): waiter.set_result(self._returncode) if all(p is not None and p.disconnected for p in self._pipes.values()): @@ -278,7 +278,7 @@ def _call_connection_lost(self, exc): finally: # wake up futures waiting for wait() for waiter in self._exit_waiters: - if not waiter.cancelled(): + if not waiter.done(): waiter.set_result(self._returncode) self._exit_waiters = None self._loop = None diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index bf301740741ae7..c08eb7cf261568 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -111,6 +111,37 @@ def test_subprocess_repr(self): ) transport.close() + def test_proc_exited_no_invalid_state_error_on_exit_waiters(self): + # gh-145541: when _connect_pipes hasn't completed (so + # _pipes_connected is False) and the process exits, _try_finish() + # sets the result on exit waiters. Then _call_connection_lost() must + # not call set_result() again on the same waiters. + self.loop.set_exception_handler( + lambda loop, context: self.fail( + f"unexpected exception: {context}") + ) + waiter = self.loop.create_future() + transport, protocol = self.create_transport(waiter) + + # Simulate a waiter registered via _wait() before the process exits. + exit_waiter = self.loop.create_future() + transport._exit_waiters.append(exit_waiter) + + # _connect_pipes hasn't completed, so _pipes_connected is False. + self.assertFalse(transport._pipes_connected) + + # Simulate process exit. _try_finish() will set the result on + # exit_waiter because _pipes_connected is False, and then schedule + # _call_connection_lost() because _pipes is empty (vacuously all + # disconnected). _call_connection_lost() must skip exit_waiter + # because it's already done. + transport._process_exited(6) + self.loop.run_until_complete(waiter) + + self.assertEqual(exit_waiter.result(), 6) + + transport.close() + class SubprocessMixin: diff --git a/Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst b/Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst new file mode 100644 index 00000000000000..15b70d734ca3b9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst @@ -0,0 +1 @@ +Fix InvalidStateError when cancelling process created by :func:`asyncio.create_subprocess_exec` or :func:`asyncio.create_subprocess_shell`. Patch by Daan De Meyer. From 0dfe649400a0b67318169ec813475f4949ad7b69 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 9 Mar 2026 15:47:02 +0100 Subject: [PATCH 365/498] gh-141510: Optimize frozendict(frozendict) (#145592) Return the same object unmodified if it's exactly the frozendict type. Optimize also PyFrozenDict_New(frozendict). --- Lib/test/test_capi/test_dict.py | 10 +++++++ Lib/test/test_dict.py | 7 +++++ Objects/dictobject.c | 53 ++++++++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index 5bdf74ef73ab54..cd46fea5476ca6 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -619,6 +619,16 @@ def test_frozendict_new(self): self.assertEqual(dct, frozendict(x=1, y=2)) self.assertIs(type(dct), frozendict) + # PyFrozenDict_New(frozendict) returns the same object unmodified + fd = frozendict(a=1, b=2, c=3) + fd2 = frozendict_new(fd) + self.assertIs(fd2, fd) + + fd = FrozenDictSubclass(a=1, b=2, c=3) + fd2 = frozendict_new(fd) + self.assertIsNot(fd2, fd) + self.assertEqual(fd2, fd) + # PyFrozenDict_New(NULL) creates an empty dictionary dct = frozendict_new(NULL) self.assertEqual(dct, frozendict()) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 45448d1264a53e..b2f4363b23e748 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1829,6 +1829,13 @@ def test_constructor(self): with self.assertRaises(TypeError): dict.__init__(d, x=1) + # Avoid copy if it's frozendict type + d2 = frozendict(d) + self.assertIs(d2, d) + d2 = FrozenDict(d) + self.assertIsNot(d2, d) + self.assertEqual(d2, d) + def test_copy(self): d = frozendict(x=1, y=2) d2 = d.copy() diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 61fde37f8d4fff..b5f2a682c54982 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -5169,15 +5169,47 @@ dict_vectorcall(PyObject *type, PyObject * const*args, return NULL; } - PyObject *self; - if (Py_Is((PyTypeObject*)type, &PyFrozenDict_Type) - || PyType_IsSubtype((PyTypeObject*)type, &PyFrozenDict_Type)) - { - self = frozendict_new(_PyType_CAST(type), NULL, NULL); + PyObject *self = dict_new(_PyType_CAST(type), NULL, NULL); + if (self == NULL) { + return NULL; } - else { - self = dict_new(_PyType_CAST(type), NULL, NULL); + if (nargs == 1) { + if (dict_update_arg(self, args[0]) < 0) { + Py_DECREF(self); + return NULL; + } + args++; } + if (kwnames != NULL) { + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) { + PyObject *key = PyTuple_GET_ITEM(kwnames, i); // borrowed + if (PyDict_SetItem(self, key, args[i]) < 0) { + Py_DECREF(self); + return NULL; + } + } + } + return self; +} + +static PyObject * +frozendict_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("frozendict", nargs, 0, 1)) { + return NULL; + } + + if (nargs == 1 && kwnames == NULL + && PyFrozenDict_CheckExact(args[0]) + && Py_Is((PyTypeObject*)type, &PyFrozenDict_Type)) + { + // frozendict(frozendict) returns the same object unmodified + return Py_NewRef(args[0]); + } + + PyObject *self = frozendict_new(_PyType_CAST(type), NULL, NULL); if (self == NULL) { return NULL; } @@ -8171,6 +8203,11 @@ PyObject* PyFrozenDict_New(PyObject *iterable) { if (iterable != NULL) { + if (PyFrozenDict_CheckExact(iterable)) { + // PyFrozenDict_New(frozendict) returns the same object unmodified + return Py_NewRef(iterable); + } + PyObject *args = PyTuple_Pack(1, iterable); if (args == NULL) { return NULL; @@ -8228,6 +8265,6 @@ PyTypeObject PyFrozenDict_Type = { .tp_alloc = _PyType_AllocNoTrack, .tp_new = frozendict_new, .tp_free = PyObject_GC_Del, - .tp_vectorcall = dict_vectorcall, + .tp_vectorcall = frozendict_vectorcall, .tp_version_tag = _Py_TYPE_VERSION_FROZENDICT, }; From 27c49707dfd13752791aacd33a3ecfbe780beca2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 9 Mar 2026 15:21:33 +0000 Subject: [PATCH 366/498] GH-144688: Fix refleaks in JIT when optimization fails (GH-145420) --- Python/optimizer.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index f485c27bca2a4f..4387bcb0d67832 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1076,12 +1076,19 @@ _PyJit_FinalizeTracing(PyThreadState *tstate, int err) exit->temperature = initial_temperature_backoff_counter(&tstate->interp->opt_config); } } + // Clear all recorded values + _PyJitUopBuffer *buffer = &tracer->code_buffer; + for (_PyUOpInstruction *inst = buffer->start; inst < buffer->next; inst++) { + if (_PyUop_Flags[inst->opcode] & HAS_RECORDS_VALUE_FLAG) { + Py_XDECREF((PyObject *)(uintptr_t)inst->operand0); + } + } Py_CLEAR(tracer->initial_state.code); Py_CLEAR(tracer->initial_state.func); Py_CLEAR(tracer->initial_state.executor); Py_CLEAR(tracer->prev_state.instr_code); Py_CLEAR(tracer->prev_state.recorded_value); - uop_buffer_init(&tracer->code_buffer, &tracer->uop_array[0], UOP_MAX_TRACE_LENGTH); + uop_buffer_init(buffer, &tracer->uop_array[0], UOP_MAX_TRACE_LENGTH); tracer->is_tracing = false; } @@ -1521,6 +1528,11 @@ uop_optimize( } assert(_PyOpcode_uop_name[buffer[pc].opcode]); } + // We've cleaned up the references in the buffer, so discard the code buffer + // to avoid doing it again during tracer cleanup + _PyJitUopBuffer *code_buffer = &_tstate->jit_tracer_state->code_buffer; + code_buffer->next = code_buffer->start; + OPT_HIST(effective_trace_length(buffer, length), optimized_trace_length_hist); _PyUOpInstruction *output = &_tstate->jit_tracer_state->uop_array[0]; length = stack_allocate(buffer, output, length); From fc03cdccc0e88fe60f1ea6d659da1f3764379520 Mon Sep 17 00:00:00 2001 From: Maciej Olko Date: Mon, 9 Mar 2026 12:19:02 -0400 Subject: [PATCH 367/498] gh-139588: Docs: fix PDF build (#145480) --- Doc/Makefile | 7 ++++++- Doc/conf.py | 1 + Doc/library/profiling.sampling.rst | 20 ++++++++++++-------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index 5b7fdf8ec08ed4..7bdabd8bf168fe 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -88,6 +88,7 @@ htmlhelp: build "build/htmlhelp/pydoc.hhp project file." .PHONY: latex +latex: _ensure-sphinxcontrib-svg2pdfconverter latex: BUILDER = latex latex: build @echo "Build finished; the LaTeX files are in build/latex." @@ -231,7 +232,7 @@ dist-text: @echo "Build finished and archived!" .PHONY: dist-pdf -dist-pdf: +dist-pdf: _ensure-sphinxcontrib-svg2pdfconverter # archive the A4 latex @echo "Building LaTeX (A4 paper)..." mkdir -p dist @@ -292,6 +293,10 @@ _ensure-pre-commit: _ensure-sphinx-autobuild: $(MAKE) _ensure-package PACKAGE=sphinx-autobuild +.PHONY: _ensure-sphinxcontrib-svg2pdfconverter +_ensure-sphinxcontrib-svg2pdfconverter: + $(MAKE) _ensure-package PACKAGE=sphinxcontrib-svg2pdfconverter + .PHONY: check check: _ensure-pre-commit $(VENVDIR)/bin/python3 -m pre_commit run --all-files diff --git a/Doc/conf.py b/Doc/conf.py index 545049bb460419..26497083d28e47 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -46,6 +46,7 @@ 'linklint.ext', 'notfound.extension', 'sphinxext.opengraph', + 'sphinxcontrib.rsvgconverter', ) for optional_ext in _OPTIONAL_EXTENSIONS: try: diff --git a/Doc/library/profiling.sampling.rst b/Doc/library/profiling.sampling.rst index 078062c08c6020..d2b7d9669ab07e 100644 --- a/Doc/library/profiling.sampling.rst +++ b/Doc/library/profiling.sampling.rst @@ -1194,10 +1194,12 @@ data, similar to the ``top`` command for system processes:: python -m profiling.sampling run --live script.py python -m profiling.sampling attach --live 12345 -.. figure:: tachyon-live-mode-2.gif - :alt: Tachyon live mode showing all threads - :align: center - :width: 100% +.. only:: not latex + + .. figure:: tachyon-live-mode-2.gif + :alt: Tachyon live mode showing all threads + :align: center + :width: 100% Live mode displays real-time profiling statistics, showing combined data from multiple threads in a multi-threaded application. @@ -1217,10 +1219,12 @@ main table, showing instruction-level statistics for the currently selected function. This panel displays which bytecode instructions are executing most frequently, including specialized variants and their base opcodes. -.. figure:: tachyon-live-mode-1.gif - :alt: Tachyon live mode with opcode panel - :align: center - :width: 100% +.. only:: not latex + + .. figure:: tachyon-live-mode-1.gif + :alt: Tachyon live mode with opcode panel + :align: center + :width: 100% Live mode with ``--opcodes`` enabled shows an opcode panel with a bytecode instruction breakdown for the selected function. From 171133aa84cd2fa8738bdbb0c76435645810e8d3 Mon Sep 17 00:00:00 2001 From: Yashraj Date: Mon, 9 Mar 2026 22:00:00 +0530 Subject: [PATCH 368/498] gh-141617: clarify `concurrent.futures.ThreadPoolExecutor` deadlock example (#141620) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --------- Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/library/concurrent.futures.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 3ea24ea77004ad..a32c3828313454 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -156,7 +156,9 @@ And:: print(f.result()) executor = ThreadPoolExecutor(max_workers=1) - executor.submit(wait_on_future) + future = executor.submit(wait_on_future) + # Note: calling future.result() would also cause a deadlock because + # the single worker thread is already waiting for wait_on_future(). .. class:: ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=()) From d76df75f51e662fd15ebe00e107058841de94860 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 9 Mar 2026 13:24:34 -0400 Subject: [PATCH 369/498] gh-145615: Fix mimalloc page leak in the free-threaded build (gh-145626) Fix three issues that caused mimalloc pages to be leaked until the owning thread exited: 1. In _PyMem_mi_page_maybe_free(), move pages out of the full queue when relying on QSBR to defer freeing the page. Pages in the full queue are never searched by mi_page_queue_find_free_ex(), so a page left there is unusable for allocations. 2. Move _PyMem_mi_page_clear_qsbr() from _mi_page_free_collect() to _mi_page_thread_free_collect() where it only fires when all blocks on the page are free (used == 0). The previous placement was too broad: it cleared QSBR state whenever local_free was non-NULL, but _mi_page_free_collect() is called from non-allocation paths (e.g., page visiting in mi_heap_visit_blocks) where the page is not being reused. 3. In _PyMem_mi_page_maybe_free(), use the page's heap tld to find the correct thread state for QSBR list insertion instead of PyThreadState_GET(). During stop-the-world pauses, the function may process pages belonging to other threads, so the current thread state is not necessarily the owner of the page. --- ...3-06-21-05-05.gh-issue-145615.NKXXZgDW.rst | 2 ++ Objects/mimalloc/heap.c | 5 ++- Objects/mimalloc/page.c | 10 ++++-- Objects/mimalloc/segment.c | 2 ++ Objects/obmalloc.c | 31 +++++++++++++++---- 5 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst new file mode 100644 index 00000000000000..2183eef618daae --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst @@ -0,0 +1,2 @@ +Fixed a memory leak in the :term:`free-threaded build` where mimalloc pages +could become permanently unreclaimable until the owning thread exited. diff --git a/Objects/mimalloc/heap.c b/Objects/mimalloc/heap.c index d92dc768e5ec28..5fbfb82baa0204 100644 --- a/Objects/mimalloc/heap.c +++ b/Objects/mimalloc/heap.c @@ -100,7 +100,10 @@ static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t // note: this will free retired pages as well. bool freed = _PyMem_mi_page_maybe_free(page, pq, collect >= MI_FORCE); if (!freed && collect == MI_ABANDON) { - _mi_page_abandon(page, pq); + // _PyMem_mi_page_maybe_free may have moved the page to a different + // page queue, so we need to re-fetch the correct queue. + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size)); + _mi_page_abandon(page, &heap->pages[bin]); } } else if (collect == MI_ABANDON) { diff --git a/Objects/mimalloc/page.c b/Objects/mimalloc/page.c index ff7444cce10923..ded59f8eb1ccaa 100644 --- a/Objects/mimalloc/page.c +++ b/Objects/mimalloc/page.c @@ -213,6 +213,13 @@ static void _mi_page_thread_free_collect(mi_page_t* page) // update counts now page->used -= count; + + if (page->used == 0) { + // The page may have had a QSBR goal set from a previous point when it + // was all-free. That goal is no longer valid because the page was + // allocated from and then freed again by other threads. + _PyMem_mi_page_clear_qsbr(page); + } } void _mi_page_free_collect(mi_page_t* page, bool force) { @@ -225,9 +232,6 @@ void _mi_page_free_collect(mi_page_t* page, bool force) { // and the local free list if (page->local_free != NULL) { - // any previous QSBR goals are no longer valid because we reused the page - _PyMem_mi_page_clear_qsbr(page); - if mi_likely(page->free == NULL) { // usual case page->free = page->local_free; diff --git a/Objects/mimalloc/segment.c b/Objects/mimalloc/segment.c index 9b092b9b734d4c..9dad69c995e7a0 100644 --- a/Objects/mimalloc/segment.c +++ b/Objects/mimalloc/segment.c @@ -1286,6 +1286,7 @@ static bool mi_segment_check_free(mi_segment_t* segment, size_t slices_needed, s _mi_stat_decrease(&tld->stats->pages_abandoned, 1); #ifdef Py_GIL_DISABLED page->qsbr_goal = 0; + mi_assert_internal(page->qsbr_node.next == NULL); #endif segment->abandoned--; slice = mi_segment_page_clear(page, tld); // re-assign slice due to coalesce! @@ -1361,6 +1362,7 @@ static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, // if everything free by now, free the page #ifdef Py_GIL_DISABLED page->qsbr_goal = 0; + mi_assert_internal(page->qsbr_node.next == NULL); #endif slice = mi_segment_page_clear(page, tld); // set slice again due to coalesceing } diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index b59ebdfbda3897..983bdddbf026a8 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -151,6 +151,12 @@ should_advance_qsbr_for_page(struct _qsbr_thread_state *qsbr, mi_page_t *page) } return false; } + +static _PyThreadStateImpl * +tstate_from_heap(mi_heap_t *heap) +{ + return _Py_CONTAINER_OF(heap->tld, _PyThreadStateImpl, mimalloc.tld); +} #endif static bool @@ -159,23 +165,35 @@ _PyMem_mi_page_maybe_free(mi_page_t *page, mi_page_queue_t *pq, bool force) #ifdef Py_GIL_DISABLED assert(mi_page_all_free(page)); if (page->use_qsbr) { - _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)PyThreadState_GET(); - if (page->qsbr_goal != 0 && _Py_qbsr_goal_reached(tstate->qsbr, page->qsbr_goal)) { + struct _qsbr_thread_state *qsbr = ((_PyThreadStateImpl *)PyThreadState_GET())->qsbr; + if (page->qsbr_goal != 0 && _Py_qbsr_goal_reached(qsbr, page->qsbr_goal)) { _PyMem_mi_page_clear_qsbr(page); _mi_page_free(page, pq, force); return true; } + // gh-145615: since we are not freeing this page yet, we want to + // make it available for allocations. Note that the QSBR goal and + // linked list node remain set even if the page is later used for + // an allocation. We only detect and clear the QSBR goal when the + // page becomes empty again (used == 0). + if (mi_page_is_in_full(page)) { + _mi_page_unfull(page); + } + _PyMem_mi_page_clear_qsbr(page); page->retire_expire = 0; - if (should_advance_qsbr_for_page(tstate->qsbr, page)) { - page->qsbr_goal = _Py_qsbr_advance(tstate->qsbr->shared); + if (should_advance_qsbr_for_page(qsbr, page)) { + page->qsbr_goal = _Py_qsbr_advance(qsbr->shared); } else { - page->qsbr_goal = _Py_qsbr_shared_next(tstate->qsbr->shared); + page->qsbr_goal = _Py_qsbr_shared_next(qsbr->shared); } + // We may be freeing a page belonging to a different thread during a + // stop-the-world event. Find the _PyThreadStateImpl for the page. + _PyThreadStateImpl *tstate = tstate_from_heap(mi_page_heap(page)); llist_insert_tail(&tstate->mimalloc.page_list, &page->qsbr_node); return false; } @@ -192,7 +210,8 @@ _PyMem_mi_page_reclaimed(mi_page_t *page) if (page->qsbr_goal != 0) { if (mi_page_all_free(page)) { assert(page->qsbr_node.next == NULL); - _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)PyThreadState_GET(); + _PyThreadStateImpl *tstate = tstate_from_heap(mi_page_heap(page)); + assert(tstate == (_PyThreadStateImpl *)_PyThreadState_GET()); page->retire_expire = 0; llist_insert_tail(&tstate->mimalloc.page_list, &page->qsbr_node); } From 255e79fa955ac5ffef9eb27087e8b1373e98e3bd Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:37:23 +0000 Subject: [PATCH 370/498] gh-143055: Fix crash in AST unparser when unparsing dict comprehension unpacking (#145556) --- Doc/conf.py | 1 + Lib/_ast_unparse.py | 10 +++++++--- Lib/test/test_future_stmt/test_future.py | 2 ++ Lib/test/test_unparse.py | 5 +++++ .../2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst | 2 ++ Python/ast_unparse.c | 12 +++++++++--- 6 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst diff --git a/Doc/conf.py b/Doc/conf.py index 26497083d28e47..6f66ed68c52e83 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -557,6 +557,7 @@ # mapping unique short aliases to a base URL and a prefix. # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html extlinks = { + "oss-fuzz": ("https://issues.oss-fuzz.com/issues/%s", "#%s"), "pypi": ("https://pypi.org/project/%s/", "%s"), "source": (SOURCE_URI, "%s"), } diff --git a/Lib/_ast_unparse.py b/Lib/_ast_unparse.py index 0c3b1d3a9108a3..916bb25d74dee9 100644 --- a/Lib/_ast_unparse.py +++ b/Lib/_ast_unparse.py @@ -738,9 +738,13 @@ def visit_SetComp(self, node): def visit_DictComp(self, node): with self.delimit("{", "}"): - self.traverse(node.key) - self.write(": ") - self.traverse(node.value) + if node.value: + self.traverse(node.key) + self.write(": ") + self.traverse(node.value) + else: + self.write("**") + self.traverse(node.key) for gen in node.generators: self.traverse(gen) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 71f1e616116d81..faa3a2bfe121dc 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -349,6 +349,8 @@ def test_annotations(self): eq("(i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3))") eq("{i: 0 for i in (1, 2, 3)}") eq("{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}") + eq("{**x for x in ()}") + eq("[*x for x in ()]") eq("[(x, y) for x, y in (a, b)]") eq("[(x,) for x, in (a,)]") eq("Python3 > Python2 > COBOL") diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index 35e4652a87b423..dcaad49ffab5d2 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -403,6 +403,11 @@ def test_set_comprehension(self): def test_dict_comprehension(self): self.check_ast_roundtrip("{x: x*x for x in range(10)}") + def test_dict_comprehension_unpacking(self): + self.check_ast_roundtrip("{**x for x in ()}") + self.check_ast_roundtrip("{**x for x in range(10)}") + self.check_ast_roundtrip("[*x for x in ()]") + def test_class_decorators(self): self.check_ast_roundtrip(class_decorator) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst new file mode 100644 index 00000000000000..9b55459bffdea8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst @@ -0,0 +1,2 @@ +Fix crash in AST unparser when unparsing dict comprehension unpacking. +Found by OSS Fuzz in :oss-fuzz:`489790200`. diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index c25699978cf651..6050c351cff68f 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -464,9 +464,15 @@ static int append_ast_dictcomp(PyUnicodeWriter *writer, expr_ty e) { APPEND_CHAR('{'); - APPEND_EXPR(e->v.DictComp.key, PR_TEST); - APPEND_STR(": "); - APPEND_EXPR(e->v.DictComp.value, PR_TEST); + if (e->v.DictComp.value) { + APPEND_EXPR(e->v.DictComp.key, PR_TEST); + APPEND_STR(": "); + APPEND_EXPR(e->v.DictComp.value, PR_TEST); + } + else { + APPEND_STR("**"); + APPEND_EXPR(e->v.DictComp.key, PR_TEST); + } APPEND(comprehensions, e->v.DictComp.generators); APPEND_CHAR_FINISH('}'); } From 07a39ca07e4cbacb2941d22c9901047df292059b Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 9 Mar 2026 19:18:14 +0100 Subject: [PATCH 371/498] gh-145278: Revert "freeze encodings (partially) and linecache (#145279)" (#145689) --- Makefile.pre.in | 20 ------------------- ...-02-26-21-22-34.gh-issue-145278.DHkYqt.rst | 4 ---- PCbuild/_freeze_module.vcxproj | 20 ------------------- PCbuild/_freeze_module.vcxproj.filters | 12 ----------- Python/frozen.c | 10 ---------- Tools/build/freeze_modules.py | 10 ++++------ 6 files changed, 4 insertions(+), 72 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst diff --git a/Makefile.pre.in b/Makefile.pre.in index 4c2426ed283d43..120a6add38507f 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1729,9 +1729,6 @@ FROZEN_FILES_IN = \ Lib/zipimport.py \ Lib/abc.py \ Lib/codecs.py \ - Lib/encodings/__init__.py \ - Lib/encodings/aliases.py \ - Lib/encodings/utf_8.py \ Lib/io.py \ Lib/_collections_abc.py \ Lib/_sitebuiltins.py \ @@ -1741,7 +1738,6 @@ FROZEN_FILES_IN = \ Lib/os.py \ Lib/site.py \ Lib/stat.py \ - Lib/linecache.py \ Lib/importlib/util.py \ Lib/importlib/machinery.py \ Lib/runpy.py \ @@ -1758,9 +1754,6 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/zipimport.h \ Python/frozen_modules/abc.h \ Python/frozen_modules/codecs.h \ - Python/frozen_modules/encodings.h \ - Python/frozen_modules/encodings.aliases.h \ - Python/frozen_modules/encodings.utf_8.h \ Python/frozen_modules/io.h \ Python/frozen_modules/_collections_abc.h \ Python/frozen_modules/_sitebuiltins.h \ @@ -1770,7 +1763,6 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/os.h \ Python/frozen_modules/site.h \ Python/frozen_modules/stat.h \ - Python/frozen_modules/linecache.h \ Python/frozen_modules/importlib.util.h \ Python/frozen_modules/importlib.machinery.h \ Python/frozen_modules/runpy.h \ @@ -1810,15 +1802,6 @@ Python/frozen_modules/abc.h: Lib/abc.py $(FREEZE_MODULE_DEPS) Python/frozen_modules/codecs.h: Lib/codecs.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) codecs $(srcdir)/Lib/codecs.py Python/frozen_modules/codecs.h -Python/frozen_modules/encodings.h: Lib/encodings/__init__.py $(FREEZE_MODULE_DEPS) - $(FREEZE_MODULE) encodings $(srcdir)/Lib/encodings/__init__.py Python/frozen_modules/encodings.h - -Python/frozen_modules/encodings.aliases.h: Lib/encodings/aliases.py $(FREEZE_MODULE_DEPS) - $(FREEZE_MODULE) encodings.aliases $(srcdir)/Lib/encodings/aliases.py Python/frozen_modules/encodings.aliases.h - -Python/frozen_modules/encodings.utf_8.h: Lib/encodings/utf_8.py $(FREEZE_MODULE_DEPS) - $(FREEZE_MODULE) encodings.utf_8 $(srcdir)/Lib/encodings/utf_8.py Python/frozen_modules/encodings.utf_8.h - Python/frozen_modules/io.h: Lib/io.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) io $(srcdir)/Lib/io.py Python/frozen_modules/io.h @@ -1846,9 +1829,6 @@ Python/frozen_modules/site.h: Lib/site.py $(FREEZE_MODULE_DEPS) Python/frozen_modules/stat.h: Lib/stat.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) stat $(srcdir)/Lib/stat.py Python/frozen_modules/stat.h -Python/frozen_modules/linecache.h: Lib/linecache.py $(FREEZE_MODULE_DEPS) - $(FREEZE_MODULE) linecache $(srcdir)/Lib/linecache.py Python/frozen_modules/linecache.h - Python/frozen_modules/importlib.util.h: Lib/importlib/util.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) importlib.util $(srcdir)/Lib/importlib/util.py Python/frozen_modules/importlib.util.h diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst deleted file mode 100644 index 6b6a9eb9813663..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-22-34.gh-issue-145278.DHkYqt.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :mod:`encodings` is now partially frozen, including -the ``aliases`` and ``utf_8`` submodules. - -The :mod:`linecache` is now frozen. diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 40946cafd16b75..cb806459596084 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -310,21 +310,6 @@ $(IntDir)codecs.g.h $(GeneratedFrozenModulesDir)Python\frozen_modules\codecs.h - - encodings - $(IntDir)encodings.g.h - $(GeneratedFrozenModulesDir)Python\frozen_modules\encodings.h - - - encodings.aliases - $(IntDir)encodings.aliases.g.h - $(GeneratedFrozenModulesDir)Python\frozen_modules\encodings.aliases.h - - - encodings.utf_8 - $(IntDir)encodings.utf_8.g.h - $(GeneratedFrozenModulesDir)Python\frozen_modules\encodings.utf_8.h - io $(IntDir)io.g.h @@ -370,11 +355,6 @@ $(IntDir)stat.g.h $(GeneratedFrozenModulesDir)Python\frozen_modules\stat.h - - linecache - $(IntDir)linecache.g.h - $(GeneratedFrozenModulesDir)Python\frozen_modules\linecache.h - importlib.util $(IntDir)importlib.util.g.h diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index a0e36a4c526ede..6dcf0e8712903a 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -537,15 +537,6 @@ Python Files - - Python Files - - - Python Files - - - Python Files - Python Files @@ -573,9 +564,6 @@ Python Files - - Python Files - Python Files diff --git a/Python/frozen.c b/Python/frozen.c index 72a291d0d43f1d..15d256b6743e0a 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -46,9 +46,6 @@ #include "frozen_modules/zipimport.h" #include "frozen_modules/abc.h" #include "frozen_modules/codecs.h" -#include "frozen_modules/encodings.h" -#include "frozen_modules/encodings.aliases.h" -#include "frozen_modules/encodings.utf_8.h" #include "frozen_modules/io.h" #include "frozen_modules/_collections_abc.h" #include "frozen_modules/_sitebuiltins.h" @@ -58,7 +55,6 @@ #include "frozen_modules/os.h" #include "frozen_modules/site.h" #include "frozen_modules/stat.h" -#include "frozen_modules/linecache.h" #include "frozen_modules/importlib.util.h" #include "frozen_modules/importlib.machinery.h" #include "frozen_modules/runpy.h" @@ -80,9 +76,6 @@ static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), false}, {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), false}, - {"encodings", _Py_M__encodings, (int)sizeof(_Py_M__encodings), true}, - {"encodings.aliases", _Py_M__encodings_aliases, (int)sizeof(_Py_M__encodings_aliases), false}, - {"encodings.utf_8", _Py_M__encodings_utf_8, (int)sizeof(_Py_M__encodings_utf_8), false}, {"io", _Py_M__io, (int)sizeof(_Py_M__io), false}, /* stdlib - startup, with site */ @@ -95,9 +88,6 @@ static const struct _frozen stdlib_modules[] = { {"site", _Py_M__site, (int)sizeof(_Py_M__site), false}, {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat), false}, - /* pythonrun - interactive */ - {"linecache", _Py_M__linecache, (int)sizeof(_Py_M__linecache), false}, - /* runpy - run module with -m */ {"importlib.util", _Py_M__importlib_util, (int)sizeof(_Py_M__importlib_util), false}, {"importlib.machinery", _Py_M__importlib_machinery, (int)sizeof(_Py_M__importlib_machinery), false}, diff --git a/Tools/build/freeze_modules.py b/Tools/build/freeze_modules.py index 0d1f5968d2a9e9..3c43f7e3bbe8ca 100644 --- a/Tools/build/freeze_modules.py +++ b/Tools/build/freeze_modules.py @@ -50,9 +50,10 @@ ('stdlib - startup, without site (python -S)', [ 'abc', 'codecs', - '', - 'encodings.aliases', - 'encodings.utf_8', + # For now we do not freeze the encodings, due # to the noise all + # those extra modules add to the text printed during the build. + # (See https://github.com/python/cpython/pull/28398#pullrequestreview-756856469.) + #'', 'io', ]), ('stdlib - startup, with site', [ @@ -65,9 +66,6 @@ 'site', 'stat', ]), - ('pythonrun - interactive', [ - 'linecache', - ]), ('runpy - run module with -m', [ "importlib.util", "importlib.machinery", From f31ac36df6e9cddb4f498a7696e595f9f667c7b9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:23:11 +0200 Subject: [PATCH 372/498] Docs: Update programming FAQ (#144573) Co-authored-by: Savannah Ostrowski Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Stan Ulbrych --- Doc/faq/programming.rst | 130 +++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 7a6f88d90a9ea5..8bd2bc99d74b83 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -8,11 +8,11 @@ Programming FAQ .. contents:: -General Questions +General questions ================= -Is there a source code level debugger with breakpoints, single-stepping, etc.? ------------------------------------------------------------------------------- +Is there a source code-level debugger with breakpoints and single-stepping? +--------------------------------------------------------------------------- Yes. @@ -25,8 +25,7 @@ Reference Manual `. You can also write your own debugger by using the code for pdb as an example. The IDLE interactive development environment, which is part of the standard -Python distribution (normally available as -`Tools/scripts/idle3 `_), +Python distribution (normally available as :mod:`idlelib`), includes a graphical debugger. PythonWin is a Python IDE that includes a GUI debugger based on pdb. The @@ -48,7 +47,6 @@ There are a number of commercial Python IDEs that include graphical debuggers. They include: * `Wing IDE `_ -* `Komodo IDE `_ * `PyCharm `_ @@ -57,13 +55,15 @@ Are there tools to help find bugs or perform static analysis? Yes. -`Pylint `_ and -`Pyflakes `_ do basic checking that will +`Ruff `__, +`Pylint `__ and +`Pyflakes `__ do basic checking that will help you catch bugs sooner. -Static type checkers such as `Mypy `_, -`Pyre `_, and -`Pytype `_ can check type hints in Python +Static type checkers such as `mypy `__, +`ty `__, +`Pyrefly `__, and +`pytype `__ can check type hints in Python source code. @@ -79,7 +79,7 @@ set of modules required by a program and bind these modules together with a Python binary to produce a single executable. One is to use the freeze tool, which is included in the Python source tree as -`Tools/freeze `_. +:source:`Tools/freeze`. It converts Python byte code to C arrays; with a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules. @@ -103,6 +103,7 @@ executables: * `py2app `_ (macOS only) * `py2exe `_ (Windows only) + Are there coding standards or a style guide for Python programs? ---------------------------------------------------------------- @@ -110,7 +111,7 @@ Yes. The coding style required for standard library modules is documented as :pep:`8`. -Core Language +Core language ============= .. _faq-unboundlocalerror: @@ -143,7 +144,7 @@ results in an :exc:`!UnboundLocalError`: >>> foo() Traceback (most recent call last): ... - UnboundLocalError: local variable 'x' referenced before assignment + UnboundLocalError: cannot access local variable 'x' where it is not associated with a value This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable @@ -208,7 +209,7 @@ Why do lambdas defined in a loop with different values all return the same resul ---------------------------------------------------------------------------------- Assume you use a for loop to define a few different lambdas (or even plain -functions), e.g.:: +functions), for example:: >>> squares = [] >>> for x in range(5): @@ -227,7 +228,7 @@ they all return ``16``:: This happens because ``x`` is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called --- not when it is defined. At the end of the loop, the value of ``x`` is ``4``, so all the -functions now return ``4**2``, i.e. ``16``. You can also verify this by +functions now return ``4**2``, that is ``16``. You can also verify this by changing the value of ``x`` and see how the results of the lambdas change:: >>> x = 8 @@ -298,9 +299,9 @@ using multiple imports per line uses less screen space. It's good practice if you import modules in the following order: -1. standard library modules -- e.g. :mod:`sys`, :mod:`os`, :mod:`argparse`, :mod:`re` +1. standard library modules -- such as :mod:`sys`, :mod:`os`, :mod:`argparse`, :mod:`re` 2. third-party library modules (anything installed in Python's site-packages - directory) -- e.g. :mod:`!dateutil`, :mod:`!requests`, :mod:`!PIL.Image` + directory) -- such as :pypi:`dateutil`, :pypi:`requests`, :pypi:`tzdata` 3. locally developed modules It is sometimes necessary to move imports to a function or class to avoid @@ -494,11 +495,11 @@ new objects). In other words: -* If we have a mutable object (:class:`list`, :class:`dict`, :class:`set`, - etc.), we can use some specific operations to mutate it and all the variables +* If we have a mutable object (such as :class:`list`, :class:`dict`, :class:`set`), + we can use some specific operations to mutate it and all the variables that refer to it will see the change. -* If we have an immutable object (:class:`str`, :class:`int`, :class:`tuple`, - etc.), all the variables that refer to it will always see the same value, +* If we have an immutable object (such as :class:`str`, :class:`int`, :class:`tuple`), + all the variables that refer to it will always see the same value, but operations that transform that value into a new value always return a new object. @@ -511,7 +512,7 @@ How do I write a function with output parameters (call by reference)? Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there's no alias between an argument name in -the caller and callee, and so no call-by-reference per se. You can achieve the +the caller and callee, and consequently no call-by-reference. You can achieve the desired effect in a number of ways. 1) By returning a tuple of the results:: @@ -714,8 +715,8 @@ not:: "a" in ("b", "a") -The same is true of the various assignment operators (``=``, ``+=`` etc). They -are not truly operators but syntactic delimiters in assignment statements. +The same is true of the various assignment operators (``=``, ``+=``, and so on). +They are not truly operators but syntactic delimiters in assignment statements. Is there an equivalent of C's "?:" ternary operator? @@ -868,9 +869,9 @@ with either a space or parentheses. How do I convert a string to a number? -------------------------------------- -For integers, use the built-in :func:`int` type constructor, e.g. ``int('144') +For integers, use the built-in :func:`int` type constructor, for example, ``int('144') == 144``. Similarly, :func:`float` converts to a floating-point number, -e.g. ``float('144') == 144.0``. +for example, ``float('144') == 144.0``. By default, these interpret the number as decimal, so that ``int('0144') == 144`` holds true, and ``int('0x144')`` raises :exc:`ValueError`. ``int(string, @@ -887,18 +888,18 @@ unwanted side effects. For example, someone could pass directory. :func:`eval` also has the effect of interpreting numbers as Python expressions, -so that e.g. ``eval('09')`` gives a syntax error because Python does not allow +so that, for example, ``eval('09')`` gives a syntax error because Python does not allow leading '0' in a decimal number (except '0'). How do I convert a number to a string? -------------------------------------- -To convert, e.g., the number ``144`` to the string ``'144'``, use the built-in type +For example, to convert the number ``144`` to the string ``'144'``, use the built-in type constructor :func:`str`. If you want a hexadecimal or octal representation, use the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see -the :ref:`f-strings` and :ref:`formatstrings` sections, -e.g. ``"{:04d}".format(144)`` yields +the :ref:`f-strings` and :ref:`formatstrings` sections. +For example, ``"{:04d}".format(144)`` yields ``'0144'`` and ``"{:.3f}".format(1.0/3.0)`` yields ``'0.333'``. @@ -908,7 +909,7 @@ How do I modify a string in place? You can't, because strings are immutable. In most situations, you should simply construct a new string from the various parts you want to assemble it from. However, if you need an object with the ability to modify in-place -unicode data, try using an :class:`io.StringIO` object or the :mod:`array` +Unicode data, try using an :class:`io.StringIO` object or the :mod:`array` module:: >>> import io @@ -1066,13 +1067,14 @@ the raw string:: Also see the specification in the :ref:`language reference `. + Performance =========== My program is too slow. How do I speed it up? --------------------------------------------- -That's a tough one, in general. First, here are a list of things to +That's a tough one, in general. First, here is list of things to remember before diving further: * Performance characteristics vary across Python implementations. This FAQ @@ -1125,6 +1127,7 @@ yourself. The wiki page devoted to `performance tips `_. + .. _efficient_string_concatenation: What is the most efficient way to concatenate many strings together? @@ -1143,7 +1146,7 @@ them into a list and call :meth:`str.join` at the end:: chunks.append(s) result = ''.join(chunks) -(another reasonably efficient idiom is to use :class:`io.StringIO`) +(Another reasonably efficient idiom is to use :class:`io.StringIO`.) To accumulate many :class:`bytes` objects, the recommended idiom is to extend a :class:`bytearray` object using in-place concatenation (the ``+=`` operator):: @@ -1153,7 +1156,7 @@ a :class:`bytearray` object using in-place concatenation (the ``+=`` operator):: result += b -Sequences (Tuples/Lists) +Sequences (tuples/lists) ======================== How do I convert between tuples and lists? @@ -1217,8 +1220,8 @@ list, deleting duplicates as you go:: else: last = mylist[i] -If all elements of the list may be used as set keys (i.e. they are all -:term:`hashable`) this is often faster :: +If all elements of the list may be used as set keys (that is, they are all +:term:`hashable`) this is often faster:: mylist = list(set(mylist)) @@ -1254,7 +1257,7 @@ difference is that a Python list can contain objects of many different types. The ``array`` module also provides methods for creating arrays of fixed types with compact representations, but they are slower to index than lists. Also note that `NumPy `_ -and other third party packages define array-like structures with +and other third-party packages define array-like structures with various characteristics as well. To get Lisp-style linked lists, you can emulate *cons cells* using tuples:: @@ -1324,7 +1327,7 @@ Or, you can use an extension that provides a matrix datatype; `NumPy How do I apply a method or function to a sequence of objects? ------------------------------------------------------------- -To call a method or function and accumulate the return values is a list, +To call a method or function and accumulate the return values in a list, a :term:`list comprehension` is an elegant solution:: result = [obj.method() for obj in mylist] @@ -1340,6 +1343,7 @@ a plain :keyword:`for` loop will suffice:: for obj in mylist: function(obj) + .. _faq-augmented-assignment-tuple-error: Why does a_tuple[i] += ['item'] raise an exception when the addition works? @@ -1444,7 +1448,7 @@ How can I sort one list by values from another list? ---------------------------------------------------- Merge them into an iterator of tuples, sort the resulting list, and then pick -out the element you want. :: +out the element you want. >>> list1 = ["what", "I'm", "sorting", "by"] >>> list2 = ["something", "else", "to", "sort"] @@ -1504,14 +1508,15 @@ How do I check if an object is an instance of a given class or of a subclass of Use the built-in function :func:`isinstance(obj, cls) `. You can check if an object is an instance of any of a number of classes by providing a tuple instead of a -single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also -check whether an object is one of Python's built-in types, e.g. +single class, for example, ``isinstance(obj, (class1, class2, ...))``, and can also +check whether an object is one of Python's built-in types, for example, ``isinstance(obj, str)`` or ``isinstance(obj, (int, float, complex))``. Note that :func:`isinstance` also checks for virtual inheritance from an :term:`abstract base class`. So, the test will return ``True`` for a registered class even if hasn't directly or indirectly inherited from it. To -test for "true inheritance", scan the :term:`MRO` of the class: +test for "true inheritance", scan the :term:`method resolution order` (MRO) of +the class: .. testcode:: @@ -1574,7 +1579,7 @@ call it:: What is delegation? ------------------- -Delegation is an object oriented technique (also called a design pattern). +Delegation is an object-oriented technique (also called a design pattern). Let's say you have an object ``x`` and want to change the behaviour of just one of its methods. You can create a new class that provides a new implementation of the method you're interested in changing and delegates all other methods to @@ -1645,7 +1650,7 @@ How can I organize my code to make it easier to change the base class? You could assign the base class to an alias and derive from the alias. Then all you have to change is the value assigned to the alias. Incidentally, this trick -is also handy if you want to decide dynamically (e.g. depending on availability +is also handy if you want to decide dynamically (such as depending on availability of resources) which base class to use. Example:: class Base: @@ -1710,9 +1715,9 @@ How can I overload constructors (or methods) in Python? This answer actually applies to all methods, but the question usually comes up first in the context of constructors. -In C++ you'd write +In C++ you'd write: -.. code-block:: c +.. code-block:: c++ class C { C() { cout << "No arguments\n"; } @@ -1731,7 +1736,7 @@ default arguments. For example:: This is not entirely equivalent, but close enough in practice. -You could also try a variable-length argument list, e.g. :: +You could also try a variable-length argument list, for example:: def __init__(self, *args): ... @@ -1774,6 +1779,7 @@ to use private variable names at all. The :ref:`private name mangling specifications ` for details and special cases. + My class defines __del__ but it is not called when I delete the object. ----------------------------------------------------------------------- @@ -1783,7 +1789,7 @@ The :keyword:`del` statement does not necessarily call :meth:`~object.__del__` - decrements the object's reference count, and if this reaches zero :meth:`!__del__` is called. -If your data structures contain circular links (e.g. a tree where each child has +If your data structures contain circular links (for example, a tree where each child has a parent reference and each parent has a list of children) the reference counts will never go back to zero. Once in a while Python runs an algorithm to detect such cycles, but the garbage collector might run some time after the last @@ -1885,9 +1891,9 @@ are preferred. In particular, identity tests should not be used to check constants such as :class:`int` and :class:`str` which aren't guaranteed to be singletons:: - >>> a = 1000 - >>> b = 500 - >>> c = b + 500 + >>> a = 10_000_000 + >>> b = 5_000_000 + >>> c = b + 5_000_000 >>> a is c False @@ -1956,9 +1962,9 @@ parent class: .. testcode:: - from datetime import date + import datetime as dt - class FirstOfMonthDate(date): + class FirstOfMonthDate(dt.date): "Always choose the first day of the month" def __new__(cls, year, month, day): return super().__new__(cls, year, month, 1) @@ -2001,7 +2007,7 @@ The two principal tools for caching methods are former stores results at the instance level and the latter at the class level. -The *cached_property* approach only works with methods that do not take +The ``cached_property`` approach only works with methods that do not take any arguments. It does not create a reference to the instance. The cached method result will be kept only as long as the instance is alive. @@ -2010,7 +2016,7 @@ method result will be released right away. The disadvantage is that if instances accumulate, so too will the accumulated method results. They can grow without bound. -The *lru_cache* approach works with methods that have :term:`hashable` +The ``lru_cache`` approach works with methods that have :term:`hashable` arguments. It creates a reference to the instance unless special efforts are made to pass in weak references. @@ -2044,11 +2050,11 @@ This example shows the various techniques:: # Depends on the station_id, date, and units. The above example assumes that the *station_id* never changes. If the -relevant instance attributes are mutable, the *cached_property* approach +relevant instance attributes are mutable, the ``cached_property`` approach can't be made to work because it cannot detect changes to the attributes. -To make the *lru_cache* approach work when the *station_id* is mutable, +To make the ``lru_cache`` approach work when the *station_id* is mutable, the class needs to define the :meth:`~object.__eq__` and :meth:`~object.__hash__` methods so that the cache can detect relevant attribute updates:: @@ -2094,10 +2100,10 @@ one user but run as another, such as if you are testing with a web server. Unless the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable is set, creation of a .pyc file is automatic if you're importing a module and Python -has the ability (permissions, free space, etc...) to create a ``__pycache__`` +has the ability (permissions, free space, and so on) to create a ``__pycache__`` subdirectory and write the compiled module to that subdirectory. -Running Python on a top level script is not considered an import and no +Running Python on a top-level script is not considered an import and no ``.pyc`` will be created. For example, if you have a top-level module ``foo.py`` that imports another module ``xyz.py``, when you run ``foo`` (by typing ``python foo.py`` as a shell command), a ``.pyc`` will be created for @@ -2116,7 +2122,7 @@ the ``compile()`` function in that module interactively:: This will write the ``.pyc`` to a ``__pycache__`` subdirectory in the same location as ``foo.py`` (or you can override that with the optional parameter -``cfile``). +*cfile*). You can also automatically compile all files in a directory or directories using the :mod:`compileall` module. You can do it from the shell prompt by running @@ -2221,7 +2227,7 @@ changed module, do this:: importlib.reload(modname) Warning: this technique is not 100% fool-proof. In particular, modules -containing statements like :: +containing statements like:: from modname import some_objects From 64d6c75dd02718e3554657a0c58c39122bf229ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Mon, 9 Mar 2026 19:37:33 +0000 Subject: [PATCH 373/498] GH-145273: don't skip missing platstdlib warning if stdlib_zip is found (#145544) --- Modules/getpath.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/getpath.py b/Modules/getpath.py index 2f4d635a29585c..4dceb5cdc8dfcf 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -776,9 +776,9 @@ def search_up(prefix, *landmarks, test=isfile): # Warn if the standard library is missing, unless pythonpath_was_set was set, as # that skips parts of the stdlib directories calculation — assume the provided # pythonpath is correct. This is how subinterpreters initialize the path for eg. -if not py_setpath and not pythonpath_was_set and (not stdlib_zip or not isfile(stdlib_zip)): +if not py_setpath and not pythonpath_was_set: home_hint = f"The Python 'home' directory was set to {home!r}, is this correct?" - if not stdlib_dir or not isdir(stdlib_dir): + if (not stdlib_zip or not isfile(stdlib_zip)) and (not stdlib_dir or not isdir(stdlib_dir)): hint = home_hint if home else f'sys.prefix is set to {prefix}, is this correct?' warn('WARN: Could not find the standard library directory! ' + hint) elif not platstdlib_dir or not isdir(platstdlib_dir): From d6c1763a08d7679ee4b11466c7fa088692c6903e Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:43:13 +0000 Subject: [PATCH 374/498] Remove the `distutils-sig@python.org` email in 'Installing Python Modules' (#145613) --- Doc/installing/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index 3a485a43a5a751..412005f3ec82f4 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -6,8 +6,6 @@ Installing Python Modules ************************* -:Email: distutils-sig@python.org - As a popular open source development project, Python has an active supporting community of contributors and users that also make their software available for other Python developers to use under open source license terms. From 63eaaf95999c530cbd75b3addc3e660499d3adbe Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:56:41 +0000 Subject: [PATCH 375/498] gh-145701: Fix `__classdict__` & `__conditional_annotations__` in class-scope inlined comprehensions (GH-145702) --- Lib/test/test_listcomps.py | 12 +++++++++ ...-03-09-18-52-03.gh-issue-145701.79KQyO.rst | 3 +++ Python/symtable.c | 26 ++++++++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index 70148dc30fc957..cee528722b85aa 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -180,6 +180,18 @@ def test_references___class___defined(self): code, outputs={"res": [2]}, scopes=["module", "function"]) self._check_in_scopes(code, raises=NameError, scopes=["class"]) + def test_references___classdict__(self): + code = """ + class i: [__classdict__ for x in y] + """ + self._check_in_scopes(code, raises=NameError) + + def test_references___conditional_annotations__(self): + code = """ + class i: [__conditional_annotations__ for x in y] + """ + self._check_in_scopes(code, raises=NameError) + def test_references___class___enclosing(self): code = """ __class__ = 2 diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst new file mode 100644 index 00000000000000..23796082fb616f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst @@ -0,0 +1,3 @@ +Fix :exc:`SystemError` when ``__classdict__`` or +``__conditional_annotations__`` is in a class-scope inlined comprehension. +Found by OSS Fuzz in :oss-fuzz:`491105000`. diff --git a/Python/symtable.c b/Python/symtable.c index beb6df88d097e3..4b695e4b2588d8 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -807,6 +807,8 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, PyObject *k, *v; Py_ssize_t pos = 0; int remove_dunder_class = 0; + int remove_dunder_classdict = 0; + int remove_dunder_cond_annotations = 0; while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) { // skip comprehension parameter @@ -829,15 +831,27 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, if (existing == NULL && PyErr_Occurred()) { return 0; } - // __class__ is never allowed to be free through a class scope (see + // __class__, __classdict__ and __conditional_annotations__ are + // never allowed to be free through a class scope (see // drop_class_free) if (scope == FREE && ste->ste_type == ClassBlock && - _PyUnicode_EqualToASCIIString(k, "__class__")) { + (_PyUnicode_EqualToASCIIString(k, "__class__") || + _PyUnicode_EqualToASCIIString(k, "__classdict__") || + _PyUnicode_EqualToASCIIString(k, "__conditional_annotations__"))) { scope = GLOBAL_IMPLICIT; if (PySet_Discard(comp_free, k) < 0) { return 0; } - remove_dunder_class = 1; + + if (_PyUnicode_EqualToASCIIString(k, "__class__")) { + remove_dunder_class = 1; + } + else if (_PyUnicode_EqualToASCIIString(k, "__conditional_annotations__")) { + remove_dunder_cond_annotations = 1; + } + else { + remove_dunder_classdict = 1; + } } if (!existing) { // name does not exist in scope, copy from comprehension @@ -877,6 +891,12 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, if (remove_dunder_class && PyDict_DelItemString(comp->ste_symbols, "__class__") < 0) { return 0; } + if (remove_dunder_classdict && PyDict_DelItemString(comp->ste_symbols, "__classdict__") < 0) { + return 0; + } + if (remove_dunder_cond_annotations && PyDict_DelItemString(comp->ste_symbols, "__conditional_annotations__") < 0) { + return 0; + } return 1; } From 0b65c88c2af6e09530a9aa21800771aa687371db Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 9 Mar 2026 18:41:07 -0400 Subject: [PATCH 376/498] gh-145685: Stop the world when updating MRO of existing types (gh-145707) We already have a stop-the-world pause elsewhere in this code path (type_set_bases) and this makes will make it easier to avoid contention on the TYPE_LOCK when looking up names in the MRO hierarchy. Also use deferred reference counting for non-immortal MROs. --- Objects/typeobject.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 27ec8bb40a929f..81abb0990eebe9 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -647,7 +647,6 @@ clear_tp_bases(PyTypeObject *self, int final) static inline PyObject * lookup_tp_mro(PyTypeObject *self) { - ASSERT_NEW_TYPE_OR_LOCKED(self); return self->tp_mro; } @@ -664,8 +663,19 @@ set_tp_mro(PyTypeObject *self, PyObject *mro, int initial) /* Other checks are done via set_tp_bases. */ _Py_SetImmortal(mro); } + else { + PyUnstable_Object_EnableDeferredRefcount(mro); + } + } + if (!initial) { + type_lock_prevent_release(); + types_stop_world(); } self->tp_mro = mro; + if (!initial) { + types_start_world(); + type_lock_allow_release(); + } } static inline void @@ -1728,18 +1738,11 @@ static PyObject * type_get_mro(PyObject *tp, void *Py_UNUSED(closure)) { PyTypeObject *type = PyTypeObject_CAST(tp); - PyObject *mro; - - BEGIN_TYPE_LOCK(); - mro = lookup_tp_mro(type); + PyObject *mro = lookup_tp_mro(type); if (mro == NULL) { - mro = Py_None; - } else { - Py_INCREF(mro); + Py_RETURN_NONE; } - - END_TYPE_LOCK(); - return mro; + return Py_NewRef(mro); } static PyTypeObject *find_best_base(PyObject *); From 099943b122cda2548ad7e9cb4b327706929af7d0 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Mar 2026 22:51:00 +0000 Subject: [PATCH 377/498] Vary compiler flags in `fuzz_pycompile` (#145236) * Vary compiler flags in fuzz_pycompile * Drop `PyCF_SOURCE_IS_UTF8` --- Modules/_xxtestfuzz/fuzzer.c | 48 +++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 14da472c1bb110..f3a22f3f6a87cb 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -517,8 +517,8 @@ static int fuzz_pycompile(const char* data, size_t size) { return 0; } - // Need 2 bytes for parameter selection - if (size < 2) { + // Need 3 bytes for parameter selection + if (size < 3) { return 0; } @@ -530,25 +530,39 @@ static int fuzz_pycompile(const char* data, size_t size) { unsigned char optimize_idx = (unsigned char) data[1]; int optimize = optimize_vals[optimize_idx % NUM_OPTIMIZE_VALS]; + // Use third byte to determine compiler flags to use. + unsigned char flags_byte = (unsigned char) data[2]; + PyCompilerFlags flags = _PyCompilerFlags_INIT; + if (flags_byte & 0x01) { + flags.cf_flags |= PyCF_DONT_IMPLY_DEDENT; + } + if (flags_byte & 0x02) { + flags.cf_flags |= PyCF_ONLY_AST; + } + if (flags_byte & 0x04) { + flags.cf_flags |= PyCF_IGNORE_COOKIE; + } + if (flags_byte & 0x08) { + flags.cf_flags |= PyCF_TYPE_COMMENTS; + } + if (flags_byte & 0x10) { + flags.cf_flags |= PyCF_ALLOW_TOP_LEVEL_AWAIT; + } + if (flags_byte & 0x20) { + flags.cf_flags |= PyCF_ALLOW_INCOMPLETE_INPUT; + } + if (flags_byte & 0x40) { + flags.cf_flags |= PyCF_OPTIMIZED_AST; + } + char pycompile_scratch[MAX_PYCOMPILE_TEST_SIZE]; // Create a NUL-terminated C string from the remaining input - memcpy(pycompile_scratch, data + 2, size - 2); + memcpy(pycompile_scratch, data + 3, size - 3); // Put a NUL terminator just after the copied data. (Space was reserved already.) - pycompile_scratch[size - 2] = '\0'; - - // XXX: instead of always using NULL for the `flags` value to - // `Py_CompileStringExFlags`, there are many flags that conditionally - // change parser behavior: - // - // #define PyCF_TYPE_COMMENTS 0x1000 - // #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 - // #define PyCF_ONLY_AST 0x0400 - // - // It would be good to test various combinations of these, too. - PyCompilerFlags *flags = NULL; - - PyObject *result = Py_CompileStringExFlags(pycompile_scratch, "", start, flags, optimize); + pycompile_scratch[size - 3] = '\0'; + + PyObject *result = Py_CompileStringExFlags(pycompile_scratch, "", start, &flags, optimize); if (result == NULL) { /* Compilation failed, most likely from a syntax error. If it was a SystemError we abort. There's no non-bug reason to raise a From 66eafc9ea74e5233f2c46b424729d6dadfbb3111 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Tue, 10 Mar 2026 12:12:48 +0800 Subject: [PATCH 378/498] gh-144681: Fix JIT trace builder assertion failure when conditional branch jump target coincides with fallthrough target (GH-144742) --- Lib/test/test_capi/test_opt.py | 13 +++++++++++++ .../2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst | 1 + Python/optimizer.c | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 90e2ed20d1f6b3..8fa4f02afb5b45 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -461,6 +461,19 @@ def testfunc(n): uops = get_opnames(ex) self.assertIn(self.guard_is_false, uops) + def test_branch_coincident_targets(self): + # test for gh-144681: https://github.com/python/cpython/issues/144681 + def testfunc(n): + for _ in range(n): + r = [x for x in range(10) if [].append(x) or True] + return r + + res = testfunc(TIER2_THRESHOLD) + ex = get_first_executor(testfunc) + + self.assertEqual(res, list(range(10))) + self.assertIsNotNone(ex) + def test_for_iter_tier_two(self): class MyIter: def __init__(self, n): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst new file mode 100644 index 00000000000000..c8ca7a7fa194ee --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst @@ -0,0 +1 @@ +Fix a JIT assertion failure when a conditional branch jumps to the same target as the fallthrough path. diff --git a/Python/optimizer.c b/Python/optimizer.c index 4387bcb0d67832..7315bb6b9f603d 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -786,8 +786,8 @@ _PyJit_translate_single_bytecode_to_trace( _Py_CODEUNIT *computed_next_instr = computed_next_instr_without_modifiers + (computed_next_instr_without_modifiers->op.code == NOT_TAKEN); _Py_CODEUNIT *computed_jump_instr = computed_next_instr_without_modifiers + oparg; assert(next_instr == computed_next_instr || next_instr == computed_jump_instr); - int jump_happened = computed_jump_instr == next_instr; - assert(jump_happened == (target_instr[1].cache & 1)); + int jump_happened = target_instr[1].cache & 1; + assert(jump_happened ? (next_instr == computed_jump_instr) : (next_instr == computed_next_instr)); uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_happened]; ADD_TO_TRACE(uopcode, 0, 0, INSTR_IP(jump_happened ? computed_next_instr : computed_jump_instr, old_code)); break; From 170d85a37deb77a1711ab86288a33fda5c0a381a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:45:07 +0200 Subject: [PATCH 379/498] gh-145731: Fix negative timestamp during DST on Windows (GH-145728) --- ...-03-10-09-46-44.gh-issue-145731.5uEGgb.rst | 1 + Python/pytime.c | 24 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst diff --git a/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst b/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst new file mode 100644 index 00000000000000..676a68e5a912f5 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst @@ -0,0 +1 @@ +Fix negative timestamp during DST on Windows. Patch by Hugo van Kemenade. diff --git a/Python/pytime.c b/Python/pytime.c index 2b1488911ef97b..399ff59ad01ab6 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -320,23 +320,27 @@ _PyTime_windows_filetime(time_t timer, struct tm *tm, int is_local) ft.dwLowDateTime = (DWORD)(ticks); // cast to DWORD truncates to low 32 bits ft.dwHighDateTime = (DWORD)(ticks >> 32); - /* Convert FILETIME to SYSTEMTIME */ + /* Convert FILETIME to SYSTEMTIME (UTC) */ + SYSTEMTIME st_utc; + if (!FileTimeToSystemTime(&ft, &st_utc)) { + PyErr_SetFromWindowsErr(0); + return -1; + } + SYSTEMTIME st_result; if (is_local) { - /* Convert to local time */ - FILETIME ft_local; - if (!FileTimeToLocalFileTime(&ft, &ft_local) || - !FileTimeToSystemTime(&ft_local, &st_result)) { + /* Convert UTC SYSTEMTIME to local SYSTEMTIME. + * We use SystemTimeToTzSpecificLocalTime instead of + * FileTimeToLocalFileTime because the latter always applies the + * _current_ DST bias, whereas the former applies the correct + * DST rules for the date being converted (gh-80620). */ + if (!SystemTimeToTzSpecificLocalTime(NULL, &st_utc, &st_result)) { PyErr_SetFromWindowsErr(0); return -1; } } else { - /* Convert to UTC */ - if (!FileTimeToSystemTime(&ft, &st_result)) { - PyErr_SetFromWindowsErr(0); - return -1; - } + st_result = st_utc; } /* Convert SYSTEMTIME to struct tm */ From bdf0105291061f9c89b2a3d4af4f465c54c8874a Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 10 Mar 2026 08:56:00 +0000 Subject: [PATCH 380/498] gh-103997: Remove incorrect statements about `-c` dedenting (gh-138624) --- Doc/using/cmdline.rst | 2 +- Doc/whatsnew/3.14.rst | 3 +-- Include/internal/pycore_unicodeobject.h | 3 ++- Misc/NEWS.d/3.14.0b1.rst | 4 ++-- Objects/unicodeobject.c | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 84b8575284b793..cc3d2f154ed754 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -49,7 +49,7 @@ additional methods of invocation: appropriately named script from that directory. * When called with ``-c command``, it executes the Python statement(s) given as *command*. Here *command* may contain multiple statements separated by - newlines. Leading whitespace is significant in Python statements! + newlines. * When called with ``-m module-name``, the given module is located on the Python module path and executed as a script. diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index d4517183d697f1..772334f40a56fb 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -897,8 +897,7 @@ Command line and environment (Contributed by Noah Kim and Adam Turner in :gh:`118655`.) * The command-line option :option:`-c` now automatically dedents its code - argument before execution. The auto-dedentation behavior mirrors - :func:`textwrap.dedent`. + argument before execution. (Contributed by Jon Crall and Steven Sun in :gh:`103998`.) * :option:`!-J` is no longer a reserved flag for Jython_, diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index af6cb84e9ff905..74d84052a2bb2b 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -326,7 +326,8 @@ extern PyObject* _PyUnicode_XStrip( /* Dedent a string. - Behaviour is expected to be an exact match of `textwrap.dedent`. + Intended to dedent Python source. Unlike `textwrap.dedent`, this + only supports spaces and tabs and doesn't normalize empty lines. Return a new reference on success, NULL with exception set on error. */ extern PyObject* _PyUnicode_Dedent(PyObject *unicode); diff --git a/Misc/NEWS.d/3.14.0b1.rst b/Misc/NEWS.d/3.14.0b1.rst index 045c47ce5addc4..cb86c95a672ed7 100644 --- a/Misc/NEWS.d/3.14.0b1.rst +++ b/Misc/NEWS.d/3.14.0b1.rst @@ -1881,8 +1881,8 @@ Improve error message when :exc:`TypeError` occurs during .. nonce: BS3uVt .. section: Core and Builtins -String arguments passed to "-c" are now automatically dedented as if by -:func:`textwrap.dedent`. This allows "python -c" invocations to be indented +String arguments passed to "-c" are now automatically dedented. +This allows "python -c" invocations to be indented in shell scripts without causing indentation errors. (Patch by Jon Crall and Steven Sun) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7756f1a8482477..a65c43874e876c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13581,7 +13581,8 @@ search_longest_common_leading_whitespace( } /* Dedent a string. - Behaviour is expected to be an exact match of `textwrap.dedent`. + Intended to dedent Python source. Unlike `textwrap.dedent`, this + only supports spaces and tabs and doesn't normalize empty lines. Return a new reference on success, NULL with exception set on error. */ PyObject * From 19676e5fc28bdee8325a062a31ddeee60960cf75 Mon Sep 17 00:00:00 2001 From: Emma Smith Date: Tue, 10 Mar 2026 02:21:57 -0700 Subject: [PATCH 381/498] gh-145607: Ensure BIG_DATA has two compressed blocks in test_bz2 (#145730) --- Lib/test/test_bz2.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 3b7897b8a88a45..d8e3b671ec229f 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -66,18 +66,28 @@ class BaseTest(unittest.TestCase): EMPTY_DATA = b'BZh9\x17rE8P\x90\x00\x00\x00\x00' BAD_DATA = b'this is not a valid bzip2 file' - # Some tests need more than one block of uncompressed data. Since one block - # is at least 100,000 bytes, we gather some data dynamically and compress it. - # Note that this assumes that compression works correctly, so we cannot - # simply use the bigger test data for all tests. + # Some tests need more than one block of data. The bz2 module does not + # support flushing a block during compression, so we must read in data until + # there are at least 2 blocks. Since different orderings of Python files may + # be compressed differently, we need to check the compression output for + # more than one bzip2 block header magic, a hex encoding of Pi + # (0x314159265359) + bz2_block_magic = bytes.fromhex('314159265359') test_size = 0 - BIG_TEXT = bytearray(128*1024) + BIG_TEXT = b'' + BIG_DATA = b'' + compressor = BZ2Compressor(1) for fname in glob.glob(os.path.join(glob.escape(os.path.dirname(__file__)), '*.py')): with open(fname, 'rb') as fh: - test_size += fh.readinto(memoryview(BIG_TEXT)[test_size:]) - if test_size > 128*1024: + data = fh.read() + BIG_DATA += compressor.compress(data) + BIG_TEXT += data + # TODO(emmatyping): if it is impossible for a block header to cross + # multiple outputs, we can just search the output of each compress call + # which should be more efficient + if BIG_DATA.count(bz2_block_magic) > 1: + BIG_DATA += compressor.flush() break - BIG_DATA = bz2.compress(BIG_TEXT, compresslevel=1) def setUp(self): fd, self.filename = tempfile.mkstemp() From 3f7141dac90d06795293ca2d071198ab6b2318b2 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Tue, 10 Mar 2026 10:46:13 +0100 Subject: [PATCH 382/498] gh-145376: Fix refleaks and double decref for code in Python/ (#145666) --- Python/ceval.c | 1 + Python/crossinterp.c | 8 ++++---- Python/sysmodule.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 1e5142f4b456a1..950050a6027116 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2243,6 +2243,7 @@ _PyEval_ExceptionGroupMatch(_PyInterpreterFrame *frame, PyObject* exc_value, if (f != NULL) { PyObject *tb = _PyTraceBack_FromFrame(NULL, f); if (tb == NULL) { + Py_DECREF(wrapped); return -1; } PyException_SetTraceback(wrapped, tb); diff --git a/Python/crossinterp.c b/Python/crossinterp.c index c8a80e7a986008..f92927da475321 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -1103,12 +1103,12 @@ _convert_exc_to_TracebackException(PyObject *exc, PyObject **p_tbexc) } PyObject *tbexc = PyObject_Call(create, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(create); if (tbexc == NULL) { goto error; } + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(create); *p_tbexc = tbexc; return 0; @@ -1497,7 +1497,7 @@ _PyXI_excinfo_Apply(_PyXI_excinfo *info, PyObject *exctype) PyObject *formatted = _PyXI_excinfo_format(info); PyErr_SetObject(exctype, formatted); - Py_DECREF(formatted); + Py_XDECREF(formatted); if (tbexc != NULL) { PyObject *exc = PyErr_GetRaisedException(); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 55b4072213d3c2..893a116565e37e 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2499,7 +2499,7 @@ sys_remote_exec_impl(PyObject *module, int pid, PyObject *script) } if (PySys_Audit("sys.remote_exec", "iO", pid, script) < 0) { - return NULL; + goto error; } debugger_script_path = PyBytes_AS_STRING(path); From 478a315b7a22bd09b97431697d0832879631f7f1 Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Tue, 10 Mar 2026 15:44:20 +0500 Subject: [PATCH 383/498] GH-145247: Implement _PyTuple_FromPair() (#145325) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement _PyTuple_FromPair() and _PyTuple_FromPairSteal(). Co-authored-by: Pieter Eendebak Co-authored-by: Victor Stinner Co-authored-by: Bartosz Sławecki Co-authored-by: Kumar Aditya --- Include/internal/pycore_tuple.h | 3 ++ Lib/test/test_capi/test_tuple.py | 37 +++++++++++++++++++++ Modules/Setup.stdlib.in | 2 +- Modules/_testinternalcapi.c | 3 ++ Modules/_testinternalcapi/parts.h | 1 + Modules/_testinternalcapi/tuple.c | 39 +++++++++++++++++++++++ Objects/tupleobject.c | 29 +++++++++++++++++ PCbuild/_testinternalcapi.vcxproj | 1 + PCbuild/_testinternalcapi.vcxproj.filters | 3 ++ 9 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 Modules/_testinternalcapi/tuple.c diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index 00562bef769920..b3fa28f5bf21d5 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -27,6 +27,9 @@ PyAPI_FUNC(PyObject *)_PyTuple_FromStackRefStealOnSuccess(const union _PyStackRe PyAPI_FUNC(PyObject *)_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); PyAPI_FUNC(PyObject *) _PyTuple_BinarySlice(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyTuple_FromPair(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyTuple_FromPairSteal(PyObject *, PyObject *); + typedef struct { PyObject_HEAD Py_ssize_t it_index; diff --git a/Lib/test/test_capi/test_tuple.py b/Lib/test/test_capi/test_tuple.py index d6669d7802c5b8..0c27e81168ff77 100644 --- a/Lib/test/test_capi/test_tuple.py +++ b/Lib/test/test_capi/test_tuple.py @@ -1,9 +1,11 @@ import unittest import gc +from sys import getrefcount from test.support import import_helper _testcapi = import_helper.import_module('_testcapi') _testlimitedcapi = import_helper.import_module('_testlimitedcapi') +_testinternalcapi = import_helper.import_module('_testinternalcapi') NULL = None PY_SSIZE_T_MIN = _testcapi.PY_SSIZE_T_MIN @@ -118,6 +120,41 @@ def test_tuple_pack(self): # CRASHES pack(1, NULL) # CRASHES pack(2, [1]) + def check_tuple_from_pair(self, from_pair): + self.assertEqual(type(from_pair(1, 2)), tuple) + self.assertEqual(from_pair(1, 145325), (1, 145325)) + self.assertEqual(from_pair(None, None), (None, None)) + self.assertEqual(from_pair(True, False), (True, False)) + + # user class supports gc + class Temp: + pass + temp = Temp() + temp_rc = getrefcount(temp) + self.assertEqual(from_pair(temp, temp), (temp, temp)) + self.assertEqual(getrefcount(temp), temp_rc) + + self._not_tracked(from_pair(1, 2)) + self._not_tracked(from_pair(None, None)) + self._not_tracked(from_pair(True, False)) + self._tracked(from_pair(temp, (1, 2))) + self._tracked(from_pair(temp, 1)) + self._tracked(from_pair([], {})) + + self.assertRaises(TypeError, from_pair, 1, 2, 3) + self.assertRaises(TypeError, from_pair, 1) + self.assertRaises(TypeError, from_pair) + + def test_tuple_from_pair(self): + # Test _PyTuple_FromPair() + from_pair = _testinternalcapi.tuple_from_pair + self.check_tuple_from_pair(from_pair) + + def test_tuple_from_pair_steal(self): + # Test _PyTuple_FromPairSteal() + from_pair = _testinternalcapi.tuple_from_pair_steal + self.check_tuple_from_pair(from_pair) + def test_tuple_size(self): # Test PyTuple_Size() size = _testlimitedcapi.tuple_size diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 39be41d9d2a426..0d520684c795d6 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -174,7 +174,7 @@ @MODULE_XXSUBTYPE_TRUE@xxsubtype xxsubtype.c @MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c -@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c _testinternalcapi/complex.c _testinternalcapi/interpreter.c +@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c _testinternalcapi/complex.c _testinternalcapi/interpreter.c _testinternalcapi/tuple.c @MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c _testcapi/bytes.c _testcapi/object.c _testcapi/modsupport.c _testcapi/monitoring.c _testcapi/config.c _testcapi/import.c _testcapi/frame.c _testcapi/type.c _testcapi/function.c _testcapi/module.c @MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/import.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/threadstate.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c _testlimitedcapi/version.c _testlimitedcapi/file.c @MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index b6ed0b8902354e..aa5911ef2fb449 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -2987,6 +2987,9 @@ module_exec(PyObject *module) if (_PyTestInternalCapi_Init_CriticalSection(module) < 0) { return 1; } + if (_PyTestInternalCapi_Init_Tuple(module) < 0) { + return 1; + } Py_ssize_t sizeof_gc_head = 0; #ifndef Py_GIL_DISABLED diff --git a/Modules/_testinternalcapi/parts.h b/Modules/_testinternalcapi/parts.h index 03557d5bf5957f..81f536c3babb18 100644 --- a/Modules/_testinternalcapi/parts.h +++ b/Modules/_testinternalcapi/parts.h @@ -15,5 +15,6 @@ int _PyTestInternalCapi_Init_PyTime(PyObject *module); int _PyTestInternalCapi_Init_Set(PyObject *module); int _PyTestInternalCapi_Init_Complex(PyObject *module); int _PyTestInternalCapi_Init_CriticalSection(PyObject *module); +int _PyTestInternalCapi_Init_Tuple(PyObject *module); #endif // Py_TESTINTERNALCAPI_PARTS_H diff --git a/Modules/_testinternalcapi/tuple.c b/Modules/_testinternalcapi/tuple.c new file mode 100644 index 00000000000000..c12ee32deb9164 --- /dev/null +++ b/Modules/_testinternalcapi/tuple.c @@ -0,0 +1,39 @@ +#include "parts.h" + +#include "pycore_tuple.h" + + +static PyObject * +tuple_from_pair(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *first, *second; + if (!PyArg_ParseTuple(args, "OO", &first, &second)) { + return NULL; + } + + return _PyTuple_FromPair(first, second); +} + +static PyObject * +tuple_from_pair_steal(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *first, *second; + if (!PyArg_ParseTuple(args, "OO", &first, &second)) { + return NULL; + } + + return _PyTuple_FromPairSteal(Py_NewRef(first), Py_NewRef(second)); +} + + +static PyMethodDef test_methods[] = { + {"tuple_from_pair", tuple_from_pair, METH_VARARGS}, + {"tuple_from_pair_steal", tuple_from_pair_steal, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestInternalCapi_Init_Tuple(PyObject *m) +{ + return PyModule_AddFunctions(m, test_methods); +} diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 3c68955495d566..01afa53e15cd5d 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -202,6 +202,35 @@ PyTuple_Pack(Py_ssize_t n, ...) return (PyObject *)result; } +PyObject * +_PyTuple_FromPair(PyObject *first, PyObject *second) +{ + assert(first != NULL); + assert(second != NULL); + + return _PyTuple_FromPairSteal(Py_NewRef(first), Py_NewRef(second)); +} + +PyObject * +_PyTuple_FromPairSteal(PyObject *first, PyObject *second) +{ + assert(first != NULL); + assert(second != NULL); + + PyTupleObject *op = tuple_alloc(2); + if (op == NULL) { + Py_DECREF(first); + Py_DECREF(second); + return NULL; + } + PyObject **items = op->ob_item; + items[0] = first; + items[1] = second; + if (maybe_tracked(first) || maybe_tracked(second)) { + _PyObject_GC_TRACK(op); + } + return (PyObject *)op; +} /* Methods */ diff --git a/PCbuild/_testinternalcapi.vcxproj b/PCbuild/_testinternalcapi.vcxproj index 3818e6d3f7bbd2..f3e423fa04668e 100644 --- a/PCbuild/_testinternalcapi.vcxproj +++ b/PCbuild/_testinternalcapi.vcxproj @@ -100,6 +100,7 @@ + diff --git a/PCbuild/_testinternalcapi.vcxproj.filters b/PCbuild/_testinternalcapi.vcxproj.filters index 012d709bd1ce5d..7ab242c2c230b6 100644 --- a/PCbuild/_testinternalcapi.vcxproj.filters +++ b/PCbuild/_testinternalcapi.vcxproj.filters @@ -27,6 +27,9 @@ Source Files + + Source Files + From 55b36fdb3deebc5692a6d1379b0d904ced27e663 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:11:43 +0200 Subject: [PATCH 384/498] gh-133879: Copyedit "What's new in Python 3.15" (#145737) --- Doc/whatsnew/3.15.rst | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 42b6171c1a83a2..ead4e7cbf2871e 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -66,19 +66,22 @@ Summary -- Release highlights .. PEP-sized items next. * :pep:`810`: :ref:`Explicit lazy imports for faster startup times - ` + ` * :pep:`814`: :ref:`Add frozendict built-in type ` * :pep:`799`: :ref:`A dedicated profiling package for organizing Python profiling tools ` * :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler ` -* :pep:`798`: :ref:`Unpacking in Comprehensions +* :pep:`798`: :ref:`Unpacking in comprehensions ` * :pep:`686`: :ref:`Python now uses UTF-8 as the default encoding ` +* :pep:`728`: ``TypedDict`` with typed extra items +* :pep:`747`: :ref:`Annotating type forms with TypeForm + ` * :pep:`782`: :ref:`A new PyBytesWriter C API to create a Python bytes object - ` + ` * :ref:`The JIT compiler has been significantly upgraded ` * :ref:`Improved error messages ` @@ -86,7 +89,7 @@ Summary -- Release highlights New features ============ -.. _whatsnew315-pep810: +.. _whatsnew315-lazy-imports: :pep:`810`: Explicit lazy imports --------------------------------- @@ -120,12 +123,12 @@ name: .. code-block:: python lazy import json - lazy from datetime import datetime + lazy from pathlib import Path - print("Starting up...") # json and datetime not loaded yet + print("Starting up...") # json and pathlib not loaded yet - data = json.loads('{"key": "value"}') # json gets loads here - now = datetime() # datetime loads here + data = json.loads('{"key": "value"}') # json loads here + p = Path(".") # pathlib loads here This mechanism is particularly useful for applications that import many modules at the top level but may only use a subset of them in any given run. @@ -189,9 +192,9 @@ raise :exc:`SyntaxError`). ---------------------------------------- A new :term:`immutable` type, :class:`frozendict`, is added to the :mod:`builtins` module. -It does not allow modification after creation. A ``frozendict`` is not a subclass of ``dict``; -it inherits directly from ``object``. A ``frozendict`` is :term:`hashable` -as long as all of its keys and values are hashable. A ``frozendict`` preserves +It does not allow modification after creation. A :class:`!frozendict` is not a subclass of ``dict``; +it inherits directly from ``object``. A :class:`!frozendict` is :term:`hashable` +as long as all of its keys and values are hashable. A :class:`!frozendict` preserves insertion order, but comparison does not take order into account. For example:: @@ -1273,7 +1276,7 @@ csv .. _whatsnew315-jit: Upgraded JIT compiler -===================== +--------------------- Results from the `pyperformance `__ benchmark suite report @@ -1438,6 +1441,8 @@ threading typing ------ +.. _whatsnew315-typeform: + * :pep:`747`: Add :data:`~typing.TypeForm`, a new special form for annotating values that are themselves type expressions. ``TypeForm[T]`` means "a type form object describing ``T`` (or a type @@ -1636,7 +1641,7 @@ New features and :c:data:`Py_mod_abi`. (Contributed by Petr Viktorin in :gh:`137210`.) -.. _whatsnew315-pep782: +.. _whatsnew315-pybyteswriter: * Implement :pep:`782`, the :ref:`PyBytesWriter API `. Add functions: From 368a26777a9915326b4857402a8ab595d9837f95 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:38:48 +0200 Subject: [PATCH 385/498] gh-142927: Detect system theme in flame graph like in heatmap (#144885) --- .../sampling/_flamegraph_assets/flamegraph.js | 42 +------------- .../flamegraph_template.html | 2 +- .../sampling/_heatmap_assets/heatmap.js | 17 ------ .../_heatmap_assets/heatmap_shared.js | 27 --------- Lib/profiling/sampling/_shared_assets/base.js | 58 +++++++++++++++++++ Lib/profiling/sampling/heatmap_collector.py | 4 +- Lib/profiling/sampling/stack_collector.py | 4 +- 7 files changed, 68 insertions(+), 86 deletions(-) create mode 100644 Lib/profiling/sampling/_shared_assets/base.js diff --git a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js index 1a51802ffefac7..a2b21da2970064 100644 --- a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js +++ b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js @@ -83,18 +83,7 @@ function resolveStringIndices(node) { // ============================================================================ function toggleTheme() { - const html = document.documentElement; - const current = html.getAttribute('data-theme') || 'light'; - const next = current === 'light' ? 'dark' : 'light'; - html.setAttribute('data-theme', next); - localStorage.setItem('flamegraph-theme', next); - - // Update theme button icon - const btn = document.getElementById('theme-btn'); - if (btn) { - btn.querySelector('.icon-moon').style.display = next === 'dark' ? 'none' : ''; - btn.querySelector('.icon-sun').style.display = next === 'dark' ? '' : 'none'; - } + toggleAndSaveTheme(); // Re-render flamegraph with new theme colors if (window.flamegraphData && normalData) { @@ -154,17 +143,9 @@ function toggleSection(sectionId) { } } +// Restore theme from localStorage, or use browser preference function restoreUIState() { - // Restore theme - const savedTheme = localStorage.getItem('flamegraph-theme'); - if (savedTheme) { - document.documentElement.setAttribute('data-theme', savedTheme); - const btn = document.getElementById('theme-btn'); - if (btn) { - btn.querySelector('.icon-moon').style.display = savedTheme === 'dark' ? 'none' : ''; - btn.querySelector('.icon-sun').style.display = savedTheme === 'dark' ? '' : 'none'; - } - } + applyTheme(getPreferredTheme()); // Restore sidebar state const savedSidebar = localStorage.getItem('flamegraph-sidebar'); @@ -1242,23 +1223,6 @@ function generateInvertedFlamegraph(data) { return invertedRoot; } -function updateToggleUI(toggleId, isOn) { - const toggle = document.getElementById(toggleId); - if (toggle) { - const track = toggle.querySelector('.toggle-track'); - const labels = toggle.querySelectorAll('.toggle-label'); - if (isOn) { - track.classList.add('on'); - labels[0].classList.remove('active'); - labels[1].classList.add('active'); - } else { - track.classList.remove('on'); - labels[0].classList.add('active'); - labels[1].classList.remove('active'); - } - } -} - function toggleInvert() { isInverted = !isInverted; updateToggleUI('toggle-invert', isInverted); diff --git a/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html b/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html index 195a555d68e98b..07b15a5a2b48c7 100644 --- a/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html +++ b/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html @@ -1,5 +1,5 @@ - + diff --git a/Lib/profiling/sampling/_heatmap_assets/heatmap.js b/Lib/profiling/sampling/_heatmap_assets/heatmap.js index 53928b7b20fb11..2da1103b82a52a 100644 --- a/Lib/profiling/sampling/_heatmap_assets/heatmap.js +++ b/Lib/profiling/sampling/_heatmap_assets/heatmap.js @@ -203,23 +203,6 @@ function applyLineColors() { // Toggle Controls // ============================================================================ -function updateToggleUI(toggleId, isOn) { - const toggle = document.getElementById(toggleId); - if (toggle) { - const track = toggle.querySelector('.toggle-track'); - const labels = toggle.querySelectorAll('.toggle-label'); - if (isOn) { - track.classList.add('on'); - labels[0].classList.remove('active'); - labels[1].classList.add('active'); - } else { - track.classList.remove('on'); - labels[0].classList.add('active'); - labels[1].classList.remove('active'); - } - } -} - function toggleColdCode() { coldCodeHidden = !coldCodeHidden; applyHotFilter(); diff --git a/Lib/profiling/sampling/_heatmap_assets/heatmap_shared.js b/Lib/profiling/sampling/_heatmap_assets/heatmap_shared.js index 84b13ca0a9682b..fb761335876b0f 100644 --- a/Lib/profiling/sampling/_heatmap_assets/heatmap_shared.js +++ b/Lib/profiling/sampling/_heatmap_assets/heatmap_shared.js @@ -43,33 +43,6 @@ function intensityToColor(intensity) { // Theme Support // ============================================================================ -// Get the preferred theme from localStorage or browser preference -function getPreferredTheme() { - const saved = localStorage.getItem('heatmap-theme'); - if (saved) return saved; - return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; -} - -// Apply theme and update UI. Returns the applied theme. -function applyTheme(theme) { - document.documentElement.setAttribute('data-theme', theme); - const btn = document.getElementById('theme-btn'); - if (btn) { - btn.querySelector('.icon-moon').style.display = theme === 'dark' ? 'none' : ''; - btn.querySelector('.icon-sun').style.display = theme === 'dark' ? '' : 'none'; - } - return theme; -} - -// Toggle theme and save preference. Returns the new theme. -function toggleAndSaveTheme() { - const current = document.documentElement.getAttribute('data-theme') || 'light'; - const next = current === 'light' ? 'dark' : 'light'; - applyTheme(next); - localStorage.setItem('heatmap-theme', next); - return next; -} - // Restore theme from localStorage, or use browser preference function restoreUIState() { applyTheme(getPreferredTheme()); diff --git a/Lib/profiling/sampling/_shared_assets/base.js b/Lib/profiling/sampling/_shared_assets/base.js new file mode 100644 index 00000000000000..da8b5851c85f62 --- /dev/null +++ b/Lib/profiling/sampling/_shared_assets/base.js @@ -0,0 +1,58 @@ +// Tachyon Profiler - Shared JavaScript +// Common utilities shared between flamegraph and heatmap views + +// ============================================================================ +// Theme Support +// ============================================================================ + +// Storage key for theme preference +const THEME_STORAGE_KEY = 'tachyon-theme'; + +// Get the preferred theme from localStorage or system preference +function getPreferredTheme() { + const saved = localStorage.getItem(THEME_STORAGE_KEY); + if (saved) return saved; + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; +} + +// Apply theme and update UI +function applyTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + const btn = document.getElementById('theme-btn'); + if (btn) { + const moonIcon = btn.querySelector('.icon-moon'); + const sunIcon = btn.querySelector('.icon-sun'); + if (moonIcon) moonIcon.style.display = theme === 'dark' ? 'none' : ''; + if (sunIcon) sunIcon.style.display = theme === 'dark' ? '' : 'none'; + } +} + +// Toggle theme and save preference. Returns the new theme. +function toggleAndSaveTheme() { + const current = document.documentElement.getAttribute('data-theme') || 'light'; + const next = current === 'light' ? 'dark' : 'light'; + applyTheme(next); + localStorage.setItem(THEME_STORAGE_KEY, next); + return next; +} + +// ============================================================================ +// Toggle Switch UI +// ============================================================================ + +function updateToggleUI(toggleId, isOn) { + const toggle = document.getElementById(toggleId); + if (toggle) { + const track = toggle.querySelector('.toggle-track'); + const labels = toggle.querySelectorAll('.toggle-label'); + if (isOn) { + track.classList.add('on'); + labels[0].classList.remove('active'); + labels[1].classList.add('active'); + } else { + track.classList.remove('on'); + labels[0].classList.add('active'); + labels[1].classList.remove('active'); + } + } +} diff --git a/Lib/profiling/sampling/heatmap_collector.py b/Lib/profiling/sampling/heatmap_collector.py index b6d9ff79e8ceec..ea1beec70d39f8 100644 --- a/Lib/profiling/sampling/heatmap_collector.py +++ b/Lib/profiling/sampling/heatmap_collector.py @@ -204,7 +204,9 @@ def _load_templates(self): self.file_css = css_content # Load JS - shared_js = (assets_dir / "heatmap_shared.js").read_text(encoding="utf-8") + base_js = (template_dir / "_shared_assets" / "base.js").read_text(encoding="utf-8") + heatmap_shared_js = (assets_dir / "heatmap_shared.js").read_text(encoding="utf-8") + shared_js = f"{base_js}\n{heatmap_shared_js}" self.index_js = f"{shared_js}\n{(assets_dir / 'heatmap_index.js').read_text(encoding='utf-8')}" self.file_js = f"{shared_js}\n{(assets_dir / 'heatmap.js').read_text(encoding='utf-8')}" diff --git a/Lib/profiling/sampling/stack_collector.py b/Lib/profiling/sampling/stack_collector.py index 5a3497a5408414..931bc2c487b55b 100644 --- a/Lib/profiling/sampling/stack_collector.py +++ b/Lib/profiling/sampling/stack_collector.py @@ -377,7 +377,9 @@ def _create_flamegraph_html(self, data): html_template = (template_dir / "_flamegraph_assets" / "flamegraph_template.html").read_text(encoding="utf-8") css_content = get_combined_css("flamegraph") - js_content = (template_dir / "_flamegraph_assets" / "flamegraph.js").read_text(encoding="utf-8") + base_js = (template_dir / "_shared_assets" / "base.js").read_text(encoding="utf-8") + component_js = (template_dir / "_flamegraph_assets" / "flamegraph.js").read_text(encoding="utf-8") + js_content = f"{base_js}\n{component_js}" # Inline first-party CSS/JS html_template = html_template.replace( From 728e4a075e3dae7e04edf90ad137a35073deb141 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Tue, 10 Mar 2026 17:41:12 +0530 Subject: [PATCH 386/498] gh-142651: use `NonCallableMock._lock` for thread safety of `call_count` (#142922) --- Lib/unittest/mock.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 34fd49bf56fbb6..64a01a0b713c61 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1184,10 +1184,16 @@ def _increment_mock_call(self, /, *args, **kwargs): # handle call_args # needs to be set here so assertions on call arguments pass before # execution in the case of awaited calls - _call = _Call((args, kwargs), two=True) - self.call_args = _call - self.call_args_list.append(_call) - self.call_count = len(self.call_args_list) + with NonCallableMock._lock: + # Lock is used here so that call_args_list and call_count are + # set atomically otherwise it is possible that by the time call_count + # is set another thread may have appended to call_args_list. + # The rest of this function relies on list.append being atomic and + # skips locking. + _call = _Call((args, kwargs), two=True) + self.call_args = _call + self.call_args_list.append(_call) + self.call_count = len(self.call_args_list) # initial stuff for method_calls: do_method_calls = self._mock_parent is not None From 6024d3c6dadf73bcd0b234d2d97365486253f0ee Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:30:46 +0200 Subject: [PATCH 387/498] Python 3.15.0a7 --- Doc/c-api/arg.rst | 4 +- Doc/c-api/dict.rst | 2 +- Doc/c-api/exceptions.rst | 2 +- Doc/c-api/import.rst | 10 +- Doc/c-api/object.rst | 2 +- Doc/library/dataclasses.rst | 2 +- Doc/library/email.headerregistry.rst | 2 +- Doc/library/exceptions.rst | 2 +- Doc/library/functions.rst | 6 +- Doc/library/importlib.rst | 4 +- Doc/library/mailbox.rst | 2 +- Doc/library/marshal.rst | 2 +- Doc/library/os.rst | 6 +- Doc/library/re.rst | 6 +- Doc/library/shutil.rst | 2 +- Doc/library/stdtypes.rst | 4 +- Doc/library/sys.rst | 8 +- Doc/library/types.rst | 2 +- Doc/library/unicodedata.rst | 2 +- Doc/library/xml.etree.elementtree.rst | 4 +- Doc/reference/lexical_analysis.rst | 2 +- Doc/reference/simple_stmts.rst | 2 +- Doc/using/cmdline.rst | 8 +- Include/patchlevel.h | 4 +- Lib/pydoc_data/module_docs.py | 2 +- Lib/pydoc_data/topics.py | 410 +++--- Misc/NEWS.d/3.15.0a7.rst | 1212 +++++++++++++++++ ...-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst | 1 - ...-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst | 1 - ...-02-10-18-26-04.gh-issue-144679.FIH73W.rst | 2 - ...-02-22-13-35-20.gh-issue-145110.KgWofW.rst | 2 - ...-02-27-18-10-02.gh-issue-144533.21fk9L.rst | 1 - ...-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst | 3 - ...-02-10-14-49-49.gh-issue-121617.57vMqa.rst | 3 - ...-02-12-19-03-31.gh-issue-141510.U_1tjz.rst | 9 - ...-02-18-15-12-34.gh-issue-144981.4ZdM63.rst | 3 - ...-02-24-14-46-05.gh-issue-144748.uhnFtE.rst | 2 - ...-03-03-14-59-57.gh-issue-142417.HiNP5j.rst | 2 - ...3-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst | 2 - ...-02-19-21-06-30.gh-issue-130327.z3TaR8.rst | 2 - ...-09-15-13-28-48.gh-issue-138912.61EYbn.rst | 1 - ...-11-09-15-44-58.gh-issue-141226.KTb_3F.rst | 3 - ...-12-06-15-46-32.gh-issue-142349.IdTuYL.rst | 1 - ...2-06-21-45-52.gh-issue-144438.GI_uB1LR.rst | 2 - ...-02-08-13-14-00.gh-issue-144569.pjlJVe.rst | 1 - ...-02-11-11-28-25.gh-issue-144702.XjFumv.rst | 2 - ...-02-11-13-30-11.gh-issue-143300.yjB63-.rst | 1 - ...-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst | 1 - ...-02-12-19-01-13.gh-issue-141510.KlKjZg.rst | 1 - ...-02-13-12-00-00.gh-issue-144759.d3qYpe.rst | 4 - ...-02-13-18-30-59.gh-issue-144766.JGu3x3.rst | 1 - ...-02-16-12-28-43.gh-issue-144872.k9_Q30.rst | 1 - ...-02-17-18-27-28.gh-issue-144914.DcXO4m.rst | 1 - ...-02-17-21-04-03.gh-issue-100239.LyVabQ.rst | 2 - ...-02-17-22-27-11.gh-issue-141510.-4yYsf.rst | 2 - ...-02-18-21-44-39.gh-issue-141510.7LST2O.rst | 1 - ...-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst | 2 - ...-02-21-09-47-45.gh-issue-145058.e-RBw-.rst | 2 - ...-02-21-12-16-46.gh-issue-145055.VyT-zI.rst | 2 - ...-02-22-07-51-10.gh-issue-145064.iIMGKA.rst | 1 - ...-02-22-19-05-03.gh-issue-145118.bU6Sic.rst | 1 - ...20-15-00.gh-issue-144015.pystrhex_simd.rst | 5 - ...-02-22-22-05-09.gh-issue-145118.TaKMJE.rst | 1 - ...-02-23-23-18-28.gh-issue-145142.T-XbVe.rst | 2 - ...-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst | 2 - ...-02-25-15-02-08.gh-issue-145197.G6hAUk.rst | 1 - ...-02-26-12-00-00.gh-issue-130555.TMSOIu.rst | 3 - ...-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst | 3 - ...-02-26-20-51-54.gh-issue-145273.B5QcUp.rst | 2 - ...-02-26-21-07-38.gh-issue-145275.qE-3O1.rst | 3 - ...-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst | 5 - ...-02-28-16-46-17.gh-issue-145376.lG5u1a.rst | 1 - ...-03-01-13-37-31.gh-issue-145335.e36kPJ.rst | 2 - ...-03-05-16-16-17.gh-issue-143055.qDUFlY.rst | 2 - ...3-05-19-10-56.gh-issue-145566.H4RupyYN.rst | 2 - ...-03-06-01-36-20.gh-issue-116738.OWVWRx.rst | 2 - ...3-06-21-05-05.gh-issue-145615.NKXXZgDW.rst | 2 - ...-03-09-18-52-03.gh-issue-145701.79KQyO.rst | 3 - ...-08-02-18-59-01.gh-issue-136246.RIK7nE.rst | 3 - ...-01-06-16-04-08.gh-issue-110937.SyO5lk.rst | 1 - ...-03-03-08-18-00.gh-issue-145450.VI7GXj.rst | 1 - .../2017-12-15-09-32-57.bpo-32234.XaOkhR.rst | 2 - .../2018-05-11-12-26-16.bpo-3405.CacMw9.rst | 3 - .../2020-04-07-05-09-34.bpo-40212.oPYeBs.rst | 1 - .../2020-04-10-14-29-53.bpo-40243.85HRib.rst | 1 - .../2022-02-05-00-15-03.bpo-42353.0ebVGG.rst | 10 - ...3-02-05-20-02-30.gh-issue-80667.7LmzeA.rst | 1 - ...-09-30-15-31-59.gh-issue-124748.KYzYFp.rst | 2 - ...-06-24-19-07-18.gh-issue-135883.38cePA.rst | 2 - ...-08-04-23-20-43.gh-issue-137335.IIjDJN.rst | 2 - ...-10-10-14-08-58.gh-issue-139899.09leRY.rst | 3 - ...2-06-16-14-18.gh-issue-142352.pW5HLX88.rst | 4 - ...-12-16-13-34-48.gh-issue-142787.wNitJX.rst | 2 - ...-12-18-00-14-16.gh-issue-142781.gcOeYF.rst | 2 - ...-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst | 1 - ...6-01-10-22-58-30.gh-issue-85809.0eW4wt.rst | 1 - ...-01-11-13-03-32.gh-issue-142516.u7An-s.rst | 2 - ...-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst | 3 - ...-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst | 3 - ...-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst | 1 - ...-01-17-08-44-25.gh-issue-143637.qyPqDo.rst | 1 - ...-02-03-19-57-41.gh-issue-144316.wop870.rst | 1 - ...-02-07-16-31-42.gh-issue-144285.iyH9iL.rst | 3 - ...-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 3 - ...-02-08-17-09-10.gh-issue-144321.w58PhQ.rst | 3 - ...-02-09-02-16-36.gh-issue-144615.s04x4n.rst | 3 - ...6-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst | 3 - ...-02-10-22-05-51.gh-issue-144156.UbrC7F.rst | 1 - ...-02-12-17-56-17.gh-issue-117865.jE1ema.rst | 1 - ...3-00-00-00.gh-issue-142224.BidiMissing.rst | 2 - ...-02-13-11-14-18.gh-issue-144763.cDwnEE.rst | 2 - ...-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst | 1 - ...-02-14-14-56-44.gh-issue-140715.AbSheM.rst | 1 - ...-02-15-00-00-00.gh-issue-144833.TUelo1.rst | 3 - ...-02-15-12-02-20.gh-issue-144835.w_oS_J.rst | 2 - ...-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst | 2 - ...-02-17-11-28-37.gh-issue-141510.OpAz0M.rst | 2 - ...-02-18-00-00-00.gh-issue-144809.nYpEUx.rst | 1 - ...-02-18-13-45-00.gh-issue-144777.R97q0a.rst | 1 - ...9-00-00-00.gh-issue-144986.atexit-leak.rst | 2 - ...6-02-19-10-57-40.gh-issue-88091.N7qGV-.rst | 1 - ...-02-19-15-42-06.gh-issue-134872.sjYX1-.rst | 1 - ...-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst | 3 - ...-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst | 2 - ...-02-19-18-02-54.gh-issue-141510.qzvYsO.rst | 3 - ...-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst | 2 - ...6-02-20-13-03-10.gh-issue-66802.OYcAi_.rst | 3 - ...-02-21-17-34-53.gh-issue-123853.6RUwWh.rst | 1 - ...-02-23-20-52-55.gh-issue-145158.vWJtxI.rst | 2 - ...6-02-27-18-04-51.gh-issue-76007.17idfK.rst | 2 - ...-02-27-19-00-26.gh-issue-145301.2Wih4b.rst | 2 - ...-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst | 2 - ...-03-02-19-41-39.gh-issue-145376.OOzSOh.rst | 2 - ...-03-02-20-08-09.gh-issue-145335.lVTBvd.rst | 5 - ...-03-03-11-49-44.gh-issue-145417.m_HxIL.rst | 4 - ...-03-05-16-06-09.gh-issue-141510.dFPAQS.rst | 2 - ...-03-05-19-01-28.gh-issue-145551.gItPRl.rst | 1 - ...-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst | 3 - ...-01-31-21-56-54.gh-issue-144370.fp9m8t.rst | 2 - ...-03-04-18-59-17.gh-issue-145506.6hwvEh.rst | 2 - ...-02-12-12-12-00.gh-issue-144739.-fx1tN.rst | 3 - ...-03-04-17-39-15.gh-issue-144741.0RHhBF.rst | 3 - ...-02-13-11-07-51.gh-issue-144551.ENtMYD.rst | 1 - ...-02-27-10-57-20.gh-issue-145307.ueoT7j.rst | 2 - ...-03-10-09-46-44.gh-issue-145731.5uEGgb.rst | 1 - README.rst | 2 +- 146 files changed, 1513 insertions(+), 454 deletions(-) create mode 100644 Misc/NEWS.d/3.15.0a7.rst delete mode 100644 Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst delete mode 100644 Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst delete mode 100644 Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst delete mode 100644 Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst delete mode 100644 Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst delete mode 100644 Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst delete mode 100644 Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst delete mode 100644 Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst delete mode 100644 Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst delete mode 100644 Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst delete mode 100644 Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst delete mode 100644 Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst delete mode 100644 Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst delete mode 100644 Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst delete mode 100644 Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst delete mode 100644 Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index 4a3a6347239c4f..58456a36b96c15 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -524,7 +524,7 @@ API Functions Returns true on success; on failure, it returns false and raises the appropriate exception. - .. versionadded:: next + .. versionadded:: 3.15 .. c:function:: int PyArg_ParseArrayAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, const char *format, const char * const *kwlist, ...) @@ -535,7 +535,7 @@ API Functions Returns true on success; on failure, it returns false and raises the appropriate exception. - .. versionadded:: next + .. versionadded:: 3.15 .. c:function:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 371761573e97de..d63c26865899cc 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -495,7 +495,7 @@ Dictionary view objects Frozen dictionary objects ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: next +.. versionadded:: 3.15 .. c:var:: PyTypeObject PyFrozenDict_Type diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index aef191d3a29ac6..8ecd7c62517104 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -716,7 +716,7 @@ Signal Handling This function may now execute a remote debugger script, if remote debugging is enabled. - .. versionchanged:: next + .. versionchanged:: 3.15 The exception set by :c:func:`PyThreadState_SetAsyncExc` is now raised. diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 04b5adb9a8f43d..367490732b994f 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -350,14 +350,14 @@ Importing Modules Gets the current lazy imports mode. - .. versionadded:: next + .. versionadded:: 3.15 .. c:function:: PyObject* PyImport_GetLazyImportsFilter() Return a :term:`strong reference` to the current lazy imports filter, or ``NULL`` if none exists. This function always succeeds. - .. versionadded:: next + .. versionadded:: 3.15 .. c:function:: int PyImport_SetLazyImportsMode(PyImport_LazyImportsMode mode) @@ -366,7 +366,7 @@ Importing Modules This function always returns ``0``. - .. versionadded:: next + .. versionadded:: 3.15 .. c:function:: int PyImport_SetLazyImportsFilter(PyObject *filter) @@ -377,7 +377,7 @@ Importing Modules Return ``0`` on success and ``-1`` with an exception set otherwise. - .. versionadded:: next + .. versionadded:: 3.15 .. c:type:: PyImport_LazyImportsMode @@ -396,7 +396,7 @@ Importing Modules Disable lazy imports entirely. Even explicit ``lazy`` statements become eager imports. - .. versionadded:: next + .. versionadded:: 3.15 .. c:function:: PyObject* PyImport_CreateModuleFromInitfunc(PyObject *spec, PyObject* (*initfunc)(void)) diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index f71bfebdb2a19a..15a4b55eab82f0 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -817,4 +817,4 @@ Object Protocol Returns 1 if the object was made immortal and returns 0 if it was not. This function cannot fail. - .. versionadded:: next + .. versionadded:: 3.15 diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 447f05e67d8418..fd8e0c0bea1cb1 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -330,7 +330,7 @@ Module contents :attr:`!C.t` will be ``20``, and the class attributes :attr:`!C.x` and :attr:`!C.y` will not be set. - .. versionchanged:: next + .. versionchanged:: 3.15 If *metadata* is ``None``, use an empty :class:`frozendict`, instead of a :func:`~types.MappingProxyType` of an empty :class:`dict`. diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index 8dfcd492f0a763..c6924a0ac29c97 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -266,7 +266,7 @@ variant, :attr:`~.BaseHeader.max_count` is set to 1. A dictionary mapping parameter names to parameter values. - .. versionchanged:: next + .. versionchanged:: 3.15 It is now a :class:`frozendict` instead of a :class:`types.MappingProxyType`. diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 33f37bdf1fc1cd..3db3c7a13503f4 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -271,7 +271,7 @@ The following exceptions are the exceptions that are usually raised. A subclass of :exc:`ImportError` which is raised when a lazy import fails because it (directly or indirectly) tries to import itself. - .. versionadded:: next + .. versionadded:: 3.15 .. exception:: IndexError diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index af53b57dc9d2a7..1d83cb6f2bb688 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -660,7 +660,7 @@ are always available. They are listed here in alphabetical order. The semantics of the default *locals* namespace have been adjusted as described for the :func:`locals` builtin. - .. versionchanged:: next + .. versionchanged:: 3.15 *globals* can now be a :class:`frozendict`. @@ -741,7 +741,7 @@ are always available. They are listed here in alphabetical order. The semantics of the default *locals* namespace have been adjusted as described for the :func:`locals` builtin. - .. versionchanged:: next + .. versionchanged:: 3.15 *globals* can now be a :class:`frozendict`. @@ -2099,7 +2099,7 @@ are always available. They are listed here in alphabetical order. Subclasses of :class:`!type` which don't override ``type.__new__`` may no longer use the one-argument form to get the type of an object. - .. versionchanged:: next + .. versionchanged:: 3.15 *dict* can now be a :class:`frozendict`. diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index d5036a0fe7510b..785f6c614b4391 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -292,7 +292,7 @@ ABC hierarchy:: instead of a :class:`list` or other :class:`collection ` type. - .. versionadded:: next + .. versionadded:: 3.15 .. class:: PathEntryFinder @@ -346,7 +346,7 @@ ABC hierarchy:: instead of a :class:`list` or other :class:`collection ` type. - .. versionadded:: next + .. versionadded:: 3.15 .. class:: Loader diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index b9a55a03dc8ae7..5b9741bdbcad19 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -80,7 +80,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. returns the mailbox object as the context object, and at context end calls :meth:`close`, thereby releasing the lock. - .. versionchanged:: next + .. versionchanged:: 3.15 Support for the :keyword:`with` statement was added. :class:`!Mailbox` instances have the following methods: diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index 25902622b8730b..4fe34f0a3a3f91 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -72,7 +72,7 @@ this module. The following types are supported: Added format version 5, which allows marshalling slices. -.. versionchanged:: next +.. versionchanged:: 3.15 Added format version 6, which allows marshalling :class:`frozendict`. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index a22afdec516bb4..940d04ccc925cd 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2409,7 +2409,7 @@ features: .. versionchanged:: 3.6 Accepts a :term:`path-like object`. - .. versionchanged:: next + .. versionchanged:: 3.15 ``os.listdir(-1)`` now fails with ``OSError(errno.EBADF)`` rather than listing the current directory. @@ -2943,7 +2943,7 @@ features: .. versionchanged:: 3.7 Added support for :ref:`file descriptors ` on Unix. - .. versionchanged:: next + .. versionchanged:: 3.15 ``os.scandir(-1)`` now fails with ``OSError(errno.EBADF)`` rather than listing the current directory. @@ -4582,7 +4582,7 @@ These functions are all available on Linux only. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. - .. versionchanged:: next + .. versionchanged:: 3.15 ``os.listxattr(-1)`` now fails with ``OSError(errno.EBADF)`` rather than listing extended attributes of the current directory. diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 7edb85ca507722..43fb7295876fe1 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -954,7 +954,7 @@ Functions :func:`~re.match`. Use that name when you need to retain compatibility with older Python versions. - .. versionchanged:: next + .. versionchanged:: 3.15 The alternate :func:`~re.prefixmatch` name of this API was added as a more explicitly descriptive name than :func:`~re.match`. Use it to better express intent. The norm in other languages and regular expression @@ -1309,7 +1309,7 @@ Regular Expression Objects :meth:`~Pattern.match`. Use that name when you need to retain compatibility with older Python versions. - .. versionchanged:: next + .. versionchanged:: 3.15 The alternate :meth:`~Pattern.prefixmatch` name of this API was added as a more explicitly descriptive name than :meth:`~Pattern.match`. Use it to better express intent. The norm in other languages and regular expression @@ -1781,7 +1781,7 @@ We **do not** plan to deprecate and remove the older *match* name, as it has been used in code for over 30 years. Code supporting older versions of Python should continue to use *match*. -.. versionadded:: next +.. versionadded:: 3.15 Making a Phonebook ^^^^^^^^^^^^^^^^^^ diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 0666fcfde61e61..d289ba58c24065 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -669,7 +669,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. This function is now made thread-safe during creation of standard ``.zip`` and tar archives. - .. versionchanged:: next + .. versionchanged:: 3.15 Accepts a :term:`path-like object` for *base_name*, *root_dir* and *base_dir*. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index c930b876b3ccbf..e16954b12a6c2b 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2385,7 +2385,7 @@ expression support in the :mod:`re` module). the same position in *to*. If there is a third argument, it must be a string, whose characters will be mapped to ``None`` in the result. - .. versionchanged:: next + .. versionchanged:: 3.15 *dict* can now be a :class:`frozendict`. @@ -5665,7 +5665,7 @@ Frozen dictionaries :class:`!frozendict` is not a :class:`!dict` subclass but inherits directly from ``object``. - .. versionadded:: next + .. versionadded:: 3.15 .. _typecontextmanager: diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 4c76feafc9b492..b1461b0cbaf528 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -924,7 +924,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only See also :func:`set_lazy_imports` and :pep:`810`. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: get_lazy_imports_filter() @@ -937,7 +937,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only :func:`set_lazy_imports_filter` for details on the filter function signature. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: getrefcount(object) @@ -1770,7 +1770,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only See also :func:`get_lazy_imports` and :pep:`810`. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: set_lazy_imports_filter(filter) @@ -1800,7 +1800,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only See also :func:`get_lazy_imports_filter` and :pep:`810`. - .. versionadded:: next + .. versionadded:: 3.15 .. function:: setprofile(profilefunc) diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 01f4df3c89091f..74898baa521bd6 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -350,7 +350,7 @@ Standard names are defined for the following types: actually accessed. This type can be used to detect lazy imports programmatically. - .. versionadded:: next + .. versionadded:: 3.15 .. seealso:: :pep:`810` diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index d5f0405efbecc6..f5c11fd849f58b 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -139,7 +139,7 @@ following functions: >>> unicodedata.block('S') 'Basic Latin' - .. versionadded:: next + .. versionadded:: 3.15 .. function:: mirrored(chr, /) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 45abf5b1e736b3..919d4c595bf793 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -702,7 +702,7 @@ Functions attributes. *extra* contains additional attributes, given as keyword arguments. Returns an element instance. - .. versionchanged:: next + .. versionchanged:: 3.15 *attrib* can now be a :class:`frozendict`. @@ -890,7 +890,7 @@ Element Objects an optional dictionary, containing element attributes. *extra* contains additional attributes, given as keyword arguments. - .. versionchanged:: next + .. versionchanged:: 3.15 *attrib* can now be a :class:`frozendict`. diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 5c931683db100a..ae541680c534d6 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -469,7 +469,7 @@ identifier names. .. versionchanged:: 3.12 ``type`` is now a soft keyword. -.. versionchanged:: next +.. versionchanged:: 3.15 ``lazy`` is now a soft keyword. .. index:: diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 9ada6f047843b4..9b84c2e9ac7017 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -918,7 +918,7 @@ used, not at the import statement itself. See :pep:`810` for the full specification of lazy imports. -.. versionadded:: next +.. versionadded:: 3.15 .. _future: diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index cc3d2f154ed754..5c3d44395c0039 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -692,7 +692,7 @@ Miscellaneous options If false (``0``) suppress these warnings. Set to true by default. See also :envvar:`PYTHON_PATHCONFIG_WARNINGS`. - .. versionadded:: next + .. versionadded:: 3.15 * :samp:`-X tlbc={0,1}` enables (1, the default) or disables (0) thread-local bytecode in builds configured with :option:`--disable-gil`. When disabled, @@ -707,7 +707,7 @@ Miscellaneous options (the default) respects the ``lazy`` keyword in source code. See also :envvar:`PYTHON_LAZY_IMPORTS`. - .. versionadded:: next + .. versionadded:: 3.15 It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -1367,7 +1367,7 @@ conflict. stderr. If false (``0``) suppress these warnings. Set to true by default. See also :option:`-X pathconfig_warnings<-X>`. - .. versionadded:: next + .. versionadded:: 3.15 .. envvar:: PYTHON_JIT @@ -1396,7 +1396,7 @@ conflict. See also the :option:`-X lazy_imports <-X>` command-line option. - .. versionadded:: next + .. versionadded:: 3.15 Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 50d5ac4a73c1d8..3cc12a2b2d3888 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -24,10 +24,10 @@ #define PY_MINOR_VERSION 15 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 6 +#define PY_RELEASE_SERIAL 7 /* Version as a string */ -#define PY_VERSION "3.15.0a6+" +#define PY_VERSION "3.15.0a7" /*--end constants--*/ diff --git a/Lib/pydoc_data/module_docs.py b/Lib/pydoc_data/module_docs.py index 76a2c18bdb2f0e..314bef547f3052 100644 --- a/Lib/pydoc_data/module_docs.py +++ b/Lib/pydoc_data/module_docs.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Wed Feb 11 14:22:57 2026 +# Autogenerated by Sphinx on Tue Mar 10 14:31:07 2026 # as part of the release process. module_docs = { diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index dc09c5fd47affe..7dd9cfe2ff5821 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Wed Feb 11 14:22:57 2026 +# Autogenerated by Sphinx on Tue Mar 10 14:31:07 2026 # as part of the release process. topics = { @@ -361,13 +361,12 @@ async def func(param1, param2): Is semantically equivalent to: - iter = (ITER) - iter = type(iter).__aiter__(iter) + iter = (ITER).__aiter__() running = True while running: try: - TARGET = await type(iter).__anext__(iter) + TARGET = await iter.__anext__() except StopAsyncIteration: running = False else: @@ -375,7 +374,8 @@ async def func(param1, param2): else: SUITE2 -See also "__aiter__()" and "__anext__()" for details. +except that implicit special method lookup is used for "__aiter__()" +and "__anext__()". It is a "SyntaxError" to use an "async for" statement outside the body of a coroutine function. @@ -397,9 +397,9 @@ async def func(param1, param2): is semantically equivalent to: manager = (EXPRESSION) - aenter = type(manager).__aenter__ - aexit = type(manager).__aexit__ - value = await aenter(manager) + aenter = manager.__aenter__ + aexit = manager.__aexit__ + value = await aenter() hit_except = False try: @@ -407,13 +407,14 @@ async def func(param1, param2): SUITE except: hit_except = True - if not await aexit(manager, *sys.exc_info()): + if not await aexit(*sys.exc_info()): raise finally: if not hit_except: - await aexit(manager, None, None, None) + await aexit(None, None, None) -See also "__aenter__()" and "__aexit__()" for details. +except that implicit special method lookup is used for "__aenter__()" +and "__aexit__()". It is a "SyntaxError" to use an "async with" statement outside the body of a coroutine function. @@ -481,16 +482,34 @@ async def func(param1, param2): 'atom-literals': r'''Literals ******** -Python supports string and bytes literals and various numeric -literals: +A *literal* is a textual representation of a value. Python supports +numeric, string and bytes literals. Format strings and template +strings are treated as string literals. + +Numeric literals consist of a single "NUMBER" token, which names an +integer, floating-point number, or an imaginary number. See the +Numeric literals section in Lexical analysis documentation for +details. + +String and bytes literals may consist of several tokens. See section +String literal concatenation for details. + +Note that negative and complex numbers, like "-3" or "3+4.2j", are +syntactically not literals, but unary or binary arithmetic operations +involving the "-" or "+" operator. + +Evaluation of a literal yields an object of the given type ("int", +"float", "complex", "str", "bytes", or "Template") with the given +value. The value may be approximated in the case of floating-point and +imaginary literals. + +The formal grammar for literals is: literal: strings | NUMBER -Evaluation of a literal yields an object of the given type (string, -bytes, integer, floating-point number, complex number) with the given -value. The value may be approximated in the case of floating-point -and imaginary (complex) literals. See section Literals for details. -See section String literal concatenation for details on "strings". + +Literals and object identity +============================ All literals correspond to immutable data types, and hence the object’s identity is less important than its value. Multiple @@ -498,21 +517,53 @@ async def func(param1, param2): occurrence in the program text or a different occurrence) may obtain the same object or a different object with the same value. +CPython implementation detail: For example, in CPython, *small* +integers with the same value evaluate to the same object: + + >>> x = 7 + >>> y = 7 + >>> x is y + True + +However, large integers evaluate to different objects: + + >>> x = 123456789 + >>> y = 123456789 + >>> x is y + False + +This behavior may change in future versions of CPython. In particular, +the boundary between “small” and “large” integers has already changed +in the past.CPython will emit a "SyntaxWarning" when you compare +literals using "is": + + >>> x = 7 + >>> x is 7 + :1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="? + True + +See When can I rely on identity tests with the is operator? for more +information. + +Template strings are immutable but may reference mutable objects as +"Interpolation" values. For the purposes of this section, two +t-strings have the “same value” if both their structure and the +*identity* of the values match. + +**CPython implementation detail:** Currently, each evaluation of a +template string results in a different object. + String literal concatenation ============================ -Multiple adjacent string or bytes literals (delimited by whitespace), -possibly using different quoting conventions, are allowed, and their -meaning is the same as their concatenation: +Multiple adjacent string or bytes literals, possibly using different +quoting conventions, are allowed, and their meaning is the same as +their concatenation: >>> "hello" 'world' "helloworld" -Formally: - - strings: ( STRING | fstring)+ | tstring+ - This feature is defined at the syntactical level, so it only works with literals. To concatenate string expressions at run time, the ‘+’ operator may be used: @@ -543,6 +594,10 @@ async def func(param1, param2): >>> t"Hello" t"{name}!" Template(strings=('Hello', '!'), interpolations=(...)) + +Formally: + + strings: (STRING | fstring)+ | tstring+ ''', 'attribute-access': r'''Customizing attribute access **************************** @@ -1007,7 +1062,7 @@ class and instance attributes applies as for regular assignments. The "%" (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first -converted to a common type. A zero right argument raises the +converted to a common type. A zero right argument raises the "ZeroDivisionError" exception. The arguments may be floating-point numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 + 0.34".) The modulo operator always yields a result with the same sign @@ -2229,9 +2284,9 @@ def foo(): is semantically equivalent to: manager = (EXPRESSION) - enter = type(manager).__enter__ - exit = type(manager).__exit__ - value = enter(manager) + enter = manager.__enter__ + exit = manager.__exit__ + value = enter() hit_except = False try: @@ -2239,11 +2294,14 @@ def foo(): SUITE except: hit_except = True - if not exit(manager, *sys.exc_info()): + if not exit(*sys.exc_info()): raise finally: if not hit_except: - exit(manager, None, None, None) + exit(None, None, None) + +except that implicit special method lookup is used for "__enter__()" +and "__exit__()". With more than one item, the context managers are processed as if multiple "with" statements were nested: @@ -3287,13 +3345,12 @@ async def func(param1, param2): Is semantically equivalent to: - iter = (ITER) - iter = type(iter).__aiter__(iter) + iter = (ITER).__aiter__() running = True while running: try: - TARGET = await type(iter).__anext__(iter) + TARGET = await iter.__anext__() except StopAsyncIteration: running = False else: @@ -3301,7 +3358,8 @@ async def func(param1, param2): else: SUITE2 -See also "__aiter__()" and "__anext__()" for details. +except that implicit special method lookup is used for "__aiter__()" +and "__anext__()". It is a "SyntaxError" to use an "async for" statement outside the body of a coroutine function. @@ -3323,9 +3381,9 @@ async def func(param1, param2): is semantically equivalent to: manager = (EXPRESSION) - aenter = type(manager).__aenter__ - aexit = type(manager).__aexit__ - value = await aenter(manager) + aenter = manager.__aenter__ + aexit = manager.__aexit__ + value = await aenter() hit_except = False try: @@ -3333,13 +3391,14 @@ async def func(param1, param2): SUITE except: hit_except = True - if not await aexit(manager, *sys.exc_info()): + if not await aexit(*sys.exc_info()): raise finally: if not hit_except: - await aexit(manager, None, None, None) + await aexit(None, None, None) -See also "__aenter__()" and "__aexit__()" for details. +except that implicit special method lookup is used for "__aenter__()" +and "__aexit__()". It is a "SyntaxError" to use an "async with" statement outside the body of a coroutine function. @@ -3676,8 +3735,8 @@ def f() -> annotation: ... * a class that inherits from any of the above - The standard library classes "dict", "frozendict" - and "types.MappingProxyType" are mappings. + The standard library classes "dict" and "types.MappingProxyType" + are mappings. [4] A string literal appearing as the first statement in the function body is transformed into the function’s "__doc__" attribute and @@ -3750,19 +3809,13 @@ def f() -> annotation: ... When a description of an arithmetic operator below uses the phrase “the numeric arguments are converted to a common real type”, this -means that the operator implementation for built-in types works as -follows: - -* If both arguments are complex numbers, no conversion is performed; +means that the operator implementation for built-in numeric types +works as described in the Numeric Types section of the standard +library documentation. -* if either argument is a complex or a floating-point number, the - other is converted to a floating-point number; - -* otherwise, both must be integers and no conversion is necessary. - -Some additional rules apply for certain operators (e.g., a string as a -left argument to the ‘%’ operator). Extensions must define their own -conversion behavior. +Some additional rules apply for certain operators and non-numeric +operands (for example, a string as a left argument to the "%" +operator). Extensions must define their own conversion behavior. ''', 'customization': r'''Basic customization ******************* @@ -4056,7 +4109,7 @@ def __hash__(self): intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict insertion, *O*(*n*^2) complexity. See - http://ocert.org/advisories/ocert-2011-003.html for + https://ocert.org/advisories/ocert-2011-003.html for details.Changing hash values affects the iteration order of sets. Python has never made guarantees about this ordering (and it typically varies between 32-bit and 64-bit builds).See also @@ -4971,8 +5024,8 @@ def inner(x): CPython, the value was evaluated before the key. Starting with 3.8, the key is evaluated before the value, as proposed by **PEP 572**. -Changed in version 3.15.0a5 (unreleased): Unpacking with the "**" -operator is now allowed in dictionary comprehensions. +Changed in version 3.15: Unpacking with the "**" operator is now +allowed in dictionary comprehensions. ''', 'dynamic-features': r'''Interaction with dynamic features ********************************* @@ -6552,6 +6605,8 @@ def whats_on_the_telly(penguin=None): * "type", when used in the "type" statement. +* "lazy", when used before an "import" statement. + These syntactically act as keywords in their specific contexts, but this distinction is done at the parser level, not when tokenizing. @@ -6561,6 +6616,9 @@ def whats_on_the_telly(penguin=None): Changed in version 3.12: "type" is now a soft keyword. +Changed in version 3.15.0a6 (unreleased): "lazy" is now a soft +keyword. + Reserved classes of identifiers =============================== @@ -6770,10 +6828,10 @@ def whats_on_the_telly(penguin=None): 'import': r'''The "import" statement ********************** - import_stmt: "import" module ["as" identifier] ("," module ["as" identifier])* - | "from" relative_module "import" identifier ["as" identifier] + import_stmt: ["lazy"] "import" module ["as" identifier] ("," module ["as" identifier])* + | ["lazy"] "from" relative_module "import" identifier ["as" identifier] ("," identifier ["as" identifier])* - | "from" relative_module "import" "(" identifier ["as" identifier] + | ["lazy"] "from" relative_module "import" "(" identifier ["as" identifier] ("," identifier ["as" identifier])* [","] ")" | "from" relative_module "import" "*" module: (identifier ".")* identifier @@ -6885,6 +6943,48 @@ def whats_on_the_telly(penguin=None): "sys.path", "sys.meta_path", "sys.path_hooks". +Lazy imports +============ + +The "lazy" keyword is a soft keyword that only has special meaning +when it appears immediately before an "import" or "from" statement. +When an import statement is preceded by the "lazy" keyword, the import +becomes *lazy*: the module is not loaded immediately at the import +statement. Instead, a lazy proxy object is created and bound to the +name. The actual module is loaded on first use of that name. + +Lazy imports are only permitted at module scope. Using "lazy" inside a +function, class body, or "try"/"except"/"finally" block raises a +"SyntaxError". Star imports cannot be lazy ("lazy from module import +*" is a syntax error), and future statements cannot be lazy. + +When using "lazy from ... import", each imported name is bound to a +lazy proxy object. The first access to any of these names triggers +loading of the entire module and resolves only that specific name to +its actual value. Other names remain as lazy proxies until they are +accessed. + +Example: + + lazy import json + import sys + + print('json' in sys.modules) # False - json module not yet loaded + + # First use triggers loading + result = json.dumps({"hello": "world"}) + + print('json' in sys.modules) # True - now loaded + +If an error occurs during module loading (such as "ImportError" or +"SyntaxError"), it is raised at the point where the lazy import is +first used, not at the import statement itself. + +See **PEP 810** for the full specification of lazy imports. + +Added in version 3.15.0a6 (unreleased). + + Future statements ================= @@ -7975,8 +8075,8 @@ class C: pass # a class with no methods (yet) The power operator has the same semantics as the built-in "pow()" function, when called with two arguments: it yields its left argument -raised to the power of its right argument. The numeric arguments are -first converted to a common type, and the result is of that type. +raised to the power of its right argument. Numeric arguments are first +converted to a common type, and the result is of that type. For int operands, the result has the same type as the operands unless the second argument is negative; in that case, all arguments are @@ -8701,7 +8801,7 @@ def __hash__(self): intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict insertion, *O*(*n*^2) complexity. See - http://ocert.org/advisories/ocert-2011-003.html for + https://ocert.org/advisories/ocert-2011-003.html for details.Changing hash values affects the iteration order of sets. Python has never made guarantees about this ordering (and it typically varies between 32-bit and 64-bit builds).See also @@ -10312,16 +10412,14 @@ class is used in a class pattern with positional arguments, each "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()". For example: - .. doctest:: - - >>> 'abc123'.isalnum() - True - >>> 'abc123!@#'.isalnum() - False - >>> ''.isalnum() - False - >>> ' '.isalnum() - False + >>> 'abc123'.isalnum() + True + >>> 'abc123!@#'.isalnum() + False + >>> ''.isalnum() + False + >>> ' '.isalnum() + False str.isalpha() @@ -10575,6 +10673,9 @@ class is used in a class pattern with positional arguments, each a third argument, it must be a string, whose characters will be mapped to "None" in the result. + Changed in version 3.15.0a6 (unreleased): *dict* can now be a + "frozendict". + str.partition(sep, /) Split the string at the first occurrence of *sep*, and return a @@ -10676,6 +10777,17 @@ class is used in a class pattern with positional arguments, each space). The original string is returned if *width* is less than or equal to "len(s)". + For example: + + >>> 'Python'.rjust(10) + ' Python' + >>> 'Python'.rjust(10, '.') + '....Python' + >>> 'Monty Python'.rjust(10, '.') + 'Monty Python' + + See also "ljust()" and "zfill()". + str.rpartition(sep, /) Split the string at the last occurrence of *sep*, and return a @@ -10982,6 +11094,8 @@ class is used in a class pattern with positional arguments, each '00042' >>> "-42".zfill(5) '-0042' + + See also "rjust()". ''', 'strings': '''String and Bytes literals ************************* @@ -13338,13 +13452,13 @@ class instance has a namespace implemented as a dictionary which is See Function definitions for more information. ''', - 'typesmapping': r'''Mapping Types — "dict" -********************** + 'typesmapping': r'''Mapping types — "dict", "frozendict" +************************************ -A *mapping* object maps *hashable* values to arbitrary objects. -Mappings are mutable objects. There is currently only one standard -mapping type, the *dictionary*. (For other containers see the built- -in "list", "set", and "tuple" classes, and the "collections" module.) +A *mapping* object maps *hashable* values to arbitrary objects. There +are currently two standard mapping types, the *dictionary* and +"frozendict". (For other containers see the built-in "list", "set", +and "tuple" classes, and the "collections" module.) A dictionary’s keys are *almost* arbitrary values. Values that are not *hashable*, that is, values containing lists, dictionaries or @@ -13618,10 +13732,15 @@ class dict(iterable, /, **kwargs) Changed in version 3.8: Dictionaries are now reversible. + See also: + + "frozendict" and "types.MappingProxyType" can be used to create a + read-only view of a "dict". + See also: - "frozendict" and "types.MappingProxyType" can be used to create a read-only - view of a "dict". + For detailed information on thread-safety guarantees for "dict" + objects, see Thread safety for dict objects. Dictionary view objects @@ -13726,6 +13845,47 @@ class dict(iterable, /, **kwargs) mappingproxy({'bacon': 1, 'spam': 500}) >>> values.mapping['spam'] 500 + + +Frozen dictionaries +=================== + +class frozendict(**kwargs) +class frozendict(mapping, /, **kwargs) +class frozendict(iterable, /, **kwargs) + + Return a new frozen dictionary initialized from an optional + positional argument and a possibly empty set of keyword arguments. + + A "frozendict" has a similar API to the "dict" API, with the + following differences: + + * "dict" has more methods than "frozendict": + + * "__delitem__()" + + * "__setitem__()" + + * "clear()" + + * "pop()" + + * "popitem()" + + * "setdefault()" + + * "update()" + + * A "frozendict" can be hashed with "hash(frozendict)" if all keys + and values can be hashed. + + * "frozendict |= other" does not modify the "frozendict" in-place + but creates a new frozen dictionary. + + "frozendict" is not a "dict" subclass but inherits directly from + "object". + + Added in version 3.15.0a6 (unreleased). ''', 'typesmethods': r'''Methods ******* @@ -14175,75 +14335,10 @@ class list(iterable=(), /) empty for the duration, and raises "ValueError" if it can detect that the list has been mutated during a sort. -Thread safety: Reading a single element from a "list" is *atomic*: - - lst[i] # list.__getitem__ - -The following methods traverse the list and use *atomic* reads of each -item to perform their function. That means that they may return -results affected by concurrent modifications: - - item in lst - lst.index(item) - lst.count(item) - -All of the above methods/operations are also lock-free. They do not -block concurrent modifications. Other operations that hold a lock will -not block these from observing intermediate states.All other -operations from here on block using the per-object lock.Writing a -single item via "lst[i] = x" is safe to call from multiple threads and -will not corrupt the list.The following operations return new objects -and appear *atomic* to other threads: - - lst1 + lst2 # concatenates two lists into a new list - x * lst # repeats lst x times into a new list - lst.copy() # returns a shallow copy of the list - -Methods that only operate on a single elements with no shifting -required are *atomic*: - - lst.append(x) # append to the end of the list, no shifting required - lst.pop() # pop element from the end of the list, no shifting required - -The "clear()" method is also *atomic*. Other threads cannot observe -elements being removed.The "sort()" method is not *atomic*. Other -threads cannot observe intermediate states during sorting, but the -list appears empty for the duration of the sort.The following -operations may allow lock-free operations to observe intermediate -states since they modify multiple elements in place: - - lst.insert(idx, item) # shifts elements - lst.pop(idx) # idx not at the end of the list, shifts elements - lst *= x # copies elements in place - -The "remove()" method may allow concurrent modifications since element -comparison may execute arbitrary Python code (via -"__eq__()")."extend()" is safe to call from multiple threads. -However, its guarantees depend on the iterable passed to it. If it is -a "list", a "tuple", a "set", a "frozenset", a "dict" or a dictionary -view object (but not their subclasses), the "extend" operation is safe -from concurrent modifications to the iterable. Otherwise, an iterator -is created which can be concurrently modified by another thread. The -same applies to inplace concatenation of a list with other iterables -when using "lst += iterable".Similarly, assigning to a list slice with -"lst[i:j] = iterable" is safe to call from multiple threads, but -"iterable" is only locked when it is also a "list" (but not its -subclasses).Operations that involve multiple accesses, as well as -iteration, are never atomic. For example: - - # NOT atomic: read-modify-write - lst[i] = lst[i] + 1 - - # NOT atomic: check-then-act - if lst: - item = lst.pop() - - # NOT thread-safe: iteration while modifying - for item in lst: - process(item) # another thread may modify lst - -Consider external synchronization when sharing "list" instances across -threads. See Python support for free threading for more information. +See also: + + For detailed information on thread-safety guarantees for "list" + objects, see Thread safety for list objects. Tuples @@ -14615,9 +14710,9 @@ class range(start, stop, step=1, /) is semantically equivalent to: manager = (EXPRESSION) - enter = type(manager).__enter__ - exit = type(manager).__exit__ - value = enter(manager) + enter = manager.__enter__ + exit = manager.__exit__ + value = enter() hit_except = False try: @@ -14625,11 +14720,14 @@ class range(start, stop, step=1, /) SUITE except: hit_except = True - if not exit(manager, *sys.exc_info()): + if not exit(*sys.exc_info()): raise finally: if not hit_except: - exit(manager, None, None, None) + exit(None, None, None) + +except that implicit special method lookup is used for "__enter__()" +and "__exit__()". With more than one item, the context managers are processed as if multiple "with" statements were nested: diff --git a/Misc/NEWS.d/3.15.0a7.rst b/Misc/NEWS.d/3.15.0a7.rst new file mode 100644 index 00000000000000..7d9681cbcbef00 --- /dev/null +++ b/Misc/NEWS.d/3.15.0a7.rst @@ -0,0 +1,1212 @@ +.. date: 2026-03-10-09-46-44 +.. gh-issue: 145731 +.. nonce: 5uEGgb +.. release date: 2026-03-10 +.. section: Windows + +Fix negative timestamp during DST on Windows. Patch by Hugo van Kemenade. + +.. + +.. date: 2026-02-27-10-57-20 +.. gh-issue: 145307 +.. nonce: ueoT7j +.. section: Windows + +Defers loading of the ``psapi.dll`` module until it is used by +:func:`ctypes.util.dllist`. + +.. + +.. date: 2026-02-13-11-07-51 +.. gh-issue: 144551 +.. nonce: ENtMYD +.. section: Windows + +Updated bundled version of OpenSSL to 3.5.5. + +.. + +.. date: 2026-03-04-17-39-15 +.. gh-issue: 144741 +.. nonce: 0RHhBF +.. section: Tests + +Fix ``test_frame_pointer_unwind`` when Python is built with +:option:`--enable-shared`. Classify also libpython frames as ``"python"``. +Patch by Victor Stinner. + +.. + +.. date: 2026-02-12-12-12-00 +.. gh-issue: 144739 +.. nonce: -fx1tN +.. section: Tests + +When Python was compiled with system expat older then 2.7.2 but tests run +with newer expat, still skip +:class:`!test.test_pyexpat.MemoryProtectionTest`. + +.. + +.. date: 2026-03-04-18-59-17 +.. gh-issue: 145506 +.. nonce: 6hwvEh +.. section: Security + +Fixes :cve:`2026-2297` by ensuring that ``SourcelessFileLoader`` uses +:func:`io.open_code` when opening ``.pyc`` files. + +.. + +.. date: 2026-01-31-21-56-54 +.. gh-issue: 144370 +.. nonce: fp9m8t +.. section: Security + +Disallow usage of control characters in status in :mod:`wsgiref.handlers` to +prevent HTTP header injections. Patch by Benedikt Johannes. + +.. + +.. date: 2026-03-07-15-00-00 +.. gh-issue: 145623 +.. nonce: 2Y7LzT +.. section: Library + +Fix crash in :mod:`struct` when calling :func:`repr` or ``__sizeof__()`` on +an uninitialized :class:`struct.Struct` object created via +``Struct.__new__()`` without calling ``__init__()``. + +.. + +.. date: 2026-03-05-19-01-28 +.. gh-issue: 145551 +.. nonce: gItPRl +.. section: Library + +Fix InvalidStateError when cancelling process created by +:func:`asyncio.create_subprocess_exec` or +:func:`asyncio.create_subprocess_shell`. Patch by Daan De Meyer. + +.. + +.. date: 2026-03-05-16-06-09 +.. gh-issue: 141510 +.. nonce: dFPAQS +.. section: Library + +:mod:`marshal` now supports :class:`frozendict` objects. The marshal format +version was increased to 6. Patch by Victor Stinner. + +.. + +.. date: 2026-03-03-11-49-44 +.. gh-issue: 145417 +.. nonce: m_HxIL +.. section: Library + +:mod:`venv`: Prevent incorrect preservation of SELinux context when copying +the ``Activate.ps1`` script. The script inherited the SELinux security +context of the system template directory, rather than the destination +project directory. + +.. + +.. date: 2026-03-02-20-08-09 +.. gh-issue: 145335 +.. nonce: lVTBvd +.. section: Library + +``os.listdir(-1)`` and ``os.scandir(-1)`` now fail with +``OSError(errno.EBADF)`` rather than listing the current directory. +``os.listxattr(-1)`` now fails with ``OSError(errno.EBADF)`` rather than +listing extended attributes of the current directory. Patch by Victor +Stinner. + +.. + +.. date: 2026-03-02-19-41-39 +.. gh-issue: 145376 +.. nonce: OOzSOh +.. section: Library + +Fix double free and null pointer dereference in unusual error scenarios in +:mod:`hashlib` and :mod:`hmac` modules. + +.. + +.. date: 2026-02-28-00-55-00 +.. gh-issue: 145301 +.. nonce: Lk2bRl +.. section: Library + +:mod:`hmac`: fix a crash when the initialization of the underlying C +extension module fails. + +.. + +.. date: 2026-02-27-19-00-26 +.. gh-issue: 145301 +.. nonce: 2Wih4b +.. section: Library + +:mod:`hashlib`: fix a crash when the initialization of the underlying C +extension module fails. + +.. + +.. date: 2026-02-27-18-04-51 +.. gh-issue: 76007 +.. nonce: 17idfK +.. section: Library + +The ``version`` attribute of the :mod:`tarfile` module is deprecated and +slated for removal in Python 3.20. + +.. + +.. date: 2026-02-23-20-52-55 +.. gh-issue: 145158 +.. nonce: vWJtxI +.. section: Library + +Avoid undefined behaviour from signed integer overflow when parsing format +strings in the :mod:`struct` module. + +.. + +.. date: 2026-02-21-17-34-53 +.. gh-issue: 123853 +.. nonce: 6RUwWh +.. section: Library + +Removed Windows 95 compatibility for :func:`locale.getdefaultlocale`. + +.. + +.. date: 2026-02-20-13-03-10 +.. gh-issue: 66802 +.. nonce: OYcAi_ +.. section: Library + +Add :func:`unicodedata.block` function to return the `Unicode block +`_ +of a character. + +.. + +.. date: 2026-02-19-20-54-25 +.. gh-issue: 145033 +.. nonce: X9EBPQ +.. section: Library + +Add :data:`typing.TypeForm`, implementing :pep:`747`. Patch by Jelle +Zijlstra. + +.. + +.. date: 2026-02-19-18-02-54 +.. gh-issue: 141510 +.. nonce: qzvYsO +.. section: Library + +:func:`dataclasses.field`: if *metadata* is ``None``, use an empty +:class:`frozendict`, instead of a :func:`~types.MappingProxyType` of an +empty :class:`dict`. Patch by Victor Stinner. + +.. + +.. date: 2026-02-19-17-50-47 +.. gh-issue: 145006 +.. nonce: 9gqA0Q +.. section: Library + +Add :exc:`ModuleNotFoundError` hints when a module for a different ABI +exists. + +.. + +.. date: 2026-02-19-16-26-08 +.. gh-issue: 141510 +.. nonce: 4Qxy8_ +.. section: Library + +``ParameterizedMIMEHeader.params`` of :mod:`email.headerregistry` is now a +:class:`frozendict` instead of a :class:`types.MappingProxyType`. Patch by +Victor Stinner. + +.. + +.. date: 2026-02-19-15-42-06 +.. gh-issue: 134872 +.. nonce: sjYX1- +.. section: Library + +Add valid import name suggestions on :exc:`ModuleNotFoundError`. + +.. + +.. date: 2026-02-19-10-57-40 +.. gh-issue: 88091 +.. nonce: N7qGV- +.. section: Library + +Fix :func:`unicodedata.decomposition` for Hangul characters. + +.. + +.. date: 2026-02-19-00-00-00 +.. gh-issue: 144986 +.. nonce: atexit-leak +.. section: Library + +Fix a memory leak in :func:`atexit.register`. Patch by Shamil Abdulaev. + +.. + +.. date: 2026-02-18-13-45-00 +.. gh-issue: 144777 +.. nonce: R97q0a +.. section: Library + +Fix data races in :class:`io.IncrementalNewlineDecoder` in the +:term:`free-threaded build`. + +.. + +.. date: 2026-02-18-00-00-00 +.. gh-issue: 144809 +.. nonce: nYpEUx +.. section: Library + +Make :class:`collections.deque` copy atomic in the :term:`free-threaded +build`. + +.. + +.. date: 2026-02-17-11-28-37 +.. gh-issue: 141510 +.. nonce: OpAz0M +.. section: Library + +The :mod:`copy` module now supports the :class:`frozendict` type. Patch by +Pieter Eendebak based on work by Victor Stinner. + +.. + +.. date: 2026-02-17-11-15-17 +.. gh-issue: 141510 +.. nonce: ZmqEUb +.. section: Library + +The :mod:`json` module now supports the :class:`frozendict` type. Patch by +Victor Stinner. + +.. + +.. date: 2026-02-15-12-02-20 +.. gh-issue: 144835 +.. nonce: w_oS_J +.. section: Library + +Added missing explanations for some parameters in :func:`glob.glob` and +:func:`glob.iglob`. + +.. + +.. date: 2026-02-15-00-00-00 +.. gh-issue: 144833 +.. nonce: TUelo1 +.. section: Library + +Fixed a use-after-free in :mod:`ssl` when ``SSL_new()`` returns NULL in +``newPySSLSocket()``. The error was reported via a dangling pointer after +the object had already been freed. + +.. + +.. date: 2026-02-14-14-56-44 +.. gh-issue: 140715 +.. nonce: AbSheM +.. section: Library + +Add ``'%D'`` support to :meth:`~datetime.datetime.strptime`. + +.. + +.. date: 2026-02-13-14-20-10 +.. gh-issue: 144782 +.. nonce: 0Y8TKj +.. section: Library + +Fix :class:`argparse.ArgumentParser` to be :mod:`pickleable `. + +.. + +.. date: 2026-02-13-11-14-18 +.. gh-issue: 144763 +.. nonce: cDwnEE +.. section: Library + +Fix a race condition in :mod:`tracemalloc`: it no longer detaches the +attached thread state to acquire its internal lock. Patch by Victor Stinner. + +.. + +.. date: 2026-02-13-00-00-00 +.. gh-issue: 142224 +.. nonce: BidiMissing +.. section: Library + +:func:`unicodedata.bidirectional` now return the correct default bidi class +for unassigned code points. + +.. + +.. date: 2026-02-12-17-56-17 +.. gh-issue: 117865 +.. nonce: jE1ema +.. section: Library + +Reduce the import time of :mod:`inspect` module by ~20%. + +.. + +.. date: 2026-02-10-22-05-51 +.. gh-issue: 144156 +.. nonce: UbrC7F +.. section: Library + +Fix the folding of headers by the :mod:`email` library when :rfc:`2047` +encoded words are used. Now whitespace is correctly preserved and also +correctly added between adjacent encoded words. The latter property was +broken by the fix for gh-92081, which mostly fixed previous failures to +preserve whitespace. + +.. + +.. date: 2026-02-10-16-56-05 +.. gh-issue: 66305 +.. nonce: PZ6GN8 +.. section: Library + +Fixed a hang on Windows in the :mod:`tempfile` module when trying to create +a temporary file or subdirectory in a non-writable directory. + +.. + +.. date: 2026-02-09-02-16-36 +.. gh-issue: 144615 +.. nonce: s04x4n +.. section: Library + +Methods directly decorated with :deco:`functools.singledispatchmethod` now +dispatch on the second argument when called after being accessed as class +attributes. Patch by Bartosz Sławecki. + +.. + +.. date: 2026-02-08-17-09-10 +.. gh-issue: 144321 +.. nonce: w58PhQ +.. section: Library + +The functional syntax for creating :class:`typing.NamedTuple` classes now +supports passing any :term:`iterable` of fields and types. Previously, only +sequences were supported. + +.. + +.. date: 2026-02-07-16-37-42 +.. gh-issue: 144475 +.. nonce: 8tFEXw +.. section: Library + +Calling :func:`repr` on :func:`functools.partial` is now safer when the +partial object's internal attributes are replaced while the string +representation is being generated. + +.. + +.. date: 2026-02-07-16-31-42 +.. gh-issue: 144285 +.. nonce: iyH9iL +.. section: Library + +Attribute suggestions in :exc:`AttributeError` tracebacks are now formatted +differently to make them easier to understand, for example: ``Did you mean +'.datetime.now' instead of '.now'``. Contributed by Bartosz Sławecki. + +.. + +.. date: 2026-02-03-19-57-41 +.. gh-issue: 144316 +.. nonce: wop870 +.. section: Library + +Fix crash in ``_remote_debugging`` that caused ``test_external_inspection`` +to intermittently fail. Patch by Taegyun Kim. + +.. + +.. date: 2026-01-17-08-44-25 +.. gh-issue: 143637 +.. nonce: qyPqDo +.. section: Library + +Fixed a crash in socket.sendmsg() that could occur if ancillary data is +mutated re-entrantly during argument parsing. + +.. + +.. date: 2026-01-12-19-39-57 +.. gh-issue: 140652 +.. nonce: HvM9Bl +.. section: Library + +Fix a crash in :func:`!_interpchannels.list_all` after closing a channel. + +.. + +.. date: 2026-01-11-18-35-52 +.. gh-issue: 143698 +.. nonce: gXDzsJ +.. section: Library + +Allow *scheduler* and *setpgroup* arguments to be explicitly :const:`None` +when calling :func:`os.posix_spawn` or :func:`os.posix_spawnp`. Patch by +Bénédikt Tran. + +.. + +.. date: 2026-01-11-16-59-22 +.. gh-issue: 143698 +.. nonce: b-Cpeb +.. section: Library + +Raise :exc:`TypeError` instead of :exc:`SystemError` when the *scheduler* in +:func:`os.posix_spawn` or :func:`os.posix_spawnp` is not a tuple. Patch by +Bénédikt Tran. + +.. + +.. date: 2026-01-11-13-03-32 +.. gh-issue: 142516 +.. nonce: u7An-s +.. section: Library + +:mod:`ssl`: fix reference leaks in :class:`ssl.SSLContext` objects. Patch by +Bénédikt Tran. + +.. + +.. date: 2026-01-10-22-58-30 +.. gh-issue: 85809 +.. nonce: 0eW4wt +.. section: Library + +Added :term:`path-like object` support for :func:`shutil.make_archive`. + +.. + +.. date: 2026-01-01-05-26-00 +.. gh-issue: 143304 +.. nonce: Kv7x9Q +.. section: Library + +Fix :class:`ctypes.CDLL` to honor the ``handle`` parameter on POSIX systems. + +.. + +.. date: 2025-12-18-00-14-16 +.. gh-issue: 142781 +.. nonce: gcOeYF +.. section: Library + +:mod:`zoneinfo`: fix a crash when instantiating :class:`~zoneinfo.ZoneInfo` +objects for which the internal class-level cache is inconsistent. + +.. + +.. date: 2025-12-16-13-34-48 +.. gh-issue: 142787 +.. nonce: wNitJX +.. section: Library + +Fix assertion failure in :mod:`sqlite3` blob subscript when slicing with +indices that result in an empty slice. + +.. + +.. date: 2025-12-06-16-14-18 +.. gh-issue: 142352 +.. nonce: pW5HLX88 +.. section: Library + +Fix :meth:`asyncio.StreamWriter.start_tls` to transfer buffered data from +:class:`~asyncio.StreamReader` to the SSL layer, preventing data loss when +upgrading a connection to TLS mid-stream (e.g., when implementing PROXY +protocol support). + +.. + +.. date: 2025-10-10-14-08-58 +.. gh-issue: 139899 +.. nonce: 09leRY +.. section: Library + +Introduced :meth:`importlib.abc.MetaPathFinder.discover` and +:meth:`importlib.abc.PathEntryFinder.discover` to allow module and submodule +name discovery without assuming the use of traditional filesystem based +imports. + +.. + +.. date: 2025-08-04-23-20-43 +.. gh-issue: 137335 +.. nonce: IIjDJN +.. section: Library + +Get rid of any possibility of a name conflict for named pipes in +:mod:`multiprocessing` and :mod:`asyncio` on Windows, no matter how small. + +.. + +.. date: 2025-06-24-19-07-18 +.. gh-issue: 135883 +.. nonce: 38cePA +.. section: Library + +Fix :mod:`sqlite3`'s :ref:`interactive shell ` keeping part of +previous commands when scrolling history. + +.. + +.. date: 2024-09-30-15-31-59 +.. gh-issue: 124748 +.. nonce: KYzYFp +.. section: Library + +Improve :exc:`TypeError` error message when +:meth:`!weakref.WeakKeyDictionary.update` is used with keyword-only +parameters. + +.. + +.. date: 2023-02-05-20-02-30 +.. gh-issue: 80667 +.. nonce: 7LmzeA +.. section: Library + +Add support for Tangut Ideographs names in :mod:`unicodedata`. + +.. + +.. bpo: 42353 +.. date: 2022-02-05-00-15-03 +.. nonce: 0ebVGG +.. section: Library + +The :mod:`re` module gains a new :func:`re.prefixmatch` function as an +explicit spelling of what has to date always been known as :func:`re.match`. +:class:`re.Pattern` similary gains a :meth:`re.Pattern.prefixmatch` method. + +Why? Explicit is better than implicit. Other widely used languages all use +the term "match" to mean what Python uses the term "search" for. The +unadorened "match" name in Python has been a frequent case of confusion and +coding bugs due to the inconsistency with the rest if the software industry. + +We do not plan to deprecate and remove the older ``match`` name. + +.. + +.. bpo: 40243 +.. date: 2020-04-10-14-29-53 +.. nonce: 85HRib +.. section: Library + +Fix :meth:`!unicodedata.ucd_3_2_0.numeric` for non-decimal values. + +.. + +.. bpo: 40212 +.. date: 2020-04-07-05-09-34 +.. nonce: oPYeBs +.. section: Library + +Re-enable :func:`os.posix_fallocate` and :func:`os.posix_fadvise` on AIX. + +.. + +.. bpo: 3405 +.. date: 2018-05-11-12-26-16 +.. nonce: CacMw9 +.. section: Library + +Add support for user data of Tk virtual events and detail for ``Enter``, +``Leave``, ``FocusIn``, ``FocusOut``, and ``ConfigureRequest`` events to +:mod:`tkinter`. + +.. + +.. bpo: 32234 +.. date: 2017-12-15-09-32-57 +.. nonce: XaOkhR +.. section: Library + +:class:`mailbox.Mailbox` instances can now be used as a context manager. The +Mailbox is locked on context entry and unlocked and closed at context exit. + +.. + +.. date: 2026-03-03-08-18-00 +.. gh-issue: 145450 +.. nonce: VI7GXj +.. section: Documentation + +Document missing public :class:`wave.Wave_write` getter methods. + +.. + +.. date: 2026-01-06-16-04-08 +.. gh-issue: 110937 +.. nonce: SyO5lk +.. section: Documentation + +Document rest of full public :class:`importlib.metadata.Distribution` API. +Also add the (already documented) :class:`~importlib.metadata.PackagePath` +to ``__all__``. + +.. + +.. date: 2025-08-02-18-59-01 +.. gh-issue: 136246 +.. nonce: RIK7nE +.. section: Documentation + +A new "Improve this page" link is available in the left-hand sidebar of the +docs, offering links to create GitHub issues, discussion forum posts, or +pull requests. + +.. + +.. date: 2026-03-09-18-52-03 +.. gh-issue: 145701 +.. nonce: 79KQyO +.. section: Core and Builtins + +Fix :exc:`SystemError` when ``__classdict__`` or +``__conditional_annotations__`` is in a class-scope inlined comprehension. +Found by OSS Fuzz in :oss-fuzz:`491105000`. + +.. + +.. date: 2026-03-06-21-05-05 +.. gh-issue: 145615 +.. nonce: NKXXZgDW +.. section: Core and Builtins + +Fixed a memory leak in the :term:`free-threaded build` where mimalloc pages +could become permanently unreclaimable until the owning thread exited. + +.. + +.. date: 2026-03-06-01-36-20 +.. gh-issue: 116738 +.. nonce: OWVWRx +.. section: Core and Builtins + +Make :meth:`!mmap.mmap.set_name` thread-safe on the :term:`free threaded +` build. + +.. + +.. date: 2026-03-05-19-10-56 +.. gh-issue: 145566 +.. nonce: H4RupyYN +.. section: Core and Builtins + +In the free threading build, skip the stop-the-world pause when reassigning +``__class__`` on a newly created object. + +.. + +.. date: 2026-03-05-16-16-17 +.. gh-issue: 143055 +.. nonce: qDUFlY +.. section: Core and Builtins + +Fix crash in AST unparser when unparsing dict comprehension unpacking. Found +by OSS Fuzz in :oss-fuzz:`489790200`. + +.. + +.. date: 2026-03-01-13-37-31 +.. gh-issue: 145335 +.. nonce: e36kPJ +.. section: Core and Builtins + +Fix a crash in :func:`os.pathconf` when called with ``-1`` as the path +argument. + +.. + +.. date: 2026-02-28-16-46-17 +.. gh-issue: 145376 +.. nonce: lG5u1a +.. section: Core and Builtins + +Fix reference leaks in various unusual error scenarios. + +.. + +.. date: 2026-02-26-21-36-00 +.. gh-issue: 145234 +.. nonce: w0mQ9n +.. section: Core and Builtins + +Fixed a ``SystemError`` in the parser when an encoding cookie (for example, +UTF-7) decodes to carriage returns (``\r``). Newlines are now normalized +after decoding in the string tokenizer. + +Patch by Pablo Galindo. + +.. + +.. date: 2026-02-26-21-07-38 +.. gh-issue: 145275 +.. nonce: qE-3O1 +.. section: Core and Builtins + +Added the :option:`-X pathconfig_warnings<-X>` and +:envvar:`PYTHON_PATHCONFIG_WARNINGS` options, allowing to disable warnings +from :ref:`sys-path-init`. + +.. + +.. date: 2026-02-26-20-51-54 +.. gh-issue: 145273 +.. nonce: B5QcUp +.. section: Core and Builtins + +A warning is now shown during :ref:`sys-path-init` if it can't find a valid +standard library. + +.. + +.. date: 2026-02-26-18-00-00 +.. gh-issue: 145241 +.. nonce: hL2k9Q +.. section: Core and Builtins + +Specialized the parser error for when ``with`` items are followed by a +trailing comma (for example, ``with item,:``), raising a clearer +:exc:`SyntaxError` message. Patch by Pablo Galindo and Bartosz Sławecki. + +.. + +.. date: 2026-02-26-12-00-00 +.. gh-issue: 130555 +.. nonce: TMSOIu +.. section: Core and Builtins + +Fix use-after-free in :meth:`dict.clear` when the dictionary values are +embedded in an object and a destructor causes re-entrant mutation of the +dictionary. + +.. + +.. date: 2026-02-25-15-02-08 +.. gh-issue: 145197 +.. nonce: G6hAUk +.. section: Core and Builtins + +Fix JIT trace crash when recording function from cleared generator frame. + +.. + +.. date: 2026-02-24-18-30-56 +.. gh-issue: 145187 +.. nonce: YjPu1Z +.. section: Core and Builtins + +Fix compiler assertion fail when a type parameter bound contains an invalid +expression in a conditional block. + +.. + +.. date: 2026-02-23-23-18-28 +.. gh-issue: 145142 +.. nonce: T-XbVe +.. section: Core and Builtins + +Fix a crash in the free-threaded build when the dictionary argument to +:meth:`str.maketrans` is concurrently modified. + +.. + +.. date: 2026-02-22-22-05-09 +.. gh-issue: 145118 +.. nonce: TaKMJE +.. section: Core and Builtins + +:meth:`str.maketrans` now accepts :class:`frozendict`. + +.. + +.. date: 2026-02-22-20-15-00 +.. gh-issue: 144015 +.. nonce: pystrhex_simd +.. section: Core and Builtins + +Speed up :meth:`bytes.hex`, :meth:`bytearray.hex`, :func:`binascii.hexlify`, +and :mod:`hashlib` ``.hexdigest()`` operations with SIMD on x86-64, ARM64, +and ARM32 with NEON when built with gcc (version 12 or higher) or clang +(version 3 or higher) compilers. Around 1.1-3x faster for common 16-64 byte +inputs such as hashlib hex digests, and up to 8x faster for larger data. + +.. + +.. date: 2026-02-22-19-05-03 +.. gh-issue: 145118 +.. nonce: bU6Sic +.. section: Core and Builtins + +:func:`type` now accepts :class:`frozendict` as an argument. + +.. + +.. date: 2026-02-22-07-51-10 +.. gh-issue: 145064 +.. nonce: iIMGKA +.. section: Core and Builtins + +Fix JIT optimizer assertion failure during ``CALL_ALLOC_AND_ENTER_INIT`` +side exit. + +.. + +.. date: 2026-02-21-12-16-46 +.. gh-issue: 145055 +.. nonce: VyT-zI +.. section: Core and Builtins + +:func:`exec` and :func:`eval` now accept :class:`frozendict` for *globals*. +Patch by Victor Stinner. + +.. + +.. date: 2026-02-21-09-47-45 +.. gh-issue: 145058 +.. nonce: e-RBw- +.. section: Core and Builtins + +Fix a crash when :func:`!__lazy_import__` is passed a non-string argument, +by raising an :exc:`TypeError` instead. + +.. + +.. date: 2026-02-19-12-49-15 +.. gh-issue: 144995 +.. nonce: Ob2oYJ +.. section: Core and Builtins + +Optimize :class:`memoryview` comparison: a :class:`memoryview` is equal to +itself, there is no need to compare values. Patch by Victor Stinner. + +.. + +.. date: 2026-02-18-21-44-39 +.. gh-issue: 141510 +.. nonce: 7LST2O +.. section: Core and Builtins + +Update specializer to support frozendict. Patch by Donghee Na. + +.. + +.. date: 2026-02-17-22-27-11 +.. gh-issue: 141510 +.. nonce: -4yYsf +.. section: Core and Builtins + +Optimize :meth:`!frozendict.fromkeys` to avoid unnecessary thread-safety +operations in frozendict cases. Patch by Donghee Na. + +.. + +.. date: 2026-02-17-21-04-03 +.. gh-issue: 100239 +.. nonce: LyVabQ +.. section: Core and Builtins + +Speedup ``BINARY_OP_EXTEND`` for exact floats and medium-size integers by up +to 15%. Patch by Chris Eibl. + +.. + +.. date: 2026-02-17-18-27-28 +.. gh-issue: 144914 +.. nonce: DcXO4m +.. section: Core and Builtins + +Use ``mimalloc`` for raw memory allocations such as via +:c:func:`PyMem_RawMalloc` for better performance on :term:`free-threaded +builds `. Patch by Kumar Aditya. + +.. + +.. date: 2026-02-16-12-28-43 +.. gh-issue: 144872 +.. nonce: k9_Q30 +.. section: Core and Builtins + +Fix heap buffer overflow in the parser found by OSS-Fuzz. + +.. + +.. date: 2026-02-13-18-30-59 +.. gh-issue: 144766 +.. nonce: JGu3x3 +.. section: Core and Builtins + +Fix a crash in fork child process when perf support is enabled. + +.. + +.. date: 2026-02-13-12-00-00 +.. gh-issue: 144759 +.. nonce: d3qYpe +.. section: Core and Builtins + +Fix undefined behavior in the lexer when ``start`` and ``multi_line_start`` +pointers are ``NULL`` in ``_PyLexer_remember_fstring_buffers()`` and +``_PyLexer_restore_fstring_buffers()``. The ``NULL`` pointer arithmetic +(``NULL - valid_pointer``) is now guarded with explicit ``NULL`` checks. + +.. + +.. date: 2026-02-12-19-01-13 +.. gh-issue: 141510 +.. nonce: KlKjZg +.. section: Core and Builtins + +Add built-in :class:`frozendict` type. Patch by Victor Stinner. + +.. + +.. date: 2026-02-12-12-39-50 +.. gh-issue: 144681 +.. nonce: Ns2OT2 +.. section: Core and Builtins + +Fix a JIT assertion failure when a conditional branch jumps to the same +target as the fallthrough path. + +.. + +.. date: 2026-02-11-13-30-11 +.. gh-issue: 143300 +.. nonce: yjB63- +.. section: Core and Builtins + +Add :c:func:`PyUnstable_SetImmortal` C-API function to mark objects as +:term:`immortal`. + +.. + +.. date: 2026-02-11-11-28-25 +.. gh-issue: 144702 +.. nonce: XjFumv +.. section: Core and Builtins + +Clarify the error message raised when a class pattern is used to match on a +non-class object. + +.. + +.. date: 2026-02-08-13-14-00 +.. gh-issue: 144569 +.. nonce: pjlJVe +.. section: Core and Builtins + +Optimize ``BINARY_SLICE`` for list, tuple, and unicode by avoiding temporary +``slice`` object creation. + +.. + +.. date: 2026-02-06-21-45-52 +.. gh-issue: 144438 +.. nonce: GI_uB1LR +.. section: Core and Builtins + +Align the QSBR thread state array to a 64-byte cache line boundary to avoid +false sharing in the :term:`free-threaded build`. + +.. + +.. date: 2025-12-06-15-46-32 +.. gh-issue: 142349 +.. nonce: IdTuYL +.. section: Core and Builtins + +Implement :pep:`810`. Patch by Pablo Galindo and Dino Viehland. + +.. + +.. date: 2025-11-09-15-44-58 +.. gh-issue: 141226 +.. nonce: KTb_3F +.. section: Core and Builtins + +Deprecate :pep:`456` support for providing an external definition of the +string hashing scheme. Removal is scheduled for Python 3.19. Patch by +Bénédikt Tran. + +.. + +.. date: 2025-09-15-13-28-48 +.. gh-issue: 138912 +.. nonce: 61EYbn +.. section: Core and Builtins + +Improve :opcode:`MATCH_CLASS` performance by up to 52% in certain cases. +Patch by Marc Mueller. + +.. + +.. date: 2025-02-19-21-06-30 +.. gh-issue: 130327 +.. nonce: z3TaR8 +.. section: Core and Builtins + +Fix erroneous clearing of an object's :attr:`~object.__dict__` if +overwritten at runtime. + +.. + +.. date: 2023-07-26-00-03-00 +.. gh-issue: 80667 +.. nonce: N7Dh8B +.. section: Core and Builtins + +Literals using the ``\N{name}`` escape syntax can now construct CJK +ideographs and Hangul syllables using case-insensitive names. + +.. + +.. date: 2026-03-03-14-59-57 +.. gh-issue: 142417 +.. nonce: HiNP5j +.. section: C API + +Restore private provisional ``_Py_InitializeMain()`` function removed in +Python 3.14. Patch by Victor Stinner. + +.. + +.. date: 2026-02-24-14-46-05 +.. gh-issue: 144748 +.. nonce: uhnFtE +.. section: C API + +:c:func:`PyErr_CheckSignals` now raises the exception scheduled by +:c:func:`PyThreadState_SetAsyncExc`, if any. + +.. + +.. date: 2026-02-18-15-12-34 +.. gh-issue: 144981 +.. nonce: 4ZdM63 +.. section: C API + +Made :c:func:`PyUnstable_Code_SetExtra`, :c:func:`PyUnstable_Code_GetExtra`, +and :c:func:`PyUnstable_Eval_RequestCodeExtraIndex` thread-safe on the +:term:`free threaded ` build. + +.. + +.. date: 2026-02-12-19-03-31 +.. gh-issue: 141510 +.. nonce: U_1tjz +.. section: C API + +Add the following functions for the new :class:`frozendict` type: + +* :c:func:`PyAnyDict_Check` +* :c:func:`PyAnyDict_CheckExact` +* :c:func:`PyFrozenDict_Check` +* :c:func:`PyFrozenDict_CheckExact` +* :c:func:`PyFrozenDict_New` + +Patch by Victor Stinner. + +.. + +.. date: 2026-02-10-14-49-49 +.. gh-issue: 121617 +.. nonce: 57vMqa +.. section: C API + +``Python.h`` now also includes ```` in the limited C API version +3.11 and newer to fix the :c:macro:`Py_CLEAR` macro which uses ``memcpy()``. +Patch by Victor Stinner. + +.. + +.. date: 2026-01-27-18-15-15 +.. gh-issue: 144175 +.. nonce: qHK5Jf +.. section: C API + +Add :c:func:`PyArg_ParseArray` and :c:func:`PyArg_ParseArrayAndKeywords` +functions to parse arguments of functions using the :c:macro:`METH_FASTCALL` +calling convention. Patch by Victor Stinner. + +.. + +.. date: 2026-02-27-18-10-02 +.. gh-issue: 144533 +.. nonce: 21fk9L +.. section: Build + +Use wasmtime's ``--argv0`` to auto-discover sysconfig in WASI builds + +.. + +.. date: 2026-02-22-13-35-20 +.. gh-issue: 145110 +.. nonce: KgWofW +.. section: Build + +Fix targets "Clean" and "CLeanAll" in case of PGO builds on Windows. Patch +by Chris Eibl. + +.. + +.. date: 2026-02-10-18-26-04 +.. gh-issue: 144679 +.. nonce: FIH73W +.. section: Build + +When building with Visual Studio 2026 (Version 18), use PlatformToolSet v145 +by default. Patch by Chris Eibl. + +.. + +.. date: 2026-02-10-16-59-56 +.. gh-issue: 144675 +.. nonce: Wrf3Es +.. section: Build + +Update to WASI SDK 30. + +.. + +.. date: 2025-07-21-00-33-38 +.. gh-issue: 136677 +.. nonce: Y1_3ec +.. section: Build + +Introduce executable specific linker flags to ``./configure``. diff --git a/Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst b/Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst deleted file mode 100644 index 30addc4bf64d4b..00000000000000 --- a/Misc/NEWS.d/next/Build/2025-07-21-00-33-38.gh-issue-136677.Y1_3ec.rst +++ /dev/null @@ -1 +0,0 @@ -Introduce executable specific linker flags to ``./configure``. diff --git a/Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst b/Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst deleted file mode 100644 index 1018ed95a2af77..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-02-10-16-59-56.gh-issue-144675.Wrf3Es.rst +++ /dev/null @@ -1 +0,0 @@ -Update to WASI SDK 30. diff --git a/Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst b/Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst deleted file mode 100644 index ebcfda54da39a7..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-02-10-18-26-04.gh-issue-144679.FIH73W.rst +++ /dev/null @@ -1,2 +0,0 @@ -When building with Visual Studio 2026 (Version 18), use PlatformToolSet v145 -by default. Patch by Chris Eibl. diff --git a/Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst b/Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst deleted file mode 100644 index 035d0c141d36ed..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-02-22-13-35-20.gh-issue-145110.KgWofW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix targets "Clean" and "CLeanAll" in case of PGO builds on Windows. Patch by -Chris Eibl. diff --git a/Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst b/Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst deleted file mode 100644 index d6e0201b90c550..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-02-27-18-10-02.gh-issue-144533.21fk9L.rst +++ /dev/null @@ -1 +0,0 @@ -Use wasmtime's ``--argv0`` to auto-discover sysconfig in WASI builds diff --git a/Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst b/Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst deleted file mode 100644 index da1e489bb3d2e5..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-01-27-18-15-15.gh-issue-144175.qHK5Jf.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :c:func:`PyArg_ParseArray` and :c:func:`PyArg_ParseArrayAndKeywords` -functions to parse arguments of functions using the :c:macro:`METH_FASTCALL` -calling convention. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst b/Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst deleted file mode 100644 index cf84f8b1b0d36b..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-02-10-14-49-49.gh-issue-121617.57vMqa.rst +++ /dev/null @@ -1,3 +0,0 @@ -``Python.h`` now also includes ```` in the limited C API version 3.11 -and newer to fix the :c:macro:`Py_CLEAR` macro which uses ``memcpy()``. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst b/Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst deleted file mode 100644 index 57a25fe045f04c..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-02-12-19-03-31.gh-issue-141510.U_1tjz.rst +++ /dev/null @@ -1,9 +0,0 @@ -Add the following functions for the new :class:`frozendict` type: - -* :c:func:`PyAnyDict_Check` -* :c:func:`PyAnyDict_CheckExact` -* :c:func:`PyFrozenDict_Check` -* :c:func:`PyFrozenDict_CheckExact` -* :c:func:`PyFrozenDict_New` - -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst b/Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst deleted file mode 100644 index d86886ab09704a..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-02-18-15-12-34.gh-issue-144981.4ZdM63.rst +++ /dev/null @@ -1,3 +0,0 @@ -Made :c:func:`PyUnstable_Code_SetExtra`, :c:func:`PyUnstable_Code_GetExtra`, -and :c:func:`PyUnstable_Eval_RequestCodeExtraIndex` thread-safe on the -:term:`free threaded ` build. diff --git a/Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst b/Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst deleted file mode 100644 index bda7003be94e54..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-02-24-14-46-05.gh-issue-144748.uhnFtE.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`PyErr_CheckSignals` now raises the exception scheduled by -:c:func:`PyThreadState_SetAsyncExc`, if any. diff --git a/Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst b/Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst deleted file mode 100644 index 943be5b4533d9e..00000000000000 --- a/Misc/NEWS.d/next/C_API/2026-03-03-14-59-57.gh-issue-142417.HiNP5j.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restore private provisional ``_Py_InitializeMain()`` function removed in -Python 3.14. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst b/Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst deleted file mode 100644 index db87a5ed9c7fc2..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2023-07-26-00-03-00.gh-issue-80667.N7Dh8B.rst +++ /dev/null @@ -1,2 +0,0 @@ -Literals using the ``\N{name}`` escape syntax can now construct CJK -ideographs and Hangul syllables using case-insensitive names. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst deleted file mode 100644 index 9b9a282b5ab414..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-19-21-06-30.gh-issue-130327.z3TaR8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix erroneous clearing of an object's :attr:`~object.__dict__` if -overwritten at runtime. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst deleted file mode 100644 index f5d312a289fe21..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-15-13-28-48.gh-issue-138912.61EYbn.rst +++ /dev/null @@ -1 +0,0 @@ -Improve :opcode:`MATCH_CLASS` performance by up to 52% in certain cases. Patch by Marc Mueller. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst deleted file mode 100644 index 3f7ce7326187d4..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-09-15-44-58.gh-issue-141226.KTb_3F.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecate :pep:`456` support for providing an external definition -of the string hashing scheme. Removal is scheduled for Python 3.19. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst deleted file mode 100644 index 73cc167fd04013..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-15-46-32.gh-issue-142349.IdTuYL.rst +++ /dev/null @@ -1 +0,0 @@ -Implement :pep:`810`. Patch by Pablo Galindo and Dino Viehland. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst deleted file mode 100644 index 3e33e461ae8b5a..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-06-21-45-52.gh-issue-144438.GI_uB1LR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Align the QSBR thread state array to a 64-byte cache line boundary to -avoid false sharing in the :term:`free-threaded build`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst deleted file mode 100644 index bdd0d6c2f7b944..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-08-13-14-00.gh-issue-144569.pjlJVe.rst +++ /dev/null @@ -1 +0,0 @@ -Optimize ``BINARY_SLICE`` for list, tuple, and unicode by avoiding temporary ``slice`` object creation. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst deleted file mode 100644 index 01d2b6570ded96..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-11-28-25.gh-issue-144702.XjFumv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Clarify the error message raised when a class pattern is used to match on a -non-class object. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst deleted file mode 100644 index 85c75a224e42fc..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-11-13-30-11.gh-issue-143300.yjB63-.rst +++ /dev/null @@ -1 +0,0 @@ -Add :c:func:`PyUnstable_SetImmortal` C-API function to mark objects as :term:`immortal`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst deleted file mode 100644 index c8ca7a7fa194ee..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a JIT assertion failure when a conditional branch jumps to the same target as the fallthrough path. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst deleted file mode 100644 index 4596e273fc6118..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-19-01-13.gh-issue-141510.KlKjZg.rst +++ /dev/null @@ -1 +0,0 @@ -Add built-in :class:`frozendict` type. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst deleted file mode 100644 index 46786d0672b0a8..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-12-00-00.gh-issue-144759.d3qYpe.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix undefined behavior in the lexer when ``start`` and ``multi_line_start`` -pointers are ``NULL`` in ``_PyLexer_remember_fstring_buffers()`` and -``_PyLexer_restore_fstring_buffers()``. The ``NULL`` pointer arithmetic -(``NULL - valid_pointer``) is now guarded with explicit ``NULL`` checks. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst deleted file mode 100644 index d9613c95af1915..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-13-18-30-59.gh-issue-144766.JGu3x3.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a crash in fork child process when perf support is enabled. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst deleted file mode 100644 index c06bf01baee6fd..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-12-28-43.gh-issue-144872.k9_Q30.rst +++ /dev/null @@ -1 +0,0 @@ -Fix heap buffer overflow in the parser found by OSS-Fuzz. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst deleted file mode 100644 index f13b8541a0ebe2..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-18-27-28.gh-issue-144914.DcXO4m.rst +++ /dev/null @@ -1 +0,0 @@ -Use ``mimalloc`` for raw memory allocations such as via :c:func:`PyMem_RawMalloc` for better performance on :term:`free-threaded builds `. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst deleted file mode 100644 index 3cfc3e930d1e9d..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-21-04-03.gh-issue-100239.LyVabQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Speedup ``BINARY_OP_EXTEND`` for exact floats and medium-size integers by up -to 15%. Patch by Chris Eibl. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst deleted file mode 100644 index b031fb3c75dea7..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-17-22-27-11.gh-issue-141510.-4yYsf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize :meth:`!frozendict.fromkeys` to avoid unnecessary thread-safety operations -in frozendict cases. Patch by Donghee Na. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst deleted file mode 100644 index 87d6a2a6df96a1..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-18-21-44-39.gh-issue-141510.7LST2O.rst +++ /dev/null @@ -1 +0,0 @@ -Update specializer to support frozendict. Patch by Donghee Na. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst deleted file mode 100644 index 83d84b9505c5a5..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-19-12-49-15.gh-issue-144995.Ob2oYJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize :class:`memoryview` comparison: a :class:`memoryview` is equal to -itself, there is no need to compare values. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst deleted file mode 100644 index 05eb296f96ec6d..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash when :func:`!__lazy_import__` is passed a non-string argument, -by raising an :exc:`TypeError` instead. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst deleted file mode 100644 index c9daaa27717ed0..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-12-16-46.gh-issue-145055.VyT-zI.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`exec` and :func:`eval` now accept :class:`frozendict` for *globals*. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst deleted file mode 100644 index 1f298e164f4488..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-07-51-10.gh-issue-145064.iIMGKA.rst +++ /dev/null @@ -1 +0,0 @@ -Fix JIT optimizer assertion failure during ``CALL_ALLOC_AND_ENTER_INIT`` side exit. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst deleted file mode 100644 index 24507d4a411f85..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-19-05-03.gh-issue-145118.bU6Sic.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`type` now accepts :class:`frozendict` as an argument. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst deleted file mode 100644 index 122315e031bc87..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-20-15-00.gh-issue-144015.pystrhex_simd.rst +++ /dev/null @@ -1,5 +0,0 @@ -Speed up :meth:`bytes.hex`, :meth:`bytearray.hex`, :func:`binascii.hexlify`, -and :mod:`hashlib` ``.hexdigest()`` operations with SIMD on x86-64, ARM64, -and ARM32 with NEON when built with gcc (version 12 or higher) or clang -(version 3 or higher) compilers. Around 1.1-3x faster for common 16-64 byte -inputs such as hashlib hex digests, and up to 8x faster for larger data. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst deleted file mode 100644 index fccc3bc2a1804e..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-22-22-05-09.gh-issue-145118.TaKMJE.rst +++ /dev/null @@ -1 +0,0 @@ -:meth:`str.maketrans` now accepts :class:`frozendict`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst deleted file mode 100644 index 5f6043cc3d9660..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-23-23-18-28.gh-issue-145142.T-XbVe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in the free-threaded build when the dictionary argument to -:meth:`str.maketrans` is concurrently modified. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst deleted file mode 100644 index 08c6b44164ebc3..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-24-18-30-56.gh-issue-145187.YjPu1Z.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix compiler assertion fail when a type parameter bound contains an invalid -expression in a conditional block. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst deleted file mode 100644 index 6d6afe5abfea9c..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-25-15-02-08.gh-issue-145197.G6hAUk.rst +++ /dev/null @@ -1 +0,0 @@ -Fix JIT trace crash when recording function from cleared generator frame. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst deleted file mode 100644 index 5a2106480fb843..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-12-00-00.gh-issue-130555.TMSOIu.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix use-after-free in :meth:`dict.clear` when the dictionary values are -embedded in an object and a destructor causes re-entrant mutation of the -dictionary. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst deleted file mode 100644 index a3253132a577ba..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-18-00-00.gh-issue-145241.hL2k9Q.rst +++ /dev/null @@ -1,3 +0,0 @@ -Specialized the parser error for when ``with`` items are followed -by a trailing comma (for example, ``with item,:``), raising a clearer -:exc:`SyntaxError` message. Patch by Pablo Galindo and Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst deleted file mode 100644 index 8d9e4a872d0d7a..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-20-51-54.gh-issue-145273.B5QcUp.rst +++ /dev/null @@ -1,2 +0,0 @@ -A warning is now shown during :ref:`sys-path-init` if it can't find a valid -standard library. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst deleted file mode 100644 index 1723a7c8c10717..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-07-38.gh-issue-145275.qE-3O1.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added the :option:`-X pathconfig_warnings<-X>` and -:envvar:`PYTHON_PATHCONFIG_WARNINGS` options, allowing to disable warnings -from :ref:`sys-path-init`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst deleted file mode 100644 index caeffff0be8a85..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-26-21-36-00.gh-issue-145234.w0mQ9n.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixed a ``SystemError`` in the parser when an encoding cookie (for example, -UTF-7) decodes to carriage returns (``\r``). Newlines are now normalized after -decoding in the string tokenizer. - -Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst deleted file mode 100644 index a5a6908757e458..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-16-46-17.gh-issue-145376.lG5u1a.rst +++ /dev/null @@ -1 +0,0 @@ -Fix reference leaks in various unusual error scenarios. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst deleted file mode 100644 index 42ed85c7da31ac..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash in :func:`os.pathconf` when called with ``-1`` as the path -argument. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst deleted file mode 100644 index 9b55459bffdea8..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-16-16-17.gh-issue-143055.qDUFlY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash in AST unparser when unparsing dict comprehension unpacking. -Found by OSS Fuzz in :oss-fuzz:`489790200`. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst deleted file mode 100644 index 723b81ddc5f897..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst +++ /dev/null @@ -1,2 +0,0 @@ -In the free threading build, skip the stop-the-world pause when reassigning -``__class__`` on a newly created object. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst deleted file mode 100644 index 212fd7b02902e9..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-01-36-20.gh-issue-116738.OWVWRx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make :meth:`!mmap.mmap.set_name` thread-safe on the :term:`free threaded ` build. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst deleted file mode 100644 index 2183eef618daae..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-06-21-05-05.gh-issue-145615.NKXXZgDW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a memory leak in the :term:`free-threaded build` where mimalloc pages -could become permanently unreclaimable until the owning thread exited. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst deleted file mode 100644 index 23796082fb616f..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-18-52-03.gh-issue-145701.79KQyO.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :exc:`SystemError` when ``__classdict__`` or -``__conditional_annotations__`` is in a class-scope inlined comprehension. -Found by OSS Fuzz in :oss-fuzz:`491105000`. diff --git a/Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst b/Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst deleted file mode 100644 index 5f83785df13209..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2025-08-02-18-59-01.gh-issue-136246.RIK7nE.rst +++ /dev/null @@ -1,3 +0,0 @@ -A new "Improve this page" link is available in the left-hand sidebar of the -docs, offering links to create GitHub issues, discussion forum posts, or -pull requests. diff --git a/Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst b/Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst deleted file mode 100644 index d29bde5ca690c6..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2026-01-06-16-04-08.gh-issue-110937.SyO5lk.rst +++ /dev/null @@ -1 +0,0 @@ -Document rest of full public :class:`importlib.metadata.Distribution` API. Also add the (already documented) :class:`~importlib.metadata.PackagePath` to ``__all__``. diff --git a/Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst b/Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst deleted file mode 100644 index 681c932b34a05d..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2026-03-03-08-18-00.gh-issue-145450.VI7GXj.rst +++ /dev/null @@ -1 +0,0 @@ -Document missing public :class:`wave.Wave_write` getter methods. diff --git a/Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst b/Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst deleted file mode 100644 index b22289835620df..00000000000000 --- a/Misc/NEWS.d/next/Library/2017-12-15-09-32-57.bpo-32234.XaOkhR.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`mailbox.Mailbox` instances can now be used as a context manager. -The Mailbox is locked on context entry and unlocked and closed at context exit. diff --git a/Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst b/Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst deleted file mode 100644 index bf97bf0231fc0a..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-05-11-12-26-16.bpo-3405.CacMw9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add support for user data of Tk virtual events and detail for -``Enter``, ``Leave``, ``FocusIn``, ``FocusOut``, and -``ConfigureRequest`` events to :mod:`tkinter`. diff --git a/Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst b/Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst deleted file mode 100644 index 2e9c3d81180e6a..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-04-07-05-09-34.bpo-40212.oPYeBs.rst +++ /dev/null @@ -1 +0,0 @@ -Re-enable :func:`os.posix_fallocate` and :func:`os.posix_fadvise` on AIX. diff --git a/Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst b/Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst deleted file mode 100644 index 1f48525cdbecd0..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-04-10-14-29-53.bpo-40243.85HRib.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :meth:`!unicodedata.ucd_3_2_0.numeric` for non-decimal values. diff --git a/Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst b/Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst deleted file mode 100644 index a3e0a3e14af1fa..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-05-00-15-03.bpo-42353.0ebVGG.rst +++ /dev/null @@ -1,10 +0,0 @@ -The :mod:`re` module gains a new :func:`re.prefixmatch` function as an -explicit spelling of what has to date always been known as :func:`re.match`. -:class:`re.Pattern` similary gains a :meth:`re.Pattern.prefixmatch` method. - -Why? Explicit is better than implicit. Other widely used languages all use -the term "match" to mean what Python uses the term "search" for. The -unadorened "match" name in Python has been a frequent case of confusion and -coding bugs due to the inconsistency with the rest if the software industry. - -We do not plan to deprecate and remove the older ``match`` name. diff --git a/Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst b/Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst deleted file mode 100644 index f82f1eeb0589c6..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-02-05-20-02-30.gh-issue-80667.7LmzeA.rst +++ /dev/null @@ -1 +0,0 @@ -Add support for Tangut Ideographs names in :mod:`unicodedata`. diff --git a/Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst b/Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst deleted file mode 100644 index 5067db357fc577..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-09-30-15-31-59.gh-issue-124748.KYzYFp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve :exc:`TypeError` error message when :meth:`!weakref.WeakKeyDictionary.update` -is used with keyword-only parameters. diff --git a/Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst b/Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst deleted file mode 100644 index 8f3efceaae1d91..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-06-24-19-07-18.gh-issue-135883.38cePA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`sqlite3`'s :ref:`interactive shell ` keeping part of -previous commands when scrolling history. diff --git a/Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst b/Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst deleted file mode 100644 index 2311ace10e411d..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-08-04-23-20-43.gh-issue-137335.IIjDJN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Get rid of any possibility of a name conflict for named pipes in -:mod:`multiprocessing` and :mod:`asyncio` on Windows, no matter how small. diff --git a/Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst b/Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst deleted file mode 100644 index fe5e7d17ab6c8c..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-10-10-14-08-58.gh-issue-139899.09leRY.rst +++ /dev/null @@ -1,3 +0,0 @@ -Introduced :meth:`importlib.abc.MetaPathFinder.discover` -and :meth:`importlib.abc.PathEntryFinder.discover` to allow module and submodule -name discovery without assuming the use of traditional filesystem based imports. diff --git a/Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst b/Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst deleted file mode 100644 index 13e38b118175b4..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-06-16-14-18.gh-issue-142352.pW5HLX88.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :meth:`asyncio.StreamWriter.start_tls` to transfer buffered data from -:class:`~asyncio.StreamReader` to the SSL layer, preventing data loss when -upgrading a connection to TLS mid-stream (e.g., when implementing PROXY -protocol support). diff --git a/Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst b/Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst deleted file mode 100644 index e928bd2cac72a8..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-16-13-34-48.gh-issue-142787.wNitJX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix assertion failure in :mod:`sqlite3` blob subscript when slicing with -indices that result in an empty slice. diff --git a/Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst b/Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst deleted file mode 100644 index 772e05766c5c69..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-12-18-00-14-16.gh-issue-142781.gcOeYF.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`zoneinfo`: fix a crash when instantiating :class:`~zoneinfo.ZoneInfo` -objects for which the internal class-level cache is inconsistent. diff --git a/Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst b/Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst deleted file mode 100644 index 826b2e9a126d36..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-01-05-26-00.gh-issue-143304.Kv7x9Q.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :class:`ctypes.CDLL` to honor the ``handle`` parameter on POSIX systems. diff --git a/Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst b/Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst deleted file mode 100644 index 3993c7a91da138..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-10-22-58-30.gh-issue-85809.0eW4wt.rst +++ /dev/null @@ -1 +0,0 @@ -Added :term:`path-like object` support for :func:`shutil.make_archive`. diff --git a/Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst b/Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst deleted file mode 100644 index efa7c8a1f62692..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-11-13-03-32.gh-issue-142516.u7An-s.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`ssl`: fix reference leaks in :class:`ssl.SSLContext` objects. Patch by -Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst b/Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst deleted file mode 100644 index 05dc4941c98a83..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-11-16-59-22.gh-issue-143698.b-Cpeb.rst +++ /dev/null @@ -1,3 +0,0 @@ -Raise :exc:`TypeError` instead of :exc:`SystemError` when the *scheduler* -in :func:`os.posix_spawn` or :func:`os.posix_spawnp` is not a tuple. -Patch by Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst b/Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst deleted file mode 100644 index 5f95b0de7d8895..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-11-18-35-52.gh-issue-143698.gXDzsJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Allow *scheduler* and *setpgroup* arguments to be explicitly :const:`None` -when calling :func:`os.posix_spawn` or :func:`os.posix_spawnp`. Patch by -Bénédikt Tran. diff --git a/Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst b/Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst deleted file mode 100644 index bed126f02f8714..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-12-19-39-57.gh-issue-140652.HvM9Bl.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a crash in :func:`!_interpchannels.list_all` after closing a channel. diff --git a/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst deleted file mode 100644 index cbb21194d5b387..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a crash in socket.sendmsg() that could occur if ancillary data is mutated re-entrantly during argument parsing. diff --git a/Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst b/Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst deleted file mode 100644 index b9d0749f56ba6a..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-03-19-57-41.gh-issue-144316.wop870.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash in ``_remote_debugging`` that caused ``test_external_inspection`` to intermittently fail. Patch by Taegyun Kim. diff --git a/Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst b/Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst deleted file mode 100644 index e1119a85e9c1f3..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-07-16-31-42.gh-issue-144285.iyH9iL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Attribute suggestions in :exc:`AttributeError` tracebacks are now formatted differently -to make them easier to understand, for example: ``Did you mean '.datetime.now' instead of '.now'``. -Contributed by Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst deleted file mode 100644 index b458399bb40640..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ /dev/null @@ -1,3 +0,0 @@ -Calling :func:`repr` on :func:`functools.partial` is now safer -when the partial object's internal attributes are replaced while -the string representation is being generated. diff --git a/Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst b/Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst deleted file mode 100644 index 45561898e2e1e9..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-08-17-09-10.gh-issue-144321.w58PhQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -The functional syntax for creating :class:`typing.NamedTuple` -classes now supports passing any :term:`iterable` of fields and types. -Previously, only sequences were supported. diff --git a/Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst b/Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst deleted file mode 100644 index 1db257ae312e84..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-09-02-16-36.gh-issue-144615.s04x4n.rst +++ /dev/null @@ -1,3 +0,0 @@ -Methods directly decorated with :deco:`functools.singledispatchmethod` now -dispatch on the second argument when called after being accessed as class -attributes. Patch by Bartosz Sławecki. diff --git a/Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst b/Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst deleted file mode 100644 index 276711e6ba3900..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-10-16-56-05.gh-issue-66305.PZ6GN8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a hang on Windows in the :mod:`tempfile` module when -trying to create a temporary file or subdirectory in a non-writable -directory. diff --git a/Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst b/Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst deleted file mode 100644 index 68e59a6276c092..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-10-22-05-51.gh-issue-144156.UbrC7F.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the folding of headers by the :mod:`email` library when :rfc:`2047` encoded words are used. Now whitespace is correctly preserved and also correctly added between adjacent encoded words. The latter property was broken by the fix for gh-92081, which mostly fixed previous failures to preserve whitespace. diff --git a/Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst b/Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst deleted file mode 100644 index f45f6682869eb1..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-12-17-56-17.gh-issue-117865.jE1ema.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce the import time of :mod:`inspect` module by ~20%. diff --git a/Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst b/Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst deleted file mode 100644 index 29fa908d739fc3..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-13-00-00-00.gh-issue-142224.BidiMissing.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`unicodedata.bidirectional` now return the correct default bidi class -for unassigned code points. diff --git a/Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst b/Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst deleted file mode 100644 index 14eb4f49c8ad3c..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-13-11-14-18.gh-issue-144763.cDwnEE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a race condition in :mod:`tracemalloc`: it no longer detaches the attached -thread state to acquire its internal lock. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst b/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst deleted file mode 100644 index 871005fd7d986c..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :class:`argparse.ArgumentParser` to be :mod:`pickleable `. diff --git a/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst b/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst deleted file mode 100644 index f7782f2fa4f23b..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-14-14-56-44.gh-issue-140715.AbSheM.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``'%D'`` support to :meth:`~datetime.datetime.strptime`. diff --git a/Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst b/Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst deleted file mode 100644 index 6d5b18f59ee7ea..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-15-00-00-00.gh-issue-144833.TUelo1.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a use-after-free in :mod:`ssl` when ``SSL_new()`` returns NULL in -``newPySSLSocket()``. The error was reported via a dangling pointer after the -object had already been freed. diff --git a/Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst b/Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst deleted file mode 100644 index 9d603b51c48a93..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-15-12-02-20.gh-issue-144835.w_oS_J.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added missing explanations for some parameters in :func:`glob.glob` and -:func:`glob.iglob`. diff --git a/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst b/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst deleted file mode 100644 index 59a8b4165cdd15..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-17-11-15-17.gh-issue-141510.ZmqEUb.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`json` module now supports the :class:`frozendict` type. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst b/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst deleted file mode 100644 index 5b604124c6d7cc..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-17-11-28-37.gh-issue-141510.OpAz0M.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`copy` module now supports the :class:`frozendict` type. Patch by -Pieter Eendebak based on work by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst b/Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst deleted file mode 100644 index 62c20b7fa06d94..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-18-00-00-00.gh-issue-144809.nYpEUx.rst +++ /dev/null @@ -1 +0,0 @@ -Make :class:`collections.deque` copy atomic in the :term:`free-threaded build`. diff --git a/Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst b/Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst deleted file mode 100644 index fd720bfd3f3da6..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-18-13-45-00.gh-issue-144777.R97q0a.rst +++ /dev/null @@ -1 +0,0 @@ -Fix data races in :class:`io.IncrementalNewlineDecoder` in the :term:`free-threaded build`. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst b/Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst deleted file mode 100644 index 841c3758ec4df1..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-00-00-00.gh-issue-144986.atexit-leak.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a memory leak in :func:`atexit.register`. -Patch by Shamil Abdulaev. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst b/Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst deleted file mode 100644 index 15cf25052bbb46..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-10-57-40.gh-issue-88091.N7qGV-.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :func:`unicodedata.decomposition` for Hangul characters. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst b/Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst deleted file mode 100644 index 4654dd060a6b78..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-15-42-06.gh-issue-134872.sjYX1-.rst +++ /dev/null @@ -1 +0,0 @@ -Add valid import name suggestions on :exc:`ModuleNotFoundError`. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst b/Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst deleted file mode 100644 index cf22e82b8415b8..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-16-26-08.gh-issue-141510.4Qxy8_.rst +++ /dev/null @@ -1,3 +0,0 @@ -``ParameterizedMIMEHeader.params`` of :mod:`email.headerregistry` is now a -:class:`frozendict` instead of a :class:`types.MappingProxyType`. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst b/Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst deleted file mode 100644 index 69052c7ca92c8a..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-17-50-47.gh-issue-145006.9gqA0Q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :exc:`ModuleNotFoundError` hints when a module for a different ABI -exists. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst b/Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst deleted file mode 100644 index ae46ff0cbdd8b1..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-18-02-54.gh-issue-141510.qzvYsO.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`dataclasses.field`: if *metadata* is ``None``, use an empty -:class:`frozendict`, instead of a :func:`~types.MappingProxyType` of an -empty :class:`dict`. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst b/Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst deleted file mode 100644 index 6f496bb30e1686..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-19-20-54-25.gh-issue-145033.X9EBPQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :data:`typing.TypeForm`, implementing :pep:`747`. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst b/Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst deleted file mode 100644 index 68a25262c7d7f7..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-20-13-03-10.gh-issue-66802.OYcAi_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :func:`unicodedata.block` function to return the `Unicode block -`_ of a -character. diff --git a/Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst b/Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst deleted file mode 100644 index 1babcbfd8e678a..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-21-17-34-53.gh-issue-123853.6RUwWh.rst +++ /dev/null @@ -1 +0,0 @@ -Removed Windows 95 compatibility for :func:`locale.getdefaultlocale`. diff --git a/Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst b/Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst deleted file mode 100644 index 60a5e4ad1f0ca4..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-23-20-52-55.gh-issue-145158.vWJtxI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid undefined behaviour from signed integer overflow when parsing format -strings in the :mod:`struct` module. diff --git a/Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst b/Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst deleted file mode 100644 index 4bb230dcb8473f..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-27-18-04-51.gh-issue-76007.17idfK.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``version`` attribute of the :mod:`tarfile` module is deprecated and -slated for removal in Python 3.20. diff --git a/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst b/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst deleted file mode 100644 index 7aeb6a1145ab4c..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-27-19-00-26.gh-issue-145301.2Wih4b.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`hashlib`: fix a crash when the initialization of the underlying C -extension module fails. diff --git a/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst b/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst deleted file mode 100644 index 436ff316b2c327..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-02-28-00-55-00.gh-issue-145301.Lk2bRl.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`hmac`: fix a crash when the initialization of the underlying C -extension module fails. diff --git a/Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst b/Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst deleted file mode 100644 index b6dbda0427181d..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-03-02-19-41-39.gh-issue-145376.OOzSOh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix double free and null pointer dereference in unusual error scenarios -in :mod:`hashlib` and :mod:`hmac` modules. diff --git a/Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst b/Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst deleted file mode 100644 index 53033b06c2fae0..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-03-02-20-08-09.gh-issue-145335.lVTBvd.rst +++ /dev/null @@ -1,5 +0,0 @@ -``os.listdir(-1)`` and ``os.scandir(-1)`` now fail with -``OSError(errno.EBADF)`` rather than listing the current directory. -``os.listxattr(-1)`` now fails with ``OSError(errno.EBADF)`` rather than -listing extended attributes of the current directory. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst b/Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst deleted file mode 100644 index 17d62df72ce1ae..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-03-03-11-49-44.gh-issue-145417.m_HxIL.rst +++ /dev/null @@ -1,4 +0,0 @@ -:mod:`venv`: Prevent incorrect preservation of SELinux context -when copying the ``Activate.ps1`` script. The script inherited -the SELinux security context of the system template directory, -rather than the destination project directory. diff --git a/Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst b/Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst deleted file mode 100644 index 280a7b3632ddae..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-03-05-16-06-09.gh-issue-141510.dFPAQS.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`marshal` now supports :class:`frozendict` objects. The marshal format -version was increased to 6. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst b/Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst deleted file mode 100644 index 15b70d734ca3b9..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-03-05-19-01-28.gh-issue-145551.gItPRl.rst +++ /dev/null @@ -1 +0,0 @@ -Fix InvalidStateError when cancelling process created by :func:`asyncio.create_subprocess_exec` or :func:`asyncio.create_subprocess_shell`. Patch by Daan De Meyer. diff --git a/Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst b/Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst deleted file mode 100644 index 77b43e79e35860..00000000000000 --- a/Misc/NEWS.d/next/Library/2026-03-07-15-00-00.gh-issue-145623.2Y7LzT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix crash in :mod:`struct` when calling :func:`repr` or -``__sizeof__()`` on an uninitialized :class:`struct.Struct` -object created via ``Struct.__new__()`` without calling ``__init__()``. diff --git a/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst b/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst deleted file mode 100644 index 2d13a0611322c5..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst +++ /dev/null @@ -1,2 +0,0 @@ -Disallow usage of control characters in status in :mod:`wsgiref.handlers` to prevent HTTP header injections. -Patch by Benedikt Johannes. diff --git a/Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst b/Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst deleted file mode 100644 index dcdb44d4fae4e5..00000000000000 --- a/Misc/NEWS.d/next/Security/2026-03-04-18-59-17.gh-issue-145506.6hwvEh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes :cve:`2026-2297` by ensuring that ``SourcelessFileLoader`` uses -:func:`io.open_code` when opening ``.pyc`` files. diff --git a/Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst b/Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst deleted file mode 100644 index 8c46ff133f9433..00000000000000 --- a/Misc/NEWS.d/next/Tests/2026-02-12-12-12-00.gh-issue-144739.-fx1tN.rst +++ /dev/null @@ -1,3 +0,0 @@ -When Python was compiled with system expat older then 2.7.2 but tests run -with newer expat, still skip -:class:`!test.test_pyexpat.MemoryProtectionTest`. diff --git a/Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst b/Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst deleted file mode 100644 index be3092f1c2592a..00000000000000 --- a/Misc/NEWS.d/next/Tests/2026-03-04-17-39-15.gh-issue-144741.0RHhBF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``test_frame_pointer_unwind`` when Python is built with -:option:`--enable-shared`. Classify also libpython frames as ``"python"``. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst b/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst deleted file mode 100644 index 810985a352baeb..00000000000000 --- a/Misc/NEWS.d/next/Windows/2026-02-13-11-07-51.gh-issue-144551.ENtMYD.rst +++ /dev/null @@ -1 +0,0 @@ -Updated bundled version of OpenSSL to 3.5.5. diff --git a/Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst b/Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst deleted file mode 100644 index 6f039197962e10..00000000000000 --- a/Misc/NEWS.d/next/Windows/2026-02-27-10-57-20.gh-issue-145307.ueoT7j.rst +++ /dev/null @@ -1,2 +0,0 @@ -Defers loading of the ``psapi.dll`` module until it is used by -:func:`ctypes.util.dllist`. diff --git a/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst b/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst deleted file mode 100644 index 676a68e5a912f5..00000000000000 --- a/Misc/NEWS.d/next/Windows/2026-03-10-09-46-44.gh-issue-145731.5uEGgb.rst +++ /dev/null @@ -1 +0,0 @@ -Fix negative timestamp during DST on Windows. Patch by Hugo van Kemenade. diff --git a/README.rst b/README.rst index 68e114e66abe43..1d2874e9ca4fdc 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.15.0 alpha 6 +This is Python version 3.15.0 alpha 7 ===================================== .. image:: https://github.com/python/cpython/actions/workflows/build.yml/badge.svg?branch=main&event=push From 2d35f9bc1cf61b27639ed992dfbf363ab436fd8b Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Tue, 10 Mar 2026 06:20:42 -0700 Subject: [PATCH 388/498] gh-145492: Fix defaultdict __repr__ infinite recursion (GH-145659) Co-Authored-By: Thomas Kowalski --- Lib/test/test_defaultdict.py | 15 +++++++++++++++ ...2026-03-09-00-00-00.gh-issue-145492.457Afc.rst | 3 +++ Modules/_collectionsmodule.c | 5 +++-- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145492.457Afc.rst diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index fbd7354a915a0a..732e9a876ca8ad 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -204,5 +204,20 @@ def default_factory(): self.assertEqual(test_dict[key], 2) self.assertEqual(count, 2) + def test_repr_recursive_factory(self): + # gh-145492: defaultdict.__repr__ should not cause infinite recursion + # when the factory's __repr__ calls repr() on the defaultdict. + class ProblematicFactory: + def __call__(self): + return {} + def __repr__(self): + repr(dd) + return "ProblematicFactory()" + + dd = defaultdict(ProblematicFactory()) + # Should not raise RecursionError + r = repr(dd) + self.assertIn('ProblematicFactory()', r) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145492.457Afc.rst b/Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145492.457Afc.rst new file mode 100644 index 00000000000000..297ee4099f12c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145492.457Afc.rst @@ -0,0 +1,3 @@ +Fix infinite recursion in :class:`collections.defaultdict` ``__repr__`` +when a ``defaultdict`` contains itself. Based on analysis by KowalskiThomas +in :gh:`145492`. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index c3d63c8aab4b47..15c9aa41911822 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -2385,9 +2385,10 @@ defdict_repr(PyObject *op) } defrepr = PyUnicode_FromString("..."); } - else + else { defrepr = PyObject_Repr(dd->default_factory); - Py_ReprLeave(dd->default_factory); + Py_ReprLeave(dd->default_factory); + } } if (defrepr == NULL) { Py_DECREF(baserepr); From ae0d2875bcfa111383e39d9ba0d24c1c317ee597 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 10 Mar 2026 13:58:32 +0000 Subject: [PATCH 389/498] gh-145035: Allows removing the _pyrepl module to completely disable the modern REPL (GH-145159) --- Lib/_sitebuiltins.py | 12 ++++- Lib/asyncio/__main__.py | 14 ++++-- Lib/pdb.py | 8 ++- Lib/pydoc.py | 49 +++++++++++++------ Lib/site.py | 2 + Lib/test/support/__init__.py | 7 +++ Lib/test/test_pyclbr.py | 3 +- Lib/test/test_pyrepl/__init__.py | 3 ++ Lib/test/test_repl.py | 7 +++ ...-02-23-21-28-12.gh-issue-145035.J5UjS6.rst | 3 ++ Modules/main.c | 48 +++++++++++++----- 11 files changed, 121 insertions(+), 35 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-23-21-28-12.gh-issue-145035.J5UjS6.rst diff --git a/Lib/_sitebuiltins.py b/Lib/_sitebuiltins.py index 81b36efc6c285f..84551e3546eb6e 100644 --- a/Lib/_sitebuiltins.py +++ b/Lib/_sitebuiltins.py @@ -65,7 +65,17 @@ def __repr__(self): return "Type %s() to see the full %s text" % ((self.__name,)*2) def __call__(self): - from _pyrepl.pager import get_pager + try: + from _pyrepl.pager import get_pager + except ModuleNotFoundError: + try: + from pydoc import get_pager + except ModuleNotFoundError: + def get_pager(): + def _print(text, title=None): + print(text) + return _print + self.__setup() pager = get_pager() diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py index 44667efc522556..0bf3bdded40200 100644 --- a/Lib/asyncio/__main__.py +++ b/Lib/asyncio/__main__.py @@ -12,13 +12,16 @@ import types import warnings -from _colorize import get_theme -from _pyrepl.console import InteractiveColoredConsole +try: + from _colorize import get_theme + from _pyrepl.console import InteractiveColoredConsole as InteractiveConsole +except ModuleNotFoundError: + from code import InteractiveConsole from . import futures -class AsyncIOInteractiveConsole(InteractiveColoredConsole): +class AsyncIOInteractiveConsole(InteractiveConsole): def __init__(self, locals, loop): super().__init__(locals, filename="") @@ -185,7 +188,10 @@ def interrupt(self) -> None: if os.getenv('PYTHON_BASIC_REPL'): CAN_USE_PYREPL = False else: - from _pyrepl.main import CAN_USE_PYREPL + try: + from _pyrepl.main import CAN_USE_PYREPL + except ModuleNotFoundError: + CAN_USE_PYREPL = False return_code = 0 loop = asyncio.new_event_loop() diff --git a/Lib/pdb.py b/Lib/pdb.py index b5d8f827827415..7b08d2bb70183d 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -97,12 +97,16 @@ import selectors import threading import _colorize -import _pyrepl.utils from contextlib import ExitStack, closing, contextmanager from types import CodeType from warnings import deprecated +try: + import _pyrepl.utils +except ModuleNotFoundError: + _pyrepl = None + class Restart(Exception): """Causes a debugger to be restarted for the debugged python program.""" @@ -1097,7 +1101,7 @@ def handle_command_def(self, line): return False def _colorize_code(self, code): - if self.colorize: + if self.colorize and _pyrepl: colors = list(_pyrepl.utils.gen_colors(code)) chars, _ = _pyrepl.utils.disp_str(code, colors=colors, force_color=True) code = "".join(chars) diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 69c83e085113c9..a1a6aad434ddf4 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -78,20 +78,41 @@ class or function within a module or module in a package. If the from reprlib import Repr from traceback import format_exception_only -from _pyrepl.pager import (get_pager, pipe_pager, - plain_pager, tempfile_pager, tty_pager) - -# Expose plain() as pydoc.plain() -from _pyrepl.pager import plain # noqa: F401 - - -# --------------------------------------------------------- old names - -getpager = get_pager -pipepager = pipe_pager -plainpager = plain_pager -tempfilepager = tempfile_pager -ttypager = tty_pager +try: + from _pyrepl.pager import (get_pager, pipe_pager, + plain_pager, tempfile_pager, tty_pager) + + # Expose plain() as pydoc.plain() + from _pyrepl.pager import plain # noqa: F401 + + # --------------------------------------------------------- old names + getpager = get_pager + pipepager = pipe_pager + plainpager = plain_pager + tempfilepager = tempfile_pager + ttypager = tty_pager + +except ModuleNotFoundError: + # Minimal alternatives for cases where _pyrepl is absent. + + def plain(text: str) -> str: + """Remove boldface formatting from text.""" + return re.sub('.\b', '', text) + + def plain_pager(text: str, title: str = '') -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8' + text = text.encode(encoding, 'backslashreplace').decode(encoding) + text = plain(text) + sys.stdout.write(text) + + def get_pager(): + """Unconditionally return the plain pager, since _pyrepl is absent.""" + return plain_pager + + # --------------------------------------------------------- old names + getpager = get_pager + plainpager = plain_pager # --------------------------------------------------------- common routines diff --git a/Lib/site.py b/Lib/site.py index 5f09a7dd8c91c0..30015b3f26b4b3 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -529,6 +529,8 @@ def register_readline(): import _pyrepl.unix_console console_errors = _pyrepl.unix_console._error from _pyrepl.main import CAN_USE_PYREPL + except ModuleNotFoundError: + CAN_USE_PYREPL = False finally: sys.path = original_path except ImportError: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d4d3c7f1aefa66..3da662b0c4d50a 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3023,6 +3023,13 @@ def force_color(color: bool): import _colorize from .os_helper import EnvironmentVarGuard + if color: + try: + import _pyrepl # noqa: F401 + except ModuleNotFoundError: + # Can't force enable color without _pyrepl, so just skip. + raise unittest.SkipTest("_pyrepl is missing") + with ( swap_attr(_colorize, "can_colorize", lambda *, file=None: color), EnvironmentVarGuard() as env, diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 79ef178f3807f4..b5ec41b17f793b 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -252,7 +252,8 @@ def test_others(self): ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'curframe_locals', '_InteractState', 'rlcompleter'), ) - cm('pydoc', ignore=('input', 'output',)) # properties + cm('pydoc', ignore=('input', 'output', # properties + 'getpager', 'plainpager', )) # aliases # Tests for modules inside packages cm('email.parser') diff --git a/Lib/test/test_pyrepl/__init__.py b/Lib/test/test_pyrepl/__init__.py index 2f37bff6df8b4a..1534d63352cc55 100644 --- a/Lib/test/test_pyrepl/__init__.py +++ b/Lib/test/test_pyrepl/__init__.py @@ -3,6 +3,9 @@ from test.support import import_helper, load_package_tests +import_helper.import_module("_pyrepl") + + if sys.platform != "win32": import_helper.import_module("termios") diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 40965835bcec00..27cd125078ea69 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -426,6 +426,13 @@ def test_toplevel_contextvars_async(self): p = spawn_asyncio_repl() p.stdin.write(user_input) user_input2 = "async def set_var(): var.set('ok')\n" + try: + import _pyrepl # noqa: F401 + except ModuleNotFoundError: + # If we're going to be forced into the regular REPL, then we need an + # extra newline here. Omit it by default to catch any breakage to + # the new REPL's behavior. + user_input2 += "\n" p.stdin.write(user_input2) user_input3 = "await set_var()\n" p.stdin.write(user_input3) diff --git a/Misc/NEWS.d/next/Library/2026-02-23-21-28-12.gh-issue-145035.J5UjS6.rst b/Misc/NEWS.d/next/Library/2026-02-23-21-28-12.gh-issue-145035.J5UjS6.rst new file mode 100644 index 00000000000000..b20da3b54c0415 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-23-21-28-12.gh-issue-145035.J5UjS6.rst @@ -0,0 +1,3 @@ +Allows omitting the internal library ``_pyrepl`` with limited loss of +functionality. This allows complete removal of the modern REPL, which is an +unsupported configuration, but still desirable for some distributions. diff --git a/Modules/main.c b/Modules/main.c index 95ba541d98c2e8..7731fa0c7c6717 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -562,13 +562,25 @@ pymain_run_stdin(PyConfig *config) return pymain_exit_err_print(); } - if (!isatty(fileno(stdin)) - || _Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) { - PyCompilerFlags cf = _PyCompilerFlags_INIT; - int run = PyRun_AnyFileExFlags(stdin, "", 0, &cf); - return (run != 0); + int run; + if (isatty(fileno(stdin)) + && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) { + PyObject *pyrepl = PyImport_ImportModule("_pyrepl"); + if (pyrepl != NULL) { + run = pymain_start_pyrepl(0); + Py_DECREF(pyrepl); + return run; + } + if (!PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) { + fprintf(stderr, "Could not import _pyrepl.main\n"); + return pymain_exit_err_print(); + } + PyErr_Clear(); } - return pymain_start_pyrepl(0); + + PyCompilerFlags cf = _PyCompilerFlags_INIT; + run = PyRun_AnyFileExFlags(stdin, "", 0, &cf); + return (run != 0); } @@ -594,14 +606,24 @@ pymain_repl(PyConfig *config, int *exitcode) return; } - if (!isatty(fileno(stdin)) - || _Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) { - PyCompilerFlags cf = _PyCompilerFlags_INIT; - int run = PyRun_AnyFileExFlags(stdin, "", 0, &cf); - *exitcode = (run != 0); - return; + if (isatty(fileno(stdin)) + && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) { + PyObject *pyrepl = PyImport_ImportModule("_pyrepl"); + if (pyrepl != NULL) { + int run = pymain_start_pyrepl(1); + *exitcode = (run != 0); + Py_DECREF(pyrepl); + return; + } + if (!PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) { + PyErr_Clear(); + fprintf(stderr, "Could not import _pyrepl.main\n"); + return; + } + PyErr_Clear(); } - int run = pymain_start_pyrepl(1); + PyCompilerFlags cf = _PyCompilerFlags_INIT; + int run = PyRun_AnyFileExFlags(stdin, "", 0, &cf); *exitcode = (run != 0); return; } From 9585f509d796cc3f89e85d4cb9e52e4f10604a01 Mon Sep 17 00:00:00 2001 From: Adorilson Bezerra Date: Tue, 10 Mar 2026 14:19:24 +0000 Subject: [PATCH 390/498] gh-106318: Add examples for str.isspace() docs (#145399) --- Doc/library/stdtypes.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index c930b876b3ccbf..bfa49b62ec5778 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2247,17 +2247,34 @@ expression support in the :mod:`re` module). >>> '\t'.isprintable(), '\n'.isprintable() (False, False) + See also :meth:`isspace`. + .. method:: str.isspace() Return ``True`` if there are only whitespace characters in the string and there is at least one character, ``False`` otherwise. + For example: + + .. doctest:: + + >>> ''.isspace() + False + >>> ' '.isspace() + True + >>> '\t\n'.isspace() # TAB and BREAK LINE + True + >>> '\u3000'.isspace() # IDEOGRAPHIC SPACE + True + A character is *whitespace* if in the Unicode character database (see :mod:`unicodedata`), either its general category is ``Zs`` ("Separator, space"), or its bidirectional class is one of ``WS``, ``B``, or ``S``. + See also :meth:`isprintable`. + .. method:: str.istitle() From 1900aa9d36f49cc3fc6c6e6d50ddc8c64b01f978 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:40:10 +0200 Subject: [PATCH 391/498] Post 3.15.0a7 --- Include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 3cc12a2b2d3888..7cffd74125f1b4 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 7 /* Version as a string */ -#define PY_VERSION "3.15.0a7" +#define PY_VERSION "3.15.0a7+" /*--end constants--*/ From 7990313afa3234d5145b32ead3ef3f6278735f4f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 10 Mar 2026 10:57:13 -0400 Subject: [PATCH 392/498] Docs: Improve the C API documentation involving threads (GH-145520) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/c-api/threads.rst | 210 +++++++++++++++++++++++++----------------- 1 file changed, 125 insertions(+), 85 deletions(-) diff --git a/Doc/c-api/threads.rst b/Doc/c-api/threads.rst index 41c7fbda2302cf..3b761d0c657cbd 100644 --- a/Doc/c-api/threads.rst +++ b/Doc/c-api/threads.rst @@ -10,43 +10,63 @@ Thread states and the global interpreter lock single: interpreter lock single: lock, interpreter -Unless on a :term:`free-threaded ` build of :term:`CPython`, -the Python interpreter is not fully thread-safe. In order to support +Unless on a :term:`free-threaded build` of :term:`CPython`, +the Python interpreter is generally not thread-safe. In order to support multi-threaded Python programs, there's a global lock, called the :term:`global -interpreter lock` or :term:`GIL`, that must be held by the current thread before -it can safely access Python objects. Without the lock, even the simplest -operations could cause problems in a multi-threaded program: for example, when +interpreter lock` or :term:`GIL`, that must be held by a thread before +accessing Python objects. Without the lock, even the simplest operations +could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice. +As such, only a thread that holds the GIL may operate on Python objects or +invoke Python's C API. + .. index:: single: setswitchinterval (in module sys) -Therefore, the rule exists that only the thread that has acquired the -:term:`GIL` may operate on Python objects or call Python/C API functions. -In order to emulate concurrency of execution, the interpreter regularly -tries to switch threads (see :func:`sys.setswitchinterval`). The lock is also -released around potentially blocking I/O operations like reading or writing -a file, so that other Python threads can run in the meantime. +In order to emulate concurrency, the interpreter regularly tries to switch +threads between bytecode instructions (see :func:`sys.setswitchinterval`). +This is why locks are also necessary for thread-safety in pure-Python code. + +Additionally, the global interpreter lock is released around blocking I/O +operations, such as reading or writing to a file. From the C API, this is done +by :ref:`detaching the thread state `. + .. index:: single: PyThreadState (C type) -The Python interpreter keeps some thread-specific bookkeeping information -inside a data structure called :c:type:`PyThreadState`, known as a :term:`thread state`. -Each OS thread has a thread-local pointer to a :c:type:`PyThreadState`; a thread state +The Python interpreter keeps some thread-local information inside +a data structure called :c:type:`PyThreadState`, known as a :term:`thread state`. +Each thread has a thread-local pointer to a :c:type:`PyThreadState`; a thread state referenced by this pointer is considered to be :term:`attached `. A thread can only have one :term:`attached thread state` at a time. An attached -thread state is typically analogous with holding the :term:`GIL`, except on -:term:`free-threaded ` builds. On builds with the :term:`GIL` enabled, -:term:`attaching ` a thread state will block until the :term:`GIL` -can be acquired. However, even on builds with the :term:`GIL` disabled, it is still required -to have an attached thread state to call most of the C API. +thread state is typically analogous with holding the GIL, except on +free-threaded builds. On builds with the GIL enabled, attaching a thread state +will block until the GIL can be acquired. However, even on builds with the GIL +disabled, it is still required to have an attached thread state, as the interpreter +needs to keep track of which threads may access Python objects. + +.. note:: + + Even on the free-threaded build, attaching a thread state may block, as the + GIL can be re-enabled or threads might be temporarily suspended (such as during + a garbage collection). + +Generally, there will always be an attached thread state when using Python's +C API, including during embedding and when implementing methods, so it's uncommon +to need to set up a thread state on your own. Only in some specific cases, such +as in a :c:macro:`Py_BEGIN_ALLOW_THREADS` block or in a fresh thread, will the +thread not have an attached thread state. +If uncertain, check if :c:func:`PyThreadState_GetUnchecked` returns ``NULL``. -In general, there will always be an :term:`attached thread state` when using Python's C API. -Only in some specific cases (such as in a :c:macro:`Py_BEGIN_ALLOW_THREADS` block) will the -thread not have an attached thread state. If uncertain, check if :c:func:`PyThreadState_GetUnchecked` returns -``NULL``. +If it turns out that you do need to create a thread state, call :c:func:`PyThreadState_New` +followed by :c:func:`PyThreadState_Swap`, or use the dangerous +:c:func:`PyGILState_Ensure` function. + + +.. _detaching-thread-state: Detaching the thread state from extension code ---------------------------------------------- @@ -86,28 +106,37 @@ The block above expands to the following code:: Here is how these functions work: -The :term:`attached thread state` holds the :term:`GIL` for the entire interpreter. When detaching -the :term:`attached thread state`, the :term:`GIL` is released, allowing other threads to attach -a thread state to their own thread, thus getting the :term:`GIL` and can start executing. -The pointer to the prior :term:`attached thread state` is stored as a local variable. -Upon reaching :c:macro:`Py_END_ALLOW_THREADS`, the thread state that was -previously :term:`attached ` is passed to :c:func:`PyEval_RestoreThread`. -This function will block until another releases its :term:`thread state `, -thus allowing the old :term:`thread state ` to get re-attached and the -C API can be called again. - -For :term:`free-threaded ` builds, the :term:`GIL` is normally -out of the question, but detaching the :term:`thread state ` is still required -for blocking I/O and long operations. The difference is that threads don't have to wait for the :term:`GIL` -to be released to attach their thread state, allowing true multi-core parallelism. +The attached thread state implies that the GIL is held for the interpreter. +To detach it, :c:func:`PyEval_SaveThread` is called and the result is stored +in a local variable. + +By detaching the thread state, the GIL is released, which allows other threads +to attach to the interpreter and execute while the current thread performs +blocking I/O. When the I/O operation is complete, the old thread state is +reattached by calling :c:func:`PyEval_RestoreThread`, which will wait until +the GIL can be acquired. .. note:: - Calling system I/O functions is the most common use case for detaching - the :term:`thread state `, but it can also be useful before calling - long-running computations which don't need access to Python objects, such - as compression or cryptographic functions operating over memory buffers. + Performing blocking I/O is the most common use case for detaching + the thread state, but it is also useful to call it over long-running + native code that doesn't need access to Python objects or Python's C API. For example, the standard :mod:`zlib` and :mod:`hashlib` modules detach the - :term:`thread state ` when compressing or hashing data. + :term:`thread state ` when compressing or hashing + data. + +On a :term:`free-threaded build`, the :term:`GIL` is usually out of the question, +but **detaching the thread state is still required**, because the interpreter +periodically needs to block all threads to get a consistent view of Python objects +without the risk of race conditions. +For example, CPython currently suspends all threads for a short period of time +while running the garbage collector. + +.. warning:: + + Detaching the thread state can lead to unexpected behavior during interpreter + finalization. See :ref:`cautions-regarding-runtime-finalization` for more + details. + APIs ^^^^ @@ -149,73 +178,84 @@ example usage in the Python source distribution. declaration. -.. _gilstate: - Non-Python created threads -------------------------- When threads are created using the dedicated Python APIs (such as the -:mod:`threading` module), a thread state is automatically associated to them -and the code shown above is therefore correct. However, when threads are -created from C (for example by a third-party library with its own thread -management), they don't hold the :term:`GIL`, because they don't have an -:term:`attached thread state`. +:mod:`threading` module), a thread state is automatically associated with them, +However, when a thread is created from native code (for example, by a +third-party library with its own thread management), it doesn't hold an +attached thread state. If you need to call Python code from these threads (often this will be part of a callback API provided by the aforementioned third-party library), you must first register these threads with the interpreter by -creating an :term:`attached thread state` before you can start using the Python/C -API. When you are done, you should detach the :term:`thread state `, and -finally free it. +creating a new thread state and attaching it. -The :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release` functions do -all of the above automatically. The typical idiom for calling into Python -from a C thread is:: +The most robust way to do this is through :c:func:`PyThreadState_New` followed +by :c:func:`PyThreadState_Swap`. - PyGILState_STATE gstate; - gstate = PyGILState_Ensure(); +.. note:: + ``PyThreadState_New`` requires an argument pointing to the desired + interpreter; such a pointer can be acquired via a call to + :c:func:`PyInterpreterState_Get` from the code where the thread was + created. + +For example:: + + /* The return value of PyInterpreterState_Get() from the + function that created this thread. */ + PyInterpreterState *interp = thread_data->interp; + + /* Create a new thread state for the interpreter. It does not start out + attached. */ + PyThreadState *tstate = PyThreadState_New(interp); + + /* Attach the thread state, which will acquire the GIL. */ + PyThreadState_Swap(tstate); /* Perform Python actions here. */ result = CallSomeFunction(); /* evaluate result or handle exception */ - /* Release the thread. No Python API allowed beyond this point. */ - PyGILState_Release(gstate); + /* Destroy the thread state. No Python API allowed beyond this point. */ + PyThreadState_Clear(tstate); + PyThreadState_DeleteCurrent(); -Note that the ``PyGILState_*`` functions assume there is only one global -interpreter (created automatically by :c:func:`Py_Initialize`). Python -supports the creation of additional interpreters (using -:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the -``PyGILState_*`` API is unsupported. This is because :c:func:`PyGILState_Ensure` -and similar functions default to :term:`attaching ` a -:term:`thread state` for the main interpreter, meaning that the thread can't safely -interact with the calling subinterpreter. +.. warning:: -Supporting subinterpreters in non-Python threads ------------------------------------------------- + If the interpreter finalized before ``PyThreadState_Swap`` was called, then + ``interp`` will be a dangling pointer! -If you would like to support subinterpreters with non-Python created threads, you -must use the ``PyThreadState_*`` API instead of the traditional ``PyGILState_*`` -API. +.. _gilstate: -In particular, you must store the interpreter state from the calling -function and pass it to :c:func:`PyThreadState_New`, which will ensure that -the :term:`thread state` is targeting the correct interpreter:: +Legacy API +---------- - /* The return value of PyInterpreterState_Get() from the - function that created this thread. */ - PyInterpreterState *interp = ThreadData->interp; - PyThreadState *tstate = PyThreadState_New(interp); - PyThreadState_Swap(tstate); +Another common pattern to call Python code from a non-Python thread is to use +:c:func:`PyGILState_Ensure` followed by a call to :c:func:`PyGILState_Release`. - /* GIL of the subinterpreter is now held. - Perform Python actions here. */ +These functions do not work well when multiple interpreters exist in the Python +process. If no Python interpreter has ever been used in the current thread (which +is common for threads created outside Python), ``PyGILState_Ensure`` will create +and attach a thread state for the "main" interpreter (the first interpreter in +the Python process). + +Additionally, these functions have thread-safety issues during interpreter +finalization. Using ``PyGILState_Ensure`` during finalization will likely +crash the process. + +Usage of these functions look like such:: + + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + /* Perform Python actions here. */ result = CallSomeFunction(); /* evaluate result or handle exception */ - /* Destroy the thread state. No Python API allowed beyond this point. */ - PyThreadState_Clear(tstate); - PyThreadState_DeleteCurrent(); + /* Release the thread. No Python API allowed beyond this point. */ + PyGILState_Release(gstate); .. _fork-and-threads: From 467507a651e351712f18fcafad64d1b5eed89b7d Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Tue, 10 Mar 2026 11:21:33 -0400 Subject: [PATCH 393/498] gh-145697: Add `.sql` and `.sqlite3` recognition in `mimetypes` (GH-145698) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Co-authored-by: Benedikt Johannes --- Doc/whatsnew/3.15.rst | 2 ++ Lib/mimetypes.py | 3 +++ Lib/test/test_mimetypes.py | 2 ++ .../Library/2026-03-09-18-33-16.gh-issue-145697.d6hFmm.rst | 1 + 4 files changed, 8 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-03-09-18-33-16.gh-issue-145697.d6hFmm.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index ead4e7cbf2871e..e749ef2a455ea2 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -825,6 +825,8 @@ mimetypes * Add ``application/node`` MIME type for ``.cjs`` extension. (Contributed by John Franey in :gh:`140937`.) * Add ``application/toml``. (Contributed by Gil Forcada in :gh:`139959`.) +* Add ``application/sql`` and ``application/vnd.sqlite3``. + (Contributed by Charlie Lin in :gh:`145698`.) * Add ``image/jxl``. (Contributed by Foolbar in :gh:`144213`.) * Rename ``application/x-texinfo`` to ``application/texinfo``. (Contributed by Charlie Lin in :gh:`140165`.) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index fc916c470a0110..ee66160be63b6f 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -501,6 +501,7 @@ def _default_mime_types(): '.ps' : 'application/postscript', '.eps' : 'application/postscript', '.rtf' : 'application/rtf', + '.sql' : 'application/sql', '.texi' : 'application/texinfo', '.texinfo': 'application/texinfo', '.toml' : 'application/toml', @@ -525,6 +526,8 @@ def _default_mime_types(): '.xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', '.docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', '.rar' : 'application/vnd.rar', + '.sqlite3': 'application/vnd.sqlite3', + '.sqlite' : 'application/vnd.sqlite3', '.wasm' : 'application/wasm', '.7z' : 'application/x-7z-compressed', '.bcpio' : 'application/x-bcpio', diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index fe7584f1f9d3b3..2d618081521e10 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -232,6 +232,7 @@ def check_extensions(): ("application/pdf", ".pdf"), ("application/postscript", ".ps"), ("application/rtf", ".rtf"), + ("application/sql", ".sql"), ("application/texinfo", ".texi"), ("application/toml", ".toml"), ("application/vnd.apple.mpegurl", ".m3u"), @@ -246,6 +247,7 @@ def check_extensions(): ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx"), ("application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx"), ("application/vnd.rar", ".rar"), + ("application/vnd.sqlite3", ".sqlite3"), ("application/x-7z-compressed", ".7z"), ("application/x-debian-package", ".deb"), ("application/x-httpd-php", ".php"), diff --git a/Misc/NEWS.d/next/Library/2026-03-09-18-33-16.gh-issue-145697.d6hFmm.rst b/Misc/NEWS.d/next/Library/2026-03-09-18-33-16.gh-issue-145697.d6hFmm.rst new file mode 100644 index 00000000000000..c3a476df75f136 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-09-18-33-16.gh-issue-145697.d6hFmm.rst @@ -0,0 +1 @@ +Add ``application/sql`` and ``application/vnd.sqlite3`` into ``mimetypes``. From 2114da976c3d85a85283d1a9437bdf8604626be8 Mon Sep 17 00:00:00 2001 From: Ali Towaiji <145403626+Towaiji@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:48:41 -0400 Subject: [PATCH 394/498] gh-145591: Move slicing note to __getitem__ (GH-145606) --- Doc/reference/datamodel.rst | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index cf5a0e71a104eb..062d301f6286f7 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -3223,21 +3223,6 @@ through the object's keys; for sequences, it should iterate through the values. .. versionadded:: 3.4 -.. index:: pair: object; slice - -.. note:: - - Slicing is done exclusively with the following three methods. A call like :: - - a[1:2] = b - - is translated to :: - - a[slice(1, 2, None)] = b - - and so forth. Missing slice items are always filled in with ``None``. - - .. method:: object.__getitem__(self, subscript) Called to implement *subscription*, that is, ``self[subscript]``. @@ -3260,6 +3245,22 @@ through the object's keys; for sequences, it should iterate through the values. should raise an :exc:`LookupError` or one of its subclasses (:exc:`IndexError` for sequences; :exc:`KeyError` for mappings). + .. index:: pair: object; slice + + .. note:: + + Slicing is handled by :meth:`!__getitem__`, :meth:`~object.__setitem__`, + and :meth:`~object.__delitem__`. + A call like :: + + a[1:2] = b + + is translated to :: + + a[slice(1, 2, None)] = b + + and so forth. Missing slice items are always filled in with ``None``. + .. note:: The sequence iteration protocol (used, for example, in :keyword:`for` From 2756d56eefe86c4df696d8c65e21e4583ffe7511 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Tue, 10 Mar 2026 19:02:57 +0300 Subject: [PATCH 395/498] gh-85277: Fix building without `stropts.h` or empty `stropts.h` (#143521) --- ...6-01-08-22-27-07.gh-issue-85277.TotySi.rst | 1 + Modules/posixmodule.c | 4 +- configure | 296 +++++++++--------- configure.ac | 12 +- 4 files changed, 167 insertions(+), 146 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-01-08-22-27-07.gh-issue-85277.TotySi.rst diff --git a/Misc/NEWS.d/next/Build/2026-01-08-22-27-07.gh-issue-85277.TotySi.rst b/Misc/NEWS.d/next/Build/2026-01-08-22-27-07.gh-issue-85277.TotySi.rst new file mode 100644 index 00000000000000..538995538d7da8 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-01-08-22-27-07.gh-issue-85277.TotySi.rst @@ -0,0 +1 @@ +Fix building without ``stropts.h`` or empty ``stropts.h`` diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index aa3d682a19bc9c..8c360ce3b79b8a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9397,13 +9397,13 @@ os_openpty_impl(PyObject *module) if (_Py_set_inheritable(master_fd, 0, NULL) < 0) goto posix_error; -#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC) +#if defined(HAVE_STROPTS_H) && !defined(HAVE_DEV_PTC) ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ #ifndef __hpux ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ #endif /* __hpux */ -#endif /* HAVE_CYGWIN */ +#endif /* defined(HAVE_STROPTS_H) && !defined(HAVE_DEV_PTC) */ #endif /* HAVE_OPENPTY */ return Py_BuildValue("(ii)", master_fd, slave_fd); diff --git a/configure b/configure index eca5f03cdcfb2d..95bb6ba4e84ccf 100755 --- a/configure +++ b/configure @@ -2340,6 +2340,60 @@ fi } # ac_fn_c_try_run +# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR +# ------------------------------------------------------------------ +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. +ac_fn_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +printf %s "checking whether $as_decl_name is declared... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + eval ac_save_FLAGS=\$$6 + as_fn_append $6 " $5" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else case e in #( + e) eval "$3=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + eval $6=\$ac_save_FLAGS + ;; +esac +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_check_decl + # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -2658,60 +2712,6 @@ printf "%s\n" "$ac_res" >&6; } } # ac_fn_c_check_func -# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR -# ------------------------------------------------------------------ -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. -ac_fn_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -printf %s "checking whether $as_decl_name is declared... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - eval ac_save_FLAGS=\$$6 - as_fn_append $6 " $5" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$3=yes" -else case e in #( - e) eval "$3=no" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - eval $6=\$ac_save_FLAGS - ;; -esac -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_check_decl - # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including @@ -11461,12 +11461,6 @@ if test "x$ac_cv_header_spawn_h" = xyes then : printf "%s\n" "#define HAVE_SPAWN_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "stropts.h" "ac_cv_header_stropts_h" "$ac_includes_default" -if test "x$ac_cv_header_stropts_h" = xyes -then : - printf "%s\n" "#define HAVE_STROPTS_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "sys/audioio.h" "ac_cv_header_sys_audioio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_audioio_h" = xyes @@ -11951,6 +11945,105 @@ fi fi +# On Linux, stropts.h may be empty +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 +printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } +if test ${ac_cv_c_undeclared_builtin_options+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) ac_save_CFLAGS=$CFLAGS + ac_cv_c_undeclared_builtin_options='cannot detect' + for ac_arg in '' -fno-builtin; do + CFLAGS="$ac_save_CFLAGS $ac_arg" + # This test program should *not* compile successfully. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +(void) strchr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else case e in #( + e) # This test program should compile successfully. + # No library function is consistently available on + # freestanding implementations, so test against a dummy + # declaration. Include always-available headers on the + # off chance that they somehow elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +extern void ac_decl (int, char *); + +int +main (void) +{ +(void) ac_decl (0, (char *) 0); + (void) ac_decl; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if test x"$ac_arg" = x +then : + ac_cv_c_undeclared_builtin_options='none needed' +else case e in #( + e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; +esac +fi + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + CFLAGS=$ac_save_CFLAGS + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 +printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } + case $ac_cv_c_undeclared_builtin_options in #( + 'cannot detect') : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "cannot make $CC report undeclared builtins +See 'config.log' for more details" "$LINENO" 5; } ;; #( + 'none needed') : + ac_c_undeclared_builtin_options='' ;; #( + *) : + ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; +esac + +ac_fn_check_decl "$LINENO" "I_PUSH" "ac_cv_have_decl_I_PUSH" " + #ifdef HAVE_SYS_TYPES_H + # include + #endif + #include + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_I_PUSH" = xyes +then : + + +printf "%s\n" "#define HAVE_STROPTS_H 1" >>confdefs.h + +fi + # bluetooth/bluetooth.h has been known to not compile with -std=c99. # http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 SAVE_CFLAGS=$CFLAGS @@ -20608,89 +20701,6 @@ fi fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 -printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } -if test ${ac_cv_c_undeclared_builtin_options+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) ac_save_CFLAGS=$CFLAGS - ac_cv_c_undeclared_builtin_options='cannot detect' - for ac_arg in '' -fno-builtin; do - CFLAGS="$ac_save_CFLAGS $ac_arg" - # This test program should *not* compile successfully. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ -(void) strchr; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else case e in #( - e) # This test program should compile successfully. - # No library function is consistently available on - # freestanding implementations, so test against a dummy - # declaration. Include always-available headers on the - # off chance that they somehow elicit warnings. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -extern void ac_decl (int, char *); - -int -main (void) -{ -(void) ac_decl (0, (char *) 0); - (void) ac_decl; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - if test x"$ac_arg" = x -then : - ac_cv_c_undeclared_builtin_options='none needed' -else case e in #( - e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; -esac -fi - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - done - CFLAGS=$ac_save_CFLAGS - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 -printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } - case $ac_cv_c_undeclared_builtin_options in #( - 'cannot detect') : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} -as_fn_error $? "cannot make $CC report undeclared builtins -See 'config.log' for more details" "$LINENO" 5; } ;; #( - 'none needed') : - ac_c_undeclared_builtin_options='' ;; #( - *) : - ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; -esac - ac_fn_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include #include " "$ac_c_undeclared_builtin_options" "CFLAGS" diff --git a/configure.ac b/configure.ac index c21024a1e77433..e049f568417335 100644 --- a/configure.ac +++ b/configure.ac @@ -3011,7 +3011,7 @@ AC_CHECK_HEADERS([ \ io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ linux/netfilter_ipv4.h linux/random.h linux/soundcard.h linux/sched.h \ linux/tipc.h linux/wait.h netdb.h net/ethernet.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 \ + sched.h setjmp.h shadow.h signal.h spawn.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 \ sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/pidfd.h sys/poll.h \ sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ @@ -3022,6 +3022,16 @@ AC_CHECK_HEADERS([ \ AC_HEADER_DIRENT AC_HEADER_MAJOR +# On Linux, stropts.h may be empty +AC_CHECK_DECL([I_PUSH], [ + AC_DEFINE([HAVE_STROPTS_H], [1], + [Define to 1 if you have the header file.])], [], [ + #ifdef HAVE_SYS_TYPES_H + # include + #endif + #include +]) + # bluetooth/bluetooth.h has been known to not compile with -std=c99. # http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 SAVE_CFLAGS=$CFLAGS From bf4017b16149ba17d723abacfe93aec79b2235fe Mon Sep 17 00:00:00 2001 From: Farhan Saif Date: Tue, 10 Mar 2026 11:23:39 -0500 Subject: [PATCH 396/498] gh-125053: Document that ob_mutex must only be used via critical section API (#144599) Add a warning in the free-threading extensions howto explaining that PyObject.ob_mutex is reserved for the critical section API and must not be locked directly with PyMutex_Lock, as this can cause deadlocks. Extension authors who need their own lock should add a separate PyMutex field to their object struct. Also add an ob_mutex member entry under PyObject in the C API reference (Doc/c-api/structures.rst) with a cross-reference to the howto. Co-authored-by: Victor Stinner --- Doc/c-api/structures.rst | 13 +++++++++++++ Doc/howto/free-threading-extensions.rst | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 70c4de543b7d00..c0d2663adefc6b 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -48,6 +48,19 @@ under :ref:`reference counting `. Do not use this field directly; use :c:macro:`Py_TYPE` and :c:func:`Py_SET_TYPE` instead. + .. c:member:: PyMutex ob_mutex + + A :ref:`per-object lock `, present only in the :term:`free-threaded ` + build (when :c:macro:`Py_GIL_DISABLED` is defined). + + This field is **reserved for use by the critical section API** + (:c:macro:`Py_BEGIN_CRITICAL_SECTION` / :c:macro:`Py_END_CRITICAL_SECTION`). + Do **not** lock it directly with ``PyMutex_Lock``; doing so can cause + deadlocks. If you need your own lock, add a separate :c:type:`PyMutex` + field to your object struct. + + .. versionadded:: 3.13 + .. c:type:: PyVarObject diff --git a/Doc/howto/free-threading-extensions.rst b/Doc/howto/free-threading-extensions.rst index 83eba8cfea3969..2f089a3d89680a 100644 --- a/Doc/howto/free-threading-extensions.rst +++ b/Doc/howto/free-threading-extensions.rst @@ -384,6 +384,30 @@ Important Considerations internal extension state, standard mutexes or other synchronization primitives might be more appropriate. +.. _per-object-locks: + +Per-Object Locks (``ob_mutex``) +............................... + +In the free-threaded build, each Python object contains a :c:member:`~PyObject.ob_mutex` +field of type :c:type:`PyMutex`. This mutex is **reserved for use by the +critical section API** (:c:macro:`Py_BEGIN_CRITICAL_SECTION` / +:c:macro:`Py_END_CRITICAL_SECTION`). + +.. warning:: + + Do **not** lock ``ob_mutex`` directly with ``PyMutex_Lock(&obj->ob_mutex)``. + Mixing direct ``PyMutex_Lock`` calls with the critical section API on the + same mutex can cause deadlocks. + +Even if your own code never uses critical sections on a particular object type, +**CPython internals may use the critical section API on any Python object**. + +If your extension type needs its own lock, add a separate :c:type:`PyMutex` +field (or another synchronization primitive) to your object struct. +:c:type:`PyMutex` is very lightweight, so there is negligible cost to having +an additional one. + Building Extensions for the Free-Threaded Build =============================================== From 3f33bf83e8496737b86333bc9ec55dc3ccb3faca Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 10 Mar 2026 18:29:23 +0200 Subject: [PATCH 397/498] gh-145743: Fix inconsistency after calling Struct.__init__() with invalid format (GH-145744) Only set the format attribute after successful (re-)initialization. --- Lib/test/test_struct.py | 20 ++++++++++++++++++-- Modules/_struct.c | 29 +++++++++++++++-------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 4cbfd7ad8b1e48..6904572d095d31 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -584,8 +584,24 @@ def test_Struct_reinitialization(self): # Issue 9422: there was a memory leak when reinitializing a # Struct instance. This test can be used to detect the leak # when running with regrtest -L. - s = struct.Struct('i') - s.__init__('ii') + s = struct.Struct('>h') + s.__init__('>hh') + self.assertEqual(s.format, '>hh') + packed = b'\x00\x01\x00\x02' + self.assertEqual(s.pack(1, 2), packed) + self.assertEqual(s.unpack(packed), (1, 2)) + + with self.assertRaises(UnicodeEncodeError): + s.__init__('\udc00') + self.assertEqual(s.format, '>hh') + self.assertEqual(s.pack(1, 2), packed) + self.assertEqual(s.unpack(packed), (1, 2)) + + with self.assertRaises(struct.error): + s.__init__('$') + self.assertEqual(s.format, '>hh') + self.assertEqual(s.pack(1, 2), packed) + self.assertEqual(s.unpack(packed), (1, 2)) def check_sizeof(self, format_str, number_of_codes): # The size of 'PyStructObject' diff --git a/Modules/_struct.c b/Modules/_struct.c index dcc3c7ec63e9e0..c2f7b1fe0e800a 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1620,11 +1620,11 @@ align(Py_ssize_t size, char c, const formatdef *e) /* calculate the size of a format string */ static int -prepare_s(PyStructObject *self) +prepare_s(PyStructObject *self, PyObject *format) { const formatdef *f; const formatdef *e; - formatcode *codes; + formatcode *codes, *codes0; const char *s; const char *fmt; @@ -1634,8 +1634,8 @@ prepare_s(PyStructObject *self) _structmodulestate *state = get_struct_state_structinst(self); - fmt = PyBytes_AS_STRING(self->s_format); - if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) { + fmt = PyBytes_AS_STRING(format); + if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(format)) { PyErr_SetString(state->StructError, "embedded null character"); return -1; @@ -1711,13 +1711,7 @@ prepare_s(PyStructObject *self) PyErr_NoMemory(); return -1; } - /* Free any s_codes value left over from a previous initialization. */ - if (self->s_codes != NULL) - PyMem_Free(self->s_codes); - self->s_codes = codes; - self->s_size = size; - self->s_len = len; - + codes0 = codes; s = fmt; size = 0; while ((c = *s++) != '\0') { @@ -1757,6 +1751,14 @@ prepare_s(PyStructObject *self) codes->size = 0; codes->repeat = 0; + /* Free any s_codes value left over from a previous initialization. */ + if (self->s_codes != NULL) + PyMem_Free(self->s_codes); + self->s_codes = codes0; + self->s_size = size; + self->s_len = len; + Py_XSETREF(self->s_format, Py_NewRef(format)); + return 0; overflow: @@ -1820,9 +1822,8 @@ Struct___init___impl(PyStructObject *self, PyObject *format) return -1; } - Py_SETREF(self->s_format, format); - - ret = prepare_s(self); + ret = prepare_s(self, format); + Py_DECREF(format); return ret; } From 9e0802330caca51fed7fc0c8c1dcce2daf03d8bd Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Tue, 10 Mar 2026 12:30:11 -0400 Subject: [PATCH 398/498] gh-145036: Fix data race for list capacity in free-threading (#145365) Co-authored-by: Kumar Aditya --- Lib/test/test_free_threading/test_list.py | 21 +++++++++++++++++++ ...-02-28-18-42-36.gh-issue-145036.70Kbfz.rst | 1 + Objects/listobject.c | 10 +++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-18-42-36.gh-issue-145036.70Kbfz.rst diff --git a/Lib/test/test_free_threading/test_list.py b/Lib/test/test_free_threading/test_list.py index 27ddc9c2d26dfb..0ede4df103f728 100644 --- a/Lib/test/test_free_threading/test_list.py +++ b/Lib/test/test_free_threading/test_list.py @@ -149,6 +149,27 @@ def reader_list(b, l): with threading_helper.start_threads(threads): pass + # gh-145036: race condition with list.__sizeof__() + def test_list_sizeof_free_threaded_build(self): + L = [] + + def mutate_function(): + for _ in range(100): + L.append(1) + L.pop() + + def size_function(): + for _ in range(100): + L.__sizeof__() + + threads = [] + for _ in range(4): + threads.append(Thread(target=mutate_function)) + threads.append(Thread(target=size_function)) + + with threading_helper.start_threads(threads): + pass + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-18-42-36.gh-issue-145036.70Kbfz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-18-42-36.gh-issue-145036.70Kbfz.rst new file mode 100644 index 00000000000000..2a565c1d02bc2e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-28-18-42-36.gh-issue-145036.70Kbfz.rst @@ -0,0 +1 @@ +In free-threaded build, fix race condition when calling :meth:`!__sizeof__` on a :class:`list` diff --git a/Objects/listobject.c b/Objects/listobject.c index 7fc21907fefd31..62d04ab150a77a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3582,8 +3582,14 @@ list___sizeof___impl(PyListObject *self) /*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/ { size_t res = _PyObject_SIZE(Py_TYPE(self)); - Py_ssize_t allocated = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->allocated); - res += (size_t)allocated * sizeof(void*); +#ifdef Py_GIL_DISABLED + PyObject **ob_item = _Py_atomic_load_ptr(&self->ob_item); + if (ob_item != NULL) { + res += list_capacity(ob_item) * sizeof(PyObject *); + } +#else + res += (size_t)self->allocated * sizeof(PyObject *); +#endif return PyLong_FromSize_t(res); } From 50f82d062b3b59a09d6b63648df22d46f7f2b010 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Tue, 10 Mar 2026 17:33:56 +0100 Subject: [PATCH 399/498] gh-145044: avoid calling `Py_DECREF` in `unsafe_object_compare` on immortal objects (#145045) --- Objects/listobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 62d04ab150a77a..1fcedd3a28c91b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2795,11 +2795,12 @@ unsafe_object_compare(PyObject *v, PyObject *w, MergeState *ms) if (PyBool_Check(res_obj)) { res = (res_obj == Py_True); + assert(_Py_IsImmortal(res_obj)); } else { res = PyObject_IsTrue(res_obj); + Py_DECREF(res_obj); } - Py_DECREF(res_obj); /* Note that we can't assert * res == PyObject_RichCompareBool(v, w, Py_LT); From c4333a12708a917d1cfb6418c04be45793ecc392 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 10 Mar 2026 19:40:51 +0300 Subject: [PATCH 400/498] gh-144173: fix flaky test_complex.test_truediv() (#144355) Previously, component-wise relative error bound was tested. However, such bound can't exist already for complex multiplication as one can be used to perform subtraction of floating-point numbers, e.g. x and y for z0=1+1j and z1=x+yj. ```pycon >>> x, y = 1e-9+1j, 1+1j >>> a = x*y*y.conjugate()/2;a (1.0000000272292198e-09+1j) >>> b = x*(y*y.conjugate()/2);b (1e-09+1j) >>> b == x True >>> (a.real-b.real)/math.ulp(b.real) 131672427.0 ``` --- Lib/test/test_complex.py | 41 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 0c7e7341f13d4e..bee2aceb187027 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -72,8 +72,8 @@ def assertAlmostEqual(self, a, b): else: unittest.TestCase.assertAlmostEqual(self, a, b) - def assertCloseAbs(self, x, y, eps=1e-9): - """Return true iff floats x and y "are close".""" + def assertClose(self, x, y, eps=1e-9): + """Return true iff complexes x and y "are close".""" # put the one with larger magnitude second if abs(x) > abs(y): x, y = y, x @@ -82,26 +82,15 @@ def assertCloseAbs(self, x, y, eps=1e-9): if x == 0: return abs(y) < eps # check that relative difference < eps - self.assertTrue(abs((x-y)/y) < eps) - - def assertClose(self, x, y, eps=1e-9): - """Return true iff complexes x and y "are close".""" - self.assertCloseAbs(x.real, y.real, eps) - self.assertCloseAbs(x.imag, y.imag, eps) + self.assertTrue(abs(x-y)/abs(y) < eps) def check_div(self, x, y): """Compute complex z=x*y, and check that z/x==y and z/y==x.""" z = x * y - if x != 0: - q = z / x - self.assertClose(q, y) - q = z.__truediv__(x) - self.assertClose(q, y) - if y != 0: - q = z / y - self.assertClose(q, x) - q = z.__truediv__(y) - self.assertClose(q, x) + if x: + self.assertClose(z / x, y) + if y: + self.assertClose(z / y, x) def test_truediv(self): simple_real = [float(i) for i in range(-5, 6)] @@ -115,10 +104,20 @@ def test_truediv(self): self.check_div(complex(1e200, 1e200), 1+0j) self.check_div(complex(1e-200, 1e-200), 1+0j) + # Smith's algorithm has several sources of inaccuracy + # for components of the result. In examples below, + # it's cancellation of digits in computation of sum. + self.check_div(1e-09+1j, 1+1j) + self.check_div(8.289760544677449e-09+0.13257307440728516j, + 0.9059966714925808+0.5054864708672686j) + # Just for fun. for i in range(100): - self.check_div(complex(random(), random()), - complex(random(), random())) + x = complex(random(), random()) + y = complex(random(), random()) + self.check_div(x, y) + y = complex(1e10*y.real, y.imag) + self.check_div(x, y) self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) self.assertRaises(TypeError, operator.truediv, 1j, None) @@ -454,7 +453,7 @@ def test_boolcontext(self): self.assertTrue(1j) def test_conjugate(self): - self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) + self.assertEqual(complex(5.3, 9.8).conjugate(), 5.3-9.8j) def test_constructor(self): def check(z, x, y): From f26eca7732ca9d0e6893e3fdfdfd4c25339c7155 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 10 Mar 2026 12:47:12 -0400 Subject: [PATCH 401/498] gh-145685: Update find_name_in_mro() to return a _PyStackRef (gh-145693) --- Objects/typeobject.c | 80 +++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 81abb0990eebe9..5dc96bf251b384 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5978,15 +5978,16 @@ PyObject_GetItemData(PyObject *obj) } /* Internal API to look for a name through the MRO, bypassing the method cache. - This returns a borrowed reference, and might set an exception. - 'error' is set to: -1: error with exception; 1: error without exception; 0: ok */ -static PyObject * -find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) + The result is stored as a _PyStackRef in `out`. It never set an exception. + Returns -1 if there was an error, 0 if the name was not found, and 1 if + the name was found. */ +static int +find_name_in_mro(PyTypeObject *type, PyObject *name, _PyStackRef *out) { Py_hash_t hash = _PyObject_HashFast(name); if (hash == -1) { - *error = -1; - return NULL; + PyErr_Clear(); + return -1; } /* Look in tp_dict of types in MRO */ @@ -5994,37 +5995,42 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) if (mro == NULL) { if (!is_readying(type)) { if (PyType_Ready(type) < 0) { - *error = -1; - return NULL; + PyErr_Clear(); + return -1; } mro = lookup_tp_mro(type); } if (mro == NULL) { - *error = 1; - return NULL; + return -1; } } - PyObject *res = NULL; + int res = 0; + PyThreadState *tstate = _PyThreadState_GET(); /* Keep a strong reference to mro because type->tp_mro can be replaced during dict lookup, e.g. when comparing to non-string keys. */ - Py_INCREF(mro); + _PyCStackRef mro_ref; + _PyThreadState_PushCStackRef(tstate, &mro_ref); + mro_ref.ref = PyStackRef_FromPyObjectNew(mro); Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { PyObject *base = PyTuple_GET_ITEM(mro, i); PyObject *dict = lookup_tp_dict(_PyType_CAST(base)); assert(dict && PyDict_Check(dict)); - if (_PyDict_GetItemRef_KnownHash((PyDictObject *)dict, name, hash, &res) < 0) { - *error = -1; + Py_ssize_t ix = _Py_dict_lookup_threadsafe_stackref( + (PyDictObject *)dict, name, hash, out); + if (ix == DKIX_ERROR) { + PyErr_Clear(); + res = -1; goto done; } - if (res != NULL) { + if (!PyStackRef_IsNull(*out)) { + res = 1; break; } } - *error = 0; done: - Py_DECREF(mro); + _PyThreadState_PopCStackRef(tstate, &mro_ref); return res; } @@ -6179,11 +6185,11 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef // We need to atomically do the lookup and capture the version before // anyone else can modify our mro or mutate the type. - PyObject *res; - int error; + int res; PyInterpreterState *interp = _PyInterpreterState_GET(); int has_version = 0; unsigned int assigned_version = 0; + BEGIN_TYPE_LOCK(); // We must assign the version before doing the lookup. If // find_name_in_mro() blocks and releases the critical section @@ -6192,35 +6198,24 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef has_version = assign_version_tag(interp, type); assigned_version = type->tp_version_tag; } - res = find_name_in_mro(type, name, &error); + res = find_name_in_mro(type, name, out); END_TYPE_LOCK(); /* Only put NULL results into cache if there was no error. */ - if (error) { - /* It's not ideal to clear the error condition, - but this function is documented as not setting - an exception, and I don't want to change that. - E.g., when PyType_Ready() can't proceed, it won't - set the "ready" flag, so future attempts to ready - the same type will call it again -- hopefully - in a context that propagates the exception out. - */ - if (error == -1) { - PyErr_Clear(); - } + if (res < 0) { *out = PyStackRef_NULL; return 0; } if (has_version) { + PyObject *res_obj = PyStackRef_AsPyObjectBorrow(*out); #if Py_GIL_DISABLED - update_cache_gil_disabled(entry, name, assigned_version, res); + update_cache_gil_disabled(entry, name, assigned_version, res_obj); #else - PyObject *old_value = update_cache(entry, name, assigned_version, res); + PyObject *old_value = update_cache(entry, name, assigned_version, res_obj); Py_DECREF(old_value); #endif } - *out = res ? PyStackRef_FromPyObjectSteal(res) : PyStackRef_NULL; return has_version ? assigned_version : 0; } @@ -11709,7 +11704,6 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p, int use_generic = 0; int offset = p->offset; - int error; void **ptr = slotptr(type, offset); if (ptr == NULL) { @@ -11725,19 +11719,15 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p, assert(!PyErr_Occurred()); do { /* Use faster uncached lookup as we won't get any cache hits during type setup. */ - descr = find_name_in_mro(type, p->name_strobj, &error); - if (descr == NULL) { - if (error == -1) { - /* It is unlikely but not impossible that there has been an exception - during lookup. Since this function originally expected no errors, - we ignore them here in order to keep up the interface. */ - PyErr_Clear(); - } + _PyStackRef descr_ref; + int res = find_name_in_mro(type, p->name_strobj, &descr_ref); + if (res <= 0) { if (ptr == (void**)&type->tp_iternext) { specific = (void *)_PyObject_NextNotImplemented; } continue; } + descr = PyStackRef_AsPyObjectBorrow(descr_ref); if (Py_IS_TYPE(descr, &PyWrapperDescr_Type) && ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) { void **tptr; @@ -11815,7 +11805,7 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p, } } } - Py_DECREF(descr); + PyStackRef_CLOSE(descr_ref); } while ((++p)->offset == offset); void *slot_value; From 9c1c71066e34b11649735e8acb4765a85c76336f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 10 Mar 2026 12:55:29 -0400 Subject: [PATCH 402/498] gh-145010: Fix Python.h compilation with -masm=intel (#145011) --- Include/object.h | 6 +++--- Lib/test/test_cppext/__init__.py | 20 ++++++++++++++++--- Lib/test/test_cppext/setup.py | 4 ++++ ...-02-19-18-39-11.gh-issue-145010.mKzjci.rst | 2 ++ 4 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-02-19-18-39-11.gh-issue-145010.mKzjci.rst diff --git a/Include/object.h b/Include/object.h index ad452be8405671..3fb28035a50547 100644 --- a/Include/object.h +++ b/Include/object.h @@ -206,11 +206,11 @@ _Py_ThreadId(void) #elif defined(__MINGW32__) && defined(_M_ARM64) tid = __getReg(18); #elif defined(__i386__) - __asm__("movl %%gs:0, %0" : "=r" (tid)); // 32-bit always uses GS + __asm__("{movl %%gs:0, %0|mov %0, dword ptr gs:[0]}" : "=r" (tid)); // 32-bit always uses GS #elif defined(__MACH__) && defined(__x86_64__) - __asm__("movq %%gs:0, %0" : "=r" (tid)); // x86_64 macOSX uses GS + __asm__("{movq %%gs:0, %0|mov %0, qword ptr gs:[0]}" : "=r" (tid)); // x86_64 macOSX uses GS #elif defined(__x86_64__) - __asm__("movq %%fs:0, %0" : "=r" (tid)); // x86_64 Linux, BSD uses FS + __asm__("{movq %%fs:0, %0|mov %0, qword ptr fs:[0]}" : "=r" (tid)); // x86_64 Linux, BSD uses FS #elif defined(__arm__) && __ARM_ARCH >= 7 __asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid)); #elif defined(__aarch64__) && defined(__APPLE__) diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py index 1fd01702f64029..5b4c97c181bb6a 100644 --- a/Lib/test/test_cppext/__init__.py +++ b/Lib/test/test_cppext/__init__.py @@ -1,6 +1,7 @@ # gh-91321: Build a basic C++ test extension to check that the Python C API is # compatible with C++ and does not emit C++ compiler warnings. import os.path +import platform import shlex import shutil import subprocess @@ -28,13 +29,16 @@ class BaseTests: TEST_INTERNAL_C_API = False - def check_build(self, extension_name, std=None, limited=False): + def check_build(self, extension_name, std=None, limited=False, + extra_cflags=None): venv_dir = 'env' with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: self._check_build(extension_name, python_exe, - std=std, limited=limited) + std=std, limited=limited, + extra_cflags=extra_cflags) - def _check_build(self, extension_name, python_exe, std, limited): + def _check_build(self, extension_name, python_exe, std, limited, + extra_cflags=None): pkg_dir = 'pkg' os.mkdir(pkg_dir) shutil.copy(SETUP, os.path.join(pkg_dir, os.path.basename(SETUP))) @@ -48,6 +52,8 @@ def run_cmd(operation, cmd): env['CPYTHON_TEST_LIMITED'] = '1' env['CPYTHON_TEST_EXT_NAME'] = extension_name env['TEST_INTERNAL_C_API'] = str(int(self.TEST_INTERNAL_C_API)) + if extra_cflags: + env['CPYTHON_TEST_EXTRA_CFLAGS'] = extra_cflags if support.verbose: print('Run:', ' '.join(map(shlex.quote, cmd))) subprocess.run(cmd, check=True, env=env) @@ -116,6 +122,14 @@ def test_build_cpp11(self): def test_build_cpp14(self): self.check_build('_testcpp14ext', std='c++14') + # Test that headers compile with Intel asm syntax, which may conflict + # with inline assembly in free-threading headers that use AT&T syntax. + @unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support -masm=intel") + @unittest.skipUnless(platform.machine() in ('x86_64', 'i686', 'AMD64'), + "x86-specific flag") + def test_build_intel_asm(self): + self.check_build('_testcppext_asm', extra_cflags='-masm=intel') + class TestInteralCAPI(BaseTests, unittest.TestCase): TEST_INTERNAL_C_API = True diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py index 2d9052a6b879da..14aeafefcaa8f7 100644 --- a/Lib/test/test_cppext/setup.py +++ b/Lib/test/test_cppext/setup.py @@ -86,6 +86,10 @@ def main(): if internal: cppflags.append('-DTEST_INTERNAL_C_API=1') + extra_cflags = os.environ.get("CPYTHON_TEST_EXTRA_CFLAGS", "") + if extra_cflags: + cppflags.extend(shlex.split(extra_cflags)) + # On Windows, add PCbuild\amd64\ to include and library directories include_dirs = [] library_dirs = [] diff --git a/Misc/NEWS.d/next/C_API/2026-02-19-18-39-11.gh-issue-145010.mKzjci.rst b/Misc/NEWS.d/next/C_API/2026-02-19-18-39-11.gh-issue-145010.mKzjci.rst new file mode 100644 index 00000000000000..7f5be699c6348d --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-02-19-18-39-11.gh-issue-145010.mKzjci.rst @@ -0,0 +1,2 @@ +Use GCC dialect alternatives for inline assembly in ``object.h`` so that the +Python headers compile correctly with ``-masm=intel``. From 4d0dce0c8ddc4d0321bd590a1a33990edc2e1b08 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:57:34 +0000 Subject: [PATCH 403/498] Fix integer overflow for formats "s" and "p" in the struct module (GH-145750) --- Lib/test/test_struct.py | 6 ++++++ .../2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst | 3 +++ Modules/_struct.c | 8 +++++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 6904572d095d31..55e2ce590a2577 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -555,6 +555,12 @@ def test_count_overflow(self): hugecount3 = '{}i{}q'.format(sys.maxsize // 4, sys.maxsize // 8) self.assertRaises(struct.error, struct.calcsize, hugecount3) + hugecount4 = '{}?s'.format(sys.maxsize) + self.assertRaises(struct.error, struct.calcsize, hugecount4) + + hugecount5 = '{}?p'.format(sys.maxsize) + self.assertRaises(struct.error, struct.calcsize, hugecount5) + def test_trailing_counter(self): store = array.array('b', b' '*100) diff --git a/Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst b/Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst new file mode 100644 index 00000000000000..a909bea2caffe9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-10-14-13-12.gh-issue-145750.iQsTeX.rst @@ -0,0 +1,3 @@ +Avoid undefined behaviour from signed integer overflow when parsing format +strings in the :mod:`struct` module. Found by OSS Fuzz in +:oss-fuzz:`488466741`. diff --git a/Modules/_struct.c b/Modules/_struct.c index c2f7b1fe0e800a..f8574322b40c8d 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1676,7 +1676,13 @@ prepare_s(PyStructObject *self, PyObject *format) switch (c) { case 's': _Py_FALLTHROUGH; - case 'p': len++; ncodes++; break; + case 'p': + if (len == PY_SSIZE_T_MAX) { + goto overflow; + } + len++; + ncodes++; + break; case 'x': break; default: if (num > PY_SSIZE_T_MAX - len) { From 665c1db94f46f8e1a18a8c2f89adb3bc72cb83dc Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 10 Mar 2026 14:47:58 -0400 Subject: [PATCH 404/498] gh-142763: Fix race in ZoneInfo cache eviction (gh-144978) The cache may be cleared between the evaluation of the if statement and the call to popitem. --- Lib/zoneinfo/_zoneinfo.py | 6 +++++- .../2025-12-18-00-00-00.gh-issue-142763.AJpZPVG5.rst | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-12-18-00-00-00.gh-issue-142763.AJpZPVG5.rst diff --git a/Lib/zoneinfo/_zoneinfo.py b/Lib/zoneinfo/_zoneinfo.py index 3ffdb4c837192b..bd3fefc6c9d959 100644 --- a/Lib/zoneinfo/_zoneinfo.py +++ b/Lib/zoneinfo/_zoneinfo.py @@ -47,7 +47,11 @@ def __new__(cls, key): cls._strong_cache[key] = cls._strong_cache.pop(key, instance) if len(cls._strong_cache) > cls._strong_cache_size: - cls._strong_cache.popitem(last=False) + try: + cls._strong_cache.popitem(last=False) + except KeyError: + # another thread may have already emptied the cache + pass return instance diff --git a/Misc/NEWS.d/next/Library/2025-12-18-00-00-00.gh-issue-142763.AJpZPVG5.rst b/Misc/NEWS.d/next/Library/2025-12-18-00-00-00.gh-issue-142763.AJpZPVG5.rst new file mode 100644 index 00000000000000..a5330365e3e42e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-18-00-00-00.gh-issue-142763.AJpZPVG5.rst @@ -0,0 +1,2 @@ +Fix a race condition between :class:`zoneinfo.ZoneInfo` creation and +:func:`zoneinfo.ZoneInfo.clear_cache` that could raise :exc:`KeyError`. From 5197ecb5e4df30ba0f6792d8bc0e36846154f58a Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Tue, 10 Mar 2026 20:51:17 +0100 Subject: [PATCH 405/498] gh-143050: Remove redundant decref in _PyLong_Negate (gh-143051) --- Objects/longobject.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 7ce5d0535b884e..185226db43a92a 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -48,6 +48,17 @@ _Py_DECREF_INT(PyLongObject *op) _Py_DECREF_SPECIALIZED((PyObject *)op, _PyLong_ExactDealloc); } +static inline int +/// Return 1 if the object is one of the immortal small ints +_long_is_small_int(PyObject *op) +{ + assert(PyLong_Check(op)); + PyLongObject *long_object = (PyLongObject *)op; + int is_small_int = (long_object->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0; + assert((!is_small_int) || PyLong_CheckExact(op)); + return is_small_int; +} + static inline int is_medium_int(stwodigits x) { @@ -344,8 +355,6 @@ medium_from_stwodigits(stwodigits x) } -/* If a freshly-allocated int is already shared, it must - be a small integer, so negating it must go to PyLong_FromLong */ Py_LOCAL_INLINE(void) _PyLong_Negate(PyLongObject **x_p) { @@ -357,8 +366,10 @@ _PyLong_Negate(PyLongObject **x_p) return; } - *x_p = _PyLong_FromSTwoDigits(-medium_value(x)); - Py_DECREF(x); + /* If a freshly-allocated int is already shared, it must + be a small integer, so negating it will fit a single digit */ + assert(_long_is_small_int((PyObject *)x)); + *x_p = (PyLongObject *)_PyLong_FromSTwoDigits(-medium_value(x)); } #define PYLONG_FROM_INT(UINT_TYPE, INT_TYPE, ival) \ @@ -3622,16 +3633,6 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } -static inline int -/// Return 1 if the object is one of the immortal small ints -_long_is_small_int(PyObject *op) -{ - PyLongObject *long_object = (PyLongObject *)op; - int is_small_int = (long_object->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0; - assert((!is_small_int) || PyLong_CheckExact(op)); - return is_small_int; -} - void _PyLong_ExactDealloc(PyObject *self) { From ebb150e76ab4988fdcd5e8caa36b9014497573a5 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 11 Mar 2026 01:43:27 +0100 Subject: [PATCH 406/498] gh-145219: Cache Emscripten build dependencies, add install-emscripten (#145664) Modifies the Emscripten build script to allow for caching of dependencies, and for automated installation of new EMSDK versions. Co-authored-by: Russell Keith-Magee --- Tools/wasm/emscripten/__main__.py | 214 +++++++++++++++---- Tools/wasm/emscripten/config.toml | 14 ++ Tools/wasm/emscripten/emscripten_version.txt | 1 - 3 files changed, 184 insertions(+), 45 deletions(-) create mode 100644 Tools/wasm/emscripten/config.toml delete mode 100644 Tools/wasm/emscripten/emscripten_version.txt diff --git a/Tools/wasm/emscripten/__main__.py b/Tools/wasm/emscripten/__main__.py index 14d32279a8c4fa..b1a779777ae9fc 100644 --- a/Tools/wasm/emscripten/__main__.py +++ b/Tools/wasm/emscripten/__main__.py @@ -4,6 +4,7 @@ import contextlib import functools import hashlib +import json import os import shutil import subprocess @@ -14,6 +15,8 @@ from textwrap import dedent from urllib.request import urlopen +import tomllib + try: from os import process_cpu_count as cpu_count except ImportError: @@ -22,25 +25,51 @@ EMSCRIPTEN_DIR = Path(__file__).parent CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent -EMSCRIPTEN_VERSION_FILE = EMSCRIPTEN_DIR / "emscripten_version.txt" +CONFIG_FILE = EMSCRIPTEN_DIR / "config.toml" DEFAULT_CROSS_BUILD_DIR = CHECKOUT / "cross-build" HOST_TRIPLE = "wasm32-emscripten" -def get_build_paths(cross_build_dir=None): +@functools.cache +def load_config_toml(): + with CONFIG_FILE.open("rb") as file: + return tomllib.load(file) + + +@functools.cache +def required_emscripten_version(): + return load_config_toml()["emscripten-version"] + + +@functools.cache +def emsdk_cache_root(emsdk_cache): + required_version = required_emscripten_version() + return Path(emsdk_cache).absolute() / required_version + + +@functools.cache +def emsdk_activate_path(emsdk_cache): + return emsdk_cache_root(emsdk_cache) / "emsdk/emsdk_env.sh" + + +def get_build_paths(cross_build_dir=None, emsdk_cache=None): """Compute all build paths from the given cross-build directory.""" if cross_build_dir is None: cross_build_dir = DEFAULT_CROSS_BUILD_DIR cross_build_dir = Path(cross_build_dir).absolute() host_triple_dir = cross_build_dir / HOST_TRIPLE + prefix_dir = host_triple_dir / "prefix" + if emsdk_cache: + prefix_dir = emsdk_cache_root(emsdk_cache) / "prefix" + return { "cross_build_dir": cross_build_dir, "native_build_dir": cross_build_dir / "build", "host_triple_dir": host_triple_dir, "host_build_dir": host_triple_dir / "build", "host_dir": host_triple_dir / "build" / "python", - "prefix_dir": host_triple_dir / "prefix", + "prefix_dir": prefix_dir, } @@ -48,22 +77,10 @@ def get_build_paths(cross_build_dir=None): LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n" -@functools.cache -def get_required_emscripten_version(): - """Read the required emscripten version from emscripten_version.txt.""" - return EMSCRIPTEN_VERSION_FILE.read_text().strip() - - -@functools.cache -def get_emsdk_activate_path(emsdk_cache): - required_version = get_required_emscripten_version() - return Path(emsdk_cache) / required_version / "emsdk_env.sh" - - def validate_emsdk_version(emsdk_cache): """Validate that the emsdk cache contains the required emscripten version.""" - required_version = get_required_emscripten_version() - emsdk_env = get_emsdk_activate_path(emsdk_cache) + required_version = required_emscripten_version() + emsdk_env = emsdk_activate_path(emsdk_cache) if not emsdk_env.is_file(): print( f"Required emscripten version {required_version} not found in {emsdk_cache}", @@ -90,7 +107,7 @@ def get_emsdk_environ(emsdk_cache): [ "bash", "-c", - f"EMSDK_QUIET=1 source {get_emsdk_activate_path(emsdk_cache)} && env", + f"EMSDK_QUIET=1 source {emsdk_activate_path(emsdk_cache)} && env", ], text=True, ) @@ -207,6 +224,35 @@ def build_python_path(context): return binary +def install_emscripten(context): + emsdk_cache = context.emsdk_cache + if emsdk_cache is None: + print("install-emscripten requires --emsdk-cache", file=sys.stderr) + sys.exit(1) + version = required_emscripten_version() + emsdk_target = emsdk_cache_root(emsdk_cache) / "emsdk" + if emsdk_target.exists(): + if not context.quiet: + print(f"Emscripten version {version} already installed") + return + if not context.quiet: + print(f"Installing emscripten version {version}") + emsdk_target.mkdir(parents=True) + call( + [ + "git", + "clone", + "https://github.com/emscripten-core/emsdk.git", + emsdk_target, + ], + quiet=context.quiet, + ) + call([emsdk_target / "emsdk", "install", version], quiet=context.quiet) + call([emsdk_target / "emsdk", "activate", version], quiet=context.quiet) + if not context.quiet: + print(f"Installed emscripten version {version}") + + @subdir("native_build_dir", clean_ok=True) def configure_build_python(context, working_dir): """Configure the build/host Python.""" @@ -258,35 +304,87 @@ def download_and_unpack(working_dir: Path, url: str, expected_shasum: str): shutil.unpack_archive(tmp_file.name, working_dir) +def should_build_library(prefix, name, config, quiet): + cached_config = prefix / (name + ".json") + if not cached_config.exists(): + if not quiet: + print( + f"No cached build of {name} version {config['version']} found, building" + ) + return True + + try: + with cached_config.open("rb") as f: + cached_config = json.load(f) + except json.JSONDecodeError: + if not quiet: + print(f"Cached data for {name} invalid, rebuilding") + return True + if config == cached_config: + if not quiet: + print( + f"Found cached build of {name} version {config['version']}, not rebuilding" + ) + return False + + if not quiet: + print( + f"Found cached build of {name} version {config['version']} but it's out of date, rebuilding" + ) + return True + + +def write_library_config(prefix, name, config, quiet): + cached_config = prefix / (name + ".json") + with cached_config.open("w") as f: + json.dump(config, f) + if not quiet: + print(f"Succeded building {name}, wrote config to {cached_config}") + + @subdir("host_build_dir", clean_ok=True) def make_emscripten_libffi(context, working_dir): - ver = "3.4.6" - libffi_dir = working_dir / f"libffi-{ver}" + prefix = context.build_paths["prefix_dir"] + libffi_config = load_config_toml()["libffi"] + if not should_build_library( + prefix, "libffi", libffi_config, context.quiet + ): + return + url = libffi_config["url"] + version = libffi_config["version"] + shasum = libffi_config["shasum"] + libffi_dir = working_dir / f"libffi-{version}" shutil.rmtree(libffi_dir, ignore_errors=True) download_and_unpack( working_dir, - f"https://github.com/libffi/libffi/releases/download/v{ver}/libffi-{ver}.tar.gz", - "b0dea9df23c863a7a50e825440f3ebffabd65df1497108e5d437747843895a4e", + url.format(version=version), + shasum, ) call( [EMSCRIPTEN_DIR / "make_libffi.sh"], - env=updated_env( - {"PREFIX": context.build_paths["prefix_dir"]}, context.emsdk_cache - ), + env=updated_env({"PREFIX": prefix}, context.emsdk_cache), cwd=libffi_dir, quiet=context.quiet, ) + write_library_config(prefix, "libffi", libffi_config, context.quiet) @subdir("host_build_dir", clean_ok=True) def make_mpdec(context, working_dir): - ver = "4.0.1" - mpdec_dir = working_dir / f"mpdecimal-{ver}" + prefix = context.build_paths["prefix_dir"] + mpdec_config = load_config_toml()["mpdec"] + if not should_build_library(prefix, "mpdec", mpdec_config, context.quiet): + return + + url = mpdec_config["url"] + version = mpdec_config["version"] + shasum = mpdec_config["shasum"] + mpdec_dir = working_dir / f"mpdecimal-{version}" shutil.rmtree(mpdec_dir, ignore_errors=True) download_and_unpack( working_dir, - f"https://www.bytereef.org/software/mpdecimal/releases/mpdecimal-{ver}.tar.gz", - "96d33abb4bb0070c7be0fed4246cd38416188325f820468214471938545b1ac8", + url.format(version=version), + shasum, ) call( [ @@ -294,7 +392,7 @@ def make_mpdec(context, working_dir): mpdec_dir / "configure", "CFLAGS=-fPIC", "--prefix", - context.build_paths["prefix_dir"], + prefix, "--disable-shared", ], cwd=mpdec_dir, @@ -306,6 +404,7 @@ def make_mpdec(context, working_dir): cwd=mpdec_dir, quiet=context.quiet, ) + write_library_config(prefix, "mpdec", mpdec_config, context.quiet) @subdir("host_dir", clean_ok=True) @@ -436,16 +535,24 @@ def make_emscripten_python(context, working_dir): subprocess.check_call([exec_script, "--version"]) -def build_all(context): - """Build everything.""" - steps = [ - configure_build_python, - make_build_python, - make_emscripten_libffi, - make_mpdec, - configure_emscripten_python, - make_emscripten_python, - ] +def build_target(context): + """Build one or more targets.""" + steps = [] + if context.target in {"all"}: + steps.append(install_emscripten) + if context.target in {"build", "all"}: + steps.extend([ + configure_build_python, + make_build_python, + ]) + if context.target in {"host", "all"}: + steps.extend([ + make_emscripten_libffi, + make_mpdec, + configure_emscripten_python, + make_emscripten_python, + ]) + for step in steps: step(context) @@ -475,7 +582,22 @@ def main(): parser = argparse.ArgumentParser() subcommands = parser.add_subparsers(dest="subcommand") + install_emscripten_cmd = subcommands.add_parser( + "install-emscripten", + help="Install the appropriate version of Emscripten", + ) build = subcommands.add_parser("build", help="Build everything") + build.add_argument( + "target", + nargs="?", + default="all", + choices=["all", "host", "build"], + help=( + "What should be built. 'build' for just the build platform, or " + "'host' for the host platform, or 'all' for both. Defaults to 'all'." + ), + ) + configure_build = subcommands.add_parser( "configure-build-python", help="Run `configure` for the build Python" ) @@ -512,6 +634,7 @@ def main(): ) for subcommand in ( + install_emscripten_cmd, build, configure_build, make_libffi_cmd, @@ -568,22 +691,25 @@ def main(): context = parser.parse_args() - context.build_paths = get_build_paths(context.cross_build_dir) - - if context.emsdk_cache: + if context.emsdk_cache and context.subcommand != "install-emscripten": validate_emsdk_version(context.emsdk_cache) context.emsdk_cache = Path(context.emsdk_cache).absolute() else: print("Build will use EMSDK from current environment.") + context.build_paths = get_build_paths( + context.cross_build_dir, context.emsdk_cache + ) + dispatch = { + "install-emscripten": install_emscripten, "make-libffi": make_emscripten_libffi, "make-mpdec": make_mpdec, "configure-build-python": configure_build_python, "make-build-python": make_build_python, "configure-host": configure_emscripten_python, "make-host": make_emscripten_python, - "build": build_all, + "build": build_target, "clean": clean_contents, } diff --git a/Tools/wasm/emscripten/config.toml b/Tools/wasm/emscripten/config.toml new file mode 100644 index 00000000000000..98edaebe992685 --- /dev/null +++ b/Tools/wasm/emscripten/config.toml @@ -0,0 +1,14 @@ +# Any data that can vary between Python versions is to be kept in this file. +# This allows for blanket copying of the Emscripten build code between supported +# Python versions. +emscripten-version = "4.0.12" + +[libffi] +url = "https://github.com/libffi/libffi/releases/download/v{version}/libffi-{version}.tar.gz" +version = "3.4.6" +shasum = "b0dea9df23c863a7a50e825440f3ebffabd65df1497108e5d437747843895a4e" + +[mpdec] +url = "https://www.bytereef.org/software/mpdecimal/releases/mpdecimal-{version}.tar.gz" +version = "4.0.1" +shasum = "96d33abb4bb0070c7be0fed4246cd38416188325f820468214471938545b1ac8" diff --git a/Tools/wasm/emscripten/emscripten_version.txt b/Tools/wasm/emscripten/emscripten_version.txt deleted file mode 100644 index 4c05e4ef57dbf8..00000000000000 --- a/Tools/wasm/emscripten/emscripten_version.txt +++ /dev/null @@ -1 +0,0 @@ -4.0.12 From c3955e049fd5dbd3d92bc95fed4442964156293d Mon Sep 17 00:00:00 2001 From: Thomas Kowalski Date: Wed, 11 Mar 2026 08:27:26 +0100 Subject: [PATCH 407/498] gh-145713: make bytearray.resize thread-safe on free-threading (#145714) Co-authored-by: Kumar Aditya --- Lib/test/test_bytes.py | 16 ++++++++++++++++ ...6-03-09-00-00-00.gh-issue-145713.KR6azvzI.rst | 3 +++ Objects/bytearrayobject.c | 5 +++-- Objects/clinic/bytearrayobject.c.h | 4 +++- 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-00-00-00.gh-issue-145713.KR6azvzI.rst diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 1c64bf888f9d27..876ecd4467b0a2 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -2908,6 +2908,22 @@ def check(funcs, it): check([iter_next] + [iter_reduce] * 10, iter(ba)) # for tsan check([iter_next] + [iter_setstate] * 10, iter(ba)) # for tsan + @unittest.skipUnless(support.Py_GIL_DISABLED, 'this test can only possibly fail with GIL disabled') + @threading_helper.reap_threads + @threading_helper.requires_working_threading() + def test_free_threading_bytearray_resize(self): + def resize_stress(ba): + for _ in range(1000): + try: + ba.resize(1000) + ba.resize(1) + except (BufferError, ValueError): + pass + + ba = bytearray(100) + threads = [threading.Thread(target=resize_stress, args=(ba,)) for _ in range(4)] + with threading_helper.start_threads(threads): + pass if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-00-00-00.gh-issue-145713.KR6azvzI.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-00-00-00.gh-issue-145713.KR6azvzI.rst new file mode 100644 index 00000000000000..2cf83eff31056a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-09-00-00-00.gh-issue-145713.KR6azvzI.rst @@ -0,0 +1,3 @@ +Make :meth:`bytearray.resize` thread-safe in the free-threaded build by +using a critical section and calling the lock-held variant of the resize +function. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 7f09769e12f05f..e2fea94e099626 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1506,6 +1506,7 @@ bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix) /*[clinic input] +@critical_section bytearray.resize size: Py_ssize_t New size to resize to. @@ -1515,10 +1516,10 @@ Resize the internal buffer of bytearray to len. static PyObject * bytearray_resize_impl(PyByteArrayObject *self, Py_ssize_t size) -/*[clinic end generated code: output=f73524922990b2d9 input=6c9a260ca7f72071]*/ +/*[clinic end generated code: output=f73524922990b2d9 input=116046316a2b5cfc]*/ { Py_ssize_t start_size = PyByteArray_GET_SIZE(self); - int result = PyByteArray_Resize((PyObject *)self, size); + int result = bytearray_resize_lock_held((PyObject *)self, size); if (result < 0) { return NULL; } diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index be704ccf68f669..cf60d0ceadc7d1 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -625,7 +625,9 @@ bytearray_resize(PyObject *self, PyObject *arg) } size = ival; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = bytearray_resize_impl((PyByteArrayObject *)self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1833,4 +1835,4 @@ bytearray_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl((PyByteArrayObject *)self); } -/*[clinic end generated code: output=5eddefde2a001ceb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2d76ef023928424f input=a9049054013a1b77]*/ From cf7c67b7c6b96527dfb0da2d6305923a92e3d766 Mon Sep 17 00:00:00 2001 From: Cody Maloney Date: Wed, 11 Mar 2026 01:02:23 -0700 Subject: [PATCH 408/498] gh-101100: Fix sphinx reference warnings around I/O (#139592) Co-authored-by: Carol Willing --- Doc/library/email.parser.rst | 2 +- Doc/library/exceptions.rst | 2 +- Doc/library/os.rst | 10 +++++----- Doc/reference/datamodel.rst | 16 ++++++++++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst index e0fcce8f0cbb8c..6a67bf7c8e555d 100644 --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -155,7 +155,7 @@ message body, instead setting the payload to the raw body. Read all the data from the binary file-like object *fp*, parse the resulting bytes, and return the message object. *fp* must support - both the :meth:`~io.IOBase.readline` and the :meth:`~io.IOBase.read` + both the :meth:`~io.IOBase.readline` and the :meth:`~io.BufferedIOBase.read` methods. The bytes contained in *fp* must be formatted as a block of :rfc:`5322` diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 3db3c7a13503f4..7fc6055aa9a881 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -221,7 +221,7 @@ The following exceptions are the exceptions that are usually raised. .. exception:: EOFError Raised when the :func:`input` function hits an end-of-file condition (EOF) - without reading any data. (Note: the :meth:`!io.IOBase.read` and + without reading any data. (Note: the :meth:`io.TextIOBase.read` and :meth:`io.IOBase.readline` methods return an empty string when they hit EOF.) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 940d04ccc925cd..7547967c6b32f0 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1294,8 +1294,8 @@ as internal buffering of data. This function is intended for low-level I/O. For normal usage, use the built-in function :func:`open`, which returns a :term:`file object` with - :meth:`~file.read` and :meth:`~file.write` methods (and many more). To - wrap a file descriptor in a file object, use :func:`fdopen`. + :meth:`~io.BufferedIOBase.read` and :meth:`~io.BufferedIOBase.write` methods. + To wrap a file descriptor in a file object, use :func:`fdopen`. .. versionchanged:: 3.3 Added the *dir_fd* parameter. @@ -1670,7 +1670,7 @@ or `the MSDN `_ on Windo descriptor as returned by :func:`os.open` or :func:`pipe`. To read a "file object" returned by the built-in function :func:`open` or by :func:`popen` or :func:`fdopen`, or :data:`sys.stdin`, use its - :meth:`~file.read` or :meth:`~file.readline` methods. + :meth:`~io.TextIOBase.read` or :meth:`~io.IOBase.readline` methods. .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an @@ -1905,7 +1905,7 @@ or `the MSDN `_ on Windo descriptor as returned by :func:`os.open` or :func:`pipe`. To write a "file object" returned by the built-in function :func:`open` or by :func:`popen` or :func:`fdopen`, or :data:`sys.stdout` or :data:`sys.stderr`, use its - :meth:`~file.write` method. + :meth:`~io.TextIOBase.write` method. .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an @@ -4720,7 +4720,7 @@ to be ignored. The current process is replaced immediately. Open file objects and descriptors are not flushed, so if there may be data buffered on these open files, you should flush them using - :func:`sys.stdout.flush` or :func:`os.fsync` before calling an + :func:`~io.IOBase.flush` or :func:`os.fsync` before calling an :func:`exec\* ` function. The "l" and "v" variants of the :func:`exec\* ` functions differ in how diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 062d301f6286f7..90b8821daaf3fb 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1401,12 +1401,28 @@ also :func:`os.popen`, :func:`os.fdopen`, and the :meth:`~socket.socket.makefile` method of socket objects (and perhaps by other functions or methods provided by extension modules). +File objects implement common methods, listed below, to simplify usage in +generic code. They are expected to be :ref:`context-managers`. + The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are initialized to file objects corresponding to the interpreter's standard input, output and error streams; they are all open in text mode and therefore follow the interface defined by the :class:`io.TextIOBase` abstract class. +.. method:: file.read(size=-1, /) + + Retrieve up to *size* data from the file. As a convenience if *size* is + unspecified or -1 retrieve all data available. + +.. method:: file.write(data, /) + + Store *data* to the file. + +.. method:: file.close() + + Flush any buffers and close the underlying file. + Internal types -------------- From bdf6de8c3f0c2ec0d737f38014a32c1eed02c7f1 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Wed, 11 Mar 2026 07:19:32 -0400 Subject: [PATCH 409/498] gh-145685: Avoid contention on TYPE_LOCK in super() lookups (gh-145775) --- Include/internal/pycore_stackref.h | 7 +++++++ Objects/typeobject.c | 20 +++++++++----------- Tools/ftscalingbench/ftscalingbench.py | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h index 69d667b4be47d2..188da775eb1cc7 100644 --- a/Include/internal/pycore_stackref.h +++ b/Include/internal/pycore_stackref.h @@ -770,6 +770,13 @@ _PyThreadState_PushCStackRef(PyThreadState *tstate, _PyCStackRef *ref) ref->ref = PyStackRef_NULL; } +static inline void +_PyThreadState_PushCStackRefNew(PyThreadState *tstate, _PyCStackRef *ref, PyObject *obj) +{ + _PyThreadState_PushCStackRef(tstate, ref); + ref->ref = PyStackRef_FromPyObjectNew(obj); +} + static inline void _PyThreadState_PopCStackRef(PyThreadState *tstate, _PyCStackRef *ref) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5dc96bf251b384..bb473dce68f65b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -12360,18 +12360,16 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * PyObject *mro, *res; Py_ssize_t i, n; - BEGIN_TYPE_LOCK(); mro = lookup_tp_mro(su_obj_type); - /* keep a strong reference to mro because su_obj_type->tp_mro can be - replaced during PyDict_GetItemRef(dict, name, &res) and because - another thread can modify it after we end the critical section - below */ - Py_XINCREF(mro); - END_TYPE_LOCK(); - if (mro == NULL) return NULL; + /* Keep a strong reference to mro because su_obj_type->tp_mro can be + replaced during PyDict_GetItemRef(dict, name, &res). */ + PyThreadState *tstate = _PyThreadState_GET(); + _PyCStackRef mro_ref; + _PyThreadState_PushCStackRefNew(tstate, &mro_ref, mro); + assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); @@ -12382,7 +12380,7 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * } i++; /* skip su->type (if any) */ if (i >= n) { - Py_DECREF(mro); + _PyThreadState_PopCStackRef(tstate, &mro_ref); return NULL; } @@ -12393,13 +12391,13 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * if (PyDict_GetItemRef(dict, name, &res) != 0) { // found or error - Py_DECREF(mro); + _PyThreadState_PopCStackRef(tstate, &mro_ref); return res; } i++; } while (i < n); - Py_DECREF(mro); + _PyThreadState_PopCStackRef(tstate, &mro_ref); return NULL; } diff --git a/Tools/ftscalingbench/ftscalingbench.py b/Tools/ftscalingbench/ftscalingbench.py index f60f5adba5c12c..8d8bbc88e7f30a 100644 --- a/Tools/ftscalingbench/ftscalingbench.py +++ b/Tools/ftscalingbench/ftscalingbench.py @@ -241,6 +241,22 @@ def instantiate_typing_namedtuple(): for _ in range(1000 * WORK_SCALE): obj = MyTypingNamedTuple(x=1, y=2, z=3) +@register_benchmark +def super_call(): + # TODO: super() on the same class from multiple threads still doesn't + # scale well, so use a class per-thread here for now. + class Base: + def method(self): + return 1 + + class Derived(Base): + def method(self): + return super().method() + + obj = Derived() + for _ in range(1000 * WORK_SCALE): + obj.method() + @register_benchmark def deepcopy(): From dae85c4d9393b706657a4eb1febc71647a5f544e Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Wed, 11 Mar 2026 14:39:24 +0300 Subject: [PATCH 410/498] gh-145633: Remove support for ancient ARM platforms with mixed-endian doubles (#145634) * Drop DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 macro. * Use DOUBLE_IS_BIG/LITTLE_ENDIAN_IEEE754 to detect endianness of float/doubles. * Drop "unknown_format" code path in PyFloat_Pack/Unpack*(). Co-authored-by: Victor Stinner --- Doc/c-api/float.rst | 8 - Include/internal/pycore_floatobject.h | 10 +- Include/internal/pycore_pymath.h | 3 +- Include/internal/pycore_runtime_init.h | 8 +- Include/internal/pycore_runtime_structs.h | 12 - Include/pymacconfig.h | 1 - ...-03-08-06-18-26.gh-issue-145633.Ogu-RF.rst | 3 + Objects/clinic/floatobject.c.h | 4 +- Objects/floatobject.c | 626 +++--------------- Python/dtoa.c | 6 +- Python/pylifecycle.c | 2 - configure | 13 - configure.ac | 14 +- pyconfig.h.in | 4 - 14 files changed, 129 insertions(+), 585 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-03-08-06-18-26.gh-issue-145633.Ogu-RF.rst diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index dcd545478277a8..ca8d44c25c1ece 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -224,11 +224,6 @@ 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`). -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, char *p, int le) Pack a C double as the IEEE 754 binary16 half-precision format. @@ -256,9 +251,6 @@ 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 char *p, int le) Unpack the IEEE 754 binary16 half-precision format as a C double. diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h index 317f984188bad8..62501cdaf44f07 100644 --- a/Include/internal/pycore_floatobject.h +++ b/Include/internal/pycore_floatobject.h @@ -12,7 +12,6 @@ extern "C" { /* runtime lifecycle */ -extern void _PyFloat_InitState(PyInterpreterState *); extern PyStatus _PyFloat_InitTypes(PyInterpreterState *); extern void _PyFloat_FiniType(PyInterpreterState *); @@ -42,6 +41,15 @@ extern double _Py_parse_inf_or_nan(const char *p, char **endptr); extern int _Py_convert_int_to_double(PyObject **v, double *dbl); +/* Should match endianness of the platform in most (all?) cases. */ + +#ifdef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# define _PY_FLOAT_BIG_ENDIAN 1 +# define _PY_FLOAT_LITTLE_ENDIAN 0 +#else +# define _PY_FLOAT_BIG_ENDIAN 0 +# define _PY_FLOAT_LITTLE_ENDIAN 1 +#endif #ifdef __cplusplus } diff --git a/Include/internal/pycore_pymath.h b/Include/internal/pycore_pymath.h index f66325aa59c4c9..532c5ceafb5639 100644 --- a/Include/internal/pycore_pymath.h +++ b/Include/internal/pycore_pymath.h @@ -182,8 +182,7 @@ extern void _Py_set_387controlword(unsigned short); // (extended precision), and we don't know how to change // the rounding precision. #if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ - !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ - !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) # define _PY_SHORT_FLOAT_REPR 0 #endif diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index b182f7825a2326..e8d1098c2078fc 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -13,7 +13,7 @@ extern "C" { #include "pycore_debug_offsets.h" // _Py_DebugOffsets_INIT() #include "pycore_dtoa.h" // _dtoa_state_INIT() #include "pycore_faulthandler.h" // _faulthandler_runtime_state_INIT -#include "pycore_floatobject.h" // _py_float_format_unknown +#include "pycore_floatobject.h" // _py_float_format_* #include "pycore_function.h" #include "pycore_hamt.h" // _PyHamt_BitmapNode_Type #include "pycore_import.h" // IMPORTS_INIT @@ -84,10 +84,6 @@ extern PyTypeObject _PyExc_MemoryError; .stoptheworld = { \ .is_global = 1, \ }, \ - .float_state = { \ - .float_format = _py_float_format_unknown, \ - .double_format = _py_float_format_unknown, \ - }, \ .types = { \ .next_version_tag = _Py_TYPE_VERSION_NEXT, \ }, \ @@ -233,4 +229,4 @@ extern PyTypeObject _PyExc_MemoryError; #ifdef __cplusplus } #endif -#endif /* !Py_INTERNAL_RUNTIME_INIT_H */ \ No newline at end of file +#endif /* !Py_INTERNAL_RUNTIME_INIT_H */ diff --git a/Include/internal/pycore_runtime_structs.h b/Include/internal/pycore_runtime_structs.h index 90e6625ad1fc9c..05369ef9f009e6 100644 --- a/Include/internal/pycore_runtime_structs.h +++ b/Include/internal/pycore_runtime_structs.h @@ -35,17 +35,6 @@ struct _pymem_allocators { PyObjectArenaAllocator obj_arena; }; -enum _py_float_format_type { - _py_float_format_unknown, - _py_float_format_ieee_big_endian, - _py_float_format_ieee_little_endian, -}; - -struct _Py_float_runtime_state { - enum _py_float_format_type float_format; - enum _py_float_format_type double_format; -}; - struct pyhash_runtime_state { struct { #ifndef MS_WINDOWS @@ -270,7 +259,6 @@ struct pyruntimestate { } audit_hooks; struct _py_object_runtime_state object_state; - struct _Py_float_runtime_state float_state; struct _Py_unicode_runtime_state unicode_state; struct _types_runtime_state types; struct _Py_time_runtime_state time; diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h index 615abe103ca038..9d63ddf8a716f4 100644 --- a/Include/pymacconfig.h +++ b/Include/pymacconfig.h @@ -18,7 +18,6 @@ #undef SIZEOF_UINTPTR_T #undef SIZEOF_PTHREAD_T #undef WORDS_BIGENDIAN -#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 #undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #undef HAVE_GCC_ASM_FOR_X87 diff --git a/Misc/NEWS.d/next/Build/2026-03-08-06-18-26.gh-issue-145633.Ogu-RF.rst b/Misc/NEWS.d/next/Build/2026-03-08-06-18-26.gh-issue-145633.Ogu-RF.rst new file mode 100644 index 00000000000000..2c4da1b60c0908 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-03-08-06-18-26.gh-issue-145633.Ogu-RF.rst @@ -0,0 +1,3 @@ +Remove support for ancient ARM platforms (ARMv4L and ARMv5L OABI boards), +using mixed-endian representation +for doubles. Patch by Sergey B Kirpichev. diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index 4051131f480ccb..c0ae9d3ff9b8d3 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -290,7 +290,7 @@ PyDoc_STRVAR(float___getformat____doc__, "\n" "It exists mainly to be used in Python\'s test suite.\n" "\n" -"This function returns whichever of \'unknown\', \'IEEE, big-endian\' or \'IEEE,\n" +"This function returns whichever of \'IEEE, big-endian\' or \'IEEE,\n" "little-endian\' best describes the format of floating-point numbers used by the\n" "C type named by typestr."); @@ -353,4 +353,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=927035897ea3573f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f0b2af257213c8b0 input=a9049054013a1b77]*/ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 579765281ca484..18871a4f3c51a9 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1666,15 +1666,6 @@ float___getnewargs___impl(PyObject *self) return Py_BuildValue("(d)", ((PyFloatObject *)self)->ob_fval); } -/* this is for the benefit of the pack/unpack routines below */ -typedef enum _py_float_format_type float_format_type; -#define unknown_format _py_float_format_unknown -#define ieee_big_endian_format _py_float_format_ieee_big_endian -#define ieee_little_endian_format _py_float_format_ieee_little_endian - -#define float_format (_PyRuntime.float_state.float_format) -#define double_format (_PyRuntime.float_state.double_format) - /*[clinic input] @permit_long_docstring_body @@ -1689,45 +1680,25 @@ You probably don't want to use this function. It exists mainly to be used in Python's test suite. -This function returns whichever of 'unknown', 'IEEE, big-endian' or 'IEEE, +This function returns whichever of 'IEEE, big-endian' or 'IEEE, little-endian' best describes the format of floating-point numbers used by the C type named by typestr. [clinic start generated code]*/ static PyObject * float___getformat___impl(PyTypeObject *type, const char *typestr) -/*[clinic end generated code: output=2bfb987228cc9628 input=d2735823bfe8e81e]*/ +/*[clinic end generated code: output=2bfb987228cc9628 input=0ae1ba35d192f704]*/ { - float_format_type r; - - if (strcmp(typestr, "double") == 0) { - r = double_format; - } - else if (strcmp(typestr, "float") == 0) { - r = float_format; - } - else { + if (strcmp(typestr, "double") != 0 && strcmp(typestr, "float") != 0) { PyErr_SetString(PyExc_ValueError, "__getformat__() argument 1 must be " "'double' or 'float'"); return NULL; } - - switch (r) { - case unknown_format: - return PyUnicode_FromString("unknown"); - case ieee_little_endian_format: - return PyUnicode_FromString("IEEE, little-endian"); - case ieee_big_endian_format: - return PyUnicode_FromString("IEEE, big-endian"); - default: - PyErr_SetString(PyExc_RuntimeError, - "insane float_format or double_format"); - return NULL; - } + return PyUnicode_FromString(_PY_FLOAT_LITTLE_ENDIAN ? + "IEEE, little-endian" : "IEEE, big-endian"); } - static PyObject * float_getreal(PyObject *v, void *Py_UNUSED(closure)) { @@ -1878,67 +1849,6 @@ PyTypeObject PyFloat_Type = { .tp_version_tag = _Py_TYPE_VERSION_FLOAT, }; -static void -_init_global_state(void) -{ - float_format_type detected_double_format, detected_float_format; - - /* We attempt to determine if this machine is using IEEE - floating-point formats by peering at the bits of some - carefully chosen values. If it looks like we are on an - IEEE platform, the float packing/unpacking routines can - just copy bits, if not they resort to arithmetic & shifts - and masks. The shifts & masks approach works on all finite - values, but what happens to infinities, NaNs and signed - zeroes on packing is an accident, and attempting to unpack - a NaN or an infinity will raise an exception. - - Note that if we're on some whacked-out platform which uses - IEEE formats but isn't strictly little-endian or big- - endian, we will fall back to the portable shifts & masks - method. */ - -#if SIZEOF_DOUBLE == 8 - { - double x = 9006104071832581.0; - if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) - detected_double_format = ieee_big_endian_format; - else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) - detected_double_format = ieee_little_endian_format; - else - detected_double_format = unknown_format; - } -#else - detected_double_format = unknown_format; -#endif - -#if SIZEOF_FLOAT == 4 - { - float y = 16711938.0; - if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) - detected_float_format = ieee_big_endian_format; - else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) - detected_float_format = ieee_little_endian_format; - else - detected_float_format = unknown_format; - } -#else - detected_float_format = unknown_format; -#endif - - double_format = detected_double_format; - float_format = detected_float_format; -} - -void -_PyFloat_InitState(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return; - } - _init_global_state(); -} - PyStatus _PyFloat_InitTypes(PyInterpreterState *interp) { @@ -2092,278 +2002,87 @@ int PyFloat_Pack4(double x, char *data, int le) { unsigned char *p = (unsigned char *)data; - if (float_format == unknown_format) { - unsigned char sign; - int e; - double f; - unsigned int fbits; - int incr = 1; - - if (le) { - p += 3; - incr = -1; - } - - if (x < 0) { - sign = 1; - x = -x; - } - else - sign = 0; - - f = frexp(x, &e); - - /* Normalize f to be in the range [1.0, 2.0) */ - if (0.5 <= f && f < 1.0) { - f *= 2.0; - e--; - } - else if (f == 0.0) - e = 0; - else { - PyErr_SetString(PyExc_SystemError, - "frexp() result out of range"); - return -1; - } - - if (e >= 128) - goto Overflow; - else if (e < -126) { - /* Gradual underflow */ - f = ldexp(f, 126 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 127; - f -= 1.0; /* Get rid of leading 1 */ - } - - f *= 8388608.0; /* 2**23 */ - fbits = (unsigned int)(f + 0.5); /* Round */ - assert(fbits <= 8388608); - if (fbits >> 23) { - /* The carry propagated out of a string of 23 1 bits. */ - fbits = 0; - ++e; - if (e >= 255) - goto Overflow; - } - - /* First byte */ - *p = (sign << 7) | (e >> 1); - p += incr; - - /* Second byte */ - *p = (char) (((e & 1) << 7) | (fbits >> 16)); - p += incr; - - /* Third byte */ - *p = (fbits >> 8) & 0xFF; - p += incr; - - /* Fourth byte */ - *p = fbits & 0xFF; - - /* Done */ - return 0; + float y = (float)x; + int i, incr = 1; + if (isinf(y) && !isinf(x)) { + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with f format"); + return -1; } - else { - float y = (float)x; - int i, incr = 1; - - if (isinf(y) && !isinf(x)) - goto Overflow; - /* correct y if x was a sNaN, transformed to qNaN by conversion */ - if (isnan(x)) { - uint64_t v; + /* correct y if x was a sNaN, transformed to qNaN by conversion */ + if (isnan(x)) { + uint64_t v; - memcpy(&v, &x, 8); + memcpy(&v, &x, 8); #ifndef __riscv - if ((v & (1ULL << 51)) == 0) { - uint32_t u32; - memcpy(&u32, &y, 4); - /* if have payload, make sNaN */ - if (u32 & 0x3fffff) { - u32 &= ~(1 << 22); - } - memcpy(&y, &u32, 4); - } -#else + if ((v & (1ULL << 51)) == 0) { uint32_t u32; - memcpy(&u32, &y, 4); - /* Workaround RISC-V: "If a NaN value is converted to a - * different floating-point type, the result is the - * canonical NaN of the new type". The canonical NaN here - * is a positive qNaN with zero payload. */ - if (v & (1ULL << 63)) { - u32 |= (1 << 31); /* set sign */ - } - /* add payload */ - u32 -= (u32 & 0x3fffff); - u32 += (uint32_t)((v & 0x7ffffffffffffULL) >> 29); /* if have payload, make sNaN */ - if ((v & (1ULL << 51)) == 0 && (u32 & 0x3fffff)) { + if (u32 & 0x3fffff) { u32 &= ~(1 << 22); } - memcpy(&y, &u32, 4); -#endif } +#else + uint32_t u32; + + memcpy(&u32, &y, 4); + /* Workaround RISC-V: "If a NaN value is converted to a + * different floating-point type, the result is the + * canonical NaN of the new type". The canonical NaN here + * is a positive qNaN with zero payload. */ + if (v & (1ULL << 63)) { + u32 |= (1 << 31); /* set sign */ + } + /* add payload */ + u32 -= (u32 & 0x3fffff); + u32 += (uint32_t)((v & 0x7ffffffffffffULL) >> 29); + /* if have payload, make sNaN */ + if ((v & (1ULL << 51)) == 0 && (u32 & 0x3fffff)) { + u32 &= ~(1 << 22); + } + + memcpy(&y, &u32, 4); +#endif + } - unsigned char s[sizeof(float)]; - memcpy(s, &y, sizeof(float)); + unsigned char s[sizeof(float)]; + memcpy(s, &y, sizeof(float)); - if ((float_format == ieee_little_endian_format && !le) - || (float_format == ieee_big_endian_format && le)) { - p += 3; - incr = -1; - } + if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) { + p += 3; + incr = -1; + } - for (i = 0; i < 4; i++) { - *p = s[i]; - p += incr; - } - return 0; + for (i = 0; i < 4; i++) { + *p = s[i]; + p += incr; } - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with f format"); - return -1; + return 0; } int PyFloat_Pack8(double x, char *data, int le) { unsigned char *p = (unsigned char *)data; - if (double_format == unknown_format) { - unsigned char sign; - int e; - double f; - unsigned int fhi, flo; - int incr = 1; - - if (le) { - p += 7; - incr = -1; - } - - if (x < 0) { - sign = 1; - x = -x; - } - else - sign = 0; - - f = frexp(x, &e); - - /* Normalize f to be in the range [1.0, 2.0) */ - if (0.5 <= f && f < 1.0) { - f *= 2.0; - e--; - } - else if (f == 0.0) - e = 0; - else { - PyErr_SetString(PyExc_SystemError, - "frexp() result out of range"); - return -1; - } + unsigned char as_bytes[8]; + memcpy(as_bytes, &x, 8); + const unsigned char *s = as_bytes; + int i, incr = 1; - if (e >= 1024) - goto Overflow; - else if (e < -1022) { - /* Gradual underflow */ - f = ldexp(f, 1022 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 1023; - f -= 1.0; /* Get rid of leading 1 */ - } - - /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ - f *= 268435456.0; /* 2**28 */ - fhi = (unsigned int)f; /* Truncate */ - assert(fhi < 268435456); - - f -= (double)fhi; - f *= 16777216.0; /* 2**24 */ - flo = (unsigned int)(f + 0.5); /* Round */ - assert(flo <= 16777216); - if (flo >> 24) { - /* The carry propagated out of a string of 24 1 bits. */ - flo = 0; - ++fhi; - if (fhi >> 28) { - /* And it also propagated out of the next 28 bits. */ - fhi = 0; - ++e; - if (e >= 2047) - goto Overflow; - } - } - - /* First byte */ - *p = (sign << 7) | (e >> 4); - p += incr; - - /* Second byte */ - *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); - p += incr; - - /* Third byte */ - *p = (fhi >> 16) & 0xFF; - p += incr; - - /* Fourth byte */ - *p = (fhi >> 8) & 0xFF; - p += incr; - - /* Fifth byte */ - *p = fhi & 0xFF; - p += incr; - - /* Sixth byte */ - *p = (flo >> 16) & 0xFF; - p += incr; - - /* Seventh byte */ - *p = (flo >> 8) & 0xFF; - p += incr; - - /* Eighth byte */ - *p = flo & 0xFF; - /* p += incr; */ - - /* Done */ - return 0; - - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with d format"); - return -1; + if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) { + p += 7; + incr = -1; } - else { - unsigned char as_bytes[8]; - memcpy(as_bytes, &x, 8); - const unsigned char *s = as_bytes; - int i, incr = 1; - - if ((double_format == ieee_little_endian_format && !le) - || (double_format == ieee_big_endian_format && le)) { - p += 7; - incr = -1; - } - for (i = 0; i < 8; i++) { - *p = *s++; - p += incr; - } - return 0; + for (i = 0; i < 8; i++) { + *p = *s++; + p += incr; } + return 0; } double @@ -2426,208 +2145,79 @@ double PyFloat_Unpack4(const char *data, int le) { unsigned char *p = (unsigned char *)data; - if (float_format == unknown_format) { - unsigned char sign; - int e; - unsigned int f; - double x; - int incr = 1; - - if (le) { - p += 3; - incr = -1; - } + float x; - /* First byte */ - sign = (*p >> 7) & 1; - e = (*p & 0x7F) << 1; - p += incr; + if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) { + char buf[4]; + char *d = &buf[3]; + int i; - /* Second byte */ - e |= (*p >> 7) & 1; - f = (*p & 0x7F) << 16; - p += incr; - - if (e == 255) { - PyErr_SetString( - PyExc_ValueError, - "can't unpack IEEE 754 special value " - "on non-IEEE platform"); - return -1; - } - - /* Third byte */ - f |= *p << 8; - p += incr; - - /* Fourth byte */ - f |= *p; - - x = (double)f / 8388608.0; - - /* XXX This sadly ignores Inf/NaN issues */ - if (e == 0) - e = -126; - else { - x += 1.0; - e -= 127; + for (i = 0; i < 4; i++) { + *d-- = *p++; } - x = ldexp(x, e); - - if (sign) - x = -x; - - return x; + memcpy(&x, buf, 4); } else { - float x; - - if ((float_format == ieee_little_endian_format && !le) - || (float_format == ieee_big_endian_format && le)) { - char buf[4]; - char *d = &buf[3]; - int i; - - for (i = 0; i < 4; i++) { - *d-- = *p++; - } - memcpy(&x, buf, 4); - } - else { - memcpy(&x, p, 4); - } + memcpy(&x, p, 4); + } - /* return sNaN double if x was sNaN float */ - if (isnan(x)) { - uint32_t v; - memcpy(&v, &x, 4); + /* return sNaN double if x was sNaN float */ + if (isnan(x)) { + uint32_t v; + memcpy(&v, &x, 4); #ifndef __riscv - if ((v & (1 << 22)) == 0) { - double y = x; /* will make qNaN double */ - uint64_t u64; - memcpy(&u64, &y, 8); - u64 &= ~(1ULL << 51); /* make sNaN */ - memcpy(&y, &u64, 8); - return y; - } -#else - double y = x; + if ((v & (1 << 22)) == 0) { + double y = x; /* will make qNaN double */ uint64_t u64; - memcpy(&u64, &y, 8); - if ((v & (1 << 22)) == 0) { - u64 &= ~(1ULL << 51); - } - /* Workaround RISC-V, see PyFloat_Pack4() */ - if (v & (1 << 31)) { - u64 |= (1ULL << 63); /* set sign */ - } - /* add payload */ - u64 -= (u64 & 0x7ffffffffffffULL); - u64 += ((v & 0x3fffffULL) << 29); - + u64 &= ~(1ULL << 51); /* make sNaN */ memcpy(&y, &u64, 8); return y; -#endif } +#else + double y = x; + uint64_t u64; - return x; + memcpy(&u64, &y, 8); + if ((v & (1 << 22)) == 0) { + u64 &= ~(1ULL << 51); + } + /* Workaround RISC-V, see PyFloat_Pack4() */ + if (v & (1 << 31)) { + u64 |= (1ULL << 63); /* set sign */ + } + /* add payload */ + u64 -= (u64 & 0x7ffffffffffffULL); + u64 += ((v & 0x3fffffULL) << 29); + + memcpy(&y, &u64, 8); + return y; +#endif } + + return x; } double PyFloat_Unpack8(const char *data, int le) { unsigned char *p = (unsigned char *)data; - if (double_format == unknown_format) { - unsigned char sign; - int e; - unsigned int fhi, flo; - double x; - int incr = 1; - - if (le) { - p += 7; - incr = -1; - } - - /* First byte */ - sign = (*p >> 7) & 1; - e = (*p & 0x7F) << 4; - - p += incr; - - /* Second byte */ - e |= (*p >> 4) & 0xF; - fhi = (*p & 0xF) << 24; - p += incr; - - if (e == 2047) { - PyErr_SetString( - PyExc_ValueError, - "can't unpack IEEE 754 special value " - "on non-IEEE platform"); - return -1.0; - } - - /* Third byte */ - fhi |= *p << 16; - p += incr; - - /* Fourth byte */ - fhi |= *p << 8; - p += incr; - - /* Fifth byte */ - fhi |= *p; - p += incr; - - /* Sixth byte */ - flo = *p << 16; - p += incr; - - /* Seventh byte */ - flo |= *p << 8; - p += incr; - - /* Eighth byte */ - flo |= *p; + double x; - x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ - x /= 268435456.0; /* 2**28 */ + if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) { + char buf[8]; + char *d = &buf[7]; + int i; - if (e == 0) - e = -1022; - else { - x += 1.0; - e -= 1023; + for (i = 0; i < 8; i++) { + *d-- = *p++; } - x = ldexp(x, e); - - if (sign) - x = -x; - - return x; + memcpy(&x, buf, 8); } else { - double x; - - if ((double_format == ieee_little_endian_format && !le) - || (double_format == ieee_big_endian_format && le)) { - char buf[8]; - char *d = &buf[7]; - int i; - - for (i = 0; i < 8; i++) { - *d-- = *p++; - } - memcpy(&x, buf, 8); - } - else { - memcpy(&x, p, 8); - } - - return x; + memcpy(&x, p, 8); } + + return x; } diff --git a/Python/dtoa.c b/Python/dtoa.c index 3de150351a4ef8..89fadd33391cb4 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -139,8 +139,7 @@ #ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 # define IEEE_8087 #endif -#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ - defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) # define IEEE_MC68k #endif #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 @@ -149,8 +148,7 @@ /* The code below assumes that the endianness of integers matches the endianness of the two 32-bit words of a double. Check this. */ -#if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \ - defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)) +#if defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) #error "doubles and ints have incompatible endianness" #endif diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 711e7bc89b71c0..21d1e036d31540 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -706,8 +706,6 @@ pycore_init_global_objects(PyInterpreterState *interp) { PyStatus status; - _PyFloat_InitState(interp); - status = _PyUnicode_InitGlobalObjects(interp); if (_PyStatus_EXCEPTION(status)) { return status; diff --git a/configure b/configure index 95bb6ba4e84ccf..a3eeef373bf7fb 100755 --- a/configure +++ b/configure @@ -26212,20 +26212,7 @@ printf "%s\n" "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h ;; *) - case $host_cpu in #( - *arm*) : - # Some ARM platforms use a mixed-endian representation for - # doubles. While Python doesn't currently have full support - # for these platforms (see e.g., issue 1762561), we can at - # least make sure that float <-> string conversions work. - # FLOAT_WORDS_BIGENDIAN doesn't actually detect this case, - # but if it's not big or little, then it must be this? - -printf "%s\n" "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h - ;; #( - *) : as_fn_error $? "Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) according to your system." "$LINENO" 5 ;; -esac ;; esac diff --git a/configure.ac b/configure.ac index e049f568417335..75e81761f95e38 100644 --- a/configure.ac +++ b/configure.ac @@ -6178,21 +6178,11 @@ AX_C_FLOAT_WORDS_BIGENDIAN( [AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1], [Define if C doubles are 64-bit IEEE 754 binary format, stored with the least significant byte first])], - [AS_CASE([$host_cpu], - [*arm*], [# Some ARM platforms use a mixed-endian representation for - # doubles. While Python doesn't currently have full support - # for these platforms (see e.g., issue 1762561), we can at - # least make sure that float <-> string conversions work. - # FLOAT_WORDS_BIGENDIAN doesn't actually detect this case, - # but if it's not big or little, then it must be this? - AC_DEFINE([DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754], [1], - [Define if C doubles are 64-bit IEEE 754 binary format, - stored in ARM mixed-endian order (byte order 45670123)])], - [AC_MSG_ERROR([m4_normalize([ + [AC_MSG_ERROR([m4_normalize([ Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) according to your system. - ])])])]) + ])])]) # The short float repr introduced in Python 3.1 requires the # correctly-rounded string <-> double conversion functions from diff --git a/pyconfig.h.in b/pyconfig.h.in index fbd5d4d625908e..9da33c954a52f8 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -32,10 +32,6 @@ /* The Android API level. */ #undef ANDROID_API_LEVEL -/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM - mixed-endian order (byte order 45670123) */ -#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 - /* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most significant byte first */ #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 From 5d6e8dd683b25348bfe45f6321f9734868199a23 Mon Sep 17 00:00:00 2001 From: Shrey Naithani Date: Wed, 11 Mar 2026 17:38:48 +0530 Subject: [PATCH 411/498] gh-145587: fix busy loop in multiprocessing.connection.wait on Windows (GH-145597) Ensure wait() blocks for the specified timeout when object_list is empty, preventing 100% CPU usage. This aligns the Windows behavior with the Unix implementation. Co-authored-by: AN Long --- Lib/multiprocessing/connection.py | 12 ++++++++++-- Lib/test/_test_multiprocessing.py | 13 +++++++++++++ .../2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 41b36066c62fcb..9ce996c9ccd211 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -1085,14 +1085,22 @@ def wait(object_list, timeout=None): Returns list of those objects in object_list which are ready/readable. ''' + object_list = list(object_list) + + if not object_list: + if timeout is None: + while True: + time.sleep(1e6) + elif timeout > 0: + time.sleep(timeout) + return [] + if timeout is None: timeout = INFINITE elif timeout < 0: timeout = 0 else: timeout = int(timeout * 1000 + 0.5) - - object_list = list(object_list) waithandle_to_obj = {} ov_list = [] ready_objects = set() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index cc07062eee6f98..d67fd13fa33bed 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3890,6 +3890,19 @@ def test_context(self): self.assertRaises(OSError, a.recv) self.assertRaises(OSError, b.recv) + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() + def test_wait_empty(self): + if self.TYPE != 'processes': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + # gh-145587: wait() with empty list should respect timeout + timeout = 0.5 + start = time.monotonic() + res = self.connection.wait([], timeout=timeout) + duration = time.monotonic() - start + + self.assertEqual(res, []) + self.assertGreaterEqual(duration, timeout - 0.1) + class _TestListener(BaseTestCase): ALLOWED_TYPES = ('processes',) diff --git a/Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst b/Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst new file mode 100644 index 00000000000000..c17d01f36b8c64 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst @@ -0,0 +1 @@ +Resolved a performance regression in ``multiprocessing.connection.wait`` on Windows that caused infinite busy loops when called with no objects. The function now properly yields control to the OS to conserve CPU resources. Patch By Shrey Naithani From ece712197d2d23bcc80937d122e7b9f07338350e Mon Sep 17 00:00:00 2001 From: Stefan Zetzsche <120379523+stefanzetzsche@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:21:22 +0000 Subject: [PATCH 412/498] gh-145546: unittest.util: fix `sorted_list_difference` tail deduplication (GH-145547) * fix(unittest.util): Deduplicate tail elements in sorted_list_difference sorted_list_difference failed to deduplicate remaining elements when one list was exhausted, causing duplicate values in the result. Deduplicate before extending. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Lib/test/test_unittest/test_util.py | 33 +++++++++++++++++++ Lib/unittest/util.py | 12 +++++-- ...-03-05-14-13-10.gh-issue-145546.3tnlxx.rst | 2 ++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-05-14-13-10.gh-issue-145546.3tnlxx.rst diff --git a/Lib/test/test_unittest/test_util.py b/Lib/test/test_unittest/test_util.py index d590a333930278..09ce09b91b7ac2 100644 --- a/Lib/test/test_unittest/test_util.py +++ b/Lib/test/test_unittest/test_util.py @@ -26,6 +26,39 @@ def test_sorted_list_difference(self): self.assertEqual(sorted_list_difference([2], [1, 1]), ([2], [1])) self.assertEqual(sorted_list_difference([1, 2], [1, 1]), ([2], [])) + def test_sorted_list_difference_tail_deduplication(self): + # Tail deduplication when one list is exhausted before the other. + # These exercise the except-IndexError path in sorted_list_difference. + self.assertEqual(sorted_list_difference([], [0, 0]), ([], [0])) + self.assertEqual(sorted_list_difference([0, 0], []), ([0], [])) + self.assertEqual(sorted_list_difference([], [1, 1, 2, 2]), ([], [1, 2])) + self.assertEqual(sorted_list_difference([1, 1, 2, 2], []), ([1, 2], [])) + # One list exhausts mid-way, leaving duplicated tail in the other. + self.assertEqual(sorted_list_difference([1], [1, 2, 2, 3, 3]), ([], [2, 3])) + self.assertEqual(sorted_list_difference([1, 2, 2, 3, 3], [1]), ([2, 3], [])) + + def test_sorted_list_difference_strings(self): + self.assertEqual( + sorted_list_difference(['a', 'b'], ['b', 'c']), + (['a'], ['c'])) + self.assertEqual( + sorted_list_difference([], ['a', 'a', 'b']), + ([], ['a', 'b'])) + self.assertEqual( + sorted_list_difference(['a', 'a', 'b'], []), + (['a', 'b'], [])) + + def test_sorted_list_difference_unhashable(self): + self.assertEqual( + sorted_list_difference([[1], [2]], [[2], [3]]), + ([[1]], [[3]])) + self.assertEqual( + sorted_list_difference([], [[0], [0]]), + ([], [[0]])) + self.assertEqual( + sorted_list_difference([[0], [0]], []), + ([[0]], [])) + def test_unorderable_list_difference(self): self.assertEqual(unorderable_list_difference([], []), ([], [])) self.assertEqual(unorderable_list_difference([1, 2], []), ([2, 1], [])) diff --git a/Lib/unittest/util.py b/Lib/unittest/util.py index c7e6b941978cd5..0681163c979587 100644 --- a/Lib/unittest/util.py +++ b/Lib/unittest/util.py @@ -63,6 +63,14 @@ def safe_repr(obj, short=False): def strclass(cls): return "%s.%s" % (cls.__module__, cls.__qualname__) +def _dedupe_sorted(lst): + """Remove consecutive duplicate elements from a sorted list.""" + result = [] + for item in lst: + if not result or result[-1] != item: + result.append(item) + return result + def sorted_list_difference(expected, actual): """Finds elements in only one or the other of two, sorted input lists. @@ -98,8 +106,8 @@ def sorted_list_difference(expected, actual): while actual[j] == a: j += 1 except IndexError: - missing.extend(expected[i:]) - unexpected.extend(actual[j:]) + missing.extend(_dedupe_sorted(expected[i:])) + unexpected.extend(_dedupe_sorted(actual[j:])) break return missing, unexpected diff --git a/Misc/NEWS.d/next/Library/2026-03-05-14-13-10.gh-issue-145546.3tnlxx.rst b/Misc/NEWS.d/next/Library/2026-03-05-14-13-10.gh-issue-145546.3tnlxx.rst new file mode 100644 index 00000000000000..e9401bb08c6774 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-05-14-13-10.gh-issue-145546.3tnlxx.rst @@ -0,0 +1,2 @@ +Fix ``unittest.util.sorted_list_difference()`` to deduplicate remaining +elements when one input list is exhausted before the other. From eb9ae65e5b1cdfcf4f60d36c0353c857bc27b92f Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:29:43 +0000 Subject: [PATCH 413/498] Warn that overriding `__builtins__` for `eval` is not a security mechanism (GH-145773) Co-authored-by: Ned Batchelder --- Doc/library/functions.rst | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 1d83cb6f2bb688..483e5b1d8fdba7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -606,17 +606,18 @@ are always available. They are listed here in alphabetical order. .. warning:: This function executes arbitrary code. Calling it with - user-supplied input may lead to security vulnerabilities. + untrusted user-supplied input will lead to security vulnerabilities. The *source* argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the *globals* and *locals* mappings as global and local namespace. If the *globals* dictionary is present and does not contain a value for the key ``__builtins__``, a reference to the dictionary of the built-in module :mod:`builtins` is - inserted under that key before *source* is parsed. That way you can - control what builtins are available to the executed code by inserting your - own ``__builtins__`` dictionary into *globals* before passing it to - :func:`eval`. If the *locals* mapping is omitted it defaults to the + inserted under that key before *source* is parsed. + Overriding ``__builtins__`` can be used to restrict or change the available + names, but this is **not** a security mechanism: the executed code can + still access all builtins. + If the *locals* mapping is omitted it defaults to the *globals* dictionary. If both mappings are omitted, the source is executed with the *globals* and *locals* in the environment where :func:`eval` is called. Note, *eval()* will only have access to the @@ -671,7 +672,7 @@ are always available. They are listed here in alphabetical order. .. warning:: This function executes arbitrary code. Calling it with - user-supplied input may lead to security vulnerabilities. + untrusted user-supplied input will lead to security vulnerabilities. This function supports dynamic execution of Python code. *source* must be either a string or a code object. If it is a string, the string is parsed as @@ -702,9 +703,10 @@ are always available. They are listed here in alphabetical order. If the *globals* dictionary does not contain a value for the key ``__builtins__``, a reference to the dictionary of the built-in module - :mod:`builtins` is inserted under that key. That way you can control what - builtins are available to the executed code by inserting your own - ``__builtins__`` dictionary into *globals* before passing it to :func:`exec`. + :mod:`builtins` is inserted under that key. + Overriding ``__builtins__`` can be used to restrict or change the available + names, but this is **not** a security mechanism: the executed code can + still access all builtins. The *closure* argument specifies a closure--a tuple of cellvars. It's only valid when the *object* is a code object containing From aa4240ebea1aacc907b1efa58e7f547d90cff3b1 Mon Sep 17 00:00:00 2001 From: Thomas Kowalski Date: Wed, 11 Mar 2026 14:02:23 +0100 Subject: [PATCH 414/498] gh-145492: fix regression test for defaultdict factory repr (GH-145788) --- Lib/test/test_defaultdict.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 732e9a876ca8ad..a193eb10f16d17 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -212,12 +212,12 @@ def __call__(self): return {} def __repr__(self): repr(dd) - return "ProblematicFactory()" + return f"ProblematicFactory for {dd}" dd = defaultdict(ProblematicFactory()) # Should not raise RecursionError r = repr(dd) - self.assertIn('ProblematicFactory()', r) + self.assertIn("ProblematicFactory for", r) if __name__ == "__main__": unittest.main() From 4f87c99a5ae9c74a5f94b91335d85f4662e1ed48 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 11 Mar 2026 14:24:15 +0100 Subject: [PATCH 415/498] gh-145376: Fix refleak & pointer type bug in uncommon code paths in Parser/ (GH-145684) --- Parser/pegen.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Parser/pegen.c b/Parser/pegen.c index 7ecc55eee13775..569f5afb312008 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -924,7 +924,6 @@ _PyPegen_set_syntax_error_metadata(Parser *p) { the_source // N gives ownership to metadata ); if (!metadata) { - Py_DECREF(the_source); PyErr_Clear(); return; } @@ -1026,8 +1025,8 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena if (tok->fp_interactive && tok->interactive_src_start && result && interactive_src != NULL) { *interactive_src = PyUnicode_FromString(tok->interactive_src_start); - if (!interactive_src || _PyArena_AddPyObject(arena, *interactive_src) < 0) { - Py_XDECREF(interactive_src); + if (!*interactive_src || _PyArena_AddPyObject(arena, *interactive_src) < 0) { + Py_XDECREF(*interactive_src); result = NULL; goto error; } From ce1abaf9b83f8535749c6d3d0a0fabf15d87079f Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Wed, 11 Mar 2026 16:25:24 +0300 Subject: [PATCH 416/498] gh-99875: Document rounding mode for old-style formatting (#126382) --- Doc/library/stdtypes.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index a70bda47da6f43..6b55daa9b6eae0 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3202,6 +3202,10 @@ The conversion types are: | | character in the result. | | +------------+-----------------------------------------------------+-------+ +For floating-point formats, the result should be correctly rounded to a given +precision ``p`` of digits after the decimal point. The rounding mode matches +that of the :func:`round` builtin. + Notes: (1) From 42d754e34c06e57ad6b8e7f92f32af679912d8ab Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Wed, 11 Mar 2026 08:47:55 -0500 Subject: [PATCH 417/498] gh-141707: Skip TarInfo DIRTYPE normalization during GNU long name handling Co-authored-by: Eashwar Ranganathan --- Lib/tarfile.py | 29 ++++++++++++++++--- Lib/test/test_tarfile.py | 19 ++++++++++++ Misc/ACKS | 1 + ...-11-18-06-35-53.gh-issue-141707.DBmQIy.rst | 2 ++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 7abda3653e764b..7f0b0b3c632573 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -1276,6 +1276,20 @@ def _create_pax_generic_header(cls, pax_headers, type, encoding): @classmethod def frombuf(cls, buf, encoding, errors): """Construct a TarInfo object from a 512 byte bytes object. + + To support the old v7 tar format AREGTYPE headers are + transformed to DIRTYPE headers if their name ends in '/'. + """ + return cls._frombuf(buf, encoding, errors) + + @classmethod + def _frombuf(cls, buf, encoding, errors, *, dircheck=True): + """Construct a TarInfo object from a 512 byte bytes object. + + If ``dircheck`` is set to ``True`` then ``AREGTYPE`` headers will + be normalized to ``DIRTYPE`` if the name ends in a trailing slash. + ``dircheck`` must be set to ``False`` if this function is called + on a follow-up header such as ``GNUTYPE_LONGNAME``. """ if len(buf) == 0: raise EmptyHeaderError("empty header") @@ -1306,7 +1320,7 @@ def frombuf(cls, buf, encoding, errors): # Old V7 tar format represents a directory as a regular # file with a trailing slash. - if obj.type == AREGTYPE and obj.name.endswith("/"): + if dircheck and obj.type == AREGTYPE and obj.name.endswith("/"): obj.type = DIRTYPE # The old GNU sparse format occupies some of the unused @@ -1341,8 +1355,15 @@ def fromtarfile(cls, tarfile): """Return the next TarInfo object from TarFile object tarfile. """ + return cls._fromtarfile(tarfile) + + @classmethod + def _fromtarfile(cls, tarfile, *, dircheck=True): + """ + See dircheck documentation in _frombuf(). + """ buf = tarfile.fileobj.read(BLOCKSIZE) - obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj = cls._frombuf(buf, tarfile.encoding, tarfile.errors, dircheck=dircheck) obj.offset = tarfile.fileobj.tell() - BLOCKSIZE return obj._proc_member(tarfile) @@ -1400,7 +1421,7 @@ def _proc_gnulong(self, tarfile): # Fetch the next header and process it. try: - next = self.fromtarfile(tarfile) + next = self._fromtarfile(tarfile, dircheck=False) except HeaderError as e: raise SubsequentHeaderError(str(e)) from None @@ -1535,7 +1556,7 @@ def _proc_pax(self, tarfile): # Fetch the next header. try: - next = self.fromtarfile(tarfile) + next = self._fromtarfile(tarfile, dircheck=False) except HeaderError as e: raise SubsequentHeaderError(str(e)) from None diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 139840dd9c1f1b..f2babaacc27d96 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1234,6 +1234,25 @@ def test_longname_directory(self): self.assertIsNotNone(tar.getmember(longdir)) self.assertIsNotNone(tar.getmember(longdir.removesuffix('/'))) + def test_longname_file_not_directory(self): + # Test reading a longname file and ensure it is not handled as a directory + # Issue #141707 + buf = io.BytesIO() + with tarfile.open(mode='w', fileobj=buf, format=self.format) as tar: + ti = tarfile.TarInfo() + ti.type = tarfile.AREGTYPE + ti.name = ('a' * 99) + '/' + ('b' * 3) + tar.addfile(ti) + + expected = {t.name: t.type for t in tar.getmembers()} + + buf.seek(0) + with tarfile.open(mode='r', fileobj=buf) as tar: + actual = {t.name: t.type for t in tar.getmembers()} + + self.assertEqual(expected, actual) + + class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase): subdir = "gnu" diff --git a/Misc/ACKS b/Misc/ACKS index 88c0a68f1e6c87..d7762f8c875fa9 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1557,6 +1557,7 @@ Ashwin Ramaswami Jeff Ramnani Grant Ramsay Bayard Randel +Eashwar Ranganathan Varpu Rantala Brodie Rao Rémi Rampin diff --git a/Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst b/Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst new file mode 100644 index 00000000000000..1f5b8ed90b8a90 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst @@ -0,0 +1,2 @@ +Don't change :class:`tarfile.TarInfo` type from ``AREGTYPE`` to ``DIRTYPE`` when parsing +GNU long name or link headers. From 805ca4f292ef18b89a2d25246feb916973acec64 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Wed, 11 Mar 2026 08:51:25 -0500 Subject: [PATCH 418/498] Add GitHub team for maintaining fuzzers Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- .github/CODEOWNERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5bf60348f68250..63ec65ac0dbd8d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,7 +132,9 @@ Tools/c-analyzer/ @ericsnowcurrently Tools/check-c-api-docs/ @ZeroIntensity # Fuzzing -Modules/_xxtestfuzz/ @ammaraskar +Modules/_xxtestfuzz/ @python/fuzzers +Lib/test/test_xxtestfuzz.py @python/fuzzers +.github/workflows/reusable-cifuzz.yml @python/fuzzers # Limited C API & Stable ABI Doc/c-api/stable.rst @encukou From 7a1da4575b1d8fa87efb62334a8e99cd513d86e9 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Wed, 11 Mar 2026 15:14:47 +0100 Subject: [PATCH 419/498] gh-142518: Improve mimalloc allocator docs (#145224) --- Doc/c-api/memory.rst | 61 ++++++++++++++++++++++++++++++----------- Doc/using/cmdline.rst | 14 ++++++++-- Doc/using/configure.rst | 3 ++ 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 563c5d96b05362..9f84e4bc6dfd91 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -204,8 +204,11 @@ The following function sets, modeled after the ANSI C standard, but specifying behavior when requesting zero bytes, are available for allocating and releasing memory from the Python heap. -The :ref:`default memory allocator ` uses the -:ref:`pymalloc memory allocator `. +In the GIL-enabled build (default build) the +:ref:`default memory allocator ` uses the +:ref:`pymalloc memory allocator `, whereas in the +:term:`free-threaded build`, the default is the +:ref:`mimalloc memory allocator ` instead. .. warning:: @@ -215,6 +218,11 @@ The :ref:`default memory allocator ` uses the The default allocator is now pymalloc instead of system :c:func:`malloc`. +.. versionchanged:: 3.13 + + In the :term:`free-threaded ` build, the default allocator + is now :ref:`mimalloc `. + .. c:function:: void* PyMem_Malloc(size_t n) Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the @@ -340,7 +348,9 @@ memory from the Python heap. the :ref:`Customize Memory Allocators ` section. The :ref:`default object allocator ` uses the -:ref:`pymalloc memory allocator `. +:ref:`pymalloc memory allocator `. In the +:term:`free-threaded ` build, the default is the +:ref:`mimalloc memory allocator ` instead. .. warning:: @@ -420,14 +430,16 @@ Default Memory Allocators Default memory allocators: -=============================== ==================== ================== ===================== ==================== -Configuration Name PyMem_RawMalloc PyMem_Malloc PyObject_Malloc -=============================== ==================== ================== ===================== ==================== -Release build ``"pymalloc"`` ``malloc`` ``pymalloc`` ``pymalloc`` -Debug build ``"pymalloc_debug"`` ``malloc`` + debug ``pymalloc`` + debug ``pymalloc`` + debug -Release build, without pymalloc ``"malloc"`` ``malloc`` ``malloc`` ``malloc`` -Debug build, without pymalloc ``"malloc_debug"`` ``malloc`` + debug ``malloc`` + debug ``malloc`` + debug -=============================== ==================== ================== ===================== ==================== +=================================== ======================= ==================== ====================== ====================== +Configuration Name PyMem_RawMalloc PyMem_Malloc PyObject_Malloc +=================================== ======================= ==================== ====================== ====================== +Release build ``"pymalloc"`` ``malloc`` ``pymalloc`` ``pymalloc`` +Debug build ``"pymalloc_debug"`` ``malloc`` + debug ``pymalloc`` + debug ``pymalloc`` + debug +Release build, without pymalloc ``"malloc"`` ``malloc`` ``malloc`` ``malloc`` +Debug build, without pymalloc ``"malloc_debug"`` ``malloc`` + debug ``malloc`` + debug ``malloc`` + debug +Free-threaded build ``"mimalloc"`` ``mimalloc`` ``mimalloc`` ``mimalloc`` +Free-threaded debug build ``"mimalloc_debug"`` ``mimalloc`` + debug ``mimalloc`` + debug ``mimalloc`` + debug +=================================== ======================= ==================== ====================== ====================== Legend: @@ -435,8 +447,7 @@ Legend: * ``malloc``: system allocators from the standard C library, C functions: :c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`. * ``pymalloc``: :ref:`pymalloc memory allocator `. -* ``mimalloc``: :ref:`mimalloc memory allocator `. The pymalloc - allocator will be used if mimalloc support isn't available. +* ``mimalloc``: :ref:`mimalloc memory allocator `. * "+ debug": with :ref:`debug hooks on the Python memory allocators `. * "Debug build": :ref:`Python build in debug mode `. @@ -733,9 +744,27 @@ The mimalloc allocator .. versionadded:: 3.13 -Python supports the mimalloc allocator when the underlying platform support is available. -mimalloc "is a general purpose allocator with excellent performance characteristics. -Initially developed by Daan Leijen for the runtime systems of the Koka and Lean languages." +Python supports the `mimalloc `__ +allocator when the underlying platform support is available. +mimalloc is a general purpose allocator with excellent performance +characteristics, initially developed by Daan Leijen for the runtime systems +of the Koka and Lean languages. + +Unlike :ref:`pymalloc `, which is optimized for small objects (512 +bytes or fewer), mimalloc handles allocations of any size. + +In the :term:`free-threaded ` build, mimalloc is the default +and **required** allocator for the :c:macro:`PYMEM_DOMAIN_MEM` and +:c:macro:`PYMEM_DOMAIN_OBJ` domains. It cannot be disabled in free-threaded +builds. The free-threaded build uses per-thread mimalloc heaps, which allows +allocation and deallocation to proceed without locking in most cases. + +In the default (non-free-threaded) build, mimalloc is available but not the +default allocator. It can be selected at runtime using +:envvar:`PYTHONMALLOC`\ ``=mimalloc`` (or ``mimalloc_debug`` to include +:ref:`debug hooks `). It can be disabled at build time +using the :option:`--without-mimalloc` configure option, but this option +cannot be combined with :option:`--disable-gil`. tracemalloc C API ================= diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 5c3d44395c0039..ce6872f3c0fda3 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -1085,6 +1085,13 @@ conflict. * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks. * ``mimalloc_debug``: same as ``mimalloc`` but also install debug hooks. + .. note:: + + In the :term:`free-threaded ` build, the ``malloc``, + ``malloc_debug``, ``pymalloc``, and ``pymalloc_debug`` values are not + supported. Only ``default``, ``debug``, ``mimalloc``, and + ``mimalloc_debug`` are accepted. + .. versionadded:: 3.6 .. versionchanged:: 3.7 @@ -1094,12 +1101,13 @@ conflict. .. envvar:: PYTHONMALLOCSTATS If set to a non-empty string, Python will print statistics of the - :ref:`pymalloc memory allocator ` every time a new pymalloc object - arena is created, and on shutdown. + :ref:`pymalloc memory allocator ` or the + :ref:`mimalloc memory allocator ` (whichever is in use) + every time a new object arena is created, and on shutdown. This variable is ignored if the :envvar:`PYTHONMALLOC` environment variable is used to force the :c:func:`malloc` allocator of the C library, or if - Python is configured without ``pymalloc`` support. + Python is configured without both ``pymalloc`` and ``mimalloc`` support. .. versionchanged:: 3.6 This variable can now also be used on Python compiled in release mode. diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 813127663ed8fe..6bef290d181fc9 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -774,6 +774,9 @@ also be used to improve performance. Disable the fast :ref:`mimalloc ` allocator (enabled by default). + This option cannot be used together with :option:`--disable-gil` + because the :term:`free-threaded ` build requires mimalloc. + See also :envvar:`PYTHONMALLOC` environment variable. .. option:: --without-pymalloc From 4722202a1a81974089801e6173d269836b6a074f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:30:09 +0100 Subject: [PATCH 420/498] gh-139933: correctly suggest attributes for classes with a custom `__dir__` (GH-139950) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Łukasz Langa --- Lib/test/test_traceback.py | 21 ++++++++++++++ Lib/traceback.py | 29 ++++++++++--------- ...-10-11-11-50-59.gh-issue-139933.05MHlx.rst | 3 ++ 3 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-10-11-11-50-59.gh-issue-139933.05MHlx.rst diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 2fbc2a041269f4..14a08995bf127c 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4213,6 +4213,27 @@ def method(self, name): self.assertIn("'._bluch'", self.get_suggestion(partial(B().method, '_luch'))) self.assertIn("'._bluch'", self.get_suggestion(partial(B().method, 'bluch'))) + def test_suggestions_with_custom___dir__(self): + class M(type): + def __dir__(cls): + return [None, "fox"] + + class C0: + def __dir__(self): + return [..., "bluch"] + + class C1(C0, metaclass=M): + pass + + self.assertNotIn("'.bluch'", self.get_suggestion(C0, "blach")) + self.assertIn("'.bluch'", self.get_suggestion(C0(), "blach")) + + self.assertIn("'.fox'", self.get_suggestion(C1, "foo")) + self.assertNotIn("'.fox'", self.get_suggestion(C1(), "foo")) + + self.assertNotIn("'.bluch'", self.get_suggestion(C1, "blach")) + self.assertIn("'.bluch'", self.get_suggestion(C1(), "blach")) + def test_do_not_trigger_for_long_attributes(self): class A: diff --git a/Lib/traceback.py b/Lib/traceback.py index 4e809acb7a01bb..956cab49131990 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1698,6 +1698,19 @@ def _check_for_nested_attribute(obj, wrong_name, attrs): return None +def _get_safe___dir__(obj): + # Use obj.__dir__() to avoid a TypeError when calling dir(obj). + # See gh-131001 and gh-139933. + # Also filters out lazy imports to avoid triggering module loading. + try: + d = obj.__dir__() + except TypeError: # when obj is a class + d = type(obj).__dir__(obj) + return sorted( + x for x in d if isinstance(x, str) and not _is_lazy_import(obj, x) + ) + + def _compute_suggestion_error(exc_value, tb, wrong_name): if wrong_name is None or not isinstance(wrong_name, str): return None @@ -1711,13 +1724,7 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): if isinstance(exc_value, AttributeError): obj = exc_value.obj try: - try: - d = dir(obj) - except TypeError: # Attributes are unsortable, e.g. int and str - d = list(obj.__class__.__dict__.keys()) + list(obj.__dict__.keys()) - d = sorted([x for x in d if isinstance(x, str)]) - # Filter out lazy imports to avoid triggering module loading - d = [x for x in d if not _is_lazy_import(obj, x)] + d = _get_safe___dir__(obj) hide_underscored = (wrong_name[:1] != '_') if hide_underscored and tb is not None: while tb.tb_next is not None: @@ -1744,13 +1751,7 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): elif isinstance(exc_value, ImportError): try: mod = __import__(exc_value.name) - try: - d = dir(mod) - except TypeError: # Attributes are unsortable, e.g. int and str - d = list(mod.__dict__.keys()) - d = sorted([x for x in d if isinstance(x, str)]) - # Filter out lazy imports to avoid triggering module loading - d = [x for x in d if not _is_lazy_import(mod, x)] + d = _get_safe___dir__(mod) if wrong_name[:1] != '_': d = [x for x in d if x[:1] != '_'] except Exception: diff --git a/Misc/NEWS.d/next/Library/2025-10-11-11-50-59.gh-issue-139933.05MHlx.rst b/Misc/NEWS.d/next/Library/2025-10-11-11-50-59.gh-issue-139933.05MHlx.rst new file mode 100644 index 00000000000000..d76f0873d77265 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-11-11-50-59.gh-issue-139933.05MHlx.rst @@ -0,0 +1,3 @@ +Improve :exc:`AttributeError` suggestions for classes with a custom +:meth:`~object.__dir__` method returning a list of unsortable values. +Patch by Bénédikt Tran. From 706fd4ec08acbf1b1def3630017ebe55d224adfa Mon Sep 17 00:00:00 2001 From: "T. Wouters" Date: Wed, 11 Mar 2026 15:46:16 +0100 Subject: [PATCH 421/498] gh-142183: Cache one datachunk per tstate to prevent alloc/dealloc thrashing (#145789) Cache one datachunk per tstate to prevent alloc/dealloc thrashing when repeatedly hitting the same call depth at exactly the wrong boundary. --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Include/cpython/pystate.h | 1 + ...-03-11-00-13-59.gh-issue-142183.2iVhJH.rst | 1 + Python/pystate.c | 30 ++++++++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 22df26bd37a5c5..1c56ad5af8072f 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -198,6 +198,7 @@ struct _ts { _PyStackChunk *datastack_chunk; PyObject **datastack_top; PyObject **datastack_limit; + _PyStackChunk *datastack_cached_chunk; /* XXX signal handlers should also be here */ /* The following fields are here to avoid allocation during init. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst new file mode 100644 index 00000000000000..827224dc71e827 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst @@ -0,0 +1 @@ +Avoid a pathological case where repeated calls at a specific stack depth could be significantly slower. diff --git a/Python/pystate.c b/Python/pystate.c index a8f37bedc81247..17b8430b19c188 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1564,6 +1564,7 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->datastack_chunk = NULL; tstate->datastack_top = NULL; tstate->datastack_limit = NULL; + tstate->datastack_cached_chunk = NULL; tstate->what_event = -1; tstate->current_executor = NULL; tstate->jit_exit = NULL; @@ -1714,6 +1715,11 @@ clear_datastack(PyThreadState *tstate) _PyObject_VirtualFree(chunk, chunk->size); chunk = prev; } + if (tstate->datastack_cached_chunk != NULL) { + _PyObject_VirtualFree(tstate->datastack_cached_chunk, + tstate->datastack_cached_chunk->size); + tstate->datastack_cached_chunk = NULL; + } } void @@ -3045,9 +3051,20 @@ push_chunk(PyThreadState *tstate, int size) while (allocate_size < (int)sizeof(PyObject*)*(size + MINIMUM_OVERHEAD)) { allocate_size *= 2; } - _PyStackChunk *new = allocate_chunk(allocate_size, tstate->datastack_chunk); - if (new == NULL) { - return NULL; + _PyStackChunk *new; + if (tstate->datastack_cached_chunk != NULL + && (size_t)allocate_size <= tstate->datastack_cached_chunk->size) + { + new = tstate->datastack_cached_chunk; + tstate->datastack_cached_chunk = NULL; + new->previous = tstate->datastack_chunk; + new->top = 0; + } + else { + new = allocate_chunk(allocate_size, tstate->datastack_chunk); + if (new == NULL) { + return NULL; + } } if (tstate->datastack_chunk) { tstate->datastack_chunk->top = tstate->datastack_top - @@ -3083,12 +3100,17 @@ _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) if (base == &tstate->datastack_chunk->data[0]) { _PyStackChunk *chunk = tstate->datastack_chunk; _PyStackChunk *previous = chunk->previous; + _PyStackChunk *cached = tstate->datastack_cached_chunk; // push_chunk ensures that the root chunk is never popped: assert(previous); tstate->datastack_top = &previous->data[previous->top]; tstate->datastack_chunk = previous; - _PyObject_VirtualFree(chunk, chunk->size); tstate->datastack_limit = (PyObject **)(((char *)previous) + previous->size); + chunk->previous = NULL; + if (cached != NULL) { + _PyObject_VirtualFree(cached, cached->size); + } + tstate->datastack_cached_chunk = chunk; } else { assert(tstate->datastack_top); From 713be70175a2dad477a1cf5e7c00bab0edda04ad Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 11 Mar 2026 17:05:09 +0100 Subject: [PATCH 422/498] gh-141510: Raise TypeError in PyDict_SetItem() on frozendict (#145564) If the following functions get an unexpected frozendict, raise TypeError instead of SystemError: * PyDict_DelItem() * PyDict_DelItemString() * PyDict_Merge() * PyDict_MergeFromSeq2() * PyDict_Pop() * PyDict_PopString() * PyDict_SetDefault() * PyDict_SetDefaultRef() * PyDict_SetItem() * PyDict_SetItemString() * _PyDict_SetItem_KnownHash() * PyDict_Update() Co-authored-by: mohsinm-dev --- Lib/test/test_capi/test_dict.py | 62 ++++++++++++++++++---- Objects/dictobject.c | 94 +++++++++++++++++++++++++-------- 2 files changed, 124 insertions(+), 32 deletions(-) diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index cd46fea5476ca6..4cf404e9f56327 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -1,3 +1,4 @@ +import contextlib import unittest from collections import OrderedDict, UserDict from types import MappingProxyType @@ -258,6 +259,12 @@ def test_dict_contains_string(self): # CRASHES contains({}, NULL) # CRASHES contains(NULL, b'a') + @contextlib.contextmanager + def frozendict_does_not_support(self, what): + errmsg = f'frozendict object does not support item {what}' + with self.assertRaisesRegex(TypeError, errmsg): + yield + def test_dict_setitem(self): # Test PyDict_SetItem() setitem = _testlimitedcapi.dict_setitem @@ -269,7 +276,10 @@ def test_dict_setitem(self): self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + setitem(test_type(), 'a', 5) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, setitem, test_type(), 'a', 5) # CRASHES setitem({}, NULL, 5) # CRASHES setitem({}, 'a', NULL) @@ -286,7 +296,10 @@ def test_dict_setitemstring(self): self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) self.assertRaises(UnicodeDecodeError, setitemstring, {}, INVALID_UTF8, 5) - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + setitemstring(test_type(), b'a', 5) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, setitemstring, test_type(), b'a', 5) # CRASHES setitemstring({}, NULL, 5) # CRASHES setitemstring({}, b'a', NULL) @@ -304,7 +317,10 @@ def test_dict_delitem(self): self.assertEqual(dct, {'c': 2}) self.assertRaises(TypeError, delitem, {}, []) # unhashable - for test_type in NOT_DICT_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('deletion'): + delitem(test_type({'a': 1}), 'a') + for test_type in MAPPING_TYPES: self.assertRaises(SystemError, delitem, test_type({'a': 1}), 'a') for test_type in OTHER_TYPES: self.assertRaises(SystemError, delitem, test_type(), 'a') @@ -323,7 +339,10 @@ def test_dict_delitemstring(self): self.assertEqual(dct, {'c': 2}) self.assertRaises(UnicodeDecodeError, delitemstring, {}, INVALID_UTF8) - for test_type in NOT_DICT_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('deletion'): + delitemstring(test_type({'a': 1}), b'a') + for test_type in MAPPING_TYPES: self.assertRaises(SystemError, delitemstring, test_type({'a': 1}), b'a') for test_type in OTHER_TYPES: self.assertRaises(SystemError, delitemstring, test_type(), b'a') @@ -341,7 +360,10 @@ def test_dict_setdefault(self): self.assertEqual(dct, {'a': 5}) self.assertRaises(TypeError, setdefault, {}, [], 5) # unhashable - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + setdefault(test_type(), 'a', 5) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, setdefault, test_type(), 'a', 5) # CRASHES setdefault({}, NULL, 5) # CRASHES setdefault({}, 'a', NULL) @@ -358,7 +380,10 @@ def test_dict_setdefaultref(self): self.assertEqual(dct, {'a': 5}) self.assertRaises(TypeError, setdefault, {}, [], 5) # unhashable - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + setdefault(test_type(), 'a', 5) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, setdefault, test_type(), 'a', 5) # CRASHES setdefault({}, NULL, 5) # CRASHES setdefault({}, 'a', NULL) @@ -424,7 +449,10 @@ def test_dict_update(self): self.assertRaises(AttributeError, update, {}, []) self.assertRaises(AttributeError, update, {}, 42) - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + update(test_type(), {}) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, update, test_type(), {}) self.assertRaises(SystemError, update, {}, NULL) self.assertRaises(SystemError, update, NULL, {}) @@ -443,7 +471,10 @@ def test_dict_merge(self): self.assertRaises(AttributeError, merge, {}, [], 0) self.assertRaises(AttributeError, merge, {}, 42, 0) - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + merge(test_type(), {}, 0) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, merge, test_type(), {}, 0) self.assertRaises(SystemError, merge, {}, NULL, 0) self.assertRaises(SystemError, merge, NULL, {}, 0) @@ -464,7 +495,10 @@ def test_dict_mergefromseq2(self): self.assertRaises(ValueError, mergefromseq2, {}, [(1, 2, 3)], 0) self.assertRaises(TypeError, mergefromseq2, {}, [1], 0) self.assertRaises(TypeError, mergefromseq2, {}, 42, 0) - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('assignment'): + mergefromseq2(test_type(), [], 0) + for test_type in MAPPING_TYPES + OTHER_TYPES: self.assertRaises(SystemError, mergefromseq2, test_type(), [], 0) # CRASHES mergefromseq2({}, NULL, 0) # CRASHES mergefromseq2(NULL, {}, 0) @@ -511,7 +545,10 @@ def test_dict_pop(self): dict_pop(mydict, not_hashable_key) # wrong dict type - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('deletion'): + dict_pop(test_type(), "key") + for test_type in MAPPING_TYPES + OTHER_TYPES: not_dict = test_type() self.assertRaises(SystemError, dict_pop, not_dict, "key") self.assertRaises(SystemError, dict_pop_null, not_dict, "key") @@ -560,7 +597,10 @@ def test_dict_popstring(self): self.assertRaises(UnicodeDecodeError, dict_popstring_null, mydict, INVALID_UTF8) # wrong dict type - for test_type in NOT_DICT_TYPES + OTHER_TYPES: + for test_type in FROZENDICT_TYPES: + with self.frozendict_does_not_support('deletion'): + dict_popstring(test_type(), "key") + for test_type in MAPPING_TYPES + OTHER_TYPES: not_dict = test_type() self.assertRaises(SystemError, dict_popstring, not_dict, "key") self.assertRaises(SystemError, dict_popstring_null, not_dict, "key") diff --git a/Objects/dictobject.c b/Objects/dictobject.c index b5f2a682c54982..842d9be73b8792 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2719,6 +2719,10 @@ _PyDict_LoadBuiltinsFromGlobals(PyObject *globals) return builtins; } +#define frozendict_does_not_support(WHAT) \ + PyErr_SetString(PyExc_TypeError, "frozendict object does " \ + "not support item " WHAT) + /* Consumes references to key and value */ static int setitem_take2_lock_held(PyDictObject *mp, PyObject *key, PyObject *value) @@ -2762,12 +2766,19 @@ _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) int PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) { + assert(key); + assert(value); + if (!PyDict_Check(op)) { - PyErr_BadInternalCall(); + if (PyFrozenDict_Check(op)) { + frozendict_does_not_support("assignment"); + } + else { + PyErr_BadInternalCall(); + } return -1; } - assert(key); - assert(value); + return _PyDict_SetItem_Take2((PyDictObject *)op, Py_NewRef(key), Py_NewRef(value)); } @@ -2807,14 +2818,20 @@ int _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, Py_hash_t hash) { - if (!PyDict_Check(op)) { - PyErr_BadInternalCall(); - return -1; - } assert(key); assert(value); assert(hash != -1); + if (!PyDict_Check(op)) { + if (PyFrozenDict_Check(op)) { + frozendict_does_not_support("assignment"); + } + else { + PyErr_BadInternalCall(); + } + return -1; + } + int res; Py_BEGIN_CRITICAL_SECTION(op); res = _PyDict_SetItem_KnownHash_LockHeld((PyDictObject *)op, key, value, hash); @@ -2899,13 +2916,18 @@ PyDict_DelItem(PyObject *op, PyObject *key) int _PyDict_DelItem_KnownHash_LockHeld(PyObject *op, PyObject *key, Py_hash_t hash) { - Py_ssize_t ix; - PyObject *old_value; - if (!PyDict_Check(op)) { - PyErr_BadInternalCall(); + if (PyFrozenDict_Check(op)) { + frozendict_does_not_support("deletion"); + } + else { + PyErr_BadInternalCall(); + } return -1; } + + Py_ssize_t ix; + PyObject *old_value; PyDictObject *mp = (PyDictObject *)op; assert(can_modify_dict(mp)); @@ -3206,7 +3228,12 @@ pop_lock_held(PyObject *op, PyObject *key, PyObject **result) if (result) { *result = NULL; } - PyErr_BadInternalCall(); + if (PyFrozenDict_Check(op)) { + frozendict_does_not_support("deletion"); + } + else { + PyErr_BadInternalCall(); + } return -1; } PyDictObject *dict = (PyDictObject *)op; @@ -4017,7 +4044,12 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) assert(d != NULL); assert(seq2 != NULL); if (!PyDict_Check(d)) { - PyErr_BadInternalCall(); + if (PyFrozenDict_Check(d)) { + frozendict_does_not_support("assignment"); + } + else { + PyErr_BadInternalCall(); + } return -1; } @@ -4220,7 +4252,12 @@ dict_merge_api(PyObject *a, PyObject *b, int override) * PyMapping_Keys() and PyObject_GetItem() be supported. */ if (a == NULL || !PyDict_Check(a) || b == NULL) { - PyErr_BadInternalCall(); + if (a != NULL && PyFrozenDict_Check(a)) { + frozendict_does_not_support("assignment"); + } + else { + PyErr_BadInternalCall(); + } return -1; } return dict_merge(a, b, override); @@ -4596,13 +4633,13 @@ static int dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_value, PyObject **result, int incref_result) { - PyDictObject *mp = (PyDictObject *)d; - PyObject *value; - Py_hash_t hash; - Py_ssize_t ix; - if (!PyDict_Check(d)) { - PyErr_BadInternalCall(); + if (PyFrozenDict_Check(d)) { + frozendict_does_not_support("assignment"); + } + else { + PyErr_BadInternalCall(); + } if (result) { *result = NULL; } @@ -4610,6 +4647,11 @@ dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_valu } assert(can_modify_dict((PyDictObject*)d)); + PyDictObject *mp = (PyDictObject *)d; + PyObject *value; + Py_hash_t hash; + Py_ssize_t ix; + hash = _PyObject_HashFast(key); if (hash == -1) { dict_unhashable_type(d, key); @@ -7154,7 +7196,17 @@ int _PyDict_SetItem_LockHeld(PyDictObject *dict, PyObject *name, PyObject *value) { if (!PyDict_Check(dict)) { - PyErr_BadInternalCall(); + if (PyFrozenDict_Check(dict)) { + if (value == NULL) { + frozendict_does_not_support("deletion"); + } + else { + frozendict_does_not_support("assignment"); + } + } + else { + PyErr_BadInternalCall(); + } return -1; } From 77d6d5d8fcc8565034dac378b2184131af735512 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 11 Mar 2026 21:01:03 +0200 Subject: [PATCH 423/498] gh-145736: Fix Tkinter tests for Tk 8.7, 9.0 and 9.1 (GH-145738) --- Lib/test/test_tkinter/test_widgets.py | 230 +++++++++++--------------- Lib/test/test_tkinter/widget_tests.py | 90 ++++------ Lib/test/test_ttk/test_widgets.py | 4 +- 3 files changed, 129 insertions(+), 195 deletions(-) diff --git a/Lib/test/test_tkinter/test_widgets.py b/Lib/test/test_tkinter/test_widgets.py index f3579a23afc539..1c400e970eb02d 100644 --- a/Lib/test/test_tkinter/test_widgets.py +++ b/Lib/test/test_tkinter/test_widgets.py @@ -26,12 +26,8 @@ def float_round(x): return float(round(x)) class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): - if tk_version < (9, 0): - _no_round = {'padx', 'pady'} - else: - _no_round = {'borderwidth', 'height', 'highlightthickness', 'padx', - 'pady', 'width'} - if tk_version < (9, 0): + _no_round = {'padx', 'pady'} + if tk_version < (8, 7): _clipped = {'highlightthickness'} else: _clipped = {'borderwidth', 'height', 'highlightthickness', 'padx', @@ -122,11 +118,6 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase): 'highlightbackground', 'highlightcolor', 'highlightthickness', 'padx', 'pady', 'relief', 'takefocus', 'tile', 'visual', 'width', ) - if tk_version < (9, 0): - _no_round = {'padx', 'pady'} - else: - _no_round = {'borderwidth', 'height', 'highlightthickness', 'padx', - 'pady', 'width'} def create(self, **kwargs): return tkinter.Frame(self.root, **kwargs) @@ -142,11 +133,6 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): 'labelanchor', 'labelwidget', 'padx', 'pady', 'relief', 'takefocus', 'text', 'visual', 'width', ) - if tk_version < (9, 0): - _no_round = {'padx', 'pady'} - else: - _no_round = {'borderwidth', 'height', 'highlightthickness', 'padx', - 'pady', 'width'} def create(self, **kwargs): return tkinter.LabelFrame(self.root, **kwargs) @@ -167,11 +153,19 @@ def test_configure_labelwidget(self): # Label, Button, Checkbutton, Radiobutton, MenuButton class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests): _rounds_pixels = False - if tk_version < (9, 0): + if tk_version < (8, 7): _clipped = {} + elif tk_version < (9, 0): + _clipped = {'borderwidth', 'height', 'highlightthickness', 'padx', 'pady', 'width'} else: - _clipped = {'borderwidth', 'insertborderwidth', 'highlightthickness', - 'padx', 'pady'} + _clipped = {'borderwidth', 'height', 'highlightthickness', + 'insertborderwidth', 'padx', 'pady', 'width'} + + def setUp(self): + super().setUp() + if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 2): + self._clipped = self._clipped - {'height', 'width'} + @add_configure_tests(StandardOptionsTests) class LabelTest(AbstractLabelTest, unittest.TestCase): @@ -201,6 +195,11 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase): 'repeatdelay', 'repeatinterval', 'state', 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength') + if tk_version < (8, 7): + _clipped = {} + else: + _clipped = {'borderwidth', 'height', 'highlightthickness', + 'padx', 'pady', 'width'} def create(self, **kwargs): return tkinter.Button(self.root, **kwargs) @@ -301,10 +300,17 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', 'wraplength', ) _rounds_pixels = (tk_version < (9, 0)) - if tk_version < (9, 0): + if tk_version < (8, 7): _clipped = {'highlightthickness', 'padx', 'pady'} + elif tk_version < (9, 0): + _clipped = {'borderwidth', 'highlightthickness', 'padx', 'pady'} else: - _clipped ={ 'insertborderwidth', 'highlightthickness', 'padx', 'pady'} + _clipped = {'borderwidth', 'highlightthickness', 'insertborderwidth', 'padx', 'pady'} + + def setUp(self): + super().setUp() + if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1): + self._clipped = self._clipped - {'borderwidth'} def create(self, **kwargs): return tkinter.Menubutton(self.root, **kwargs) @@ -316,16 +322,17 @@ def test_configure_direction(self): def test_configure_height(self): widget = self.create() - if tk_version < (9, 0): - self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str) + if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)): + conv = str else: - self.checkIntegerParam(widget, 'height', 0, -100, 0) + conv = False + self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=conv) def test_configure_image(self): widget = self.create() image = tkinter.PhotoImage(master=self.root, name='image1') self.checkParam(widget, 'image', image, conv=str) - if tk_version < (9, 0): + if tk_version < (8, 7): errmsg = 'image "spam" doesn\'t exist' else: errmsg = 'image "spam" does not exist' @@ -346,10 +353,11 @@ def test_configure_menu(self): def test_configure_width(self): widget = self.create() - if tk_version < (9, 0): - self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str) + if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)): + conv = str else: - self.checkIntegerParam(widget, 'width', 402, 0, 0) + conv = False + self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=conv) class OptionMenuTest(MenubuttonTest, unittest.TestCase): @@ -368,12 +376,11 @@ def test_specify_name(self): @add_configure_tests(IntegerSizeTests, StandardOptionsTests) class EntryTest(AbstractWidgetTest, unittest.TestCase): - _rounds_pixels = (tk_version < (9, 0)) - if tk_version < (9, 0): + if tk_version < (8, 7): _clipped = {'highlightthickness'} else: - _clipped = {'highlightthickness', 'borderwidth', 'insertborderwidth', - 'selectborderwidth'} + _clipped = {'borderwidth', 'highlightthickness', 'insertborderwidth', + 'insertwidth', 'selectborderwidth'} OPTIONS = ( 'background', 'borderwidth', 'cursor', @@ -398,28 +405,21 @@ def test_configure_disabledbackground(self): def test_configure_insertborderwidth(self): widget = self.create(insertwidth=100) - if tk_version < (9, 0): - self.checkPixelsParam(widget, 'insertborderwidth', - 0, 1.3, 2.6, 6, '10p') - else: - self.checkPixelsParam(widget, 'insertborderwidth', - 0, 1.3, 3, 6, '10p') - self.checkParam(widget, 'insertborderwidth', -2) + self.checkPixelsParam(widget, 'insertborderwidth', + 0, 1.3, 2.6, 6, -2, '10p') # insertborderwidth is bounded above by a half of insertwidth. - expected = 100 // 2 if tk_version < (9, 0) else 60 + expected = 100 // 2 if tk_version < (8, 7) else 60 self.checkParam(widget, 'insertborderwidth', 60, expected=expected) def test_configure_insertwidth(self): widget = self.create() - self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p') - if tk_version < (9, 0): + self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, 0.9, '10p') + if tk_version < (8, 7): + self.checkParam(widget, 'insertwidth', 0, expected=2) self.checkParam(widget, 'insertwidth', 0.1, expected=2) self.checkParam(widget, 'insertwidth', -2, expected=2) - self.checkParam(widget, 'insertwidth', 0.9, expected=1) else: - self.checkParam(widget, 'insertwidth', 0.1) - self.checkParam(widget, 'insertwidth', -2, expected=0) - self.checkParam(widget, 'insertwidth', 0.9) + self.checkPixelsParam(widget, 'insertwidth', 0, 0.1, -2) def test_configure_invalidcommand(self): widget = self.create() @@ -562,7 +562,7 @@ def test_configure_values(self): # XXX widget = self.create() self.assertEqual(widget['values'], '') - if tk_version < (9, 0): + if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)): expected = 'mon tue wed thur' else: expected = ('mon', 'tue', 'wed', 'thur') @@ -571,7 +571,7 @@ def test_configure_values(self): self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'), expected=expected) - if tk_version < (9, 0): + if tk_version < (8, 7) or (tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1)): expected = '42 3.14 {} {any string}' else: expected = (42, 3.14, '', 'any string') @@ -640,9 +640,20 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): 'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap', 'xscrollcommand', 'yscrollcommand', ) - _rounds_pixels = (tk_version < (9, 0)) _no_round = {'selectborderwidth'} - _clipped = {'highlightthickness'} + if tk_version < (9, 0): + _clipped = {'highlightthickness', 'spacing1', 'spacing2', 'spacing3'} + else: + _clipped = {'borderwidth', 'height', 'highlightthickness', + 'insertborderwidth', 'insertwidth', 'padx', 'pady', + 'selectborderwidth', 'spacing1', 'spacing2', 'spacing3'} + + def setUp(self): + super().setUp() + if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 2): + self._clipped = self._clipped - {'borderwidth', 'height', 'padx', 'pady'} + if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1): + self._clipped = self._clipped - {'insertborderwidth', 'insertwidth', 'selectborderwidth'} def create(self, **kwargs): return tkinter.Text(self.root, **kwargs) @@ -671,9 +682,11 @@ def test_configure_endline(self): def test_configure_height(self): widget = self.create() self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c') - expected = 1 if tk_version < (9, 0) else 0 - self.checkParam(widget, 'height', -100, expected=expected) - self.checkParam(widget, 'height', 0, expected=expected) + if tk_version < (9, 0): + self.checkParam(widget, 'height', 0, expected=1) + self.checkParam(widget, 'height', -100, expected=1) + else: + self.checkPixelsParam(widget, 'height', 0, -100) def test_configure_maxundo(self): widget = self.create() @@ -689,26 +702,17 @@ def test_configure_insertunfocussed(self): self.checkEnumParam(widget, 'insertunfocussed', 'hollow', 'none', 'solid') - def test_configure_selectborderwidth(self): - widget = self.create() - value = -2 if tk_version < (9, 0) else 0 - self.checkPixelsParam(widget, 'selectborderwidth', - 1.3, 2.6, value, '10p', conv=False) - def test_configure_spacing1(self): widget = self.create() - self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c') - self.checkParam(widget, 'spacing1', -5, expected=0) + self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, -5, '0.5c') def test_configure_spacing2(self): widget = self.create() - self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c') - self.checkParam(widget, 'spacing2', -1, expected=0) + self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, -1, '0.1c') def test_configure_spacing3(self): widget = self.create() - self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c') - self.checkParam(widget, 'spacing3', -10, expected=0) + self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, -10, '0.5c') def test_configure_startline(self): widget = self.create() @@ -781,17 +785,22 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase): 'xscrollcommand', 'xscrollincrement', 'yscrollcommand', 'yscrollincrement', 'width', ) - _rounds_pixels = True - if tk_version < (9, 0): - _noround = {} + if tk_version < (8, 7): _clipped = {'highlightthickness'} else: - _no_round = {'borderwidth', 'height', 'highlightthickness', 'width', - 'xscrollincrement', 'yscrollincrement'} - _clipped = {'borderwidth', 'height', 'highlightthickness', 'width', - 'xscrollincrement', 'yscrollincrement'} + _clipped = {'borderwidth', 'height', 'highlightthickness', + 'insertborderwidth', 'insertwidth', 'selectborderwidth', + 'width', 'xscrollincrement', 'yscrollincrement'} _stringify = True + def setUp(self): + super().setUp() + if tk_version[:2] == (9, 0) and get_tk_patchlevel(self.root) < (9, 0, 1): + self._rounds_pixels = True + self._no_round = {'borderwidth', 'height', 'highlightthickness', + 'width', 'xscrollincrement', 'yscrollincrement'} + self._clipped = self._clipped - {'insertborderwidth', 'insertwidth', 'selectborderwidth'} + def create(self, **kwargs): return tkinter.Canvas(self.root, **kwargs) @@ -938,7 +947,6 @@ def test_create_line(self): def test_create_polygon(self): c = self.create() - tk87 = tk_version >= (8, 7) # In Tk < 8.7 polygons are filled, but has no outline by default. # This affects its size, so always explicitly specify outline. i1 = c.create_polygon(20, 30, 40, 50, 60, 10, outline='red') @@ -1043,11 +1051,10 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): 'selectmode', 'setgrid', 'state', 'takefocus', 'width', 'xscrollcommand', 'yscrollcommand', ) - _rounds_pixels = (tk_version < (9, 0)) - if tk_version < (9, 0): + if tk_version < (8, 7): _clipped = {'highlightthickness'} else: - _clipped = { 'borderwidth', 'highlightthickness', 'selectborderwidth'} + _clipped = {'borderwidth', 'highlightthickness', 'selectborderwidth'} def create(self, **kwargs): return tkinter.Listbox(self.root, **kwargs) @@ -1185,7 +1192,6 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): 'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state', 'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width', ) - _rounds_pixels = (tk_version < (9, 0)) _clipped = {'highlightthickness'} default_orient = 'vertical' @@ -1255,14 +1261,13 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): 'repeatdelay', 'repeatinterval', 'takefocus', 'troughcolor', 'width', ) - _rounds_pixels = True - if tk_version >= (9, 0): - _no_round = {'borderwidth', 'elementborderwidth', 'highlightthickness', - 'width'} - if tk_version < (9, 0): + if tk_version < (8, 7): _clipped = {'highlightthickness'} + elif tk_version < (9, 0): + _clipped = {'borderwidth', 'elementborderwidth', 'highlightthickness'} else: - _clipped = {'borderwidth', 'highlightthickness', 'width'} + _clipped = {'borderwidth', 'elementborderwidth', 'highlightthickness', 'width'} + _clipped_to_default = {'elementborderwidth'} _stringify = True default_orient = 'vertical' @@ -1271,9 +1276,7 @@ def create(self, **kwargs): def test_configure_elementborderwidth(self): widget = self.create() - self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, '1m') - expected = self._default_pixels if tk_version >= (8, 7) else -2 - self.checkParam(widget, 'elementborderwidth', -2, expected=expected) + self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m') def test_configure_orient(self): widget = self.create() @@ -1300,7 +1303,7 @@ def test_set(self): self.assertRaises(TypeError, sb.set, 0.6, 0.7, 0.8) -@add_configure_tests(StandardOptionsTests) +@add_configure_tests(PixelSizeTests, StandardOptionsTests) class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): OPTIONS = ( 'background', 'borderwidth', 'cursor', @@ -1311,14 +1314,8 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): 'sashcursor', 'sashpad', 'sashrelief', 'sashwidth', 'showhandle', 'width', ) - _rounds_pixels = True - if tk_version < (9, 0): - _no_round = {'handlesize', 'height', 'proxyborderwidth', 'sashwidth', - 'selectborderwidth', 'width'} - else: - _no_round = {'borderwidth', 'handlepad', 'handlesize', 'height', - 'proxyborderwidth', 'sashpad', 'sashwidth', - 'selectborderwidth', 'width'} + _no_round = {'handlesize', 'height', 'proxyborderwidth', 'sashwidth', + 'selectborderwidth', 'width'} _clipped = {} default_orient = 'horizontal' @@ -1331,13 +1328,7 @@ 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=False) - - def test_configure_height(self): - widget = self.create() - self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i', - conv=False) + self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m') def test_configure_opaqueresize(self): widget = self.create() @@ -1352,8 +1343,7 @@ def test_configure_proxybackground(self): def test_configure_proxyborderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'proxyborderwidth', - 0, 1.3, 2.9, 6, -2, '10p', - conv=False) + 0, 1.3, 2.9, 6, -2, '10p') @requires_tk(8, 6, 5) def test_configure_proxyrelief(self): @@ -1375,18 +1365,12 @@ 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=False) + self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m') def test_configure_showhandle(self): widget = self.create() self.checkBooleanParam(widget, 'showhandle') - def test_configure_width(self): - widget = self.create() - self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i', - conv=False) - def create2(self): p = self.create() b = tkinter.Button(p) @@ -1568,12 +1552,12 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase): 'justify', 'padx', 'pady', 'relief', 'takefocus', 'text', 'textvariable', 'width', ) - _rounds_pixels = (tk_version < (9, 0)) _no_round = {'padx', 'pady'} - if tk_version < (9, 0): + if tk_version < (8, 7): _clipped = {'highlightthickness'} else: - _clipped = {'borderwidth', 'highlightthickness', 'padx', 'pady'} + _clipped = {'borderwidth', 'highlightthickness', 'padx', 'pady', 'width'} + _clipped_to_default = {'padx', 'pady'} def create(self, **kwargs): return tkinter.Message(self.root, **kwargs) @@ -1582,24 +1566,6 @@ def test_configure_aspect(self): widget = self.create() self.checkIntegerParam(widget, 'aspect', 250, 0, -300) - def test_configure_padx(self): - widget = self.create() - self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m') - expected = -2 if tk_version < (9, 0) else self._default_pixels - self.checkParam(widget, 'padx', -2, expected=expected) - - def test_configure_pady(self): - widget = self.create() - self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m') - expected = -2 if tk_version < (9, 0) else self._default_pixels - self.checkParam(widget, 'pady', -2, expected=expected) - - def test_configure_width(self): - widget = self.create() - self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, 0, '5i') - expected = 0 if tk_version >= (8, 7) else -402 - self.checkParam(widget, 'width', -402, expected=expected) - class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase): diff --git a/Lib/test/test_tkinter/widget_tests.py b/Lib/test/test_tkinter/widget_tests.py index dd2d7c4da459ab..94244a8b3fe244 100644 --- a/Lib/test/test_tkinter/widget_tests.py +++ b/Lib/test/test_tkinter/widget_tests.py @@ -12,11 +12,12 @@ # borderwidth = bd class AbstractWidgetTest(AbstractTkTest): - _default_pixels = '' # Value for unset pixel options. - _rounds_pixels = True # True if some pixel options are rounded. - _no_round = {} # Pixel options which are not rounded nonetheless + _default_pixels = '' if tk_version >= (9, 0) else -1 # Value for unset pixel options. + _rounds_pixels = (tk_version < (9, 0)) # True if some pixel options are rounded. + _no_round = set() # Pixel options which are not rounded nonetheless _stringify = False # Whether to convert tuples to strings _allow_empty_justify = False + _clipped_to_default = set() @property def scaling(self): @@ -43,9 +44,12 @@ def checkParam(self, widget, name, value, *, expected=_sentinel, widget[name] = value if expected is _sentinel: expected = value - if name in self._clipped: - if not isinstance(expected, str): - expected = max(expected, 0) + if name in self._clipped: + if not isinstance(expected, str) and expected < 0: + if tk_version >= (8, 7) and name in self._clipped_to_default: + expected = self._default_pixels + else: + expected = 0 if conv: expected = conv(expected) if self._stringify or not self.wantobjects: @@ -143,10 +147,10 @@ def checkEnumParam(self, widget, name, *values, self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg) def checkPixelsParam(self, widget, name, *values, conv=None, **kwargs): - if not self._rounds_pixels or name in self._no_round: - conv = False - elif conv != str: - conv = round + if conv is None: + if self._rounds_pixels and name not in self._no_round: + conv = round + alow_neg = tk_version < (9, 1) for value in values: expected = _sentinel conv1 = conv @@ -156,6 +160,9 @@ def checkPixelsParam(self, widget, name, *values, conv=None, **kwargs): if conv1 and conv1 is not str: expected = pixels_conv(value) * self.scaling conv1 = round + elif not alow_neg and isinstance(value, (int, float)) and value < 0: + self.checkInvalidParam(widget, name, value) + continue self.checkParam(widget, name, value, expected=expected, conv=conv1, **kwargs) errmsg = '(bad|expected) screen distance ((or "" )?but got )?"{}"' @@ -177,7 +184,7 @@ def checkReliefParam(self, widget, name, *, allow_empty=False): def checkImageParam(self, widget, name): image = tkinter.PhotoImage(master=self.root, name='image1') self.checkParam(widget, name, image, conv=str) - if tk_version < (9, 0): + if tk_version < (8, 7): errmsg = 'image "spam" doesn\'t exist' else: errmsg = 'image "spam" does not exist' @@ -246,11 +253,7 @@ def test_configure_activeborderwidth(self): def test_configure_borderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'borderwidth', - 0, 1.3, 2.6, 6, '10p') - if tk_version < (9, 0): - self.checkParam(widget, 'borderwidth', -2) - else: - self.checkParam(widget, 'borderwidth', 0) + 0, 1.3, 2.6, 6, -2, '10p') if 'bd' in self.OPTIONS: self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, '10p') @@ -259,50 +262,27 @@ def test_configure_borderwidth(self): def test_configure_highlightthickness(self): widget = self.create() self.checkPixelsParam(widget, 'highlightthickness', - 0, 1.3, 2.6, 6, '10p') - self.checkParam(widget, 'highlightthickness', -2) + 0, 1.3, 2.6, 6, -2, '10p') def test_configure_insertborderwidth(self): widget = self.create() - if tk_version < (9, 0): - values = (0, 1.3, 2.6, 6, -2, '10p') - value = -2 - else: - values = (0, 1, 3, 6, 13) - value = 0 - self.checkPixelsParam(widget, 'insertborderwidth', *values) - self.checkParam(widget, 'insertborderwidth', value) + self.checkPixelsParam(widget, 'insertborderwidth', 0, 1.3, 2.6, 6, -2, '10p') def test_configure_insertwidth(self): widget = self.create() - if tk_version < (9, 0): - self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p') - else: - self.checkPixelsParam(widget, 'insertwidth', 1, 3, 0, 13) + self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p') def test_configure_padx(self): widget = self.create() - self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m') - if tk_version < (9, 0): - self.checkParam(widget, 'padx', -2) - else: - self.checkParam(widget, 'padx', 0) + self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m') def test_configure_pady(self): widget = self.create() - self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m') - if tk_version < (9, 0): - self.checkParam(widget, 'pady', -2) - else: - self.checkParam(widget, 'pady', 0) + self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m') def test_configure_selectborderwidth(self): widget = self.create() - if tk_version < (9, 0): - values = (1.3, 2.6, -2, '10p') - else: - values = (1, 3, 0, 13) - self.checkPixelsParam(widget, 'selectborderwidth', *values) + self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p') class StandardOptionsTests(PixelOptionsTests): @@ -569,34 +549,22 @@ class IntegerSizeTests: """ Tests widgets which only accept integral width and height.""" def test_configure_height(self): widget = self.create() - if tk_version < (9, 0): - self.checkIntegerParam(widget, 'height', 100, -100, 0) - else: - self.checkIntegerParam(widget, 'height', 100, 0, 0) + self.checkIntegerParam(widget, 'height', 100, -100, 0) def test_configure_width(self): widget = self.create() - if tk_version < (9, 0): - self.checkIntegerParam(widget, 'width', 402, -402, 0) - else: - self.checkIntegerParam(widget, 'width', 402, 0, 0) + self.checkIntegerParam(widget, 'width', 402, -402, 0) class PixelSizeTests: """ Tests widgets which accept screen distances for width and height.""" def test_configure_height(self): widget = self.create() - value = -100 if tk_version < (9, 0) else 0 - self.checkPixelsParam( - widget, 'height', 100, 101.2, 102.6, value, 0, '3c' - ) + self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c') def test_configure_width(self): widget = self.create() - value = -402 if tk_version < (9, 0) else 0 - self.checkPixelsParam( - widget, 'width', 402, 403.4, 404.6, value, 0, '5i' - ) + self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i') def add_configure_tests(*source_classes): diff --git a/Lib/test/test_ttk/test_widgets.py b/Lib/test/test_ttk/test_widgets.py index e738fbff82ed43..8cce9aed9d514f 100644 --- a/Lib/test/test_ttk/test_widgets.py +++ b/Lib/test/test_ttk/test_widgets.py @@ -183,7 +183,7 @@ def checkImageParam(self, widget, name): expected=('image1', 'active', 'image2')) self.checkParam(widget, name, 'image1 active image2', expected=('image1', 'active', 'image2')) - if tk_version < (9, 0): + if tk_version < (8, 7): errmsg = 'image "spam" doesn\'t exist' else: errmsg = 'image "spam" does not exist' @@ -1192,7 +1192,7 @@ def test_traversal(self): elif sys.platform == 'win32': focus_identify_as = 'focus' else: - focus_identify_as = 'focus' if tk_version < (9,0) else 'padding' + focus_identify_as = 'focus' if tk_version < (8, 7) else 'padding' self.assertEqual(self.nb.identify(5, 5), focus_identify_as) simulate_mouse_click(self.nb, 5, 5) self.nb.focus_force() From f062014d3876f1f81c0e60bf861c3460429ac3b4 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Thu, 12 Mar 2026 04:24:19 +0800 Subject: [PATCH 424/498] gh-144540: Add _MAKE_HEAP_SAFE uop to eliminate unnecessary refcount operations in RETURN_VALUE and YIELD_VALUE (GH-144414) --- Include/internal/pycore_opcode_metadata.h | 4 +- Include/internal/pycore_uop_ids.h | 1929 +++++++++++---------- Include/internal/pycore_uop_metadata.h | 21 + Lib/test/test_capi/test_opt.py | 44 + Modules/_testinternalcapi/test_cases.c.h | 122 +- Python/bytecodes.c | 26 +- Python/executor_cases.c.h | 63 +- Python/generated_cases.c.h | 122 +- Python/optimizer_bytecodes.c | 14 +- Python/optimizer_cases.c.h | 15 +- 10 files changed, 1288 insertions(+), 1072 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 126bc7d7102925..09588e9428281e 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1495,7 +1495,7 @@ _PyOpcode_macro_expansion[256] = { [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, OPARG_SIMPLE, 0 } } }, [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, OPARG_SIMPLE, 0 } } }, [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } }, - [RETURN_VALUE] = { .nuops = 1, .uops = { { _RETURN_VALUE, OPARG_SIMPLE, 0 } } }, + [RETURN_VALUE] = { .nuops = 2, .uops = { { _MAKE_HEAP_SAFE, OPARG_SIMPLE, 0 }, { _RETURN_VALUE, OPARG_SIMPLE, 0 } } }, [SEND_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS_GEN_FUNC, OPARG_SIMPLE, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, OPARG_SIMPLE, 0 } } }, [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, OPARG_SIMPLE, 0 } } }, @@ -1532,7 +1532,7 @@ _PyOpcode_macro_expansion[256] = { [UNPACK_SEQUENCE_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TUPLE, OPARG_SIMPLE, 1 } } }, [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TWO_TUPLE, OPARG_SIMPLE, 1 } } }, [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, OPARG_SIMPLE, 0 } } }, - [YIELD_VALUE] = { .nuops = 1, .uops = { { _YIELD_VALUE, OPARG_SIMPLE, 0 } } }, + [YIELD_VALUE] = { .nuops = 2, .uops = { { _MAKE_HEAP_SAFE, OPARG_SIMPLE, 0 }, { _YIELD_VALUE, OPARG_SIMPLE, 0 } } }, }; #endif // NEED_OPCODE_METADATA diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 38f290df2c770f..216436604c6973 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -289,994 +289,999 @@ extern "C" { #define _MAKE_CALLARGS_A_TUPLE 517 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 518 +#define _MAKE_HEAP_SAFE 518 +#define _MAKE_WARM 519 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 519 -#define _MAYBE_EXPAND_METHOD_KW 520 -#define _MONITOR_CALL 521 -#define _MONITOR_CALL_KW 522 -#define _MONITOR_JUMP_BACKWARD 523 -#define _MONITOR_RESUME 524 +#define _MAYBE_EXPAND_METHOD 520 +#define _MAYBE_EXPAND_METHOD_KW 521 +#define _MONITOR_CALL 522 +#define _MONITOR_CALL_KW 523 +#define _MONITOR_JUMP_BACKWARD 524 +#define _MONITOR_RESUME 525 #define _NOP NOP -#define _POP_CALL 525 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 526 -#define _POP_CALL_ONE 527 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 528 -#define _POP_CALL_TWO 529 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 530 +#define _POP_CALL 526 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 527 +#define _POP_CALL_ONE 528 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 529 +#define _POP_CALL_TWO 530 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 531 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 531 -#define _POP_JUMP_IF_TRUE 532 +#define _POP_JUMP_IF_FALSE 532 +#define _POP_JUMP_IF_TRUE 533 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 533 -#define _POP_TOP_INT 534 -#define _POP_TOP_LOAD_CONST_INLINE 535 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 536 -#define _POP_TOP_NOP 537 -#define _POP_TOP_UNICODE 538 -#define _POP_TWO 539 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 540 +#define _POP_TOP_FLOAT 534 +#define _POP_TOP_INT 535 +#define _POP_TOP_LOAD_CONST_INLINE 536 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 537 +#define _POP_TOP_NOP 538 +#define _POP_TOP_UNICODE 539 +#define _POP_TWO 540 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 541 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 541 +#define _PUSH_FRAME 542 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 542 -#define _PY_FRAME_EX 543 -#define _PY_FRAME_GENERAL 544 -#define _PY_FRAME_KW 545 -#define _QUICKEN_RESUME 546 -#define _RECORD_4OS 547 -#define _RECORD_BOUND_METHOD 548 -#define _RECORD_CALLABLE 549 -#define _RECORD_CODE 550 -#define _RECORD_NOS 551 -#define _RECORD_NOS_GEN_FUNC 552 -#define _RECORD_TOS 553 -#define _RECORD_TOS_TYPE 554 -#define _REPLACE_WITH_TRUE 555 +#define _PUSH_NULL_CONDITIONAL 543 +#define _PY_FRAME_EX 544 +#define _PY_FRAME_GENERAL 545 +#define _PY_FRAME_KW 546 +#define _QUICKEN_RESUME 547 +#define _RECORD_4OS 548 +#define _RECORD_BOUND_METHOD 549 +#define _RECORD_CALLABLE 550 +#define _RECORD_CODE 551 +#define _RECORD_NOS 552 +#define _RECORD_NOS_GEN_FUNC 553 +#define _RECORD_TOS 554 +#define _RECORD_TOS_TYPE 555 +#define _REPLACE_WITH_TRUE 556 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 556 -#define _SEND 557 -#define _SEND_GEN_FRAME 558 +#define _RETURN_VALUE 557 +#define _SAVE_RETURN_OFFSET 558 +#define _SEND 559 +#define _SEND_GEN_FRAME 560 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 559 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 560 -#define _SPILL_OR_RELOAD 561 -#define _START_EXECUTOR 562 -#define _STORE_ATTR 563 -#define _STORE_ATTR_INSTANCE_VALUE 564 -#define _STORE_ATTR_SLOT 565 -#define _STORE_ATTR_WITH_HINT 566 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 561 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 562 +#define _SPILL_OR_RELOAD 563 +#define _START_EXECUTOR 564 +#define _STORE_ATTR 565 +#define _STORE_ATTR_INSTANCE_VALUE 566 +#define _STORE_ATTR_SLOT 567 +#define _STORE_ATTR_WITH_HINT 568 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 567 -#define _STORE_SUBSCR 568 -#define _STORE_SUBSCR_DICT 569 -#define _STORE_SUBSCR_LIST_INT 570 -#define _SWAP 571 -#define _SWAP_2 572 -#define _SWAP_3 573 -#define _SWAP_FAST 574 -#define _SWAP_FAST_0 575 -#define _SWAP_FAST_1 576 -#define _SWAP_FAST_2 577 -#define _SWAP_FAST_3 578 -#define _SWAP_FAST_4 579 -#define _SWAP_FAST_5 580 -#define _SWAP_FAST_6 581 -#define _SWAP_FAST_7 582 -#define _TIER2_RESUME_CHECK 583 -#define _TO_BOOL 584 +#define _STORE_SLICE 569 +#define _STORE_SUBSCR 570 +#define _STORE_SUBSCR_DICT 571 +#define _STORE_SUBSCR_LIST_INT 572 +#define _SWAP 573 +#define _SWAP_2 574 +#define _SWAP_3 575 +#define _SWAP_FAST 576 +#define _SWAP_FAST_0 577 +#define _SWAP_FAST_1 578 +#define _SWAP_FAST_2 579 +#define _SWAP_FAST_3 580 +#define _SWAP_FAST_4 581 +#define _SWAP_FAST_5 582 +#define _SWAP_FAST_6 583 +#define _SWAP_FAST_7 584 +#define _TIER2_RESUME_CHECK 585 +#define _TO_BOOL 586 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 585 -#define _TO_BOOL_LIST 586 +#define _TO_BOOL_INT 587 +#define _TO_BOOL_LIST 588 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 587 +#define _TO_BOOL_STR 589 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 588 -#define _UNARY_NEGATIVE 589 +#define _UNARY_INVERT 590 +#define _UNARY_NEGATIVE 591 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 590 -#define _UNPACK_SEQUENCE_LIST 591 -#define _UNPACK_SEQUENCE_TUPLE 592 -#define _UNPACK_SEQUENCE_TWO_TUPLE 593 +#define _UNPACK_SEQUENCE 592 +#define _UNPACK_SEQUENCE_LIST 593 +#define _UNPACK_SEQUENCE_TUPLE 594 +#define _UNPACK_SEQUENCE_TWO_TUPLE 595 #define _WITH_EXCEPT_START WITH_EXCEPT_START -#define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 593 -#define _BINARY_OP_r23 594 -#define _BINARY_OP_ADD_FLOAT_r03 595 -#define _BINARY_OP_ADD_FLOAT_r13 596 -#define _BINARY_OP_ADD_FLOAT_r23 597 -#define _BINARY_OP_ADD_INT_r03 598 -#define _BINARY_OP_ADD_INT_r13 599 -#define _BINARY_OP_ADD_INT_r23 600 -#define _BINARY_OP_ADD_UNICODE_r03 601 -#define _BINARY_OP_ADD_UNICODE_r13 602 -#define _BINARY_OP_ADD_UNICODE_r23 603 -#define _BINARY_OP_EXTEND_r23 604 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 605 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 606 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 607 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 608 -#define _BINARY_OP_MULTIPLY_INT_r03 609 -#define _BINARY_OP_MULTIPLY_INT_r13 610 -#define _BINARY_OP_MULTIPLY_INT_r23 611 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 612 -#define _BINARY_OP_SUBSCR_DICT_r23 613 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 614 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 615 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 616 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 617 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 618 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 619 -#define _BINARY_OP_SUBSCR_STR_INT_r23 620 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 621 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 622 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 623 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 624 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 625 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 626 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 627 -#define _BINARY_OP_SUBTRACT_INT_r03 628 -#define _BINARY_OP_SUBTRACT_INT_r13 629 -#define _BINARY_OP_SUBTRACT_INT_r23 630 -#define _BINARY_SLICE_r31 631 -#define _BUILD_INTERPOLATION_r01 632 -#define _BUILD_LIST_r01 633 -#define _BUILD_MAP_r01 634 -#define _BUILD_SET_r01 635 -#define _BUILD_SLICE_r01 636 -#define _BUILD_STRING_r01 637 -#define _BUILD_TEMPLATE_r21 638 -#define _BUILD_TUPLE_r01 639 -#define _CALL_BUILTIN_CLASS_r01 640 -#define _CALL_BUILTIN_FAST_r01 641 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 642 -#define _CALL_BUILTIN_O_r03 643 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 644 -#define _CALL_INTRINSIC_1_r11 645 -#define _CALL_INTRINSIC_2_r21 646 -#define _CALL_ISINSTANCE_r31 647 -#define _CALL_KW_NON_PY_r11 648 -#define _CALL_LEN_r33 649 -#define _CALL_LIST_APPEND_r03 650 -#define _CALL_LIST_APPEND_r13 651 -#define _CALL_LIST_APPEND_r23 652 -#define _CALL_LIST_APPEND_r33 653 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 654 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 655 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 656 -#define _CALL_METHOD_DESCRIPTOR_O_r03 657 -#define _CALL_NON_PY_GENERAL_r01 658 -#define _CALL_STR_1_r32 659 -#define _CALL_TUPLE_1_r32 660 -#define _CALL_TYPE_1_r02 661 -#define _CALL_TYPE_1_r12 662 -#define _CALL_TYPE_1_r22 663 -#define _CALL_TYPE_1_r32 664 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 665 -#define _CHECK_ATTR_CLASS_r01 666 -#define _CHECK_ATTR_CLASS_r11 667 -#define _CHECK_ATTR_CLASS_r22 668 -#define _CHECK_ATTR_CLASS_r33 669 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 670 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 671 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 672 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 673 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 674 -#define _CHECK_EG_MATCH_r22 675 -#define _CHECK_EXC_MATCH_r22 676 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 677 -#define _CHECK_FUNCTION_VERSION_r00 678 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 679 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 680 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 681 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 682 -#define _CHECK_FUNCTION_VERSION_KW_r11 683 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 684 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 685 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 686 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 687 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 688 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 689 -#define _CHECK_IS_PY_CALLABLE_EX_r03 690 -#define _CHECK_IS_PY_CALLABLE_EX_r13 691 -#define _CHECK_IS_PY_CALLABLE_EX_r23 692 -#define _CHECK_IS_PY_CALLABLE_EX_r33 693 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 694 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 695 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 696 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 697 -#define _CHECK_METHOD_VERSION_r00 698 -#define _CHECK_METHOD_VERSION_KW_r11 699 -#define _CHECK_PEP_523_r00 700 -#define _CHECK_PEP_523_r11 701 -#define _CHECK_PEP_523_r22 702 -#define _CHECK_PEP_523_r33 703 -#define _CHECK_PERIODIC_r00 704 -#define _CHECK_PERIODIC_AT_END_r00 705 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 706 -#define _CHECK_RECURSION_REMAINING_r00 707 -#define _CHECK_RECURSION_REMAINING_r11 708 -#define _CHECK_RECURSION_REMAINING_r22 709 -#define _CHECK_RECURSION_REMAINING_r33 710 -#define _CHECK_STACK_SPACE_r00 711 -#define _CHECK_STACK_SPACE_OPERAND_r00 712 -#define _CHECK_STACK_SPACE_OPERAND_r11 713 -#define _CHECK_STACK_SPACE_OPERAND_r22 714 -#define _CHECK_STACK_SPACE_OPERAND_r33 715 -#define _CHECK_VALIDITY_r00 716 -#define _CHECK_VALIDITY_r11 717 -#define _CHECK_VALIDITY_r22 718 -#define _CHECK_VALIDITY_r33 719 -#define _COLD_DYNAMIC_EXIT_r00 720 -#define _COLD_EXIT_r00 721 -#define _COMPARE_OP_r21 722 -#define _COMPARE_OP_FLOAT_r03 723 -#define _COMPARE_OP_FLOAT_r13 724 -#define _COMPARE_OP_FLOAT_r23 725 -#define _COMPARE_OP_INT_r23 726 -#define _COMPARE_OP_STR_r23 727 -#define _CONTAINS_OP_r23 728 -#define _CONTAINS_OP_DICT_r23 729 -#define _CONTAINS_OP_SET_r23 730 -#define _CONVERT_VALUE_r11 731 -#define _COPY_r01 732 -#define _COPY_1_r02 733 -#define _COPY_1_r12 734 -#define _COPY_1_r23 735 -#define _COPY_2_r03 736 -#define _COPY_2_r13 737 -#define _COPY_2_r23 738 -#define _COPY_3_r03 739 -#define _COPY_3_r13 740 -#define _COPY_3_r23 741 -#define _COPY_3_r33 742 -#define _COPY_FREE_VARS_r00 743 -#define _COPY_FREE_VARS_r11 744 -#define _COPY_FREE_VARS_r22 745 -#define _COPY_FREE_VARS_r33 746 -#define _CREATE_INIT_FRAME_r01 747 -#define _DELETE_ATTR_r10 748 -#define _DELETE_DEREF_r00 749 -#define _DELETE_FAST_r00 750 -#define _DELETE_GLOBAL_r00 751 -#define _DELETE_NAME_r00 752 -#define _DELETE_SUBSCR_r20 753 -#define _DEOPT_r00 754 -#define _DEOPT_r10 755 -#define _DEOPT_r20 756 -#define _DEOPT_r30 757 -#define _DICT_MERGE_r10 758 -#define _DICT_UPDATE_r10 759 -#define _DO_CALL_r01 760 -#define _DO_CALL_FUNCTION_EX_r31 761 -#define _DO_CALL_KW_r11 762 -#define _DYNAMIC_EXIT_r00 763 -#define _DYNAMIC_EXIT_r10 764 -#define _DYNAMIC_EXIT_r20 765 -#define _DYNAMIC_EXIT_r30 766 -#define _END_FOR_r10 767 -#define _END_SEND_r21 768 -#define _ERROR_POP_N_r00 769 -#define _EXIT_INIT_CHECK_r10 770 -#define _EXIT_TRACE_r00 771 -#define _EXIT_TRACE_r10 772 -#define _EXIT_TRACE_r20 773 -#define _EXIT_TRACE_r30 774 -#define _EXPAND_METHOD_r00 775 -#define _EXPAND_METHOD_KW_r11 776 -#define _FATAL_ERROR_r00 777 -#define _FATAL_ERROR_r11 778 -#define _FATAL_ERROR_r22 779 -#define _FATAL_ERROR_r33 780 -#define _FORMAT_SIMPLE_r11 781 -#define _FORMAT_WITH_SPEC_r21 782 -#define _FOR_ITER_r23 783 -#define _FOR_ITER_GEN_FRAME_r03 784 -#define _FOR_ITER_GEN_FRAME_r13 785 -#define _FOR_ITER_GEN_FRAME_r23 786 -#define _FOR_ITER_TIER_TWO_r23 787 -#define _GET_AITER_r11 788 -#define _GET_ANEXT_r12 789 -#define _GET_AWAITABLE_r11 790 -#define _GET_ITER_r12 791 -#define _GET_LEN_r12 792 -#define _GET_YIELD_FROM_ITER_r11 793 -#define _GUARD_BINARY_OP_EXTEND_r22 794 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 795 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 796 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 797 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 798 -#define _GUARD_BIT_IS_SET_POP_r00 799 -#define _GUARD_BIT_IS_SET_POP_r10 800 -#define _GUARD_BIT_IS_SET_POP_r21 801 -#define _GUARD_BIT_IS_SET_POP_r32 802 -#define _GUARD_BIT_IS_SET_POP_4_r00 803 -#define _GUARD_BIT_IS_SET_POP_4_r10 804 -#define _GUARD_BIT_IS_SET_POP_4_r21 805 -#define _GUARD_BIT_IS_SET_POP_4_r32 806 -#define _GUARD_BIT_IS_SET_POP_5_r00 807 -#define _GUARD_BIT_IS_SET_POP_5_r10 808 -#define _GUARD_BIT_IS_SET_POP_5_r21 809 -#define _GUARD_BIT_IS_SET_POP_5_r32 810 -#define _GUARD_BIT_IS_SET_POP_6_r00 811 -#define _GUARD_BIT_IS_SET_POP_6_r10 812 -#define _GUARD_BIT_IS_SET_POP_6_r21 813 -#define _GUARD_BIT_IS_SET_POP_6_r32 814 -#define _GUARD_BIT_IS_SET_POP_7_r00 815 -#define _GUARD_BIT_IS_SET_POP_7_r10 816 -#define _GUARD_BIT_IS_SET_POP_7_r21 817 -#define _GUARD_BIT_IS_SET_POP_7_r32 818 -#define _GUARD_BIT_IS_UNSET_POP_r00 819 -#define _GUARD_BIT_IS_UNSET_POP_r10 820 -#define _GUARD_BIT_IS_UNSET_POP_r21 821 -#define _GUARD_BIT_IS_UNSET_POP_r32 822 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 823 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 824 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 825 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 826 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 827 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 828 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 829 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 830 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 831 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 832 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 833 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 834 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 835 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 836 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 837 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 838 -#define _GUARD_CALLABLE_ISINSTANCE_r03 839 -#define _GUARD_CALLABLE_ISINSTANCE_r13 840 -#define _GUARD_CALLABLE_ISINSTANCE_r23 841 -#define _GUARD_CALLABLE_ISINSTANCE_r33 842 -#define _GUARD_CALLABLE_LEN_r03 843 -#define _GUARD_CALLABLE_LEN_r13 844 -#define _GUARD_CALLABLE_LEN_r23 845 -#define _GUARD_CALLABLE_LEN_r33 846 -#define _GUARD_CALLABLE_LIST_APPEND_r03 847 -#define _GUARD_CALLABLE_LIST_APPEND_r13 848 -#define _GUARD_CALLABLE_LIST_APPEND_r23 849 -#define _GUARD_CALLABLE_LIST_APPEND_r33 850 -#define _GUARD_CALLABLE_STR_1_r03 851 -#define _GUARD_CALLABLE_STR_1_r13 852 -#define _GUARD_CALLABLE_STR_1_r23 853 -#define _GUARD_CALLABLE_STR_1_r33 854 -#define _GUARD_CALLABLE_TUPLE_1_r03 855 -#define _GUARD_CALLABLE_TUPLE_1_r13 856 -#define _GUARD_CALLABLE_TUPLE_1_r23 857 -#define _GUARD_CALLABLE_TUPLE_1_r33 858 -#define _GUARD_CALLABLE_TYPE_1_r03 859 -#define _GUARD_CALLABLE_TYPE_1_r13 860 -#define _GUARD_CALLABLE_TYPE_1_r23 861 -#define _GUARD_CALLABLE_TYPE_1_r33 862 -#define _GUARD_CODE_VERSION_r00 863 -#define _GUARD_CODE_VERSION_r11 864 -#define _GUARD_CODE_VERSION_r22 865 -#define _GUARD_CODE_VERSION_r33 866 -#define _GUARD_DORV_NO_DICT_r01 867 -#define _GUARD_DORV_NO_DICT_r11 868 -#define _GUARD_DORV_NO_DICT_r22 869 -#define _GUARD_DORV_NO_DICT_r33 870 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 871 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 872 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 873 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 874 -#define _GUARD_GLOBALS_VERSION_r00 875 -#define _GUARD_GLOBALS_VERSION_r11 876 -#define _GUARD_GLOBALS_VERSION_r22 877 -#define _GUARD_GLOBALS_VERSION_r33 878 -#define _GUARD_IP_RETURN_GENERATOR_r00 879 -#define _GUARD_IP_RETURN_GENERATOR_r11 880 -#define _GUARD_IP_RETURN_GENERATOR_r22 881 -#define _GUARD_IP_RETURN_GENERATOR_r33 882 -#define _GUARD_IP_RETURN_VALUE_r00 883 -#define _GUARD_IP_RETURN_VALUE_r11 884 -#define _GUARD_IP_RETURN_VALUE_r22 885 -#define _GUARD_IP_RETURN_VALUE_r33 886 -#define _GUARD_IP_YIELD_VALUE_r00 887 -#define _GUARD_IP_YIELD_VALUE_r11 888 -#define _GUARD_IP_YIELD_VALUE_r22 889 -#define _GUARD_IP_YIELD_VALUE_r33 890 -#define _GUARD_IP__PUSH_FRAME_r00 891 -#define _GUARD_IP__PUSH_FRAME_r11 892 -#define _GUARD_IP__PUSH_FRAME_r22 893 -#define _GUARD_IP__PUSH_FRAME_r33 894 -#define _GUARD_IS_FALSE_POP_r00 895 -#define _GUARD_IS_FALSE_POP_r10 896 -#define _GUARD_IS_FALSE_POP_r21 897 -#define _GUARD_IS_FALSE_POP_r32 898 -#define _GUARD_IS_NONE_POP_r00 899 -#define _GUARD_IS_NONE_POP_r10 900 -#define _GUARD_IS_NONE_POP_r21 901 -#define _GUARD_IS_NONE_POP_r32 902 -#define _GUARD_IS_NOT_NONE_POP_r10 903 -#define _GUARD_IS_TRUE_POP_r00 904 -#define _GUARD_IS_TRUE_POP_r10 905 -#define _GUARD_IS_TRUE_POP_r21 906 -#define _GUARD_IS_TRUE_POP_r32 907 -#define _GUARD_KEYS_VERSION_r01 908 -#define _GUARD_KEYS_VERSION_r11 909 -#define _GUARD_KEYS_VERSION_r22 910 -#define _GUARD_KEYS_VERSION_r33 911 -#define _GUARD_NOS_ANY_DICT_r02 912 -#define _GUARD_NOS_ANY_DICT_r12 913 -#define _GUARD_NOS_ANY_DICT_r22 914 -#define _GUARD_NOS_ANY_DICT_r33 915 -#define _GUARD_NOS_COMPACT_ASCII_r02 916 -#define _GUARD_NOS_COMPACT_ASCII_r12 917 -#define _GUARD_NOS_COMPACT_ASCII_r22 918 -#define _GUARD_NOS_COMPACT_ASCII_r33 919 -#define _GUARD_NOS_DICT_r02 920 -#define _GUARD_NOS_DICT_r12 921 -#define _GUARD_NOS_DICT_r22 922 -#define _GUARD_NOS_DICT_r33 923 -#define _GUARD_NOS_FLOAT_r02 924 -#define _GUARD_NOS_FLOAT_r12 925 -#define _GUARD_NOS_FLOAT_r22 926 -#define _GUARD_NOS_FLOAT_r33 927 -#define _GUARD_NOS_INT_r02 928 -#define _GUARD_NOS_INT_r12 929 -#define _GUARD_NOS_INT_r22 930 -#define _GUARD_NOS_INT_r33 931 -#define _GUARD_NOS_LIST_r02 932 -#define _GUARD_NOS_LIST_r12 933 -#define _GUARD_NOS_LIST_r22 934 -#define _GUARD_NOS_LIST_r33 935 -#define _GUARD_NOS_NOT_NULL_r02 936 -#define _GUARD_NOS_NOT_NULL_r12 937 -#define _GUARD_NOS_NOT_NULL_r22 938 -#define _GUARD_NOS_NOT_NULL_r33 939 -#define _GUARD_NOS_NULL_r02 940 -#define _GUARD_NOS_NULL_r12 941 -#define _GUARD_NOS_NULL_r22 942 -#define _GUARD_NOS_NULL_r33 943 -#define _GUARD_NOS_OVERFLOWED_r02 944 -#define _GUARD_NOS_OVERFLOWED_r12 945 -#define _GUARD_NOS_OVERFLOWED_r22 946 -#define _GUARD_NOS_OVERFLOWED_r33 947 -#define _GUARD_NOS_TUPLE_r02 948 -#define _GUARD_NOS_TUPLE_r12 949 -#define _GUARD_NOS_TUPLE_r22 950 -#define _GUARD_NOS_TUPLE_r33 951 -#define _GUARD_NOS_UNICODE_r02 952 -#define _GUARD_NOS_UNICODE_r12 953 -#define _GUARD_NOS_UNICODE_r22 954 -#define _GUARD_NOS_UNICODE_r33 955 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 956 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 957 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 958 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 959 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 960 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 961 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 962 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 963 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 964 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 965 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 966 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 967 -#define _GUARD_THIRD_NULL_r03 968 -#define _GUARD_THIRD_NULL_r13 969 -#define _GUARD_THIRD_NULL_r23 970 -#define _GUARD_THIRD_NULL_r33 971 -#define _GUARD_TOS_ANY_DICT_r01 972 -#define _GUARD_TOS_ANY_DICT_r11 973 -#define _GUARD_TOS_ANY_DICT_r22 974 -#define _GUARD_TOS_ANY_DICT_r33 975 -#define _GUARD_TOS_ANY_SET_r01 976 -#define _GUARD_TOS_ANY_SET_r11 977 -#define _GUARD_TOS_ANY_SET_r22 978 -#define _GUARD_TOS_ANY_SET_r33 979 -#define _GUARD_TOS_DICT_r01 980 -#define _GUARD_TOS_DICT_r11 981 -#define _GUARD_TOS_DICT_r22 982 -#define _GUARD_TOS_DICT_r33 983 -#define _GUARD_TOS_FLOAT_r01 984 -#define _GUARD_TOS_FLOAT_r11 985 -#define _GUARD_TOS_FLOAT_r22 986 -#define _GUARD_TOS_FLOAT_r33 987 -#define _GUARD_TOS_FROZENDICT_r01 988 -#define _GUARD_TOS_FROZENDICT_r11 989 -#define _GUARD_TOS_FROZENDICT_r22 990 -#define _GUARD_TOS_FROZENDICT_r33 991 -#define _GUARD_TOS_FROZENSET_r01 992 -#define _GUARD_TOS_FROZENSET_r11 993 -#define _GUARD_TOS_FROZENSET_r22 994 -#define _GUARD_TOS_FROZENSET_r33 995 -#define _GUARD_TOS_INT_r01 996 -#define _GUARD_TOS_INT_r11 997 -#define _GUARD_TOS_INT_r22 998 -#define _GUARD_TOS_INT_r33 999 -#define _GUARD_TOS_LIST_r01 1000 -#define _GUARD_TOS_LIST_r11 1001 -#define _GUARD_TOS_LIST_r22 1002 -#define _GUARD_TOS_LIST_r33 1003 -#define _GUARD_TOS_OVERFLOWED_r01 1004 -#define _GUARD_TOS_OVERFLOWED_r11 1005 -#define _GUARD_TOS_OVERFLOWED_r22 1006 -#define _GUARD_TOS_OVERFLOWED_r33 1007 -#define _GUARD_TOS_SET_r01 1008 -#define _GUARD_TOS_SET_r11 1009 -#define _GUARD_TOS_SET_r22 1010 -#define _GUARD_TOS_SET_r33 1011 -#define _GUARD_TOS_SLICE_r01 1012 -#define _GUARD_TOS_SLICE_r11 1013 -#define _GUARD_TOS_SLICE_r22 1014 -#define _GUARD_TOS_SLICE_r33 1015 -#define _GUARD_TOS_TUPLE_r01 1016 -#define _GUARD_TOS_TUPLE_r11 1017 -#define _GUARD_TOS_TUPLE_r22 1018 -#define _GUARD_TOS_TUPLE_r33 1019 -#define _GUARD_TOS_UNICODE_r01 1020 -#define _GUARD_TOS_UNICODE_r11 1021 -#define _GUARD_TOS_UNICODE_r22 1022 -#define _GUARD_TOS_UNICODE_r33 1023 -#define _GUARD_TYPE_VERSION_r01 1024 -#define _GUARD_TYPE_VERSION_r11 1025 -#define _GUARD_TYPE_VERSION_r22 1026 -#define _GUARD_TYPE_VERSION_r33 1027 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1028 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1029 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1030 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1031 -#define _HANDLE_PENDING_AND_DEOPT_r00 1032 -#define _HANDLE_PENDING_AND_DEOPT_r10 1033 -#define _HANDLE_PENDING_AND_DEOPT_r20 1034 -#define _HANDLE_PENDING_AND_DEOPT_r30 1035 -#define _IMPORT_FROM_r12 1036 -#define _IMPORT_NAME_r21 1037 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1038 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1039 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1040 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1041 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1042 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1043 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1044 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1045 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1046 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1047 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1048 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1049 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1050 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1051 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1052 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1053 -#define _INSERT_NULL_r10 1054 -#define _INSTRUMENTED_FOR_ITER_r23 1055 -#define _INSTRUMENTED_INSTRUCTION_r00 1056 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1057 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1058 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1059 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1060 -#define _INSTRUMENTED_LINE_r00 1061 -#define _INSTRUMENTED_NOT_TAKEN_r00 1062 -#define _INSTRUMENTED_NOT_TAKEN_r11 1063 -#define _INSTRUMENTED_NOT_TAKEN_r22 1064 -#define _INSTRUMENTED_NOT_TAKEN_r33 1065 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1066 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1067 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1068 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1069 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1070 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1071 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1072 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1073 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1074 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1075 -#define _IS_NONE_r11 1076 -#define _IS_OP_r03 1077 -#define _IS_OP_r13 1078 -#define _IS_OP_r23 1079 -#define _ITER_CHECK_LIST_r02 1080 -#define _ITER_CHECK_LIST_r12 1081 -#define _ITER_CHECK_LIST_r22 1082 -#define _ITER_CHECK_LIST_r33 1083 -#define _ITER_CHECK_RANGE_r02 1084 -#define _ITER_CHECK_RANGE_r12 1085 -#define _ITER_CHECK_RANGE_r22 1086 -#define _ITER_CHECK_RANGE_r33 1087 -#define _ITER_CHECK_TUPLE_r02 1088 -#define _ITER_CHECK_TUPLE_r12 1089 -#define _ITER_CHECK_TUPLE_r22 1090 -#define _ITER_CHECK_TUPLE_r33 1091 -#define _ITER_JUMP_LIST_r02 1092 -#define _ITER_JUMP_LIST_r12 1093 -#define _ITER_JUMP_LIST_r22 1094 -#define _ITER_JUMP_LIST_r33 1095 -#define _ITER_JUMP_RANGE_r02 1096 -#define _ITER_JUMP_RANGE_r12 1097 -#define _ITER_JUMP_RANGE_r22 1098 -#define _ITER_JUMP_RANGE_r33 1099 -#define _ITER_JUMP_TUPLE_r02 1100 -#define _ITER_JUMP_TUPLE_r12 1101 -#define _ITER_JUMP_TUPLE_r22 1102 -#define _ITER_JUMP_TUPLE_r33 1103 -#define _ITER_NEXT_LIST_r23 1104 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1105 -#define _ITER_NEXT_RANGE_r03 1106 -#define _ITER_NEXT_RANGE_r13 1107 -#define _ITER_NEXT_RANGE_r23 1108 -#define _ITER_NEXT_TUPLE_r03 1109 -#define _ITER_NEXT_TUPLE_r13 1110 -#define _ITER_NEXT_TUPLE_r23 1111 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1112 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1113 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1114 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1115 -#define _JUMP_TO_TOP_r00 1116 -#define _LIST_APPEND_r10 1117 -#define _LIST_EXTEND_r10 1118 -#define _LOAD_ATTR_r10 1119 -#define _LOAD_ATTR_CLASS_r11 1120 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1121 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1122 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1123 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1124 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1125 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1126 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1127 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1128 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1129 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1130 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1131 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1132 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1133 -#define _LOAD_ATTR_MODULE_r12 1134 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1135 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1136 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1137 -#define _LOAD_ATTR_SLOT_r02 1138 -#define _LOAD_ATTR_SLOT_r12 1139 -#define _LOAD_ATTR_SLOT_r23 1140 -#define _LOAD_ATTR_WITH_HINT_r12 1141 -#define _LOAD_BUILD_CLASS_r01 1142 -#define _LOAD_BYTECODE_r00 1143 -#define _LOAD_COMMON_CONSTANT_r01 1144 -#define _LOAD_COMMON_CONSTANT_r12 1145 -#define _LOAD_COMMON_CONSTANT_r23 1146 -#define _LOAD_CONST_r01 1147 -#define _LOAD_CONST_r12 1148 -#define _LOAD_CONST_r23 1149 -#define _LOAD_CONST_INLINE_r01 1150 -#define _LOAD_CONST_INLINE_r12 1151 -#define _LOAD_CONST_INLINE_r23 1152 -#define _LOAD_CONST_INLINE_BORROW_r01 1153 -#define _LOAD_CONST_INLINE_BORROW_r12 1154 -#define _LOAD_CONST_INLINE_BORROW_r23 1155 -#define _LOAD_CONST_UNDER_INLINE_r02 1156 -#define _LOAD_CONST_UNDER_INLINE_r12 1157 -#define _LOAD_CONST_UNDER_INLINE_r23 1158 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1159 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1160 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1161 -#define _LOAD_DEREF_r01 1162 -#define _LOAD_FAST_r01 1163 -#define _LOAD_FAST_r12 1164 -#define _LOAD_FAST_r23 1165 -#define _LOAD_FAST_0_r01 1166 -#define _LOAD_FAST_0_r12 1167 -#define _LOAD_FAST_0_r23 1168 -#define _LOAD_FAST_1_r01 1169 -#define _LOAD_FAST_1_r12 1170 -#define _LOAD_FAST_1_r23 1171 -#define _LOAD_FAST_2_r01 1172 -#define _LOAD_FAST_2_r12 1173 -#define _LOAD_FAST_2_r23 1174 -#define _LOAD_FAST_3_r01 1175 -#define _LOAD_FAST_3_r12 1176 -#define _LOAD_FAST_3_r23 1177 -#define _LOAD_FAST_4_r01 1178 -#define _LOAD_FAST_4_r12 1179 -#define _LOAD_FAST_4_r23 1180 -#define _LOAD_FAST_5_r01 1181 -#define _LOAD_FAST_5_r12 1182 -#define _LOAD_FAST_5_r23 1183 -#define _LOAD_FAST_6_r01 1184 -#define _LOAD_FAST_6_r12 1185 -#define _LOAD_FAST_6_r23 1186 -#define _LOAD_FAST_7_r01 1187 -#define _LOAD_FAST_7_r12 1188 -#define _LOAD_FAST_7_r23 1189 -#define _LOAD_FAST_AND_CLEAR_r01 1190 -#define _LOAD_FAST_AND_CLEAR_r12 1191 -#define _LOAD_FAST_AND_CLEAR_r23 1192 -#define _LOAD_FAST_BORROW_r01 1193 -#define _LOAD_FAST_BORROW_r12 1194 -#define _LOAD_FAST_BORROW_r23 1195 -#define _LOAD_FAST_BORROW_0_r01 1196 -#define _LOAD_FAST_BORROW_0_r12 1197 -#define _LOAD_FAST_BORROW_0_r23 1198 -#define _LOAD_FAST_BORROW_1_r01 1199 -#define _LOAD_FAST_BORROW_1_r12 1200 -#define _LOAD_FAST_BORROW_1_r23 1201 -#define _LOAD_FAST_BORROW_2_r01 1202 -#define _LOAD_FAST_BORROW_2_r12 1203 -#define _LOAD_FAST_BORROW_2_r23 1204 -#define _LOAD_FAST_BORROW_3_r01 1205 -#define _LOAD_FAST_BORROW_3_r12 1206 -#define _LOAD_FAST_BORROW_3_r23 1207 -#define _LOAD_FAST_BORROW_4_r01 1208 -#define _LOAD_FAST_BORROW_4_r12 1209 -#define _LOAD_FAST_BORROW_4_r23 1210 -#define _LOAD_FAST_BORROW_5_r01 1211 -#define _LOAD_FAST_BORROW_5_r12 1212 -#define _LOAD_FAST_BORROW_5_r23 1213 -#define _LOAD_FAST_BORROW_6_r01 1214 -#define _LOAD_FAST_BORROW_6_r12 1215 -#define _LOAD_FAST_BORROW_6_r23 1216 -#define _LOAD_FAST_BORROW_7_r01 1217 -#define _LOAD_FAST_BORROW_7_r12 1218 -#define _LOAD_FAST_BORROW_7_r23 1219 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1220 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1221 -#define _LOAD_FAST_CHECK_r01 1222 -#define _LOAD_FAST_CHECK_r12 1223 -#define _LOAD_FAST_CHECK_r23 1224 -#define _LOAD_FAST_LOAD_FAST_r02 1225 -#define _LOAD_FAST_LOAD_FAST_r13 1226 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1227 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1228 -#define _LOAD_GLOBAL_r00 1229 -#define _LOAD_GLOBAL_BUILTINS_r01 1230 -#define _LOAD_GLOBAL_MODULE_r01 1231 -#define _LOAD_LOCALS_r01 1232 -#define _LOAD_LOCALS_r12 1233 -#define _LOAD_LOCALS_r23 1234 -#define _LOAD_NAME_r01 1235 -#define _LOAD_SMALL_INT_r01 1236 -#define _LOAD_SMALL_INT_r12 1237 -#define _LOAD_SMALL_INT_r23 1238 -#define _LOAD_SMALL_INT_0_r01 1239 -#define _LOAD_SMALL_INT_0_r12 1240 -#define _LOAD_SMALL_INT_0_r23 1241 -#define _LOAD_SMALL_INT_1_r01 1242 -#define _LOAD_SMALL_INT_1_r12 1243 -#define _LOAD_SMALL_INT_1_r23 1244 -#define _LOAD_SMALL_INT_2_r01 1245 -#define _LOAD_SMALL_INT_2_r12 1246 -#define _LOAD_SMALL_INT_2_r23 1247 -#define _LOAD_SMALL_INT_3_r01 1248 -#define _LOAD_SMALL_INT_3_r12 1249 -#define _LOAD_SMALL_INT_3_r23 1250 -#define _LOAD_SPECIAL_r00 1251 -#define _LOAD_SUPER_ATTR_ATTR_r31 1252 -#define _LOAD_SUPER_ATTR_METHOD_r32 1253 -#define _MAKE_CALLARGS_A_TUPLE_r33 1254 -#define _MAKE_CELL_r00 1255 -#define _MAKE_FUNCTION_r11 1256 -#define _MAKE_WARM_r00 1257 -#define _MAKE_WARM_r11 1258 -#define _MAKE_WARM_r22 1259 -#define _MAKE_WARM_r33 1260 -#define _MAP_ADD_r20 1261 -#define _MATCH_CLASS_r31 1262 -#define _MATCH_KEYS_r23 1263 -#define _MATCH_MAPPING_r02 1264 -#define _MATCH_MAPPING_r12 1265 -#define _MATCH_MAPPING_r23 1266 -#define _MATCH_SEQUENCE_r02 1267 -#define _MATCH_SEQUENCE_r12 1268 -#define _MATCH_SEQUENCE_r23 1269 -#define _MAYBE_EXPAND_METHOD_r00 1270 -#define _MAYBE_EXPAND_METHOD_KW_r11 1271 -#define _MONITOR_CALL_r00 1272 -#define _MONITOR_CALL_KW_r11 1273 -#define _MONITOR_JUMP_BACKWARD_r00 1274 -#define _MONITOR_JUMP_BACKWARD_r11 1275 -#define _MONITOR_JUMP_BACKWARD_r22 1276 -#define _MONITOR_JUMP_BACKWARD_r33 1277 -#define _MONITOR_RESUME_r00 1278 -#define _NOP_r00 1279 -#define _NOP_r11 1280 -#define _NOP_r22 1281 -#define _NOP_r33 1282 -#define _POP_CALL_r20 1283 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1284 -#define _POP_CALL_ONE_r30 1285 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1286 -#define _POP_CALL_TWO_r30 1287 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1288 -#define _POP_EXCEPT_r10 1289 -#define _POP_ITER_r20 1290 -#define _POP_JUMP_IF_FALSE_r00 1291 -#define _POP_JUMP_IF_FALSE_r10 1292 -#define _POP_JUMP_IF_FALSE_r21 1293 -#define _POP_JUMP_IF_FALSE_r32 1294 -#define _POP_JUMP_IF_TRUE_r00 1295 -#define _POP_JUMP_IF_TRUE_r10 1296 -#define _POP_JUMP_IF_TRUE_r21 1297 -#define _POP_JUMP_IF_TRUE_r32 1298 -#define _POP_TOP_r10 1299 -#define _POP_TOP_FLOAT_r00 1300 -#define _POP_TOP_FLOAT_r10 1301 -#define _POP_TOP_FLOAT_r21 1302 -#define _POP_TOP_FLOAT_r32 1303 -#define _POP_TOP_INT_r00 1304 -#define _POP_TOP_INT_r10 1305 -#define _POP_TOP_INT_r21 1306 -#define _POP_TOP_INT_r32 1307 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1308 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1309 -#define _POP_TOP_NOP_r00 1310 -#define _POP_TOP_NOP_r10 1311 -#define _POP_TOP_NOP_r21 1312 -#define _POP_TOP_NOP_r32 1313 -#define _POP_TOP_UNICODE_r00 1314 -#define _POP_TOP_UNICODE_r10 1315 -#define _POP_TOP_UNICODE_r21 1316 -#define _POP_TOP_UNICODE_r32 1317 -#define _POP_TWO_r20 1318 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1319 -#define _PUSH_EXC_INFO_r02 1320 -#define _PUSH_EXC_INFO_r12 1321 -#define _PUSH_EXC_INFO_r23 1322 -#define _PUSH_FRAME_r10 1323 -#define _PUSH_NULL_r01 1324 -#define _PUSH_NULL_r12 1325 -#define _PUSH_NULL_r23 1326 -#define _PUSH_NULL_CONDITIONAL_r00 1327 -#define _PY_FRAME_EX_r31 1328 -#define _PY_FRAME_GENERAL_r01 1329 -#define _PY_FRAME_KW_r11 1330 -#define _QUICKEN_RESUME_r00 1331 -#define _QUICKEN_RESUME_r11 1332 -#define _QUICKEN_RESUME_r22 1333 -#define _QUICKEN_RESUME_r33 1334 -#define _REPLACE_WITH_TRUE_r02 1335 -#define _REPLACE_WITH_TRUE_r12 1336 -#define _REPLACE_WITH_TRUE_r23 1337 -#define _RESUME_CHECK_r00 1338 -#define _RESUME_CHECK_r11 1339 -#define _RESUME_CHECK_r22 1340 -#define _RESUME_CHECK_r33 1341 -#define _RETURN_GENERATOR_r01 1342 -#define _RETURN_VALUE_r11 1343 -#define _SAVE_RETURN_OFFSET_r00 1344 -#define _SAVE_RETURN_OFFSET_r11 1345 -#define _SAVE_RETURN_OFFSET_r22 1346 -#define _SAVE_RETURN_OFFSET_r33 1347 -#define _SEND_r22 1348 -#define _SEND_GEN_FRAME_r22 1349 -#define _SETUP_ANNOTATIONS_r00 1350 -#define _SET_ADD_r10 1351 -#define _SET_FUNCTION_ATTRIBUTE_r01 1352 -#define _SET_FUNCTION_ATTRIBUTE_r11 1353 -#define _SET_FUNCTION_ATTRIBUTE_r21 1354 -#define _SET_FUNCTION_ATTRIBUTE_r32 1355 -#define _SET_IP_r00 1356 -#define _SET_IP_r11 1357 -#define _SET_IP_r22 1358 -#define _SET_IP_r33 1359 -#define _SET_UPDATE_r10 1360 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1361 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1362 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1363 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1364 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1365 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1366 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1367 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1368 -#define _SPILL_OR_RELOAD_r01 1369 -#define _SPILL_OR_RELOAD_r02 1370 -#define _SPILL_OR_RELOAD_r03 1371 -#define _SPILL_OR_RELOAD_r10 1372 -#define _SPILL_OR_RELOAD_r12 1373 -#define _SPILL_OR_RELOAD_r13 1374 -#define _SPILL_OR_RELOAD_r20 1375 -#define _SPILL_OR_RELOAD_r21 1376 -#define _SPILL_OR_RELOAD_r23 1377 -#define _SPILL_OR_RELOAD_r30 1378 -#define _SPILL_OR_RELOAD_r31 1379 -#define _SPILL_OR_RELOAD_r32 1380 -#define _START_EXECUTOR_r00 1381 -#define _STORE_ATTR_r20 1382 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1383 -#define _STORE_ATTR_SLOT_r21 1384 -#define _STORE_ATTR_WITH_HINT_r21 1385 -#define _STORE_DEREF_r10 1386 -#define _STORE_FAST_LOAD_FAST_r11 1387 -#define _STORE_FAST_STORE_FAST_r20 1388 -#define _STORE_GLOBAL_r10 1389 -#define _STORE_NAME_r10 1390 -#define _STORE_SLICE_r30 1391 -#define _STORE_SUBSCR_r30 1392 -#define _STORE_SUBSCR_DICT_r31 1393 -#define _STORE_SUBSCR_LIST_INT_r32 1394 -#define _SWAP_r11 1395 -#define _SWAP_2_r02 1396 -#define _SWAP_2_r12 1397 -#define _SWAP_2_r22 1398 -#define _SWAP_2_r33 1399 -#define _SWAP_3_r03 1400 -#define _SWAP_3_r13 1401 -#define _SWAP_3_r23 1402 -#define _SWAP_3_r33 1403 -#define _SWAP_FAST_r01 1404 -#define _SWAP_FAST_r11 1405 -#define _SWAP_FAST_r22 1406 -#define _SWAP_FAST_r33 1407 -#define _SWAP_FAST_0_r01 1408 -#define _SWAP_FAST_0_r11 1409 -#define _SWAP_FAST_0_r22 1410 -#define _SWAP_FAST_0_r33 1411 -#define _SWAP_FAST_1_r01 1412 -#define _SWAP_FAST_1_r11 1413 -#define _SWAP_FAST_1_r22 1414 -#define _SWAP_FAST_1_r33 1415 -#define _SWAP_FAST_2_r01 1416 -#define _SWAP_FAST_2_r11 1417 -#define _SWAP_FAST_2_r22 1418 -#define _SWAP_FAST_2_r33 1419 -#define _SWAP_FAST_3_r01 1420 -#define _SWAP_FAST_3_r11 1421 -#define _SWAP_FAST_3_r22 1422 -#define _SWAP_FAST_3_r33 1423 -#define _SWAP_FAST_4_r01 1424 -#define _SWAP_FAST_4_r11 1425 -#define _SWAP_FAST_4_r22 1426 -#define _SWAP_FAST_4_r33 1427 -#define _SWAP_FAST_5_r01 1428 -#define _SWAP_FAST_5_r11 1429 -#define _SWAP_FAST_5_r22 1430 -#define _SWAP_FAST_5_r33 1431 -#define _SWAP_FAST_6_r01 1432 -#define _SWAP_FAST_6_r11 1433 -#define _SWAP_FAST_6_r22 1434 -#define _SWAP_FAST_6_r33 1435 -#define _SWAP_FAST_7_r01 1436 -#define _SWAP_FAST_7_r11 1437 -#define _SWAP_FAST_7_r22 1438 -#define _SWAP_FAST_7_r33 1439 -#define _TIER2_RESUME_CHECK_r00 1440 -#define _TIER2_RESUME_CHECK_r11 1441 -#define _TIER2_RESUME_CHECK_r22 1442 -#define _TIER2_RESUME_CHECK_r33 1443 -#define _TO_BOOL_r11 1444 -#define _TO_BOOL_BOOL_r01 1445 -#define _TO_BOOL_BOOL_r11 1446 -#define _TO_BOOL_BOOL_r22 1447 -#define _TO_BOOL_BOOL_r33 1448 -#define _TO_BOOL_INT_r02 1449 -#define _TO_BOOL_INT_r12 1450 -#define _TO_BOOL_INT_r23 1451 -#define _TO_BOOL_LIST_r02 1452 -#define _TO_BOOL_LIST_r12 1453 -#define _TO_BOOL_LIST_r23 1454 -#define _TO_BOOL_NONE_r01 1455 -#define _TO_BOOL_NONE_r11 1456 -#define _TO_BOOL_NONE_r22 1457 -#define _TO_BOOL_NONE_r33 1458 -#define _TO_BOOL_STR_r02 1459 -#define _TO_BOOL_STR_r12 1460 -#define _TO_BOOL_STR_r23 1461 -#define _TRACE_RECORD_r00 1462 -#define _UNARY_INVERT_r12 1463 -#define _UNARY_NEGATIVE_r12 1464 -#define _UNARY_NOT_r01 1465 -#define _UNARY_NOT_r11 1466 -#define _UNARY_NOT_r22 1467 -#define _UNARY_NOT_r33 1468 -#define _UNPACK_EX_r10 1469 -#define _UNPACK_SEQUENCE_r10 1470 -#define _UNPACK_SEQUENCE_LIST_r10 1471 -#define _UNPACK_SEQUENCE_TUPLE_r10 1472 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1473 -#define _WITH_EXCEPT_START_r33 1474 -#define _YIELD_VALUE_r11 1475 -#define MAX_UOP_REGS_ID 1475 +#define _YIELD_VALUE 596 +#define MAX_UOP_ID 596 +#define _BINARY_OP_r23 597 +#define _BINARY_OP_ADD_FLOAT_r03 598 +#define _BINARY_OP_ADD_FLOAT_r13 599 +#define _BINARY_OP_ADD_FLOAT_r23 600 +#define _BINARY_OP_ADD_INT_r03 601 +#define _BINARY_OP_ADD_INT_r13 602 +#define _BINARY_OP_ADD_INT_r23 603 +#define _BINARY_OP_ADD_UNICODE_r03 604 +#define _BINARY_OP_ADD_UNICODE_r13 605 +#define _BINARY_OP_ADD_UNICODE_r23 606 +#define _BINARY_OP_EXTEND_r23 607 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 608 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 609 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 610 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 611 +#define _BINARY_OP_MULTIPLY_INT_r03 612 +#define _BINARY_OP_MULTIPLY_INT_r13 613 +#define _BINARY_OP_MULTIPLY_INT_r23 614 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 615 +#define _BINARY_OP_SUBSCR_DICT_r23 616 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 617 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 618 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 619 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 620 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 621 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 622 +#define _BINARY_OP_SUBSCR_STR_INT_r23 623 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 624 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 625 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 626 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 627 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 628 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 629 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 630 +#define _BINARY_OP_SUBTRACT_INT_r03 631 +#define _BINARY_OP_SUBTRACT_INT_r13 632 +#define _BINARY_OP_SUBTRACT_INT_r23 633 +#define _BINARY_SLICE_r31 634 +#define _BUILD_INTERPOLATION_r01 635 +#define _BUILD_LIST_r01 636 +#define _BUILD_MAP_r01 637 +#define _BUILD_SET_r01 638 +#define _BUILD_SLICE_r01 639 +#define _BUILD_STRING_r01 640 +#define _BUILD_TEMPLATE_r21 641 +#define _BUILD_TUPLE_r01 642 +#define _CALL_BUILTIN_CLASS_r01 643 +#define _CALL_BUILTIN_FAST_r01 644 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 645 +#define _CALL_BUILTIN_O_r03 646 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 647 +#define _CALL_INTRINSIC_1_r11 648 +#define _CALL_INTRINSIC_2_r21 649 +#define _CALL_ISINSTANCE_r31 650 +#define _CALL_KW_NON_PY_r11 651 +#define _CALL_LEN_r33 652 +#define _CALL_LIST_APPEND_r03 653 +#define _CALL_LIST_APPEND_r13 654 +#define _CALL_LIST_APPEND_r23 655 +#define _CALL_LIST_APPEND_r33 656 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 657 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 658 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 659 +#define _CALL_METHOD_DESCRIPTOR_O_r03 660 +#define _CALL_NON_PY_GENERAL_r01 661 +#define _CALL_STR_1_r32 662 +#define _CALL_TUPLE_1_r32 663 +#define _CALL_TYPE_1_r02 664 +#define _CALL_TYPE_1_r12 665 +#define _CALL_TYPE_1_r22 666 +#define _CALL_TYPE_1_r32 667 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 668 +#define _CHECK_ATTR_CLASS_r01 669 +#define _CHECK_ATTR_CLASS_r11 670 +#define _CHECK_ATTR_CLASS_r22 671 +#define _CHECK_ATTR_CLASS_r33 672 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 673 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 674 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 675 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 676 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 677 +#define _CHECK_EG_MATCH_r22 678 +#define _CHECK_EXC_MATCH_r22 679 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 680 +#define _CHECK_FUNCTION_VERSION_r00 681 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 682 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 683 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 684 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 685 +#define _CHECK_FUNCTION_VERSION_KW_r11 686 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 687 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 688 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 689 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 690 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 691 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 692 +#define _CHECK_IS_PY_CALLABLE_EX_r03 693 +#define _CHECK_IS_PY_CALLABLE_EX_r13 694 +#define _CHECK_IS_PY_CALLABLE_EX_r23 695 +#define _CHECK_IS_PY_CALLABLE_EX_r33 696 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 697 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 698 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 699 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 700 +#define _CHECK_METHOD_VERSION_r00 701 +#define _CHECK_METHOD_VERSION_KW_r11 702 +#define _CHECK_PEP_523_r00 703 +#define _CHECK_PEP_523_r11 704 +#define _CHECK_PEP_523_r22 705 +#define _CHECK_PEP_523_r33 706 +#define _CHECK_PERIODIC_r00 707 +#define _CHECK_PERIODIC_AT_END_r00 708 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 709 +#define _CHECK_RECURSION_REMAINING_r00 710 +#define _CHECK_RECURSION_REMAINING_r11 711 +#define _CHECK_RECURSION_REMAINING_r22 712 +#define _CHECK_RECURSION_REMAINING_r33 713 +#define _CHECK_STACK_SPACE_r00 714 +#define _CHECK_STACK_SPACE_OPERAND_r00 715 +#define _CHECK_STACK_SPACE_OPERAND_r11 716 +#define _CHECK_STACK_SPACE_OPERAND_r22 717 +#define _CHECK_STACK_SPACE_OPERAND_r33 718 +#define _CHECK_VALIDITY_r00 719 +#define _CHECK_VALIDITY_r11 720 +#define _CHECK_VALIDITY_r22 721 +#define _CHECK_VALIDITY_r33 722 +#define _COLD_DYNAMIC_EXIT_r00 723 +#define _COLD_EXIT_r00 724 +#define _COMPARE_OP_r21 725 +#define _COMPARE_OP_FLOAT_r03 726 +#define _COMPARE_OP_FLOAT_r13 727 +#define _COMPARE_OP_FLOAT_r23 728 +#define _COMPARE_OP_INT_r23 729 +#define _COMPARE_OP_STR_r23 730 +#define _CONTAINS_OP_r23 731 +#define _CONTAINS_OP_DICT_r23 732 +#define _CONTAINS_OP_SET_r23 733 +#define _CONVERT_VALUE_r11 734 +#define _COPY_r01 735 +#define _COPY_1_r02 736 +#define _COPY_1_r12 737 +#define _COPY_1_r23 738 +#define _COPY_2_r03 739 +#define _COPY_2_r13 740 +#define _COPY_2_r23 741 +#define _COPY_3_r03 742 +#define _COPY_3_r13 743 +#define _COPY_3_r23 744 +#define _COPY_3_r33 745 +#define _COPY_FREE_VARS_r00 746 +#define _COPY_FREE_VARS_r11 747 +#define _COPY_FREE_VARS_r22 748 +#define _COPY_FREE_VARS_r33 749 +#define _CREATE_INIT_FRAME_r01 750 +#define _DELETE_ATTR_r10 751 +#define _DELETE_DEREF_r00 752 +#define _DELETE_FAST_r00 753 +#define _DELETE_GLOBAL_r00 754 +#define _DELETE_NAME_r00 755 +#define _DELETE_SUBSCR_r20 756 +#define _DEOPT_r00 757 +#define _DEOPT_r10 758 +#define _DEOPT_r20 759 +#define _DEOPT_r30 760 +#define _DICT_MERGE_r10 761 +#define _DICT_UPDATE_r10 762 +#define _DO_CALL_r01 763 +#define _DO_CALL_FUNCTION_EX_r31 764 +#define _DO_CALL_KW_r11 765 +#define _DYNAMIC_EXIT_r00 766 +#define _DYNAMIC_EXIT_r10 767 +#define _DYNAMIC_EXIT_r20 768 +#define _DYNAMIC_EXIT_r30 769 +#define _END_FOR_r10 770 +#define _END_SEND_r21 771 +#define _ERROR_POP_N_r00 772 +#define _EXIT_INIT_CHECK_r10 773 +#define _EXIT_TRACE_r00 774 +#define _EXIT_TRACE_r10 775 +#define _EXIT_TRACE_r20 776 +#define _EXIT_TRACE_r30 777 +#define _EXPAND_METHOD_r00 778 +#define _EXPAND_METHOD_KW_r11 779 +#define _FATAL_ERROR_r00 780 +#define _FATAL_ERROR_r11 781 +#define _FATAL_ERROR_r22 782 +#define _FATAL_ERROR_r33 783 +#define _FORMAT_SIMPLE_r11 784 +#define _FORMAT_WITH_SPEC_r21 785 +#define _FOR_ITER_r23 786 +#define _FOR_ITER_GEN_FRAME_r03 787 +#define _FOR_ITER_GEN_FRAME_r13 788 +#define _FOR_ITER_GEN_FRAME_r23 789 +#define _FOR_ITER_TIER_TWO_r23 790 +#define _GET_AITER_r11 791 +#define _GET_ANEXT_r12 792 +#define _GET_AWAITABLE_r11 793 +#define _GET_ITER_r12 794 +#define _GET_LEN_r12 795 +#define _GET_YIELD_FROM_ITER_r11 796 +#define _GUARD_BINARY_OP_EXTEND_r22 797 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 798 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 799 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 800 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 801 +#define _GUARD_BIT_IS_SET_POP_r00 802 +#define _GUARD_BIT_IS_SET_POP_r10 803 +#define _GUARD_BIT_IS_SET_POP_r21 804 +#define _GUARD_BIT_IS_SET_POP_r32 805 +#define _GUARD_BIT_IS_SET_POP_4_r00 806 +#define _GUARD_BIT_IS_SET_POP_4_r10 807 +#define _GUARD_BIT_IS_SET_POP_4_r21 808 +#define _GUARD_BIT_IS_SET_POP_4_r32 809 +#define _GUARD_BIT_IS_SET_POP_5_r00 810 +#define _GUARD_BIT_IS_SET_POP_5_r10 811 +#define _GUARD_BIT_IS_SET_POP_5_r21 812 +#define _GUARD_BIT_IS_SET_POP_5_r32 813 +#define _GUARD_BIT_IS_SET_POP_6_r00 814 +#define _GUARD_BIT_IS_SET_POP_6_r10 815 +#define _GUARD_BIT_IS_SET_POP_6_r21 816 +#define _GUARD_BIT_IS_SET_POP_6_r32 817 +#define _GUARD_BIT_IS_SET_POP_7_r00 818 +#define _GUARD_BIT_IS_SET_POP_7_r10 819 +#define _GUARD_BIT_IS_SET_POP_7_r21 820 +#define _GUARD_BIT_IS_SET_POP_7_r32 821 +#define _GUARD_BIT_IS_UNSET_POP_r00 822 +#define _GUARD_BIT_IS_UNSET_POP_r10 823 +#define _GUARD_BIT_IS_UNSET_POP_r21 824 +#define _GUARD_BIT_IS_UNSET_POP_r32 825 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 826 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 827 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 828 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 829 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 830 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 831 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 832 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 833 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 834 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 835 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 836 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 837 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 838 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 839 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 840 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 841 +#define _GUARD_CALLABLE_ISINSTANCE_r03 842 +#define _GUARD_CALLABLE_ISINSTANCE_r13 843 +#define _GUARD_CALLABLE_ISINSTANCE_r23 844 +#define _GUARD_CALLABLE_ISINSTANCE_r33 845 +#define _GUARD_CALLABLE_LEN_r03 846 +#define _GUARD_CALLABLE_LEN_r13 847 +#define _GUARD_CALLABLE_LEN_r23 848 +#define _GUARD_CALLABLE_LEN_r33 849 +#define _GUARD_CALLABLE_LIST_APPEND_r03 850 +#define _GUARD_CALLABLE_LIST_APPEND_r13 851 +#define _GUARD_CALLABLE_LIST_APPEND_r23 852 +#define _GUARD_CALLABLE_LIST_APPEND_r33 853 +#define _GUARD_CALLABLE_STR_1_r03 854 +#define _GUARD_CALLABLE_STR_1_r13 855 +#define _GUARD_CALLABLE_STR_1_r23 856 +#define _GUARD_CALLABLE_STR_1_r33 857 +#define _GUARD_CALLABLE_TUPLE_1_r03 858 +#define _GUARD_CALLABLE_TUPLE_1_r13 859 +#define _GUARD_CALLABLE_TUPLE_1_r23 860 +#define _GUARD_CALLABLE_TUPLE_1_r33 861 +#define _GUARD_CALLABLE_TYPE_1_r03 862 +#define _GUARD_CALLABLE_TYPE_1_r13 863 +#define _GUARD_CALLABLE_TYPE_1_r23 864 +#define _GUARD_CALLABLE_TYPE_1_r33 865 +#define _GUARD_CODE_VERSION_r00 866 +#define _GUARD_CODE_VERSION_r11 867 +#define _GUARD_CODE_VERSION_r22 868 +#define _GUARD_CODE_VERSION_r33 869 +#define _GUARD_DORV_NO_DICT_r01 870 +#define _GUARD_DORV_NO_DICT_r11 871 +#define _GUARD_DORV_NO_DICT_r22 872 +#define _GUARD_DORV_NO_DICT_r33 873 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 874 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 875 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 876 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 877 +#define _GUARD_GLOBALS_VERSION_r00 878 +#define _GUARD_GLOBALS_VERSION_r11 879 +#define _GUARD_GLOBALS_VERSION_r22 880 +#define _GUARD_GLOBALS_VERSION_r33 881 +#define _GUARD_IP_RETURN_GENERATOR_r00 882 +#define _GUARD_IP_RETURN_GENERATOR_r11 883 +#define _GUARD_IP_RETURN_GENERATOR_r22 884 +#define _GUARD_IP_RETURN_GENERATOR_r33 885 +#define _GUARD_IP_RETURN_VALUE_r00 886 +#define _GUARD_IP_RETURN_VALUE_r11 887 +#define _GUARD_IP_RETURN_VALUE_r22 888 +#define _GUARD_IP_RETURN_VALUE_r33 889 +#define _GUARD_IP_YIELD_VALUE_r00 890 +#define _GUARD_IP_YIELD_VALUE_r11 891 +#define _GUARD_IP_YIELD_VALUE_r22 892 +#define _GUARD_IP_YIELD_VALUE_r33 893 +#define _GUARD_IP__PUSH_FRAME_r00 894 +#define _GUARD_IP__PUSH_FRAME_r11 895 +#define _GUARD_IP__PUSH_FRAME_r22 896 +#define _GUARD_IP__PUSH_FRAME_r33 897 +#define _GUARD_IS_FALSE_POP_r00 898 +#define _GUARD_IS_FALSE_POP_r10 899 +#define _GUARD_IS_FALSE_POP_r21 900 +#define _GUARD_IS_FALSE_POP_r32 901 +#define _GUARD_IS_NONE_POP_r00 902 +#define _GUARD_IS_NONE_POP_r10 903 +#define _GUARD_IS_NONE_POP_r21 904 +#define _GUARD_IS_NONE_POP_r32 905 +#define _GUARD_IS_NOT_NONE_POP_r10 906 +#define _GUARD_IS_TRUE_POP_r00 907 +#define _GUARD_IS_TRUE_POP_r10 908 +#define _GUARD_IS_TRUE_POP_r21 909 +#define _GUARD_IS_TRUE_POP_r32 910 +#define _GUARD_KEYS_VERSION_r01 911 +#define _GUARD_KEYS_VERSION_r11 912 +#define _GUARD_KEYS_VERSION_r22 913 +#define _GUARD_KEYS_VERSION_r33 914 +#define _GUARD_NOS_ANY_DICT_r02 915 +#define _GUARD_NOS_ANY_DICT_r12 916 +#define _GUARD_NOS_ANY_DICT_r22 917 +#define _GUARD_NOS_ANY_DICT_r33 918 +#define _GUARD_NOS_COMPACT_ASCII_r02 919 +#define _GUARD_NOS_COMPACT_ASCII_r12 920 +#define _GUARD_NOS_COMPACT_ASCII_r22 921 +#define _GUARD_NOS_COMPACT_ASCII_r33 922 +#define _GUARD_NOS_DICT_r02 923 +#define _GUARD_NOS_DICT_r12 924 +#define _GUARD_NOS_DICT_r22 925 +#define _GUARD_NOS_DICT_r33 926 +#define _GUARD_NOS_FLOAT_r02 927 +#define _GUARD_NOS_FLOAT_r12 928 +#define _GUARD_NOS_FLOAT_r22 929 +#define _GUARD_NOS_FLOAT_r33 930 +#define _GUARD_NOS_INT_r02 931 +#define _GUARD_NOS_INT_r12 932 +#define _GUARD_NOS_INT_r22 933 +#define _GUARD_NOS_INT_r33 934 +#define _GUARD_NOS_LIST_r02 935 +#define _GUARD_NOS_LIST_r12 936 +#define _GUARD_NOS_LIST_r22 937 +#define _GUARD_NOS_LIST_r33 938 +#define _GUARD_NOS_NOT_NULL_r02 939 +#define _GUARD_NOS_NOT_NULL_r12 940 +#define _GUARD_NOS_NOT_NULL_r22 941 +#define _GUARD_NOS_NOT_NULL_r33 942 +#define _GUARD_NOS_NULL_r02 943 +#define _GUARD_NOS_NULL_r12 944 +#define _GUARD_NOS_NULL_r22 945 +#define _GUARD_NOS_NULL_r33 946 +#define _GUARD_NOS_OVERFLOWED_r02 947 +#define _GUARD_NOS_OVERFLOWED_r12 948 +#define _GUARD_NOS_OVERFLOWED_r22 949 +#define _GUARD_NOS_OVERFLOWED_r33 950 +#define _GUARD_NOS_TUPLE_r02 951 +#define _GUARD_NOS_TUPLE_r12 952 +#define _GUARD_NOS_TUPLE_r22 953 +#define _GUARD_NOS_TUPLE_r33 954 +#define _GUARD_NOS_UNICODE_r02 955 +#define _GUARD_NOS_UNICODE_r12 956 +#define _GUARD_NOS_UNICODE_r22 957 +#define _GUARD_NOS_UNICODE_r33 958 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 959 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 960 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 961 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 962 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 963 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 964 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 965 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 966 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 967 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 968 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 969 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 970 +#define _GUARD_THIRD_NULL_r03 971 +#define _GUARD_THIRD_NULL_r13 972 +#define _GUARD_THIRD_NULL_r23 973 +#define _GUARD_THIRD_NULL_r33 974 +#define _GUARD_TOS_ANY_DICT_r01 975 +#define _GUARD_TOS_ANY_DICT_r11 976 +#define _GUARD_TOS_ANY_DICT_r22 977 +#define _GUARD_TOS_ANY_DICT_r33 978 +#define _GUARD_TOS_ANY_SET_r01 979 +#define _GUARD_TOS_ANY_SET_r11 980 +#define _GUARD_TOS_ANY_SET_r22 981 +#define _GUARD_TOS_ANY_SET_r33 982 +#define _GUARD_TOS_DICT_r01 983 +#define _GUARD_TOS_DICT_r11 984 +#define _GUARD_TOS_DICT_r22 985 +#define _GUARD_TOS_DICT_r33 986 +#define _GUARD_TOS_FLOAT_r01 987 +#define _GUARD_TOS_FLOAT_r11 988 +#define _GUARD_TOS_FLOAT_r22 989 +#define _GUARD_TOS_FLOAT_r33 990 +#define _GUARD_TOS_FROZENDICT_r01 991 +#define _GUARD_TOS_FROZENDICT_r11 992 +#define _GUARD_TOS_FROZENDICT_r22 993 +#define _GUARD_TOS_FROZENDICT_r33 994 +#define _GUARD_TOS_FROZENSET_r01 995 +#define _GUARD_TOS_FROZENSET_r11 996 +#define _GUARD_TOS_FROZENSET_r22 997 +#define _GUARD_TOS_FROZENSET_r33 998 +#define _GUARD_TOS_INT_r01 999 +#define _GUARD_TOS_INT_r11 1000 +#define _GUARD_TOS_INT_r22 1001 +#define _GUARD_TOS_INT_r33 1002 +#define _GUARD_TOS_LIST_r01 1003 +#define _GUARD_TOS_LIST_r11 1004 +#define _GUARD_TOS_LIST_r22 1005 +#define _GUARD_TOS_LIST_r33 1006 +#define _GUARD_TOS_OVERFLOWED_r01 1007 +#define _GUARD_TOS_OVERFLOWED_r11 1008 +#define _GUARD_TOS_OVERFLOWED_r22 1009 +#define _GUARD_TOS_OVERFLOWED_r33 1010 +#define _GUARD_TOS_SET_r01 1011 +#define _GUARD_TOS_SET_r11 1012 +#define _GUARD_TOS_SET_r22 1013 +#define _GUARD_TOS_SET_r33 1014 +#define _GUARD_TOS_SLICE_r01 1015 +#define _GUARD_TOS_SLICE_r11 1016 +#define _GUARD_TOS_SLICE_r22 1017 +#define _GUARD_TOS_SLICE_r33 1018 +#define _GUARD_TOS_TUPLE_r01 1019 +#define _GUARD_TOS_TUPLE_r11 1020 +#define _GUARD_TOS_TUPLE_r22 1021 +#define _GUARD_TOS_TUPLE_r33 1022 +#define _GUARD_TOS_UNICODE_r01 1023 +#define _GUARD_TOS_UNICODE_r11 1024 +#define _GUARD_TOS_UNICODE_r22 1025 +#define _GUARD_TOS_UNICODE_r33 1026 +#define _GUARD_TYPE_VERSION_r01 1027 +#define _GUARD_TYPE_VERSION_r11 1028 +#define _GUARD_TYPE_VERSION_r22 1029 +#define _GUARD_TYPE_VERSION_r33 1030 +#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1031 +#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1032 +#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1033 +#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1034 +#define _HANDLE_PENDING_AND_DEOPT_r00 1035 +#define _HANDLE_PENDING_AND_DEOPT_r10 1036 +#define _HANDLE_PENDING_AND_DEOPT_r20 1037 +#define _HANDLE_PENDING_AND_DEOPT_r30 1038 +#define _IMPORT_FROM_r12 1039 +#define _IMPORT_NAME_r21 1040 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1041 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1042 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1043 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1044 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1045 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1046 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1047 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1048 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1049 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1050 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1051 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1052 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1053 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1054 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1055 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1056 +#define _INSERT_NULL_r10 1057 +#define _INSTRUMENTED_FOR_ITER_r23 1058 +#define _INSTRUMENTED_INSTRUCTION_r00 1059 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1060 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1061 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1062 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1063 +#define _INSTRUMENTED_LINE_r00 1064 +#define _INSTRUMENTED_NOT_TAKEN_r00 1065 +#define _INSTRUMENTED_NOT_TAKEN_r11 1066 +#define _INSTRUMENTED_NOT_TAKEN_r22 1067 +#define _INSTRUMENTED_NOT_TAKEN_r33 1068 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1069 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1070 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1071 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1072 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1073 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1074 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1075 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1076 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1077 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1078 +#define _IS_NONE_r11 1079 +#define _IS_OP_r03 1080 +#define _IS_OP_r13 1081 +#define _IS_OP_r23 1082 +#define _ITER_CHECK_LIST_r02 1083 +#define _ITER_CHECK_LIST_r12 1084 +#define _ITER_CHECK_LIST_r22 1085 +#define _ITER_CHECK_LIST_r33 1086 +#define _ITER_CHECK_RANGE_r02 1087 +#define _ITER_CHECK_RANGE_r12 1088 +#define _ITER_CHECK_RANGE_r22 1089 +#define _ITER_CHECK_RANGE_r33 1090 +#define _ITER_CHECK_TUPLE_r02 1091 +#define _ITER_CHECK_TUPLE_r12 1092 +#define _ITER_CHECK_TUPLE_r22 1093 +#define _ITER_CHECK_TUPLE_r33 1094 +#define _ITER_JUMP_LIST_r02 1095 +#define _ITER_JUMP_LIST_r12 1096 +#define _ITER_JUMP_LIST_r22 1097 +#define _ITER_JUMP_LIST_r33 1098 +#define _ITER_JUMP_RANGE_r02 1099 +#define _ITER_JUMP_RANGE_r12 1100 +#define _ITER_JUMP_RANGE_r22 1101 +#define _ITER_JUMP_RANGE_r33 1102 +#define _ITER_JUMP_TUPLE_r02 1103 +#define _ITER_JUMP_TUPLE_r12 1104 +#define _ITER_JUMP_TUPLE_r22 1105 +#define _ITER_JUMP_TUPLE_r33 1106 +#define _ITER_NEXT_LIST_r23 1107 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1108 +#define _ITER_NEXT_RANGE_r03 1109 +#define _ITER_NEXT_RANGE_r13 1110 +#define _ITER_NEXT_RANGE_r23 1111 +#define _ITER_NEXT_TUPLE_r03 1112 +#define _ITER_NEXT_TUPLE_r13 1113 +#define _ITER_NEXT_TUPLE_r23 1114 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1115 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1116 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1117 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1118 +#define _JUMP_TO_TOP_r00 1119 +#define _LIST_APPEND_r10 1120 +#define _LIST_EXTEND_r10 1121 +#define _LOAD_ATTR_r10 1122 +#define _LOAD_ATTR_CLASS_r11 1123 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1124 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1125 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1126 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1127 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1128 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1129 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1130 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1131 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1132 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1133 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1134 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1135 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1136 +#define _LOAD_ATTR_MODULE_r12 1137 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1138 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1139 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1140 +#define _LOAD_ATTR_SLOT_r02 1141 +#define _LOAD_ATTR_SLOT_r12 1142 +#define _LOAD_ATTR_SLOT_r23 1143 +#define _LOAD_ATTR_WITH_HINT_r12 1144 +#define _LOAD_BUILD_CLASS_r01 1145 +#define _LOAD_BYTECODE_r00 1146 +#define _LOAD_COMMON_CONSTANT_r01 1147 +#define _LOAD_COMMON_CONSTANT_r12 1148 +#define _LOAD_COMMON_CONSTANT_r23 1149 +#define _LOAD_CONST_r01 1150 +#define _LOAD_CONST_r12 1151 +#define _LOAD_CONST_r23 1152 +#define _LOAD_CONST_INLINE_r01 1153 +#define _LOAD_CONST_INLINE_r12 1154 +#define _LOAD_CONST_INLINE_r23 1155 +#define _LOAD_CONST_INLINE_BORROW_r01 1156 +#define _LOAD_CONST_INLINE_BORROW_r12 1157 +#define _LOAD_CONST_INLINE_BORROW_r23 1158 +#define _LOAD_CONST_UNDER_INLINE_r02 1159 +#define _LOAD_CONST_UNDER_INLINE_r12 1160 +#define _LOAD_CONST_UNDER_INLINE_r23 1161 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1162 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1163 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1164 +#define _LOAD_DEREF_r01 1165 +#define _LOAD_FAST_r01 1166 +#define _LOAD_FAST_r12 1167 +#define _LOAD_FAST_r23 1168 +#define _LOAD_FAST_0_r01 1169 +#define _LOAD_FAST_0_r12 1170 +#define _LOAD_FAST_0_r23 1171 +#define _LOAD_FAST_1_r01 1172 +#define _LOAD_FAST_1_r12 1173 +#define _LOAD_FAST_1_r23 1174 +#define _LOAD_FAST_2_r01 1175 +#define _LOAD_FAST_2_r12 1176 +#define _LOAD_FAST_2_r23 1177 +#define _LOAD_FAST_3_r01 1178 +#define _LOAD_FAST_3_r12 1179 +#define _LOAD_FAST_3_r23 1180 +#define _LOAD_FAST_4_r01 1181 +#define _LOAD_FAST_4_r12 1182 +#define _LOAD_FAST_4_r23 1183 +#define _LOAD_FAST_5_r01 1184 +#define _LOAD_FAST_5_r12 1185 +#define _LOAD_FAST_5_r23 1186 +#define _LOAD_FAST_6_r01 1187 +#define _LOAD_FAST_6_r12 1188 +#define _LOAD_FAST_6_r23 1189 +#define _LOAD_FAST_7_r01 1190 +#define _LOAD_FAST_7_r12 1191 +#define _LOAD_FAST_7_r23 1192 +#define _LOAD_FAST_AND_CLEAR_r01 1193 +#define _LOAD_FAST_AND_CLEAR_r12 1194 +#define _LOAD_FAST_AND_CLEAR_r23 1195 +#define _LOAD_FAST_BORROW_r01 1196 +#define _LOAD_FAST_BORROW_r12 1197 +#define _LOAD_FAST_BORROW_r23 1198 +#define _LOAD_FAST_BORROW_0_r01 1199 +#define _LOAD_FAST_BORROW_0_r12 1200 +#define _LOAD_FAST_BORROW_0_r23 1201 +#define _LOAD_FAST_BORROW_1_r01 1202 +#define _LOAD_FAST_BORROW_1_r12 1203 +#define _LOAD_FAST_BORROW_1_r23 1204 +#define _LOAD_FAST_BORROW_2_r01 1205 +#define _LOAD_FAST_BORROW_2_r12 1206 +#define _LOAD_FAST_BORROW_2_r23 1207 +#define _LOAD_FAST_BORROW_3_r01 1208 +#define _LOAD_FAST_BORROW_3_r12 1209 +#define _LOAD_FAST_BORROW_3_r23 1210 +#define _LOAD_FAST_BORROW_4_r01 1211 +#define _LOAD_FAST_BORROW_4_r12 1212 +#define _LOAD_FAST_BORROW_4_r23 1213 +#define _LOAD_FAST_BORROW_5_r01 1214 +#define _LOAD_FAST_BORROW_5_r12 1215 +#define _LOAD_FAST_BORROW_5_r23 1216 +#define _LOAD_FAST_BORROW_6_r01 1217 +#define _LOAD_FAST_BORROW_6_r12 1218 +#define _LOAD_FAST_BORROW_6_r23 1219 +#define _LOAD_FAST_BORROW_7_r01 1220 +#define _LOAD_FAST_BORROW_7_r12 1221 +#define _LOAD_FAST_BORROW_7_r23 1222 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1223 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1224 +#define _LOAD_FAST_CHECK_r01 1225 +#define _LOAD_FAST_CHECK_r12 1226 +#define _LOAD_FAST_CHECK_r23 1227 +#define _LOAD_FAST_LOAD_FAST_r02 1228 +#define _LOAD_FAST_LOAD_FAST_r13 1229 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1230 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1231 +#define _LOAD_GLOBAL_r00 1232 +#define _LOAD_GLOBAL_BUILTINS_r01 1233 +#define _LOAD_GLOBAL_MODULE_r01 1234 +#define _LOAD_LOCALS_r01 1235 +#define _LOAD_LOCALS_r12 1236 +#define _LOAD_LOCALS_r23 1237 +#define _LOAD_NAME_r01 1238 +#define _LOAD_SMALL_INT_r01 1239 +#define _LOAD_SMALL_INT_r12 1240 +#define _LOAD_SMALL_INT_r23 1241 +#define _LOAD_SMALL_INT_0_r01 1242 +#define _LOAD_SMALL_INT_0_r12 1243 +#define _LOAD_SMALL_INT_0_r23 1244 +#define _LOAD_SMALL_INT_1_r01 1245 +#define _LOAD_SMALL_INT_1_r12 1246 +#define _LOAD_SMALL_INT_1_r23 1247 +#define _LOAD_SMALL_INT_2_r01 1248 +#define _LOAD_SMALL_INT_2_r12 1249 +#define _LOAD_SMALL_INT_2_r23 1250 +#define _LOAD_SMALL_INT_3_r01 1251 +#define _LOAD_SMALL_INT_3_r12 1252 +#define _LOAD_SMALL_INT_3_r23 1253 +#define _LOAD_SPECIAL_r00 1254 +#define _LOAD_SUPER_ATTR_ATTR_r31 1255 +#define _LOAD_SUPER_ATTR_METHOD_r32 1256 +#define _MAKE_CALLARGS_A_TUPLE_r33 1257 +#define _MAKE_CELL_r00 1258 +#define _MAKE_FUNCTION_r11 1259 +#define _MAKE_HEAP_SAFE_r01 1260 +#define _MAKE_HEAP_SAFE_r11 1261 +#define _MAKE_HEAP_SAFE_r22 1262 +#define _MAKE_HEAP_SAFE_r33 1263 +#define _MAKE_WARM_r00 1264 +#define _MAKE_WARM_r11 1265 +#define _MAKE_WARM_r22 1266 +#define _MAKE_WARM_r33 1267 +#define _MAP_ADD_r20 1268 +#define _MATCH_CLASS_r31 1269 +#define _MATCH_KEYS_r23 1270 +#define _MATCH_MAPPING_r02 1271 +#define _MATCH_MAPPING_r12 1272 +#define _MATCH_MAPPING_r23 1273 +#define _MATCH_SEQUENCE_r02 1274 +#define _MATCH_SEQUENCE_r12 1275 +#define _MATCH_SEQUENCE_r23 1276 +#define _MAYBE_EXPAND_METHOD_r00 1277 +#define _MAYBE_EXPAND_METHOD_KW_r11 1278 +#define _MONITOR_CALL_r00 1279 +#define _MONITOR_CALL_KW_r11 1280 +#define _MONITOR_JUMP_BACKWARD_r00 1281 +#define _MONITOR_JUMP_BACKWARD_r11 1282 +#define _MONITOR_JUMP_BACKWARD_r22 1283 +#define _MONITOR_JUMP_BACKWARD_r33 1284 +#define _MONITOR_RESUME_r00 1285 +#define _NOP_r00 1286 +#define _NOP_r11 1287 +#define _NOP_r22 1288 +#define _NOP_r33 1289 +#define _POP_CALL_r20 1290 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1291 +#define _POP_CALL_ONE_r30 1292 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1293 +#define _POP_CALL_TWO_r30 1294 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1295 +#define _POP_EXCEPT_r10 1296 +#define _POP_ITER_r20 1297 +#define _POP_JUMP_IF_FALSE_r00 1298 +#define _POP_JUMP_IF_FALSE_r10 1299 +#define _POP_JUMP_IF_FALSE_r21 1300 +#define _POP_JUMP_IF_FALSE_r32 1301 +#define _POP_JUMP_IF_TRUE_r00 1302 +#define _POP_JUMP_IF_TRUE_r10 1303 +#define _POP_JUMP_IF_TRUE_r21 1304 +#define _POP_JUMP_IF_TRUE_r32 1305 +#define _POP_TOP_r10 1306 +#define _POP_TOP_FLOAT_r00 1307 +#define _POP_TOP_FLOAT_r10 1308 +#define _POP_TOP_FLOAT_r21 1309 +#define _POP_TOP_FLOAT_r32 1310 +#define _POP_TOP_INT_r00 1311 +#define _POP_TOP_INT_r10 1312 +#define _POP_TOP_INT_r21 1313 +#define _POP_TOP_INT_r32 1314 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1315 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1316 +#define _POP_TOP_NOP_r00 1317 +#define _POP_TOP_NOP_r10 1318 +#define _POP_TOP_NOP_r21 1319 +#define _POP_TOP_NOP_r32 1320 +#define _POP_TOP_UNICODE_r00 1321 +#define _POP_TOP_UNICODE_r10 1322 +#define _POP_TOP_UNICODE_r21 1323 +#define _POP_TOP_UNICODE_r32 1324 +#define _POP_TWO_r20 1325 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1326 +#define _PUSH_EXC_INFO_r02 1327 +#define _PUSH_EXC_INFO_r12 1328 +#define _PUSH_EXC_INFO_r23 1329 +#define _PUSH_FRAME_r10 1330 +#define _PUSH_NULL_r01 1331 +#define _PUSH_NULL_r12 1332 +#define _PUSH_NULL_r23 1333 +#define _PUSH_NULL_CONDITIONAL_r00 1334 +#define _PY_FRAME_EX_r31 1335 +#define _PY_FRAME_GENERAL_r01 1336 +#define _PY_FRAME_KW_r11 1337 +#define _QUICKEN_RESUME_r00 1338 +#define _QUICKEN_RESUME_r11 1339 +#define _QUICKEN_RESUME_r22 1340 +#define _QUICKEN_RESUME_r33 1341 +#define _REPLACE_WITH_TRUE_r02 1342 +#define _REPLACE_WITH_TRUE_r12 1343 +#define _REPLACE_WITH_TRUE_r23 1344 +#define _RESUME_CHECK_r00 1345 +#define _RESUME_CHECK_r11 1346 +#define _RESUME_CHECK_r22 1347 +#define _RESUME_CHECK_r33 1348 +#define _RETURN_GENERATOR_r01 1349 +#define _RETURN_VALUE_r11 1350 +#define _SAVE_RETURN_OFFSET_r00 1351 +#define _SAVE_RETURN_OFFSET_r11 1352 +#define _SAVE_RETURN_OFFSET_r22 1353 +#define _SAVE_RETURN_OFFSET_r33 1354 +#define _SEND_r22 1355 +#define _SEND_GEN_FRAME_r22 1356 +#define _SETUP_ANNOTATIONS_r00 1357 +#define _SET_ADD_r10 1358 +#define _SET_FUNCTION_ATTRIBUTE_r01 1359 +#define _SET_FUNCTION_ATTRIBUTE_r11 1360 +#define _SET_FUNCTION_ATTRIBUTE_r21 1361 +#define _SET_FUNCTION_ATTRIBUTE_r32 1362 +#define _SET_IP_r00 1363 +#define _SET_IP_r11 1364 +#define _SET_IP_r22 1365 +#define _SET_IP_r33 1366 +#define _SET_UPDATE_r10 1367 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1368 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1369 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1370 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1371 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1372 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1373 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1374 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1375 +#define _SPILL_OR_RELOAD_r01 1376 +#define _SPILL_OR_RELOAD_r02 1377 +#define _SPILL_OR_RELOAD_r03 1378 +#define _SPILL_OR_RELOAD_r10 1379 +#define _SPILL_OR_RELOAD_r12 1380 +#define _SPILL_OR_RELOAD_r13 1381 +#define _SPILL_OR_RELOAD_r20 1382 +#define _SPILL_OR_RELOAD_r21 1383 +#define _SPILL_OR_RELOAD_r23 1384 +#define _SPILL_OR_RELOAD_r30 1385 +#define _SPILL_OR_RELOAD_r31 1386 +#define _SPILL_OR_RELOAD_r32 1387 +#define _START_EXECUTOR_r00 1388 +#define _STORE_ATTR_r20 1389 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1390 +#define _STORE_ATTR_SLOT_r21 1391 +#define _STORE_ATTR_WITH_HINT_r21 1392 +#define _STORE_DEREF_r10 1393 +#define _STORE_FAST_LOAD_FAST_r11 1394 +#define _STORE_FAST_STORE_FAST_r20 1395 +#define _STORE_GLOBAL_r10 1396 +#define _STORE_NAME_r10 1397 +#define _STORE_SLICE_r30 1398 +#define _STORE_SUBSCR_r30 1399 +#define _STORE_SUBSCR_DICT_r31 1400 +#define _STORE_SUBSCR_LIST_INT_r32 1401 +#define _SWAP_r11 1402 +#define _SWAP_2_r02 1403 +#define _SWAP_2_r12 1404 +#define _SWAP_2_r22 1405 +#define _SWAP_2_r33 1406 +#define _SWAP_3_r03 1407 +#define _SWAP_3_r13 1408 +#define _SWAP_3_r23 1409 +#define _SWAP_3_r33 1410 +#define _SWAP_FAST_r01 1411 +#define _SWAP_FAST_r11 1412 +#define _SWAP_FAST_r22 1413 +#define _SWAP_FAST_r33 1414 +#define _SWAP_FAST_0_r01 1415 +#define _SWAP_FAST_0_r11 1416 +#define _SWAP_FAST_0_r22 1417 +#define _SWAP_FAST_0_r33 1418 +#define _SWAP_FAST_1_r01 1419 +#define _SWAP_FAST_1_r11 1420 +#define _SWAP_FAST_1_r22 1421 +#define _SWAP_FAST_1_r33 1422 +#define _SWAP_FAST_2_r01 1423 +#define _SWAP_FAST_2_r11 1424 +#define _SWAP_FAST_2_r22 1425 +#define _SWAP_FAST_2_r33 1426 +#define _SWAP_FAST_3_r01 1427 +#define _SWAP_FAST_3_r11 1428 +#define _SWAP_FAST_3_r22 1429 +#define _SWAP_FAST_3_r33 1430 +#define _SWAP_FAST_4_r01 1431 +#define _SWAP_FAST_4_r11 1432 +#define _SWAP_FAST_4_r22 1433 +#define _SWAP_FAST_4_r33 1434 +#define _SWAP_FAST_5_r01 1435 +#define _SWAP_FAST_5_r11 1436 +#define _SWAP_FAST_5_r22 1437 +#define _SWAP_FAST_5_r33 1438 +#define _SWAP_FAST_6_r01 1439 +#define _SWAP_FAST_6_r11 1440 +#define _SWAP_FAST_6_r22 1441 +#define _SWAP_FAST_6_r33 1442 +#define _SWAP_FAST_7_r01 1443 +#define _SWAP_FAST_7_r11 1444 +#define _SWAP_FAST_7_r22 1445 +#define _SWAP_FAST_7_r33 1446 +#define _TIER2_RESUME_CHECK_r00 1447 +#define _TIER2_RESUME_CHECK_r11 1448 +#define _TIER2_RESUME_CHECK_r22 1449 +#define _TIER2_RESUME_CHECK_r33 1450 +#define _TO_BOOL_r11 1451 +#define _TO_BOOL_BOOL_r01 1452 +#define _TO_BOOL_BOOL_r11 1453 +#define _TO_BOOL_BOOL_r22 1454 +#define _TO_BOOL_BOOL_r33 1455 +#define _TO_BOOL_INT_r02 1456 +#define _TO_BOOL_INT_r12 1457 +#define _TO_BOOL_INT_r23 1458 +#define _TO_BOOL_LIST_r02 1459 +#define _TO_BOOL_LIST_r12 1460 +#define _TO_BOOL_LIST_r23 1461 +#define _TO_BOOL_NONE_r01 1462 +#define _TO_BOOL_NONE_r11 1463 +#define _TO_BOOL_NONE_r22 1464 +#define _TO_BOOL_NONE_r33 1465 +#define _TO_BOOL_STR_r02 1466 +#define _TO_BOOL_STR_r12 1467 +#define _TO_BOOL_STR_r23 1468 +#define _TRACE_RECORD_r00 1469 +#define _UNARY_INVERT_r12 1470 +#define _UNARY_NEGATIVE_r12 1471 +#define _UNARY_NOT_r01 1472 +#define _UNARY_NOT_r11 1473 +#define _UNARY_NOT_r22 1474 +#define _UNARY_NOT_r33 1475 +#define _UNPACK_EX_r10 1476 +#define _UNPACK_SEQUENCE_r10 1477 +#define _UNPACK_SEQUENCE_LIST_r10 1478 +#define _UNPACK_SEQUENCE_TUPLE_r10 1479 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1480 +#define _WITH_EXCEPT_START_r33 1481 +#define _YIELD_VALUE_r11 1482 +#define MAX_UOP_REGS_ID 1482 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index c08f1e24fd1c12..4a8245365f805a 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -142,6 +142,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_MAKE_HEAP_SAFE] = 0, [_RETURN_VALUE] = HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG, [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, @@ -1366,6 +1367,15 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, }, }, + [_MAKE_HEAP_SAFE] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _MAKE_HEAP_SAFE_r01 }, + { 1, 1, _MAKE_HEAP_SAFE_r11 }, + { 2, 2, _MAKE_HEAP_SAFE_r22 }, + { 3, 3, _MAKE_HEAP_SAFE_r33 }, + }, + }, [_RETURN_VALUE] = { .best = { 1, 1, 1, 1 }, .entries = { @@ -3804,6 +3814,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_DELETE_SUBSCR_r20] = _DELETE_SUBSCR, [_CALL_INTRINSIC_1_r11] = _CALL_INTRINSIC_1, [_CALL_INTRINSIC_2_r21] = _CALL_INTRINSIC_2, + [_MAKE_HEAP_SAFE_r01] = _MAKE_HEAP_SAFE, + [_MAKE_HEAP_SAFE_r11] = _MAKE_HEAP_SAFE, + [_MAKE_HEAP_SAFE_r22] = _MAKE_HEAP_SAFE, + [_MAKE_HEAP_SAFE_r33] = _MAKE_HEAP_SAFE, [_RETURN_VALUE_r11] = _RETURN_VALUE, [_GET_AITER_r11] = _GET_AITER, [_GET_ANEXT_r12] = _GET_ANEXT, @@ -5199,6 +5213,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_MAKE_CELL_r00] = "_MAKE_CELL_r00", [_MAKE_FUNCTION] = "_MAKE_FUNCTION", [_MAKE_FUNCTION_r11] = "_MAKE_FUNCTION_r11", + [_MAKE_HEAP_SAFE] = "_MAKE_HEAP_SAFE", + [_MAKE_HEAP_SAFE_r01] = "_MAKE_HEAP_SAFE_r01", + [_MAKE_HEAP_SAFE_r11] = "_MAKE_HEAP_SAFE_r11", + [_MAKE_HEAP_SAFE_r22] = "_MAKE_HEAP_SAFE_r22", + [_MAKE_HEAP_SAFE_r33] = "_MAKE_HEAP_SAFE_r33", [_MAKE_WARM] = "_MAKE_WARM", [_MAKE_WARM_r00] = "_MAKE_WARM_r00", [_MAKE_WARM_r11] = "_MAKE_WARM_r11", @@ -5709,6 +5728,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _CALL_INTRINSIC_2: return 2; + case _MAKE_HEAP_SAFE: + return 0; case _RETURN_VALUE: return 1; case _GET_AITER: diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 8fa4f02afb5b45..4dd1140f7d85b7 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1304,6 +1304,50 @@ def testfunc(n): self.assertIsNotNone(ex) self.assertIn("_RETURN_GENERATOR", get_opnames(ex)) + def test_make_heap_safe_optimized_immortal(self): + def returns_immortal(): + return None + def testfunc(n): + a = 0 + for _ in range(n): + a = returns_immortal() + return a + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertIsNone(res) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertNotIn("_MAKE_HEAP_SAFE", uops) + self.assertIn("_RETURN_VALUE", uops) + + def test_make_heap_safe_optimized_yield(self): + def gen(n): + for _ in range(n): + yield 1 + def testfunc(n): + for _ in gen(n): + pass + testfunc(TIER2_THRESHOLD * 2) + gen_ex = get_first_executor(gen) + self.assertIsNotNone(gen_ex) + uops = get_opnames(gen_ex) + self.assertNotIn("_MAKE_HEAP_SAFE", uops) + self.assertIn("_YIELD_VALUE", uops) + + def test_make_heap_safe_not_optimized_for_owned(self): + def returns_owned(x): + return x + 1 + def testfunc(n): + a = 0 + for _ in range(n): + a = returns_owned(a) + return a + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertIn("_MAKE_HEAP_SAFE", uops) + self.assertIn("_RETURN_VALUE", uops) + def test_for_iter(self): def testfunc(n): t = 0 diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 79320a4bff17fb..2615b1d4dd2b5f 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -7519,6 +7519,7 @@ next_instr += 1; INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE); _PyStackRef val; + _PyStackRef value; _PyStackRef retval; _PyStackRef res; // _RETURN_VALUE_EVENT @@ -7533,11 +7534,16 @@ JUMP_TO_LABEL(error); } } + // _MAKE_HEAP_SAFE + { + value = val; + value = PyStackRef_MakeHeapSafe(value); + } // _RETURN_VALUE { - retval = val; + retval = value; assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); + _PyStackRef temp = retval; stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); @@ -7568,8 +7574,8 @@ next_instr += 1; INSTRUCTION_STATS(INSTRUMENTED_YIELD_VALUE); _PyStackRef val; - _PyStackRef retval; _PyStackRef value; + _PyStackRef retval; // _YIELD_VALUE_EVENT { val = stack_pointer[-1]; @@ -7586,9 +7592,14 @@ DISPATCH(); } } + // _MAKE_HEAP_SAFE + { + value = val; + value = PyStackRef_MakeHeapSafe(value); + } // _YIELD_VALUE { - retval = val; + retval = value; assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); frame->instr_ptr++; PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); @@ -7617,7 +7628,7 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); + value = temp; LLTRACE_RESUME_FRAME(); } stack_pointer[0] = value; @@ -10571,23 +10582,32 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(RETURN_VALUE); + _PyStackRef value; _PyStackRef retval; _PyStackRef res; - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - assert(STACK_LEVEL() == 0); - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *dying = frame; - frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); + // _MAKE_HEAP_SAFE + { + value = stack_pointer[-1]; + value = PyStackRef_MakeHeapSafe(value); + } + // _RETURN_VALUE + { + retval = value; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + _PyStackRef temp = retval; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(STACK_LEVEL() == 0); + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(frame->return_offset); + res = temp; + LLTRACE_RESUME_FRAME(); + } stack_pointer[0] = res; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -12402,39 +12422,47 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(YIELD_VALUE); - _PyStackRef retval; _PyStackRef value; - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - frame->instr_ptr++; - PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); - assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); - assert(oparg == 0 || oparg == 1); - _PyStackRef temp = retval; - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *gen_frame = frame; - frame = tstate->current_frame = frame->previous; - gen_frame->previous = NULL; - ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; - FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); - assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); - #if TIER_ONE - assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || + _PyStackRef retval; + // _MAKE_HEAP_SAFE + { + value = stack_pointer[-1]; + value = PyStackRef_MakeHeapSafe(value); + } + // _YIELD_VALUE + { + retval = value; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + frame->instr_ptr++; + PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + _PyStackRef temp = retval; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + #if TIER_ONE + assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || frame->instr_ptr->op.code == INSTRUMENTED_INSTRUCTION || _PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND || _PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER || _PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT || _PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR); - #endif - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); - LLTRACE_RESUME_FRAME(); + #endif + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + value = temp; + LLTRACE_RESUME_FRAME(); + } stack_pointer[0] = value; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 8a748fec9e4201..ac3e519398dbce 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1299,12 +1299,16 @@ dummy_func( return result; } + op(_MAKE_HEAP_SAFE, (value -- value)) { + value = PyStackRef_MakeHeapSafe(value); + } + // The stack effect here is a bit misleading. // retval is popped from the stack, but res // is pushed to a different frame, the callers' frame. - inst(RETURN_VALUE, (retval -- res)) { + op(_RETURN_VALUE, (retval -- res)) { assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); + _PyStackRef temp = retval; DEAD(retval); SAVE_STACK(); assert(STACK_LEVEL() == 0); @@ -1319,6 +1323,10 @@ dummy_func( LLTRACE_RESUME_FRAME(); } + macro(RETURN_VALUE) = + _MAKE_HEAP_SAFE + + _RETURN_VALUE; + tier1 op(_RETURN_VALUE_EVENT, (val -- val)) { int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, @@ -1328,7 +1336,8 @@ dummy_func( macro(INSTRUMENTED_RETURN_VALUE) = _RETURN_VALUE_EVENT + - RETURN_VALUE; + _MAKE_HEAP_SAFE + + _RETURN_VALUE; inst(GET_AITER, (obj -- iter)) { unaryfunc getter = NULL; @@ -1470,7 +1479,7 @@ dummy_func( _SEND_GEN_FRAME + _PUSH_FRAME; - inst(YIELD_VALUE, (retval -- value)) { + op(_YIELD_VALUE, (retval -- value)) { // NOTE: It's important that YIELD_VALUE never raises an exception! // The compiler treats any exception raised here as a failed close() // or throw() call. @@ -1502,10 +1511,14 @@ dummy_func( #endif RELOAD_STACK(); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); + value = temp; LLTRACE_RESUME_FRAME(); } + macro(YIELD_VALUE) = + _MAKE_HEAP_SAFE + + _YIELD_VALUE; + tier1 op(_YIELD_VALUE_EVENT, (val -- val)) { int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_YIELD, @@ -1521,7 +1534,8 @@ dummy_func( macro(INSTRUMENTED_YIELD_VALUE) = _YIELD_VALUE_EVENT + - YIELD_VALUE; + _MAKE_HEAP_SAFE + + _YIELD_VALUE; inst(POP_EXCEPT, (exc_value -- )) { _PyErr_StackItem *exc_info = tstate->exc_info; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 09004545267026..6271778bed4419 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -6920,6 +6920,65 @@ break; } + case _MAKE_HEAP_SAFE_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + value = stack_pointer[-1]; + value = PyStackRef_MakeHeapSafe(value); + _tos_cache0 = value; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _MAKE_HEAP_SAFE_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + _PyStackRef _stack_item_0 = _tos_cache0; + value = _stack_item_0; + value = PyStackRef_MakeHeapSafe(value); + _tos_cache0 = value; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _MAKE_HEAP_SAFE_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + value = _stack_item_1; + value = PyStackRef_MakeHeapSafe(value); + _tos_cache1 = value; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _MAKE_HEAP_SAFE_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + value = _stack_item_2; + value = PyStackRef_MakeHeapSafe(value); + _tos_cache2 = value; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _RETURN_VALUE_r11: { CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); @@ -6928,7 +6987,7 @@ _PyStackRef _stack_item_0 = _tos_cache0; retval = _stack_item_0; assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); + _PyStackRef temp = retval; _PyFrame_SetStackPointer(frame, stack_pointer); assert(STACK_LEVEL() == 0); _Py_LeaveRecursiveCallPy(tstate); @@ -7154,7 +7213,7 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); + value = temp; LLTRACE_RESUME_FRAME(); _tos_cache0 = value; _tos_cache1 = PyStackRef_ZERO_BITS; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 42098c59040f07..5d853998bf68b5 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -7518,6 +7518,7 @@ next_instr += 1; INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE); _PyStackRef val; + _PyStackRef value; _PyStackRef retval; _PyStackRef res; // _RETURN_VALUE_EVENT @@ -7532,11 +7533,16 @@ JUMP_TO_LABEL(error); } } + // _MAKE_HEAP_SAFE + { + value = val; + value = PyStackRef_MakeHeapSafe(value); + } // _RETURN_VALUE { - retval = val; + retval = value; assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); + _PyStackRef temp = retval; stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); _PyFrame_SetStackPointer(frame, stack_pointer); @@ -7567,8 +7573,8 @@ next_instr += 1; INSTRUCTION_STATS(INSTRUMENTED_YIELD_VALUE); _PyStackRef val; - _PyStackRef retval; _PyStackRef value; + _PyStackRef retval; // _YIELD_VALUE_EVENT { val = stack_pointer[-1]; @@ -7585,9 +7591,14 @@ DISPATCH(); } } + // _MAKE_HEAP_SAFE + { + value = val; + value = PyStackRef_MakeHeapSafe(value); + } // _YIELD_VALUE { - retval = val; + retval = value; assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); frame->instr_ptr++; PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); @@ -7616,7 +7627,7 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); + value = temp; LLTRACE_RESUME_FRAME(); } stack_pointer[0] = value; @@ -10568,23 +10579,32 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(RETURN_VALUE); + _PyStackRef value; _PyStackRef retval; _PyStackRef res; - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - _PyStackRef temp = PyStackRef_MakeHeapSafe(retval); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - assert(STACK_LEVEL() == 0); - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *dying = frame; - frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); + // _MAKE_HEAP_SAFE + { + value = stack_pointer[-1]; + value = PyStackRef_MakeHeapSafe(value); + } + // _RETURN_VALUE + { + retval = value; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + _PyStackRef temp = retval; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(STACK_LEVEL() == 0); + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *dying = frame; + frame = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(frame->return_offset); + res = temp; + LLTRACE_RESUME_FRAME(); + } stack_pointer[0] = res; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -12399,39 +12419,47 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(YIELD_VALUE); - _PyStackRef retval; _PyStackRef value; - retval = stack_pointer[-1]; - assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); - frame->instr_ptr++; - PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); - assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); - assert(oparg == 0 || oparg == 1); - _PyStackRef temp = retval; - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *gen_frame = frame; - frame = tstate->current_frame = frame->previous; - gen_frame->previous = NULL; - ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; - FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); - assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); - #if TIER_ONE - assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || + _PyStackRef retval; + // _MAKE_HEAP_SAFE + { + value = stack_pointer[-1]; + value = PyStackRef_MakeHeapSafe(value); + } + // _YIELD_VALUE + { + retval = value; + assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); + frame->instr_ptr++; + PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + _PyStackRef temp = retval; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + #if TIER_ONE + assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || frame->instr_ptr->op.code == INSTRUMENTED_INSTRUCTION || _PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND || _PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER || _PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT || _PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR); - #endif - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); - value = PyStackRef_MakeHeapSafe(temp); - LLTRACE_RESUME_FRAME(); + #endif + stack_pointer = _PyFrame_GetStackPointer(frame); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + value = temp; + LLTRACE_RESUME_FRAME(); + } stack_pointer[0] = value; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 2f52837f058113..2b68ba4d2cde92 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -88,6 +88,14 @@ dummy_func(void) { // BEGIN BYTECODES // + op(_MAKE_HEAP_SAFE, (value -- value)) { + // eliminate _MAKE_HEAP_SAFE when we *know* the value is immortal + if (sym_is_immortal(PyJitRef_Unwrap(value))) { + ADD_OP(_NOP, 0, 0); + } + value = PyJitRef_StripReferenceInfo(value); + } + op(_LOAD_FAST_CHECK, (-- value)) { value = GETLOCAL(oparg); // We guarantee this will error - just bail and don't optimize it. @@ -944,8 +952,7 @@ dummy_func(void) { } op(_RETURN_VALUE, (retval -- res)) { - // Mimics PyStackRef_MakeHeapSafe in the interpreter. - JitOptRef temp = PyJitRef_StripReferenceInfo(retval); + JitOptRef temp = retval; DEAD(retval); SAVE_STACK(); ctx->frame->stack_pointer = stack_pointer; @@ -983,8 +990,7 @@ dummy_func(void) { } op(_YIELD_VALUE, (retval -- value)) { - // Mimics PyStackRef_MakeHeapSafe in the interpreter. - JitOptRef temp = PyJitRef_StripReferenceInfo(retval); + JitOptRef temp = retval; DEAD(retval); SAVE_STACK(); ctx->frame->stack_pointer = stack_pointer; diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index c35c77ed442d7a..f996c1f6cc70a7 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1309,11 +1309,22 @@ break; } + case _MAKE_HEAP_SAFE: { + JitOptRef value; + value = stack_pointer[-1]; + if (sym_is_immortal(PyJitRef_Unwrap(value))) { + ADD_OP(_NOP, 0, 0); + } + value = PyJitRef_StripReferenceInfo(value); + stack_pointer[-1] = value; + break; + } + case _RETURN_VALUE: { JitOptRef retval; JitOptRef res; retval = stack_pointer[-1]; - JitOptRef temp = PyJitRef_StripReferenceInfo(retval); + JitOptRef temp = retval; CHECK_STACK_BOUNDS(-1); stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -1385,7 +1396,7 @@ JitOptRef retval; JitOptRef value; retval = stack_pointer[-1]; - JitOptRef temp = PyJitRef_StripReferenceInfo(retval); + JitOptRef temp = retval; CHECK_STACK_BOUNDS(-1); stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); From d19de375a204c74ab5f3a28ec42335bae139033d Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Thu, 12 Mar 2026 02:08:18 +0500 Subject: [PATCH 425/498] GH-145247: Use _PyTuple_FromPair in Parser and Python (#145842) Use _PyTuple_FromPair in Parser and Python --- Parser/pegen_errors.c | 5 +++-- Python/Python-tokenize.c | 3 ++- Python/_warnings.c | 3 ++- Python/bltinmodule.c | 2 +- Python/compile.c | 3 ++- Python/hamt.c | 3 ++- Python/marshal.c | 5 ++--- Python/pylifecycle.c | 3 ++- 8 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index 1c61524d60a1af..312699415efd9a 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -3,6 +3,7 @@ #include "pycore_pyerrors.h" // _PyErr_ProgramDecodedTextObject() #include "pycore_runtime.h" // _Py_ID() +#include "pycore_tuple.h" // _PyTuple_FromPair #include "lexer/state.h" #include "lexer/lexer.h" #include "pegen.h" @@ -41,7 +42,7 @@ _PyPegen_raise_tokenizer_init_error(PyObject *filename) goto error; } - tuple = PyTuple_Pack(2, errstr, tmp); + tuple = _PyTuple_FromPair(errstr, tmp); Py_DECREF(tmp); if (!tuple) { goto error; @@ -393,7 +394,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, if (!tmp) { goto error; } - value = PyTuple_Pack(2, errstr, tmp); + value = _PyTuple_FromPair(errstr, tmp); Py_DECREF(tmp); if (!value) { goto error; diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c index 152d61c686722e..c50ff1190686c2 100644 --- a/Python/Python-tokenize.c +++ b/Python/Python-tokenize.c @@ -1,6 +1,7 @@ #include "Python.h" #include "errcode.h" #include "internal/pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION +#include "internal/pycore_tuple.h" // _PyTuple_FromPair #include "../Parser/lexer/state.h" #include "../Parser/lexer/lexer.h" #include "../Parser/tokenizer/tokenizer.h" @@ -164,7 +165,7 @@ _tokenizer_error(tokenizeriterobject *it) goto exit; } - value = PyTuple_Pack(2, errstr, tmp); + value = _PyTuple_FromPair(errstr, tmp); if (!value) { result = -1; goto exit; diff --git a/Python/_warnings.c b/Python/_warnings.c index 0ea785772f03b9..6b6ac238935765 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -7,6 +7,7 @@ #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_traceback.h" // _Py_DisplaySourceLine() +#include "pycore_tuple.h" // _PyTuple_FromPair #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString() #include @@ -634,7 +635,7 @@ update_registry(PyInterpreterState *interp, PyObject *registry, PyObject *text, if (add_zero) altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero()); else - altkey = PyTuple_Pack(2, text, category); + altkey = _PyTuple_FromPair(text, category); rc = already_warned(interp, registry, altkey, 1); Py_XDECREF(altkey); diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index fc69f6372028a6..5680e8971576cd 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -3341,7 +3341,7 @@ zip_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) if (lz->strict) { return PyTuple_Pack(3, Py_TYPE(lz), lz->ittuple, Py_True); } - return PyTuple_Pack(2, Py_TYPE(lz), lz->ittuple); + return _PyTuple_FromPair((PyObject *)Py_TYPE(lz), lz->ittuple); } static PyObject * diff --git a/Python/compile.c b/Python/compile.c index 96779a0a219a55..4cf178b06ae11d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -23,6 +23,7 @@ #include "pycore_runtime.h" // _Py_ID() #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_stats.h" +#include "pycore_tuple.h" // _PyTuple_FromPair #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString() #include "cpython/code.h" @@ -1697,7 +1698,7 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags, return NULL; } /* Allocate a copy of the instruction sequence on the heap */ - res = PyTuple_Pack(2, _PyCompile_InstrSequence(c), metadata); + res = _PyTuple_FromPair((PyObject *)_PyCompile_InstrSequence(c), metadata); finally: Py_XDECREF(metadata); diff --git a/Python/hamt.c b/Python/hamt.c index 881290a0e60db8..e4719e71a5259a 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -4,6 +4,7 @@ #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _PyLong_Format() #include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_tuple.h" // _PyTuple_FromPair #include // offsetof() @@ -2542,7 +2543,7 @@ PyTypeObject _PyHamtItems_Type = { static PyObject * hamt_iter_yield_items(PyObject *key, PyObject *val) { - return PyTuple_Pack(2, key, val); + return _PyTuple_FromPair(key, val); } PyObject * diff --git a/Python/marshal.c b/Python/marshal.c index 59db6456552c35..cc6a787ba75022 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -14,6 +14,7 @@ #include "pycore_object.h" // _PyObject_IsUniquelyReferenced #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_setobject.h" // _PySet_NextEntryRef() +#include "pycore_tuple.h" // _PyTuple_FromPairSteal #include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal() #include "marshal.h" // Py_MARSHAL_VERSION @@ -629,9 +630,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) Py_DECREF(value); break; } - PyObject *pair = PyTuple_Pack(2, dump, value); - Py_DECREF(dump); - Py_DECREF(value); + PyObject *pair = _PyTuple_FromPairSteal(dump, value); if (pair == NULL) { p->error = WFERR_NOMEMORY; break; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 21d1e036d31540..2b8e9a02cb6184 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -30,6 +30,7 @@ #include "pycore_stats.h" // _PyStats_InterpInit() #include "pycore_sysmodule.h" // _PySys_ClearAttrString() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() +#include "pycore_tuple.h" // _PyTuple_FromPair #include "pycore_typeobject.h" // _PyTypes_InitTypes() #include "pycore_typevarobject.h" // _Py_clear_generic_types() #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() @@ -1613,7 +1614,7 @@ finalize_remove_modules(PyObject *modules, int verbose) if (weaklist != NULL) { \ PyObject *wr = PyWeakref_NewRef(mod, NULL); \ if (wr) { \ - PyObject *tup = PyTuple_Pack(2, name, wr); \ + PyObject *tup = _PyTuple_FromPair(name, wr); \ if (!tup || PyList_Append(weaklist, tup) < 0) { \ PyErr_FormatUnraisable("Exception ignored while removing modules"); \ } \ From 0dce4c6eab9dcfcb44bb2739dc60c8ac5fa1ebad Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Thu, 12 Mar 2026 07:48:43 +0100 Subject: [PATCH 426/498] gh-145254: Add thread safety annotation in docs (#145255) --- Doc/conf.py | 1 + Doc/data/threadsafety.dat | 19 ++++++ Doc/library/threadsafety.rst | 82 +++++++++++++++++++++++ Doc/tools/extensions/c_annotations.py | 93 +++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 Doc/data/threadsafety.dat diff --git a/Doc/conf.py b/Doc/conf.py index 6f66ed68c52e83..4ac6f6192a0806 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -569,6 +569,7 @@ # Relative filename of the data files refcount_file = 'data/refcounts.dat' stable_abi_file = 'data/stable_abi.dat' +threadsafety_file = 'data/threadsafety.dat' # Options for sphinxext-opengraph # ------------------------------- diff --git a/Doc/data/threadsafety.dat b/Doc/data/threadsafety.dat new file mode 100644 index 00000000000000..f063ca1360d5fb --- /dev/null +++ b/Doc/data/threadsafety.dat @@ -0,0 +1,19 @@ +# Thread safety annotations for C API functions. +# +# Each line has the form: +# function_name : level +# +# Where level is one of: +# incompatible -- not safe even with external locking +# compatible -- safe if the caller serializes all access with external locks +# distinct -- safe on distinct objects without external synchronization +# shared -- safe for concurrent use on the same object +# atomic -- atomic +# +# Lines beginning with '#' are ignored. +# The function name must match the C domain identifier used in the documentation. + +# Synchronization primitives (Doc/c-api/synchronization.rst) +PyMutex_Lock:shared: +PyMutex_Unlock:shared: +PyMutex_IsLocked:atomic: diff --git a/Doc/library/threadsafety.rst b/Doc/library/threadsafety.rst index 5b5949d4eff437..7ab5921c7ec298 100644 --- a/Doc/library/threadsafety.rst +++ b/Doc/library/threadsafety.rst @@ -13,6 +13,88 @@ For general guidance on writing thread-safe code in free-threaded Python, see :ref:`freethreading-python-howto`. +.. _threadsafety-levels: + +Thread safety levels +==================== + +The C API documentation uses the following levels to describe the thread +safety guarantees of each function. The levels are listed from least to +most safe. + +.. _threadsafety-level-incompatible: + +Incompatible +------------ + +A function or operation that cannot be made safe for concurrent use even +with external synchronization. Incompatible code typically accesses +global state in an unsynchronized way and must only be called from a single +thread throughout the program's lifetime. + +Example: a function that modifies process-wide state such as signal handlers +or environment variables, where concurrent calls from any threads, even with +external locking, can conflict with the runtime or other libraries. + +.. _threadsafety-level-compatible: + +Compatible +---------- + +A function or operation that is safe to call from multiple threads +*provided* the caller supplies appropriate external synchronization, for +example by holding a :term:`lock` for the duration of each call. Without +such synchronization, concurrent calls may produce :term:`race conditions +` or :term:`data races `. + +Example: a function that reads from or writes to an object whose internal +state is not protected by a lock. Callers must ensure that no two threads +access the same object at the same time. + +.. _threadsafety-level-distinct: + +Safe on distinct objects +------------------------ + +A function or operation that is safe to call from multiple threads without +external synchronization, as long as each thread operates on a **different** +object. Two threads may call the function at the same time, but they must +not pass the same object (or objects that share underlying state) as +arguments. + +Example: a function that modifies fields of a struct using non-atomic +writes. Two threads can each call the function on their own struct +instance safely, but concurrent calls on the *same* instance require +external synchronization. + +.. _threadsafety-level-shared: + +Safe on shared objects +---------------------- + +A function or operation that is safe for concurrent use on the **same** +object. The implementation uses internal synchronization (such as +:term:`per-object locks ` or +:ref:`critical sections `) to protect shared +mutable state, so callers do not need to supply their own locking. + +Example: :c:func:`PyList_GetItemRef` can be called from multiple threads on the +same :c:type:`PyListObject` - it uses internal synchronization to serialize +access. + +.. _threadsafety-level-atomic: + +Atomic +------ + +A function or operation that appears :term:`atomic ` with +respect to other threads - it executes instantaneously from the perspective +of other threads. This is the strongest form of thread safety. + +Example: :c:func:`PyMutex_IsLocked` performs an atomic read of the mutex +state and can be called from any thread at any time. + + .. _thread-safety-list: Thread safety for list objects diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py index e04a5f144c449b..58f597c2eb2d0c 100644 --- a/Doc/tools/extensions/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -3,10 +3,12 @@ * Reference count annotations for C API functions. * Stable ABI annotations * Limited API annotations +* Thread safety annotations for C API functions. Configuration: * Set ``refcount_file`` to the path to the reference count data file. * Set ``stable_abi_file`` to the path to stable ABI list. +* Set ``threadsafety_file`` to the path to the thread safety data file. """ from __future__ import annotations @@ -48,6 +50,15 @@ class RefCountEntry: result_refs: int | None = None +@dataclasses.dataclass(frozen=True, slots=True) +class ThreadSafetyEntry: + # Name of the function. + name: str + # Thread safety level. + # One of: 'incompatible', 'compatible', 'safe'. + level: str + + @dataclasses.dataclass(frozen=True, slots=True) class StableABIEntry: # Role of the object. @@ -113,10 +124,42 @@ def read_stable_abi_data(stable_abi_file: Path) -> dict[str, StableABIEntry]: return stable_abi_data +_VALID_THREADSAFETY_LEVELS = frozenset({ + "incompatible", + "compatible", + "distinct", + "shared", + "atomic", +}) + + +def read_threadsafety_data( + threadsafety_filename: Path, +) -> dict[str, ThreadSafetyEntry]: + threadsafety_data = {} + for line in threadsafety_filename.read_text(encoding="utf8").splitlines(): + line = line.strip() + if not line or line.startswith("#"): + continue + # Each line is of the form: function_name : level : [comment] + parts = line.split(":", 2) + if len(parts) < 2: + raise ValueError(f"Wrong field count in {line!r}") + name, level = parts[0].strip(), parts[1].strip() + if level not in _VALID_THREADSAFETY_LEVELS: + raise ValueError( + f"Unknown thread safety level {level!r} for {name!r}. " + f"Valid levels: {sorted(_VALID_THREADSAFETY_LEVELS)}" + ) + threadsafety_data[name] = ThreadSafetyEntry(name=name, level=level) + return threadsafety_data + + def add_annotations(app: Sphinx, doctree: nodes.document) -> None: state = app.env.domaindata["c_annotations"] refcount_data = state["refcount_data"] stable_abi_data = state["stable_abi_data"] + threadsafety_data = state["threadsafety_data"] for node in doctree.findall(addnodes.desc_content): par = node.parent if par["domain"] != "c": @@ -126,6 +169,12 @@ def add_annotations(app: Sphinx, doctree: nodes.document) -> None: name = par[0]["ids"][0].removeprefix("c.") objtype = par["objtype"] + # Thread safety annotation — inserted first so it appears last (bottom-most) + # among all annotations. + if entry := threadsafety_data.get(name): + annotation = _threadsafety_annotation(entry.level) + node.insert(0, annotation) + # Stable ABI annotation. if record := stable_abi_data.get(name): if ROLE_TO_OBJECT_TYPE[record.role] != objtype: @@ -256,6 +305,46 @@ def _unstable_api_annotation() -> nodes.admonition: ) +def _threadsafety_annotation(level: str) -> nodes.emphasis: + match level: + case "incompatible": + display = sphinx_gettext("Not safe to call from multiple threads.") + reftarget = "threadsafety-level-incompatible" + case "compatible": + display = sphinx_gettext( + "Safe to call from multiple threads" + " with external synchronization only." + ) + reftarget = "threadsafety-level-compatible" + case "distinct": + display = sphinx_gettext( + "Safe to call without external synchronization" + " on distinct objects." + ) + reftarget = "threadsafety-level-distinct" + case "shared": + display = sphinx_gettext( + "Safe for concurrent use on the same object." + ) + reftarget = "threadsafety-level-shared" + case "atomic": + display = sphinx_gettext("Atomic.") + reftarget = "threadsafety-level-atomic" + case _: + raise AssertionError(f"Unknown thread safety level {level!r}") + ref_node = addnodes.pending_xref( + display, + nodes.Text(display), + refdomain="std", + reftarget=reftarget, + reftype="ref", + refexplicit="True", + ) + prefix = sphinx_gettext("Thread safety:") + " " + classes = ["threadsafety", f"threadsafety-{level}"] + return nodes.emphasis("", prefix, ref_node, classes=classes) + + def _return_value_annotation(result_refs: int | None) -> nodes.emphasis: classes = ["refcount"] if result_refs is None: @@ -342,11 +431,15 @@ def init_annotations(app: Sphinx) -> None: state["stable_abi_data"] = read_stable_abi_data( Path(app.srcdir, app.config.stable_abi_file) ) + state["threadsafety_data"] = read_threadsafety_data( + Path(app.srcdir, app.config.threadsafety_file) + ) def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value("refcount_file", "", "env", types={str}) app.add_config_value("stable_abi_file", "", "env", types={str}) + app.add_config_value("threadsafety_file", "", "env", types={str}) app.add_directive("limited-api-list", LimitedAPIList) app.add_directive("corresponding-type-slot", CorrespondingTypeSlot) app.connect("builder-inited", init_annotations) From 72456309e9673019622d9d20d93c707f96d2f8e9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 12 Mar 2026 09:44:11 +0200 Subject: [PATCH 427/498] gh-143715: Deprecate incomplete initialization of struct.Struct() (GH-145580) * Struct.__new__() will require a mandatory argument (format) * Calls of __init__() method with a different format argument on initialized Struct are deprecated Co-authored-by: Sergey B Kirpichev --- Doc/deprecations/pending-removal-in-3.20.rst | 7 + Doc/whatsnew/3.15.rst | 9 + Lib/test/test_struct.py | 163 +++++++++++++- ...-01-10-16-23-21.gh-issue-143715.HZrfSA.rst | 3 + Modules/_struct.c | 207 +++++++++++++++--- Modules/clinic/_struct.c.h | 62 +++++- 6 files changed, 409 insertions(+), 42 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-10-16-23-21.gh-issue-143715.HZrfSA.rst diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst index 8372432a34daa5..176e8f3f9f601c 100644 --- a/Doc/deprecations/pending-removal-in-3.20.rst +++ b/Doc/deprecations/pending-removal-in-3.20.rst @@ -1,6 +1,13 @@ Pending removal in Python 3.20 ------------------------------ +* Calling the ``__new__()`` method of :class:`struct.Struct` without the + *format* argument is deprecated and will be removed in Python 3.20. Calling + :meth:`~object.__init__` method on initialized :class:`~struct.Struct` + objects is deprecated and will be removed in Python 3.20. + + (Contributed by Sergey B Kirpichev and Serhiy Storchaka in :gh:`143715`.) + * The ``__version__``, ``version`` and ``VERSION`` attributes have been deprecated in these standard library modules and will be removed in Python 3.20. Use :py:data:`sys.version_info` instead. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index e749ef2a455ea2..c979118abd0a07 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1560,6 +1560,15 @@ New deprecations (Contributed by Bénédikt Tran in :gh:`134978`.) +* :mod:`struct`: + + * Calling the ``Struct.__new__()`` without required argument now is + deprecated and will be removed in Python 3.20. Calling + :meth:`~object.__init__` method on initialized :class:`~struct.Struct` + objects is deprecated and will be removed in Python 3.20. + + (Contributed by Sergey B Kirpichev and Serhiy Storchaka in :gh:`143715`.) + * ``__version__`` * The ``__version__``, ``version`` and ``VERSION`` attributes have been diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 55e2ce590a2577..e3e02097b1f550 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -591,27 +591,36 @@ def test_Struct_reinitialization(self): # Struct instance. This test can be used to detect the leak # when running with regrtest -L. s = struct.Struct('>h') - s.__init__('>hh') + msg = 'Re-initialization .* will not work' + with self.assertWarnsRegex(FutureWarning, msg): + s.__init__('>hh') self.assertEqual(s.format, '>hh') packed = b'\x00\x01\x00\x02' self.assertEqual(s.pack(1, 2), packed) self.assertEqual(s.unpack(packed), (1, 2)) - with self.assertRaises(UnicodeEncodeError): - s.__init__('\udc00') + s.__init__('>hh') # same format self.assertEqual(s.format, '>hh') self.assertEqual(s.pack(1, 2), packed) self.assertEqual(s.unpack(packed), (1, 2)) - with self.assertRaises(struct.error): - s.__init__('$') + with self.assertWarnsRegex(FutureWarning, msg): + with self.assertRaises(UnicodeEncodeError): + s.__init__('\udc00') + self.assertEqual(s.format, '>hh') + self.assertEqual(s.pack(1, 2), packed) + self.assertEqual(s.unpack(packed), (1, 2)) + + with self.assertWarnsRegex(FutureWarning, msg): + with self.assertRaises(struct.error): + s.__init__('$') self.assertEqual(s.format, '>hh') self.assertEqual(s.pack(1, 2), packed) self.assertEqual(s.unpack(packed), (1, 2)) def check_sizeof(self, format_str, number_of_codes): # The size of 'PyStructObject' - totalsize = support.calcobjsize('2n3P') + totalsize = support.calcobjsize('2n3P?0P') # The size taken up by the 'formatcode' dynamic array totalsize += struct.calcsize('P3n0P') * (number_of_codes + 1) support.check_sizeof(self, struct.Struct(format_str), totalsize) @@ -809,14 +818,152 @@ def test_error_propagation(fmt_str): test_error_propagation('N') test_error_propagation('n') - def test_struct_subclass_instantiation(self): + def test_custom_struct_init(self): # Regression test for https://github.com/python/cpython/issues/112358 class MyStruct(struct.Struct): - def __init__(self): + def __init__(self, *args, **kwargs): super().__init__('>h') + my_struct = MyStruct('>h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + my_struct = MyStruct(format='>h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + + warnmsg = r"Different format arguments for __new__\(\) and __init__\(\) methods of Struct" + with self.assertWarnsRegex(FutureWarning, warnmsg): + my_struct = MyStruct('h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + + warnmsg = r"Struct\(\) takes at most 1 argument \(2 given\)" + with self.assertWarnsRegex(DeprecationWarning, warnmsg): + my_struct = MyStruct('>h', 42) + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg): + my_struct = MyStruct('>h', arg=42) + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg): + my_struct = MyStruct('>h', format=42) + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg): + my_struct = MyStruct(format='>h', arg=42) + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + + warnmsg = r"Invalid 'format' argument for Struct\.__new__\(\): " + with self.assertWarnsRegex(DeprecationWarning, warnmsg + '.*must be'): + my_struct = MyStruct(42) + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg + '.*must be'): + my_struct = MyStruct(format=42) + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg + 'bad char'): + my_struct = MyStruct('$') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg + 'bad char'): + my_struct = MyStruct(format='$') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg + ".*can't encode"): + my_struct = MyStruct('\udc00') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertWarnsRegex(DeprecationWarning, warnmsg + ".*can't encode"): + my_struct = MyStruct(format='\udc00') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + + def test_custom_struct_new(self): + # New way, no warnings: + class MyStruct(struct.Struct): + def __new__(cls, *args, **kwargs): + return super().__new__(cls, '>h') + + for format in '>h', 'h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + my_struct = MyStruct(format='h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') my_struct = MyStruct() + self.assertEqual(my_struct.format, '>h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + my_struct = MyStruct('h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + + def test_custom_struct_new_and_init(self): + # New way, no warnings: + class MyStruct(struct.Struct): + def __new__(cls, newargs, initargs): + return super().__new__(cls, *newargs) + def __init__(self, newargs, initargs): + if initargs is not None: + super().__init__(*initargs) + + my_struct = MyStruct(('>h',), ('>h',)) + self.assertEqual(my_struct.format, '>h') self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertRaises(TypeError): + MyStruct((), ()) + with self.assertRaises(TypeError): + MyStruct(('>h',), ()) + with self.assertRaises(TypeError): + MyStruct((), ('>h',)) + with self.assertRaises(TypeError): + MyStruct((42,), ('>h',)) + with self.assertWarns(FutureWarning): + with self.assertRaises(TypeError): + MyStruct(('>h',), (42,)) + with self.assertRaises(struct.error): + MyStruct(('$',), ('>h',)) + with self.assertWarns(FutureWarning): + with self.assertRaises(struct.error): + MyStruct(('>h',), ('$',)) + with self.assertRaises(UnicodeEncodeError): + MyStruct(('\udc00',), ('>h',)) + with self.assertWarns(FutureWarning): + with self.assertRaises(UnicodeEncodeError): + MyStruct(('>h',), ('\udc00',)) + with self.assertWarns(FutureWarning): + my_struct = MyStruct(('>h',), ('h') + self.assertEqual(my_struct.format, '>h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + my_struct = MyStruct(format='>h') + self.assertEqual(my_struct.format, '>h') + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + with self.assertRaises(TypeError): + MyStruct() + with self.assertRaises(TypeError): + MyStruct(42) + with self.assertRaises(struct.error): + MyStruct('$') + with self.assertRaises(UnicodeEncodeError): + MyStruct('\udc00') + with self.assertRaises(TypeError): + MyStruct('>h', 42) + with self.assertRaises(TypeError): + MyStruct('>h', arg=42) + with self.assertRaises(TypeError): + MyStruct(arg=42) + with self.assertRaises(TypeError): + MyStruct('>h', format='>h') def test_repr(self): s = struct.Struct('=i2H') diff --git a/Misc/NEWS.d/next/Library/2026-01-10-16-23-21.gh-issue-143715.HZrfSA.rst b/Misc/NEWS.d/next/Library/2026-01-10-16-23-21.gh-issue-143715.HZrfSA.rst new file mode 100644 index 00000000000000..90aae6bee835f0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-10-16-23-21.gh-issue-143715.HZrfSA.rst @@ -0,0 +1,3 @@ +Calling the ``Struct.__new__()`` without required argument now is deprecated. +Calling :meth:`~object.__init__` method on initialized :class:`~struct.Struct` +objects is deprecated. diff --git a/Modules/_struct.c b/Modules/_struct.c index f8574322b40c8d..7eddc9bdc38a89 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -70,6 +70,7 @@ typedef struct { formatcode *s_codes; PyObject *s_format; PyObject *weakreflist; /* List of weak references */ + bool init_called; } PyStructObject; #define PyStructObject_CAST(op) ((PyStructObject *)(op)) @@ -1773,24 +1774,153 @@ prepare_s(PyStructObject *self, PyObject *format) return -1; } +/* This should be moved to Struct_impl() when Struct___init__() and + * s_new() will be removed (see gh-143715 and gh-94532). */ +static int +set_format(PyStructObject *self, PyObject *format) +{ + if (PyUnicode_Check(format)) { + format = PyUnicode_AsASCIIString(format); + if (format == NULL) + return -1; + } + else if (PyBytes_Check(format)) { + Py_INCREF(format); + } + else { + PyErr_Format(PyExc_TypeError, + "Struct() argument 1 must be a str or bytes object, " + "not %T", format); + return -1; + } + if (prepare_s(self, format)) { + Py_DECREF(format); + return -1; + } + Py_DECREF(format); + return 0; +} + +/*[clinic input] +@classmethod +Struct.__new__ + + format: object + +Create a compiled struct object. + +Return a new Struct object which writes and reads binary data according +to the format string. See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +Struct_impl(PyTypeObject *type, PyObject *format) +/*[clinic end generated code: output=49468b044e334308 input=8381a9796f20f24e]*/ +{ + PyStructObject *self = (PyStructObject *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->s_format = Py_NewRef(Py_None); + self->s_codes = NULL; + self->s_size = -1; + self->s_len = -1; + self->init_called = false; + if (set_format(self, format) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *)self; +} + + +static int +s_init(PyObject *self, PyObject *args, PyObject *kwargs); + static PyObject * s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *self; + if (type->tp_new != s_new) { + /* Struct.__new__() was called explicitly in a subclass' __new__(). */ + return Struct(type, args, kwds); + } - assert(type != NULL); - allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); - assert(alloc_func != NULL); + PyObject *format = NULL; + if (PyTuple_GET_SIZE(args) == 1 && (kwds == NULL || PyDict_GET_SIZE(kwds) == 0)) { + format = Py_NewRef(PyTuple_GET_ITEM(args, 0)); + } + else if (PyTuple_GET_SIZE(args) == 0 && kwds != NULL && PyDict_GET_SIZE(kwds) == 1) { + if (PyDict_GetItemStringRef(kwds, "format", &format) < 0) { + return NULL; + } + } + if (format == NULL && type->tp_init != s_init) { + Py_ssize_t nargs = PyTuple_GET_SIZE(args) + (kwds ? PyDict_GET_SIZE(kwds) : 0); + if (nargs > 1) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Struct() takes at most 1 argument (%zd given)", nargs)) + { + Py_XDECREF(format); + return NULL; + } + } + else { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Struct() missing required argument 'format' (pos 1)", 1)) + { + Py_XDECREF(format); + return NULL; + } + } + } - self = alloc_func(type, 0); - if (self != NULL) { - PyStructObject *s = (PyStructObject*)self; - s->s_format = Py_NewRef(Py_None); - s->s_codes = NULL; - s->s_size = -1; - s->s_len = -1; + PyStructObject *self = (PyStructObject *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->s_format = Py_NewRef(Py_None); + self->s_codes = NULL; + self->s_size = -1; + self->s_len = -1; + self->init_called = false; + if (format && set_format(self, format) < 0) { + if (type->tp_init == s_init) { + /* No custom __init__() method, so __new__() should do + * all the work. */ + Py_DECREF(format); + Py_DECREF(self); + return NULL; + } + PyObject *exc = PyErr_GetRaisedException(); + Py_SETREF(self->s_format, Py_NewRef(Py_None)); + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Invalid 'format' argument for Struct.__new__(): %S", exc)) + { + Py_DECREF(exc); + Py_DECREF(format); + Py_DECREF(self); + return NULL; + } + Py_DECREF(exc); + } + Py_XDECREF(format); + return (PyObject *)self; +} + +static bool +same_format(PyStructObject *s, PyObject *format) +{ + Py_ssize_t size = PyBytes_GET_SIZE(s->s_format); + const void *data = PyBytes_AS_STRING(s->s_format); + if (PyUnicode_Check(format) && PyUnicode_IS_ASCII(format)) { + return PyUnicode_GET_LENGTH(format) == size + && memcmp(PyUnicode_1BYTE_DATA(format), data, size) == 0; + } + if (PyBytes_Check(format)) { + return PyBytes_GET_SIZE(format) == size + && memcmp(PyBytes_AS_STRING(format), data, size) == 0; } - return self; + return false; } /*[clinic input] @@ -1808,29 +1938,42 @@ static int Struct___init___impl(PyStructObject *self, PyObject *format) /*[clinic end generated code: output=b8e80862444e92d0 input=1af78a5f57d82cec]*/ { - int ret = 0; - - if (PyUnicode_Check(format)) { - format = PyUnicode_AsASCIIString(format); - if (format == NULL) + if (self->s_format == Py_None) { + if (set_format(self, format) < 0) { return -1; + } } - else { - Py_INCREF(format); + else if (!same_format(self, format)) { + const char *msg = self->init_called + ? "Re-initialization of Struct by calling the __init__() method " + "will not work in future Python versions" + : "Different format arguments for __new__() and __init__() " + "methods of Struct"; + if (PyErr_WarnEx(PyExc_FutureWarning, msg, 1)) { + return -1; + } + if (set_format(self, format) < 0) { + return -1; + } } + self->init_called = true; + return 0; +} - if (!PyBytes_Check(format)) { - Py_DECREF(format); - PyErr_Format(PyExc_TypeError, - "Struct() argument 1 must be a str or bytes object, " - "not %.200s", - _PyType_Name(Py_TYPE(format))); - return -1; +static int +s_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + if (!((PyStructObject *)self)->init_called + && Py_TYPE(self)->tp_init == s_init + && ((PyStructObject *)self)->s_format != Py_None) + { + /* Struct.__init__() was called implicitly. + * __new__() already did all the work. */ + ((PyStructObject *)self)->init_called = true; + return 0; } - - ret = prepare_s(self, format); - Py_DECREF(format); - return ret; + /* Struct.__init__() was called explicitly. */ + return Struct___init__(self, args, kwargs); } static int @@ -2446,10 +2589,8 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_methods, s_methods}, {Py_tp_members, s_members}, {Py_tp_getset, s_getsetlist}, - {Py_tp_init, Struct___init__}, - {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_init, s_init}, {Py_tp_new, s_new}, - {Py_tp_free, PyObject_GC_Del}, {0, 0}, }; diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index 9c9d29748fcf28..e75698e3ed00cc 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -9,6 +9,66 @@ preserve #include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_modsupport.h" // _PyArg_UnpackKeywords() +PyDoc_STRVAR(Struct__doc__, +"Struct(format)\n" +"--\n" +"\n" +"Create a compiled struct object.\n" +"\n" +"Return a new Struct object which writes and reads binary data according\n" +"to the format string. See help(struct) for more on format strings."); + +static PyObject * +Struct_impl(PyTypeObject *type, PyObject *format); + +static PyObject * +Struct(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(format), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"format", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Struct", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *format; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, + /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!fastargs) { + goto exit; + } + format = fastargs[0]; + return_value = Struct_impl(type, format); + +exit: + return return_value; +} + PyDoc_STRVAR(Struct___init____doc__, "Struct(format)\n" "--\n" @@ -664,4 +724,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=09ee4ac45b7e709b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0f417d43a2a387c8 input=a9049054013a1b77]*/ From 86a0756234df7ce42fa4731c91067cb7f2e244d5 Mon Sep 17 00:00:00 2001 From: Shamil Date: Thu, 12 Mar 2026 13:46:36 +0300 Subject: [PATCH 428/498] gh-140594: Fix an out of bounds read when feeding NUL byte to PyOS_StdioReadline() (#140910) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Victor Stinner --- Lib/test/test_cmd_line.py | 8 ++++++++ .../2025-11-02-16-23-17.gh-issue-140594.YIWUpl.rst | 2 ++ Parser/myreadline.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-16-23-17.gh-issue-140594.YIWUpl.rst diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 55e5f06c8071ea..e106ac20809f20 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -200,6 +200,14 @@ def test_run_module_bug1764407(self): self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) + @support.cpython_only + def test_null_byte_in_interactive_mode(self): + # gh-140594: Fix an out of bounds read when a single NUL character + # is read from the standard input in interactive mode. + proc = spawn_python('-i') + proc.communicate(b'\x00', timeout=support.SHORT_TIMEOUT) + self.assertEqual(proc.returncode, 0) + 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 diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-16-23-17.gh-issue-140594.YIWUpl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-16-23-17.gh-issue-140594.YIWUpl.rst new file mode 100644 index 00000000000000..aa126e7e25bba7 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-02-16-23-17.gh-issue-140594.YIWUpl.rst @@ -0,0 +1,2 @@ +Fix an out of bounds read when a single NUL character is read from the standard input. +Patch by Shamil Abdulaev. diff --git a/Parser/myreadline.c b/Parser/myreadline.c index 64e8f5383f0602..ee77479ba7bdcc 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -344,7 +344,7 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) break; } n += strlen(p + n); - } while (p[n-1] != '\n'); + } while (n == 0 || p[n-1] != '\n'); pr = (char *)PyMem_RawRealloc(p, n+1); if (pr == NULL) { From 453562a467a1f78a851ee12e7a556d1fe34f5a44 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 12 Mar 2026 10:57:59 +0000 Subject: [PATCH 429/498] GH-145692: Convert DEOPT_IFs to EXIT_IFs (GH-145751) * Convert DEOPT_IFs to EXIT_IFs for guards. Keep DEOPT_IF for intentional drops to the interpreter. * Modify BINARY_OP_SUBSCR_LIST_INT and STORE_SUBSCR_LIST_INT to handle negative indices, to keep EXIT_IFs and DEOPT_IFs in different uops --- Include/internal/pycore_opcode_metadata.h | 62 +- Include/internal/pycore_uop_ids.h | 1943 +++++++++++---------- Include/internal/pycore_uop_metadata.h | 125 +- Modules/_testinternalcapi/test_cases.c.h | 43 +- Python/bytecodes.c | 163 +- Python/executor_cases.c.h | 145 +- Python/generated_cases.c.h | 43 +- Python/optimizer_cases.c.h | 6 +- 8 files changed, 1304 insertions(+), 1226 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 09588e9428281e..2586ed3a5299a6 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1096,17 +1096,17 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG }, [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG }, [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG }, - [BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_LOCAL_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG }, [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG }, [BINARY_OP_SUBSCR_DICT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, - [BINARY_OP_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [BINARY_OP_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_SUBSCR_LIST_SLICE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, - [BINARY_OP_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, - [BINARY_OP_SUBSCR_USTR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG }, + [BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG }, + [BINARY_OP_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_SUBSCR_USTR_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG }, [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG }, [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG }, [BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1120,24 +1120,24 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG }, [CACHE] = { true, INSTR_FMT_IX, 0 }, [CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, - [CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_BOUND_METHOD_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, - [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, - [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, - [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, + [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, + [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_EX_NON_PY_GENERAL] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_EX_PY] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_FUNCTION_EX] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [CALL_ISINSTANCE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [CALL_ISINSTANCE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_KW] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [CALL_KW_BOUND_METHOD] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [CALL_KW_NON_PY] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_KW_PY] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, - [CALL_LEN] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [CALL_LEN] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, @@ -1146,9 +1146,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [CALL_NON_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, - [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, @@ -1158,7 +1158,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG }, [CONTAINS_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CONTAINS_OP_DICT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [CONTAINS_OP_SET] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [CONTAINS_OP_SET] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_PURE_FLAG }, [COPY_FREE_VARS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, @@ -1179,7 +1179,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, - [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG }, @@ -1226,15 +1226,15 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, + [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, + [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, + [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, + [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_COMMON_CONSTANT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, @@ -1255,8 +1255,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [LOAD_SMALL_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1283,13 +1283,13 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, - [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, + [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [STORE_ATTR] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, + [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG }, @@ -1317,8 +1317,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, - [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, - [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, + [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, + [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [ANNOTATIONS_PLACEHOLDER] = { true, -1, HAS_PURE_FLAG }, @@ -1502,7 +1502,7 @@ _PyOpcode_macro_expansion[256] = { [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, OPARG_SIMPLE, 0 } } }, [SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, OPARG_SIMPLE, 0 } } }, [STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, OPARG_SIMPLE, 3 } } }, - [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION_AND_LOCK, 2, 1 }, { _GUARD_DORV_NO_DICT, OPARG_SIMPLE, 3 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } }, + [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 5, .uops = { { _LOCK_OBJECT, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION_LOCKED, 2, 1 }, { _GUARD_DORV_NO_DICT, OPARG_SIMPLE, 3 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } }, [STORE_ATTR_SLOT] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } }, [STORE_ATTR_WITH_HINT] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } }, [STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 216436604c6973..79e62edfeed978 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -189,7 +189,7 @@ extern "C" { #define _GUARD_TOS_TUPLE 444 #define _GUARD_TOS_UNICODE 445 #define _GUARD_TYPE_VERSION 446 -#define _GUARD_TYPE_VERSION_AND_LOCK 447 +#define _GUARD_TYPE_VERSION_LOCKED 447 #define _HANDLE_PENDING_AND_DEOPT 448 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME @@ -286,1002 +286,1007 @@ extern "C" { #define _LOAD_SPECIAL 516 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 517 +#define _LOCK_OBJECT 517 +#define _MAKE_CALLARGS_A_TUPLE 518 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_HEAP_SAFE 518 -#define _MAKE_WARM 519 +#define _MAKE_HEAP_SAFE 519 +#define _MAKE_WARM 520 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 520 -#define _MAYBE_EXPAND_METHOD_KW 521 -#define _MONITOR_CALL 522 -#define _MONITOR_CALL_KW 523 -#define _MONITOR_JUMP_BACKWARD 524 -#define _MONITOR_RESUME 525 +#define _MAYBE_EXPAND_METHOD 521 +#define _MAYBE_EXPAND_METHOD_KW 522 +#define _MONITOR_CALL 523 +#define _MONITOR_CALL_KW 524 +#define _MONITOR_JUMP_BACKWARD 525 +#define _MONITOR_RESUME 526 #define _NOP NOP -#define _POP_CALL 526 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 527 -#define _POP_CALL_ONE 528 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 529 -#define _POP_CALL_TWO 530 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 531 +#define _POP_CALL 527 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 528 +#define _POP_CALL_ONE 529 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 530 +#define _POP_CALL_TWO 531 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 532 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 532 -#define _POP_JUMP_IF_TRUE 533 +#define _POP_JUMP_IF_FALSE 533 +#define _POP_JUMP_IF_TRUE 534 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 534 -#define _POP_TOP_INT 535 -#define _POP_TOP_LOAD_CONST_INLINE 536 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 537 -#define _POP_TOP_NOP 538 -#define _POP_TOP_UNICODE 539 -#define _POP_TWO 540 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 541 +#define _POP_TOP_FLOAT 535 +#define _POP_TOP_INT 536 +#define _POP_TOP_LOAD_CONST_INLINE 537 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 538 +#define _POP_TOP_NOP 539 +#define _POP_TOP_UNICODE 540 +#define _POP_TWO 541 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 542 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 542 +#define _PUSH_FRAME 543 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 543 -#define _PY_FRAME_EX 544 -#define _PY_FRAME_GENERAL 545 -#define _PY_FRAME_KW 546 -#define _QUICKEN_RESUME 547 -#define _RECORD_4OS 548 -#define _RECORD_BOUND_METHOD 549 -#define _RECORD_CALLABLE 550 -#define _RECORD_CODE 551 -#define _RECORD_NOS 552 -#define _RECORD_NOS_GEN_FUNC 553 -#define _RECORD_TOS 554 -#define _RECORD_TOS_TYPE 555 -#define _REPLACE_WITH_TRUE 556 +#define _PUSH_NULL_CONDITIONAL 544 +#define _PY_FRAME_EX 545 +#define _PY_FRAME_GENERAL 546 +#define _PY_FRAME_KW 547 +#define _QUICKEN_RESUME 548 +#define _RECORD_4OS 549 +#define _RECORD_BOUND_METHOD 550 +#define _RECORD_CALLABLE 551 +#define _RECORD_CODE 552 +#define _RECORD_NOS 553 +#define _RECORD_NOS_GEN_FUNC 554 +#define _RECORD_TOS 555 +#define _RECORD_TOS_TYPE 556 +#define _REPLACE_WITH_TRUE 557 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE 557 -#define _SAVE_RETURN_OFFSET 558 -#define _SEND 559 -#define _SEND_GEN_FRAME 560 +#define _RETURN_VALUE 558 +#define _SAVE_RETURN_OFFSET 559 +#define _SEND 560 +#define _SEND_GEN_FRAME 561 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 561 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 562 -#define _SPILL_OR_RELOAD 563 -#define _START_EXECUTOR 564 -#define _STORE_ATTR 565 -#define _STORE_ATTR_INSTANCE_VALUE 566 -#define _STORE_ATTR_SLOT 567 -#define _STORE_ATTR_WITH_HINT 568 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 562 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 563 +#define _SPILL_OR_RELOAD 564 +#define _START_EXECUTOR 565 +#define _STORE_ATTR 566 +#define _STORE_ATTR_INSTANCE_VALUE 567 +#define _STORE_ATTR_SLOT 568 +#define _STORE_ATTR_WITH_HINT 569 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 569 -#define _STORE_SUBSCR 570 -#define _STORE_SUBSCR_DICT 571 -#define _STORE_SUBSCR_LIST_INT 572 -#define _SWAP 573 -#define _SWAP_2 574 -#define _SWAP_3 575 -#define _SWAP_FAST 576 -#define _SWAP_FAST_0 577 -#define _SWAP_FAST_1 578 -#define _SWAP_FAST_2 579 -#define _SWAP_FAST_3 580 -#define _SWAP_FAST_4 581 -#define _SWAP_FAST_5 582 -#define _SWAP_FAST_6 583 -#define _SWAP_FAST_7 584 -#define _TIER2_RESUME_CHECK 585 -#define _TO_BOOL 586 +#define _STORE_SLICE 570 +#define _STORE_SUBSCR 571 +#define _STORE_SUBSCR_DICT 572 +#define _STORE_SUBSCR_LIST_INT 573 +#define _SWAP 574 +#define _SWAP_2 575 +#define _SWAP_3 576 +#define _SWAP_FAST 577 +#define _SWAP_FAST_0 578 +#define _SWAP_FAST_1 579 +#define _SWAP_FAST_2 580 +#define _SWAP_FAST_3 581 +#define _SWAP_FAST_4 582 +#define _SWAP_FAST_5 583 +#define _SWAP_FAST_6 584 +#define _SWAP_FAST_7 585 +#define _TIER2_RESUME_CHECK 586 +#define _TO_BOOL 587 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 587 -#define _TO_BOOL_LIST 588 +#define _TO_BOOL_INT 588 +#define _TO_BOOL_LIST 589 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 589 +#define _TO_BOOL_STR 590 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 590 -#define _UNARY_NEGATIVE 591 +#define _UNARY_INVERT 591 +#define _UNARY_NEGATIVE 592 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 592 -#define _UNPACK_SEQUENCE_LIST 593 -#define _UNPACK_SEQUENCE_TUPLE 594 -#define _UNPACK_SEQUENCE_TWO_TUPLE 595 +#define _UNPACK_SEQUENCE 593 +#define _UNPACK_SEQUENCE_LIST 594 +#define _UNPACK_SEQUENCE_TUPLE 595 +#define _UNPACK_SEQUENCE_TWO_TUPLE 596 #define _WITH_EXCEPT_START WITH_EXCEPT_START -#define _YIELD_VALUE 596 -#define MAX_UOP_ID 596 -#define _BINARY_OP_r23 597 -#define _BINARY_OP_ADD_FLOAT_r03 598 -#define _BINARY_OP_ADD_FLOAT_r13 599 -#define _BINARY_OP_ADD_FLOAT_r23 600 -#define _BINARY_OP_ADD_INT_r03 601 -#define _BINARY_OP_ADD_INT_r13 602 -#define _BINARY_OP_ADD_INT_r23 603 -#define _BINARY_OP_ADD_UNICODE_r03 604 -#define _BINARY_OP_ADD_UNICODE_r13 605 -#define _BINARY_OP_ADD_UNICODE_r23 606 -#define _BINARY_OP_EXTEND_r23 607 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 608 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 609 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 610 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 611 -#define _BINARY_OP_MULTIPLY_INT_r03 612 -#define _BINARY_OP_MULTIPLY_INT_r13 613 -#define _BINARY_OP_MULTIPLY_INT_r23 614 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 615 -#define _BINARY_OP_SUBSCR_DICT_r23 616 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 617 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 618 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 619 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 620 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 621 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 622 -#define _BINARY_OP_SUBSCR_STR_INT_r23 623 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 624 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 625 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 626 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 627 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 628 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 629 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 630 -#define _BINARY_OP_SUBTRACT_INT_r03 631 -#define _BINARY_OP_SUBTRACT_INT_r13 632 -#define _BINARY_OP_SUBTRACT_INT_r23 633 -#define _BINARY_SLICE_r31 634 -#define _BUILD_INTERPOLATION_r01 635 -#define _BUILD_LIST_r01 636 -#define _BUILD_MAP_r01 637 -#define _BUILD_SET_r01 638 -#define _BUILD_SLICE_r01 639 -#define _BUILD_STRING_r01 640 -#define _BUILD_TEMPLATE_r21 641 -#define _BUILD_TUPLE_r01 642 -#define _CALL_BUILTIN_CLASS_r01 643 -#define _CALL_BUILTIN_FAST_r01 644 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 645 -#define _CALL_BUILTIN_O_r03 646 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 647 -#define _CALL_INTRINSIC_1_r11 648 -#define _CALL_INTRINSIC_2_r21 649 -#define _CALL_ISINSTANCE_r31 650 -#define _CALL_KW_NON_PY_r11 651 -#define _CALL_LEN_r33 652 -#define _CALL_LIST_APPEND_r03 653 -#define _CALL_LIST_APPEND_r13 654 -#define _CALL_LIST_APPEND_r23 655 -#define _CALL_LIST_APPEND_r33 656 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 657 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 658 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 659 -#define _CALL_METHOD_DESCRIPTOR_O_r03 660 -#define _CALL_NON_PY_GENERAL_r01 661 -#define _CALL_STR_1_r32 662 -#define _CALL_TUPLE_1_r32 663 -#define _CALL_TYPE_1_r02 664 -#define _CALL_TYPE_1_r12 665 -#define _CALL_TYPE_1_r22 666 -#define _CALL_TYPE_1_r32 667 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 668 -#define _CHECK_ATTR_CLASS_r01 669 -#define _CHECK_ATTR_CLASS_r11 670 -#define _CHECK_ATTR_CLASS_r22 671 -#define _CHECK_ATTR_CLASS_r33 672 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 673 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 674 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 675 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 676 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 677 -#define _CHECK_EG_MATCH_r22 678 -#define _CHECK_EXC_MATCH_r22 679 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 680 -#define _CHECK_FUNCTION_VERSION_r00 681 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 682 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 683 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 684 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 685 -#define _CHECK_FUNCTION_VERSION_KW_r11 686 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 687 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 688 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 689 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 690 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 691 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 692 -#define _CHECK_IS_PY_CALLABLE_EX_r03 693 -#define _CHECK_IS_PY_CALLABLE_EX_r13 694 -#define _CHECK_IS_PY_CALLABLE_EX_r23 695 -#define _CHECK_IS_PY_CALLABLE_EX_r33 696 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 697 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 698 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 699 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 700 -#define _CHECK_METHOD_VERSION_r00 701 -#define _CHECK_METHOD_VERSION_KW_r11 702 -#define _CHECK_PEP_523_r00 703 -#define _CHECK_PEP_523_r11 704 -#define _CHECK_PEP_523_r22 705 -#define _CHECK_PEP_523_r33 706 -#define _CHECK_PERIODIC_r00 707 -#define _CHECK_PERIODIC_AT_END_r00 708 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 709 -#define _CHECK_RECURSION_REMAINING_r00 710 -#define _CHECK_RECURSION_REMAINING_r11 711 -#define _CHECK_RECURSION_REMAINING_r22 712 -#define _CHECK_RECURSION_REMAINING_r33 713 -#define _CHECK_STACK_SPACE_r00 714 -#define _CHECK_STACK_SPACE_OPERAND_r00 715 -#define _CHECK_STACK_SPACE_OPERAND_r11 716 -#define _CHECK_STACK_SPACE_OPERAND_r22 717 -#define _CHECK_STACK_SPACE_OPERAND_r33 718 -#define _CHECK_VALIDITY_r00 719 -#define _CHECK_VALIDITY_r11 720 -#define _CHECK_VALIDITY_r22 721 -#define _CHECK_VALIDITY_r33 722 -#define _COLD_DYNAMIC_EXIT_r00 723 -#define _COLD_EXIT_r00 724 -#define _COMPARE_OP_r21 725 -#define _COMPARE_OP_FLOAT_r03 726 -#define _COMPARE_OP_FLOAT_r13 727 -#define _COMPARE_OP_FLOAT_r23 728 -#define _COMPARE_OP_INT_r23 729 -#define _COMPARE_OP_STR_r23 730 -#define _CONTAINS_OP_r23 731 -#define _CONTAINS_OP_DICT_r23 732 -#define _CONTAINS_OP_SET_r23 733 -#define _CONVERT_VALUE_r11 734 -#define _COPY_r01 735 -#define _COPY_1_r02 736 -#define _COPY_1_r12 737 -#define _COPY_1_r23 738 -#define _COPY_2_r03 739 -#define _COPY_2_r13 740 -#define _COPY_2_r23 741 -#define _COPY_3_r03 742 -#define _COPY_3_r13 743 -#define _COPY_3_r23 744 -#define _COPY_3_r33 745 -#define _COPY_FREE_VARS_r00 746 -#define _COPY_FREE_VARS_r11 747 -#define _COPY_FREE_VARS_r22 748 -#define _COPY_FREE_VARS_r33 749 -#define _CREATE_INIT_FRAME_r01 750 -#define _DELETE_ATTR_r10 751 -#define _DELETE_DEREF_r00 752 -#define _DELETE_FAST_r00 753 -#define _DELETE_GLOBAL_r00 754 -#define _DELETE_NAME_r00 755 -#define _DELETE_SUBSCR_r20 756 -#define _DEOPT_r00 757 -#define _DEOPT_r10 758 -#define _DEOPT_r20 759 -#define _DEOPT_r30 760 -#define _DICT_MERGE_r10 761 -#define _DICT_UPDATE_r10 762 -#define _DO_CALL_r01 763 -#define _DO_CALL_FUNCTION_EX_r31 764 -#define _DO_CALL_KW_r11 765 -#define _DYNAMIC_EXIT_r00 766 -#define _DYNAMIC_EXIT_r10 767 -#define _DYNAMIC_EXIT_r20 768 -#define _DYNAMIC_EXIT_r30 769 -#define _END_FOR_r10 770 -#define _END_SEND_r21 771 -#define _ERROR_POP_N_r00 772 -#define _EXIT_INIT_CHECK_r10 773 -#define _EXIT_TRACE_r00 774 -#define _EXIT_TRACE_r10 775 -#define _EXIT_TRACE_r20 776 -#define _EXIT_TRACE_r30 777 -#define _EXPAND_METHOD_r00 778 -#define _EXPAND_METHOD_KW_r11 779 -#define _FATAL_ERROR_r00 780 -#define _FATAL_ERROR_r11 781 -#define _FATAL_ERROR_r22 782 -#define _FATAL_ERROR_r33 783 -#define _FORMAT_SIMPLE_r11 784 -#define _FORMAT_WITH_SPEC_r21 785 -#define _FOR_ITER_r23 786 -#define _FOR_ITER_GEN_FRAME_r03 787 -#define _FOR_ITER_GEN_FRAME_r13 788 -#define _FOR_ITER_GEN_FRAME_r23 789 -#define _FOR_ITER_TIER_TWO_r23 790 -#define _GET_AITER_r11 791 -#define _GET_ANEXT_r12 792 -#define _GET_AWAITABLE_r11 793 -#define _GET_ITER_r12 794 -#define _GET_LEN_r12 795 -#define _GET_YIELD_FROM_ITER_r11 796 -#define _GUARD_BINARY_OP_EXTEND_r22 797 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 798 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 799 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 800 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 801 -#define _GUARD_BIT_IS_SET_POP_r00 802 -#define _GUARD_BIT_IS_SET_POP_r10 803 -#define _GUARD_BIT_IS_SET_POP_r21 804 -#define _GUARD_BIT_IS_SET_POP_r32 805 -#define _GUARD_BIT_IS_SET_POP_4_r00 806 -#define _GUARD_BIT_IS_SET_POP_4_r10 807 -#define _GUARD_BIT_IS_SET_POP_4_r21 808 -#define _GUARD_BIT_IS_SET_POP_4_r32 809 -#define _GUARD_BIT_IS_SET_POP_5_r00 810 -#define _GUARD_BIT_IS_SET_POP_5_r10 811 -#define _GUARD_BIT_IS_SET_POP_5_r21 812 -#define _GUARD_BIT_IS_SET_POP_5_r32 813 -#define _GUARD_BIT_IS_SET_POP_6_r00 814 -#define _GUARD_BIT_IS_SET_POP_6_r10 815 -#define _GUARD_BIT_IS_SET_POP_6_r21 816 -#define _GUARD_BIT_IS_SET_POP_6_r32 817 -#define _GUARD_BIT_IS_SET_POP_7_r00 818 -#define _GUARD_BIT_IS_SET_POP_7_r10 819 -#define _GUARD_BIT_IS_SET_POP_7_r21 820 -#define _GUARD_BIT_IS_SET_POP_7_r32 821 -#define _GUARD_BIT_IS_UNSET_POP_r00 822 -#define _GUARD_BIT_IS_UNSET_POP_r10 823 -#define _GUARD_BIT_IS_UNSET_POP_r21 824 -#define _GUARD_BIT_IS_UNSET_POP_r32 825 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 826 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 827 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 828 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 829 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 830 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 831 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 832 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 833 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 834 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 835 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 836 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 837 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 838 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 839 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 840 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 841 -#define _GUARD_CALLABLE_ISINSTANCE_r03 842 -#define _GUARD_CALLABLE_ISINSTANCE_r13 843 -#define _GUARD_CALLABLE_ISINSTANCE_r23 844 -#define _GUARD_CALLABLE_ISINSTANCE_r33 845 -#define _GUARD_CALLABLE_LEN_r03 846 -#define _GUARD_CALLABLE_LEN_r13 847 -#define _GUARD_CALLABLE_LEN_r23 848 -#define _GUARD_CALLABLE_LEN_r33 849 -#define _GUARD_CALLABLE_LIST_APPEND_r03 850 -#define _GUARD_CALLABLE_LIST_APPEND_r13 851 -#define _GUARD_CALLABLE_LIST_APPEND_r23 852 -#define _GUARD_CALLABLE_LIST_APPEND_r33 853 -#define _GUARD_CALLABLE_STR_1_r03 854 -#define _GUARD_CALLABLE_STR_1_r13 855 -#define _GUARD_CALLABLE_STR_1_r23 856 -#define _GUARD_CALLABLE_STR_1_r33 857 -#define _GUARD_CALLABLE_TUPLE_1_r03 858 -#define _GUARD_CALLABLE_TUPLE_1_r13 859 -#define _GUARD_CALLABLE_TUPLE_1_r23 860 -#define _GUARD_CALLABLE_TUPLE_1_r33 861 -#define _GUARD_CALLABLE_TYPE_1_r03 862 -#define _GUARD_CALLABLE_TYPE_1_r13 863 -#define _GUARD_CALLABLE_TYPE_1_r23 864 -#define _GUARD_CALLABLE_TYPE_1_r33 865 -#define _GUARD_CODE_VERSION_r00 866 -#define _GUARD_CODE_VERSION_r11 867 -#define _GUARD_CODE_VERSION_r22 868 -#define _GUARD_CODE_VERSION_r33 869 -#define _GUARD_DORV_NO_DICT_r01 870 -#define _GUARD_DORV_NO_DICT_r11 871 -#define _GUARD_DORV_NO_DICT_r22 872 -#define _GUARD_DORV_NO_DICT_r33 873 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 874 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 875 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 876 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 877 -#define _GUARD_GLOBALS_VERSION_r00 878 -#define _GUARD_GLOBALS_VERSION_r11 879 -#define _GUARD_GLOBALS_VERSION_r22 880 -#define _GUARD_GLOBALS_VERSION_r33 881 -#define _GUARD_IP_RETURN_GENERATOR_r00 882 -#define _GUARD_IP_RETURN_GENERATOR_r11 883 -#define _GUARD_IP_RETURN_GENERATOR_r22 884 -#define _GUARD_IP_RETURN_GENERATOR_r33 885 -#define _GUARD_IP_RETURN_VALUE_r00 886 -#define _GUARD_IP_RETURN_VALUE_r11 887 -#define _GUARD_IP_RETURN_VALUE_r22 888 -#define _GUARD_IP_RETURN_VALUE_r33 889 -#define _GUARD_IP_YIELD_VALUE_r00 890 -#define _GUARD_IP_YIELD_VALUE_r11 891 -#define _GUARD_IP_YIELD_VALUE_r22 892 -#define _GUARD_IP_YIELD_VALUE_r33 893 -#define _GUARD_IP__PUSH_FRAME_r00 894 -#define _GUARD_IP__PUSH_FRAME_r11 895 -#define _GUARD_IP__PUSH_FRAME_r22 896 -#define _GUARD_IP__PUSH_FRAME_r33 897 -#define _GUARD_IS_FALSE_POP_r00 898 -#define _GUARD_IS_FALSE_POP_r10 899 -#define _GUARD_IS_FALSE_POP_r21 900 -#define _GUARD_IS_FALSE_POP_r32 901 -#define _GUARD_IS_NONE_POP_r00 902 -#define _GUARD_IS_NONE_POP_r10 903 -#define _GUARD_IS_NONE_POP_r21 904 -#define _GUARD_IS_NONE_POP_r32 905 -#define _GUARD_IS_NOT_NONE_POP_r10 906 -#define _GUARD_IS_TRUE_POP_r00 907 -#define _GUARD_IS_TRUE_POP_r10 908 -#define _GUARD_IS_TRUE_POP_r21 909 -#define _GUARD_IS_TRUE_POP_r32 910 -#define _GUARD_KEYS_VERSION_r01 911 -#define _GUARD_KEYS_VERSION_r11 912 -#define _GUARD_KEYS_VERSION_r22 913 -#define _GUARD_KEYS_VERSION_r33 914 -#define _GUARD_NOS_ANY_DICT_r02 915 -#define _GUARD_NOS_ANY_DICT_r12 916 -#define _GUARD_NOS_ANY_DICT_r22 917 -#define _GUARD_NOS_ANY_DICT_r33 918 -#define _GUARD_NOS_COMPACT_ASCII_r02 919 -#define _GUARD_NOS_COMPACT_ASCII_r12 920 -#define _GUARD_NOS_COMPACT_ASCII_r22 921 -#define _GUARD_NOS_COMPACT_ASCII_r33 922 -#define _GUARD_NOS_DICT_r02 923 -#define _GUARD_NOS_DICT_r12 924 -#define _GUARD_NOS_DICT_r22 925 -#define _GUARD_NOS_DICT_r33 926 -#define _GUARD_NOS_FLOAT_r02 927 -#define _GUARD_NOS_FLOAT_r12 928 -#define _GUARD_NOS_FLOAT_r22 929 -#define _GUARD_NOS_FLOAT_r33 930 -#define _GUARD_NOS_INT_r02 931 -#define _GUARD_NOS_INT_r12 932 -#define _GUARD_NOS_INT_r22 933 -#define _GUARD_NOS_INT_r33 934 -#define _GUARD_NOS_LIST_r02 935 -#define _GUARD_NOS_LIST_r12 936 -#define _GUARD_NOS_LIST_r22 937 -#define _GUARD_NOS_LIST_r33 938 -#define _GUARD_NOS_NOT_NULL_r02 939 -#define _GUARD_NOS_NOT_NULL_r12 940 -#define _GUARD_NOS_NOT_NULL_r22 941 -#define _GUARD_NOS_NOT_NULL_r33 942 -#define _GUARD_NOS_NULL_r02 943 -#define _GUARD_NOS_NULL_r12 944 -#define _GUARD_NOS_NULL_r22 945 -#define _GUARD_NOS_NULL_r33 946 -#define _GUARD_NOS_OVERFLOWED_r02 947 -#define _GUARD_NOS_OVERFLOWED_r12 948 -#define _GUARD_NOS_OVERFLOWED_r22 949 -#define _GUARD_NOS_OVERFLOWED_r33 950 -#define _GUARD_NOS_TUPLE_r02 951 -#define _GUARD_NOS_TUPLE_r12 952 -#define _GUARD_NOS_TUPLE_r22 953 -#define _GUARD_NOS_TUPLE_r33 954 -#define _GUARD_NOS_UNICODE_r02 955 -#define _GUARD_NOS_UNICODE_r12 956 -#define _GUARD_NOS_UNICODE_r22 957 -#define _GUARD_NOS_UNICODE_r33 958 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 959 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 960 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 961 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 962 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 963 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 964 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 965 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 966 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 967 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 968 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 969 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 970 -#define _GUARD_THIRD_NULL_r03 971 -#define _GUARD_THIRD_NULL_r13 972 -#define _GUARD_THIRD_NULL_r23 973 -#define _GUARD_THIRD_NULL_r33 974 -#define _GUARD_TOS_ANY_DICT_r01 975 -#define _GUARD_TOS_ANY_DICT_r11 976 -#define _GUARD_TOS_ANY_DICT_r22 977 -#define _GUARD_TOS_ANY_DICT_r33 978 -#define _GUARD_TOS_ANY_SET_r01 979 -#define _GUARD_TOS_ANY_SET_r11 980 -#define _GUARD_TOS_ANY_SET_r22 981 -#define _GUARD_TOS_ANY_SET_r33 982 -#define _GUARD_TOS_DICT_r01 983 -#define _GUARD_TOS_DICT_r11 984 -#define _GUARD_TOS_DICT_r22 985 -#define _GUARD_TOS_DICT_r33 986 -#define _GUARD_TOS_FLOAT_r01 987 -#define _GUARD_TOS_FLOAT_r11 988 -#define _GUARD_TOS_FLOAT_r22 989 -#define _GUARD_TOS_FLOAT_r33 990 -#define _GUARD_TOS_FROZENDICT_r01 991 -#define _GUARD_TOS_FROZENDICT_r11 992 -#define _GUARD_TOS_FROZENDICT_r22 993 -#define _GUARD_TOS_FROZENDICT_r33 994 -#define _GUARD_TOS_FROZENSET_r01 995 -#define _GUARD_TOS_FROZENSET_r11 996 -#define _GUARD_TOS_FROZENSET_r22 997 -#define _GUARD_TOS_FROZENSET_r33 998 -#define _GUARD_TOS_INT_r01 999 -#define _GUARD_TOS_INT_r11 1000 -#define _GUARD_TOS_INT_r22 1001 -#define _GUARD_TOS_INT_r33 1002 -#define _GUARD_TOS_LIST_r01 1003 -#define _GUARD_TOS_LIST_r11 1004 -#define _GUARD_TOS_LIST_r22 1005 -#define _GUARD_TOS_LIST_r33 1006 -#define _GUARD_TOS_OVERFLOWED_r01 1007 -#define _GUARD_TOS_OVERFLOWED_r11 1008 -#define _GUARD_TOS_OVERFLOWED_r22 1009 -#define _GUARD_TOS_OVERFLOWED_r33 1010 -#define _GUARD_TOS_SET_r01 1011 -#define _GUARD_TOS_SET_r11 1012 -#define _GUARD_TOS_SET_r22 1013 -#define _GUARD_TOS_SET_r33 1014 -#define _GUARD_TOS_SLICE_r01 1015 -#define _GUARD_TOS_SLICE_r11 1016 -#define _GUARD_TOS_SLICE_r22 1017 -#define _GUARD_TOS_SLICE_r33 1018 -#define _GUARD_TOS_TUPLE_r01 1019 -#define _GUARD_TOS_TUPLE_r11 1020 -#define _GUARD_TOS_TUPLE_r22 1021 -#define _GUARD_TOS_TUPLE_r33 1022 -#define _GUARD_TOS_UNICODE_r01 1023 -#define _GUARD_TOS_UNICODE_r11 1024 -#define _GUARD_TOS_UNICODE_r22 1025 -#define _GUARD_TOS_UNICODE_r33 1026 -#define _GUARD_TYPE_VERSION_r01 1027 -#define _GUARD_TYPE_VERSION_r11 1028 -#define _GUARD_TYPE_VERSION_r22 1029 -#define _GUARD_TYPE_VERSION_r33 1030 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 1031 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 1032 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 1033 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 1034 -#define _HANDLE_PENDING_AND_DEOPT_r00 1035 -#define _HANDLE_PENDING_AND_DEOPT_r10 1036 -#define _HANDLE_PENDING_AND_DEOPT_r20 1037 -#define _HANDLE_PENDING_AND_DEOPT_r30 1038 -#define _IMPORT_FROM_r12 1039 -#define _IMPORT_NAME_r21 1040 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1041 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1042 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1043 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1044 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1045 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1046 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1047 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1048 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1049 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1050 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1051 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1052 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1053 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1054 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1055 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1056 -#define _INSERT_NULL_r10 1057 -#define _INSTRUMENTED_FOR_ITER_r23 1058 -#define _INSTRUMENTED_INSTRUCTION_r00 1059 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1060 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1061 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1062 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1063 -#define _INSTRUMENTED_LINE_r00 1064 -#define _INSTRUMENTED_NOT_TAKEN_r00 1065 -#define _INSTRUMENTED_NOT_TAKEN_r11 1066 -#define _INSTRUMENTED_NOT_TAKEN_r22 1067 -#define _INSTRUMENTED_NOT_TAKEN_r33 1068 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1069 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1070 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1071 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1072 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1073 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1074 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1075 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1076 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1077 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1078 -#define _IS_NONE_r11 1079 -#define _IS_OP_r03 1080 -#define _IS_OP_r13 1081 -#define _IS_OP_r23 1082 -#define _ITER_CHECK_LIST_r02 1083 -#define _ITER_CHECK_LIST_r12 1084 -#define _ITER_CHECK_LIST_r22 1085 -#define _ITER_CHECK_LIST_r33 1086 -#define _ITER_CHECK_RANGE_r02 1087 -#define _ITER_CHECK_RANGE_r12 1088 -#define _ITER_CHECK_RANGE_r22 1089 -#define _ITER_CHECK_RANGE_r33 1090 -#define _ITER_CHECK_TUPLE_r02 1091 -#define _ITER_CHECK_TUPLE_r12 1092 -#define _ITER_CHECK_TUPLE_r22 1093 -#define _ITER_CHECK_TUPLE_r33 1094 -#define _ITER_JUMP_LIST_r02 1095 -#define _ITER_JUMP_LIST_r12 1096 -#define _ITER_JUMP_LIST_r22 1097 -#define _ITER_JUMP_LIST_r33 1098 -#define _ITER_JUMP_RANGE_r02 1099 -#define _ITER_JUMP_RANGE_r12 1100 -#define _ITER_JUMP_RANGE_r22 1101 -#define _ITER_JUMP_RANGE_r33 1102 -#define _ITER_JUMP_TUPLE_r02 1103 -#define _ITER_JUMP_TUPLE_r12 1104 -#define _ITER_JUMP_TUPLE_r22 1105 -#define _ITER_JUMP_TUPLE_r33 1106 -#define _ITER_NEXT_LIST_r23 1107 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1108 -#define _ITER_NEXT_RANGE_r03 1109 -#define _ITER_NEXT_RANGE_r13 1110 -#define _ITER_NEXT_RANGE_r23 1111 -#define _ITER_NEXT_TUPLE_r03 1112 -#define _ITER_NEXT_TUPLE_r13 1113 -#define _ITER_NEXT_TUPLE_r23 1114 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1115 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1116 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1117 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1118 -#define _JUMP_TO_TOP_r00 1119 -#define _LIST_APPEND_r10 1120 -#define _LIST_EXTEND_r10 1121 -#define _LOAD_ATTR_r10 1122 -#define _LOAD_ATTR_CLASS_r11 1123 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1124 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1125 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1126 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1127 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1128 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1129 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1130 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1131 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1132 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1133 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1134 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1135 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1136 -#define _LOAD_ATTR_MODULE_r12 1137 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1138 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1139 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1140 -#define _LOAD_ATTR_SLOT_r02 1141 -#define _LOAD_ATTR_SLOT_r12 1142 -#define _LOAD_ATTR_SLOT_r23 1143 -#define _LOAD_ATTR_WITH_HINT_r12 1144 -#define _LOAD_BUILD_CLASS_r01 1145 -#define _LOAD_BYTECODE_r00 1146 -#define _LOAD_COMMON_CONSTANT_r01 1147 -#define _LOAD_COMMON_CONSTANT_r12 1148 -#define _LOAD_COMMON_CONSTANT_r23 1149 -#define _LOAD_CONST_r01 1150 -#define _LOAD_CONST_r12 1151 -#define _LOAD_CONST_r23 1152 -#define _LOAD_CONST_INLINE_r01 1153 -#define _LOAD_CONST_INLINE_r12 1154 -#define _LOAD_CONST_INLINE_r23 1155 -#define _LOAD_CONST_INLINE_BORROW_r01 1156 -#define _LOAD_CONST_INLINE_BORROW_r12 1157 -#define _LOAD_CONST_INLINE_BORROW_r23 1158 -#define _LOAD_CONST_UNDER_INLINE_r02 1159 -#define _LOAD_CONST_UNDER_INLINE_r12 1160 -#define _LOAD_CONST_UNDER_INLINE_r23 1161 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1162 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1163 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1164 -#define _LOAD_DEREF_r01 1165 -#define _LOAD_FAST_r01 1166 -#define _LOAD_FAST_r12 1167 -#define _LOAD_FAST_r23 1168 -#define _LOAD_FAST_0_r01 1169 -#define _LOAD_FAST_0_r12 1170 -#define _LOAD_FAST_0_r23 1171 -#define _LOAD_FAST_1_r01 1172 -#define _LOAD_FAST_1_r12 1173 -#define _LOAD_FAST_1_r23 1174 -#define _LOAD_FAST_2_r01 1175 -#define _LOAD_FAST_2_r12 1176 -#define _LOAD_FAST_2_r23 1177 -#define _LOAD_FAST_3_r01 1178 -#define _LOAD_FAST_3_r12 1179 -#define _LOAD_FAST_3_r23 1180 -#define _LOAD_FAST_4_r01 1181 -#define _LOAD_FAST_4_r12 1182 -#define _LOAD_FAST_4_r23 1183 -#define _LOAD_FAST_5_r01 1184 -#define _LOAD_FAST_5_r12 1185 -#define _LOAD_FAST_5_r23 1186 -#define _LOAD_FAST_6_r01 1187 -#define _LOAD_FAST_6_r12 1188 -#define _LOAD_FAST_6_r23 1189 -#define _LOAD_FAST_7_r01 1190 -#define _LOAD_FAST_7_r12 1191 -#define _LOAD_FAST_7_r23 1192 -#define _LOAD_FAST_AND_CLEAR_r01 1193 -#define _LOAD_FAST_AND_CLEAR_r12 1194 -#define _LOAD_FAST_AND_CLEAR_r23 1195 -#define _LOAD_FAST_BORROW_r01 1196 -#define _LOAD_FAST_BORROW_r12 1197 -#define _LOAD_FAST_BORROW_r23 1198 -#define _LOAD_FAST_BORROW_0_r01 1199 -#define _LOAD_FAST_BORROW_0_r12 1200 -#define _LOAD_FAST_BORROW_0_r23 1201 -#define _LOAD_FAST_BORROW_1_r01 1202 -#define _LOAD_FAST_BORROW_1_r12 1203 -#define _LOAD_FAST_BORROW_1_r23 1204 -#define _LOAD_FAST_BORROW_2_r01 1205 -#define _LOAD_FAST_BORROW_2_r12 1206 -#define _LOAD_FAST_BORROW_2_r23 1207 -#define _LOAD_FAST_BORROW_3_r01 1208 -#define _LOAD_FAST_BORROW_3_r12 1209 -#define _LOAD_FAST_BORROW_3_r23 1210 -#define _LOAD_FAST_BORROW_4_r01 1211 -#define _LOAD_FAST_BORROW_4_r12 1212 -#define _LOAD_FAST_BORROW_4_r23 1213 -#define _LOAD_FAST_BORROW_5_r01 1214 -#define _LOAD_FAST_BORROW_5_r12 1215 -#define _LOAD_FAST_BORROW_5_r23 1216 -#define _LOAD_FAST_BORROW_6_r01 1217 -#define _LOAD_FAST_BORROW_6_r12 1218 -#define _LOAD_FAST_BORROW_6_r23 1219 -#define _LOAD_FAST_BORROW_7_r01 1220 -#define _LOAD_FAST_BORROW_7_r12 1221 -#define _LOAD_FAST_BORROW_7_r23 1222 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1223 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1224 -#define _LOAD_FAST_CHECK_r01 1225 -#define _LOAD_FAST_CHECK_r12 1226 -#define _LOAD_FAST_CHECK_r23 1227 -#define _LOAD_FAST_LOAD_FAST_r02 1228 -#define _LOAD_FAST_LOAD_FAST_r13 1229 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1230 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1231 -#define _LOAD_GLOBAL_r00 1232 -#define _LOAD_GLOBAL_BUILTINS_r01 1233 -#define _LOAD_GLOBAL_MODULE_r01 1234 -#define _LOAD_LOCALS_r01 1235 -#define _LOAD_LOCALS_r12 1236 -#define _LOAD_LOCALS_r23 1237 -#define _LOAD_NAME_r01 1238 -#define _LOAD_SMALL_INT_r01 1239 -#define _LOAD_SMALL_INT_r12 1240 -#define _LOAD_SMALL_INT_r23 1241 -#define _LOAD_SMALL_INT_0_r01 1242 -#define _LOAD_SMALL_INT_0_r12 1243 -#define _LOAD_SMALL_INT_0_r23 1244 -#define _LOAD_SMALL_INT_1_r01 1245 -#define _LOAD_SMALL_INT_1_r12 1246 -#define _LOAD_SMALL_INT_1_r23 1247 -#define _LOAD_SMALL_INT_2_r01 1248 -#define _LOAD_SMALL_INT_2_r12 1249 -#define _LOAD_SMALL_INT_2_r23 1250 -#define _LOAD_SMALL_INT_3_r01 1251 -#define _LOAD_SMALL_INT_3_r12 1252 -#define _LOAD_SMALL_INT_3_r23 1253 -#define _LOAD_SPECIAL_r00 1254 -#define _LOAD_SUPER_ATTR_ATTR_r31 1255 -#define _LOAD_SUPER_ATTR_METHOD_r32 1256 -#define _MAKE_CALLARGS_A_TUPLE_r33 1257 -#define _MAKE_CELL_r00 1258 -#define _MAKE_FUNCTION_r11 1259 -#define _MAKE_HEAP_SAFE_r01 1260 -#define _MAKE_HEAP_SAFE_r11 1261 -#define _MAKE_HEAP_SAFE_r22 1262 -#define _MAKE_HEAP_SAFE_r33 1263 -#define _MAKE_WARM_r00 1264 -#define _MAKE_WARM_r11 1265 -#define _MAKE_WARM_r22 1266 -#define _MAKE_WARM_r33 1267 -#define _MAP_ADD_r20 1268 -#define _MATCH_CLASS_r31 1269 -#define _MATCH_KEYS_r23 1270 -#define _MATCH_MAPPING_r02 1271 -#define _MATCH_MAPPING_r12 1272 -#define _MATCH_MAPPING_r23 1273 -#define _MATCH_SEQUENCE_r02 1274 -#define _MATCH_SEQUENCE_r12 1275 -#define _MATCH_SEQUENCE_r23 1276 -#define _MAYBE_EXPAND_METHOD_r00 1277 -#define _MAYBE_EXPAND_METHOD_KW_r11 1278 -#define _MONITOR_CALL_r00 1279 -#define _MONITOR_CALL_KW_r11 1280 -#define _MONITOR_JUMP_BACKWARD_r00 1281 -#define _MONITOR_JUMP_BACKWARD_r11 1282 -#define _MONITOR_JUMP_BACKWARD_r22 1283 -#define _MONITOR_JUMP_BACKWARD_r33 1284 -#define _MONITOR_RESUME_r00 1285 -#define _NOP_r00 1286 -#define _NOP_r11 1287 -#define _NOP_r22 1288 -#define _NOP_r33 1289 -#define _POP_CALL_r20 1290 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1291 -#define _POP_CALL_ONE_r30 1292 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1293 -#define _POP_CALL_TWO_r30 1294 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1295 -#define _POP_EXCEPT_r10 1296 -#define _POP_ITER_r20 1297 -#define _POP_JUMP_IF_FALSE_r00 1298 -#define _POP_JUMP_IF_FALSE_r10 1299 -#define _POP_JUMP_IF_FALSE_r21 1300 -#define _POP_JUMP_IF_FALSE_r32 1301 -#define _POP_JUMP_IF_TRUE_r00 1302 -#define _POP_JUMP_IF_TRUE_r10 1303 -#define _POP_JUMP_IF_TRUE_r21 1304 -#define _POP_JUMP_IF_TRUE_r32 1305 -#define _POP_TOP_r10 1306 -#define _POP_TOP_FLOAT_r00 1307 -#define _POP_TOP_FLOAT_r10 1308 -#define _POP_TOP_FLOAT_r21 1309 -#define _POP_TOP_FLOAT_r32 1310 -#define _POP_TOP_INT_r00 1311 -#define _POP_TOP_INT_r10 1312 -#define _POP_TOP_INT_r21 1313 -#define _POP_TOP_INT_r32 1314 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1315 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1316 -#define _POP_TOP_NOP_r00 1317 -#define _POP_TOP_NOP_r10 1318 -#define _POP_TOP_NOP_r21 1319 -#define _POP_TOP_NOP_r32 1320 -#define _POP_TOP_UNICODE_r00 1321 -#define _POP_TOP_UNICODE_r10 1322 -#define _POP_TOP_UNICODE_r21 1323 -#define _POP_TOP_UNICODE_r32 1324 -#define _POP_TWO_r20 1325 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1326 -#define _PUSH_EXC_INFO_r02 1327 -#define _PUSH_EXC_INFO_r12 1328 -#define _PUSH_EXC_INFO_r23 1329 -#define _PUSH_FRAME_r10 1330 -#define _PUSH_NULL_r01 1331 -#define _PUSH_NULL_r12 1332 -#define _PUSH_NULL_r23 1333 -#define _PUSH_NULL_CONDITIONAL_r00 1334 -#define _PY_FRAME_EX_r31 1335 -#define _PY_FRAME_GENERAL_r01 1336 -#define _PY_FRAME_KW_r11 1337 -#define _QUICKEN_RESUME_r00 1338 -#define _QUICKEN_RESUME_r11 1339 -#define _QUICKEN_RESUME_r22 1340 -#define _QUICKEN_RESUME_r33 1341 -#define _REPLACE_WITH_TRUE_r02 1342 -#define _REPLACE_WITH_TRUE_r12 1343 -#define _REPLACE_WITH_TRUE_r23 1344 -#define _RESUME_CHECK_r00 1345 -#define _RESUME_CHECK_r11 1346 -#define _RESUME_CHECK_r22 1347 -#define _RESUME_CHECK_r33 1348 -#define _RETURN_GENERATOR_r01 1349 -#define _RETURN_VALUE_r11 1350 -#define _SAVE_RETURN_OFFSET_r00 1351 -#define _SAVE_RETURN_OFFSET_r11 1352 -#define _SAVE_RETURN_OFFSET_r22 1353 -#define _SAVE_RETURN_OFFSET_r33 1354 -#define _SEND_r22 1355 -#define _SEND_GEN_FRAME_r22 1356 -#define _SETUP_ANNOTATIONS_r00 1357 -#define _SET_ADD_r10 1358 -#define _SET_FUNCTION_ATTRIBUTE_r01 1359 -#define _SET_FUNCTION_ATTRIBUTE_r11 1360 -#define _SET_FUNCTION_ATTRIBUTE_r21 1361 -#define _SET_FUNCTION_ATTRIBUTE_r32 1362 -#define _SET_IP_r00 1363 -#define _SET_IP_r11 1364 -#define _SET_IP_r22 1365 -#define _SET_IP_r33 1366 -#define _SET_UPDATE_r10 1367 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1368 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1369 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1370 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1371 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1372 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1373 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1374 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1375 -#define _SPILL_OR_RELOAD_r01 1376 -#define _SPILL_OR_RELOAD_r02 1377 -#define _SPILL_OR_RELOAD_r03 1378 -#define _SPILL_OR_RELOAD_r10 1379 -#define _SPILL_OR_RELOAD_r12 1380 -#define _SPILL_OR_RELOAD_r13 1381 -#define _SPILL_OR_RELOAD_r20 1382 -#define _SPILL_OR_RELOAD_r21 1383 -#define _SPILL_OR_RELOAD_r23 1384 -#define _SPILL_OR_RELOAD_r30 1385 -#define _SPILL_OR_RELOAD_r31 1386 -#define _SPILL_OR_RELOAD_r32 1387 -#define _START_EXECUTOR_r00 1388 -#define _STORE_ATTR_r20 1389 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1390 -#define _STORE_ATTR_SLOT_r21 1391 -#define _STORE_ATTR_WITH_HINT_r21 1392 -#define _STORE_DEREF_r10 1393 -#define _STORE_FAST_LOAD_FAST_r11 1394 -#define _STORE_FAST_STORE_FAST_r20 1395 -#define _STORE_GLOBAL_r10 1396 -#define _STORE_NAME_r10 1397 -#define _STORE_SLICE_r30 1398 -#define _STORE_SUBSCR_r30 1399 -#define _STORE_SUBSCR_DICT_r31 1400 -#define _STORE_SUBSCR_LIST_INT_r32 1401 -#define _SWAP_r11 1402 -#define _SWAP_2_r02 1403 -#define _SWAP_2_r12 1404 -#define _SWAP_2_r22 1405 -#define _SWAP_2_r33 1406 -#define _SWAP_3_r03 1407 -#define _SWAP_3_r13 1408 -#define _SWAP_3_r23 1409 -#define _SWAP_3_r33 1410 -#define _SWAP_FAST_r01 1411 -#define _SWAP_FAST_r11 1412 -#define _SWAP_FAST_r22 1413 -#define _SWAP_FAST_r33 1414 -#define _SWAP_FAST_0_r01 1415 -#define _SWAP_FAST_0_r11 1416 -#define _SWAP_FAST_0_r22 1417 -#define _SWAP_FAST_0_r33 1418 -#define _SWAP_FAST_1_r01 1419 -#define _SWAP_FAST_1_r11 1420 -#define _SWAP_FAST_1_r22 1421 -#define _SWAP_FAST_1_r33 1422 -#define _SWAP_FAST_2_r01 1423 -#define _SWAP_FAST_2_r11 1424 -#define _SWAP_FAST_2_r22 1425 -#define _SWAP_FAST_2_r33 1426 -#define _SWAP_FAST_3_r01 1427 -#define _SWAP_FAST_3_r11 1428 -#define _SWAP_FAST_3_r22 1429 -#define _SWAP_FAST_3_r33 1430 -#define _SWAP_FAST_4_r01 1431 -#define _SWAP_FAST_4_r11 1432 -#define _SWAP_FAST_4_r22 1433 -#define _SWAP_FAST_4_r33 1434 -#define _SWAP_FAST_5_r01 1435 -#define _SWAP_FAST_5_r11 1436 -#define _SWAP_FAST_5_r22 1437 -#define _SWAP_FAST_5_r33 1438 -#define _SWAP_FAST_6_r01 1439 -#define _SWAP_FAST_6_r11 1440 -#define _SWAP_FAST_6_r22 1441 -#define _SWAP_FAST_6_r33 1442 -#define _SWAP_FAST_7_r01 1443 -#define _SWAP_FAST_7_r11 1444 -#define _SWAP_FAST_7_r22 1445 -#define _SWAP_FAST_7_r33 1446 -#define _TIER2_RESUME_CHECK_r00 1447 -#define _TIER2_RESUME_CHECK_r11 1448 -#define _TIER2_RESUME_CHECK_r22 1449 -#define _TIER2_RESUME_CHECK_r33 1450 -#define _TO_BOOL_r11 1451 -#define _TO_BOOL_BOOL_r01 1452 -#define _TO_BOOL_BOOL_r11 1453 -#define _TO_BOOL_BOOL_r22 1454 -#define _TO_BOOL_BOOL_r33 1455 -#define _TO_BOOL_INT_r02 1456 -#define _TO_BOOL_INT_r12 1457 -#define _TO_BOOL_INT_r23 1458 -#define _TO_BOOL_LIST_r02 1459 -#define _TO_BOOL_LIST_r12 1460 -#define _TO_BOOL_LIST_r23 1461 -#define _TO_BOOL_NONE_r01 1462 -#define _TO_BOOL_NONE_r11 1463 -#define _TO_BOOL_NONE_r22 1464 -#define _TO_BOOL_NONE_r33 1465 -#define _TO_BOOL_STR_r02 1466 -#define _TO_BOOL_STR_r12 1467 -#define _TO_BOOL_STR_r23 1468 -#define _TRACE_RECORD_r00 1469 -#define _UNARY_INVERT_r12 1470 -#define _UNARY_NEGATIVE_r12 1471 -#define _UNARY_NOT_r01 1472 -#define _UNARY_NOT_r11 1473 -#define _UNARY_NOT_r22 1474 -#define _UNARY_NOT_r33 1475 -#define _UNPACK_EX_r10 1476 -#define _UNPACK_SEQUENCE_r10 1477 -#define _UNPACK_SEQUENCE_LIST_r10 1478 -#define _UNPACK_SEQUENCE_TUPLE_r10 1479 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1480 -#define _WITH_EXCEPT_START_r33 1481 -#define _YIELD_VALUE_r11 1482 -#define MAX_UOP_REGS_ID 1482 +#define _YIELD_VALUE 597 +#define MAX_UOP_ID 597 +#define _BINARY_OP_r23 598 +#define _BINARY_OP_ADD_FLOAT_r03 599 +#define _BINARY_OP_ADD_FLOAT_r13 600 +#define _BINARY_OP_ADD_FLOAT_r23 601 +#define _BINARY_OP_ADD_INT_r03 602 +#define _BINARY_OP_ADD_INT_r13 603 +#define _BINARY_OP_ADD_INT_r23 604 +#define _BINARY_OP_ADD_UNICODE_r03 605 +#define _BINARY_OP_ADD_UNICODE_r13 606 +#define _BINARY_OP_ADD_UNICODE_r23 607 +#define _BINARY_OP_EXTEND_r23 608 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 609 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 610 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 611 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 612 +#define _BINARY_OP_MULTIPLY_INT_r03 613 +#define _BINARY_OP_MULTIPLY_INT_r13 614 +#define _BINARY_OP_MULTIPLY_INT_r23 615 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 616 +#define _BINARY_OP_SUBSCR_DICT_r23 617 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 618 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 619 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 620 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 621 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 622 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 623 +#define _BINARY_OP_SUBSCR_STR_INT_r23 624 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 625 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 626 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 627 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 628 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 629 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 630 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 631 +#define _BINARY_OP_SUBTRACT_INT_r03 632 +#define _BINARY_OP_SUBTRACT_INT_r13 633 +#define _BINARY_OP_SUBTRACT_INT_r23 634 +#define _BINARY_SLICE_r31 635 +#define _BUILD_INTERPOLATION_r01 636 +#define _BUILD_LIST_r01 637 +#define _BUILD_MAP_r01 638 +#define _BUILD_SET_r01 639 +#define _BUILD_SLICE_r01 640 +#define _BUILD_STRING_r01 641 +#define _BUILD_TEMPLATE_r21 642 +#define _BUILD_TUPLE_r01 643 +#define _CALL_BUILTIN_CLASS_r01 644 +#define _CALL_BUILTIN_FAST_r01 645 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 646 +#define _CALL_BUILTIN_O_r03 647 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 648 +#define _CALL_INTRINSIC_1_r11 649 +#define _CALL_INTRINSIC_2_r21 650 +#define _CALL_ISINSTANCE_r31 651 +#define _CALL_KW_NON_PY_r11 652 +#define _CALL_LEN_r33 653 +#define _CALL_LIST_APPEND_r03 654 +#define _CALL_LIST_APPEND_r13 655 +#define _CALL_LIST_APPEND_r23 656 +#define _CALL_LIST_APPEND_r33 657 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 658 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 659 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 660 +#define _CALL_METHOD_DESCRIPTOR_O_r03 661 +#define _CALL_NON_PY_GENERAL_r01 662 +#define _CALL_STR_1_r32 663 +#define _CALL_TUPLE_1_r32 664 +#define _CALL_TYPE_1_r02 665 +#define _CALL_TYPE_1_r12 666 +#define _CALL_TYPE_1_r22 667 +#define _CALL_TYPE_1_r32 668 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 669 +#define _CHECK_ATTR_CLASS_r01 670 +#define _CHECK_ATTR_CLASS_r11 671 +#define _CHECK_ATTR_CLASS_r22 672 +#define _CHECK_ATTR_CLASS_r33 673 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 674 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 675 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 676 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 677 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 678 +#define _CHECK_EG_MATCH_r22 679 +#define _CHECK_EXC_MATCH_r22 680 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 681 +#define _CHECK_FUNCTION_VERSION_r00 682 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 683 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 684 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 685 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 686 +#define _CHECK_FUNCTION_VERSION_KW_r11 687 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 688 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 689 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 690 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 691 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 692 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 693 +#define _CHECK_IS_PY_CALLABLE_EX_r03 694 +#define _CHECK_IS_PY_CALLABLE_EX_r13 695 +#define _CHECK_IS_PY_CALLABLE_EX_r23 696 +#define _CHECK_IS_PY_CALLABLE_EX_r33 697 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 698 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 699 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 700 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 701 +#define _CHECK_METHOD_VERSION_r00 702 +#define _CHECK_METHOD_VERSION_KW_r11 703 +#define _CHECK_PEP_523_r00 704 +#define _CHECK_PEP_523_r11 705 +#define _CHECK_PEP_523_r22 706 +#define _CHECK_PEP_523_r33 707 +#define _CHECK_PERIODIC_r00 708 +#define _CHECK_PERIODIC_AT_END_r00 709 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 710 +#define _CHECK_RECURSION_REMAINING_r00 711 +#define _CHECK_RECURSION_REMAINING_r11 712 +#define _CHECK_RECURSION_REMAINING_r22 713 +#define _CHECK_RECURSION_REMAINING_r33 714 +#define _CHECK_STACK_SPACE_r00 715 +#define _CHECK_STACK_SPACE_OPERAND_r00 716 +#define _CHECK_STACK_SPACE_OPERAND_r11 717 +#define _CHECK_STACK_SPACE_OPERAND_r22 718 +#define _CHECK_STACK_SPACE_OPERAND_r33 719 +#define _CHECK_VALIDITY_r00 720 +#define _CHECK_VALIDITY_r11 721 +#define _CHECK_VALIDITY_r22 722 +#define _CHECK_VALIDITY_r33 723 +#define _COLD_DYNAMIC_EXIT_r00 724 +#define _COLD_EXIT_r00 725 +#define _COMPARE_OP_r21 726 +#define _COMPARE_OP_FLOAT_r03 727 +#define _COMPARE_OP_FLOAT_r13 728 +#define _COMPARE_OP_FLOAT_r23 729 +#define _COMPARE_OP_INT_r23 730 +#define _COMPARE_OP_STR_r23 731 +#define _CONTAINS_OP_r23 732 +#define _CONTAINS_OP_DICT_r23 733 +#define _CONTAINS_OP_SET_r23 734 +#define _CONVERT_VALUE_r11 735 +#define _COPY_r01 736 +#define _COPY_1_r02 737 +#define _COPY_1_r12 738 +#define _COPY_1_r23 739 +#define _COPY_2_r03 740 +#define _COPY_2_r13 741 +#define _COPY_2_r23 742 +#define _COPY_3_r03 743 +#define _COPY_3_r13 744 +#define _COPY_3_r23 745 +#define _COPY_3_r33 746 +#define _COPY_FREE_VARS_r00 747 +#define _COPY_FREE_VARS_r11 748 +#define _COPY_FREE_VARS_r22 749 +#define _COPY_FREE_VARS_r33 750 +#define _CREATE_INIT_FRAME_r01 751 +#define _DELETE_ATTR_r10 752 +#define _DELETE_DEREF_r00 753 +#define _DELETE_FAST_r00 754 +#define _DELETE_GLOBAL_r00 755 +#define _DELETE_NAME_r00 756 +#define _DELETE_SUBSCR_r20 757 +#define _DEOPT_r00 758 +#define _DEOPT_r10 759 +#define _DEOPT_r20 760 +#define _DEOPT_r30 761 +#define _DICT_MERGE_r10 762 +#define _DICT_UPDATE_r10 763 +#define _DO_CALL_r01 764 +#define _DO_CALL_FUNCTION_EX_r31 765 +#define _DO_CALL_KW_r11 766 +#define _DYNAMIC_EXIT_r00 767 +#define _DYNAMIC_EXIT_r10 768 +#define _DYNAMIC_EXIT_r20 769 +#define _DYNAMIC_EXIT_r30 770 +#define _END_FOR_r10 771 +#define _END_SEND_r21 772 +#define _ERROR_POP_N_r00 773 +#define _EXIT_INIT_CHECK_r10 774 +#define _EXIT_TRACE_r00 775 +#define _EXIT_TRACE_r10 776 +#define _EXIT_TRACE_r20 777 +#define _EXIT_TRACE_r30 778 +#define _EXPAND_METHOD_r00 779 +#define _EXPAND_METHOD_KW_r11 780 +#define _FATAL_ERROR_r00 781 +#define _FATAL_ERROR_r11 782 +#define _FATAL_ERROR_r22 783 +#define _FATAL_ERROR_r33 784 +#define _FORMAT_SIMPLE_r11 785 +#define _FORMAT_WITH_SPEC_r21 786 +#define _FOR_ITER_r23 787 +#define _FOR_ITER_GEN_FRAME_r03 788 +#define _FOR_ITER_GEN_FRAME_r13 789 +#define _FOR_ITER_GEN_FRAME_r23 790 +#define _FOR_ITER_TIER_TWO_r23 791 +#define _GET_AITER_r11 792 +#define _GET_ANEXT_r12 793 +#define _GET_AWAITABLE_r11 794 +#define _GET_ITER_r12 795 +#define _GET_LEN_r12 796 +#define _GET_YIELD_FROM_ITER_r11 797 +#define _GUARD_BINARY_OP_EXTEND_r22 798 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 799 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 800 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 801 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 802 +#define _GUARD_BIT_IS_SET_POP_r00 803 +#define _GUARD_BIT_IS_SET_POP_r10 804 +#define _GUARD_BIT_IS_SET_POP_r21 805 +#define _GUARD_BIT_IS_SET_POP_r32 806 +#define _GUARD_BIT_IS_SET_POP_4_r00 807 +#define _GUARD_BIT_IS_SET_POP_4_r10 808 +#define _GUARD_BIT_IS_SET_POP_4_r21 809 +#define _GUARD_BIT_IS_SET_POP_4_r32 810 +#define _GUARD_BIT_IS_SET_POP_5_r00 811 +#define _GUARD_BIT_IS_SET_POP_5_r10 812 +#define _GUARD_BIT_IS_SET_POP_5_r21 813 +#define _GUARD_BIT_IS_SET_POP_5_r32 814 +#define _GUARD_BIT_IS_SET_POP_6_r00 815 +#define _GUARD_BIT_IS_SET_POP_6_r10 816 +#define _GUARD_BIT_IS_SET_POP_6_r21 817 +#define _GUARD_BIT_IS_SET_POP_6_r32 818 +#define _GUARD_BIT_IS_SET_POP_7_r00 819 +#define _GUARD_BIT_IS_SET_POP_7_r10 820 +#define _GUARD_BIT_IS_SET_POP_7_r21 821 +#define _GUARD_BIT_IS_SET_POP_7_r32 822 +#define _GUARD_BIT_IS_UNSET_POP_r00 823 +#define _GUARD_BIT_IS_UNSET_POP_r10 824 +#define _GUARD_BIT_IS_UNSET_POP_r21 825 +#define _GUARD_BIT_IS_UNSET_POP_r32 826 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 827 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 828 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 829 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 830 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 831 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 832 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 833 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 834 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 835 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 836 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 837 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 838 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 839 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 840 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 841 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 842 +#define _GUARD_CALLABLE_ISINSTANCE_r03 843 +#define _GUARD_CALLABLE_ISINSTANCE_r13 844 +#define _GUARD_CALLABLE_ISINSTANCE_r23 845 +#define _GUARD_CALLABLE_ISINSTANCE_r33 846 +#define _GUARD_CALLABLE_LEN_r03 847 +#define _GUARD_CALLABLE_LEN_r13 848 +#define _GUARD_CALLABLE_LEN_r23 849 +#define _GUARD_CALLABLE_LEN_r33 850 +#define _GUARD_CALLABLE_LIST_APPEND_r03 851 +#define _GUARD_CALLABLE_LIST_APPEND_r13 852 +#define _GUARD_CALLABLE_LIST_APPEND_r23 853 +#define _GUARD_CALLABLE_LIST_APPEND_r33 854 +#define _GUARD_CALLABLE_STR_1_r03 855 +#define _GUARD_CALLABLE_STR_1_r13 856 +#define _GUARD_CALLABLE_STR_1_r23 857 +#define _GUARD_CALLABLE_STR_1_r33 858 +#define _GUARD_CALLABLE_TUPLE_1_r03 859 +#define _GUARD_CALLABLE_TUPLE_1_r13 860 +#define _GUARD_CALLABLE_TUPLE_1_r23 861 +#define _GUARD_CALLABLE_TUPLE_1_r33 862 +#define _GUARD_CALLABLE_TYPE_1_r03 863 +#define _GUARD_CALLABLE_TYPE_1_r13 864 +#define _GUARD_CALLABLE_TYPE_1_r23 865 +#define _GUARD_CALLABLE_TYPE_1_r33 866 +#define _GUARD_CODE_VERSION_r00 867 +#define _GUARD_CODE_VERSION_r11 868 +#define _GUARD_CODE_VERSION_r22 869 +#define _GUARD_CODE_VERSION_r33 870 +#define _GUARD_DORV_NO_DICT_r01 871 +#define _GUARD_DORV_NO_DICT_r11 872 +#define _GUARD_DORV_NO_DICT_r22 873 +#define _GUARD_DORV_NO_DICT_r33 874 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 875 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 876 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 877 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 878 +#define _GUARD_GLOBALS_VERSION_r00 879 +#define _GUARD_GLOBALS_VERSION_r11 880 +#define _GUARD_GLOBALS_VERSION_r22 881 +#define _GUARD_GLOBALS_VERSION_r33 882 +#define _GUARD_IP_RETURN_GENERATOR_r00 883 +#define _GUARD_IP_RETURN_GENERATOR_r11 884 +#define _GUARD_IP_RETURN_GENERATOR_r22 885 +#define _GUARD_IP_RETURN_GENERATOR_r33 886 +#define _GUARD_IP_RETURN_VALUE_r00 887 +#define _GUARD_IP_RETURN_VALUE_r11 888 +#define _GUARD_IP_RETURN_VALUE_r22 889 +#define _GUARD_IP_RETURN_VALUE_r33 890 +#define _GUARD_IP_YIELD_VALUE_r00 891 +#define _GUARD_IP_YIELD_VALUE_r11 892 +#define _GUARD_IP_YIELD_VALUE_r22 893 +#define _GUARD_IP_YIELD_VALUE_r33 894 +#define _GUARD_IP__PUSH_FRAME_r00 895 +#define _GUARD_IP__PUSH_FRAME_r11 896 +#define _GUARD_IP__PUSH_FRAME_r22 897 +#define _GUARD_IP__PUSH_FRAME_r33 898 +#define _GUARD_IS_FALSE_POP_r00 899 +#define _GUARD_IS_FALSE_POP_r10 900 +#define _GUARD_IS_FALSE_POP_r21 901 +#define _GUARD_IS_FALSE_POP_r32 902 +#define _GUARD_IS_NONE_POP_r00 903 +#define _GUARD_IS_NONE_POP_r10 904 +#define _GUARD_IS_NONE_POP_r21 905 +#define _GUARD_IS_NONE_POP_r32 906 +#define _GUARD_IS_NOT_NONE_POP_r10 907 +#define _GUARD_IS_TRUE_POP_r00 908 +#define _GUARD_IS_TRUE_POP_r10 909 +#define _GUARD_IS_TRUE_POP_r21 910 +#define _GUARD_IS_TRUE_POP_r32 911 +#define _GUARD_KEYS_VERSION_r01 912 +#define _GUARD_KEYS_VERSION_r11 913 +#define _GUARD_KEYS_VERSION_r22 914 +#define _GUARD_KEYS_VERSION_r33 915 +#define _GUARD_NOS_ANY_DICT_r02 916 +#define _GUARD_NOS_ANY_DICT_r12 917 +#define _GUARD_NOS_ANY_DICT_r22 918 +#define _GUARD_NOS_ANY_DICT_r33 919 +#define _GUARD_NOS_COMPACT_ASCII_r02 920 +#define _GUARD_NOS_COMPACT_ASCII_r12 921 +#define _GUARD_NOS_COMPACT_ASCII_r22 922 +#define _GUARD_NOS_COMPACT_ASCII_r33 923 +#define _GUARD_NOS_DICT_r02 924 +#define _GUARD_NOS_DICT_r12 925 +#define _GUARD_NOS_DICT_r22 926 +#define _GUARD_NOS_DICT_r33 927 +#define _GUARD_NOS_FLOAT_r02 928 +#define _GUARD_NOS_FLOAT_r12 929 +#define _GUARD_NOS_FLOAT_r22 930 +#define _GUARD_NOS_FLOAT_r33 931 +#define _GUARD_NOS_INT_r02 932 +#define _GUARD_NOS_INT_r12 933 +#define _GUARD_NOS_INT_r22 934 +#define _GUARD_NOS_INT_r33 935 +#define _GUARD_NOS_LIST_r02 936 +#define _GUARD_NOS_LIST_r12 937 +#define _GUARD_NOS_LIST_r22 938 +#define _GUARD_NOS_LIST_r33 939 +#define _GUARD_NOS_NOT_NULL_r02 940 +#define _GUARD_NOS_NOT_NULL_r12 941 +#define _GUARD_NOS_NOT_NULL_r22 942 +#define _GUARD_NOS_NOT_NULL_r33 943 +#define _GUARD_NOS_NULL_r02 944 +#define _GUARD_NOS_NULL_r12 945 +#define _GUARD_NOS_NULL_r22 946 +#define _GUARD_NOS_NULL_r33 947 +#define _GUARD_NOS_OVERFLOWED_r02 948 +#define _GUARD_NOS_OVERFLOWED_r12 949 +#define _GUARD_NOS_OVERFLOWED_r22 950 +#define _GUARD_NOS_OVERFLOWED_r33 951 +#define _GUARD_NOS_TUPLE_r02 952 +#define _GUARD_NOS_TUPLE_r12 953 +#define _GUARD_NOS_TUPLE_r22 954 +#define _GUARD_NOS_TUPLE_r33 955 +#define _GUARD_NOS_UNICODE_r02 956 +#define _GUARD_NOS_UNICODE_r12 957 +#define _GUARD_NOS_UNICODE_r22 958 +#define _GUARD_NOS_UNICODE_r33 959 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 960 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 961 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 962 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 963 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 964 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 965 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 966 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 967 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 968 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 969 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 970 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 971 +#define _GUARD_THIRD_NULL_r03 972 +#define _GUARD_THIRD_NULL_r13 973 +#define _GUARD_THIRD_NULL_r23 974 +#define _GUARD_THIRD_NULL_r33 975 +#define _GUARD_TOS_ANY_DICT_r01 976 +#define _GUARD_TOS_ANY_DICT_r11 977 +#define _GUARD_TOS_ANY_DICT_r22 978 +#define _GUARD_TOS_ANY_DICT_r33 979 +#define _GUARD_TOS_ANY_SET_r01 980 +#define _GUARD_TOS_ANY_SET_r11 981 +#define _GUARD_TOS_ANY_SET_r22 982 +#define _GUARD_TOS_ANY_SET_r33 983 +#define _GUARD_TOS_DICT_r01 984 +#define _GUARD_TOS_DICT_r11 985 +#define _GUARD_TOS_DICT_r22 986 +#define _GUARD_TOS_DICT_r33 987 +#define _GUARD_TOS_FLOAT_r01 988 +#define _GUARD_TOS_FLOAT_r11 989 +#define _GUARD_TOS_FLOAT_r22 990 +#define _GUARD_TOS_FLOAT_r33 991 +#define _GUARD_TOS_FROZENDICT_r01 992 +#define _GUARD_TOS_FROZENDICT_r11 993 +#define _GUARD_TOS_FROZENDICT_r22 994 +#define _GUARD_TOS_FROZENDICT_r33 995 +#define _GUARD_TOS_FROZENSET_r01 996 +#define _GUARD_TOS_FROZENSET_r11 997 +#define _GUARD_TOS_FROZENSET_r22 998 +#define _GUARD_TOS_FROZENSET_r33 999 +#define _GUARD_TOS_INT_r01 1000 +#define _GUARD_TOS_INT_r11 1001 +#define _GUARD_TOS_INT_r22 1002 +#define _GUARD_TOS_INT_r33 1003 +#define _GUARD_TOS_LIST_r01 1004 +#define _GUARD_TOS_LIST_r11 1005 +#define _GUARD_TOS_LIST_r22 1006 +#define _GUARD_TOS_LIST_r33 1007 +#define _GUARD_TOS_OVERFLOWED_r01 1008 +#define _GUARD_TOS_OVERFLOWED_r11 1009 +#define _GUARD_TOS_OVERFLOWED_r22 1010 +#define _GUARD_TOS_OVERFLOWED_r33 1011 +#define _GUARD_TOS_SET_r01 1012 +#define _GUARD_TOS_SET_r11 1013 +#define _GUARD_TOS_SET_r22 1014 +#define _GUARD_TOS_SET_r33 1015 +#define _GUARD_TOS_SLICE_r01 1016 +#define _GUARD_TOS_SLICE_r11 1017 +#define _GUARD_TOS_SLICE_r22 1018 +#define _GUARD_TOS_SLICE_r33 1019 +#define _GUARD_TOS_TUPLE_r01 1020 +#define _GUARD_TOS_TUPLE_r11 1021 +#define _GUARD_TOS_TUPLE_r22 1022 +#define _GUARD_TOS_TUPLE_r33 1023 +#define _GUARD_TOS_UNICODE_r01 1024 +#define _GUARD_TOS_UNICODE_r11 1025 +#define _GUARD_TOS_UNICODE_r22 1026 +#define _GUARD_TOS_UNICODE_r33 1027 +#define _GUARD_TYPE_VERSION_r01 1028 +#define _GUARD_TYPE_VERSION_r11 1029 +#define _GUARD_TYPE_VERSION_r22 1030 +#define _GUARD_TYPE_VERSION_r33 1031 +#define _GUARD_TYPE_VERSION_LOCKED_r01 1032 +#define _GUARD_TYPE_VERSION_LOCKED_r11 1033 +#define _GUARD_TYPE_VERSION_LOCKED_r22 1034 +#define _GUARD_TYPE_VERSION_LOCKED_r33 1035 +#define _HANDLE_PENDING_AND_DEOPT_r00 1036 +#define _HANDLE_PENDING_AND_DEOPT_r10 1037 +#define _HANDLE_PENDING_AND_DEOPT_r20 1038 +#define _HANDLE_PENDING_AND_DEOPT_r30 1039 +#define _IMPORT_FROM_r12 1040 +#define _IMPORT_NAME_r21 1041 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1042 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1043 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1044 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1045 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1046 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1047 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1048 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1049 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1050 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1051 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1052 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1053 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1054 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1055 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1056 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1057 +#define _INSERT_NULL_r10 1058 +#define _INSTRUMENTED_FOR_ITER_r23 1059 +#define _INSTRUMENTED_INSTRUCTION_r00 1060 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1061 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1062 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1063 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1064 +#define _INSTRUMENTED_LINE_r00 1065 +#define _INSTRUMENTED_NOT_TAKEN_r00 1066 +#define _INSTRUMENTED_NOT_TAKEN_r11 1067 +#define _INSTRUMENTED_NOT_TAKEN_r22 1068 +#define _INSTRUMENTED_NOT_TAKEN_r33 1069 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1070 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1071 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1072 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1073 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1074 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1075 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1076 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1077 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1078 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1079 +#define _IS_NONE_r11 1080 +#define _IS_OP_r03 1081 +#define _IS_OP_r13 1082 +#define _IS_OP_r23 1083 +#define _ITER_CHECK_LIST_r02 1084 +#define _ITER_CHECK_LIST_r12 1085 +#define _ITER_CHECK_LIST_r22 1086 +#define _ITER_CHECK_LIST_r33 1087 +#define _ITER_CHECK_RANGE_r02 1088 +#define _ITER_CHECK_RANGE_r12 1089 +#define _ITER_CHECK_RANGE_r22 1090 +#define _ITER_CHECK_RANGE_r33 1091 +#define _ITER_CHECK_TUPLE_r02 1092 +#define _ITER_CHECK_TUPLE_r12 1093 +#define _ITER_CHECK_TUPLE_r22 1094 +#define _ITER_CHECK_TUPLE_r33 1095 +#define _ITER_JUMP_LIST_r02 1096 +#define _ITER_JUMP_LIST_r12 1097 +#define _ITER_JUMP_LIST_r22 1098 +#define _ITER_JUMP_LIST_r33 1099 +#define _ITER_JUMP_RANGE_r02 1100 +#define _ITER_JUMP_RANGE_r12 1101 +#define _ITER_JUMP_RANGE_r22 1102 +#define _ITER_JUMP_RANGE_r33 1103 +#define _ITER_JUMP_TUPLE_r02 1104 +#define _ITER_JUMP_TUPLE_r12 1105 +#define _ITER_JUMP_TUPLE_r22 1106 +#define _ITER_JUMP_TUPLE_r33 1107 +#define _ITER_NEXT_LIST_r23 1108 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1109 +#define _ITER_NEXT_RANGE_r03 1110 +#define _ITER_NEXT_RANGE_r13 1111 +#define _ITER_NEXT_RANGE_r23 1112 +#define _ITER_NEXT_TUPLE_r03 1113 +#define _ITER_NEXT_TUPLE_r13 1114 +#define _ITER_NEXT_TUPLE_r23 1115 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1116 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1117 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1118 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1119 +#define _JUMP_TO_TOP_r00 1120 +#define _LIST_APPEND_r10 1121 +#define _LIST_EXTEND_r10 1122 +#define _LOAD_ATTR_r10 1123 +#define _LOAD_ATTR_CLASS_r11 1124 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1125 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1126 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1127 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1128 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1129 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1130 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1131 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1132 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1133 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1134 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1135 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1136 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1137 +#define _LOAD_ATTR_MODULE_r12 1138 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1139 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1140 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1141 +#define _LOAD_ATTR_SLOT_r02 1142 +#define _LOAD_ATTR_SLOT_r12 1143 +#define _LOAD_ATTR_SLOT_r23 1144 +#define _LOAD_ATTR_WITH_HINT_r12 1145 +#define _LOAD_BUILD_CLASS_r01 1146 +#define _LOAD_BYTECODE_r00 1147 +#define _LOAD_COMMON_CONSTANT_r01 1148 +#define _LOAD_COMMON_CONSTANT_r12 1149 +#define _LOAD_COMMON_CONSTANT_r23 1150 +#define _LOAD_CONST_r01 1151 +#define _LOAD_CONST_r12 1152 +#define _LOAD_CONST_r23 1153 +#define _LOAD_CONST_INLINE_r01 1154 +#define _LOAD_CONST_INLINE_r12 1155 +#define _LOAD_CONST_INLINE_r23 1156 +#define _LOAD_CONST_INLINE_BORROW_r01 1157 +#define _LOAD_CONST_INLINE_BORROW_r12 1158 +#define _LOAD_CONST_INLINE_BORROW_r23 1159 +#define _LOAD_CONST_UNDER_INLINE_r02 1160 +#define _LOAD_CONST_UNDER_INLINE_r12 1161 +#define _LOAD_CONST_UNDER_INLINE_r23 1162 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1163 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1164 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1165 +#define _LOAD_DEREF_r01 1166 +#define _LOAD_FAST_r01 1167 +#define _LOAD_FAST_r12 1168 +#define _LOAD_FAST_r23 1169 +#define _LOAD_FAST_0_r01 1170 +#define _LOAD_FAST_0_r12 1171 +#define _LOAD_FAST_0_r23 1172 +#define _LOAD_FAST_1_r01 1173 +#define _LOAD_FAST_1_r12 1174 +#define _LOAD_FAST_1_r23 1175 +#define _LOAD_FAST_2_r01 1176 +#define _LOAD_FAST_2_r12 1177 +#define _LOAD_FAST_2_r23 1178 +#define _LOAD_FAST_3_r01 1179 +#define _LOAD_FAST_3_r12 1180 +#define _LOAD_FAST_3_r23 1181 +#define _LOAD_FAST_4_r01 1182 +#define _LOAD_FAST_4_r12 1183 +#define _LOAD_FAST_4_r23 1184 +#define _LOAD_FAST_5_r01 1185 +#define _LOAD_FAST_5_r12 1186 +#define _LOAD_FAST_5_r23 1187 +#define _LOAD_FAST_6_r01 1188 +#define _LOAD_FAST_6_r12 1189 +#define _LOAD_FAST_6_r23 1190 +#define _LOAD_FAST_7_r01 1191 +#define _LOAD_FAST_7_r12 1192 +#define _LOAD_FAST_7_r23 1193 +#define _LOAD_FAST_AND_CLEAR_r01 1194 +#define _LOAD_FAST_AND_CLEAR_r12 1195 +#define _LOAD_FAST_AND_CLEAR_r23 1196 +#define _LOAD_FAST_BORROW_r01 1197 +#define _LOAD_FAST_BORROW_r12 1198 +#define _LOAD_FAST_BORROW_r23 1199 +#define _LOAD_FAST_BORROW_0_r01 1200 +#define _LOAD_FAST_BORROW_0_r12 1201 +#define _LOAD_FAST_BORROW_0_r23 1202 +#define _LOAD_FAST_BORROW_1_r01 1203 +#define _LOAD_FAST_BORROW_1_r12 1204 +#define _LOAD_FAST_BORROW_1_r23 1205 +#define _LOAD_FAST_BORROW_2_r01 1206 +#define _LOAD_FAST_BORROW_2_r12 1207 +#define _LOAD_FAST_BORROW_2_r23 1208 +#define _LOAD_FAST_BORROW_3_r01 1209 +#define _LOAD_FAST_BORROW_3_r12 1210 +#define _LOAD_FAST_BORROW_3_r23 1211 +#define _LOAD_FAST_BORROW_4_r01 1212 +#define _LOAD_FAST_BORROW_4_r12 1213 +#define _LOAD_FAST_BORROW_4_r23 1214 +#define _LOAD_FAST_BORROW_5_r01 1215 +#define _LOAD_FAST_BORROW_5_r12 1216 +#define _LOAD_FAST_BORROW_5_r23 1217 +#define _LOAD_FAST_BORROW_6_r01 1218 +#define _LOAD_FAST_BORROW_6_r12 1219 +#define _LOAD_FAST_BORROW_6_r23 1220 +#define _LOAD_FAST_BORROW_7_r01 1221 +#define _LOAD_FAST_BORROW_7_r12 1222 +#define _LOAD_FAST_BORROW_7_r23 1223 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1224 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1225 +#define _LOAD_FAST_CHECK_r01 1226 +#define _LOAD_FAST_CHECK_r12 1227 +#define _LOAD_FAST_CHECK_r23 1228 +#define _LOAD_FAST_LOAD_FAST_r02 1229 +#define _LOAD_FAST_LOAD_FAST_r13 1230 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1231 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1232 +#define _LOAD_GLOBAL_r00 1233 +#define _LOAD_GLOBAL_BUILTINS_r01 1234 +#define _LOAD_GLOBAL_MODULE_r01 1235 +#define _LOAD_LOCALS_r01 1236 +#define _LOAD_LOCALS_r12 1237 +#define _LOAD_LOCALS_r23 1238 +#define _LOAD_NAME_r01 1239 +#define _LOAD_SMALL_INT_r01 1240 +#define _LOAD_SMALL_INT_r12 1241 +#define _LOAD_SMALL_INT_r23 1242 +#define _LOAD_SMALL_INT_0_r01 1243 +#define _LOAD_SMALL_INT_0_r12 1244 +#define _LOAD_SMALL_INT_0_r23 1245 +#define _LOAD_SMALL_INT_1_r01 1246 +#define _LOAD_SMALL_INT_1_r12 1247 +#define _LOAD_SMALL_INT_1_r23 1248 +#define _LOAD_SMALL_INT_2_r01 1249 +#define _LOAD_SMALL_INT_2_r12 1250 +#define _LOAD_SMALL_INT_2_r23 1251 +#define _LOAD_SMALL_INT_3_r01 1252 +#define _LOAD_SMALL_INT_3_r12 1253 +#define _LOAD_SMALL_INT_3_r23 1254 +#define _LOAD_SPECIAL_r00 1255 +#define _LOAD_SUPER_ATTR_ATTR_r31 1256 +#define _LOAD_SUPER_ATTR_METHOD_r32 1257 +#define _LOCK_OBJECT_r01 1258 +#define _LOCK_OBJECT_r11 1259 +#define _LOCK_OBJECT_r22 1260 +#define _LOCK_OBJECT_r33 1261 +#define _MAKE_CALLARGS_A_TUPLE_r33 1262 +#define _MAKE_CELL_r00 1263 +#define _MAKE_FUNCTION_r11 1264 +#define _MAKE_HEAP_SAFE_r01 1265 +#define _MAKE_HEAP_SAFE_r11 1266 +#define _MAKE_HEAP_SAFE_r22 1267 +#define _MAKE_HEAP_SAFE_r33 1268 +#define _MAKE_WARM_r00 1269 +#define _MAKE_WARM_r11 1270 +#define _MAKE_WARM_r22 1271 +#define _MAKE_WARM_r33 1272 +#define _MAP_ADD_r20 1273 +#define _MATCH_CLASS_r31 1274 +#define _MATCH_KEYS_r23 1275 +#define _MATCH_MAPPING_r02 1276 +#define _MATCH_MAPPING_r12 1277 +#define _MATCH_MAPPING_r23 1278 +#define _MATCH_SEQUENCE_r02 1279 +#define _MATCH_SEQUENCE_r12 1280 +#define _MATCH_SEQUENCE_r23 1281 +#define _MAYBE_EXPAND_METHOD_r00 1282 +#define _MAYBE_EXPAND_METHOD_KW_r11 1283 +#define _MONITOR_CALL_r00 1284 +#define _MONITOR_CALL_KW_r11 1285 +#define _MONITOR_JUMP_BACKWARD_r00 1286 +#define _MONITOR_JUMP_BACKWARD_r11 1287 +#define _MONITOR_JUMP_BACKWARD_r22 1288 +#define _MONITOR_JUMP_BACKWARD_r33 1289 +#define _MONITOR_RESUME_r00 1290 +#define _NOP_r00 1291 +#define _NOP_r11 1292 +#define _NOP_r22 1293 +#define _NOP_r33 1294 +#define _POP_CALL_r20 1295 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1296 +#define _POP_CALL_ONE_r30 1297 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1298 +#define _POP_CALL_TWO_r30 1299 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1300 +#define _POP_EXCEPT_r10 1301 +#define _POP_ITER_r20 1302 +#define _POP_JUMP_IF_FALSE_r00 1303 +#define _POP_JUMP_IF_FALSE_r10 1304 +#define _POP_JUMP_IF_FALSE_r21 1305 +#define _POP_JUMP_IF_FALSE_r32 1306 +#define _POP_JUMP_IF_TRUE_r00 1307 +#define _POP_JUMP_IF_TRUE_r10 1308 +#define _POP_JUMP_IF_TRUE_r21 1309 +#define _POP_JUMP_IF_TRUE_r32 1310 +#define _POP_TOP_r10 1311 +#define _POP_TOP_FLOAT_r00 1312 +#define _POP_TOP_FLOAT_r10 1313 +#define _POP_TOP_FLOAT_r21 1314 +#define _POP_TOP_FLOAT_r32 1315 +#define _POP_TOP_INT_r00 1316 +#define _POP_TOP_INT_r10 1317 +#define _POP_TOP_INT_r21 1318 +#define _POP_TOP_INT_r32 1319 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1320 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1321 +#define _POP_TOP_NOP_r00 1322 +#define _POP_TOP_NOP_r10 1323 +#define _POP_TOP_NOP_r21 1324 +#define _POP_TOP_NOP_r32 1325 +#define _POP_TOP_UNICODE_r00 1326 +#define _POP_TOP_UNICODE_r10 1327 +#define _POP_TOP_UNICODE_r21 1328 +#define _POP_TOP_UNICODE_r32 1329 +#define _POP_TWO_r20 1330 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1331 +#define _PUSH_EXC_INFO_r02 1332 +#define _PUSH_EXC_INFO_r12 1333 +#define _PUSH_EXC_INFO_r23 1334 +#define _PUSH_FRAME_r10 1335 +#define _PUSH_NULL_r01 1336 +#define _PUSH_NULL_r12 1337 +#define _PUSH_NULL_r23 1338 +#define _PUSH_NULL_CONDITIONAL_r00 1339 +#define _PY_FRAME_EX_r31 1340 +#define _PY_FRAME_GENERAL_r01 1341 +#define _PY_FRAME_KW_r11 1342 +#define _QUICKEN_RESUME_r00 1343 +#define _QUICKEN_RESUME_r11 1344 +#define _QUICKEN_RESUME_r22 1345 +#define _QUICKEN_RESUME_r33 1346 +#define _REPLACE_WITH_TRUE_r02 1347 +#define _REPLACE_WITH_TRUE_r12 1348 +#define _REPLACE_WITH_TRUE_r23 1349 +#define _RESUME_CHECK_r00 1350 +#define _RESUME_CHECK_r11 1351 +#define _RESUME_CHECK_r22 1352 +#define _RESUME_CHECK_r33 1353 +#define _RETURN_GENERATOR_r01 1354 +#define _RETURN_VALUE_r11 1355 +#define _SAVE_RETURN_OFFSET_r00 1356 +#define _SAVE_RETURN_OFFSET_r11 1357 +#define _SAVE_RETURN_OFFSET_r22 1358 +#define _SAVE_RETURN_OFFSET_r33 1359 +#define _SEND_r22 1360 +#define _SEND_GEN_FRAME_r22 1361 +#define _SETUP_ANNOTATIONS_r00 1362 +#define _SET_ADD_r10 1363 +#define _SET_FUNCTION_ATTRIBUTE_r01 1364 +#define _SET_FUNCTION_ATTRIBUTE_r11 1365 +#define _SET_FUNCTION_ATTRIBUTE_r21 1366 +#define _SET_FUNCTION_ATTRIBUTE_r32 1367 +#define _SET_IP_r00 1368 +#define _SET_IP_r11 1369 +#define _SET_IP_r22 1370 +#define _SET_IP_r33 1371 +#define _SET_UPDATE_r10 1372 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1373 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1374 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1375 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1376 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1377 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1378 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1379 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1380 +#define _SPILL_OR_RELOAD_r01 1381 +#define _SPILL_OR_RELOAD_r02 1382 +#define _SPILL_OR_RELOAD_r03 1383 +#define _SPILL_OR_RELOAD_r10 1384 +#define _SPILL_OR_RELOAD_r12 1385 +#define _SPILL_OR_RELOAD_r13 1386 +#define _SPILL_OR_RELOAD_r20 1387 +#define _SPILL_OR_RELOAD_r21 1388 +#define _SPILL_OR_RELOAD_r23 1389 +#define _SPILL_OR_RELOAD_r30 1390 +#define _SPILL_OR_RELOAD_r31 1391 +#define _SPILL_OR_RELOAD_r32 1392 +#define _START_EXECUTOR_r00 1393 +#define _STORE_ATTR_r20 1394 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1395 +#define _STORE_ATTR_SLOT_r21 1396 +#define _STORE_ATTR_WITH_HINT_r21 1397 +#define _STORE_DEREF_r10 1398 +#define _STORE_FAST_LOAD_FAST_r11 1399 +#define _STORE_FAST_STORE_FAST_r20 1400 +#define _STORE_GLOBAL_r10 1401 +#define _STORE_NAME_r10 1402 +#define _STORE_SLICE_r30 1403 +#define _STORE_SUBSCR_r30 1404 +#define _STORE_SUBSCR_DICT_r31 1405 +#define _STORE_SUBSCR_LIST_INT_r32 1406 +#define _SWAP_r11 1407 +#define _SWAP_2_r02 1408 +#define _SWAP_2_r12 1409 +#define _SWAP_2_r22 1410 +#define _SWAP_2_r33 1411 +#define _SWAP_3_r03 1412 +#define _SWAP_3_r13 1413 +#define _SWAP_3_r23 1414 +#define _SWAP_3_r33 1415 +#define _SWAP_FAST_r01 1416 +#define _SWAP_FAST_r11 1417 +#define _SWAP_FAST_r22 1418 +#define _SWAP_FAST_r33 1419 +#define _SWAP_FAST_0_r01 1420 +#define _SWAP_FAST_0_r11 1421 +#define _SWAP_FAST_0_r22 1422 +#define _SWAP_FAST_0_r33 1423 +#define _SWAP_FAST_1_r01 1424 +#define _SWAP_FAST_1_r11 1425 +#define _SWAP_FAST_1_r22 1426 +#define _SWAP_FAST_1_r33 1427 +#define _SWAP_FAST_2_r01 1428 +#define _SWAP_FAST_2_r11 1429 +#define _SWAP_FAST_2_r22 1430 +#define _SWAP_FAST_2_r33 1431 +#define _SWAP_FAST_3_r01 1432 +#define _SWAP_FAST_3_r11 1433 +#define _SWAP_FAST_3_r22 1434 +#define _SWAP_FAST_3_r33 1435 +#define _SWAP_FAST_4_r01 1436 +#define _SWAP_FAST_4_r11 1437 +#define _SWAP_FAST_4_r22 1438 +#define _SWAP_FAST_4_r33 1439 +#define _SWAP_FAST_5_r01 1440 +#define _SWAP_FAST_5_r11 1441 +#define _SWAP_FAST_5_r22 1442 +#define _SWAP_FAST_5_r33 1443 +#define _SWAP_FAST_6_r01 1444 +#define _SWAP_FAST_6_r11 1445 +#define _SWAP_FAST_6_r22 1446 +#define _SWAP_FAST_6_r33 1447 +#define _SWAP_FAST_7_r01 1448 +#define _SWAP_FAST_7_r11 1449 +#define _SWAP_FAST_7_r22 1450 +#define _SWAP_FAST_7_r33 1451 +#define _TIER2_RESUME_CHECK_r00 1452 +#define _TIER2_RESUME_CHECK_r11 1453 +#define _TIER2_RESUME_CHECK_r22 1454 +#define _TIER2_RESUME_CHECK_r33 1455 +#define _TO_BOOL_r11 1456 +#define _TO_BOOL_BOOL_r01 1457 +#define _TO_BOOL_BOOL_r11 1458 +#define _TO_BOOL_BOOL_r22 1459 +#define _TO_BOOL_BOOL_r33 1460 +#define _TO_BOOL_INT_r02 1461 +#define _TO_BOOL_INT_r12 1462 +#define _TO_BOOL_INT_r23 1463 +#define _TO_BOOL_LIST_r02 1464 +#define _TO_BOOL_LIST_r12 1465 +#define _TO_BOOL_LIST_r23 1466 +#define _TO_BOOL_NONE_r01 1467 +#define _TO_BOOL_NONE_r11 1468 +#define _TO_BOOL_NONE_r22 1469 +#define _TO_BOOL_NONE_r33 1470 +#define _TO_BOOL_STR_r02 1471 +#define _TO_BOOL_STR_r12 1472 +#define _TO_BOOL_STR_r23 1473 +#define _TRACE_RECORD_r00 1474 +#define _UNARY_INVERT_r12 1475 +#define _UNARY_NEGATIVE_r12 1476 +#define _UNARY_NOT_r01 1477 +#define _UNARY_NOT_r11 1478 +#define _UNARY_NOT_r22 1479 +#define _UNARY_NOT_r33 1480 +#define _UNPACK_EX_r10 1481 +#define _UNPACK_SEQUENCE_r10 1482 +#define _UNPACK_SEQUENCE_LIST_r10 1483 +#define _UNPACK_SEQUENCE_TUPLE_r10 1484 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1485 +#define _WITH_EXCEPT_START_r33 1486 +#define _YIELD_VALUE_r11 1487 +#define MAX_UOP_REGS_ID 1487 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 4a8245365f805a..fbcb95baf2aa60 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -113,18 +113,18 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG, [_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG, [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_PURE_FLAG, - [_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_GUARD_BINARY_OP_EXTEND] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, + [_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_GUARD_BINARY_OP_EXTEND] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG, [_BINARY_OP_EXTEND] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_BINARY_OP_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, + [_BINARY_OP_SUBSCR_LIST_INT] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG, [_BINARY_OP_SUBSCR_LIST_SLICE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_BINARY_OP_SUBSCR_STR_INT] = HAS_DEOPT_FLAG, - [_BINARY_OP_SUBSCR_USTR_INT] = HAS_DEOPT_FLAG, + [_BINARY_OP_SUBSCR_STR_INT] = HAS_EXIT_FLAG, + [_BINARY_OP_SUBSCR_USTR_INT] = HAS_EXIT_FLAG, [_GUARD_NOS_TUPLE] = HAS_EXIT_FLAG, [_GUARD_TOS_TUPLE] = HAS_EXIT_FLAG, - [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = HAS_DEOPT_FLAG, + [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = HAS_EXIT_FLAG, [_BINARY_OP_SUBSCR_TUPLE_INT] = 0, [_GUARD_NOS_DICT] = HAS_EXIT_FLAG, [_GUARD_NOS_ANY_DICT] = HAS_EXIT_FLAG, @@ -132,7 +132,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_GUARD_TOS_DICT] = HAS_EXIT_FLAG, [_GUARD_TOS_FROZENDICT] = HAS_EXIT_FLAG, [_BINARY_OP_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_BINARY_OP_SUBSCR_CHECK_FUNC] = HAS_DEOPT_FLAG, + [_BINARY_OP_SUBSCR_CHECK_FUNC] = HAS_EXIT_FLAG, [_BINARY_OP_SUBSCR_INIT_CALL] = 0, [_LIST_APPEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG, [_SET_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -147,7 +147,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_GET_AWAITABLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_SEND_GEN_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, + [_SEND_GEN_FRAME] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_YIELD_VALUE] = HAS_ARG_FLAG | HAS_NEEDS_GUARD_IP_FLAG, [_POP_EXCEPT] = HAS_ESCAPES_FLAG, [_LOAD_COMMON_CONSTANT] = HAS_ARG_FLAG, @@ -155,8 +155,8 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_STORE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_DELETE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_UNPACK_SEQUENCE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, - [_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, + [_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG, + [_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG, [_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_UNPACK_EX] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_STORE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -190,21 +190,22 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_DICT_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, + [_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG, - [_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG, - [_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG, + [_GUARD_TYPE_VERSION_LOCKED] = HAS_EXIT_FLAG, + [_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_EXIT_FLAG, [_LOAD_ATTR_INSTANCE_VALUE] = HAS_DEOPT_FLAG, - [_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG, - [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG, - [_LOAD_ATTR_SLOT] = HAS_DEOPT_FLAG, + [_LOAD_ATTR_MODULE] = HAS_EXIT_FLAG, + [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG, + [_LOAD_ATTR_SLOT] = HAS_EXIT_FLAG, [_CHECK_ATTR_CLASS] = HAS_EXIT_FLAG, [_LOAD_ATTR_CLASS] = HAS_ESCAPES_FLAG, - [_LOAD_ATTR_PROPERTY_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, + [_LOAD_ATTR_PROPERTY_FRAME] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_GUARD_DORV_NO_DICT] = HAS_EXIT_FLAG, [_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG, + [_LOCK_OBJECT] = HAS_DEOPT_FLAG, [_STORE_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_STORE_ATTR_SLOT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -213,9 +214,9 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_COMPARE_OP_STR] = HAS_ARG_FLAG, [_IS_OP] = HAS_ARG_FLAG, [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_GUARD_TOS_ANY_SET] = HAS_DEOPT_FLAG, - [_GUARD_TOS_SET] = HAS_DEOPT_FLAG, - [_GUARD_TOS_FROZENSET] = HAS_DEOPT_FLAG, + [_GUARD_TOS_ANY_SET] = HAS_EXIT_FLAG, + [_GUARD_TOS_SET] = HAS_EXIT_FLAG, + [_GUARD_TOS_FROZENSET] = HAS_EXIT_FLAG, [_CONTAINS_OP_SET] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CONTAINS_OP_DICT] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CHECK_EG_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -240,18 +241,18 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_ITER_CHECK_RANGE] = HAS_EXIT_FLAG, [_GUARD_NOT_EXHAUSTED_RANGE] = HAS_EXIT_FLAG, [_ITER_NEXT_RANGE] = HAS_ERROR_FLAG, - [_FOR_ITER_GEN_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG, + [_FOR_ITER_GEN_FRAME] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_INSERT_NULL] = 0, [_LOAD_SPECIAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_WITH_EXCEPT_START] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_PUSH_EXC_INFO] = 0, - [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG, - [_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG, + [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_EXIT_FLAG, + [_GUARD_KEYS_VERSION] = HAS_EXIT_FLAG, [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG, [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG, [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG, [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG, - [_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG, + [_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_EXIT_FLAG, [_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG, [_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG, [_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG, @@ -274,27 +275,27 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_INIT_CALL_PY_EXACT_ARGS_4] = HAS_PURE_FLAG, [_INIT_CALL_PY_EXACT_ARGS] = HAS_ARG_FLAG | HAS_PURE_FLAG, [_PUSH_FRAME] = HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG, - [_GUARD_NOS_NULL] = HAS_DEOPT_FLAG, + [_GUARD_NOS_NULL] = HAS_EXIT_FLAG, [_GUARD_NOS_NOT_NULL] = HAS_EXIT_FLAG, - [_GUARD_THIRD_NULL] = HAS_DEOPT_FLAG, - [_GUARD_CALLABLE_TYPE_1] = HAS_DEOPT_FLAG, + [_GUARD_THIRD_NULL] = HAS_EXIT_FLAG, + [_GUARD_CALLABLE_TYPE_1] = HAS_EXIT_FLAG, [_CALL_TYPE_1] = HAS_ARG_FLAG, - [_GUARD_CALLABLE_STR_1] = HAS_DEOPT_FLAG, + [_GUARD_CALLABLE_STR_1] = HAS_EXIT_FLAG, [_CALL_STR_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_GUARD_CALLABLE_TUPLE_1] = HAS_DEOPT_FLAG, + [_GUARD_CALLABLE_TUPLE_1] = HAS_EXIT_FLAG, [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_CHECK_AND_ALLOCATE_OBJECT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, + [_CHECK_AND_ALLOCATE_OBJECT] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CREATE_INIT_FRAME] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG, [_EXIT_INIT_CHECK] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_CALL_BUILTIN_CLASS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_CALL_BUILTIN_CLASS] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_BUILTIN_O] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_CALL_BUILTIN_FAST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_GUARD_CALLABLE_LEN] = HAS_DEOPT_FLAG, + [_CALL_BUILTIN_FAST] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_GUARD_CALLABLE_LEN] = HAS_EXIT_FLAG, [_CALL_LEN] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_GUARD_CALLABLE_ISINSTANCE] = HAS_DEOPT_FLAG, + [_GUARD_CALLABLE_ISINSTANCE] = HAS_EXIT_FLAG, [_CALL_ISINSTANCE] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_GUARD_CALLABLE_LIST_APPEND] = HAS_DEOPT_FLAG, + [_GUARD_CALLABLE_LIST_APPEND] = HAS_EXIT_FLAG, [_CALL_LIST_APPEND] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG, [_CALL_METHOD_DESCRIPTOR_O] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -1835,13 +1836,13 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { 3, 3, _GUARD_TYPE_VERSION_r33 }, }, }, - [_GUARD_TYPE_VERSION_AND_LOCK] = { + [_GUARD_TYPE_VERSION_LOCKED] = { .best = { 0, 1, 2, 3 }, .entries = { - { 1, 0, _GUARD_TYPE_VERSION_AND_LOCK_r01 }, - { 1, 1, _GUARD_TYPE_VERSION_AND_LOCK_r11 }, - { 2, 2, _GUARD_TYPE_VERSION_AND_LOCK_r22 }, - { 3, 3, _GUARD_TYPE_VERSION_AND_LOCK_r33 }, + { 1, 0, _GUARD_TYPE_VERSION_LOCKED_r01 }, + { 1, 1, _GUARD_TYPE_VERSION_LOCKED_r11 }, + { 2, 2, _GUARD_TYPE_VERSION_LOCKED_r22 }, + { 3, 3, _GUARD_TYPE_VERSION_LOCKED_r33 }, }, }, [_CHECK_MANAGED_OBJECT_HAS_VALUES] = { @@ -1934,6 +1935,15 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, }, }, + [_LOCK_OBJECT] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 1, 0, _LOCK_OBJECT_r01 }, + { 1, 1, _LOCK_OBJECT_r11 }, + { 2, 2, _LOCK_OBJECT_r22 }, + { 3, 3, _LOCK_OBJECT_r33 }, + }, + }, [_STORE_ATTR_WITH_HINT] = { .best = { 2, 2, 2, 2 }, .entries = { @@ -3882,10 +3892,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_GUARD_TYPE_VERSION_r11] = _GUARD_TYPE_VERSION, [_GUARD_TYPE_VERSION_r22] = _GUARD_TYPE_VERSION, [_GUARD_TYPE_VERSION_r33] = _GUARD_TYPE_VERSION, - [_GUARD_TYPE_VERSION_AND_LOCK_r01] = _GUARD_TYPE_VERSION_AND_LOCK, - [_GUARD_TYPE_VERSION_AND_LOCK_r11] = _GUARD_TYPE_VERSION_AND_LOCK, - [_GUARD_TYPE_VERSION_AND_LOCK_r22] = _GUARD_TYPE_VERSION_AND_LOCK, - [_GUARD_TYPE_VERSION_AND_LOCK_r33] = _GUARD_TYPE_VERSION_AND_LOCK, + [_GUARD_TYPE_VERSION_LOCKED_r01] = _GUARD_TYPE_VERSION_LOCKED, + [_GUARD_TYPE_VERSION_LOCKED_r11] = _GUARD_TYPE_VERSION_LOCKED, + [_GUARD_TYPE_VERSION_LOCKED_r22] = _GUARD_TYPE_VERSION_LOCKED, + [_GUARD_TYPE_VERSION_LOCKED_r33] = _GUARD_TYPE_VERSION_LOCKED, [_CHECK_MANAGED_OBJECT_HAS_VALUES_r01] = _CHECK_MANAGED_OBJECT_HAS_VALUES, [_CHECK_MANAGED_OBJECT_HAS_VALUES_r11] = _CHECK_MANAGED_OBJECT_HAS_VALUES, [_CHECK_MANAGED_OBJECT_HAS_VALUES_r22] = _CHECK_MANAGED_OBJECT_HAS_VALUES, @@ -3909,6 +3919,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_GUARD_DORV_NO_DICT_r22] = _GUARD_DORV_NO_DICT, [_GUARD_DORV_NO_DICT_r33] = _GUARD_DORV_NO_DICT, [_STORE_ATTR_INSTANCE_VALUE_r21] = _STORE_ATTR_INSTANCE_VALUE, + [_LOCK_OBJECT_r01] = _LOCK_OBJECT, + [_LOCK_OBJECT_r11] = _LOCK_OBJECT, + [_LOCK_OBJECT_r22] = _LOCK_OBJECT, + [_LOCK_OBJECT_r33] = _LOCK_OBJECT, [_STORE_ATTR_WITH_HINT_r21] = _STORE_ATTR_WITH_HINT, [_STORE_ATTR_SLOT_r21] = _STORE_ATTR_SLOT, [_COMPARE_OP_r21] = _COMPARE_OP, @@ -4946,11 +4960,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_GUARD_TYPE_VERSION_r11] = "_GUARD_TYPE_VERSION_r11", [_GUARD_TYPE_VERSION_r22] = "_GUARD_TYPE_VERSION_r22", [_GUARD_TYPE_VERSION_r33] = "_GUARD_TYPE_VERSION_r33", - [_GUARD_TYPE_VERSION_AND_LOCK] = "_GUARD_TYPE_VERSION_AND_LOCK", - [_GUARD_TYPE_VERSION_AND_LOCK_r01] = "_GUARD_TYPE_VERSION_AND_LOCK_r01", - [_GUARD_TYPE_VERSION_AND_LOCK_r11] = "_GUARD_TYPE_VERSION_AND_LOCK_r11", - [_GUARD_TYPE_VERSION_AND_LOCK_r22] = "_GUARD_TYPE_VERSION_AND_LOCK_r22", - [_GUARD_TYPE_VERSION_AND_LOCK_r33] = "_GUARD_TYPE_VERSION_AND_LOCK_r33", + [_GUARD_TYPE_VERSION_LOCKED] = "_GUARD_TYPE_VERSION_LOCKED", + [_GUARD_TYPE_VERSION_LOCKED_r01] = "_GUARD_TYPE_VERSION_LOCKED_r01", + [_GUARD_TYPE_VERSION_LOCKED_r11] = "_GUARD_TYPE_VERSION_LOCKED_r11", + [_GUARD_TYPE_VERSION_LOCKED_r22] = "_GUARD_TYPE_VERSION_LOCKED_r22", + [_GUARD_TYPE_VERSION_LOCKED_r33] = "_GUARD_TYPE_VERSION_LOCKED_r33", [_HANDLE_PENDING_AND_DEOPT] = "_HANDLE_PENDING_AND_DEOPT", [_HANDLE_PENDING_AND_DEOPT_r00] = "_HANDLE_PENDING_AND_DEOPT_r00", [_HANDLE_PENDING_AND_DEOPT_r10] = "_HANDLE_PENDING_AND_DEOPT_r10", @@ -5207,6 +5221,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_LOAD_SUPER_ATTR_ATTR_r31] = "_LOAD_SUPER_ATTR_ATTR_r31", [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD", [_LOAD_SUPER_ATTR_METHOD_r32] = "_LOAD_SUPER_ATTR_METHOD_r32", + [_LOCK_OBJECT] = "_LOCK_OBJECT", + [_LOCK_OBJECT_r01] = "_LOCK_OBJECT_r01", + [_LOCK_OBJECT_r11] = "_LOCK_OBJECT_r11", + [_LOCK_OBJECT_r22] = "_LOCK_OBJECT_r22", + [_LOCK_OBJECT_r33] = "_LOCK_OBJECT_r33", [_MAKE_CALLARGS_A_TUPLE] = "_MAKE_CALLARGS_A_TUPLE", [_MAKE_CALLARGS_A_TUPLE_r33] = "_MAKE_CALLARGS_A_TUPLE_r33", [_MAKE_CELL] = "_MAKE_CELL", @@ -5832,7 +5851,7 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _GUARD_TYPE_VERSION: return 0; - case _GUARD_TYPE_VERSION_AND_LOCK: + case _GUARD_TYPE_VERSION_LOCKED: return 0; case _CHECK_MANAGED_OBJECT_HAS_VALUES: return 0; @@ -5854,6 +5873,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _STORE_ATTR_INSTANCE_VALUE: return 2; + case _LOCK_OBJECT: + return 0; case _STORE_ATTR_WITH_HINT: return 2; case _STORE_ATTR_SLOT: diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 2615b1d4dd2b5f..b025f7b0eb7fe5 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -825,12 +825,10 @@ PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { - UPDATE_MISS_STATS(BINARY_OP); - assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); - JUMP_TO_PREDICTED(BINARY_OP); + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); + if (index < 0) { + index += PyList_GET_SIZE(list); } - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; #ifdef Py_GIL_DISABLED _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index); @@ -840,15 +838,13 @@ assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); } - STAT_INC(BINARY_OP, hit); res = PyStackRef_FromPyObjectSteal(res_o); #else - if (index >= PyList_GET_SIZE(list)) { + if (index < 0 || index >= PyList_GET_SIZE(list)) { UPDATE_MISS_STATS(BINARY_OP); assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); } - STAT_INC(BINARY_OP, hit); PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); res = PyStackRef_FromPyObjectNew(res_o); @@ -10979,21 +10975,25 @@ next_instr += 5; INSTRUCTION_STATS(STORE_ATTR_INSTANCE_VALUE); static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); - _PyStackRef owner; _PyStackRef value; + _PyStackRef owner; _PyStackRef o; /* Skip 1 cache entry */ - // _GUARD_TYPE_VERSION_AND_LOCK + // _LOCK_OBJECT { - owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&this_instr[2].cache); - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(type_version != 0); - if (!LOCK_OBJECT(owner_o)) { + value = stack_pointer[-1]; + if (!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))) { UPDATE_MISS_STATS(STORE_ATTR); assert(_PyOpcode_Deopt[opcode] == (STORE_ATTR)); JUMP_TO_PREDICTED(STORE_ATTR); } + } + // _GUARD_TYPE_VERSION_LOCKED + { + owner = value; + uint32_t type_version = read_u32(&this_instr[2].cache); + PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); + assert(type_version != 0); PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -11617,18 +11617,17 @@ PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { - UPDATE_MISS_STATS(STORE_SUBSCR); - assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); - JUMP_TO_PREDICTED(STORE_SUBSCR); - } - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); if (!LOCK_OBJECT(list)) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); JUMP_TO_PREDICTED(STORE_SUBSCR); } - if (index >= PyList_GET_SIZE(list)) { + Py_ssize_t len = PyList_GET_SIZE(list); + if (index < 0) { + index += len; + } + if (index < 0 || index >= len) { UNLOCK_OBJECT(list); if (true) { UPDATE_MISS_STATS(STORE_SUBSCR); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ac3e519398dbce..0eff5f76740f78 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -794,7 +794,7 @@ dummy_func( #endif _PyStackRef *target_local = &GETLOCAL(next_oparg); assert(PyUnicode_CheckExact(left_o)); - DEOPT_IF(PyStackRef_AsPyObjectBorrow(*target_local) != left_o); + EXIT_IF(PyStackRef_AsPyObjectBorrow(*target_local) != left_o); STAT_INC(BINARY_OP, hit); /* Handle `left = left + right` or `left += right` for str. * @@ -830,7 +830,7 @@ dummy_func( assert(INLINE_CACHE_ENTRIES_BINARY_OP == 5); assert(d && d->guard); int res = d->guard(left_o, right_o); - DEOPT_IF(!res); + EXIT_IF(!res); } op(_BINARY_OP_EXTEND, (descr/4, left, right -- res, l, r)) { @@ -930,17 +930,16 @@ dummy_func( assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - // Deopt unless 0 <= sub < PyList_Size(list) - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); + if (index < 0) { + index += PyList_GET_SIZE(list); + } #ifdef Py_GIL_DISABLED PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index); - DEOPT_IF(res_o == NULL); - STAT_INC(BINARY_OP, hit); + EXIT_IF(res_o == NULL); res = PyStackRef_FromPyObjectSteal(res_o); #else - DEOPT_IF(index >= PyList_GET_SIZE(list)); - STAT_INC(BINARY_OP, hit); + EXIT_IF(index < 0 || index >= PyList_GET_SIZE(list)); PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); res = PyStackRef_FromPyObjectNew(res_o); @@ -981,9 +980,9 @@ dummy_func( assert(PyLong_CheckExact(sub)); assert(PyUnicode_CheckExact(str)); - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject*)sub)); + EXIT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject*)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index); + EXIT_IF(PyUnicode_GET_LENGTH(str) <= index); uint8_t c = PyUnicode_1BYTE_DATA(str)[index]; assert(c < 128); STAT_INC(BINARY_OP, hit); @@ -1003,12 +1002,12 @@ dummy_func( assert(PyLong_CheckExact(sub)); assert(PyUnicode_CheckExact(str)); - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject*)sub)); + EXIT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject*)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index); + EXIT_IF(PyUnicode_GET_LENGTH(str) <= index); // Specialize for reading an ASCII character from any string: Py_UCS4 c = PyUnicode_READ_CHAR(str, index); - DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c); + EXIT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c); STAT_INC(BINARY_OP, hit); PyObject *res_o = (PyObject*)&_Py_SINGLETON(strings).ascii[c]; s = str_st; @@ -1045,9 +1044,9 @@ dummy_func( assert(PyTuple_CheckExact(tuple)); // Deopt unless 0 <= sub < PyTuple_Size(list) - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); + EXIT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(index >= PyTuple_GET_SIZE(tuple)); + EXIT_IF(index >= PyTuple_GET_SIZE(tuple)); } op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res, ts, ss)) { @@ -1117,16 +1116,16 @@ dummy_func( op(_BINARY_OP_SUBSCR_CHECK_FUNC, (container, unused -- container, unused, getitem)) { PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(container)); - DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); + EXIT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; PyObject *getitem_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(ht->_spec_cache.getitem); - DEOPT_IF(getitem_o == NULL); + EXIT_IF(getitem_o == NULL); assert(PyFunction_Check(getitem_o)); uint32_t cached_version = FT_ATOMIC_LOAD_UINT32_RELAXED(ht->_spec_cache.getitem_version); - DEOPT_IF(((PyFunctionObject *)getitem_o)->func_version != cached_version); + EXIT_IF(((PyFunctionObject *)getitem_o)->func_version != cached_version); PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(getitem_o); assert(code->co_argcount == 2); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); + EXIT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); getitem = PyStackRef_FromPyObjectNew(getitem_o); } @@ -1196,12 +1195,14 @@ dummy_func( assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - // Ensure nonnegative, zero-or-one-digit ints. - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); DEOPT_IF(!LOCK_OBJECT(list)); + Py_ssize_t len = PyList_GET_SIZE(list); // Ensure index < len(list) - if (index >= PyList_GET_SIZE(list)) { + if (index < 0) { + index += len; + } + if (index < 0 || index >= len) { UNLOCK_OBJECT(list); DEOPT_IF(true); } @@ -1458,8 +1459,8 @@ dummy_func( op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) { PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver); - DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); - DEOPT_IF(!gen_try_set_executing((PyGenObject *)gen)); + EXIT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); + EXIT_IF(!gen_try_set_executing((PyGenObject *)gen)); STAT_INC(SEND, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); @@ -1699,7 +1700,7 @@ dummy_func( assert(oparg == 2); PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq); assert(PyTuple_CheckExact(seq_o)); - DEOPT_IF(PyTuple_GET_SIZE(seq_o) != 2); + EXIT_IF(PyTuple_GET_SIZE(seq_o) != 2); STAT_INC(UNPACK_SEQUENCE, hit); val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0)); val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1)); @@ -1712,7 +1713,7 @@ dummy_func( op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg])) { PyObject *seq_o = PyStackRef_AsPyObjectBorrow(seq); assert(PyTuple_CheckExact(seq_o)); - DEOPT_IF(PyTuple_GET_SIZE(seq_o) != oparg); + EXIT_IF(PyTuple_GET_SIZE(seq_o) != oparg); STAT_INC(UNPACK_SEQUENCE, hit); PyObject **items = _PyTuple_ITEMS(seq_o); for (int i = oparg; --i >= 0; ) { @@ -2362,8 +2363,8 @@ dummy_func( PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); assert(!(oparg & 1)); - DEOPT_IF(global_super != (PyObject *)&PySuper_Type); - DEOPT_IF(!PyType_Check(class)); + EXIT_IF(global_super != (PyObject *)&PySuper_Type); + EXIT_IF(!PyType_Check(class)); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyObject *attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); @@ -2378,8 +2379,8 @@ dummy_func( PyObject *self = PyStackRef_AsPyObjectBorrow(self_st); assert(oparg & 1); - DEOPT_IF(global_super != (PyObject *)&PySuper_Type); - DEOPT_IF(!PyType_Check(class)); + EXIT_IF(global_super != (PyObject *)&PySuper_Type); + EXIT_IF(!PyType_Check(class)); STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyTypeObject *cls = (PyTypeObject *)class; @@ -2462,10 +2463,9 @@ dummy_func( EXIT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version); } - op(_GUARD_TYPE_VERSION_AND_LOCK, (type_version/2, owner -- owner)) { + op(_GUARD_TYPE_VERSION_LOCKED, (type_version/2, owner -- owner)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(type_version != 0); - EXIT_IF(!LOCK_OBJECT(owner_o)); PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -2477,7 +2477,7 @@ dummy_func( PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); - DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)); + EXIT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)); } op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, o)) { @@ -2510,20 +2510,20 @@ dummy_func( op(_LOAD_ATTR_MODULE, (dict_version/2, index/1, owner -- attr, o)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - DEOPT_IF(Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro); + EXIT_IF(Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict; assert(dict != NULL); PyDictKeysObject *keys = FT_ATOMIC_LOAD_PTR_ACQUIRE(dict->ma_keys); - DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != dict_version); + EXIT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != dict_version); assert(keys->dk_kind == DICT_KEYS_UNICODE); assert(index < FT_ATOMIC_LOAD_SSIZE_RELAXED(keys->dk_nentries)); PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(keys) + index; PyObject *attr_o = FT_ATOMIC_LOAD_PTR_RELAXED(ep->me_value); - DEOPT_IF(attr_o == NULL); + EXIT_IF(attr_o == NULL); #ifdef Py_GIL_DISABLED int increfed = _Py_TryIncrefCompareStackRef(&ep->me_value, attr_o, &attr); if (!increfed) { - DEOPT_IF(true); + EXIT_IF(true); } #else attr = PyStackRef_FromPyObjectNew(attr_o); @@ -2544,34 +2544,34 @@ dummy_func( PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); - DEOPT_IF(dict == NULL); + EXIT_IF(dict == NULL); PyDictKeysObject *dk = FT_ATOMIC_LOAD_PTR(dict->ma_keys); assert(PyDict_CheckExact((PyObject *)dict)); #ifdef Py_GIL_DISABLED - DEOPT_IF(!_Py_IsOwnedByCurrentThread((PyObject *)dict) && !_PyObject_GC_IS_SHARED(dict)); + EXIT_IF(!_Py_IsOwnedByCurrentThread((PyObject *)dict) && !_PyObject_GC_IS_SHARED(dict)); #endif PyObject *attr_o; if (hint >= (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_nentries)) { - DEOPT_IF(true); + EXIT_IF(true); } PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (dk->dk_kind != DICT_KEYS_UNICODE) { - DEOPT_IF(true); + EXIT_IF(true); } PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + hint; if (FT_ATOMIC_LOAD_PTR_RELAXED(ep->me_key) != name) { - DEOPT_IF(true); + EXIT_IF(true); } attr_o = FT_ATOMIC_LOAD_PTR(ep->me_value); if (attr_o == NULL) { - DEOPT_IF(true); + EXIT_IF(true); } STAT_INC(LOAD_ATTR, hit); #ifdef Py_GIL_DISABLED int increfed = _Py_TryIncrefCompareStackRef(&ep->me_value, attr_o, &attr); if (!increfed) { - DEOPT_IF(true); + EXIT_IF(true); } #else attr = PyStackRef_FromPyObjectNew(attr_o); @@ -2594,10 +2594,10 @@ dummy_func( PyObject **addr = (PyObject **)((char *)owner_o + index); PyObject *attr_o = FT_ATOMIC_LOAD_PTR(*addr); - DEOPT_IF(attr_o == NULL); + EXIT_IF(attr_o == NULL); #ifdef Py_GIL_DISABLED int increfed = _Py_TryIncrefCompareStackRef(addr, attr_o, &attr); - DEOPT_IF(!increfed); + EXIT_IF(!increfed); #else attr = PyStackRef_FromPyObjectNew(attr_o); #endif @@ -2650,10 +2650,10 @@ dummy_func( assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; PyCodeObject *code = (PyCodeObject *)f->func_code; - DEOPT_IF((code->co_flags & (CO_VARKEYWORDS | CO_VARARGS | CO_OPTIMIZED)) != CO_OPTIMIZED); - DEOPT_IF(code->co_kwonlyargcount); - DEOPT_IF(code->co_argcount != 1); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); + EXIT_IF((code->co_flags & (CO_VARKEYWORDS | CO_VARARGS | CO_OPTIMIZED)) != CO_OPTIMIZED); + EXIT_IF(code->co_kwonlyargcount); + EXIT_IF(code->co_argcount != 1); + EXIT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(LOAD_ATTR, hit); _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); pushed_frame->localsplus[0] = owner; @@ -2731,9 +2731,14 @@ dummy_func( Py_XDECREF(old_value); } + op(_LOCK_OBJECT, (value -- value)) { + DEOPT_IF(!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))); + } + macro(STORE_ATTR_INSTANCE_VALUE) = unused/1 + - _GUARD_TYPE_VERSION_AND_LOCK + + _LOCK_OBJECT + + _GUARD_TYPE_VERSION_LOCKED + _GUARD_DORV_NO_DICT + _STORE_ATTR_INSTANCE_VALUE + POP_TOP; @@ -2952,17 +2957,17 @@ dummy_func( op(_GUARD_TOS_ANY_SET, (tos -- tos)) { PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - DEOPT_IF(!PyAnySet_CheckExact(o)); + EXIT_IF(!PyAnySet_CheckExact(o)); } op(_GUARD_TOS_SET, (tos -- tos)) { PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - DEOPT_IF(!PySet_CheckExact(o)); + EXIT_IF(!PySet_CheckExact(o)); } op(_GUARD_TOS_FROZENSET, (tos -- tos)) { PyObject *o = PyStackRef_AsPyObjectBorrow(tos); - DEOPT_IF(!PyFrozenSet_CheckExact(o)); + EXIT_IF(!PyFrozenSet_CheckExact(o)); } macro(CONTAINS_OP_SET) = _GUARD_TOS_ANY_SET + unused/1 + _CONTAINS_OP_SET + POP_TOP + POP_TOP; @@ -3585,8 +3590,8 @@ dummy_func( op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame)) { PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); - DEOPT_IF(Py_TYPE(gen) != &PyGen_Type); - DEOPT_IF(!gen_try_set_executing((PyGenObject *)gen)); + EXIT_IF(Py_TYPE(gen) != &PyGen_Type); + EXIT_IF(!gen_try_set_executing((PyGenObject *)gen)); STAT_INC(FOR_ITER, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_None); @@ -3711,14 +3716,14 @@ dummy_func( PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); PyDictValues *ivs = _PyObject_InlineValues(owner_o); - DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid)); + EXIT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid)); } op(_GUARD_KEYS_VERSION, (keys_version/2, owner -- owner)) { PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner)); PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; PyDictKeysObject *keys = owner_heap_type->ht_cached_keys; - DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version); + EXIT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version); } op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) { @@ -3794,7 +3799,7 @@ dummy_func( char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset; PyObject *dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*(PyObject **)ptr); /* This object has a __dict__, just not yet created */ - DEOPT_IF(dict != NULL); + EXIT_IF(dict != NULL); } op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) { @@ -4150,7 +4155,7 @@ dummy_func( _PUSH_FRAME; op(_GUARD_NOS_NULL, (null, unused -- null, unused)) { - DEOPT_IF(!PyStackRef_IsNull(null)); + EXIT_IF(!PyStackRef_IsNull(null)); } op(_GUARD_NOS_NOT_NULL, (nos, unused -- nos, unused)) { @@ -4159,12 +4164,12 @@ dummy_func( } op(_GUARD_THIRD_NULL, (null, unused, unused -- null, unused, unused)) { - DEOPT_IF(!PyStackRef_IsNull(null)); + EXIT_IF(!PyStackRef_IsNull(null)); } op(_GUARD_CALLABLE_TYPE_1, (callable, unused, unused -- callable, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(callable_o != (PyObject *)&PyType_Type); + EXIT_IF(callable_o != (PyObject *)&PyType_Type); } op(_CALL_TYPE_1, (callable, null, arg -- res, a)) { @@ -4187,7 +4192,7 @@ dummy_func( op(_GUARD_CALLABLE_STR_1, (callable, unused, unused -- callable, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(callable_o != (PyObject *)&PyUnicode_Type); + EXIT_IF(callable_o != (PyObject *)&PyUnicode_Type); } op(_CALL_STR_1, (callable, null, arg -- res, a)) { @@ -4215,7 +4220,7 @@ dummy_func( op(_GUARD_CALLABLE_TUPLE_1, (callable, unused, unused -- callable, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(callable_o != (PyObject *)&PyTuple_Type); + EXIT_IF(callable_o != (PyObject *)&PyTuple_Type); } op(_CALL_TUPLE_1, (callable, null, arg -- res, a)) { @@ -4243,17 +4248,17 @@ dummy_func( op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(!PyStackRef_IsNull(self_or_null)); - DEOPT_IF(!PyType_Check(callable_o)); + EXIT_IF(!PyStackRef_IsNull(self_or_null)); + EXIT_IF(!PyType_Check(callable_o)); PyTypeObject *tp = (PyTypeObject *)callable_o; - DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(tp->tp_version_tag) != type_version); + EXIT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(tp->tp_version_tag) != type_version); assert(tp->tp_new == PyBaseObject_Type.tp_new); assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); assert(tp->tp_alloc == PyType_GenericAlloc); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable_o; PyFunctionObject *init_func = (PyFunctionObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(cls->_spec_cache.init); PyCodeObject *code = (PyCodeObject *)init_func->func_code; - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize + _Py_InitCleanup.co_framesize)); + EXIT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize + _Py_InitCleanup.co_framesize)); STAT_INC(CALL, hit); PyObject *self_o = PyType_GenericAlloc(tp, 0); if (self_o == NULL) { @@ -4310,7 +4315,7 @@ dummy_func( op(_CALL_BUILTIN_CLASS, (callable, self_or_null, args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(!PyType_Check(callable_o)); + EXIT_IF(!PyType_Check(callable_o)); PyTypeObject *tp = (PyTypeObject *)callable_o; int total_args = oparg; _PyStackRef *arguments = args; @@ -4318,7 +4323,7 @@ dummy_func( arguments--; total_args++; } - DEOPT_IF(tp->tp_vectorcall == NULL); + EXIT_IF(tp->tp_vectorcall == NULL); STAT_INC(CALL, hit); PyObject *res_o = _Py_CallBuiltinClass_StackRefSteal( callable, @@ -4385,8 +4390,8 @@ dummy_func( total_args++; } PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(!PyCFunction_CheckExact(callable_o)); - DEOPT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_FASTCALL); + EXIT_IF(!PyCFunction_CheckExact(callable_o)); + EXIT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_FASTCALL); STAT_INC(CALL, hit); PyObject *res_o = _Py_BuiltinCallFast_StackRefSteal( callable, @@ -4416,8 +4421,8 @@ dummy_func( total_args++; } PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - DEOPT_IF(!PyCFunction_CheckExact(callable_o)); - DEOPT_IF(PyCFunction_GET_FLAGS(callable_o) != (METH_FASTCALL | METH_KEYWORDS)); + EXIT_IF(!PyCFunction_CheckExact(callable_o)); + EXIT_IF(PyCFunction_GET_FLAGS(callable_o) != (METH_FASTCALL | METH_KEYWORDS)); STAT_INC(CALL, hit); PyObject *res_o = _Py_BuiltinCallFastWithKeywords_StackRefSteal(callable, arguments, total_args); DEAD(args); @@ -4446,7 +4451,7 @@ dummy_func( op(_GUARD_CALLABLE_LEN, (callable, unused, unused -- callable, unused, unused)){ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable_o != interp->callable_cache.len); + EXIT_IF(callable_o != interp->callable_cache.len); } op(_CALL_LEN, (callable, null, arg -- res, a, c)) { @@ -4471,7 +4476,7 @@ dummy_func( op(_GUARD_CALLABLE_ISINSTANCE, (callable, unused, unused, unused -- callable, unused, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable_o != interp->callable_cache.isinstance); + EXIT_IF(callable_o != interp->callable_cache.isinstance); } op(_CALL_ISINSTANCE, (callable, null, instance, cls -- res)) { @@ -4512,7 +4517,7 @@ dummy_func( op(_GUARD_CALLABLE_LIST_APPEND, (callable, unused, unused -- callable, unused, unused)){ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable_o != interp->callable_cache.list_append); + EXIT_IF(callable_o != interp->callable_cache.list_append); } op(_CALL_LIST_APPEND, (callable, self, arg -- none, c, s)) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 6271778bed4419..032d6faeda6a96 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5358,14 +5358,10 @@ PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { - UOP_STAT_INC(uopcode, miss); - _tos_cache1 = sub_st; - _tos_cache0 = list_st; - SET_CURRENT_CACHED_VALUES(2); - JUMP_TO_JUMP_TARGET(); + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); + if (index < 0) { + index += PyList_GET_SIZE(list); } - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; #ifdef Py_GIL_DISABLED stack_pointer[0] = list_st; stack_pointer[1] = sub_st; @@ -5383,17 +5379,15 @@ ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); JUMP_TO_JUMP_TARGET(); } - STAT_INC(BINARY_OP, hit); res = PyStackRef_FromPyObjectSteal(res_o); #else - if (index >= PyList_GET_SIZE(list)) { + if (index < 0 || index >= PyList_GET_SIZE(list)) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = sub_st; _tos_cache0 = list_st; SET_CURRENT_CACHED_VALUES(2); JUMP_TO_JUMP_TARGET(); } - STAT_INC(BINARY_OP, hit); PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); res = PyStackRef_FromPyObjectNew(res_o); @@ -6705,15 +6699,7 @@ PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { - UOP_STAT_INC(uopcode, miss); - _tos_cache2 = sub_st; - _tos_cache1 = list_st; - _tos_cache0 = value; - SET_CURRENT_CACHED_VALUES(3); - JUMP_TO_JUMP_TARGET(); - } - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); if (!LOCK_OBJECT(list)) { UOP_STAT_INC(uopcode, miss); _tos_cache2 = sub_st; @@ -6722,7 +6708,11 @@ SET_CURRENT_CACHED_VALUES(3); JUMP_TO_JUMP_TARGET(); } - if (index >= PyList_GET_SIZE(list)) { + Py_ssize_t len = PyList_GET_SIZE(list); + if (index < 0) { + index += len; + } + if (index < 0 || index >= len) { UNLOCK_OBJECT(list); if (true) { UOP_STAT_INC(uopcode, miss); @@ -9189,7 +9179,7 @@ break; } - case _GUARD_TYPE_VERSION_AND_LOCK_r01: { + case _GUARD_TYPE_VERSION_LOCKED_r01: { CHECK_CURRENT_CACHED_VALUES(0); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef owner; @@ -9197,11 +9187,6 @@ uint32_t type_version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(type_version != 0); - if (!LOCK_OBJECT(owner_o)) { - UOP_STAT_INC(uopcode, miss); - SET_CURRENT_CACHED_VALUES(0); - JUMP_TO_JUMP_TARGET(); - } PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -9219,7 +9204,7 @@ break; } - case _GUARD_TYPE_VERSION_AND_LOCK_r11: { + case _GUARD_TYPE_VERSION_LOCKED_r11: { CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef owner; @@ -9228,12 +9213,6 @@ uint32_t type_version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(type_version != 0); - if (!LOCK_OBJECT(owner_o)) { - UOP_STAT_INC(uopcode, miss); - _tos_cache0 = owner; - SET_CURRENT_CACHED_VALUES(1); - JUMP_TO_JUMP_TARGET(); - } PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -9250,7 +9229,7 @@ break; } - case _GUARD_TYPE_VERSION_AND_LOCK_r22: { + case _GUARD_TYPE_VERSION_LOCKED_r22: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef owner; @@ -9260,13 +9239,6 @@ uint32_t type_version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(type_version != 0); - if (!LOCK_OBJECT(owner_o)) { - UOP_STAT_INC(uopcode, miss); - _tos_cache1 = owner; - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(2); - JUMP_TO_JUMP_TARGET(); - } PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -9285,7 +9257,7 @@ break; } - case _GUARD_TYPE_VERSION_AND_LOCK_r33: { + case _GUARD_TYPE_VERSION_LOCKED_r33: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef owner; @@ -9296,14 +9268,6 @@ uint32_t type_version = (uint32_t)CURRENT_OPERAND0_32(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(type_version != 0); - if (!LOCK_OBJECT(owner_o)) { - UOP_STAT_INC(uopcode, miss); - _tos_cache2 = owner; - _tos_cache1 = _stack_item_1; - _tos_cache0 = _stack_item_0; - SET_CURRENT_CACHED_VALUES(3); - JUMP_TO_JUMP_TARGET(); - } PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -10153,6 +10117,87 @@ break; } + case _LOCK_OBJECT_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + value = stack_pointer[-1]; + if (!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = value; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _LOCK_OBJECT_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + _PyStackRef _stack_item_0 = _tos_cache0; + value = _stack_item_0; + if (!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = value; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache0 = value; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _LOCK_OBJECT_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + value = _stack_item_1; + if (!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))) { + UOP_STAT_INC(uopcode, miss); + _tos_cache1 = value; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache1 = value; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _LOCK_OBJECT_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef value; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + value = _stack_item_2; + if (!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = value; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + _tos_cache2 = value; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _STORE_ATTR_WITH_HINT_r21: { CHECK_CURRENT_CACHED_VALUES(2); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 5d853998bf68b5..de036fb964b691 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -825,12 +825,10 @@ PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { - UPDATE_MISS_STATS(BINARY_OP); - assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); - JUMP_TO_PREDICTED(BINARY_OP); + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); + if (index < 0) { + index += PyList_GET_SIZE(list); } - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; #ifdef Py_GIL_DISABLED _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index); @@ -840,15 +838,13 @@ assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); } - STAT_INC(BINARY_OP, hit); res = PyStackRef_FromPyObjectSteal(res_o); #else - if (index >= PyList_GET_SIZE(list)) { + if (index < 0 || index >= PyList_GET_SIZE(list)) { UPDATE_MISS_STATS(BINARY_OP); assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); } - STAT_INC(BINARY_OP, hit); PyObject *res_o = PyList_GET_ITEM(list, index); assert(res_o != NULL); res = PyStackRef_FromPyObjectNew(res_o); @@ -10976,21 +10972,25 @@ next_instr += 5; INSTRUCTION_STATS(STORE_ATTR_INSTANCE_VALUE); static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); - _PyStackRef owner; _PyStackRef value; + _PyStackRef owner; _PyStackRef o; /* Skip 1 cache entry */ - // _GUARD_TYPE_VERSION_AND_LOCK + // _LOCK_OBJECT { - owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&this_instr[2].cache); - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(type_version != 0); - if (!LOCK_OBJECT(owner_o)) { + value = stack_pointer[-1]; + if (!LOCK_OBJECT(PyStackRef_AsPyObjectBorrow(value))) { UPDATE_MISS_STATS(STORE_ATTR); assert(_PyOpcode_Deopt[opcode] == (STORE_ATTR)); JUMP_TO_PREDICTED(STORE_ATTR); } + } + // _GUARD_TYPE_VERSION_LOCKED + { + owner = value; + uint32_t type_version = read_u32(&this_instr[2].cache); + PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); + assert(type_version != 0); PyTypeObject *tp = Py_TYPE(owner_o); if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { UNLOCK_OBJECT(owner_o); @@ -11614,18 +11614,17 @@ PyObject *list = PyStackRef_AsPyObjectBorrow(list_st); assert(PyLong_CheckExact(sub)); assert(PyList_CheckExact(list)); - if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { - UPDATE_MISS_STATS(STORE_SUBSCR); - assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); - JUMP_TO_PREDICTED(STORE_SUBSCR); - } - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + Py_ssize_t index = _PyLong_CompactValue((PyLongObject *)sub); if (!LOCK_OBJECT(list)) { UPDATE_MISS_STATS(STORE_SUBSCR); assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR)); JUMP_TO_PREDICTED(STORE_SUBSCR); } - if (index >= PyList_GET_SIZE(list)) { + Py_ssize_t len = PyList_GET_SIZE(list); + if (index < 0) { + index += len; + } + if (index < 0 || index >= len) { UNLOCK_OBJECT(list); if (true) { UPDATE_MISS_STATS(STORE_SUBSCR); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index f996c1f6cc70a7..fe083411b7b739 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1929,7 +1929,7 @@ break; } - case _GUARD_TYPE_VERSION_AND_LOCK: { + case _GUARD_TYPE_VERSION_LOCKED: { break; } @@ -2099,6 +2099,10 @@ break; } + case _LOCK_OBJECT: { + break; + } + case _STORE_ATTR_WITH_HINT: { JitOptRef owner; JitOptRef value; From 7836ecc5daf541061de2072070f7371d41b009ee Mon Sep 17 00:00:00 2001 From: Thomas Kowalski Date: Thu, 12 Mar 2026 14:27:07 +0100 Subject: [PATCH 430/498] gh-145681: do not deallocate list buffer in `_PyList_AsTupleAndClear` (GH-145680) Setting the size to 0 turns the list contents into overallocated memory that the deallocator will free. Ownership is transferred to the new tuple so no refcount adjustment is needed. --- Objects/listobject.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 1fcedd3a28c91b..1cc62764e2fd8c 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3283,10 +3283,8 @@ _PyList_AsTupleAndClear(PyListObject *self) Py_BEGIN_CRITICAL_SECTION(self); PyObject **items = self->ob_item; Py_ssize_t size = Py_SIZE(self); - self->ob_item = NULL; Py_SET_SIZE(self, 0); ret = _PyTuple_FromArraySteal(items, size); - free_list_items(items, false); Py_END_CRITICAL_SECTION(); return ret; } From 17eb0354ff3110b27f811343c2d4b3c85f2685d5 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Thu, 12 Mar 2026 09:46:37 -0400 Subject: [PATCH 431/498] gh-145446: Add critical section in functools module for `PyDict_Next` (GH-145487) --- .../2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst | 1 + Modules/_functoolsmodule.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst diff --git a/Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst b/Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst new file mode 100644 index 00000000000000..96eb0d9ddb07ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst @@ -0,0 +1 @@ +Now :mod:`functools` is safer in free-threaded build when using keywords in :func:`functools.partial` diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 336a2e57ec0179..723080ede1d9ae 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -492,12 +492,15 @@ partial_vectorcall(PyObject *self, PyObject *const *args, /* Copy pto_keywords with overlapping call keywords merged * Note, tail is already coppied. */ Py_ssize_t pos = 0, i = 0; - while (PyDict_Next(n_merges ? pto_kw_merged : pto->kw, &pos, &key, &val)) { + PyObject *keyword_dict = n_merges ? pto_kw_merged : pto->kw; + Py_BEGIN_CRITICAL_SECTION(keyword_dict); + while (PyDict_Next(keyword_dict, &pos, &key, &val)) { assert(i < pto_nkwds); PyTuple_SET_ITEM(tot_kwnames, i, Py_NewRef(key)); stack[tot_nargs + i] = val; i++; } + Py_END_CRITICAL_SECTION(); assert(i == pto_nkwds); Py_XDECREF(pto_kw_merged); @@ -728,6 +731,8 @@ partial_repr(PyObject *self) } } /* Pack keyword arguments */ + int error = 0; + Py_BEGIN_CRITICAL_SECTION(kw); for (i = 0; PyDict_Next(kw, &i, &key, &value);) { /* Prevent key.__str__ from deleting the value. */ Py_INCREF(value); @@ -735,9 +740,14 @@ partial_repr(PyObject *self) key, value)); Py_DECREF(value); if (arglist == NULL) { - goto done; + error = 1; + break; } } + Py_END_CRITICAL_SECTION(); + if (error) { + goto done; + } mod = PyType_GetModuleName(Py_TYPE(pto)); if (mod == NULL) { From d4cc553294a558d632a2f69523eb04fa8c51f1a7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Mar 2026 15:04:36 +0100 Subject: [PATCH 432/498] gh-141510: Update PyDict C API doc for frozendict (#145533) Mention frozendict support. --- Doc/c-api/dict.rst | 67 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index d63c26865899cc..f44c18e80758bb 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -42,6 +42,12 @@ Dictionary objects enforces read-only behavior. This is normally used to create a view to prevent modification of the dictionary for non-dynamic class types. + The first argument can be a :class:`dict`, a :class:`frozendict`, or a + mapping. + + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:var:: PyTypeObject PyDictProxy_Type @@ -68,6 +74,11 @@ Dictionary objects *key*, return ``1``, otherwise return ``0``. On error, return ``-1``. This is equivalent to the Python expression ``key in p``. + The first argument can be a :class:`dict` or a :class:`frozendict`. + + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: int PyDict_ContainsString(PyObject *p, const char *key) @@ -75,8 +86,13 @@ Dictionary objects :c:expr:`const char*` UTF-8 encoded bytes string, rather than a :c:expr:`PyObject*`. + The first argument can be a :class:`dict` or a :class:`frozendict`. + .. versionadded:: 3.13 + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: PyObject* PyDict_Copy(PyObject *p) @@ -122,8 +138,13 @@ Dictionary objects * If the key is missing, set *\*result* to ``NULL`` and return ``0``. * On error, raise an exception and return ``-1``. + The first argument can be a :class:`dict` or a :class:`frozendict`. + .. versionadded:: 3.13 + .. versionchanged:: next + Also accept :class:`frozendict`. + See also the :c:func:`PyObject_GetItem` function. @@ -133,6 +154,8 @@ Dictionary objects has a key *key*. Return ``NULL`` if the key *key* is missing *without* setting an exception. + The first argument can be a :class:`dict` or a :class:`frozendict`. + .. note:: Exceptions that occur while this calls :meth:`~object.__hash__` and @@ -143,6 +166,9 @@ Dictionary objects Calling this API without an :term:`attached thread state` had been allowed for historical reason. It is no longer allowed. + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) @@ -151,6 +177,9 @@ Dictionary objects occurred. Return ``NULL`` **without** an exception set if the key wasn't present. + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) @@ -166,6 +195,9 @@ Dictionary objects Prefer using the :c:func:`PyDict_GetItemWithError` function with your own :c:func:`PyUnicode_FromString` *key* instead. + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: int PyDict_GetItemStringRef(PyObject *p, const char *key, PyObject **result) @@ -175,6 +207,9 @@ Dictionary objects .. versionadded:: 3.13 + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj) @@ -238,17 +273,32 @@ Dictionary objects Return a :c:type:`PyListObject` containing all the items from the dictionary. + The first argument can be a :class:`dict` or a :class:`frozendict`. + + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: PyObject* PyDict_Keys(PyObject *p) Return a :c:type:`PyListObject` containing all the keys from the dictionary. + The first argument can be a :class:`dict` or a :class:`frozendict`. + + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: PyObject* PyDict_Values(PyObject *p) Return a :c:type:`PyListObject` containing all the values from the dictionary *p*. + The first argument can be a :class:`dict` or a :class:`frozendict`. + + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: Py_ssize_t PyDict_Size(PyObject *p) @@ -257,11 +307,19 @@ Dictionary objects Return the number of items in the dictionary. This is equivalent to ``len(p)`` on a dictionary. + The argument can be a :class:`dict` or a :class:`frozendict`. + + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: Py_ssize_t PyDict_GET_SIZE(PyObject *p) Similar to :c:func:`PyDict_Size`, but without error checking. + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) @@ -276,6 +334,8 @@ Dictionary objects value represents offsets within the internal dictionary structure, and since the structure is sparse, the offsets are not consecutive. + The first argument can be a :class:`dict` or a :class:`frozendict`. + For example:: PyObject *key, *value; @@ -309,7 +369,7 @@ Dictionary objects } The function is not thread-safe in the :term:`free-threaded ` - build without external synchronization. You can use + build without external synchronization for a mutable :class:`dict`. You can use :c:macro:`Py_BEGIN_CRITICAL_SECTION` to lock the dictionary while iterating over it:: @@ -319,6 +379,8 @@ Dictionary objects } Py_END_CRITICAL_SECTION(); + The function is thread-safe on a :class:`frozendict`. + .. note:: On the free-threaded build, this function can be used safely inside a @@ -329,6 +391,9 @@ Dictionary objects :term:`strong reference ` (for example, using :c:func:`Py_NewRef`). + .. versionchanged:: next + Also accept :class:`frozendict`. + .. c:function:: int PyDict_Merge(PyObject *a, PyObject *b, int override) Iterate over mapping object *b* adding key-value pairs to dictionary *a*. From e13f6dccd7a2f8df543a18c4a3ad92610dc087cb Mon Sep 17 00:00:00 2001 From: Tan Long Date: Thu, 12 Mar 2026 23:59:43 +0800 Subject: [PATCH 433/498] gh-140131: Fix REPL cursor position on Windows when module completion suggestion line hits console width (GH-140333) --- Lib/_pyrepl/windows_console.py | 17 +++---- Lib/test/test_pyrepl/test_pyrepl.py | 46 ++++++++++++++++++- ...-02-11-21-01-30.gh-issue-144259.OAhOR8.rst | 1 + ...-10-19-23-44-46.gh-issue-140131.AABF2k.rst | 2 + 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst create mode 100644 Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py index 6c949c046875f3..cb1834168e881c 100644 --- a/Lib/_pyrepl/windows_console.py +++ b/Lib/_pyrepl/windows_console.py @@ -270,18 +270,13 @@ def __write_changed_line( self._erase_to_end() self.__write(newline[x_pos:]) - if wlen(newline) == self.width: - # If we wrapped we want to start at the next line - self._move_relative(0, y + 1) - self.posxy = 0, y + 1 - else: - self.posxy = wlen(newline), y + self.posxy = min(wlen(newline), self.width - 1), y - if "\x1b" in newline or y != self.posxy[1] or '\x1a' in newline: - # ANSI escape characters are present, so we can't assume - # anything about the position of the cursor. Moving the cursor - # to the left margin should work to get to a known position. - self.move_cursor(0, y) + if "\x1b" in newline or y != self.posxy[1] or '\x1a' in newline: + # ANSI escape characters are present, so we can't assume + # anything about the position of the cursor. Moving the cursor + # to the left margin should work to get to a known position. + self.move_cursor(0, y) def _scroll( self, top: int, bottom: int, left: int | None = None, right: int | None = None diff --git a/Lib/test/test_pyrepl/test_pyrepl.py b/Lib/test/test_pyrepl/test_pyrepl.py index 35a1733787e7a2..082215da0a3fba 100644 --- a/Lib/test/test_pyrepl/test_pyrepl.py +++ b/Lib/test/test_pyrepl/test_pyrepl.py @@ -12,7 +12,7 @@ import tempfile from pkgutil import ModuleInfo from unittest import TestCase, skipUnless, skipIf, SkipTest -from unittest.mock import patch +from unittest.mock import Mock, patch from test.support import force_not_colorized, make_clean_env, Py_DEBUG from test.support import has_subprocess_support, SHORT_TIMEOUT, STDLIB_DIR from test.support.import_helper import import_module @@ -2105,3 +2105,47 @@ def test_ctrl_d_single_line_end_no_newline(self): ) reader, _ = handle_all_events(events) self.assertEqual("hello", "".join(reader.buffer)) + + +@skipUnless(sys.platform == "win32", "windows console only") +class TestWindowsConsoleEolWrap(TestCase): + def _make_mock_console(self, width=80): + from _pyrepl import windows_console as wc + + console = object.__new__(wc.WindowsConsole) + + console.width = width + console.posxy = (0, 0) + console.screen = [""] + + console._hide_cursor = Mock() + console._show_cursor = Mock() + console._erase_to_end = Mock() + console._move_relative = Mock() + console.move_cursor = Mock() + console._WindowsConsole__write = Mock() + + return console, wc + + def test_short_line_sets_posxy_normally(self): + width = 10 + y = 3 + console, wc = self._make_mock_console(width=width) + old_line = "" + new_line = "a" * 3 + wc.WindowsConsole._WindowsConsole__write_changed_line( + console, y, old_line, new_line, 0 + ) + self.assertEqual(console.posxy, (3, y)) + + def test_exact_width_line_does_not_wrap(self): + width = 10 + y = 3 + console, wc = self._make_mock_console(width=width) + old_line = "" + new_line = "a" * width + + wc.WindowsConsole._WindowsConsole__write_changed_line( + console, y, old_line, new_line, 0 + ) + self.assertEqual(console.posxy, (width - 1, y)) diff --git a/Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst b/Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst new file mode 100644 index 00000000000000..280f3b742b013c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst @@ -0,0 +1 @@ +Fix inconsistent display of long multiline pasted content in the REPL. diff --git a/Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst b/Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst new file mode 100644 index 00000000000000..3c2d30d8d9813d --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst @@ -0,0 +1,2 @@ +Fix REPL cursor position on Windows when module completion suggestion line +hits console width. From 7a65900764e27c5f9b4d69e0a117777a757f2d22 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Thu, 12 Mar 2026 12:56:07 -0400 Subject: [PATCH 434/498] gh-145717: Add a few Microsoft-specific MIME types, and synchronize between `mimetypes` module and tests (#145718) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Petr Viktorin --- Doc/whatsnew/3.15.rst | 8 ++++++++ Lib/mimetypes.py | 3 +++ .../2026-03-10-01-48-12.gh-issue-145717.dPc0Rt.rst | 1 + 3 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-03-10-01-48-12.gh-issue-145717.dPc0Rt.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index c979118abd0a07..7daea13d31c83d 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -828,6 +828,14 @@ mimetypes * Add ``application/sql`` and ``application/vnd.sqlite3``. (Contributed by Charlie Lin in :gh:`145698`.) * Add ``image/jxl``. (Contributed by Foolbar in :gh:`144213`.) +* Add the following MIME types: + + - ``application/vnd.ms-cab-compressed`` for ``.cab`` extension + - ``application/vnd.ms-htmlhelp`` for ``.chm`` extension + - ``application/vnd.ms-officetheme`` for ``.thmx`` extension + + (Contributed by Charlie Lin in :gh:`145718`.) + * Rename ``application/x-texinfo`` to ``application/texinfo``. (Contributed by Charlie Lin in :gh:`140165`.) * Changed the MIME type for ``.ai`` files to ``application/pdf``. diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index ee66160be63b6f..60e8c2be1e2504 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -510,9 +510,12 @@ def _default_mime_types(): '.m3u8' : 'application/vnd.apple.mpegurl', '.dll' : 'application/vnd.microsoft.portable-executable', '.exe' : 'application/vnd.microsoft.portable-executable', + '.cab' : 'application/vnd.ms-cab-compressed', '.xls' : 'application/vnd.ms-excel', '.xlb' : 'application/vnd.ms-excel', '.eot' : 'application/vnd.ms-fontobject', + '.chm' : 'application/vnd.ms-htmlhelp', + '.thmx' : 'application/vnd.ms-officetheme', '.ppt' : 'application/vnd.ms-powerpoint', '.pot' : 'application/vnd.ms-powerpoint', '.ppa' : 'application/vnd.ms-powerpoint', diff --git a/Misc/NEWS.d/next/Library/2026-03-10-01-48-12.gh-issue-145717.dPc0Rt.rst b/Misc/NEWS.d/next/Library/2026-03-10-01-48-12.gh-issue-145717.dPc0Rt.rst new file mode 100644 index 00000000000000..55ef5206c992cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-10-01-48-12.gh-issue-145717.dPc0Rt.rst @@ -0,0 +1 @@ +Add a few Microsoft-specific MIME types. From cd5217283112d41c0244e2d96302cbe33f0b4cb1 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Thu, 12 Mar 2026 13:30:36 -0400 Subject: [PATCH 435/498] gh-145685: Improve scaling of type attribute lookups (gh-145774) Avoid locking in the PyType_Lookup cache-miss path if the type's tp_version_tag is already valid. --- .../internal/pycore_pyatomic_ft_wrappers.h | 3 ++ ...-03-10-12-52-06.gh-issue-145685.80B7gK.rst | 2 + Objects/typeobject.c | 54 ++++++++++--------- 3 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-12-52-06.gh-issue-145685.80B7gK.rst diff --git a/Include/internal/pycore_pyatomic_ft_wrappers.h b/Include/internal/pycore_pyatomic_ft_wrappers.h index 70a32db663b293..c0f859a23e10b8 100644 --- a/Include/internal/pycore_pyatomic_ft_wrappers.h +++ b/Include/internal/pycore_pyatomic_ft_wrappers.h @@ -95,6 +95,8 @@ extern "C" { _Py_atomic_store_int_relaxed(&value, new_value) #define FT_ATOMIC_LOAD_INT_RELAXED(value) \ _Py_atomic_load_int_relaxed(&value) +#define FT_ATOMIC_LOAD_UINT(value) \ + _Py_atomic_load_uint(&value) #define FT_ATOMIC_STORE_UINT_RELAXED(value, new_value) \ _Py_atomic_store_uint_relaxed(&value, new_value) #define FT_ATOMIC_LOAD_UINT_RELAXED(value) \ @@ -167,6 +169,7 @@ extern "C" { #define FT_ATOMIC_STORE_INT(value, new_value) value = new_value #define FT_ATOMIC_LOAD_INT_RELAXED(value) value #define FT_ATOMIC_STORE_INT_RELAXED(value, new_value) value = new_value +#define FT_ATOMIC_LOAD_UINT(value) value #define FT_ATOMIC_LOAD_UINT_RELAXED(value) value #define FT_ATOMIC_STORE_UINT_RELAXED(value, new_value) value = new_value #define FT_ATOMIC_LOAD_LONG_RELAXED(value) value diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-12-52-06.gh-issue-145685.80B7gK.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-12-52-06.gh-issue-145685.80B7gK.rst new file mode 100644 index 00000000000000..da34b67c952c7c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-12-52-06.gh-issue-145685.80B7gK.rst @@ -0,0 +1,2 @@ +Improve scaling of type attribute lookups in the :term:`free-threaded build` by +avoiding contention on the internal type lock. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index bb473dce68f65b..2a818f5f0205fd 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -52,8 +52,8 @@ class object "PyObject *" "&PyBaseObject_Type" MCACHE_HASH(FT_ATOMIC_LOAD_UINT_RELAXED((type)->tp_version_tag), \ ((Py_ssize_t)(name)) >> 3) #define MCACHE_CACHEABLE_NAME(name) \ - PyUnicode_CheckExact(name) && \ - (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE) + (PyUnicode_CheckExact(name) && \ + (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE)) #define NEXT_VERSION_TAG(interp) \ (interp)->types.next_version_tag @@ -6134,6 +6134,14 @@ _PyType_LookupRefAndVersion(PyTypeObject *type, PyObject *name, unsigned int *ve return PyStackRef_AsPyObjectSteal(out); } +static int +should_assign_version_tag(PyTypeObject *type, PyObject *name, unsigned int version_tag) +{ + return (version_tag == 0 + && FT_ATOMIC_LOAD_UINT16_RELAXED(type->tp_versions_used) < MAX_VERSIONS_PER_CLASS + && MCACHE_CACHEABLE_NAME(name)); +} + unsigned int _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef *out) { @@ -6182,24 +6190,20 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef /* We may end up clearing live exceptions below, so make sure it's ours. */ assert(!PyErr_Occurred()); - // We need to atomically do the lookup and capture the version before - // anyone else can modify our mro or mutate the type. - int res; PyInterpreterState *interp = _PyInterpreterState_GET(); - int has_version = 0; - unsigned int assigned_version = 0; - BEGIN_TYPE_LOCK(); - // We must assign the version before doing the lookup. If - // find_name_in_mro() blocks and releases the critical section - // then the type version can change. - if (MCACHE_CACHEABLE_NAME(name)) { - has_version = assign_version_tag(interp, type); - assigned_version = type->tp_version_tag; - } - res = find_name_in_mro(type, name, out); - END_TYPE_LOCK(); + unsigned int version_tag = FT_ATOMIC_LOAD_UINT(type->tp_version_tag); + if (should_assign_version_tag(type, name, version_tag)) { + BEGIN_TYPE_LOCK(); + assign_version_tag(interp, type); + version_tag = type->tp_version_tag; + res = find_name_in_mro(type, name, out); + END_TYPE_LOCK(); + } + else { + res = find_name_in_mro(type, name, out); + } /* Only put NULL results into cache if there was no error. */ if (res < 0) { @@ -6207,16 +6211,18 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef return 0; } - if (has_version) { - PyObject *res_obj = PyStackRef_AsPyObjectBorrow(*out); + if (version_tag == 0 || !MCACHE_CACHEABLE_NAME(name)) { + return 0; + } + + PyObject *res_obj = PyStackRef_AsPyObjectBorrow(*out); #if Py_GIL_DISABLED - update_cache_gil_disabled(entry, name, assigned_version, res_obj); + update_cache_gil_disabled(entry, name, version_tag, res_obj); #else - PyObject *old_value = update_cache(entry, name, assigned_version, res_obj); - Py_DECREF(old_value); + PyObject *old_value = update_cache(entry, name, version_tag, res_obj); + Py_DECREF(old_value); #endif - } - return has_version ? assigned_version : 0; + return version_tag; } /* Internal API to look for a name through the MRO. From f105265538823126dda5bc113fdb72cb2d5d2dbc Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Fri, 13 Mar 2026 03:16:53 +0500 Subject: [PATCH 436/498] GH-132042: Fix calculation of slotdef index in update_one_slot() (#145880) --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2a818f5f0205fd..7b4318e79fb2be 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -11737,7 +11737,7 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p, if (Py_IS_TYPE(descr, &PyWrapperDescr_Type) && ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) { void **tptr; - size_t index = (p - slotdefs) / sizeof(slotdefs[0]); + size_t index = (p - slotdefs); if (slotdefs_name_counts[index] == 1) { tptr = slotptr(type, p->offset); } From 08a018ebe0d673e9c352f790d2e4604d69604188 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 12 Mar 2026 23:48:51 +0100 Subject: [PATCH 437/498] gh-145801: Use gcc -fprofile-update=atomic for PGO builds (#145802) When Python build is optimized with GCC using PGO, use -fprofile-update=atomic option to use atomic operations when updating profile information. This option reduces the risk of gcov Data Files (.gcda) corruption which can cause random GCC crashes. --- ...-03-11-11-58-42.gh-issue-145801.iCXa3v.rst | 4 ++ configure | 42 ++++++++++++++++++- configure.ac | 5 ++- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-03-11-11-58-42.gh-issue-145801.iCXa3v.rst diff --git a/Misc/NEWS.d/next/Build/2026-03-11-11-58-42.gh-issue-145801.iCXa3v.rst b/Misc/NEWS.d/next/Build/2026-03-11-11-58-42.gh-issue-145801.iCXa3v.rst new file mode 100644 index 00000000000000..c5f3982cc5416c --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-03-11-11-58-42.gh-issue-145801.iCXa3v.rst @@ -0,0 +1,4 @@ +When Python build is optimized with GCC using PGO, use +``-fprofile-update=atomic`` option to use atomic operations when updating +profile information. This option reduces the risk of gcov Data Files (.gcda) +corruption which can cause random GCC crashes. Patch by Victor Stinner. diff --git a/configure b/configure index a3eeef373bf7fb..23f24d51c79e1a 100755 --- a/configure +++ b/configure @@ -9083,7 +9083,47 @@ case "$ac_cv_cc_name" in fi ;; gcc) - PGO_PROF_GEN_FLAG="-fprofile-generate" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fprofile-update=atomic" >&5 +printf %s "checking whether C compiler accepts -fprofile-update=atomic... " >&6; } +if test ${ax_cv_check_cflags___fprofile_update_atomic+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fprofile-update=atomic" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___fprofile_update_atomic=yes +else case e in #( + e) ax_cv_check_cflags___fprofile_update_atomic=no ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fprofile_update_atomic" >&5 +printf "%s\n" "$ax_cv_check_cflags___fprofile_update_atomic" >&6; } +if test "x$ax_cv_check_cflags___fprofile_update_atomic" = xyes +then : + PGO_PROF_GEN_FLAG="-fprofile-generate -fprofile-update=atomic" +else case e in #( + e) PGO_PROF_GEN_FLAG="-fprofile-generate" ;; +esac +fi + PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction" LLVM_PROF_MERGER="true" LLVM_PROF_FILE="" diff --git a/configure.ac b/configure.ac index 75e81761f95e38..635fce3f2e6fad 100644 --- a/configure.ac +++ b/configure.ac @@ -2084,7 +2084,10 @@ case "$ac_cv_cc_name" in fi ;; gcc) - PGO_PROF_GEN_FLAG="-fprofile-generate" + AX_CHECK_COMPILE_FLAG( + [-fprofile-update=atomic], + [PGO_PROF_GEN_FLAG="-fprofile-generate -fprofile-update=atomic"], + [PGO_PROF_GEN_FLAG="-fprofile-generate"]) PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction" LLVM_PROF_MERGER="true" LLVM_PROF_FILE="" From 0adc7289c3ab097b5608c0d288d91e1f5f236469 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 13 Mar 2026 01:53:29 +0000 Subject: [PATCH 438/498] Revert "gh-143050: Remove redundant decref in _PyLong_Negate (gh-143051)" (#145891) OSS Fuzzer caught an assertion failure. This reverts commit 5197ecb5e4df30ba0f6792d8bc0e36846154f58a. --- Objects/longobject.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 185226db43a92a..7ce5d0535b884e 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -48,17 +48,6 @@ _Py_DECREF_INT(PyLongObject *op) _Py_DECREF_SPECIALIZED((PyObject *)op, _PyLong_ExactDealloc); } -static inline int -/// Return 1 if the object is one of the immortal small ints -_long_is_small_int(PyObject *op) -{ - assert(PyLong_Check(op)); - PyLongObject *long_object = (PyLongObject *)op; - int is_small_int = (long_object->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0; - assert((!is_small_int) || PyLong_CheckExact(op)); - return is_small_int; -} - static inline int is_medium_int(stwodigits x) { @@ -355,6 +344,8 @@ medium_from_stwodigits(stwodigits x) } +/* If a freshly-allocated int is already shared, it must + be a small integer, so negating it must go to PyLong_FromLong */ Py_LOCAL_INLINE(void) _PyLong_Negate(PyLongObject **x_p) { @@ -366,10 +357,8 @@ _PyLong_Negate(PyLongObject **x_p) return; } - /* If a freshly-allocated int is already shared, it must - be a small integer, so negating it will fit a single digit */ - assert(_long_is_small_int((PyObject *)x)); - *x_p = (PyLongObject *)_PyLong_FromSTwoDigits(-medium_value(x)); + *x_p = _PyLong_FromSTwoDigits(-medium_value(x)); + Py_DECREF(x); } #define PYLONG_FROM_INT(UINT_TYPE, INT_TYPE, ival) \ @@ -3633,6 +3622,16 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } +static inline int +/// Return 1 if the object is one of the immortal small ints +_long_is_small_int(PyObject *op) +{ + PyLongObject *long_object = (PyLongObject *)op; + int is_small_int = (long_object->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0; + assert((!is_small_int) || PyLong_CheckExact(op)); + return is_small_int; +} + void _PyLong_ExactDealloc(PyObject *self) { From 6d1e9ceed3e70ebc39953f5ad4f20702ffa32119 Mon Sep 17 00:00:00 2001 From: Maurizio Sambati Date: Fri, 13 Mar 2026 10:40:20 +0100 Subject: [PATCH 439/498] Docs: except with multiple exceptions parentheses not required (#145848) As of PEP 758 the except statement doesn't require parentheses anymore for exception tuples. See: https://peps.python.org/pep-0758/ --- Doc/tutorial/errors.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 1c20fa2f0b6ae5..ae21dfdbf0ac44 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -121,9 +121,9 @@ A :keyword:`try` statement may have more than one *except clause*, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding *try clause*, not in other handlers of the same :keyword:`!try` statement. An *except clause* -may name multiple exceptions as a parenthesized tuple, for example:: +may name multiple exceptions, for example:: - ... except (RuntimeError, TypeError, NameError): + ... except RuntimeError, TypeError, NameError: ... pass A class in an :keyword:`except` clause matches exceptions which are instances of the From e1c224624ae601c464acbf173e2aa90fa980ab45 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:05:20 +0000 Subject: [PATCH 440/498] gh-145783: Propagate errors raised in `NEW_TYPE_COMMENT` (#145784) --- Lib/test/test_type_comments.py | 8 + ...-03-10-19-00-39.gh-issue-145783.dS5TM9.rst | 2 + Modules/_testcapimodule.c | 13 + Parser/parser.c | 1070 ++++++++--------- Tools/peg_generator/pegen/c_generator.py | 2 +- 5 files changed, 559 insertions(+), 536 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-19-00-39.gh-issue-145783.dS5TM9.rst diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index c40c45594f4d80..dd2e67841651d9 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -1,6 +1,7 @@ import ast import sys import unittest +from test.support import import_helper funcdef = """\ @@ -391,6 +392,13 @@ def check_both_ways(source): check_both_ways("pass # type: ignorewhatever\n") check_both_ways("pass # type: ignoreé\n") + def test_non_utf8_type_comment_with_ignore_cookie(self): + _testcapi = import_helper.import_module('_testcapi') + flags = 0x0800 | 0x1000 # PyCF_IGNORE_COOKIE | PyCF_TYPE_COMMENTS + with self.assertRaises(UnicodeDecodeError): + _testcapi.Py_CompileStringExFlags( + b"a=1 # type: \x80", "", 256, flags) + def test_func_type_input(self): def parse_func_type_input(source): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-19-00-39.gh-issue-145783.dS5TM9.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-19-00-39.gh-issue-145783.dS5TM9.rst new file mode 100644 index 00000000000000..ce9aa286068819 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-10-19-00-39.gh-issue-145783.dS5TM9.rst @@ -0,0 +1,2 @@ +Fix an unlikely crash in the parser when certain errors were erroneously not +propagated. Found by OSS Fuzz in :oss-fuzz:`491369109`. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c0ab35cda191c8..a25b127f1011b8 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -226,6 +226,18 @@ pycompilestring(PyObject* self, PyObject *obj) { return Py_CompileString(the_string, "", Py_file_input); } +static PyObject* +pycompilestringexflags(PyObject *self, PyObject *args) { + const char *the_string, *filename; + int start, flags; + if (!PyArg_ParseTuple(args, "ysii", &the_string, &filename, &start, &flags)) { + return NULL; + } + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags = flags; + return Py_CompileStringExFlags(the_string, filename, start, &cf, -1); +} + static PyObject* test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored)) { @@ -2659,6 +2671,7 @@ static PyMethodDef TestMethods[] = { {"return_result_with_error", return_result_with_error, METH_NOARGS}, {"getitem_with_error", getitem_with_error, METH_VARARGS}, {"Py_CompileString", pycompilestring, METH_O}, + {"Py_CompileStringExFlags", pycompilestringexflags, METH_VARARGS}, {"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS}, {"stack_pointer", stack_pointer, METH_NOARGS}, #ifdef W_STOPCODE diff --git a/Parser/parser.c b/Parser/parser.c index f8d6d1ce89b54d..f853d309de9180 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -1030,7 +1030,7 @@ file_rule(Parser *p) { D(fprintf(stderr, "%*c+ file[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statements? $")); _res = _PyPegen_make_module ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1073,7 +1073,7 @@ interactive_rule(Parser *p) { D(fprintf(stderr, "%*c+ interactive[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement_newline")); _res = _PyAST_Interactive ( a , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1122,7 +1122,7 @@ eval_rule(Parser *p) { D(fprintf(stderr, "%*c+ eval[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $")); _res = _PyAST_Expression ( a , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1183,7 +1183,7 @@ func_type_rule(Parser *p) { D(fprintf(stderr, "%*c+ func_type[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); _res = _PyAST_FunctionType ( a , b , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1226,7 +1226,7 @@ statements_rule(Parser *p) { D(fprintf(stderr, "%*c+ statements[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement+")); _res = ( asdl_stmt_seq* ) _PyPegen_seq_flatten ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1269,7 +1269,7 @@ statement_rule(Parser *p) { D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt")); _res = _PyPegen_register_stmts ( p , ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1293,7 +1293,7 @@ statement_rule(Parser *p) { D(fprintf(stderr, "%*c+ statement[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmts")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1336,7 +1336,7 @@ single_compound_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ single_compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "compound_stmt")); _res = _PyPegen_register_stmts ( p , ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1391,7 +1391,7 @@ statement_newline_rule(Parser *p) { D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_compound_stmt NEWLINE")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1443,7 +1443,7 @@ statement_newline_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , CHECK ( stmt_ty , _PyAST_Pass ( EXTRA ) ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1467,7 +1467,7 @@ statement_newline_rule(Parser *p) { D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "$")); _res = _PyPegen_interactive_exit ( p ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1515,7 +1515,7 @@ simple_stmts_rule(Parser *p) { D(fprintf(stderr, "%*c+ simple_stmts[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt !';' NEWLINE")); _res = ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1546,7 +1546,7 @@ simple_stmts_rule(Parser *p) { D(fprintf(stderr, "%*c+ simple_stmts[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'.simple_stmt+ ';'? NEWLINE")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -1686,7 +1686,7 @@ simple_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Expr ( e , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2165,7 +2165,7 @@ assignment_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 6 , "Variable annotation syntax is" , _PyAST_AnnAssign ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , b , c , 1 , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2207,7 +2207,7 @@ assignment_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 6 , "Variable annotations syntax is" , _PyAST_AnnAssign ( a , b , c , 0 , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2248,7 +2248,7 @@ assignment_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Assign ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2290,7 +2290,7 @@ assignment_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_AugAssign ( a , b -> kind , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2426,7 +2426,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+='")); _res = _PyPegen_augoperator ( p , Add ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2450,7 +2450,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-='")); _res = _PyPegen_augoperator ( p , Sub ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2474,7 +2474,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*='")); _res = _PyPegen_augoperator ( p , Mult ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2498,7 +2498,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@='")); _res = CHECK_VERSION ( AugOperator* , 5 , "The '@' operator is" , _PyPegen_augoperator ( p , MatMult ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2522,7 +2522,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/='")); _res = _PyPegen_augoperator ( p , Div ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2546,7 +2546,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'%='")); _res = _PyPegen_augoperator ( p , Mod ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2570,7 +2570,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'&='")); _res = _PyPegen_augoperator ( p , BitAnd ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2594,7 +2594,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|='")); _res = _PyPegen_augoperator ( p , BitOr ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2618,7 +2618,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'^='")); _res = _PyPegen_augoperator ( p , BitXor ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2642,7 +2642,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<<='")); _res = _PyPegen_augoperator ( p , LShift ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2666,7 +2666,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>>='")); _res = _PyPegen_augoperator ( p , RShift ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2690,7 +2690,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**='")); _res = _PyPegen_augoperator ( p , Pow ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2714,7 +2714,7 @@ augassign_rule(Parser *p) { D(fprintf(stderr, "%*c+ augassign[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'//='")); _res = _PyPegen_augoperator ( p , FloorDiv ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2778,7 +2778,7 @@ return_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Return ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2852,7 +2852,7 @@ raise_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Raise ( a , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2907,7 +2907,7 @@ raise_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Raise ( a , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -2940,7 +2940,7 @@ raise_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Raise ( NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3001,7 +3001,7 @@ pass_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Pass ( EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3062,7 +3062,7 @@ break_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Break ( EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3123,7 +3123,7 @@ continue_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Continue ( EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3187,7 +3187,7 @@ global_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Global ( CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3251,7 +3251,7 @@ nonlocal_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Nonlocal ( CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3317,7 +3317,7 @@ del_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Delete ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3397,7 +3397,7 @@ yield_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Expr ( y , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3483,7 +3483,7 @@ assert_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Assert ( a , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3631,7 +3631,7 @@ import_name_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Import ( a , lazy ? 1 : 0 , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3709,7 +3709,7 @@ import_from_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_checked_future_import ( p , b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , lazy , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3754,7 +3754,7 @@ import_from_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , lazy ? 1 : 0 , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3820,7 +3820,7 @@ import_from_targets_rule(Parser *p) { D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3874,7 +3874,7 @@ import_from_targets_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = ( asdl_alias_seq* ) _PyPegen_singleton_seq ( p , CHECK ( alias_ty , _PyPegen_alias_for_star ( p , EXTRA ) ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -3936,7 +3936,7 @@ import_from_as_names_rule(Parser *p) { D(fprintf(stderr, "%*c+ import_from_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4019,7 +4019,7 @@ import_from_as_name_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4062,7 +4062,7 @@ dotted_as_names_rule(Parser *p) { D(fprintf(stderr, "%*c+ dotted_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4145,7 +4145,7 @@ dotted_as_name_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4230,7 +4230,7 @@ dotted_name_raw(Parser *p) { D(fprintf(stderr, "%*c+ dotted_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME")); _res = _PyPegen_join_names_with_dot ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4305,7 +4305,7 @@ block_rule(Parser *p) { D(fprintf(stderr, "%*c+ block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4387,7 +4387,7 @@ decorators_rule(Parser *p) { D(fprintf(stderr, "%*c+ decorators[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4433,7 +4433,7 @@ class_def_rule(Parser *p) { D(fprintf(stderr, "%*c+ class_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); _res = _PyPegen_class_def_decorators ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4549,7 +4549,7 @@ class_def_raw_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , t , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4595,7 +4595,7 @@ function_def_rule(Parser *p) { D(fprintf(stderr, "%*c+ function_def[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); _res = _PyPegen_function_def_decorators ( p , d , f ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4724,7 +4724,7 @@ function_def_raw_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , t , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4787,7 +4787,7 @@ function_def_raw_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 5 , "Async functions are" , _PyAST_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , t , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4901,7 +4901,7 @@ parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4931,7 +4931,7 @@ parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4961,7 +4961,7 @@ parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); _res = _PyPegen_make_arguments ( p , NULL , NULL , a , b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -4988,7 +4988,7 @@ parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?")); _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5012,7 +5012,7 @@ parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_etc")); _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5061,7 +5061,7 @@ slash_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5090,7 +5090,7 @@ slash_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5144,7 +5144,7 @@ slash_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5176,7 +5176,7 @@ slash_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5252,7 +5252,7 @@ star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); _res = _PyPegen_star_etc ( p , a , b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5285,7 +5285,7 @@ star_etc_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5318,7 +5318,7 @@ star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); _res = _PyPegen_star_etc ( p , NULL , b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5342,7 +5342,7 @@ star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwds")); _res = _PyPegen_star_etc ( p , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5407,7 +5407,7 @@ kwds_rule(Parser *p) { D(fprintf(stderr, "%*c+ kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param_no_default")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5456,7 +5456,7 @@ param_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?")); _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5485,7 +5485,7 @@ param_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'")); _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5536,7 +5536,7 @@ param_no_default_star_annotation_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5565,7 +5565,7 @@ param_no_default_star_annotation_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5617,7 +5617,7 @@ param_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?")); _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5649,7 +5649,7 @@ param_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'")); _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5703,7 +5703,7 @@ param_maybe_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?")); _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5735,7 +5735,7 @@ param_maybe_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'")); _res = _PyPegen_name_default_pair ( p , a , c , tc ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5799,7 +5799,7 @@ param_rule(Parser *p) 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5863,7 +5863,7 @@ param_star_annotation_rule(Parser *p) 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5909,7 +5909,7 @@ annotation_rule(Parser *p) { D(fprintf(stderr, "%*c+ annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -5955,7 +5955,7 @@ star_annotation_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6001,7 +6001,7 @@ default_rule(Parser *p) { D(fprintf(stderr, "%*c+ default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' expression")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6115,7 +6115,7 @@ if_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_If ( a , b , CHECK ( asdl_stmt_seq* , _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6160,7 +6160,7 @@ if_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_If ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6255,7 +6255,7 @@ elif_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_If ( a , b , CHECK ( asdl_stmt_seq* , _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6300,7 +6300,7 @@ elif_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_If ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6368,7 +6368,7 @@ else_block_rule(Parser *p) { D(fprintf(stderr, "%*c+ else_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' &&':' block")); _res = b; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6460,7 +6460,7 @@ while_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_While ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6568,7 +6568,7 @@ for_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_For ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6632,7 +6632,7 @@ for_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 5 , "Async for loops are" , _PyAST_AsyncFor ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6763,7 +6763,7 @@ with_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6808,7 +6808,7 @@ with_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6863,7 +6863,7 @@ with_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 5 , "Async with statements are" , _PyAST_AsyncWith ( a , b , NULL , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6911,7 +6911,7 @@ with_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 5 , "Async with statements are" , _PyAST_AsyncWith ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -6984,7 +6984,7 @@ with_item_rule(Parser *p) { D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); _res = _PyAST_withitem ( e , t , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7027,7 +7027,7 @@ with_item_rule(Parser *p) { D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression")); _res = _PyAST_withitem ( e , NULL , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7120,7 +7120,7 @@ try_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Try ( b , NULL , NULL , f , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7168,7 +7168,7 @@ try_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Try ( b , ex , el , f , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7216,7 +7216,7 @@ try_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 11 , "Exception groups are" , _PyAST_TryStar ( b , ex , el , f , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7311,7 +7311,7 @@ except_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ExceptHandler ( e , NULL , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7359,7 +7359,7 @@ except_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ExceptHandler ( e , ( ( expr_ty ) t ) -> v . Name . id , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7401,7 +7401,7 @@ except_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( excepthandler_ty , 14 , "except expressions without parentheses are" , _PyAST_ExceptHandler ( e , NULL , b , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7440,7 +7440,7 @@ except_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ExceptHandler ( NULL , NULL , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7556,7 +7556,7 @@ except_star_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ExceptHandler ( e , NULL , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7607,7 +7607,7 @@ except_star_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ExceptHandler ( e , ( ( expr_ty ) t ) -> v . Name . id , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7652,7 +7652,7 @@ except_star_block_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( excepthandler_ty , 14 , "except expressions without parentheses are" , _PyAST_ExceptHandler ( e , NULL , b , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7739,7 +7739,7 @@ finally_block_rule(Parser *p) { D(fprintf(stderr, "%*c+ finally_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally' &&':' block")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7820,7 +7820,7 @@ match_stmt_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 10 , "Pattern matching is" , _PyAST_Match ( subject , cases , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7906,7 +7906,7 @@ subject_expr_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , value , values ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -7999,7 +7999,7 @@ case_block_rule(Parser *p) { D(fprintf(stderr, "%*c+ case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block")); _res = _PyAST_match_case ( pattern , guard , body , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8045,7 +8045,7 @@ guard_rule(Parser *p) { D(fprintf(stderr, "%*c+ guard[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression")); _res = guard; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8106,7 +8106,7 @@ patterns_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchSequence ( patterns , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8249,7 +8249,7 @@ as_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchAs ( pattern , target -> v . Name . id , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8329,7 +8329,7 @@ or_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = asdl_seq_LEN ( patterns ) == 1 ? asdl_seq_GET ( patterns , 0 ) : _PyAST_MatchOr ( patterns , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8582,7 +8582,7 @@ literal_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchValue ( value , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8615,7 +8615,7 @@ literal_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchValue ( value , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8648,7 +8648,7 @@ literal_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchValue ( value , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8681,7 +8681,7 @@ literal_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchSingleton ( Py_None , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8714,7 +8714,7 @@ literal_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchSingleton ( Py_True , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8747,7 +8747,7 @@ literal_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchSingleton ( Py_False , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8875,7 +8875,7 @@ literal_expr_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_None , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8908,7 +8908,7 @@ literal_expr_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_True , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -8941,7 +8941,7 @@ literal_expr_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_False , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9010,7 +9010,7 @@ complex_number_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( real , Add , imag , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9049,7 +9049,7 @@ complex_number_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( real , Sub , imag , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9132,7 +9132,7 @@ signed_number_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_UnaryOp ( USub , number , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9215,7 +9215,7 @@ signed_real_number_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_UnaryOp ( USub , real , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9258,7 +9258,7 @@ real_number_rule(Parser *p) { D(fprintf(stderr, "%*c+ real_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); _res = _PyPegen_ensure_real ( p , real ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9301,7 +9301,7 @@ imaginary_number_rule(Parser *p) { D(fprintf(stderr, "%*c+ imaginary_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NUMBER")); _res = _PyPegen_ensure_imaginary ( p , imag ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9362,7 +9362,7 @@ capture_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchAs ( NULL , target -> v . Name . id , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9409,7 +9409,7 @@ pattern_capture_target_rule(Parser *p) { D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); _res = _PyPegen_set_expr_context ( p , name , Store ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9470,7 +9470,7 @@ wildcard_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchAs ( NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9533,7 +9533,7 @@ value_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchValue ( attr , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9636,7 +9636,7 @@ attr_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Attribute ( value , attr -> v . Name . id , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9743,7 +9743,7 @@ group_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ group_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' pattern ')'")); _res = pattern; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9810,7 +9810,7 @@ sequence_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchSequence ( patterns , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9849,7 +9849,7 @@ sequence_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchSequence ( patterns , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9898,7 +9898,7 @@ open_sequence_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ open_sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern ',' maybe_sequence_pattern?")); _res = _PyPegen_seq_insert_in_front ( p , pattern , patterns ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -9945,7 +9945,7 @@ maybe_sequence_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ maybe_sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.maybe_star_pattern+ ','?")); _res = patterns; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10070,7 +10070,7 @@ star_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchStar ( target -> v . Name . id , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10106,7 +10106,7 @@ star_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchStar ( NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10176,7 +10176,7 @@ mapping_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchMapping ( NULL , NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10219,7 +10219,7 @@ mapping_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchMapping ( NULL , NULL , rest -> v . Name . id , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10268,7 +10268,7 @@ mapping_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchMapping ( CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , items ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , items ) ) , rest -> v . Name . id , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10311,7 +10311,7 @@ mapping_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchMapping ( CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , items ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , items ) ) , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10417,7 +10417,7 @@ key_value_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ key_value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(literal_expr | attr) ':' pattern")); _res = _PyPegen_key_pattern_pair ( p , key , pattern ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10463,7 +10463,7 @@ double_star_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ double_star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' pattern_capture_target")); _res = target; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10535,7 +10535,7 @@ class_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchClass ( cls , NULL , NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10581,7 +10581,7 @@ class_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchClass ( cls , patterns , NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10627,7 +10627,7 @@ class_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchClass ( cls , NULL , CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , keywords ) ) ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , keywords ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10679,7 +10679,7 @@ class_pattern_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_MatchClass ( cls , patterns , CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , keywords ) ) ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , keywords ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10741,7 +10741,7 @@ positional_patterns_rule(Parser *p) { D(fprintf(stderr, "%*c+ positional_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.pattern+")); _res = args; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10828,7 +10828,7 @@ keyword_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ keyword_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' pattern")); _res = _PyPegen_key_pattern_pair ( p , arg , value ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10901,7 +10901,7 @@ type_alias_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( stmt_ty , 12 , "Type statement is" , _PyAST_TypeAlias ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , n , Store ) ) , t , b , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -10969,7 +10969,7 @@ type_params_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' type_param_seq ']'")); _res = CHECK_VERSION ( asdl_type_param_seq* , 12 , "Type parameter lists are" , t ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11016,7 +11016,7 @@ type_param_seq_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_param_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.type_param+ ','?")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11091,7 +11091,7 @@ type_param_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_TypeVar ( a -> v . Name . id , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11149,7 +11149,7 @@ type_param_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_TypeVarTuple ( a -> v . Name . id , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11188,7 +11188,7 @@ type_param_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ParamSpec ( a -> v . Name . id , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11235,7 +11235,7 @@ type_param_bound_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_param_bound[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression")); _res = e; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11281,7 +11281,7 @@ type_param_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_param_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' expression")); _res = CHECK_VERSION ( expr_ty , 13 , "Type parameter defaults are" , e ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11327,7 +11327,7 @@ type_param_starred_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_param_starred_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' star_expression")); _res = CHECK_VERSION ( expr_ty , 13 , "Type parameter defaults are" , e ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11395,7 +11395,7 @@ expressions_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11431,7 +11431,7 @@ expressions_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11667,7 +11667,7 @@ if_expression_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_IfExp ( b , a , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11734,7 +11734,7 @@ yield_expr_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_YieldFrom ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11770,7 +11770,7 @@ yield_expr_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Yield ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11841,7 +11841,7 @@ star_expressions_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11877,7 +11877,7 @@ star_expressions_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -11964,7 +11964,7 @@ star_expression_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Starred ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12031,7 +12031,7 @@ star_named_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_named_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12078,7 +12078,7 @@ star_named_expressions_sequence_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_named_expressions_sequence[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_named_expression_sequence+ ','?")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12142,7 +12142,7 @@ star_named_expression_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Starred ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12290,7 +12290,7 @@ assignment_expression_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( expr_ty , 8 , "Assignment expressions are" , _PyAST_NamedExpr ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , b , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12440,7 +12440,7 @@ disjunction_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BoolOp ( Or , CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12528,7 +12528,7 @@ conjunction_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BoolOp ( And , CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12616,7 +12616,7 @@ inversion_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_UnaryOp ( Not , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12700,7 +12700,7 @@ comparison_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Compare ( a , CHECK ( asdl_int_seq* , _PyPegen_get_cmpops ( p , b ) ) , CHECK ( asdl_expr_seq* , _PyPegen_get_exprs ( p , b ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -12984,7 +12984,7 @@ eq_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ eq_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , Eq , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13030,7 +13030,7 @@ noteq_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ noteq_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , NotEq , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13076,7 +13076,7 @@ lte_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ lte_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , LtE , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13122,7 +13122,7 @@ lt_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ lt_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , Lt , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13168,7 +13168,7 @@ gte_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ gte_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , GtE , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13214,7 +13214,7 @@ gt_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ gt_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , Gt , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13263,7 +13263,7 @@ notin_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ notin_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , NotIn , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13309,7 +13309,7 @@ in_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ in_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , In , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13358,7 +13358,7 @@ isnot_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ isnot_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , IsNot , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13404,7 +13404,7 @@ is_bitwise_or_rule(Parser *p) { D(fprintf(stderr, "%*c+ is_bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or")); _res = _PyPegen_cmpop_expr_pair ( p , Is , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13507,7 +13507,7 @@ bitwise_or_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , BitOr , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13629,7 +13629,7 @@ bitwise_xor_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , BitXor , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13751,7 +13751,7 @@ bitwise_and_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , BitAnd , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13873,7 +13873,7 @@ shift_expr_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , LShift , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -13912,7 +13912,7 @@ shift_expr_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , RShift , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14053,7 +14053,7 @@ sum_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , Add , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14092,7 +14092,7 @@ sum_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , Sub , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14221,7 +14221,7 @@ term_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , Mult , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14260,7 +14260,7 @@ term_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , Div , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14299,7 +14299,7 @@ term_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , FloorDiv , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14338,7 +14338,7 @@ term_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , Mod , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14377,7 +14377,7 @@ term_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( expr_ty , 5 , "The '@' operator is" , _PyAST_BinOp ( a , MatMult , b , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14483,7 +14483,7 @@ factor_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_UnaryOp ( UAdd , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14519,7 +14519,7 @@ factor_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_UnaryOp ( USub , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14555,7 +14555,7 @@ factor_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_UnaryOp ( Invert , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14642,7 +14642,7 @@ power_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_BinOp ( a , Pow , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14729,7 +14729,7 @@ await_primary_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = CHECK_VERSION ( expr_ty , 5 , "Await expressions are" , _PyAST_Await ( a , EXTRA ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14857,7 +14857,7 @@ primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Attribute ( a , b -> v . Name . id , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14893,7 +14893,7 @@ primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Call ( a , CHECK ( asdl_expr_seq* , ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14935,7 +14935,7 @@ primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -14977,7 +14977,7 @@ primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Subscript ( a , b , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15050,7 +15050,7 @@ slices_rule(Parser *p) { D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice !','")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15087,7 +15087,7 @@ slices_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15157,7 +15157,7 @@ slice_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Slice ( a , b , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15181,7 +15181,7 @@ slice_rule(Parser *p) { D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15271,7 +15271,7 @@ atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_True , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15304,7 +15304,7 @@ atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_False , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15337,7 +15337,7 @@ atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_None , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15473,7 +15473,7 @@ atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Constant ( Py_Ellipsis , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15522,7 +15522,7 @@ group_rule(Parser *p) { D(fprintf(stderr, "%*c+ group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15611,7 +15611,7 @@ lambdef_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Lambda ( ( a ) ? a : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15725,7 +15725,7 @@ lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15755,7 +15755,7 @@ lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15785,7 +15785,7 @@ lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); _res = _PyPegen_make_arguments ( p , NULL , NULL , a , b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15812,7 +15812,7 @@ lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15836,7 +15836,7 @@ lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_star_etc")); _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15887,7 +15887,7 @@ lambda_slash_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15916,7 +15916,7 @@ lambda_slash_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_slash_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -15970,7 +15970,7 @@ lambda_slash_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16002,7 +16002,7 @@ lambda_slash_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_slash_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16077,7 +16077,7 @@ lambda_star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); _res = _PyPegen_star_etc ( p , a , b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16110,7 +16110,7 @@ lambda_star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); _res = _PyPegen_star_etc ( p , NULL , b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16134,7 +16134,7 @@ lambda_star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); _res = _PyPegen_star_etc ( p , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16199,7 +16199,7 @@ lambda_kwds_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16245,7 +16245,7 @@ lambda_param_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param ','")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16271,7 +16271,7 @@ lambda_param_no_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_param_no_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param &':'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16320,7 +16320,7 @@ lambda_param_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default ','")); _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16349,7 +16349,7 @@ lambda_param_with_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_param_with_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'")); _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16398,7 +16398,7 @@ lambda_param_maybe_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','")); _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16427,7 +16427,7 @@ lambda_param_maybe_default_rule(Parser *p) { D(fprintf(stderr, "%*c+ lambda_param_maybe_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'")); _res = _PyPegen_name_default_pair ( p , a , c , NULL ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16488,7 +16488,7 @@ lambda_param_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_arg ( a -> v . Name . id , NULL , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16550,7 +16550,7 @@ fstring_middle_rule(Parser *p) { D(fprintf(stderr, "%*c+ fstring_middle[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); _res = _PyPegen_constant_from_token ( p , t ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16628,7 +16628,7 @@ fstring_replacement_field_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_formatted_value ( p , a , debug_expr , conversion , format , rbrace , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16693,7 +16693,7 @@ fstring_conversion_rule(Parser *p) { D(fprintf(stderr, "%*c+ fstring_conversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"!\" NAME")); _res = _PyPegen_check_fstring_conversion ( p , conv_token , conv ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16757,7 +16757,7 @@ fstring_full_format_spec_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_setup_full_format_spec ( p , colon , ( asdl_expr_seq* ) spec , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16800,7 +16800,7 @@ fstring_format_spec_rule(Parser *p) { D(fprintf(stderr, "%*c+ fstring_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); _res = _PyPegen_decoded_constant_from_token ( p , t ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16868,7 +16868,7 @@ fstring_rule(Parser *p) { D(fprintf(stderr, "%*c+ fstring[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); _res = _PyPegen_joined_str ( p , a , ( asdl_expr_seq* ) b , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -16946,7 +16946,7 @@ tstring_format_spec_replacement_field_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_formatted_value ( p , a , debug_expr , conversion , format , rbrace , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17008,7 +17008,7 @@ tstring_format_spec_rule(Parser *p) { D(fprintf(stderr, "%*c+ tstring_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TSTRING_MIDDLE")); _res = _PyPegen_decoded_constant_from_token ( p , t ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17091,7 +17091,7 @@ tstring_full_format_spec_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_setup_full_format_spec ( p , colon , ( asdl_expr_seq* ) spec , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17169,7 +17169,7 @@ tstring_replacement_field_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_interpolation ( p , a , debug_expr , conversion , format , rbrace , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17250,7 +17250,7 @@ tstring_middle_rule(Parser *p) { D(fprintf(stderr, "%*c+ tstring_middle[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TSTRING_MIDDLE")); _res = _PyPegen_constant_from_token ( p , t ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17303,7 +17303,7 @@ tstring_rule(Parser *p) { D(fprintf(stderr, "%*c+ tstring[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TSTRING_START tstring_middle* TSTRING_END")); _res = CHECK_VERSION ( expr_ty , 14 , "t-strings are" , _PyPegen_template_str ( p , a , ( asdl_expr_seq* ) b , c ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17347,7 +17347,7 @@ string_rule(Parser *p) { D(fprintf(stderr, "%*c+ string[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING")); _res = _PyPegen_constant_from_string ( p , s ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17431,7 +17431,7 @@ strings_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_concatenate_strings ( p , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17464,7 +17464,7 @@ strings_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_concatenate_tstrings ( p , a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17532,7 +17532,7 @@ list_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_List ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17599,7 +17599,7 @@ tuple_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17666,7 +17666,7 @@ set_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Set ( a , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17733,7 +17733,7 @@ dict_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Dict ( CHECK ( asdl_expr_seq* , _PyPegen_get_keys ( p , a ) ) , CHECK ( asdl_expr_seq* , _PyPegen_get_values ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17805,7 +17805,7 @@ double_starred_kvpairs_rule(Parser *p) { D(fprintf(stderr, "%*c+ double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17851,7 +17851,7 @@ double_starred_kvpair_rule(Parser *p) { D(fprintf(stderr, "%*c+ double_starred_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); _res = _PyPegen_key_value_pair ( p , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17919,7 +17919,7 @@ kvpair_rule(Parser *p) { D(fprintf(stderr, "%*c+ kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); _res = _PyPegen_key_value_pair ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -17962,7 +17962,7 @@ for_if_clauses_rule(Parser *p) { D(fprintf(stderr, "%*c+ for_if_clauses[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18027,7 +18027,7 @@ for_if_clause_rule(Parser *p) { 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))*")); _res = CHECK_VERSION ( comprehension_ty , 6 , "Async comprehensions are" , _PyAST_comprehension ( a , b , c , 1 , p -> arena ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18070,7 +18070,7 @@ for_if_clause_rule(Parser *p) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); _res = _PyAST_comprehension ( a , b , c , 0 , p -> arena ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18182,7 +18182,7 @@ listcomp_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_ListComp ( a , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18271,7 +18271,7 @@ setcomp_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_SetComp ( a , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18362,7 +18362,7 @@ genexp_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_GeneratorExp ( a , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18451,7 +18451,7 @@ dictcomp_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_DictComp ( a -> key , a -> value , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18496,7 +18496,7 @@ dictcomp_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_DictComp ( a , NULL , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18549,7 +18549,7 @@ arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','? &')'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18635,7 +18635,7 @@ args_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18668,7 +18668,7 @@ args_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Call ( _PyPegen_dummy_name ( p ) , CHECK_NULL_ALLOWED ( asdl_expr_seq* , _PyPegen_seq_extract_starred_exprs ( p , a ) ) , CHECK_NULL_ALLOWED ( asdl_keyword_seq* , _PyPegen_seq_delete_starred_exprs ( p , a ) ) , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18720,7 +18720,7 @@ kwargs_rule(Parser *p) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); _res = _PyPegen_join_sequences ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18844,7 +18844,7 @@ starred_expression_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Starred ( a , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18949,7 +18949,7 @@ kwarg_or_starred_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -18973,7 +18973,7 @@ kwarg_or_starred_rule(Parser *p) { D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = _PyPegen_keyword_or_starred ( p , a , 0 ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19059,7 +19059,7 @@ kwarg_or_double_starred_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19095,7 +19095,7 @@ kwarg_or_double_starred_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( NULL , a , EXTRA ) ) , 1 ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19149,7 +19149,7 @@ star_targets_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target !','")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19189,7 +19189,7 @@ star_targets_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19236,7 +19236,7 @@ star_targets_list_seq_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_targets_list_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19286,7 +19286,7 @@ star_targets_tuple_seq_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?")); _res = ( asdl_expr_seq* ) _PyPegen_seq_insert_in_front ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19313,7 +19313,7 @@ star_targets_tuple_seq_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_targets_tuple_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ','")); _res = ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19381,7 +19381,7 @@ star_target_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Starred ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19477,7 +19477,7 @@ target_with_star_atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Attribute ( a , b -> v . Name . id , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19521,7 +19521,7 @@ target_with_star_atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Subscript ( a , b , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19597,7 +19597,7 @@ star_atom_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); _res = _PyPegen_set_expr_context ( p , a , Store ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19627,7 +19627,7 @@ star_atom_rule(Parser *p) { D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'")); _res = _PyPegen_set_expr_context ( p , a , Store ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19666,7 +19666,7 @@ star_atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( a , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19705,7 +19705,7 @@ star_atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_List ( a , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19767,7 +19767,7 @@ single_target_rule(Parser *p) { D(fprintf(stderr, "%*c+ single_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); _res = _PyPegen_set_expr_context ( p , a , Store ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19797,7 +19797,7 @@ single_target_rule(Parser *p) { D(fprintf(stderr, "%*c+ single_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19868,7 +19868,7 @@ single_subscript_attribute_target_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Attribute ( a , b -> v . Name . id , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -19912,7 +19912,7 @@ single_subscript_attribute_target_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Subscript ( a , b , Store , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20022,7 +20022,7 @@ t_primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Attribute ( a , b -> v . Name . id , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20066,7 +20066,7 @@ t_primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Subscript ( a , b , Load , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20104,7 +20104,7 @@ t_primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Call ( a , CHECK ( asdl_expr_seq* , ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20148,7 +20148,7 @@ t_primary_raw(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20174,7 +20174,7 @@ t_primary_raw(Parser *p) { D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20297,7 +20297,7 @@ del_targets_rule(Parser *p) { D(fprintf(stderr, "%*c+ del_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20373,7 +20373,7 @@ del_target_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Attribute ( a , b -> v . Name . id , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20417,7 +20417,7 @@ del_target_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Subscript ( a , b , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20489,7 +20489,7 @@ del_t_atom_rule(Parser *p) { D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); _res = _PyPegen_set_expr_context ( p , a , Del ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20519,7 +20519,7 @@ del_t_atom_rule(Parser *p) { D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'")); _res = _PyPegen_set_expr_context ( p , a , Del ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20558,7 +20558,7 @@ del_t_atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_Tuple ( a , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20597,7 +20597,7 @@ del_t_atom_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_List ( a , Del , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20665,7 +20665,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , CHECK ( asdl_seq* , _PyPegen_seq_append_to_end ( p , a , b ) ) , c ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20698,7 +20698,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20731,7 +20731,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20767,7 +20767,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , CHECK ( asdl_seq* , _PyPegen_singleton_seq ( p , a ) ) , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20794,7 +20794,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression")); _res = ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20821,7 +20821,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression")); _res = ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20845,7 +20845,7 @@ type_expressions_rule(Parser *p) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20896,7 +20896,7 @@ func_type_comment_rule(Parser *p) { D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); _res = t; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -20990,7 +20990,7 @@ invalid_arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "iterable argument unpacking follows keyword argument unpacking" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21024,7 +21024,7 @@ invalid_arguments_rule(Parser *p) { 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]")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , _PyPegen_get_last_comprehension_item ( PyPegen_last_item ( b , comprehension_ty ) ) , "Generator expression must be parenthesized" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21057,7 +21057,7 @@ invalid_arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21090,7 +21090,7 @@ invalid_arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected argument value expression" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21117,7 +21117,7 @@ invalid_arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); _res = _PyPegen_nonparen_genexp_in_call ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21150,7 +21150,7 @@ invalid_arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , _PyPegen_get_last_comprehension_item ( PyPegen_last_item ( b , comprehension_ty ) ) , "Generator expression must be parenthesized" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21180,7 +21180,7 @@ invalid_arguments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' args")); _res = _PyPegen_arguments_parsing_error ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21230,7 +21230,7 @@ invalid_kwarg_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('True' | 'False' | 'None') '='")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to %s" , PyBytes_AS_STRING ( a -> bytes ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21263,7 +21263,7 @@ invalid_kwarg_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21292,7 +21292,7 @@ invalid_kwarg_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expression cannot contain assignment, perhaps you meant \"==\"?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21325,7 +21325,7 @@ invalid_kwarg_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression '=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to keyword argument unpacking" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21407,7 +21407,7 @@ expression_without_invalid_rule(Parser *p) int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro _res = _PyAST_IfExp ( b , a , c , EXTRA ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->call_invalid_rules = _prev_call_invalid; p->level--; @@ -21497,7 +21497,7 @@ invalid_legacy_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_legacy_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME !'(' star_expressions")); _res = _PyPegen_check_legacy_stmt ( p , a ) ? RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Missing parentheses in call to '%U'. Did you mean %U(...)?" , a -> v . Name . id , a -> v . Name . id ) : NULL; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21549,7 +21549,7 @@ invalid_type_param_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME ':' expression")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with TypeVarTuple" : "cannot use bound with TypeVarTuple" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21582,7 +21582,7 @@ invalid_type_param_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME ':' expression")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with ParamSpec" : "cannot use bound with ParamSpec" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21638,7 +21638,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING ((!STRING expression_without_invalid))+ STRING")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( PyPegen_first_item ( a , expr_ty ) , PyPegen_last_item ( a , expr_ty ) , "invalid syntax. Is this intended to be part of the string?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21667,7 +21667,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid")); _res = _PyPegen_raise_error_for_missing_comma ( p , a , b ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21699,7 +21699,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected 'else' after 'if' expression" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21734,7 +21734,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' !expression")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "expected expression after 'else', but statement is given" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21770,7 +21770,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(pass_stmt | break_stmt | continue_stmt) 'if' disjunction 'else' simple_stmt")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected expression before 'if', but statement is given" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21803,7 +21803,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "f-string: lambda expressions are not allowed without parentheses" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21836,7 +21836,7 @@ invalid_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &TSTRING_MIDDLE")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "t-string: lambda expressions are not allowed without parentheses" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21893,7 +21893,7 @@ invalid_if_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_if_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' '*'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot unpack only part of a conditional expression" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21929,7 +21929,7 @@ invalid_if_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_if_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' '**'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use dict unpacking on only part of a conditional expression" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -21985,7 +21985,7 @@ invalid_named_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use assignment expressions with %s" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22017,7 +22017,7 @@ invalid_named_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22051,7 +22051,7 @@ invalid_named_expression_rule(Parser *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 !('=' | ':=')")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot assign to %s here. Maybe you meant '==' instead of '='?" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22107,7 +22107,7 @@ invalid_assignment_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not %s) can be annotated" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22143,7 +22143,7 @@ invalid_assignment_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not tuple) can be annotated" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22173,7 +22173,7 @@ invalid_assignment_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal target for annotation" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22203,7 +22203,7 @@ invalid_assignment_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22233,7 +22233,7 @@ invalid_assignment_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "assignment to yield expression not possible" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22263,7 +22263,7 @@ invalid_assignment_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign annotated_rhs")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22350,7 +22350,7 @@ invalid_ann_assign_target_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_ann_assign_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22396,7 +22396,7 @@ invalid_raise_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' 'from'")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "did you forget an expression between 'raise' and 'from'?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22426,7 +22426,7 @@ invalid_raise_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' expression 'from'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "did you forget an expression after 'from'?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22472,7 +22472,7 @@ invalid_del_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' star_expressions")); _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( DEL_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22528,7 +22528,7 @@ invalid_assert_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression '=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to %s here. Maybe you meant '==' instead of '='?" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22567,7 +22567,7 @@ invalid_assert_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression ',' expression '=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to %s here. Maybe you meant '==' instead of '='?" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22600,7 +22600,7 @@ invalid_assert_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression ':=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use named expression without parentheses here" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22639,7 +22639,7 @@ invalid_assert_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression ',' expression ':=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use named expression without parentheses here" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22684,7 +22684,7 @@ invalid_block_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22740,7 +22740,7 @@ invalid_comprehension_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' '**' expression for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use dict unpacking in list comprehension" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22773,7 +22773,7 @@ invalid_comprehension_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' '**' expression for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use dict unpacking in generator expression" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22809,7 +22809,7 @@ invalid_comprehension_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , PyPegen_last_item ( b , expr_ty ) , "did you forget parentheses around the comprehension target?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22842,7 +22842,7 @@ invalid_comprehension_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_comprehension[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "did you forget parentheses around the comprehension target?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22894,7 +22894,7 @@ invalid_parameters_rule(Parser *p) { 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 parameter must precede /" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22924,7 +22924,7 @@ invalid_parameters_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22958,7 +22958,7 @@ invalid_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "parameter without a default follows parameter with a default" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -22995,7 +22995,7 @@ invalid_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Function parameters cannot be parenthesized" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23035,7 +23035,7 @@ invalid_parameters_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23065,7 +23065,7 @@ invalid_parameters_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23110,7 +23110,7 @@ invalid_default_rule(Parser *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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23160,7 +23160,7 @@ invalid_star_etc_rule(Parser *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 parameters must follow bare *" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23190,7 +23190,7 @@ invalid_star_etc_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23220,7 +23220,7 @@ invalid_star_etc_rule(Parser *p) { 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 parameter cannot have default value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23256,7 +23256,7 @@ invalid_star_etc_rule(Parser *p) { 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 , "* may appear only once" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23305,7 +23305,7 @@ invalid_kwds_rule(Parser *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 , "var-keyword parameter cannot have default value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23338,7 +23338,7 @@ invalid_kwds_rule(Parser *p) { 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 , "parameters cannot follow var-keyword parameter" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23371,7 +23371,7 @@ invalid_kwds_rule(Parser *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 , "parameters cannot follow var-keyword parameter" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23414,7 +23414,7 @@ invalid_parameters_helper_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23485,7 +23485,7 @@ invalid_lambda_parameters_rule(Parser *p) { 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 parameter must precede /" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23515,7 +23515,7 @@ invalid_lambda_parameters_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23549,7 +23549,7 @@ invalid_lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "parameter without a default follows parameter with a default" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23586,7 +23586,7 @@ invalid_lambda_parameters_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Lambda expression parameters cannot be parenthesized" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23626,7 +23626,7 @@ invalid_lambda_parameters_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23656,7 +23656,7 @@ invalid_lambda_parameters_rule(Parser *p) { 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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23701,7 +23701,7 @@ invalid_lambda_parameters_helper_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23769,7 +23769,7 @@ invalid_lambda_star_etc_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); _res = RAISE_SYNTAX_ERROR ( "named parameters must follow bare *" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23799,7 +23799,7 @@ invalid_lambda_star_etc_rule(Parser *p) { 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 parameter cannot have default value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23835,7 +23835,7 @@ invalid_lambda_star_etc_rule(Parser *p) { 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 , "* may appear only once" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23887,7 +23887,7 @@ invalid_lambda_kwds_rule(Parser *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 , "var-keyword parameter cannot have default value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23920,7 +23920,7 @@ invalid_lambda_kwds_rule(Parser *p) { 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 , "parameters cannot follow var-keyword parameter" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -23953,7 +23953,7 @@ invalid_lambda_kwds_rule(Parser *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 , "parameters cannot follow var-keyword parameter" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24008,7 +24008,7 @@ invalid_double_type_comments_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_double_type_comments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); _res = RAISE_SYNTAX_ERROR ( "Cannot have two type comments on def" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24059,7 +24059,7 @@ invalid_with_item_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24111,7 +24111,7 @@ invalid_for_if_clause_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' (bitwise_or ((',' bitwise_or))* ','?) !'in'")); _res = RAISE_SYNTAX_ERROR ( "'in' expected after for-loop variables" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24161,7 +24161,7 @@ invalid_for_target_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_for_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_expressions")); _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( FOR_TARGETS , a ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24210,7 +24210,7 @@ invalid_group_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use starred expression here" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24243,7 +24243,7 @@ invalid_group_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_group[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use double starred expression here" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24295,7 +24295,7 @@ invalid_import_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_import[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "Did you mean to use 'from ... import ...' instead?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24322,7 +24322,7 @@ invalid_import_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_import[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' NEWLINE")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( token , "Expected one or more names after 'import'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24373,7 +24373,7 @@ invalid_dotted_as_name_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_dotted_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name 'as' !(NAME (',' | ')' | ';' | NEWLINE)) expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use %s as import target" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24424,7 +24424,7 @@ invalid_import_from_as_name_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_import_from_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME 'as' !(NAME (',' | ')' | ';' | NEWLINE)) expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use %s as import target" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24473,7 +24473,7 @@ invalid_import_from_targets_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "trailing comma not allowed without surrounding parentheses" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24497,7 +24497,7 @@ invalid_import_from_targets_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( token , "Expected one or more names after 'import'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24556,7 +24556,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' ','.(expression ['as' star_target])+ ',' ':'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( trailing , "the last 'with' item has a trailing comma" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24590,7 +24590,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' ','.(expression ['as' star_target])+ NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24634,7 +24634,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])+ ','? ')' NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24694,7 +24694,7 @@ invalid_with_stmt_indent_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24743,7 +24743,7 @@ invalid_with_stmt_indent_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_with_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24798,7 +24798,7 @@ invalid_try_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'try' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24830,7 +24830,7 @@ invalid_try_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); _res = RAISE_SYNTAX_ERROR ( "expected 'except' or 'finally' block" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24879,7 +24879,7 @@ invalid_try_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':'")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot have both 'except' and 'except*' on the same 'try'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24922,7 +24922,7 @@ invalid_try_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot have both 'except' and 'except*' on the same 'try'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -24987,7 +24987,7 @@ invalid_except_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ',' expressions 'as' NAME ':'")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "multiple exception types must be parenthesized when using 'as'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25021,7 +25021,7 @@ invalid_except_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25048,7 +25048,7 @@ invalid_except_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25087,7 +25087,7 @@ invalid_except_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression 'as' expression ':' block")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use except statement with %s" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25155,7 +25155,7 @@ invalid_except_star_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_star_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ',' expressions 'as' NAME ':'")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "multiple exception types must be parenthesized when using 'as'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25192,7 +25192,7 @@ invalid_except_star_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_star_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ['as' NAME] NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25222,7 +25222,7 @@ invalid_except_star_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_star_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); _res = RAISE_SYNTAX_ERROR ( "expected one or more exception types" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25264,7 +25264,7 @@ invalid_except_star_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_star_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' expression 'as' expression ':' block")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use except* statement with %s" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25315,7 +25315,7 @@ invalid_finally_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_finally_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally' ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'finally' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25375,7 +25375,7 @@ invalid_except_stmt_indent_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25407,7 +25407,7 @@ invalid_except_stmt_indent_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25469,7 +25469,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_except_star_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ['as' NAME] ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except*' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25521,7 +25521,7 @@ invalid_match_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr NEWLINE")); _res = CHECK_VERSION ( void* , 10 , "Pattern matching is" , RAISE_SYNTAX_ERROR ( "expected ':'" ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25556,7 +25556,7 @@ invalid_match_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'match' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25593,7 +25593,7 @@ invalid_match_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "case statement must be inside match statement" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25648,7 +25648,7 @@ invalid_case_block_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25687,7 +25687,7 @@ invalid_case_block_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'case' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25736,7 +25736,7 @@ invalid_as_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' \"_\"")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use '_' as a target" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25766,7 +25766,7 @@ invalid_as_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use %s as pattern target" , _PyPegen_get_expr_name ( a ) ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25815,7 +25815,7 @@ invalid_class_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' invalid_class_argument_pattern")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( PyPegen_first_item ( a , pattern_ty ) , PyPegen_last_item ( a , pattern_ty ) , "positional patterns follow keyword patterns" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25879,7 +25879,7 @@ invalid_mapping_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' [(items_pattern ',')] double_star_pattern ',' items_pattern ','? '}'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( rest , "double star pattern must be the last (right-most) subpattern in the mapping pattern" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25933,7 +25933,7 @@ invalid_class_argument_pattern_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_class_argument_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[positional_patterns ','] keyword_patterns ',' positional_patterns")); _res = a; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -25984,7 +25984,7 @@ invalid_if_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26019,7 +26019,7 @@ invalid_if_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'if' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26070,7 +26070,7 @@ invalid_elif_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26105,7 +26105,7 @@ invalid_elif_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'elif' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26156,7 +26156,7 @@ invalid_else_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_else_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'else' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26189,7 +26189,7 @@ invalid_else_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_else_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':' block 'elif'")); _res = RAISE_SYNTAX_ERROR ( "'elif' block follows an 'else' block" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26240,7 +26240,7 @@ invalid_while_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26275,7 +26275,7 @@ invalid_while_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'while' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26336,7 +26336,7 @@ invalid_for_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26381,7 +26381,7 @@ invalid_for_stmt_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'for' statement on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26459,7 +26459,7 @@ invalid_def_raw_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'? 'def' NAME type_params? '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after function definition on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26572,7 +26572,7 @@ invalid_class_def_raw_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26615,7 +26615,7 @@ invalid_class_def_raw_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after class definition on line %d" , a -> lineno ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26714,7 +26714,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, "expression ':' &('}' | ',')")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression expected after dictionary key and ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26765,7 +26765,7 @@ invalid_kvpair_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' if_expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid double starred expression. Did you forget to wrap the conditional expression in parentheses?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26798,7 +26798,7 @@ invalid_kvpair_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or ':' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use a starred expression in a dictionary key" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26831,7 +26831,7 @@ invalid_kvpair_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or ':' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use dict unpacking in a dictionary key" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26864,7 +26864,7 @@ invalid_kvpair_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use a starred expression in a dictionary value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26897,7 +26897,7 @@ invalid_kvpair_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' '**' bitwise_or")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot use dict unpacking in a dictionary value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26946,7 +26946,7 @@ invalid_kvpair_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !(':')")); _res = RAISE_ERROR_KNOWN_LOCATION ( p , PyExc_SyntaxError , a -> lineno , a -> end_col_offset - 1 , a -> end_lineno , - 1 , "':' expected after dictionary key" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -26979,7 +26979,7 @@ invalid_kvpair_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "cannot use a starred expression in a dictionary value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27012,7 +27012,7 @@ invalid_kvpair_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' '**' bitwise_or")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "cannot use dict unpacking in a dictionary value" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27041,7 +27041,7 @@ invalid_kvpair_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression expected after dictionary key and ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27087,7 +27087,7 @@ invalid_starred_expression_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_starred_expression_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' if_expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid starred expression. Did you forget to wrap the conditional expression in parentheses?" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27120,7 +27120,7 @@ invalid_starred_expression_unpacking_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_starred_expression_unpacking[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression '=' expression")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to iterable argument unpacking" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27168,7 +27168,7 @@ invalid_starred_expression_unpacking_sequence_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_starred_expression_unpacking_sequence[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use dict unpacking here" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27230,7 +27230,7 @@ invalid_starred_expression_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = RAISE_SYNTAX_ERROR ( "Invalid star expression" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27287,7 +27287,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '='")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before '='" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27314,7 +27314,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '!'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before '!'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27341,7 +27341,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' ':'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27368,7 +27368,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '}'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27394,7 +27394,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !annotated_rhs")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting a valid expression after '{'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27423,7 +27423,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs !('=' | '!' | ':' | '}')")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '=', or '!', or ':', or '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27455,7 +27455,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '=' !('!' | ':' | '}')")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '!', or ':', or '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27521,7 +27521,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!' NAME] !(':' | '}')")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting ':' or '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27564,7 +27564,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!' NAME] ':' fstring_format_spec* !'}'")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '}', or format specs" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27601,7 +27601,7 @@ invalid_fstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!' NAME] !'}'")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27646,7 +27646,7 @@ invalid_fstring_conversion_character_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: missing conversion character" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27672,7 +27672,7 @@ invalid_fstring_conversion_character_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_fstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' !NAME")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: invalid conversion character" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27729,7 +27729,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '='")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "t-string: valid expression required before '='" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27756,7 +27756,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '!'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "t-string: valid expression required before '!'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27783,7 +27783,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' ':'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "t-string: valid expression required before ':'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27810,7 +27810,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '}'")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "t-string: valid expression required before '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27836,7 +27836,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !annotated_rhs")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: expecting a valid expression after '{'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27865,7 +27865,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs !('=' | '!' | ':' | '}')")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: expecting '=', or '!', or ':', or '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27897,7 +27897,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '=' !('!' | ':' | '}')")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: expecting '!', or ':', or '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -27963,7 +27963,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!' NAME] !(':' | '}')")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: expecting ':' or '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28006,7 +28006,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!' NAME] ':' fstring_format_spec* !'}'")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: expecting '}', or format specs" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28043,7 +28043,7 @@ invalid_tstring_replacement_field_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!' NAME] !'}'")); _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: expecting '}'" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28088,7 +28088,7 @@ invalid_tstring_conversion_character_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: missing conversion character" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28114,7 +28114,7 @@ invalid_tstring_conversion_character_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_tstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' !NAME")); _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "t-string: invalid conversion character" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28162,7 +28162,7 @@ invalid_string_tstring_concat_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_string_tstring_concat[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((fstring | string))+ tstring")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( PyPegen_last_item ( a , expr_ty ) , b , "cannot mix t-string literals with string or bytes literals" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28189,7 +28189,7 @@ invalid_string_tstring_concat_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_string_tstring_concat[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tstring+ (fstring | string)")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( PyPegen_last_item ( a , expr_ty ) , b , "cannot mix t-string literals with string or bytes literals" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28241,7 +28241,7 @@ invalid_arithmetic_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_arithmetic[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum ('+' | '-' | '*' | '/' | '%' | '//' | '@') 'not' inversion")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "'not' after an operator must be parenthesized" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28290,7 +28290,7 @@ invalid_factor_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('+' | '-' | '~') 'not' factor")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "'not' after an operator must be parenthesized" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28336,7 +28336,7 @@ invalid_type_params_rule(Parser *p) { D(fprintf(stderr, "%*c+ invalid_type_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' ']'")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( token , "Type parameter list cannot be empty" ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -28529,7 +28529,7 @@ _loop0_3_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -28961,7 +28961,7 @@ _tmp_10_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); _res = d; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -29010,7 +29010,7 @@ _tmp_11_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); _res = b; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -29155,7 +29155,7 @@ _loop0_13_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -29321,7 +29321,7 @@ _tmp_16_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = z; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -29514,7 +29514,7 @@ _loop0_19_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -29623,7 +29623,7 @@ _tmp_21_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_21[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -29677,7 +29677,7 @@ _loop0_22_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -29861,7 +29861,7 @@ _tmp_25_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_25[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = z; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -29907,7 +29907,7 @@ _tmp_26_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_26[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = z; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -30378,7 +30378,7 @@ _loop0_33_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -30787,7 +30787,7 @@ _loop0_39_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -31113,7 +31113,7 @@ _loop0_44_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -31230,7 +31230,7 @@ _loop0_46_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -31404,7 +31404,7 @@ _loop0_49_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -31521,7 +31521,7 @@ _loop0_51_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -31638,7 +31638,7 @@ _loop0_53_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -31899,7 +31899,7 @@ _loop0_57_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -32016,7 +32016,7 @@ _loop0_59_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -32338,7 +32338,7 @@ _tmp_64_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_64[%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()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -32392,7 +32392,7 @@ _loop0_65_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -32501,7 +32501,7 @@ _tmp_67_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); _res = d; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -33664,7 +33664,7 @@ _tmp_84_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_84[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression_sequence ',' star_named_expressions_sequence?")); _res = _PyPegen_seq_insert_in_front ( p , y , z ); - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -33718,7 +33718,7 @@ _loop0_85_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -34052,7 +34052,7 @@ _loop0_90_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -34162,7 +34162,7 @@ _tmp_92_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); _res = k; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -34216,7 +34216,7 @@ _loop0_93_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -34333,7 +34333,7 @@ _loop0_95_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -34517,7 +34517,7 @@ _loop0_98_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -34746,7 +34746,7 @@ _loop0_102_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -34863,7 +34863,7 @@ _loop0_104_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -35080,7 +35080,7 @@ _loop0_108_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -36539,7 +36539,7 @@ _loop0_131_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -36875,7 +36875,7 @@ _loop0_137_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -37033,7 +37033,7 @@ _loop0_140_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -37150,7 +37150,7 @@ _loop0_142_rule(Parser *p) ) { _res = elem; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); p->level--; @@ -38232,7 +38232,7 @@ _tmp_159_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -38338,7 +38338,7 @@ _tmp_161_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -38384,7 +38384,7 @@ _tmp_162_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -38430,7 +38430,7 @@ _tmp_163_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -38476,7 +38476,7 @@ _tmp_164_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -38579,7 +38579,7 @@ _tmp_166_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; @@ -38684,7 +38684,7 @@ _tmp_168_rule(Parser *p) { D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; - if (_res == NULL && PyErr_Occurred()) { + if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) { p->error_indicator = 1; p->level--; return NULL; diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index a4e111972bdad5..d9236dfb22835b 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -739,7 +739,7 @@ def join_conditions(self, keyword: str, node: Any) -> None: def emit_action(self, node: Alt, cleanup_code: str | None = None) -> None: self.print(f"_res = {node.action};") - self.print("if (_res == NULL && PyErr_Occurred()) {") + self.print("if ((_res == NULL || p->error_indicator) && PyErr_Occurred()) {") with self.indent(): self.print("p->error_indicator = 1;") if cleanup_code: From 962fb872ebd97ab6ab808a1b8e2034577e5501bf Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 13 Mar 2026 13:05:41 +0200 Subject: [PATCH 441/498] gh-145850: Change some implementation details in struct.Struct (GH-145851) * calling it with non-ASCII string format will now raise a ValueError instead of UnicodeEncodeError * calling it with non-ASCII bytes format will now raise a ValueError instead of struct.error * getting the format attribute of uninitialized object will now raise an AttributeError instead of RuntimeError. --- Lib/test/test_struct.py | 21 ++++-- ...-03-12-12-17-39.gh-issue-145850.uW3stt.rst | 6 ++ Modules/_struct.c | 68 +++++++------------ Modules/_xxtestfuzz/fuzzer.c | 4 ++ 4 files changed, 48 insertions(+), 51 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-12-12-17-39.gh-issue-145850.uW3stt.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index e3e02097b1f550..c7dc69defded50 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -605,7 +605,7 @@ def test_Struct_reinitialization(self): self.assertEqual(s.unpack(packed), (1, 2)) with self.assertWarnsRegex(FutureWarning, msg): - with self.assertRaises(UnicodeEncodeError): + with self.assertRaises(ValueError): s.__init__('\udc00') self.assertEqual(s.format, '>hh') self.assertEqual(s.pack(1, 2), packed) @@ -872,10 +872,10 @@ def __init__(self, *args, **kwargs): with self.assertWarnsRegex(DeprecationWarning, warnmsg + 'bad char'): my_struct = MyStruct(format='$') self.assertEqual(my_struct.pack(12345), b'\x30\x39') - with self.assertWarnsRegex(DeprecationWarning, warnmsg + ".*can't encode"): + with self.assertWarnsRegex(DeprecationWarning, warnmsg + "non-ASCII"): my_struct = MyStruct('\udc00') self.assertEqual(my_struct.pack(12345), b'\x30\x39') - with self.assertWarnsRegex(DeprecationWarning, warnmsg + ".*can't encode"): + with self.assertWarnsRegex(DeprecationWarning, warnmsg + "non-ASCII"): my_struct = MyStruct(format='\udc00') self.assertEqual(my_struct.pack(12345), b'\x30\x39') @@ -928,11 +928,16 @@ def __init__(self, newargs, initargs): with self.assertWarns(FutureWarning): with self.assertRaises(struct.error): MyStruct(('>h',), ('$',)) - with self.assertRaises(UnicodeEncodeError): + with self.assertRaises(ValueError): MyStruct(('\udc00',), ('>h',)) + with self.assertRaises(ValueError): + MyStruct((b'\xa4',), ('>h',)) with self.assertWarns(FutureWarning): - with self.assertRaises(UnicodeEncodeError): + with self.assertRaises(ValueError): MyStruct(('>h',), ('\udc00',)) + with self.assertWarns(FutureWarning): + with self.assertRaises(ValueError): + MyStruct(('>h',), (b'\xa4',)) with self.assertWarns(FutureWarning): my_struct = MyStruct(('>h',), ('h', 42) with self.assertRaises(TypeError): @@ -1004,7 +1011,7 @@ def test_operations_on_half_initialized_Struct(self): self.assertRaises(RuntimeError, S.pack_into, spam, 1) self.assertRaises(RuntimeError, S.unpack, spam) self.assertRaises(RuntimeError, S.unpack_from, spam) - self.assertRaises(RuntimeError, getattr, S, 'format') + self.assertRaises(AttributeError, getattr, S, 'format') self.assertRaises(RuntimeError, S.__sizeof__) self.assertRaises(RuntimeError, repr, S) self.assertEqual(S.size, -1) diff --git a/Misc/NEWS.d/next/Library/2026-03-12-12-17-39.gh-issue-145850.uW3stt.rst b/Misc/NEWS.d/next/Library/2026-03-12-12-17-39.gh-issue-145850.uW3stt.rst new file mode 100644 index 00000000000000..35ba57a95b0e7e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-12-12-17-39.gh-issue-145850.uW3stt.rst @@ -0,0 +1,6 @@ +Changed some implementation details in :class:`struct.Struct`: calling it +with non-ASCII string format will now raise a :exc:`ValueError` instead of +:exc:`UnicodeEncodeError`, calling it with non-ASCII bytes format will now +raise a :exc:`ValueError` instead of :exc:`struct.error`, getting +the :attr:`!format` attribute of uninitialized object will now raise an +:exc:`AttributeError` instead of :exc:`RuntimeError`. diff --git a/Modules/_struct.c b/Modules/_struct.c index 7eddc9bdc38a89..2059218029ea34 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1635,8 +1635,12 @@ prepare_s(PyStructObject *self, PyObject *format) _structmodulestate *state = get_struct_state_structinst(self); - fmt = PyBytes_AS_STRING(format); - if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(format)) { + if (!PyUnicode_IS_ASCII(format)) { + PyErr_SetString(PyExc_ValueError, "non-ASCII character in struct format"); + return -1; + } + fmt = (const char *)PyUnicode_1BYTE_DATA(format); + if (strlen(fmt) != (size_t)PyUnicode_GET_LENGTH(format)) { PyErr_SetString(state->StructError, "embedded null character"); return -1; @@ -1780,12 +1784,11 @@ static int set_format(PyStructObject *self, PyObject *format) { if (PyUnicode_Check(format)) { - format = PyUnicode_AsASCIIString(format); - if (format == NULL) - return -1; + format = PyUnicode_FromObject(format); } else if (PyBytes_Check(format)) { - Py_INCREF(format); + format = PyUnicode_DecodeASCII(PyBytes_AS_STRING(format), + PyBytes_GET_SIZE(format), "surrogateescape"); } else { PyErr_Format(PyExc_TypeError, @@ -1793,6 +1796,9 @@ set_format(PyStructObject *self, PyObject *format) "not %T", format); return -1; } + if (format == NULL) { + return -1; + } if (prepare_s(self, format)) { Py_DECREF(format); return -1; @@ -1821,7 +1827,7 @@ Struct_impl(PyTypeObject *type, PyObject *format) if (self == NULL) { return NULL; } - self->s_format = Py_NewRef(Py_None); + self->s_format = NULL; self->s_codes = NULL; self->s_size = -1; self->s_len = -1; @@ -1878,7 +1884,7 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self == NULL) { return NULL; } - self->s_format = Py_NewRef(Py_None); + self->s_format = NULL; self->s_codes = NULL; self->s_size = -1; self->s_len = -1; @@ -1892,7 +1898,7 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } PyObject *exc = PyErr_GetRaisedException(); - Py_SETREF(self->s_format, Py_NewRef(Py_None)); + Py_CLEAR(self->s_format); if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "Invalid 'format' argument for Struct.__new__(): %S", exc)) { @@ -1910,8 +1916,8 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static bool same_format(PyStructObject *s, PyObject *format) { - Py_ssize_t size = PyBytes_GET_SIZE(s->s_format); - const void *data = PyBytes_AS_STRING(s->s_format); + Py_ssize_t size = PyUnicode_GET_LENGTH(s->s_format); + const void *data = PyUnicode_1BYTE_DATA(s->s_format); if (PyUnicode_Check(format) && PyUnicode_IS_ASCII(format)) { return PyUnicode_GET_LENGTH(format) == size && memcmp(PyUnicode_1BYTE_DATA(format), data, size) == 0; @@ -1938,7 +1944,7 @@ static int Struct___init___impl(PyStructObject *self, PyObject *format) /*[clinic end generated code: output=b8e80862444e92d0 input=1af78a5f57d82cec]*/ { - if (self->s_format == Py_None) { + if (self->s_format == NULL) { if (set_format(self, format) < 0) { return -1; } @@ -1965,7 +1971,7 @@ s_init(PyObject *self, PyObject *args, PyObject *kwargs) { if (!((PyStructObject *)self)->init_called && Py_TYPE(self)->tp_init == s_init - && ((PyStructObject *)self)->s_format != Py_None) + && ((PyStructObject *)self)->s_format != NULL) { /* Struct.__init__() was called implicitly. * __new__() already did all the work. */ @@ -2508,22 +2514,6 @@ Struct_pack_into_impl(PyStructObject *self, Py_buffer *buffer, Py_RETURN_NONE; } -static PyObject * -s_get_format(PyObject *op, void *Py_UNUSED(closure)) -{ - PyStructObject *self = PyStructObject_CAST(op); - ENSURE_STRUCT_IS_READY(self); - return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format), - PyBytes_GET_SIZE(self->s_format)); -} - -static PyObject * -s_get_size(PyObject *op, void *Py_UNUSED(closure)) -{ - PyStructObject *self = PyStructObject_CAST(op); - return PyLong_FromSsize_t(self->s_size); -} - /*[clinic input] Struct.__sizeof__ [clinic start generated code]*/ @@ -2545,14 +2535,7 @@ s_repr(PyObject *op) { PyStructObject *self = PyStructObject_CAST(op); ENSURE_STRUCT_IS_READY(self); - PyObject* fmt = PyUnicode_FromStringAndSize( - PyBytes_AS_STRING(self->s_format), PyBytes_GET_SIZE(self->s_format)); - if (fmt == NULL) { - return NULL; - } - PyObject* s = PyUnicode_FromFormat("%s(%R)", _PyType_Name(Py_TYPE(self)), fmt); - Py_DECREF(fmt); - return s; + return PyUnicode_FromFormat("%s(%R)", _PyType_Name(Py_TYPE(self)), self->s_format); } /* List of functions */ @@ -2569,15 +2552,13 @@ static struct PyMethodDef s_methods[] = { static PyMemberDef s_members[] = { {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(PyStructObject, weakreflist), Py_READONLY}, + {"format", Py_T_OBJECT_EX, offsetof(PyStructObject, s_format), + Py_READONLY, PyDoc_STR("struct format string")}, + {"size", Py_T_PYSSIZET, offsetof(PyStructObject, s_size), Py_READONLY, + PyDoc_STR("struct size in bytes")}, {NULL} /* sentinel */ }; -static PyGetSetDef s_getsetlist[] = { - {"format", s_get_format, NULL, PyDoc_STR("struct format string"), NULL}, - {"size", s_get_size, NULL, PyDoc_STR("struct size in bytes"), NULL}, - {NULL} /* sentinel */ -}; - static PyType_Slot PyStructType_slots[] = { {Py_tp_dealloc, s_dealloc}, {Py_tp_getattro, PyObject_GenericGetAttr}, @@ -2588,7 +2569,6 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_clear, s_clear}, {Py_tp_methods, s_methods}, {Py_tp_members, s_members}, - {Py_tp_getset, s_getsetlist}, {Py_tp_init, s_init}, {Py_tp_new, s_new}, {0, 0}, diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index f3a22f3f6a87cb..6cb11562476e40 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -133,6 +133,10 @@ static int fuzz_struct_unpack(const char* data, size_t size) { if (unpacked == NULL && PyErr_ExceptionMatches(PyExc_SystemError)) { PyErr_Clear(); } + /* Ignore any ValueError, these are triggered by non-ASCII format. */ + if (unpacked == NULL && PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + } /* Ignore any struct.error exceptions, these can be caused by invalid formats or incomplete buffers both of which are common. */ if (unpacked == NULL && PyErr_ExceptionMatches(struct_error)) { From 0b6a2346e5b203fb988a382fdc3d51b36641fe1a Mon Sep 17 00:00:00 2001 From: devdanzin <74280297+devdanzin@users.noreply.github.com> Date: Fri, 13 Mar 2026 08:57:35 -0300 Subject: [PATCH 442/498] gh-145887: Use `write()` instead of `stream.write()` in `PrettyPrinter._pprint_frozendict` (#145894) --- Lib/pprint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/pprint.py b/Lib/pprint.py index e111bd59d4152c..a0e484b1c097c3 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -238,7 +238,7 @@ def _pprint_dict(self, object, stream, indent, allowance, context, level): def _pprint_frozendict(self, object, stream, indent, allowance, context, level): write = stream.write cls = object.__class__ - stream.write(cls.__name__ + '(') + write(cls.__name__ + '(') length = len(object) if length: self._pprint_dict(object, stream, From 59d97683c19923b06e2b2110efadb90fe37f53f3 Mon Sep 17 00:00:00 2001 From: VanshAgarwal24036 <148854295+VanshAgarwal24036@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:45:26 +0530 Subject: [PATCH 443/498] gh-145792: Fix incorrect alloca allocation size in traceback.c (#145814) --- .../2026-03-11-19-09-47.gh-issue-145792.X5KUhc.rst | 2 ++ Python/traceback.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-19-09-47.gh-issue-145792.X5KUhc.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-19-09-47.gh-issue-145792.X5KUhc.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-19-09-47.gh-issue-145792.X5KUhc.rst new file mode 100644 index 00000000000000..bd42f32d6ae3f5 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-19-09-47.gh-issue-145792.X5KUhc.rst @@ -0,0 +1,2 @@ +Fix out-of-bounds access when invoking faulthandler on a CPython build +compiled without support for VLAs. diff --git a/Python/traceback.c b/Python/traceback.c index 74360a1c73c271..1e8c9c879f9aac 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -41,7 +41,7 @@ #if defined(__STDC_NO_VLA__) && (__STDC_NO_VLA__ == 1) /* Use alloca() for VLAs. */ -# define VLA(type, name, size) type *name = alloca(size) +# define VLA(type, name, size) type *name = alloca(sizeof(type) * (size)) #elif !defined(__STDC_NO_VLA__) || (__STDC_NO_VLA__ == 0) /* Use actual C VLAs.*/ # define VLA(type, name, size) type name[size] From 9162238511197be119c5e7cdc554c1e39522a946 Mon Sep 17 00:00:00 2001 From: Furkan Onder Date: Fri, 13 Mar 2026 21:38:06 +0900 Subject: [PATCH 444/498] gh-99631: Add shelve custom serialization to What's New in 3.15 (#145253) --- Doc/whatsnew/3.15.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 7daea13d31c83d..459846e55ccf70 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -912,6 +912,9 @@ shelve * Added new :meth:`!reorganize` method to :mod:`shelve` used to recover unused free space previously occupied by deleted entries. (Contributed by Andrea Oliveri in :gh:`134004`.) +* Add support for custom serialization and deserialization functions + in the :mod:`shelve` module. + (Contributed by Furkan Onder in :gh:`99631`.) socket From f884dc6f70fde3550a175ff7ddce79ccc38b3ec6 Mon Sep 17 00:00:00 2001 From: "Jason Yalim, PhD" <4813268+jyalim@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:00:39 -0700 Subject: [PATCH 445/498] gh-140715: Add %t and %n format codes support to strptime() (GH-144896) Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/datetime.rst | 14 +++++++++----- Lib/_strptime.py | 5 ++++- Lib/test/datetimetester.py | 14 ++++++++++++++ Lib/test/test_strptime.py | 17 +++++++++++++++++ Lib/test/test_time.py | 2 +- ...26-02-17-03-43-07.gh-issue-140715.twmcM_.rst | 1 + 6 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-17-03-43-07.gh-issue-140715.twmcM_.rst diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 73217136f14472..8993049a720b1c 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2611,8 +2611,10 @@ requires, and these work on all supported platforms. | ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) | | | decimal number. | | | +-----------+--------------------------------+------------------------+-------+ -| ``%n`` | The newline character | ``\n`` | \(0) | -| | (``'\n'``). | | | +| ``%n`` | The newline character | ``\n`` | | +| | (``'\n'``). For | | | +| | :meth:`!strptime`, zero or | | | +| | more whitespace. | | | +-----------+--------------------------------+------------------------+-------+ | ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), | | | AM or PM. || am, pm (de_DE) | \(3) | @@ -2625,8 +2627,9 @@ requires, and these work on all supported platforms. | ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), | | | decimal number. | | \(9) | +-----------+--------------------------------+------------------------+-------+ -| ``%t`` | The tab character | ``\t`` | \(0) | -| | (``'\t'``). | | | +| ``%t`` | The tab character (``'\t'``). | ``\t`` | | +| | For :meth:`!strptime`, | | | +| | zero or more whitespace. | | | +-----------+--------------------------------+------------------------+-------+ | ``%T`` | ISO 8601 time format, | 10:01:59 | | | | equivalent to ``%H:%M:%S``. | | | @@ -2717,7 +2720,8 @@ differences between platforms in handling of unsupported format specifiers. ``%:z`` was added for :meth:`~.datetime.strftime`. .. versionadded:: 3.15 - ``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`. + ``%D``, ``%F``, ``%n``, ``%t``, and ``%:z`` were added for + :meth:`~.datetime.strptime`. Technical detail diff --git a/Lib/_strptime.py b/Lib/_strptime.py index 0d81ff6765e1ed..3367ac485a590c 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -382,7 +382,10 @@ def __init__(self, locale_time=None): 'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone for tz in tz_names), 'Z'), - '%': '%'} + 'n': r'\s*', + 't': r'\s*', + '%': '%', + } if self.locale_time.LC_alt_digits is None: for d in 'dmyCHIMS': mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 97eec618932aa5..e264433ca590bf 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2207,6 +2207,20 @@ def test_strptime_D_format(self): self.theclass.strptime(test_date, "%m/%d/%y") ) + def test_strptime_n_and_t_format(self): + format_directives = ('%n', '%t', '%n%t', '%t%n') + whitespaces = ('', ' ', '\t', '\r', '\v', '\n', '\f') + for fd in format_directives: + for ws in (*whitespaces, ''.join(whitespaces)): + with self.subTest(format_directive=fd, whitespace=ws): + self.assertEqual( + self.theclass.strptime( + f"2026{ws}02{ws}03", + f"%Y{fd}%m{fd}%d", + ), + self.theclass(2026, 2, 3), + ) + ############################################################################# # datetime tests diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index fd8525feb88d53..dfc8ef6d2c5b7e 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -670,6 +670,23 @@ def test_strptime_D_format(self): time.strptime(test_date, "%m/%d/%y") ) + def test_strptime_n_and_t_format(self): + format_directives = ('%n', '%t', '%n%t', '%t%n') + whitespaces = ('', ' ', '\t', '\r', '\v', '\n', '\f') + for fd in format_directives: + for ws in (*whitespaces, ''.join(whitespaces)): + with self.subTest(format_directive=fd, whitespace=ws): + self.assertEqual( + time.strptime( + f"2026{ws}02{ws}03", + f"%Y{fd}%m{fd}%d", + ), + time.strptime( + f'2026-02-03', + "%Y-%m-%d", + ), + ) + class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index da5fd16b8b6291..be8f6b057654c2 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -359,7 +359,7 @@ def test_strptime(self): # raising an exception. tt = time.gmtime(self.t) for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'D', 'F', 'H', 'I', - 'j', 'm', 'M', 'p', 'S', 'T', + 'j', 'm', 'M', 'n', 'p', 'S', 't', 'T', 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): format = '%' + directive if directive == 'd': diff --git a/Misc/NEWS.d/next/Library/2026-02-17-03-43-07.gh-issue-140715.twmcM_.rst b/Misc/NEWS.d/next/Library/2026-02-17-03-43-07.gh-issue-140715.twmcM_.rst new file mode 100644 index 00000000000000..3bebc6660df825 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-17-03-43-07.gh-issue-140715.twmcM_.rst @@ -0,0 +1 @@ +Add ``%n`` and ``%t`` support to :meth:`~datetime.datetime.strptime`. From 61f2a1a5993967ed4b97ba93a4477c37fe68cf59 Mon Sep 17 00:00:00 2001 From: "Michiel W. Beijen" Date: Fri, 13 Mar 2026 14:10:48 +0100 Subject: [PATCH 446/498] GH-60729: Add IEEE format wave audio support (GH-145384) Co-authored-by: Lionel Koenig --- Doc/library/wave.rst | 69 ++++++- Doc/whatsnew/3.15.rst | 15 ++ Lib/test/audiodata/pluck-float32.wav | Bin 0 -> 26514 bytes Lib/test/audiotests.py | 16 +- Lib/test/test_wave.py | 188 +++++++++++++++++- Lib/wave.py | 88 ++++++-- ...3-03-10-13-10-06.gh-issue-60729.KCCHTe.rst | 1 + 7 files changed, 352 insertions(+), 25 deletions(-) create mode 100644 Lib/test/audiodata/pluck-float32.wav create mode 100644 Misc/NEWS.d/next/Library/2023-03-10-13-10-06.gh-issue-60729.KCCHTe.rst diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index ff020b52da3f23..9d30a14f112937 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -9,14 +9,19 @@ -------------- The :mod:`!wave` module provides a convenient interface to the Waveform Audio -"WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are -supported. +"WAVE" (or "WAV") file format. + +The module supports uncompressed PCM and IEEE floating-point WAV formats. .. versionchanged:: 3.12 Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the extended format is ``KSDATAFORMAT_SUBTYPE_PCM``. +.. versionchanged:: next + + Support for reading and writing ``WAVE_FORMAT_IEEE_FLOAT`` files was added. + The :mod:`!wave` module defines the following function and exception: @@ -60,6 +65,21 @@ The :mod:`!wave` module defines the following function and exception: specification or hits an implementation deficiency. +.. data:: WAVE_FORMAT_PCM + + Format code for uncompressed PCM audio. + + +.. data:: WAVE_FORMAT_IEEE_FLOAT + + Format code for IEEE floating-point audio. + + +.. data:: WAVE_FORMAT_EXTENSIBLE + + Format code for WAVE extensible headers. + + .. _wave-read-objects: Wave_read Objects @@ -98,6 +118,14 @@ Wave_read Objects Returns number of audio frames. + .. method:: getformat() + + Returns the frame format code. + + This is one of :data:`WAVE_FORMAT_PCM`, + :data:`WAVE_FORMAT_IEEE_FLOAT`, or :data:`WAVE_FORMAT_EXTENSIBLE`. + + .. method:: getcomptype() Returns compression type (``'NONE'`` is the only supported type). @@ -112,8 +140,8 @@ Wave_read Objects .. method:: getparams() Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth, - framerate, nframes, comptype, compname)``, equivalent to output of the - ``get*()`` methods. + framerate, nframes, comptype, compname)``, equivalent to output + of the ``get*()`` methods. .. method:: readframes(n) @@ -190,6 +218,9 @@ Wave_write Objects Set the sample width to *n* bytes. + For :data:`WAVE_FORMAT_IEEE_FLOAT`, only 4-byte (32-bit) and + 8-byte (64-bit) sample widths are supported. + .. method:: getsampwidth() @@ -238,11 +269,32 @@ Wave_write Objects Return the human-readable compression type name. + .. method:: setformat(format) + + Set the frame format code. + + Supported values are :data:`WAVE_FORMAT_PCM` and + :data:`WAVE_FORMAT_IEEE_FLOAT`. + + When setting :data:`WAVE_FORMAT_IEEE_FLOAT`, the sample width must be + 4 or 8 bytes. + + + .. method:: getformat() + + Return the current frame format code. + + .. method:: setparams(tuple) - The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype, - compname)``, with values valid for the ``set*()`` methods. Sets all - parameters. + The *tuple* should be + ``(nchannels, sampwidth, framerate, nframes, comptype, compname, format)``, + with values valid for the ``set*()`` methods. Sets all parameters. + + For backwards compatibility, a 6-item tuple without *format* is also + accepted and defaults to :data:`WAVE_FORMAT_PCM`. + + For ``format=WAVE_FORMAT_IEEE_FLOAT``, *sampwidth* must be 4 or 8. .. method:: getparams() @@ -279,3 +331,6 @@ Wave_write Objects Note that it is invalid to set any parameters after calling :meth:`writeframes` or :meth:`writeframesraw`, and any attempt to do so will raise :exc:`wave.Error`. + + For :data:`WAVE_FORMAT_IEEE_FLOAT` output, a ``fact`` chunk is written as + required by the WAVE specification for non-PCM formats. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 459846e55ccf70..d5b14216770906 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1518,6 +1518,21 @@ typing wave ---- +* Added support for IEEE floating-point WAVE audio + (``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`. + +* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`, + and :meth:`wave.Wave_write.setformat` for explicit frame format handling. + +* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including + ``format`` and 6-item tuples for backwards compatibility (defaulting to + ``WAVE_FORMAT_PCM``). + +* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk, + as required for non-PCM WAVE formats. + +(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.) + * Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes, which were deprecated since Python 3.13. diff --git a/Lib/test/audiodata/pluck-float32.wav b/Lib/test/audiodata/pluck-float32.wav new file mode 100644 index 0000000000000000000000000000000000000000..2030fb16d6e3bd797523605091ff1d732b432b88 GIT binary patch literal 26514 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±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 4: + if self._format == WAVE_FORMAT_IEEE_FLOAT: + if sampwidth not in (4, 8): + raise Error('unsupported sample width for IEEE float format') + elif sampwidth < 1 or sampwidth > 4: raise Error('bad sample width') self._sampwidth = sampwidth @@ -518,6 +546,18 @@ def setcomptype(self, comptype, compname): self._comptype = comptype self._compname = compname + def setformat(self, format): + if self._datawritten: + raise Error('cannot change parameters after starting to write') + if format not in (WAVE_FORMAT_IEEE_FLOAT, WAVE_FORMAT_PCM): + raise Error('unsupported wave format') + if format == WAVE_FORMAT_IEEE_FLOAT and self._sampwidth and self._sampwidth not in (4, 8): + raise Error('unsupported sample width for IEEE float format') + self._format = format + + def getformat(self): + return self._format + def getcomptype(self): return self._comptype @@ -525,10 +565,15 @@ def getcompname(self): return self._compname def setparams(self, params): - nchannels, sampwidth, framerate, nframes, comptype, compname = params if self._datawritten: raise Error('cannot change parameters after starting to write') + if len(params) == 6: + nchannels, sampwidth, framerate, nframes, comptype, compname = params + format = WAVE_FORMAT_PCM + else: + nchannels, sampwidth, framerate, nframes, comptype, compname, format = params self.setnchannels(nchannels) + self.setformat(format) self.setsampwidth(sampwidth) self.setframerate(framerate) self.setnframes(nframes) @@ -589,6 +634,9 @@ def _ensure_header_written(self, datasize): raise Error('sampling rate not specified') self._write_header(datasize) + def _needs_fact_chunk(self): + return self._format == WAVE_FORMAT_IEEE_FLOAT + def _write_header(self, initlength): assert not self._headerwritten self._file.write(b'RIFF') @@ -599,12 +647,23 @@ def _write_header(self, initlength): self._form_length_pos = self._file.tell() except (AttributeError, OSError): self._form_length_pos = None - self._file.write(struct.pack(' Date: Fri, 13 Mar 2026 14:53:01 +0100 Subject: [PATCH 447/498] gh-142518: Document thread-safety guarantees of set objects (#145225) --- Doc/library/stdtypes.rst | 5 ++ Doc/library/threadsafety.rst | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 6b55daa9b6eae0..7ae399eb95ba6e 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -5251,6 +5251,11 @@ Note, the *elem* argument to the :meth:`~object.__contains__`, :meth:`~set.discard` methods may be a set. To support searching for an equivalent frozenset, a temporary one is created from *elem*. +.. seealso:: + + For detailed information on thread-safety guarantees for :class:`set` + objects, see :ref:`thread-safety-set`. + .. _typesmapping: diff --git a/Doc/library/threadsafety.rst b/Doc/library/threadsafety.rst index 7ab5921c7ec298..4f2eda19b85e07 100644 --- a/Doc/library/threadsafety.rst +++ b/Doc/library/threadsafety.rst @@ -342,3 +342,108 @@ thread, iterate over a copy: Consider external synchronization when sharing :class:`dict` instances across threads. + + +.. _thread-safety-set: + +Thread safety for set objects +============================== + +The :func:`len` function is lock-free and :term:`atomic `. + +The following read operation is lock-free. It does not block concurrent +modifications and may observe intermediate states from operations that +hold the per-object lock: + +.. code-block:: + :class: good + + elem in s # set.__contains__ + +This operation may compare elements using :meth:`~object.__eq__`, which can +execute arbitrary Python code. During such comparisons, the set may be +modified by another thread. For built-in types like :class:`str`, +:class:`int`, and :class:`float`, :meth:`!__eq__` does not release the +underlying lock during comparisons and this is not a concern. + +All other operations from here on hold the per-object lock. + +Adding or removing a single element is safe to call from multiple threads +and will not corrupt the set: + +.. code-block:: + :class: good + + s.add(elem) # add element + s.remove(elem) # remove element, raise if missing + s.discard(elem) # remove element if present + s.pop() # remove and return arbitrary element + +These operations also compare elements, so the same :meth:`~object.__eq__` +considerations as above apply. + +The :meth:`~set.copy` method returns a new object and holds the per-object lock +for the duration so that it is always atomic. + +The :meth:`~set.clear` method holds the lock for its duration. Other +threads cannot observe elements being removed. + +The following operations only accept :class:`set` or :class:`frozenset` +as operands and always lock both objects: + +.. code-block:: + :class: good + + s |= other # other must be set/frozenset + s &= other # other must be set/frozenset + s -= other # other must be set/frozenset + s ^= other # other must be set/frozenset + s & other # other must be set/frozenset + s | other # other must be set/frozenset + s - other # other must be set/frozenset + s ^ other # other must be set/frozenset + +:meth:`set.update`, :meth:`set.union`, :meth:`set.intersection` and +:meth:`set.difference` can take multiple iterables as arguments. They all +iterate through all the passed iterables and do the following: + + * :meth:`set.update` and :meth:`set.union` lock both objects only when + the other operand is a :class:`set`, :class:`frozenset`, or :class:`dict`. + * :meth:`set.intersection` and :meth:`set.difference` always try to lock + all objects. + +:meth:`set.symmetric_difference` tries to lock both objects. + +The update variants of the above methods also have some differences between +them: + + * :meth:`set.difference_update` and :meth:`set.intersection_update` try + to lock all objects one-by-one. + * :meth:`set.symmetric_difference_update` only locks the arguments if it is + of type :class:`set`, :class:`frozenset`, or :class:`dict`. + +The following methods always try to lock both objects: + +.. code-block:: + :class: good + + s.isdisjoint(other) # both locked + s.issubset(other) # both locked + s.issuperset(other) # both locked + +Operations that involve multiple accesses, as well as iteration, are never +atomic: + +.. code-block:: + :class: bad + + # NOT atomic: check-then-act + if elem in s: + s.remove(elem) + + # NOT thread-safe: iteration while modifying + for elem in s: + process(elem) # another thread may modify s + +Consider external synchronization when sharing :class:`set` instances +across threads. See :ref:`freethreading-python-howto` for more information. From 00a25859a94b6bf34e58a5176e2befab7e273d20 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 13 Mar 2026 16:42:19 +0100 Subject: [PATCH 448/498] gh-145376: Fix GC tracking in `structseq.__replace__` (#145820) --- Lib/test/test_structseq.py | 9 +++++++++ .../2026-03-11-21-27-28.gh-issue-145376.LfDvyw.rst | 1 + Objects/structseq.c | 1 + 3 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-21-27-28.gh-issue-145376.LfDvyw.rst diff --git a/Lib/test/test_structseq.py b/Lib/test/test_structseq.py index 9622151143cd78..74506fc54de50e 100644 --- a/Lib/test/test_structseq.py +++ b/Lib/test/test_structseq.py @@ -1,4 +1,5 @@ import copy +import gc import os import pickle import re @@ -355,6 +356,14 @@ def test_reference_cycle(self): type(t).refcyle = t """)) + def test_replace_gc_tracked(self): + # Verify that __replace__ results are properly GC-tracked + time_struct = time.gmtime(0) + lst = [] + replaced_struct = time_struct.__replace__(tm_year=lst) + lst.append(replaced_struct) + + self.assertTrue(gc.is_tracked(replaced_struct)) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-21-27-28.gh-issue-145376.LfDvyw.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-21-27-28.gh-issue-145376.LfDvyw.rst new file mode 100644 index 00000000000000..476be205da8001 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-21-27-28.gh-issue-145376.LfDvyw.rst @@ -0,0 +1 @@ +Fix GC tracking in ``structseq.__replace__()``. diff --git a/Objects/structseq.c b/Objects/structseq.c index b8bb041f0cff21..8fa9cbba3bcce3 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -445,6 +445,7 @@ structseq_replace(PyObject *op, PyObject *args, PyObject *kwargs) } } + _PyObject_GC_TRACK(result); return (PyObject *)result; error: From 747ef70faa8637ccf6dd896323fa84aee8f14513 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 13 Mar 2026 18:51:23 +0100 Subject: [PATCH 449/498] GH-60729: Revert "Add IEEE format wave audio support (GH-145384)" (GH-145928) Revert "GH-60729: Add IEEE format wave audio support (GH-145384)" This reverts commit 61f2a1a5993967ed4b97ba93a4477c37fe68cf59 for now; as tests fail on big-endian machines. --- Doc/library/wave.rst | 69 +------ Doc/whatsnew/3.15.rst | 15 -- Lib/test/audiodata/pluck-float32.wav | Bin 26514 -> 0 bytes Lib/test/audiotests.py | 16 +- Lib/test/test_wave.py | 188 +----------------- Lib/wave.py | 88 ++------ ...3-03-10-13-10-06.gh-issue-60729.KCCHTe.rst | 1 - 7 files changed, 25 insertions(+), 352 deletions(-) delete mode 100644 Lib/test/audiodata/pluck-float32.wav delete mode 100644 Misc/NEWS.d/next/Library/2023-03-10-13-10-06.gh-issue-60729.KCCHTe.rst diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index 9d30a14f112937..ff020b52da3f23 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -9,19 +9,14 @@ -------------- The :mod:`!wave` module provides a convenient interface to the Waveform Audio -"WAVE" (or "WAV") file format. - -The module supports uncompressed PCM and IEEE floating-point WAV formats. +"WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are +supported. .. versionchanged:: 3.12 Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the extended format is ``KSDATAFORMAT_SUBTYPE_PCM``. -.. versionchanged:: next - - Support for reading and writing ``WAVE_FORMAT_IEEE_FLOAT`` files was added. - The :mod:`!wave` module defines the following function and exception: @@ -65,21 +60,6 @@ The :mod:`!wave` module defines the following function and exception: specification or hits an implementation deficiency. -.. data:: WAVE_FORMAT_PCM - - Format code for uncompressed PCM audio. - - -.. data:: WAVE_FORMAT_IEEE_FLOAT - - Format code for IEEE floating-point audio. - - -.. data:: WAVE_FORMAT_EXTENSIBLE - - Format code for WAVE extensible headers. - - .. _wave-read-objects: Wave_read Objects @@ -118,14 +98,6 @@ Wave_read Objects Returns number of audio frames. - .. method:: getformat() - - Returns the frame format code. - - This is one of :data:`WAVE_FORMAT_PCM`, - :data:`WAVE_FORMAT_IEEE_FLOAT`, or :data:`WAVE_FORMAT_EXTENSIBLE`. - - .. method:: getcomptype() Returns compression type (``'NONE'`` is the only supported type). @@ -140,8 +112,8 @@ Wave_read Objects .. method:: getparams() Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth, - framerate, nframes, comptype, compname)``, equivalent to output - of the ``get*()`` methods. + framerate, nframes, comptype, compname)``, equivalent to output of the + ``get*()`` methods. .. method:: readframes(n) @@ -218,9 +190,6 @@ Wave_write Objects Set the sample width to *n* bytes. - For :data:`WAVE_FORMAT_IEEE_FLOAT`, only 4-byte (32-bit) and - 8-byte (64-bit) sample widths are supported. - .. method:: getsampwidth() @@ -269,32 +238,11 @@ Wave_write Objects Return the human-readable compression type name. - .. method:: setformat(format) - - Set the frame format code. - - Supported values are :data:`WAVE_FORMAT_PCM` and - :data:`WAVE_FORMAT_IEEE_FLOAT`. - - When setting :data:`WAVE_FORMAT_IEEE_FLOAT`, the sample width must be - 4 or 8 bytes. - - - .. method:: getformat() - - Return the current frame format code. - - .. method:: setparams(tuple) - The *tuple* should be - ``(nchannels, sampwidth, framerate, nframes, comptype, compname, format)``, - with values valid for the ``set*()`` methods. Sets all parameters. - - For backwards compatibility, a 6-item tuple without *format* is also - accepted and defaults to :data:`WAVE_FORMAT_PCM`. - - For ``format=WAVE_FORMAT_IEEE_FLOAT``, *sampwidth* must be 4 or 8. + The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype, + compname)``, with values valid for the ``set*()`` methods. Sets all + parameters. .. method:: getparams() @@ -331,6 +279,3 @@ Wave_write Objects Note that it is invalid to set any parameters after calling :meth:`writeframes` or :meth:`writeframesraw`, and any attempt to do so will raise :exc:`wave.Error`. - - For :data:`WAVE_FORMAT_IEEE_FLOAT` output, a ``fact`` chunk is written as - required by the WAVE specification for non-PCM formats. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index d5b14216770906..459846e55ccf70 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1518,21 +1518,6 @@ typing wave ---- -* Added support for IEEE floating-point WAVE audio - (``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`. - -* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`, - and :meth:`wave.Wave_write.setformat` for explicit frame format handling. - -* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including - ``format`` and 6-item tuples for backwards compatibility (defaulting to - ``WAVE_FORMAT_PCM``). - -* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk, - as required for non-PCM WAVE formats. - -(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.) - * Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes, which were deprecated since Python 3.13. diff --git a/Lib/test/audiodata/pluck-float32.wav b/Lib/test/audiodata/pluck-float32.wav deleted file mode 100644 index 2030fb16d6e3bd797523605091ff1d732b432b88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26514 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±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 4: + if sampwidth < 1 or sampwidth > 4: raise Error('bad sample width') self._sampwidth = sampwidth @@ -546,18 +518,6 @@ def setcomptype(self, comptype, compname): self._comptype = comptype self._compname = compname - def setformat(self, format): - if self._datawritten: - raise Error('cannot change parameters after starting to write') - if format not in (WAVE_FORMAT_IEEE_FLOAT, WAVE_FORMAT_PCM): - raise Error('unsupported wave format') - if format == WAVE_FORMAT_IEEE_FLOAT and self._sampwidth and self._sampwidth not in (4, 8): - raise Error('unsupported sample width for IEEE float format') - self._format = format - - def getformat(self): - return self._format - def getcomptype(self): return self._comptype @@ -565,15 +525,10 @@ def getcompname(self): return self._compname def setparams(self, params): + nchannels, sampwidth, framerate, nframes, comptype, compname = params if self._datawritten: raise Error('cannot change parameters after starting to write') - if len(params) == 6: - nchannels, sampwidth, framerate, nframes, comptype, compname = params - format = WAVE_FORMAT_PCM - else: - nchannels, sampwidth, framerate, nframes, comptype, compname, format = params self.setnchannels(nchannels) - self.setformat(format) self.setsampwidth(sampwidth) self.setframerate(framerate) self.setnframes(nframes) @@ -634,9 +589,6 @@ def _ensure_header_written(self, datasize): raise Error('sampling rate not specified') self._write_header(datasize) - def _needs_fact_chunk(self): - return self._format == WAVE_FORMAT_IEEE_FLOAT - def _write_header(self, initlength): assert not self._headerwritten self._file.write(b'RIFF') @@ -647,23 +599,12 @@ def _write_header(self, initlength): self._form_length_pos = self._file.tell() except (AttributeError, OSError): self._form_length_pos = None - has_fact = self._needs_fact_chunk() - header_overhead = 36 + (12 if has_fact else 0) - self._file.write(struct.pack(' Date: Fri, 13 Mar 2026 19:44:51 +0100 Subject: [PATCH 450/498] gh-129813: Document that PyBytesWriter_GetData() cannot fail (#145900) Document that PyBytesWriter_GetData() and PyBytesWriter_GetSize() getter functions cannot fail --- Doc/c-api/bytes.rst | 4 ++++ Modules/binascii.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 82c2557368371f..b3cd26a8504715 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -371,6 +371,8 @@ Getters Get the writer size. + The function cannot fail. + .. c:function:: void* PyBytesWriter_GetData(PyBytesWriter *writer) Get the writer data: start of the internal buffer. @@ -378,6 +380,8 @@ Getters The pointer is valid until :c:func:`PyBytesWriter_Finish` or :c:func:`PyBytesWriter_Discard` is called on *writer*. + The function cannot fail. + Low-level API ^^^^^^^^^^^^^ diff --git a/Modules/binascii.c b/Modules/binascii.c index 3f3695d50f2754..c076b12fb149b2 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -923,9 +923,6 @@ binascii_a2b_ascii85_impl(PyObject *module, Py_buffer *data, int foldspaces, return NULL; } unsigned char *bin_data = PyBytesWriter_GetData(writer); - if (bin_data == NULL) { - goto error; - } uint32_t leftchar = 0; int group_pos = 0; From 77c06f3da629b5088975309959ef6895bef841e3 Mon Sep 17 00:00:00 2001 From: Konstantin Vlasov Date: Sat, 14 Mar 2026 06:37:30 +0100 Subject: [PATCH 451/498] gh-145703: Fix `asyncio.BaseEventLoop` low clock resolution (#145706) --- Lib/asyncio/base_events.py | 8 ++++++-- .../2026-03-09-19-59-05.gh-issue-145703.4EEP7J.rst | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-09-19-59-05.gh-issue-145703.4EEP7J.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index b565b1d8a9e226..0930ef403c6c4b 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -19,14 +19,15 @@ import errno import heapq import itertools +import math import os import socket import stat import subprocess +import sys import threading import time import traceback -import sys import warnings import weakref @@ -2022,7 +2023,10 @@ def _run_once(self): event_list = None # Handle 'later' callbacks that are ready. - end_time = self.time() + self._clock_resolution + now = self.time() + # Ensure that `end_time` is strictly increasing + # when the clock resolution is too small. + end_time = now + max(self._clock_resolution, math.ulp(now)) while self._scheduled: handle = self._scheduled[0] if handle._when >= end_time: diff --git a/Misc/NEWS.d/next/Library/2026-03-09-19-59-05.gh-issue-145703.4EEP7J.rst b/Misc/NEWS.d/next/Library/2026-03-09-19-59-05.gh-issue-145703.4EEP7J.rst new file mode 100644 index 00000000000000..bc239ce58c9eed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-09-19-59-05.gh-issue-145703.4EEP7J.rst @@ -0,0 +1,3 @@ +:mod:`asyncio`: Make sure that :meth:`loop.call_at ` and +:meth:`loop.call_later ` trigger scheduled events on +time when the clock resolution becomes too small. From 51e8acf8de1aa1f1751dd5bb84d44b8d42143b9c Mon Sep 17 00:00:00 2001 From: Connor Gibson Date: Sat, 14 Mar 2026 02:19:00 -0700 Subject: [PATCH 452/498] Docs: fix missing period in `Doc/library/stdtypes.rst` (#145935) --- Doc/library/stdtypes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 7ae399eb95ba6e..6e2c72daf7ac44 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1286,7 +1286,7 @@ Mutable sequence types also support the following methods: :no-typesetting: .. method:: sequence.append(value, /) - Append *value* to the end of the sequence + Append *value* to the end of the sequence. This is equivalent to writing ``seq[len(seq):len(seq)] = [value]``. .. method:: bytearray.clear() From 97968564b61965f2a65a9be8af731cee6913eb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 14 Mar 2026 10:58:15 +0100 Subject: [PATCH 453/498] gh-143636: fix a crash when calling ``__replace__`` on invalid `SimpleNamespace` instances (#143655) --- Lib/test/test_types.py | 15 +++++++++++++++ ...2026-01-10-12-59-58.gh-issue-143636.dzr26e.rst | 2 ++ Objects/namespaceobject.c | 9 +++++++++ 3 files changed, 26 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-12-59-58.gh-issue-143636.dzr26e.rst diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 39d57c5f5b61c9..2084b30d71ff6c 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -2168,6 +2168,21 @@ class Spam(types.SimpleNamespace): self.assertIs(type(spam2), Spam) self.assertEqual(vars(spam2), {'ham': 5, 'eggs': 9}) + def test_replace_invalid_subtype(self): + # See https://github.com/python/cpython/issues/143636. + class MyNS(types.SimpleNamespace): + def __new__(cls, *args, **kwargs): + if created: + return 12345 + return super().__new__(cls) + + created = False + ns = MyNS() + created = True + err = (r"^expect types\.SimpleNamespace type, " + r"but .+\.MyNS\(\) returned 'int' object") + self.assertRaisesRegex(TypeError, err, copy.replace, ns) + def test_fake_namespace_compare(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # SystemError. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-12-59-58.gh-issue-143636.dzr26e.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-12-59-58.gh-issue-143636.dzr26e.rst new file mode 100644 index 00000000000000..4d5249ffe3a206 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-10-12-59-58.gh-issue-143636.dzr26e.rst @@ -0,0 +1,2 @@ +Fix a crash when calling :class:`SimpleNamespace.__replace__() +` on non-namespace instances. Patch by Bénédikt Tran. diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index 201cb8a7df8da1..3803c41027dd85 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -13,6 +13,7 @@ typedef struct { } _PyNamespaceObject; #define _PyNamespace_CAST(op) _Py_CAST(_PyNamespaceObject*, (op)) +#define _PyNamespace_Check(op) PyObject_TypeCheck((op), &_PyNamespace_Type) static PyMemberDef namespace_members[] = { @@ -234,6 +235,14 @@ namespace_replace(PyObject *self, PyObject *args, PyObject *kwargs) if (!result) { return NULL; } + if (!_PyNamespace_Check(result)) { + PyErr_Format(PyExc_TypeError, + "expect %N type, but %T() returned '%T' object", + &_PyNamespace_Type, self, result); + Py_DECREF(result); + return NULL; + } + if (PyDict_Update(((_PyNamespaceObject*)result)->ns_dict, ((_PyNamespaceObject*)self)->ns_dict) < 0) { From 798070d8ca4a32c1d7d10e69defcb1b2f934bea6 Mon Sep 17 00:00:00 2001 From: Sacul <183588943+Sacul0457@users.noreply.github.com> Date: Sat, 14 Mar 2026 20:00:18 +0800 Subject: [PATCH 454/498] gh-134584: Eliminate redundant refcounting in JIT for `MATCH_CLASS` (GH-144821) --- Include/internal/pycore_opcode_metadata.h | 4 +- Include/internal/pycore_uop_ids.h | 1940 ++++++++--------- Include/internal/pycore_uop_metadata.h | 8 +- Lib/test/test_capi/test_opt.py | 18 + ...-02-14-15-51-16.gh-issue-134584.6WFSuB.rst | 1 + Modules/_testinternalcapi/test_cases.c.h | 91 +- Python/bytecodes.c | 13 +- Python/executor_cases.c.h | 33 +- Python/generated_cases.c.h | 91 +- Python/optimizer_bytecodes.c | 7 + Python/optimizer_cases.c.h | 19 +- 11 files changed, 1155 insertions(+), 1070 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-14-15-51-16.gh-issue-134584.6WFSuB.rst diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 2586ed3a5299a6..c64d4e8ba85b3d 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1260,7 +1260,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [MATCH_KEYS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 }, [MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 }, @@ -1478,7 +1478,7 @@ _PyOpcode_macro_expansion[256] = { [MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, OPARG_SIMPLE, 0 } } }, [MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, OPARG_SIMPLE, 0 } } }, [MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, OPARG_SIMPLE, 0 } } }, - [MATCH_CLASS] = { .nuops = 1, .uops = { { _MATCH_CLASS, OPARG_SIMPLE, 0 } } }, + [MATCH_CLASS] = { .nuops = 4, .uops = { { _MATCH_CLASS, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } }, [MATCH_KEYS] = { .nuops = 1, .uops = { { _MATCH_KEYS, OPARG_SIMPLE, 0 } } }, [MATCH_MAPPING] = { .nuops = 1, .uops = { { _MATCH_MAPPING, OPARG_SIMPLE, 0 } } }, [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { _MATCH_SEQUENCE, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 79e62edfeed978..0fdeb56122ecc7 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -293,1000 +293,1000 @@ extern "C" { #define _MAKE_HEAP_SAFE 519 #define _MAKE_WARM 520 #define _MAP_ADD MAP_ADD -#define _MATCH_CLASS MATCH_CLASS +#define _MATCH_CLASS 521 #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 521 -#define _MAYBE_EXPAND_METHOD_KW 522 -#define _MONITOR_CALL 523 -#define _MONITOR_CALL_KW 524 -#define _MONITOR_JUMP_BACKWARD 525 -#define _MONITOR_RESUME 526 +#define _MAYBE_EXPAND_METHOD 522 +#define _MAYBE_EXPAND_METHOD_KW 523 +#define _MONITOR_CALL 524 +#define _MONITOR_CALL_KW 525 +#define _MONITOR_JUMP_BACKWARD 526 +#define _MONITOR_RESUME 527 #define _NOP NOP -#define _POP_CALL 527 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 528 -#define _POP_CALL_ONE 529 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 530 -#define _POP_CALL_TWO 531 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 532 +#define _POP_CALL 528 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 529 +#define _POP_CALL_ONE 530 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 531 +#define _POP_CALL_TWO 532 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 533 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 533 -#define _POP_JUMP_IF_TRUE 534 +#define _POP_JUMP_IF_FALSE 534 +#define _POP_JUMP_IF_TRUE 535 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 535 -#define _POP_TOP_INT 536 -#define _POP_TOP_LOAD_CONST_INLINE 537 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 538 -#define _POP_TOP_NOP 539 -#define _POP_TOP_UNICODE 540 -#define _POP_TWO 541 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 542 +#define _POP_TOP_FLOAT 536 +#define _POP_TOP_INT 537 +#define _POP_TOP_LOAD_CONST_INLINE 538 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 539 +#define _POP_TOP_NOP 540 +#define _POP_TOP_UNICODE 541 +#define _POP_TWO 542 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 543 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 543 +#define _PUSH_FRAME 544 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 544 -#define _PY_FRAME_EX 545 -#define _PY_FRAME_GENERAL 546 -#define _PY_FRAME_KW 547 -#define _QUICKEN_RESUME 548 -#define _RECORD_4OS 549 -#define _RECORD_BOUND_METHOD 550 -#define _RECORD_CALLABLE 551 -#define _RECORD_CODE 552 -#define _RECORD_NOS 553 -#define _RECORD_NOS_GEN_FUNC 554 -#define _RECORD_TOS 555 -#define _RECORD_TOS_TYPE 556 -#define _REPLACE_WITH_TRUE 557 +#define _PUSH_NULL_CONDITIONAL 545 +#define _PY_FRAME_EX 546 +#define _PY_FRAME_GENERAL 547 +#define _PY_FRAME_KW 548 +#define _QUICKEN_RESUME 549 +#define _RECORD_4OS 550 +#define _RECORD_BOUND_METHOD 551 +#define _RECORD_CALLABLE 552 +#define _RECORD_CODE 553 +#define _RECORD_NOS 554 +#define _RECORD_NOS_GEN_FUNC 555 +#define _RECORD_TOS 556 +#define _RECORD_TOS_TYPE 557 +#define _REPLACE_WITH_TRUE 558 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE 558 -#define _SAVE_RETURN_OFFSET 559 -#define _SEND 560 -#define _SEND_GEN_FRAME 561 +#define _RETURN_VALUE 559 +#define _SAVE_RETURN_OFFSET 560 +#define _SEND 561 +#define _SEND_GEN_FRAME 562 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 562 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 563 -#define _SPILL_OR_RELOAD 564 -#define _START_EXECUTOR 565 -#define _STORE_ATTR 566 -#define _STORE_ATTR_INSTANCE_VALUE 567 -#define _STORE_ATTR_SLOT 568 -#define _STORE_ATTR_WITH_HINT 569 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 563 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 564 +#define _SPILL_OR_RELOAD 565 +#define _START_EXECUTOR 566 +#define _STORE_ATTR 567 +#define _STORE_ATTR_INSTANCE_VALUE 568 +#define _STORE_ATTR_SLOT 569 +#define _STORE_ATTR_WITH_HINT 570 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 570 -#define _STORE_SUBSCR 571 -#define _STORE_SUBSCR_DICT 572 -#define _STORE_SUBSCR_LIST_INT 573 -#define _SWAP 574 -#define _SWAP_2 575 -#define _SWAP_3 576 -#define _SWAP_FAST 577 -#define _SWAP_FAST_0 578 -#define _SWAP_FAST_1 579 -#define _SWAP_FAST_2 580 -#define _SWAP_FAST_3 581 -#define _SWAP_FAST_4 582 -#define _SWAP_FAST_5 583 -#define _SWAP_FAST_6 584 -#define _SWAP_FAST_7 585 -#define _TIER2_RESUME_CHECK 586 -#define _TO_BOOL 587 +#define _STORE_SLICE 571 +#define _STORE_SUBSCR 572 +#define _STORE_SUBSCR_DICT 573 +#define _STORE_SUBSCR_LIST_INT 574 +#define _SWAP 575 +#define _SWAP_2 576 +#define _SWAP_3 577 +#define _SWAP_FAST 578 +#define _SWAP_FAST_0 579 +#define _SWAP_FAST_1 580 +#define _SWAP_FAST_2 581 +#define _SWAP_FAST_3 582 +#define _SWAP_FAST_4 583 +#define _SWAP_FAST_5 584 +#define _SWAP_FAST_6 585 +#define _SWAP_FAST_7 586 +#define _TIER2_RESUME_CHECK 587 +#define _TO_BOOL 588 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 588 -#define _TO_BOOL_LIST 589 +#define _TO_BOOL_INT 589 +#define _TO_BOOL_LIST 590 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 590 +#define _TO_BOOL_STR 591 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 591 -#define _UNARY_NEGATIVE 592 +#define _UNARY_INVERT 592 +#define _UNARY_NEGATIVE 593 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 593 -#define _UNPACK_SEQUENCE_LIST 594 -#define _UNPACK_SEQUENCE_TUPLE 595 -#define _UNPACK_SEQUENCE_TWO_TUPLE 596 +#define _UNPACK_SEQUENCE 594 +#define _UNPACK_SEQUENCE_LIST 595 +#define _UNPACK_SEQUENCE_TUPLE 596 +#define _UNPACK_SEQUENCE_TWO_TUPLE 597 #define _WITH_EXCEPT_START WITH_EXCEPT_START -#define _YIELD_VALUE 597 -#define MAX_UOP_ID 597 -#define _BINARY_OP_r23 598 -#define _BINARY_OP_ADD_FLOAT_r03 599 -#define _BINARY_OP_ADD_FLOAT_r13 600 -#define _BINARY_OP_ADD_FLOAT_r23 601 -#define _BINARY_OP_ADD_INT_r03 602 -#define _BINARY_OP_ADD_INT_r13 603 -#define _BINARY_OP_ADD_INT_r23 604 -#define _BINARY_OP_ADD_UNICODE_r03 605 -#define _BINARY_OP_ADD_UNICODE_r13 606 -#define _BINARY_OP_ADD_UNICODE_r23 607 -#define _BINARY_OP_EXTEND_r23 608 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 609 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 610 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 611 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 612 -#define _BINARY_OP_MULTIPLY_INT_r03 613 -#define _BINARY_OP_MULTIPLY_INT_r13 614 -#define _BINARY_OP_MULTIPLY_INT_r23 615 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 616 -#define _BINARY_OP_SUBSCR_DICT_r23 617 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 618 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 619 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 620 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 621 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 622 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 623 -#define _BINARY_OP_SUBSCR_STR_INT_r23 624 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 625 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 626 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 627 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 628 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 629 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 630 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 631 -#define _BINARY_OP_SUBTRACT_INT_r03 632 -#define _BINARY_OP_SUBTRACT_INT_r13 633 -#define _BINARY_OP_SUBTRACT_INT_r23 634 -#define _BINARY_SLICE_r31 635 -#define _BUILD_INTERPOLATION_r01 636 -#define _BUILD_LIST_r01 637 -#define _BUILD_MAP_r01 638 -#define _BUILD_SET_r01 639 -#define _BUILD_SLICE_r01 640 -#define _BUILD_STRING_r01 641 -#define _BUILD_TEMPLATE_r21 642 -#define _BUILD_TUPLE_r01 643 -#define _CALL_BUILTIN_CLASS_r01 644 -#define _CALL_BUILTIN_FAST_r01 645 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 646 -#define _CALL_BUILTIN_O_r03 647 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 648 -#define _CALL_INTRINSIC_1_r11 649 -#define _CALL_INTRINSIC_2_r21 650 -#define _CALL_ISINSTANCE_r31 651 -#define _CALL_KW_NON_PY_r11 652 -#define _CALL_LEN_r33 653 -#define _CALL_LIST_APPEND_r03 654 -#define _CALL_LIST_APPEND_r13 655 -#define _CALL_LIST_APPEND_r23 656 -#define _CALL_LIST_APPEND_r33 657 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 658 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 659 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 660 -#define _CALL_METHOD_DESCRIPTOR_O_r03 661 -#define _CALL_NON_PY_GENERAL_r01 662 -#define _CALL_STR_1_r32 663 -#define _CALL_TUPLE_1_r32 664 -#define _CALL_TYPE_1_r02 665 -#define _CALL_TYPE_1_r12 666 -#define _CALL_TYPE_1_r22 667 -#define _CALL_TYPE_1_r32 668 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 669 -#define _CHECK_ATTR_CLASS_r01 670 -#define _CHECK_ATTR_CLASS_r11 671 -#define _CHECK_ATTR_CLASS_r22 672 -#define _CHECK_ATTR_CLASS_r33 673 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 674 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 675 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 676 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 677 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 678 -#define _CHECK_EG_MATCH_r22 679 -#define _CHECK_EXC_MATCH_r22 680 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 681 -#define _CHECK_FUNCTION_VERSION_r00 682 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 683 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 684 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 685 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 686 -#define _CHECK_FUNCTION_VERSION_KW_r11 687 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 688 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 689 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 690 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 691 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 692 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 693 -#define _CHECK_IS_PY_CALLABLE_EX_r03 694 -#define _CHECK_IS_PY_CALLABLE_EX_r13 695 -#define _CHECK_IS_PY_CALLABLE_EX_r23 696 -#define _CHECK_IS_PY_CALLABLE_EX_r33 697 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 698 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 699 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 700 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 701 -#define _CHECK_METHOD_VERSION_r00 702 -#define _CHECK_METHOD_VERSION_KW_r11 703 -#define _CHECK_PEP_523_r00 704 -#define _CHECK_PEP_523_r11 705 -#define _CHECK_PEP_523_r22 706 -#define _CHECK_PEP_523_r33 707 -#define _CHECK_PERIODIC_r00 708 -#define _CHECK_PERIODIC_AT_END_r00 709 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 710 -#define _CHECK_RECURSION_REMAINING_r00 711 -#define _CHECK_RECURSION_REMAINING_r11 712 -#define _CHECK_RECURSION_REMAINING_r22 713 -#define _CHECK_RECURSION_REMAINING_r33 714 -#define _CHECK_STACK_SPACE_r00 715 -#define _CHECK_STACK_SPACE_OPERAND_r00 716 -#define _CHECK_STACK_SPACE_OPERAND_r11 717 -#define _CHECK_STACK_SPACE_OPERAND_r22 718 -#define _CHECK_STACK_SPACE_OPERAND_r33 719 -#define _CHECK_VALIDITY_r00 720 -#define _CHECK_VALIDITY_r11 721 -#define _CHECK_VALIDITY_r22 722 -#define _CHECK_VALIDITY_r33 723 -#define _COLD_DYNAMIC_EXIT_r00 724 -#define _COLD_EXIT_r00 725 -#define _COMPARE_OP_r21 726 -#define _COMPARE_OP_FLOAT_r03 727 -#define _COMPARE_OP_FLOAT_r13 728 -#define _COMPARE_OP_FLOAT_r23 729 -#define _COMPARE_OP_INT_r23 730 -#define _COMPARE_OP_STR_r23 731 -#define _CONTAINS_OP_r23 732 -#define _CONTAINS_OP_DICT_r23 733 -#define _CONTAINS_OP_SET_r23 734 -#define _CONVERT_VALUE_r11 735 -#define _COPY_r01 736 -#define _COPY_1_r02 737 -#define _COPY_1_r12 738 -#define _COPY_1_r23 739 -#define _COPY_2_r03 740 -#define _COPY_2_r13 741 -#define _COPY_2_r23 742 -#define _COPY_3_r03 743 -#define _COPY_3_r13 744 -#define _COPY_3_r23 745 -#define _COPY_3_r33 746 -#define _COPY_FREE_VARS_r00 747 -#define _COPY_FREE_VARS_r11 748 -#define _COPY_FREE_VARS_r22 749 -#define _COPY_FREE_VARS_r33 750 -#define _CREATE_INIT_FRAME_r01 751 -#define _DELETE_ATTR_r10 752 -#define _DELETE_DEREF_r00 753 -#define _DELETE_FAST_r00 754 -#define _DELETE_GLOBAL_r00 755 -#define _DELETE_NAME_r00 756 -#define _DELETE_SUBSCR_r20 757 -#define _DEOPT_r00 758 -#define _DEOPT_r10 759 -#define _DEOPT_r20 760 -#define _DEOPT_r30 761 -#define _DICT_MERGE_r10 762 -#define _DICT_UPDATE_r10 763 -#define _DO_CALL_r01 764 -#define _DO_CALL_FUNCTION_EX_r31 765 -#define _DO_CALL_KW_r11 766 -#define _DYNAMIC_EXIT_r00 767 -#define _DYNAMIC_EXIT_r10 768 -#define _DYNAMIC_EXIT_r20 769 -#define _DYNAMIC_EXIT_r30 770 -#define _END_FOR_r10 771 -#define _END_SEND_r21 772 -#define _ERROR_POP_N_r00 773 -#define _EXIT_INIT_CHECK_r10 774 -#define _EXIT_TRACE_r00 775 -#define _EXIT_TRACE_r10 776 -#define _EXIT_TRACE_r20 777 -#define _EXIT_TRACE_r30 778 -#define _EXPAND_METHOD_r00 779 -#define _EXPAND_METHOD_KW_r11 780 -#define _FATAL_ERROR_r00 781 -#define _FATAL_ERROR_r11 782 -#define _FATAL_ERROR_r22 783 -#define _FATAL_ERROR_r33 784 -#define _FORMAT_SIMPLE_r11 785 -#define _FORMAT_WITH_SPEC_r21 786 -#define _FOR_ITER_r23 787 -#define _FOR_ITER_GEN_FRAME_r03 788 -#define _FOR_ITER_GEN_FRAME_r13 789 -#define _FOR_ITER_GEN_FRAME_r23 790 -#define _FOR_ITER_TIER_TWO_r23 791 -#define _GET_AITER_r11 792 -#define _GET_ANEXT_r12 793 -#define _GET_AWAITABLE_r11 794 -#define _GET_ITER_r12 795 -#define _GET_LEN_r12 796 -#define _GET_YIELD_FROM_ITER_r11 797 -#define _GUARD_BINARY_OP_EXTEND_r22 798 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 799 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 800 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 801 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 802 -#define _GUARD_BIT_IS_SET_POP_r00 803 -#define _GUARD_BIT_IS_SET_POP_r10 804 -#define _GUARD_BIT_IS_SET_POP_r21 805 -#define _GUARD_BIT_IS_SET_POP_r32 806 -#define _GUARD_BIT_IS_SET_POP_4_r00 807 -#define _GUARD_BIT_IS_SET_POP_4_r10 808 -#define _GUARD_BIT_IS_SET_POP_4_r21 809 -#define _GUARD_BIT_IS_SET_POP_4_r32 810 -#define _GUARD_BIT_IS_SET_POP_5_r00 811 -#define _GUARD_BIT_IS_SET_POP_5_r10 812 -#define _GUARD_BIT_IS_SET_POP_5_r21 813 -#define _GUARD_BIT_IS_SET_POP_5_r32 814 -#define _GUARD_BIT_IS_SET_POP_6_r00 815 -#define _GUARD_BIT_IS_SET_POP_6_r10 816 -#define _GUARD_BIT_IS_SET_POP_6_r21 817 -#define _GUARD_BIT_IS_SET_POP_6_r32 818 -#define _GUARD_BIT_IS_SET_POP_7_r00 819 -#define _GUARD_BIT_IS_SET_POP_7_r10 820 -#define _GUARD_BIT_IS_SET_POP_7_r21 821 -#define _GUARD_BIT_IS_SET_POP_7_r32 822 -#define _GUARD_BIT_IS_UNSET_POP_r00 823 -#define _GUARD_BIT_IS_UNSET_POP_r10 824 -#define _GUARD_BIT_IS_UNSET_POP_r21 825 -#define _GUARD_BIT_IS_UNSET_POP_r32 826 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 827 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 828 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 829 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 830 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 831 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 832 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 833 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 834 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 835 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 836 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 837 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 838 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 839 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 840 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 841 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 842 -#define _GUARD_CALLABLE_ISINSTANCE_r03 843 -#define _GUARD_CALLABLE_ISINSTANCE_r13 844 -#define _GUARD_CALLABLE_ISINSTANCE_r23 845 -#define _GUARD_CALLABLE_ISINSTANCE_r33 846 -#define _GUARD_CALLABLE_LEN_r03 847 -#define _GUARD_CALLABLE_LEN_r13 848 -#define _GUARD_CALLABLE_LEN_r23 849 -#define _GUARD_CALLABLE_LEN_r33 850 -#define _GUARD_CALLABLE_LIST_APPEND_r03 851 -#define _GUARD_CALLABLE_LIST_APPEND_r13 852 -#define _GUARD_CALLABLE_LIST_APPEND_r23 853 -#define _GUARD_CALLABLE_LIST_APPEND_r33 854 -#define _GUARD_CALLABLE_STR_1_r03 855 -#define _GUARD_CALLABLE_STR_1_r13 856 -#define _GUARD_CALLABLE_STR_1_r23 857 -#define _GUARD_CALLABLE_STR_1_r33 858 -#define _GUARD_CALLABLE_TUPLE_1_r03 859 -#define _GUARD_CALLABLE_TUPLE_1_r13 860 -#define _GUARD_CALLABLE_TUPLE_1_r23 861 -#define _GUARD_CALLABLE_TUPLE_1_r33 862 -#define _GUARD_CALLABLE_TYPE_1_r03 863 -#define _GUARD_CALLABLE_TYPE_1_r13 864 -#define _GUARD_CALLABLE_TYPE_1_r23 865 -#define _GUARD_CALLABLE_TYPE_1_r33 866 -#define _GUARD_CODE_VERSION_r00 867 -#define _GUARD_CODE_VERSION_r11 868 -#define _GUARD_CODE_VERSION_r22 869 -#define _GUARD_CODE_VERSION_r33 870 -#define _GUARD_DORV_NO_DICT_r01 871 -#define _GUARD_DORV_NO_DICT_r11 872 -#define _GUARD_DORV_NO_DICT_r22 873 -#define _GUARD_DORV_NO_DICT_r33 874 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 875 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 876 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 877 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 878 -#define _GUARD_GLOBALS_VERSION_r00 879 -#define _GUARD_GLOBALS_VERSION_r11 880 -#define _GUARD_GLOBALS_VERSION_r22 881 -#define _GUARD_GLOBALS_VERSION_r33 882 -#define _GUARD_IP_RETURN_GENERATOR_r00 883 -#define _GUARD_IP_RETURN_GENERATOR_r11 884 -#define _GUARD_IP_RETURN_GENERATOR_r22 885 -#define _GUARD_IP_RETURN_GENERATOR_r33 886 -#define _GUARD_IP_RETURN_VALUE_r00 887 -#define _GUARD_IP_RETURN_VALUE_r11 888 -#define _GUARD_IP_RETURN_VALUE_r22 889 -#define _GUARD_IP_RETURN_VALUE_r33 890 -#define _GUARD_IP_YIELD_VALUE_r00 891 -#define _GUARD_IP_YIELD_VALUE_r11 892 -#define _GUARD_IP_YIELD_VALUE_r22 893 -#define _GUARD_IP_YIELD_VALUE_r33 894 -#define _GUARD_IP__PUSH_FRAME_r00 895 -#define _GUARD_IP__PUSH_FRAME_r11 896 -#define _GUARD_IP__PUSH_FRAME_r22 897 -#define _GUARD_IP__PUSH_FRAME_r33 898 -#define _GUARD_IS_FALSE_POP_r00 899 -#define _GUARD_IS_FALSE_POP_r10 900 -#define _GUARD_IS_FALSE_POP_r21 901 -#define _GUARD_IS_FALSE_POP_r32 902 -#define _GUARD_IS_NONE_POP_r00 903 -#define _GUARD_IS_NONE_POP_r10 904 -#define _GUARD_IS_NONE_POP_r21 905 -#define _GUARD_IS_NONE_POP_r32 906 -#define _GUARD_IS_NOT_NONE_POP_r10 907 -#define _GUARD_IS_TRUE_POP_r00 908 -#define _GUARD_IS_TRUE_POP_r10 909 -#define _GUARD_IS_TRUE_POP_r21 910 -#define _GUARD_IS_TRUE_POP_r32 911 -#define _GUARD_KEYS_VERSION_r01 912 -#define _GUARD_KEYS_VERSION_r11 913 -#define _GUARD_KEYS_VERSION_r22 914 -#define _GUARD_KEYS_VERSION_r33 915 -#define _GUARD_NOS_ANY_DICT_r02 916 -#define _GUARD_NOS_ANY_DICT_r12 917 -#define _GUARD_NOS_ANY_DICT_r22 918 -#define _GUARD_NOS_ANY_DICT_r33 919 -#define _GUARD_NOS_COMPACT_ASCII_r02 920 -#define _GUARD_NOS_COMPACT_ASCII_r12 921 -#define _GUARD_NOS_COMPACT_ASCII_r22 922 -#define _GUARD_NOS_COMPACT_ASCII_r33 923 -#define _GUARD_NOS_DICT_r02 924 -#define _GUARD_NOS_DICT_r12 925 -#define _GUARD_NOS_DICT_r22 926 -#define _GUARD_NOS_DICT_r33 927 -#define _GUARD_NOS_FLOAT_r02 928 -#define _GUARD_NOS_FLOAT_r12 929 -#define _GUARD_NOS_FLOAT_r22 930 -#define _GUARD_NOS_FLOAT_r33 931 -#define _GUARD_NOS_INT_r02 932 -#define _GUARD_NOS_INT_r12 933 -#define _GUARD_NOS_INT_r22 934 -#define _GUARD_NOS_INT_r33 935 -#define _GUARD_NOS_LIST_r02 936 -#define _GUARD_NOS_LIST_r12 937 -#define _GUARD_NOS_LIST_r22 938 -#define _GUARD_NOS_LIST_r33 939 -#define _GUARD_NOS_NOT_NULL_r02 940 -#define _GUARD_NOS_NOT_NULL_r12 941 -#define _GUARD_NOS_NOT_NULL_r22 942 -#define _GUARD_NOS_NOT_NULL_r33 943 -#define _GUARD_NOS_NULL_r02 944 -#define _GUARD_NOS_NULL_r12 945 -#define _GUARD_NOS_NULL_r22 946 -#define _GUARD_NOS_NULL_r33 947 -#define _GUARD_NOS_OVERFLOWED_r02 948 -#define _GUARD_NOS_OVERFLOWED_r12 949 -#define _GUARD_NOS_OVERFLOWED_r22 950 -#define _GUARD_NOS_OVERFLOWED_r33 951 -#define _GUARD_NOS_TUPLE_r02 952 -#define _GUARD_NOS_TUPLE_r12 953 -#define _GUARD_NOS_TUPLE_r22 954 -#define _GUARD_NOS_TUPLE_r33 955 -#define _GUARD_NOS_UNICODE_r02 956 -#define _GUARD_NOS_UNICODE_r12 957 -#define _GUARD_NOS_UNICODE_r22 958 -#define _GUARD_NOS_UNICODE_r33 959 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 960 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 961 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 962 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 963 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 964 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 965 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 966 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 967 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 968 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 969 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 970 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 971 -#define _GUARD_THIRD_NULL_r03 972 -#define _GUARD_THIRD_NULL_r13 973 -#define _GUARD_THIRD_NULL_r23 974 -#define _GUARD_THIRD_NULL_r33 975 -#define _GUARD_TOS_ANY_DICT_r01 976 -#define _GUARD_TOS_ANY_DICT_r11 977 -#define _GUARD_TOS_ANY_DICT_r22 978 -#define _GUARD_TOS_ANY_DICT_r33 979 -#define _GUARD_TOS_ANY_SET_r01 980 -#define _GUARD_TOS_ANY_SET_r11 981 -#define _GUARD_TOS_ANY_SET_r22 982 -#define _GUARD_TOS_ANY_SET_r33 983 -#define _GUARD_TOS_DICT_r01 984 -#define _GUARD_TOS_DICT_r11 985 -#define _GUARD_TOS_DICT_r22 986 -#define _GUARD_TOS_DICT_r33 987 -#define _GUARD_TOS_FLOAT_r01 988 -#define _GUARD_TOS_FLOAT_r11 989 -#define _GUARD_TOS_FLOAT_r22 990 -#define _GUARD_TOS_FLOAT_r33 991 -#define _GUARD_TOS_FROZENDICT_r01 992 -#define _GUARD_TOS_FROZENDICT_r11 993 -#define _GUARD_TOS_FROZENDICT_r22 994 -#define _GUARD_TOS_FROZENDICT_r33 995 -#define _GUARD_TOS_FROZENSET_r01 996 -#define _GUARD_TOS_FROZENSET_r11 997 -#define _GUARD_TOS_FROZENSET_r22 998 -#define _GUARD_TOS_FROZENSET_r33 999 -#define _GUARD_TOS_INT_r01 1000 -#define _GUARD_TOS_INT_r11 1001 -#define _GUARD_TOS_INT_r22 1002 -#define _GUARD_TOS_INT_r33 1003 -#define _GUARD_TOS_LIST_r01 1004 -#define _GUARD_TOS_LIST_r11 1005 -#define _GUARD_TOS_LIST_r22 1006 -#define _GUARD_TOS_LIST_r33 1007 -#define _GUARD_TOS_OVERFLOWED_r01 1008 -#define _GUARD_TOS_OVERFLOWED_r11 1009 -#define _GUARD_TOS_OVERFLOWED_r22 1010 -#define _GUARD_TOS_OVERFLOWED_r33 1011 -#define _GUARD_TOS_SET_r01 1012 -#define _GUARD_TOS_SET_r11 1013 -#define _GUARD_TOS_SET_r22 1014 -#define _GUARD_TOS_SET_r33 1015 -#define _GUARD_TOS_SLICE_r01 1016 -#define _GUARD_TOS_SLICE_r11 1017 -#define _GUARD_TOS_SLICE_r22 1018 -#define _GUARD_TOS_SLICE_r33 1019 -#define _GUARD_TOS_TUPLE_r01 1020 -#define _GUARD_TOS_TUPLE_r11 1021 -#define _GUARD_TOS_TUPLE_r22 1022 -#define _GUARD_TOS_TUPLE_r33 1023 -#define _GUARD_TOS_UNICODE_r01 1024 -#define _GUARD_TOS_UNICODE_r11 1025 -#define _GUARD_TOS_UNICODE_r22 1026 -#define _GUARD_TOS_UNICODE_r33 1027 -#define _GUARD_TYPE_VERSION_r01 1028 -#define _GUARD_TYPE_VERSION_r11 1029 -#define _GUARD_TYPE_VERSION_r22 1030 -#define _GUARD_TYPE_VERSION_r33 1031 -#define _GUARD_TYPE_VERSION_LOCKED_r01 1032 -#define _GUARD_TYPE_VERSION_LOCKED_r11 1033 -#define _GUARD_TYPE_VERSION_LOCKED_r22 1034 -#define _GUARD_TYPE_VERSION_LOCKED_r33 1035 -#define _HANDLE_PENDING_AND_DEOPT_r00 1036 -#define _HANDLE_PENDING_AND_DEOPT_r10 1037 -#define _HANDLE_PENDING_AND_DEOPT_r20 1038 -#define _HANDLE_PENDING_AND_DEOPT_r30 1039 -#define _IMPORT_FROM_r12 1040 -#define _IMPORT_NAME_r21 1041 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1042 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1043 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1044 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1045 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1046 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1047 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1048 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1049 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1050 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1051 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1052 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1053 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1054 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1055 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1056 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1057 -#define _INSERT_NULL_r10 1058 -#define _INSTRUMENTED_FOR_ITER_r23 1059 -#define _INSTRUMENTED_INSTRUCTION_r00 1060 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1061 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1062 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1063 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1064 -#define _INSTRUMENTED_LINE_r00 1065 -#define _INSTRUMENTED_NOT_TAKEN_r00 1066 -#define _INSTRUMENTED_NOT_TAKEN_r11 1067 -#define _INSTRUMENTED_NOT_TAKEN_r22 1068 -#define _INSTRUMENTED_NOT_TAKEN_r33 1069 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1070 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1071 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1072 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1073 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1074 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1075 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1076 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1077 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1078 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1079 -#define _IS_NONE_r11 1080 -#define _IS_OP_r03 1081 -#define _IS_OP_r13 1082 -#define _IS_OP_r23 1083 -#define _ITER_CHECK_LIST_r02 1084 -#define _ITER_CHECK_LIST_r12 1085 -#define _ITER_CHECK_LIST_r22 1086 -#define _ITER_CHECK_LIST_r33 1087 -#define _ITER_CHECK_RANGE_r02 1088 -#define _ITER_CHECK_RANGE_r12 1089 -#define _ITER_CHECK_RANGE_r22 1090 -#define _ITER_CHECK_RANGE_r33 1091 -#define _ITER_CHECK_TUPLE_r02 1092 -#define _ITER_CHECK_TUPLE_r12 1093 -#define _ITER_CHECK_TUPLE_r22 1094 -#define _ITER_CHECK_TUPLE_r33 1095 -#define _ITER_JUMP_LIST_r02 1096 -#define _ITER_JUMP_LIST_r12 1097 -#define _ITER_JUMP_LIST_r22 1098 -#define _ITER_JUMP_LIST_r33 1099 -#define _ITER_JUMP_RANGE_r02 1100 -#define _ITER_JUMP_RANGE_r12 1101 -#define _ITER_JUMP_RANGE_r22 1102 -#define _ITER_JUMP_RANGE_r33 1103 -#define _ITER_JUMP_TUPLE_r02 1104 -#define _ITER_JUMP_TUPLE_r12 1105 -#define _ITER_JUMP_TUPLE_r22 1106 -#define _ITER_JUMP_TUPLE_r33 1107 -#define _ITER_NEXT_LIST_r23 1108 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1109 -#define _ITER_NEXT_RANGE_r03 1110 -#define _ITER_NEXT_RANGE_r13 1111 -#define _ITER_NEXT_RANGE_r23 1112 -#define _ITER_NEXT_TUPLE_r03 1113 -#define _ITER_NEXT_TUPLE_r13 1114 -#define _ITER_NEXT_TUPLE_r23 1115 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1116 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1117 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1118 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1119 -#define _JUMP_TO_TOP_r00 1120 -#define _LIST_APPEND_r10 1121 -#define _LIST_EXTEND_r10 1122 -#define _LOAD_ATTR_r10 1123 -#define _LOAD_ATTR_CLASS_r11 1124 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1125 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1126 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1127 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1128 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1129 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1130 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1131 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1132 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1133 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1134 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1135 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1136 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1137 -#define _LOAD_ATTR_MODULE_r12 1138 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1139 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1140 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1141 -#define _LOAD_ATTR_SLOT_r02 1142 -#define _LOAD_ATTR_SLOT_r12 1143 -#define _LOAD_ATTR_SLOT_r23 1144 -#define _LOAD_ATTR_WITH_HINT_r12 1145 -#define _LOAD_BUILD_CLASS_r01 1146 -#define _LOAD_BYTECODE_r00 1147 -#define _LOAD_COMMON_CONSTANT_r01 1148 -#define _LOAD_COMMON_CONSTANT_r12 1149 -#define _LOAD_COMMON_CONSTANT_r23 1150 -#define _LOAD_CONST_r01 1151 -#define _LOAD_CONST_r12 1152 -#define _LOAD_CONST_r23 1153 -#define _LOAD_CONST_INLINE_r01 1154 -#define _LOAD_CONST_INLINE_r12 1155 -#define _LOAD_CONST_INLINE_r23 1156 -#define _LOAD_CONST_INLINE_BORROW_r01 1157 -#define _LOAD_CONST_INLINE_BORROW_r12 1158 -#define _LOAD_CONST_INLINE_BORROW_r23 1159 -#define _LOAD_CONST_UNDER_INLINE_r02 1160 -#define _LOAD_CONST_UNDER_INLINE_r12 1161 -#define _LOAD_CONST_UNDER_INLINE_r23 1162 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1163 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1164 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1165 -#define _LOAD_DEREF_r01 1166 -#define _LOAD_FAST_r01 1167 -#define _LOAD_FAST_r12 1168 -#define _LOAD_FAST_r23 1169 -#define _LOAD_FAST_0_r01 1170 -#define _LOAD_FAST_0_r12 1171 -#define _LOAD_FAST_0_r23 1172 -#define _LOAD_FAST_1_r01 1173 -#define _LOAD_FAST_1_r12 1174 -#define _LOAD_FAST_1_r23 1175 -#define _LOAD_FAST_2_r01 1176 -#define _LOAD_FAST_2_r12 1177 -#define _LOAD_FAST_2_r23 1178 -#define _LOAD_FAST_3_r01 1179 -#define _LOAD_FAST_3_r12 1180 -#define _LOAD_FAST_3_r23 1181 -#define _LOAD_FAST_4_r01 1182 -#define _LOAD_FAST_4_r12 1183 -#define _LOAD_FAST_4_r23 1184 -#define _LOAD_FAST_5_r01 1185 -#define _LOAD_FAST_5_r12 1186 -#define _LOAD_FAST_5_r23 1187 -#define _LOAD_FAST_6_r01 1188 -#define _LOAD_FAST_6_r12 1189 -#define _LOAD_FAST_6_r23 1190 -#define _LOAD_FAST_7_r01 1191 -#define _LOAD_FAST_7_r12 1192 -#define _LOAD_FAST_7_r23 1193 -#define _LOAD_FAST_AND_CLEAR_r01 1194 -#define _LOAD_FAST_AND_CLEAR_r12 1195 -#define _LOAD_FAST_AND_CLEAR_r23 1196 -#define _LOAD_FAST_BORROW_r01 1197 -#define _LOAD_FAST_BORROW_r12 1198 -#define _LOAD_FAST_BORROW_r23 1199 -#define _LOAD_FAST_BORROW_0_r01 1200 -#define _LOAD_FAST_BORROW_0_r12 1201 -#define _LOAD_FAST_BORROW_0_r23 1202 -#define _LOAD_FAST_BORROW_1_r01 1203 -#define _LOAD_FAST_BORROW_1_r12 1204 -#define _LOAD_FAST_BORROW_1_r23 1205 -#define _LOAD_FAST_BORROW_2_r01 1206 -#define _LOAD_FAST_BORROW_2_r12 1207 -#define _LOAD_FAST_BORROW_2_r23 1208 -#define _LOAD_FAST_BORROW_3_r01 1209 -#define _LOAD_FAST_BORROW_3_r12 1210 -#define _LOAD_FAST_BORROW_3_r23 1211 -#define _LOAD_FAST_BORROW_4_r01 1212 -#define _LOAD_FAST_BORROW_4_r12 1213 -#define _LOAD_FAST_BORROW_4_r23 1214 -#define _LOAD_FAST_BORROW_5_r01 1215 -#define _LOAD_FAST_BORROW_5_r12 1216 -#define _LOAD_FAST_BORROW_5_r23 1217 -#define _LOAD_FAST_BORROW_6_r01 1218 -#define _LOAD_FAST_BORROW_6_r12 1219 -#define _LOAD_FAST_BORROW_6_r23 1220 -#define _LOAD_FAST_BORROW_7_r01 1221 -#define _LOAD_FAST_BORROW_7_r12 1222 -#define _LOAD_FAST_BORROW_7_r23 1223 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1224 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1225 -#define _LOAD_FAST_CHECK_r01 1226 -#define _LOAD_FAST_CHECK_r12 1227 -#define _LOAD_FAST_CHECK_r23 1228 -#define _LOAD_FAST_LOAD_FAST_r02 1229 -#define _LOAD_FAST_LOAD_FAST_r13 1230 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1231 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1232 -#define _LOAD_GLOBAL_r00 1233 -#define _LOAD_GLOBAL_BUILTINS_r01 1234 -#define _LOAD_GLOBAL_MODULE_r01 1235 -#define _LOAD_LOCALS_r01 1236 -#define _LOAD_LOCALS_r12 1237 -#define _LOAD_LOCALS_r23 1238 -#define _LOAD_NAME_r01 1239 -#define _LOAD_SMALL_INT_r01 1240 -#define _LOAD_SMALL_INT_r12 1241 -#define _LOAD_SMALL_INT_r23 1242 -#define _LOAD_SMALL_INT_0_r01 1243 -#define _LOAD_SMALL_INT_0_r12 1244 -#define _LOAD_SMALL_INT_0_r23 1245 -#define _LOAD_SMALL_INT_1_r01 1246 -#define _LOAD_SMALL_INT_1_r12 1247 -#define _LOAD_SMALL_INT_1_r23 1248 -#define _LOAD_SMALL_INT_2_r01 1249 -#define _LOAD_SMALL_INT_2_r12 1250 -#define _LOAD_SMALL_INT_2_r23 1251 -#define _LOAD_SMALL_INT_3_r01 1252 -#define _LOAD_SMALL_INT_3_r12 1253 -#define _LOAD_SMALL_INT_3_r23 1254 -#define _LOAD_SPECIAL_r00 1255 -#define _LOAD_SUPER_ATTR_ATTR_r31 1256 -#define _LOAD_SUPER_ATTR_METHOD_r32 1257 -#define _LOCK_OBJECT_r01 1258 -#define _LOCK_OBJECT_r11 1259 -#define _LOCK_OBJECT_r22 1260 -#define _LOCK_OBJECT_r33 1261 -#define _MAKE_CALLARGS_A_TUPLE_r33 1262 -#define _MAKE_CELL_r00 1263 -#define _MAKE_FUNCTION_r11 1264 -#define _MAKE_HEAP_SAFE_r01 1265 -#define _MAKE_HEAP_SAFE_r11 1266 -#define _MAKE_HEAP_SAFE_r22 1267 -#define _MAKE_HEAP_SAFE_r33 1268 -#define _MAKE_WARM_r00 1269 -#define _MAKE_WARM_r11 1270 -#define _MAKE_WARM_r22 1271 -#define _MAKE_WARM_r33 1272 -#define _MAP_ADD_r20 1273 -#define _MATCH_CLASS_r31 1274 -#define _MATCH_KEYS_r23 1275 -#define _MATCH_MAPPING_r02 1276 -#define _MATCH_MAPPING_r12 1277 -#define _MATCH_MAPPING_r23 1278 -#define _MATCH_SEQUENCE_r02 1279 -#define _MATCH_SEQUENCE_r12 1280 -#define _MATCH_SEQUENCE_r23 1281 -#define _MAYBE_EXPAND_METHOD_r00 1282 -#define _MAYBE_EXPAND_METHOD_KW_r11 1283 -#define _MONITOR_CALL_r00 1284 -#define _MONITOR_CALL_KW_r11 1285 -#define _MONITOR_JUMP_BACKWARD_r00 1286 -#define _MONITOR_JUMP_BACKWARD_r11 1287 -#define _MONITOR_JUMP_BACKWARD_r22 1288 -#define _MONITOR_JUMP_BACKWARD_r33 1289 -#define _MONITOR_RESUME_r00 1290 -#define _NOP_r00 1291 -#define _NOP_r11 1292 -#define _NOP_r22 1293 -#define _NOP_r33 1294 -#define _POP_CALL_r20 1295 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1296 -#define _POP_CALL_ONE_r30 1297 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1298 -#define _POP_CALL_TWO_r30 1299 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1300 -#define _POP_EXCEPT_r10 1301 -#define _POP_ITER_r20 1302 -#define _POP_JUMP_IF_FALSE_r00 1303 -#define _POP_JUMP_IF_FALSE_r10 1304 -#define _POP_JUMP_IF_FALSE_r21 1305 -#define _POP_JUMP_IF_FALSE_r32 1306 -#define _POP_JUMP_IF_TRUE_r00 1307 -#define _POP_JUMP_IF_TRUE_r10 1308 -#define _POP_JUMP_IF_TRUE_r21 1309 -#define _POP_JUMP_IF_TRUE_r32 1310 -#define _POP_TOP_r10 1311 -#define _POP_TOP_FLOAT_r00 1312 -#define _POP_TOP_FLOAT_r10 1313 -#define _POP_TOP_FLOAT_r21 1314 -#define _POP_TOP_FLOAT_r32 1315 -#define _POP_TOP_INT_r00 1316 -#define _POP_TOP_INT_r10 1317 -#define _POP_TOP_INT_r21 1318 -#define _POP_TOP_INT_r32 1319 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1320 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1321 -#define _POP_TOP_NOP_r00 1322 -#define _POP_TOP_NOP_r10 1323 -#define _POP_TOP_NOP_r21 1324 -#define _POP_TOP_NOP_r32 1325 -#define _POP_TOP_UNICODE_r00 1326 -#define _POP_TOP_UNICODE_r10 1327 -#define _POP_TOP_UNICODE_r21 1328 -#define _POP_TOP_UNICODE_r32 1329 -#define _POP_TWO_r20 1330 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1331 -#define _PUSH_EXC_INFO_r02 1332 -#define _PUSH_EXC_INFO_r12 1333 -#define _PUSH_EXC_INFO_r23 1334 -#define _PUSH_FRAME_r10 1335 -#define _PUSH_NULL_r01 1336 -#define _PUSH_NULL_r12 1337 -#define _PUSH_NULL_r23 1338 -#define _PUSH_NULL_CONDITIONAL_r00 1339 -#define _PY_FRAME_EX_r31 1340 -#define _PY_FRAME_GENERAL_r01 1341 -#define _PY_FRAME_KW_r11 1342 -#define _QUICKEN_RESUME_r00 1343 -#define _QUICKEN_RESUME_r11 1344 -#define _QUICKEN_RESUME_r22 1345 -#define _QUICKEN_RESUME_r33 1346 -#define _REPLACE_WITH_TRUE_r02 1347 -#define _REPLACE_WITH_TRUE_r12 1348 -#define _REPLACE_WITH_TRUE_r23 1349 -#define _RESUME_CHECK_r00 1350 -#define _RESUME_CHECK_r11 1351 -#define _RESUME_CHECK_r22 1352 -#define _RESUME_CHECK_r33 1353 -#define _RETURN_GENERATOR_r01 1354 -#define _RETURN_VALUE_r11 1355 -#define _SAVE_RETURN_OFFSET_r00 1356 -#define _SAVE_RETURN_OFFSET_r11 1357 -#define _SAVE_RETURN_OFFSET_r22 1358 -#define _SAVE_RETURN_OFFSET_r33 1359 -#define _SEND_r22 1360 -#define _SEND_GEN_FRAME_r22 1361 -#define _SETUP_ANNOTATIONS_r00 1362 -#define _SET_ADD_r10 1363 -#define _SET_FUNCTION_ATTRIBUTE_r01 1364 -#define _SET_FUNCTION_ATTRIBUTE_r11 1365 -#define _SET_FUNCTION_ATTRIBUTE_r21 1366 -#define _SET_FUNCTION_ATTRIBUTE_r32 1367 -#define _SET_IP_r00 1368 -#define _SET_IP_r11 1369 -#define _SET_IP_r22 1370 -#define _SET_IP_r33 1371 -#define _SET_UPDATE_r10 1372 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1373 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1374 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1375 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1376 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1377 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1378 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1379 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1380 -#define _SPILL_OR_RELOAD_r01 1381 -#define _SPILL_OR_RELOAD_r02 1382 -#define _SPILL_OR_RELOAD_r03 1383 -#define _SPILL_OR_RELOAD_r10 1384 -#define _SPILL_OR_RELOAD_r12 1385 -#define _SPILL_OR_RELOAD_r13 1386 -#define _SPILL_OR_RELOAD_r20 1387 -#define _SPILL_OR_RELOAD_r21 1388 -#define _SPILL_OR_RELOAD_r23 1389 -#define _SPILL_OR_RELOAD_r30 1390 -#define _SPILL_OR_RELOAD_r31 1391 -#define _SPILL_OR_RELOAD_r32 1392 -#define _START_EXECUTOR_r00 1393 -#define _STORE_ATTR_r20 1394 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1395 -#define _STORE_ATTR_SLOT_r21 1396 -#define _STORE_ATTR_WITH_HINT_r21 1397 -#define _STORE_DEREF_r10 1398 -#define _STORE_FAST_LOAD_FAST_r11 1399 -#define _STORE_FAST_STORE_FAST_r20 1400 -#define _STORE_GLOBAL_r10 1401 -#define _STORE_NAME_r10 1402 -#define _STORE_SLICE_r30 1403 -#define _STORE_SUBSCR_r30 1404 -#define _STORE_SUBSCR_DICT_r31 1405 -#define _STORE_SUBSCR_LIST_INT_r32 1406 -#define _SWAP_r11 1407 -#define _SWAP_2_r02 1408 -#define _SWAP_2_r12 1409 -#define _SWAP_2_r22 1410 -#define _SWAP_2_r33 1411 -#define _SWAP_3_r03 1412 -#define _SWAP_3_r13 1413 -#define _SWAP_3_r23 1414 -#define _SWAP_3_r33 1415 -#define _SWAP_FAST_r01 1416 -#define _SWAP_FAST_r11 1417 -#define _SWAP_FAST_r22 1418 -#define _SWAP_FAST_r33 1419 -#define _SWAP_FAST_0_r01 1420 -#define _SWAP_FAST_0_r11 1421 -#define _SWAP_FAST_0_r22 1422 -#define _SWAP_FAST_0_r33 1423 -#define _SWAP_FAST_1_r01 1424 -#define _SWAP_FAST_1_r11 1425 -#define _SWAP_FAST_1_r22 1426 -#define _SWAP_FAST_1_r33 1427 -#define _SWAP_FAST_2_r01 1428 -#define _SWAP_FAST_2_r11 1429 -#define _SWAP_FAST_2_r22 1430 -#define _SWAP_FAST_2_r33 1431 -#define _SWAP_FAST_3_r01 1432 -#define _SWAP_FAST_3_r11 1433 -#define _SWAP_FAST_3_r22 1434 -#define _SWAP_FAST_3_r33 1435 -#define _SWAP_FAST_4_r01 1436 -#define _SWAP_FAST_4_r11 1437 -#define _SWAP_FAST_4_r22 1438 -#define _SWAP_FAST_4_r33 1439 -#define _SWAP_FAST_5_r01 1440 -#define _SWAP_FAST_5_r11 1441 -#define _SWAP_FAST_5_r22 1442 -#define _SWAP_FAST_5_r33 1443 -#define _SWAP_FAST_6_r01 1444 -#define _SWAP_FAST_6_r11 1445 -#define _SWAP_FAST_6_r22 1446 -#define _SWAP_FAST_6_r33 1447 -#define _SWAP_FAST_7_r01 1448 -#define _SWAP_FAST_7_r11 1449 -#define _SWAP_FAST_7_r22 1450 -#define _SWAP_FAST_7_r33 1451 -#define _TIER2_RESUME_CHECK_r00 1452 -#define _TIER2_RESUME_CHECK_r11 1453 -#define _TIER2_RESUME_CHECK_r22 1454 -#define _TIER2_RESUME_CHECK_r33 1455 -#define _TO_BOOL_r11 1456 -#define _TO_BOOL_BOOL_r01 1457 -#define _TO_BOOL_BOOL_r11 1458 -#define _TO_BOOL_BOOL_r22 1459 -#define _TO_BOOL_BOOL_r33 1460 -#define _TO_BOOL_INT_r02 1461 -#define _TO_BOOL_INT_r12 1462 -#define _TO_BOOL_INT_r23 1463 -#define _TO_BOOL_LIST_r02 1464 -#define _TO_BOOL_LIST_r12 1465 -#define _TO_BOOL_LIST_r23 1466 -#define _TO_BOOL_NONE_r01 1467 -#define _TO_BOOL_NONE_r11 1468 -#define _TO_BOOL_NONE_r22 1469 -#define _TO_BOOL_NONE_r33 1470 -#define _TO_BOOL_STR_r02 1471 -#define _TO_BOOL_STR_r12 1472 -#define _TO_BOOL_STR_r23 1473 -#define _TRACE_RECORD_r00 1474 -#define _UNARY_INVERT_r12 1475 -#define _UNARY_NEGATIVE_r12 1476 -#define _UNARY_NOT_r01 1477 -#define _UNARY_NOT_r11 1478 -#define _UNARY_NOT_r22 1479 -#define _UNARY_NOT_r33 1480 -#define _UNPACK_EX_r10 1481 -#define _UNPACK_SEQUENCE_r10 1482 -#define _UNPACK_SEQUENCE_LIST_r10 1483 -#define _UNPACK_SEQUENCE_TUPLE_r10 1484 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1485 -#define _WITH_EXCEPT_START_r33 1486 -#define _YIELD_VALUE_r11 1487 -#define MAX_UOP_REGS_ID 1487 +#define _YIELD_VALUE 598 +#define MAX_UOP_ID 598 +#define _BINARY_OP_r23 599 +#define _BINARY_OP_ADD_FLOAT_r03 600 +#define _BINARY_OP_ADD_FLOAT_r13 601 +#define _BINARY_OP_ADD_FLOAT_r23 602 +#define _BINARY_OP_ADD_INT_r03 603 +#define _BINARY_OP_ADD_INT_r13 604 +#define _BINARY_OP_ADD_INT_r23 605 +#define _BINARY_OP_ADD_UNICODE_r03 606 +#define _BINARY_OP_ADD_UNICODE_r13 607 +#define _BINARY_OP_ADD_UNICODE_r23 608 +#define _BINARY_OP_EXTEND_r23 609 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 610 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 611 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 612 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 613 +#define _BINARY_OP_MULTIPLY_INT_r03 614 +#define _BINARY_OP_MULTIPLY_INT_r13 615 +#define _BINARY_OP_MULTIPLY_INT_r23 616 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 617 +#define _BINARY_OP_SUBSCR_DICT_r23 618 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 619 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 620 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 621 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 622 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 623 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 624 +#define _BINARY_OP_SUBSCR_STR_INT_r23 625 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 626 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 627 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 628 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 629 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 630 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 631 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 632 +#define _BINARY_OP_SUBTRACT_INT_r03 633 +#define _BINARY_OP_SUBTRACT_INT_r13 634 +#define _BINARY_OP_SUBTRACT_INT_r23 635 +#define _BINARY_SLICE_r31 636 +#define _BUILD_INTERPOLATION_r01 637 +#define _BUILD_LIST_r01 638 +#define _BUILD_MAP_r01 639 +#define _BUILD_SET_r01 640 +#define _BUILD_SLICE_r01 641 +#define _BUILD_STRING_r01 642 +#define _BUILD_TEMPLATE_r21 643 +#define _BUILD_TUPLE_r01 644 +#define _CALL_BUILTIN_CLASS_r01 645 +#define _CALL_BUILTIN_FAST_r01 646 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 647 +#define _CALL_BUILTIN_O_r03 648 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 649 +#define _CALL_INTRINSIC_1_r11 650 +#define _CALL_INTRINSIC_2_r21 651 +#define _CALL_ISINSTANCE_r31 652 +#define _CALL_KW_NON_PY_r11 653 +#define _CALL_LEN_r33 654 +#define _CALL_LIST_APPEND_r03 655 +#define _CALL_LIST_APPEND_r13 656 +#define _CALL_LIST_APPEND_r23 657 +#define _CALL_LIST_APPEND_r33 658 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 659 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 660 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 661 +#define _CALL_METHOD_DESCRIPTOR_O_r03 662 +#define _CALL_NON_PY_GENERAL_r01 663 +#define _CALL_STR_1_r32 664 +#define _CALL_TUPLE_1_r32 665 +#define _CALL_TYPE_1_r02 666 +#define _CALL_TYPE_1_r12 667 +#define _CALL_TYPE_1_r22 668 +#define _CALL_TYPE_1_r32 669 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 670 +#define _CHECK_ATTR_CLASS_r01 671 +#define _CHECK_ATTR_CLASS_r11 672 +#define _CHECK_ATTR_CLASS_r22 673 +#define _CHECK_ATTR_CLASS_r33 674 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 675 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 676 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 677 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 678 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 679 +#define _CHECK_EG_MATCH_r22 680 +#define _CHECK_EXC_MATCH_r22 681 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 682 +#define _CHECK_FUNCTION_VERSION_r00 683 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 684 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 685 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 686 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 687 +#define _CHECK_FUNCTION_VERSION_KW_r11 688 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 689 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 690 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 691 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 692 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 693 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 694 +#define _CHECK_IS_PY_CALLABLE_EX_r03 695 +#define _CHECK_IS_PY_CALLABLE_EX_r13 696 +#define _CHECK_IS_PY_CALLABLE_EX_r23 697 +#define _CHECK_IS_PY_CALLABLE_EX_r33 698 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 699 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 700 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 701 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 702 +#define _CHECK_METHOD_VERSION_r00 703 +#define _CHECK_METHOD_VERSION_KW_r11 704 +#define _CHECK_PEP_523_r00 705 +#define _CHECK_PEP_523_r11 706 +#define _CHECK_PEP_523_r22 707 +#define _CHECK_PEP_523_r33 708 +#define _CHECK_PERIODIC_r00 709 +#define _CHECK_PERIODIC_AT_END_r00 710 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 711 +#define _CHECK_RECURSION_REMAINING_r00 712 +#define _CHECK_RECURSION_REMAINING_r11 713 +#define _CHECK_RECURSION_REMAINING_r22 714 +#define _CHECK_RECURSION_REMAINING_r33 715 +#define _CHECK_STACK_SPACE_r00 716 +#define _CHECK_STACK_SPACE_OPERAND_r00 717 +#define _CHECK_STACK_SPACE_OPERAND_r11 718 +#define _CHECK_STACK_SPACE_OPERAND_r22 719 +#define _CHECK_STACK_SPACE_OPERAND_r33 720 +#define _CHECK_VALIDITY_r00 721 +#define _CHECK_VALIDITY_r11 722 +#define _CHECK_VALIDITY_r22 723 +#define _CHECK_VALIDITY_r33 724 +#define _COLD_DYNAMIC_EXIT_r00 725 +#define _COLD_EXIT_r00 726 +#define _COMPARE_OP_r21 727 +#define _COMPARE_OP_FLOAT_r03 728 +#define _COMPARE_OP_FLOAT_r13 729 +#define _COMPARE_OP_FLOAT_r23 730 +#define _COMPARE_OP_INT_r23 731 +#define _COMPARE_OP_STR_r23 732 +#define _CONTAINS_OP_r23 733 +#define _CONTAINS_OP_DICT_r23 734 +#define _CONTAINS_OP_SET_r23 735 +#define _CONVERT_VALUE_r11 736 +#define _COPY_r01 737 +#define _COPY_1_r02 738 +#define _COPY_1_r12 739 +#define _COPY_1_r23 740 +#define _COPY_2_r03 741 +#define _COPY_2_r13 742 +#define _COPY_2_r23 743 +#define _COPY_3_r03 744 +#define _COPY_3_r13 745 +#define _COPY_3_r23 746 +#define _COPY_3_r33 747 +#define _COPY_FREE_VARS_r00 748 +#define _COPY_FREE_VARS_r11 749 +#define _COPY_FREE_VARS_r22 750 +#define _COPY_FREE_VARS_r33 751 +#define _CREATE_INIT_FRAME_r01 752 +#define _DELETE_ATTR_r10 753 +#define _DELETE_DEREF_r00 754 +#define _DELETE_FAST_r00 755 +#define _DELETE_GLOBAL_r00 756 +#define _DELETE_NAME_r00 757 +#define _DELETE_SUBSCR_r20 758 +#define _DEOPT_r00 759 +#define _DEOPT_r10 760 +#define _DEOPT_r20 761 +#define _DEOPT_r30 762 +#define _DICT_MERGE_r10 763 +#define _DICT_UPDATE_r10 764 +#define _DO_CALL_r01 765 +#define _DO_CALL_FUNCTION_EX_r31 766 +#define _DO_CALL_KW_r11 767 +#define _DYNAMIC_EXIT_r00 768 +#define _DYNAMIC_EXIT_r10 769 +#define _DYNAMIC_EXIT_r20 770 +#define _DYNAMIC_EXIT_r30 771 +#define _END_FOR_r10 772 +#define _END_SEND_r21 773 +#define _ERROR_POP_N_r00 774 +#define _EXIT_INIT_CHECK_r10 775 +#define _EXIT_TRACE_r00 776 +#define _EXIT_TRACE_r10 777 +#define _EXIT_TRACE_r20 778 +#define _EXIT_TRACE_r30 779 +#define _EXPAND_METHOD_r00 780 +#define _EXPAND_METHOD_KW_r11 781 +#define _FATAL_ERROR_r00 782 +#define _FATAL_ERROR_r11 783 +#define _FATAL_ERROR_r22 784 +#define _FATAL_ERROR_r33 785 +#define _FORMAT_SIMPLE_r11 786 +#define _FORMAT_WITH_SPEC_r21 787 +#define _FOR_ITER_r23 788 +#define _FOR_ITER_GEN_FRAME_r03 789 +#define _FOR_ITER_GEN_FRAME_r13 790 +#define _FOR_ITER_GEN_FRAME_r23 791 +#define _FOR_ITER_TIER_TWO_r23 792 +#define _GET_AITER_r11 793 +#define _GET_ANEXT_r12 794 +#define _GET_AWAITABLE_r11 795 +#define _GET_ITER_r12 796 +#define _GET_LEN_r12 797 +#define _GET_YIELD_FROM_ITER_r11 798 +#define _GUARD_BINARY_OP_EXTEND_r22 799 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 800 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 801 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 802 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 803 +#define _GUARD_BIT_IS_SET_POP_r00 804 +#define _GUARD_BIT_IS_SET_POP_r10 805 +#define _GUARD_BIT_IS_SET_POP_r21 806 +#define _GUARD_BIT_IS_SET_POP_r32 807 +#define _GUARD_BIT_IS_SET_POP_4_r00 808 +#define _GUARD_BIT_IS_SET_POP_4_r10 809 +#define _GUARD_BIT_IS_SET_POP_4_r21 810 +#define _GUARD_BIT_IS_SET_POP_4_r32 811 +#define _GUARD_BIT_IS_SET_POP_5_r00 812 +#define _GUARD_BIT_IS_SET_POP_5_r10 813 +#define _GUARD_BIT_IS_SET_POP_5_r21 814 +#define _GUARD_BIT_IS_SET_POP_5_r32 815 +#define _GUARD_BIT_IS_SET_POP_6_r00 816 +#define _GUARD_BIT_IS_SET_POP_6_r10 817 +#define _GUARD_BIT_IS_SET_POP_6_r21 818 +#define _GUARD_BIT_IS_SET_POP_6_r32 819 +#define _GUARD_BIT_IS_SET_POP_7_r00 820 +#define _GUARD_BIT_IS_SET_POP_7_r10 821 +#define _GUARD_BIT_IS_SET_POP_7_r21 822 +#define _GUARD_BIT_IS_SET_POP_7_r32 823 +#define _GUARD_BIT_IS_UNSET_POP_r00 824 +#define _GUARD_BIT_IS_UNSET_POP_r10 825 +#define _GUARD_BIT_IS_UNSET_POP_r21 826 +#define _GUARD_BIT_IS_UNSET_POP_r32 827 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 828 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 829 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 830 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 831 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 832 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 833 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 834 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 835 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 836 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 837 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 838 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 839 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 840 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 841 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 842 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 843 +#define _GUARD_CALLABLE_ISINSTANCE_r03 844 +#define _GUARD_CALLABLE_ISINSTANCE_r13 845 +#define _GUARD_CALLABLE_ISINSTANCE_r23 846 +#define _GUARD_CALLABLE_ISINSTANCE_r33 847 +#define _GUARD_CALLABLE_LEN_r03 848 +#define _GUARD_CALLABLE_LEN_r13 849 +#define _GUARD_CALLABLE_LEN_r23 850 +#define _GUARD_CALLABLE_LEN_r33 851 +#define _GUARD_CALLABLE_LIST_APPEND_r03 852 +#define _GUARD_CALLABLE_LIST_APPEND_r13 853 +#define _GUARD_CALLABLE_LIST_APPEND_r23 854 +#define _GUARD_CALLABLE_LIST_APPEND_r33 855 +#define _GUARD_CALLABLE_STR_1_r03 856 +#define _GUARD_CALLABLE_STR_1_r13 857 +#define _GUARD_CALLABLE_STR_1_r23 858 +#define _GUARD_CALLABLE_STR_1_r33 859 +#define _GUARD_CALLABLE_TUPLE_1_r03 860 +#define _GUARD_CALLABLE_TUPLE_1_r13 861 +#define _GUARD_CALLABLE_TUPLE_1_r23 862 +#define _GUARD_CALLABLE_TUPLE_1_r33 863 +#define _GUARD_CALLABLE_TYPE_1_r03 864 +#define _GUARD_CALLABLE_TYPE_1_r13 865 +#define _GUARD_CALLABLE_TYPE_1_r23 866 +#define _GUARD_CALLABLE_TYPE_1_r33 867 +#define _GUARD_CODE_VERSION_r00 868 +#define _GUARD_CODE_VERSION_r11 869 +#define _GUARD_CODE_VERSION_r22 870 +#define _GUARD_CODE_VERSION_r33 871 +#define _GUARD_DORV_NO_DICT_r01 872 +#define _GUARD_DORV_NO_DICT_r11 873 +#define _GUARD_DORV_NO_DICT_r22 874 +#define _GUARD_DORV_NO_DICT_r33 875 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 876 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 877 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 878 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 879 +#define _GUARD_GLOBALS_VERSION_r00 880 +#define _GUARD_GLOBALS_VERSION_r11 881 +#define _GUARD_GLOBALS_VERSION_r22 882 +#define _GUARD_GLOBALS_VERSION_r33 883 +#define _GUARD_IP_RETURN_GENERATOR_r00 884 +#define _GUARD_IP_RETURN_GENERATOR_r11 885 +#define _GUARD_IP_RETURN_GENERATOR_r22 886 +#define _GUARD_IP_RETURN_GENERATOR_r33 887 +#define _GUARD_IP_RETURN_VALUE_r00 888 +#define _GUARD_IP_RETURN_VALUE_r11 889 +#define _GUARD_IP_RETURN_VALUE_r22 890 +#define _GUARD_IP_RETURN_VALUE_r33 891 +#define _GUARD_IP_YIELD_VALUE_r00 892 +#define _GUARD_IP_YIELD_VALUE_r11 893 +#define _GUARD_IP_YIELD_VALUE_r22 894 +#define _GUARD_IP_YIELD_VALUE_r33 895 +#define _GUARD_IP__PUSH_FRAME_r00 896 +#define _GUARD_IP__PUSH_FRAME_r11 897 +#define _GUARD_IP__PUSH_FRAME_r22 898 +#define _GUARD_IP__PUSH_FRAME_r33 899 +#define _GUARD_IS_FALSE_POP_r00 900 +#define _GUARD_IS_FALSE_POP_r10 901 +#define _GUARD_IS_FALSE_POP_r21 902 +#define _GUARD_IS_FALSE_POP_r32 903 +#define _GUARD_IS_NONE_POP_r00 904 +#define _GUARD_IS_NONE_POP_r10 905 +#define _GUARD_IS_NONE_POP_r21 906 +#define _GUARD_IS_NONE_POP_r32 907 +#define _GUARD_IS_NOT_NONE_POP_r10 908 +#define _GUARD_IS_TRUE_POP_r00 909 +#define _GUARD_IS_TRUE_POP_r10 910 +#define _GUARD_IS_TRUE_POP_r21 911 +#define _GUARD_IS_TRUE_POP_r32 912 +#define _GUARD_KEYS_VERSION_r01 913 +#define _GUARD_KEYS_VERSION_r11 914 +#define _GUARD_KEYS_VERSION_r22 915 +#define _GUARD_KEYS_VERSION_r33 916 +#define _GUARD_NOS_ANY_DICT_r02 917 +#define _GUARD_NOS_ANY_DICT_r12 918 +#define _GUARD_NOS_ANY_DICT_r22 919 +#define _GUARD_NOS_ANY_DICT_r33 920 +#define _GUARD_NOS_COMPACT_ASCII_r02 921 +#define _GUARD_NOS_COMPACT_ASCII_r12 922 +#define _GUARD_NOS_COMPACT_ASCII_r22 923 +#define _GUARD_NOS_COMPACT_ASCII_r33 924 +#define _GUARD_NOS_DICT_r02 925 +#define _GUARD_NOS_DICT_r12 926 +#define _GUARD_NOS_DICT_r22 927 +#define _GUARD_NOS_DICT_r33 928 +#define _GUARD_NOS_FLOAT_r02 929 +#define _GUARD_NOS_FLOAT_r12 930 +#define _GUARD_NOS_FLOAT_r22 931 +#define _GUARD_NOS_FLOAT_r33 932 +#define _GUARD_NOS_INT_r02 933 +#define _GUARD_NOS_INT_r12 934 +#define _GUARD_NOS_INT_r22 935 +#define _GUARD_NOS_INT_r33 936 +#define _GUARD_NOS_LIST_r02 937 +#define _GUARD_NOS_LIST_r12 938 +#define _GUARD_NOS_LIST_r22 939 +#define _GUARD_NOS_LIST_r33 940 +#define _GUARD_NOS_NOT_NULL_r02 941 +#define _GUARD_NOS_NOT_NULL_r12 942 +#define _GUARD_NOS_NOT_NULL_r22 943 +#define _GUARD_NOS_NOT_NULL_r33 944 +#define _GUARD_NOS_NULL_r02 945 +#define _GUARD_NOS_NULL_r12 946 +#define _GUARD_NOS_NULL_r22 947 +#define _GUARD_NOS_NULL_r33 948 +#define _GUARD_NOS_OVERFLOWED_r02 949 +#define _GUARD_NOS_OVERFLOWED_r12 950 +#define _GUARD_NOS_OVERFLOWED_r22 951 +#define _GUARD_NOS_OVERFLOWED_r33 952 +#define _GUARD_NOS_TUPLE_r02 953 +#define _GUARD_NOS_TUPLE_r12 954 +#define _GUARD_NOS_TUPLE_r22 955 +#define _GUARD_NOS_TUPLE_r33 956 +#define _GUARD_NOS_UNICODE_r02 957 +#define _GUARD_NOS_UNICODE_r12 958 +#define _GUARD_NOS_UNICODE_r22 959 +#define _GUARD_NOS_UNICODE_r33 960 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 961 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 962 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 963 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 964 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 965 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 966 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 967 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 968 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 969 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 970 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 971 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 972 +#define _GUARD_THIRD_NULL_r03 973 +#define _GUARD_THIRD_NULL_r13 974 +#define _GUARD_THIRD_NULL_r23 975 +#define _GUARD_THIRD_NULL_r33 976 +#define _GUARD_TOS_ANY_DICT_r01 977 +#define _GUARD_TOS_ANY_DICT_r11 978 +#define _GUARD_TOS_ANY_DICT_r22 979 +#define _GUARD_TOS_ANY_DICT_r33 980 +#define _GUARD_TOS_ANY_SET_r01 981 +#define _GUARD_TOS_ANY_SET_r11 982 +#define _GUARD_TOS_ANY_SET_r22 983 +#define _GUARD_TOS_ANY_SET_r33 984 +#define _GUARD_TOS_DICT_r01 985 +#define _GUARD_TOS_DICT_r11 986 +#define _GUARD_TOS_DICT_r22 987 +#define _GUARD_TOS_DICT_r33 988 +#define _GUARD_TOS_FLOAT_r01 989 +#define _GUARD_TOS_FLOAT_r11 990 +#define _GUARD_TOS_FLOAT_r22 991 +#define _GUARD_TOS_FLOAT_r33 992 +#define _GUARD_TOS_FROZENDICT_r01 993 +#define _GUARD_TOS_FROZENDICT_r11 994 +#define _GUARD_TOS_FROZENDICT_r22 995 +#define _GUARD_TOS_FROZENDICT_r33 996 +#define _GUARD_TOS_FROZENSET_r01 997 +#define _GUARD_TOS_FROZENSET_r11 998 +#define _GUARD_TOS_FROZENSET_r22 999 +#define _GUARD_TOS_FROZENSET_r33 1000 +#define _GUARD_TOS_INT_r01 1001 +#define _GUARD_TOS_INT_r11 1002 +#define _GUARD_TOS_INT_r22 1003 +#define _GUARD_TOS_INT_r33 1004 +#define _GUARD_TOS_LIST_r01 1005 +#define _GUARD_TOS_LIST_r11 1006 +#define _GUARD_TOS_LIST_r22 1007 +#define _GUARD_TOS_LIST_r33 1008 +#define _GUARD_TOS_OVERFLOWED_r01 1009 +#define _GUARD_TOS_OVERFLOWED_r11 1010 +#define _GUARD_TOS_OVERFLOWED_r22 1011 +#define _GUARD_TOS_OVERFLOWED_r33 1012 +#define _GUARD_TOS_SET_r01 1013 +#define _GUARD_TOS_SET_r11 1014 +#define _GUARD_TOS_SET_r22 1015 +#define _GUARD_TOS_SET_r33 1016 +#define _GUARD_TOS_SLICE_r01 1017 +#define _GUARD_TOS_SLICE_r11 1018 +#define _GUARD_TOS_SLICE_r22 1019 +#define _GUARD_TOS_SLICE_r33 1020 +#define _GUARD_TOS_TUPLE_r01 1021 +#define _GUARD_TOS_TUPLE_r11 1022 +#define _GUARD_TOS_TUPLE_r22 1023 +#define _GUARD_TOS_TUPLE_r33 1024 +#define _GUARD_TOS_UNICODE_r01 1025 +#define _GUARD_TOS_UNICODE_r11 1026 +#define _GUARD_TOS_UNICODE_r22 1027 +#define _GUARD_TOS_UNICODE_r33 1028 +#define _GUARD_TYPE_VERSION_r01 1029 +#define _GUARD_TYPE_VERSION_r11 1030 +#define _GUARD_TYPE_VERSION_r22 1031 +#define _GUARD_TYPE_VERSION_r33 1032 +#define _GUARD_TYPE_VERSION_LOCKED_r01 1033 +#define _GUARD_TYPE_VERSION_LOCKED_r11 1034 +#define _GUARD_TYPE_VERSION_LOCKED_r22 1035 +#define _GUARD_TYPE_VERSION_LOCKED_r33 1036 +#define _HANDLE_PENDING_AND_DEOPT_r00 1037 +#define _HANDLE_PENDING_AND_DEOPT_r10 1038 +#define _HANDLE_PENDING_AND_DEOPT_r20 1039 +#define _HANDLE_PENDING_AND_DEOPT_r30 1040 +#define _IMPORT_FROM_r12 1041 +#define _IMPORT_NAME_r21 1042 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1043 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1044 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1045 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1046 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1047 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1048 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1049 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1050 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1051 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1052 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1053 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1054 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1055 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1056 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1057 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1058 +#define _INSERT_NULL_r10 1059 +#define _INSTRUMENTED_FOR_ITER_r23 1060 +#define _INSTRUMENTED_INSTRUCTION_r00 1061 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1062 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1063 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1064 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1065 +#define _INSTRUMENTED_LINE_r00 1066 +#define _INSTRUMENTED_NOT_TAKEN_r00 1067 +#define _INSTRUMENTED_NOT_TAKEN_r11 1068 +#define _INSTRUMENTED_NOT_TAKEN_r22 1069 +#define _INSTRUMENTED_NOT_TAKEN_r33 1070 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1071 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1072 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1073 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1074 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1075 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1076 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1077 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1078 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1079 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1080 +#define _IS_NONE_r11 1081 +#define _IS_OP_r03 1082 +#define _IS_OP_r13 1083 +#define _IS_OP_r23 1084 +#define _ITER_CHECK_LIST_r02 1085 +#define _ITER_CHECK_LIST_r12 1086 +#define _ITER_CHECK_LIST_r22 1087 +#define _ITER_CHECK_LIST_r33 1088 +#define _ITER_CHECK_RANGE_r02 1089 +#define _ITER_CHECK_RANGE_r12 1090 +#define _ITER_CHECK_RANGE_r22 1091 +#define _ITER_CHECK_RANGE_r33 1092 +#define _ITER_CHECK_TUPLE_r02 1093 +#define _ITER_CHECK_TUPLE_r12 1094 +#define _ITER_CHECK_TUPLE_r22 1095 +#define _ITER_CHECK_TUPLE_r33 1096 +#define _ITER_JUMP_LIST_r02 1097 +#define _ITER_JUMP_LIST_r12 1098 +#define _ITER_JUMP_LIST_r22 1099 +#define _ITER_JUMP_LIST_r33 1100 +#define _ITER_JUMP_RANGE_r02 1101 +#define _ITER_JUMP_RANGE_r12 1102 +#define _ITER_JUMP_RANGE_r22 1103 +#define _ITER_JUMP_RANGE_r33 1104 +#define _ITER_JUMP_TUPLE_r02 1105 +#define _ITER_JUMP_TUPLE_r12 1106 +#define _ITER_JUMP_TUPLE_r22 1107 +#define _ITER_JUMP_TUPLE_r33 1108 +#define _ITER_NEXT_LIST_r23 1109 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1110 +#define _ITER_NEXT_RANGE_r03 1111 +#define _ITER_NEXT_RANGE_r13 1112 +#define _ITER_NEXT_RANGE_r23 1113 +#define _ITER_NEXT_TUPLE_r03 1114 +#define _ITER_NEXT_TUPLE_r13 1115 +#define _ITER_NEXT_TUPLE_r23 1116 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1117 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1118 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1119 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1120 +#define _JUMP_TO_TOP_r00 1121 +#define _LIST_APPEND_r10 1122 +#define _LIST_EXTEND_r10 1123 +#define _LOAD_ATTR_r10 1124 +#define _LOAD_ATTR_CLASS_r11 1125 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1126 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1127 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1128 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1129 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1130 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1131 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1132 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1133 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1134 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1135 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1136 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1137 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1138 +#define _LOAD_ATTR_MODULE_r12 1139 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1140 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1141 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1142 +#define _LOAD_ATTR_SLOT_r02 1143 +#define _LOAD_ATTR_SLOT_r12 1144 +#define _LOAD_ATTR_SLOT_r23 1145 +#define _LOAD_ATTR_WITH_HINT_r12 1146 +#define _LOAD_BUILD_CLASS_r01 1147 +#define _LOAD_BYTECODE_r00 1148 +#define _LOAD_COMMON_CONSTANT_r01 1149 +#define _LOAD_COMMON_CONSTANT_r12 1150 +#define _LOAD_COMMON_CONSTANT_r23 1151 +#define _LOAD_CONST_r01 1152 +#define _LOAD_CONST_r12 1153 +#define _LOAD_CONST_r23 1154 +#define _LOAD_CONST_INLINE_r01 1155 +#define _LOAD_CONST_INLINE_r12 1156 +#define _LOAD_CONST_INLINE_r23 1157 +#define _LOAD_CONST_INLINE_BORROW_r01 1158 +#define _LOAD_CONST_INLINE_BORROW_r12 1159 +#define _LOAD_CONST_INLINE_BORROW_r23 1160 +#define _LOAD_CONST_UNDER_INLINE_r02 1161 +#define _LOAD_CONST_UNDER_INLINE_r12 1162 +#define _LOAD_CONST_UNDER_INLINE_r23 1163 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1164 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1165 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1166 +#define _LOAD_DEREF_r01 1167 +#define _LOAD_FAST_r01 1168 +#define _LOAD_FAST_r12 1169 +#define _LOAD_FAST_r23 1170 +#define _LOAD_FAST_0_r01 1171 +#define _LOAD_FAST_0_r12 1172 +#define _LOAD_FAST_0_r23 1173 +#define _LOAD_FAST_1_r01 1174 +#define _LOAD_FAST_1_r12 1175 +#define _LOAD_FAST_1_r23 1176 +#define _LOAD_FAST_2_r01 1177 +#define _LOAD_FAST_2_r12 1178 +#define _LOAD_FAST_2_r23 1179 +#define _LOAD_FAST_3_r01 1180 +#define _LOAD_FAST_3_r12 1181 +#define _LOAD_FAST_3_r23 1182 +#define _LOAD_FAST_4_r01 1183 +#define _LOAD_FAST_4_r12 1184 +#define _LOAD_FAST_4_r23 1185 +#define _LOAD_FAST_5_r01 1186 +#define _LOAD_FAST_5_r12 1187 +#define _LOAD_FAST_5_r23 1188 +#define _LOAD_FAST_6_r01 1189 +#define _LOAD_FAST_6_r12 1190 +#define _LOAD_FAST_6_r23 1191 +#define _LOAD_FAST_7_r01 1192 +#define _LOAD_FAST_7_r12 1193 +#define _LOAD_FAST_7_r23 1194 +#define _LOAD_FAST_AND_CLEAR_r01 1195 +#define _LOAD_FAST_AND_CLEAR_r12 1196 +#define _LOAD_FAST_AND_CLEAR_r23 1197 +#define _LOAD_FAST_BORROW_r01 1198 +#define _LOAD_FAST_BORROW_r12 1199 +#define _LOAD_FAST_BORROW_r23 1200 +#define _LOAD_FAST_BORROW_0_r01 1201 +#define _LOAD_FAST_BORROW_0_r12 1202 +#define _LOAD_FAST_BORROW_0_r23 1203 +#define _LOAD_FAST_BORROW_1_r01 1204 +#define _LOAD_FAST_BORROW_1_r12 1205 +#define _LOAD_FAST_BORROW_1_r23 1206 +#define _LOAD_FAST_BORROW_2_r01 1207 +#define _LOAD_FAST_BORROW_2_r12 1208 +#define _LOAD_FAST_BORROW_2_r23 1209 +#define _LOAD_FAST_BORROW_3_r01 1210 +#define _LOAD_FAST_BORROW_3_r12 1211 +#define _LOAD_FAST_BORROW_3_r23 1212 +#define _LOAD_FAST_BORROW_4_r01 1213 +#define _LOAD_FAST_BORROW_4_r12 1214 +#define _LOAD_FAST_BORROW_4_r23 1215 +#define _LOAD_FAST_BORROW_5_r01 1216 +#define _LOAD_FAST_BORROW_5_r12 1217 +#define _LOAD_FAST_BORROW_5_r23 1218 +#define _LOAD_FAST_BORROW_6_r01 1219 +#define _LOAD_FAST_BORROW_6_r12 1220 +#define _LOAD_FAST_BORROW_6_r23 1221 +#define _LOAD_FAST_BORROW_7_r01 1222 +#define _LOAD_FAST_BORROW_7_r12 1223 +#define _LOAD_FAST_BORROW_7_r23 1224 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1225 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1226 +#define _LOAD_FAST_CHECK_r01 1227 +#define _LOAD_FAST_CHECK_r12 1228 +#define _LOAD_FAST_CHECK_r23 1229 +#define _LOAD_FAST_LOAD_FAST_r02 1230 +#define _LOAD_FAST_LOAD_FAST_r13 1231 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1232 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1233 +#define _LOAD_GLOBAL_r00 1234 +#define _LOAD_GLOBAL_BUILTINS_r01 1235 +#define _LOAD_GLOBAL_MODULE_r01 1236 +#define _LOAD_LOCALS_r01 1237 +#define _LOAD_LOCALS_r12 1238 +#define _LOAD_LOCALS_r23 1239 +#define _LOAD_NAME_r01 1240 +#define _LOAD_SMALL_INT_r01 1241 +#define _LOAD_SMALL_INT_r12 1242 +#define _LOAD_SMALL_INT_r23 1243 +#define _LOAD_SMALL_INT_0_r01 1244 +#define _LOAD_SMALL_INT_0_r12 1245 +#define _LOAD_SMALL_INT_0_r23 1246 +#define _LOAD_SMALL_INT_1_r01 1247 +#define _LOAD_SMALL_INT_1_r12 1248 +#define _LOAD_SMALL_INT_1_r23 1249 +#define _LOAD_SMALL_INT_2_r01 1250 +#define _LOAD_SMALL_INT_2_r12 1251 +#define _LOAD_SMALL_INT_2_r23 1252 +#define _LOAD_SMALL_INT_3_r01 1253 +#define _LOAD_SMALL_INT_3_r12 1254 +#define _LOAD_SMALL_INT_3_r23 1255 +#define _LOAD_SPECIAL_r00 1256 +#define _LOAD_SUPER_ATTR_ATTR_r31 1257 +#define _LOAD_SUPER_ATTR_METHOD_r32 1258 +#define _LOCK_OBJECT_r01 1259 +#define _LOCK_OBJECT_r11 1260 +#define _LOCK_OBJECT_r22 1261 +#define _LOCK_OBJECT_r33 1262 +#define _MAKE_CALLARGS_A_TUPLE_r33 1263 +#define _MAKE_CELL_r00 1264 +#define _MAKE_FUNCTION_r11 1265 +#define _MAKE_HEAP_SAFE_r01 1266 +#define _MAKE_HEAP_SAFE_r11 1267 +#define _MAKE_HEAP_SAFE_r22 1268 +#define _MAKE_HEAP_SAFE_r33 1269 +#define _MAKE_WARM_r00 1270 +#define _MAKE_WARM_r11 1271 +#define _MAKE_WARM_r22 1272 +#define _MAKE_WARM_r33 1273 +#define _MAP_ADD_r20 1274 +#define _MATCH_CLASS_r33 1275 +#define _MATCH_KEYS_r23 1276 +#define _MATCH_MAPPING_r02 1277 +#define _MATCH_MAPPING_r12 1278 +#define _MATCH_MAPPING_r23 1279 +#define _MATCH_SEQUENCE_r02 1280 +#define _MATCH_SEQUENCE_r12 1281 +#define _MATCH_SEQUENCE_r23 1282 +#define _MAYBE_EXPAND_METHOD_r00 1283 +#define _MAYBE_EXPAND_METHOD_KW_r11 1284 +#define _MONITOR_CALL_r00 1285 +#define _MONITOR_CALL_KW_r11 1286 +#define _MONITOR_JUMP_BACKWARD_r00 1287 +#define _MONITOR_JUMP_BACKWARD_r11 1288 +#define _MONITOR_JUMP_BACKWARD_r22 1289 +#define _MONITOR_JUMP_BACKWARD_r33 1290 +#define _MONITOR_RESUME_r00 1291 +#define _NOP_r00 1292 +#define _NOP_r11 1293 +#define _NOP_r22 1294 +#define _NOP_r33 1295 +#define _POP_CALL_r20 1296 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1297 +#define _POP_CALL_ONE_r30 1298 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1299 +#define _POP_CALL_TWO_r30 1300 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1301 +#define _POP_EXCEPT_r10 1302 +#define _POP_ITER_r20 1303 +#define _POP_JUMP_IF_FALSE_r00 1304 +#define _POP_JUMP_IF_FALSE_r10 1305 +#define _POP_JUMP_IF_FALSE_r21 1306 +#define _POP_JUMP_IF_FALSE_r32 1307 +#define _POP_JUMP_IF_TRUE_r00 1308 +#define _POP_JUMP_IF_TRUE_r10 1309 +#define _POP_JUMP_IF_TRUE_r21 1310 +#define _POP_JUMP_IF_TRUE_r32 1311 +#define _POP_TOP_r10 1312 +#define _POP_TOP_FLOAT_r00 1313 +#define _POP_TOP_FLOAT_r10 1314 +#define _POP_TOP_FLOAT_r21 1315 +#define _POP_TOP_FLOAT_r32 1316 +#define _POP_TOP_INT_r00 1317 +#define _POP_TOP_INT_r10 1318 +#define _POP_TOP_INT_r21 1319 +#define _POP_TOP_INT_r32 1320 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1321 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1322 +#define _POP_TOP_NOP_r00 1323 +#define _POP_TOP_NOP_r10 1324 +#define _POP_TOP_NOP_r21 1325 +#define _POP_TOP_NOP_r32 1326 +#define _POP_TOP_UNICODE_r00 1327 +#define _POP_TOP_UNICODE_r10 1328 +#define _POP_TOP_UNICODE_r21 1329 +#define _POP_TOP_UNICODE_r32 1330 +#define _POP_TWO_r20 1331 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1332 +#define _PUSH_EXC_INFO_r02 1333 +#define _PUSH_EXC_INFO_r12 1334 +#define _PUSH_EXC_INFO_r23 1335 +#define _PUSH_FRAME_r10 1336 +#define _PUSH_NULL_r01 1337 +#define _PUSH_NULL_r12 1338 +#define _PUSH_NULL_r23 1339 +#define _PUSH_NULL_CONDITIONAL_r00 1340 +#define _PY_FRAME_EX_r31 1341 +#define _PY_FRAME_GENERAL_r01 1342 +#define _PY_FRAME_KW_r11 1343 +#define _QUICKEN_RESUME_r00 1344 +#define _QUICKEN_RESUME_r11 1345 +#define _QUICKEN_RESUME_r22 1346 +#define _QUICKEN_RESUME_r33 1347 +#define _REPLACE_WITH_TRUE_r02 1348 +#define _REPLACE_WITH_TRUE_r12 1349 +#define _REPLACE_WITH_TRUE_r23 1350 +#define _RESUME_CHECK_r00 1351 +#define _RESUME_CHECK_r11 1352 +#define _RESUME_CHECK_r22 1353 +#define _RESUME_CHECK_r33 1354 +#define _RETURN_GENERATOR_r01 1355 +#define _RETURN_VALUE_r11 1356 +#define _SAVE_RETURN_OFFSET_r00 1357 +#define _SAVE_RETURN_OFFSET_r11 1358 +#define _SAVE_RETURN_OFFSET_r22 1359 +#define _SAVE_RETURN_OFFSET_r33 1360 +#define _SEND_r22 1361 +#define _SEND_GEN_FRAME_r22 1362 +#define _SETUP_ANNOTATIONS_r00 1363 +#define _SET_ADD_r10 1364 +#define _SET_FUNCTION_ATTRIBUTE_r01 1365 +#define _SET_FUNCTION_ATTRIBUTE_r11 1366 +#define _SET_FUNCTION_ATTRIBUTE_r21 1367 +#define _SET_FUNCTION_ATTRIBUTE_r32 1368 +#define _SET_IP_r00 1369 +#define _SET_IP_r11 1370 +#define _SET_IP_r22 1371 +#define _SET_IP_r33 1372 +#define _SET_UPDATE_r10 1373 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1374 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1375 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1376 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1377 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1378 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1379 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1380 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1381 +#define _SPILL_OR_RELOAD_r01 1382 +#define _SPILL_OR_RELOAD_r02 1383 +#define _SPILL_OR_RELOAD_r03 1384 +#define _SPILL_OR_RELOAD_r10 1385 +#define _SPILL_OR_RELOAD_r12 1386 +#define _SPILL_OR_RELOAD_r13 1387 +#define _SPILL_OR_RELOAD_r20 1388 +#define _SPILL_OR_RELOAD_r21 1389 +#define _SPILL_OR_RELOAD_r23 1390 +#define _SPILL_OR_RELOAD_r30 1391 +#define _SPILL_OR_RELOAD_r31 1392 +#define _SPILL_OR_RELOAD_r32 1393 +#define _START_EXECUTOR_r00 1394 +#define _STORE_ATTR_r20 1395 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1396 +#define _STORE_ATTR_SLOT_r21 1397 +#define _STORE_ATTR_WITH_HINT_r21 1398 +#define _STORE_DEREF_r10 1399 +#define _STORE_FAST_LOAD_FAST_r11 1400 +#define _STORE_FAST_STORE_FAST_r20 1401 +#define _STORE_GLOBAL_r10 1402 +#define _STORE_NAME_r10 1403 +#define _STORE_SLICE_r30 1404 +#define _STORE_SUBSCR_r30 1405 +#define _STORE_SUBSCR_DICT_r31 1406 +#define _STORE_SUBSCR_LIST_INT_r32 1407 +#define _SWAP_r11 1408 +#define _SWAP_2_r02 1409 +#define _SWAP_2_r12 1410 +#define _SWAP_2_r22 1411 +#define _SWAP_2_r33 1412 +#define _SWAP_3_r03 1413 +#define _SWAP_3_r13 1414 +#define _SWAP_3_r23 1415 +#define _SWAP_3_r33 1416 +#define _SWAP_FAST_r01 1417 +#define _SWAP_FAST_r11 1418 +#define _SWAP_FAST_r22 1419 +#define _SWAP_FAST_r33 1420 +#define _SWAP_FAST_0_r01 1421 +#define _SWAP_FAST_0_r11 1422 +#define _SWAP_FAST_0_r22 1423 +#define _SWAP_FAST_0_r33 1424 +#define _SWAP_FAST_1_r01 1425 +#define _SWAP_FAST_1_r11 1426 +#define _SWAP_FAST_1_r22 1427 +#define _SWAP_FAST_1_r33 1428 +#define _SWAP_FAST_2_r01 1429 +#define _SWAP_FAST_2_r11 1430 +#define _SWAP_FAST_2_r22 1431 +#define _SWAP_FAST_2_r33 1432 +#define _SWAP_FAST_3_r01 1433 +#define _SWAP_FAST_3_r11 1434 +#define _SWAP_FAST_3_r22 1435 +#define _SWAP_FAST_3_r33 1436 +#define _SWAP_FAST_4_r01 1437 +#define _SWAP_FAST_4_r11 1438 +#define _SWAP_FAST_4_r22 1439 +#define _SWAP_FAST_4_r33 1440 +#define _SWAP_FAST_5_r01 1441 +#define _SWAP_FAST_5_r11 1442 +#define _SWAP_FAST_5_r22 1443 +#define _SWAP_FAST_5_r33 1444 +#define _SWAP_FAST_6_r01 1445 +#define _SWAP_FAST_6_r11 1446 +#define _SWAP_FAST_6_r22 1447 +#define _SWAP_FAST_6_r33 1448 +#define _SWAP_FAST_7_r01 1449 +#define _SWAP_FAST_7_r11 1450 +#define _SWAP_FAST_7_r22 1451 +#define _SWAP_FAST_7_r33 1452 +#define _TIER2_RESUME_CHECK_r00 1453 +#define _TIER2_RESUME_CHECK_r11 1454 +#define _TIER2_RESUME_CHECK_r22 1455 +#define _TIER2_RESUME_CHECK_r33 1456 +#define _TO_BOOL_r11 1457 +#define _TO_BOOL_BOOL_r01 1458 +#define _TO_BOOL_BOOL_r11 1459 +#define _TO_BOOL_BOOL_r22 1460 +#define _TO_BOOL_BOOL_r33 1461 +#define _TO_BOOL_INT_r02 1462 +#define _TO_BOOL_INT_r12 1463 +#define _TO_BOOL_INT_r23 1464 +#define _TO_BOOL_LIST_r02 1465 +#define _TO_BOOL_LIST_r12 1466 +#define _TO_BOOL_LIST_r23 1467 +#define _TO_BOOL_NONE_r01 1468 +#define _TO_BOOL_NONE_r11 1469 +#define _TO_BOOL_NONE_r22 1470 +#define _TO_BOOL_NONE_r33 1471 +#define _TO_BOOL_STR_r02 1472 +#define _TO_BOOL_STR_r12 1473 +#define _TO_BOOL_STR_r23 1474 +#define _TRACE_RECORD_r00 1475 +#define _UNARY_INVERT_r12 1476 +#define _UNARY_NEGATIVE_r12 1477 +#define _UNARY_NOT_r01 1478 +#define _UNARY_NOT_r11 1479 +#define _UNARY_NOT_r22 1480 +#define _UNARY_NOT_r33 1481 +#define _UNPACK_EX_r10 1482 +#define _UNPACK_SEQUENCE_r10 1483 +#define _UNPACK_SEQUENCE_LIST_r10 1484 +#define _UNPACK_SEQUENCE_TUPLE_r10 1485 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1486 +#define _WITH_EXCEPT_START_r33 1487 +#define _YIELD_VALUE_r11 1488 +#define MAX_UOP_REGS_ID 1488 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index fbcb95baf2aa60..9a0852f872d763 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -225,7 +225,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_IMPORT_FROM] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_IS_NONE] = HAS_ESCAPES_FLAG, [_GET_LEN] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_MATCH_MAPPING] = 0, [_MATCH_SEQUENCE] = 0, [_MATCH_KEYS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -2121,7 +2121,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { 1, 3, _MATCH_CLASS_r31 }, + { 3, 3, _MATCH_CLASS_r33 }, }, }, [_MATCH_MAPPING] = { @@ -3955,7 +3955,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_IMPORT_FROM_r12] = _IMPORT_FROM, [_IS_NONE_r11] = _IS_NONE, [_GET_LEN_r12] = _GET_LEN, - [_MATCH_CLASS_r31] = _MATCH_CLASS, + [_MATCH_CLASS_r33] = _MATCH_CLASS, [_MATCH_MAPPING_r02] = _MATCH_MAPPING, [_MATCH_MAPPING_r12] = _MATCH_MAPPING, [_MATCH_MAPPING_r23] = _MATCH_MAPPING, @@ -5245,7 +5245,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_MAP_ADD] = "_MAP_ADD", [_MAP_ADD_r20] = "_MAP_ADD_r20", [_MATCH_CLASS] = "_MATCH_CLASS", - [_MATCH_CLASS_r31] = "_MATCH_CLASS_r31", + [_MATCH_CLASS_r33] = "_MATCH_CLASS_r33", [_MATCH_KEYS] = "_MATCH_KEYS", [_MATCH_KEYS_r23] = "_MATCH_KEYS_r23", [_MATCH_MAPPING] = "_MATCH_MAPPING", diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 4dd1140f7d85b7..e5fada1f40ce43 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3950,6 +3950,24 @@ def testfunc(n): self.assertIn("_POP_TOP_NOP", uops) self.assertLessEqual(count_ops(ex, "_POP_TOP"), 2) + def test_match_class(self): + def testfunc(n): + class A: + val = 1 + x = A() + ret = 0 + for _ in range(n): + match x: + case A(): + ret += x.val + return ret + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + uops = get_opnames(ex) + + self.assertIn("_MATCH_CLASS", uops) + self.assertEqual(count_ops(ex, "_POP_TOP_NOP"), 4) def test_143026(self): # https://github.com/python/cpython/issues/143026 diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-14-15-51-16.gh-issue-134584.6WFSuB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-14-15-51-16.gh-issue-134584.6WFSuB.rst new file mode 100644 index 00000000000000..5b7293b567109a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-14-15-51-16.gh-issue-134584.6WFSuB.rst @@ -0,0 +1 @@ +Eliminate redundant refcounting for ``MATCH_CLASS`` in the JIT. diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index b025f7b0eb7fe5..9e86bc42f20074 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -9984,43 +9984,64 @@ _PyStackRef type; _PyStackRef names; _PyStackRef attrs; - names = stack_pointer[-1]; - type = stack_pointer[-2]; - subject = stack_pointer[-3]; - assert(PyTuple_CheckExact(PyStackRef_AsPyObjectBorrow(names))); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *attrs_o = _PyEval_MatchClass(tstate, - PyStackRef_AsPyObjectBorrow(subject), - PyStackRef_AsPyObjectBorrow(type), oparg, - PyStackRef_AsPyObjectBorrow(names)); - _PyStackRef tmp = names; - names = PyStackRef_NULL; - stack_pointer[-1] = names; - PyStackRef_CLOSE(tmp); - tmp = type; - type = PyStackRef_NULL; - stack_pointer[-2] = type; - PyStackRef_CLOSE(tmp); - tmp = subject; - subject = PyStackRef_NULL; - stack_pointer[-3] = subject; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - if (attrs_o) { - assert(PyTuple_CheckExact(attrs_o)); - attrs = PyStackRef_FromPyObjectSteal(attrs_o); - } - else { - if (_PyErr_Occurred(tstate)) { - JUMP_TO_LABEL(error); + _PyStackRef s; + _PyStackRef tp; + _PyStackRef n; + _PyStackRef value; + // _MATCH_CLASS + { + names = stack_pointer[-1]; + type = stack_pointer[-2]; + subject = stack_pointer[-3]; + assert(PyTuple_CheckExact(PyStackRef_AsPyObjectBorrow(names))); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *attrs_o = _PyEval_MatchClass(tstate, + PyStackRef_AsPyObjectBorrow(subject), + PyStackRef_AsPyObjectBorrow(type), oparg, + PyStackRef_AsPyObjectBorrow(names)); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (attrs_o) { + assert(PyTuple_CheckExact(attrs_o)); + attrs = PyStackRef_FromPyObjectSteal(attrs_o); } - attrs = PyStackRef_None; + else { + if (_PyErr_Occurred(tstate)) { + JUMP_TO_LABEL(error); + } + attrs = PyStackRef_None; + } + s = subject; + tp = type; + n = names; + } + // _POP_TOP + { + value = n; + stack_pointer[-3] = attrs; + stack_pointer[-2] = s; + stack_pointer[-1] = tp; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _POP_TOP + { + value = tp; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _POP_TOP + { + value = s; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer[0] = attrs; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); DISPATCH(); } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 0eff5f76740f78..43a512611fb1ee 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3254,7 +3254,7 @@ dummy_func( len = PyStackRef_FromPyObjectSteal(len_o); } - inst(MATCH_CLASS, (subject, type, names -- attrs)) { + op(_MATCH_CLASS, (subject, type, names -- attrs, s, tp, n)) { // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(PyStackRef_AsPyObjectBorrow(names))); @@ -3262,17 +3262,24 @@ dummy_func( PyStackRef_AsPyObjectBorrow(subject), PyStackRef_AsPyObjectBorrow(type), oparg, PyStackRef_AsPyObjectBorrow(names)); - DECREF_INPUTS(); if (attrs_o) { assert(PyTuple_CheckExact(attrs_o)); // Success! attrs = PyStackRef_FromPyObjectSteal(attrs_o); } else { - ERROR_IF(_PyErr_Occurred(tstate)); // Error! + if (_PyErr_Occurred(tstate)) { // Error! + ERROR_NO_POP(); + } attrs = PyStackRef_None; // Failure! } + s = subject; + tp = type; + n = names; + INPUTS_DEAD(); } + macro(MATCH_CLASS) = _MATCH_CLASS + POP_TOP + POP_TOP + POP_TOP; + inst(MATCH_MAPPING, (subject -- subject, res)) { int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = match ? PyStackRef_True : PyStackRef_False; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 032d6faeda6a96..7a698e422abd77 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -11292,13 +11292,16 @@ break; } - case _MATCH_CLASS_r31: { + case _MATCH_CLASS_r33: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef names; _PyStackRef type; _PyStackRef subject; _PyStackRef attrs; + _PyStackRef s; + _PyStackRef tp; + _PyStackRef n; _PyStackRef _stack_item_0 = _tos_cache0; _PyStackRef _stack_item_1 = _tos_cache1; _PyStackRef _stack_item_2 = _tos_cache2; @@ -11317,21 +11320,7 @@ PyStackRef_AsPyObjectBorrow(subject), PyStackRef_AsPyObjectBorrow(type), oparg, PyStackRef_AsPyObjectBorrow(names)); - _PyStackRef tmp = names; - names = PyStackRef_NULL; - stack_pointer[-1] = names; - PyStackRef_CLOSE(tmp); - tmp = type; - type = PyStackRef_NULL; - stack_pointer[-2] = type; - PyStackRef_CLOSE(tmp); - tmp = subject; - subject = PyStackRef_NULL; - stack_pointer[-3] = subject; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); if (attrs_o) { assert(PyTuple_CheckExact(attrs_o)); attrs = PyStackRef_FromPyObjectSteal(attrs_o); @@ -11343,10 +11332,16 @@ } attrs = PyStackRef_None; } - _tos_cache0 = attrs; - _tos_cache1 = PyStackRef_ZERO_BITS; - _tos_cache2 = PyStackRef_ZERO_BITS; - SET_CURRENT_CACHED_VALUES(1); + s = subject; + tp = type; + n = names; + _tos_cache2 = n; + _tos_cache1 = tp; + _tos_cache0 = s; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer[-3] = attrs; + stack_pointer += -2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index de036fb964b691..72619fd3afa91a 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -9982,43 +9982,64 @@ _PyStackRef type; _PyStackRef names; _PyStackRef attrs; - names = stack_pointer[-1]; - type = stack_pointer[-2]; - subject = stack_pointer[-3]; - assert(PyTuple_CheckExact(PyStackRef_AsPyObjectBorrow(names))); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *attrs_o = _PyEval_MatchClass(tstate, - PyStackRef_AsPyObjectBorrow(subject), - PyStackRef_AsPyObjectBorrow(type), oparg, - PyStackRef_AsPyObjectBorrow(names)); - _PyStackRef tmp = names; - names = PyStackRef_NULL; - stack_pointer[-1] = names; - PyStackRef_CLOSE(tmp); - tmp = type; - type = PyStackRef_NULL; - stack_pointer[-2] = type; - PyStackRef_CLOSE(tmp); - tmp = subject; - subject = PyStackRef_NULL; - stack_pointer[-3] = subject; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - if (attrs_o) { - assert(PyTuple_CheckExact(attrs_o)); - attrs = PyStackRef_FromPyObjectSteal(attrs_o); - } - else { - if (_PyErr_Occurred(tstate)) { - JUMP_TO_LABEL(error); + _PyStackRef s; + _PyStackRef tp; + _PyStackRef n; + _PyStackRef value; + // _MATCH_CLASS + { + names = stack_pointer[-1]; + type = stack_pointer[-2]; + subject = stack_pointer[-3]; + assert(PyTuple_CheckExact(PyStackRef_AsPyObjectBorrow(names))); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *attrs_o = _PyEval_MatchClass(tstate, + PyStackRef_AsPyObjectBorrow(subject), + PyStackRef_AsPyObjectBorrow(type), oparg, + PyStackRef_AsPyObjectBorrow(names)); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (attrs_o) { + assert(PyTuple_CheckExact(attrs_o)); + attrs = PyStackRef_FromPyObjectSteal(attrs_o); } - attrs = PyStackRef_None; + else { + if (_PyErr_Occurred(tstate)) { + JUMP_TO_LABEL(error); + } + attrs = PyStackRef_None; + } + s = subject; + tp = type; + n = names; + } + // _POP_TOP + { + value = n; + stack_pointer[-3] = attrs; + stack_pointer[-2] = s; + stack_pointer[-1] = tp; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _POP_TOP + { + value = tp; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); + } + // _POP_TOP + { + value = s; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer[0] = attrs; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); DISPATCH(); } diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 2b68ba4d2cde92..6092da8c04e708 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1710,6 +1710,13 @@ dummy_func(void) { ss = sub_st; } + op(_MATCH_CLASS, (subject, type, names -- attrs, s, tp, n)) { + attrs = sym_new_not_null(ctx); + s = subject; + tp = type; + n = names; + } + op(_RECORD_TOS, (tos -- tos)) { sym_set_recorded_value(tos, (PyObject *)this_instr->operand0); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index fe083411b7b739..2df50ebbcaa1c0 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2649,11 +2649,26 @@ } case _MATCH_CLASS: { + JitOptRef names; + JitOptRef type; + JitOptRef subject; JitOptRef attrs; + JitOptRef s; + JitOptRef tp; + JitOptRef n; + names = stack_pointer[-1]; + type = stack_pointer[-2]; + subject = stack_pointer[-3]; attrs = sym_new_not_null(ctx); - CHECK_STACK_BOUNDS(-2); + s = subject; + tp = type; + n = names; + CHECK_STACK_BOUNDS(1); stack_pointer[-3] = attrs; - stack_pointer += -2; + stack_pointer[-2] = s; + stack_pointer[-1] = tp; + stack_pointer[0] = n; + stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); break; } From 9a83c02a0f5d85f6940c5ce3ad630e2e8d6c5661 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:00:15 +0000 Subject: [PATCH 455/498] gh-137650: Group dependabot actions updates (#145947) --- .github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7f3376f8ddb1e2..e68a07382d5884 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,6 +12,10 @@ updates: update-types: - "version-update:semver-minor" - "version-update:semver-patch" + groups: + actions: + patterns: + - "*" cooldown: # https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns # Cooldowns protect against supply chain attacks by avoiding the From 0575ce936d3f16ce2547ba17d2a22d90369779b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:30:26 +0000 Subject: [PATCH 456/498] build(deps): bump the actions group with 4 updates (#145952) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/reusable-check-c-api-docs.yml | 4 ++-- .github/workflows/reusable-cifuzz.yml | 2 +- .github/workflows/reusable-san.yml | 2 +- .github/workflows/stale.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c017ee04d67f07..2fa2ab768dc48b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -475,7 +475,7 @@ jobs: -x test_subprocess \ -x test_signal \ -x test_sysconfig - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 if: always() with: name: hypothesis-example-db diff --git a/.github/workflows/reusable-check-c-api-docs.yml b/.github/workflows/reusable-check-c-api-docs.yml index bab1ca67d538ad..b95bd6a0184ea7 100644 --- a/.github/workflows/reusable-check-c-api-docs.yml +++ b/.github/workflows/reusable-check-c-api-docs.yml @@ -15,10 +15,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.x' - name: Check for undocumented C APIs diff --git a/.github/workflows/reusable-cifuzz.yml b/.github/workflows/reusable-cifuzz.yml index 1986f5fb2cc640..6cd9c26037f527 100644 --- a/.github/workflows/reusable-cifuzz.yml +++ b/.github/workflows/reusable-cifuzz.yml @@ -34,7 +34,7 @@ jobs: sanitizer: ${{ inputs.sanitizer }} - name: Upload crash if: failure() && steps.build.outcome == 'success' - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ inputs.sanitizer }}-artifacts path: ./out/artifacts diff --git a/.github/workflows/reusable-san.yml b/.github/workflows/reusable-san.yml index b70f9b4b0d6259..79a4ded09fc9ca 100644 --- a/.github/workflows/reusable-san.yml +++ b/.github/workflows/reusable-san.yml @@ -96,7 +96,7 @@ jobs: run: find "${GITHUB_WORKSPACE}" -name 'san_log.*' | xargs head -n 1000 - name: Archive logs if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: >- ${{ inputs.sanitizer }}-logs-${{ diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index febb2dd823a8fe..915b1acd33f814 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,7 +14,7 @@ jobs: steps: - name: "Check PRs" - uses: actions/stale@v9 + uses: actions/stale@v10 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.' From 31c41a61f1afb7929d2698e48894264d8e2df86b Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 14 Mar 2026 18:11:29 +0000 Subject: [PATCH 457/498] Fix `fuzz_builtin_int` fuzzer reproducibility (#145890) --- Modules/_xxtestfuzz/fuzzer.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 6cb11562476e40..02afb01d3731fb 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -38,23 +38,18 @@ static int fuzz_builtin_float(const char* data, size_t size) { static int fuzz_builtin_int(const char* data, size_t size) { /* Ignore test cases with very long ints to avoid timeouts int("9" * 1000000) is not a very interesting test caase */ - if (size > MAX_INT_TEST_SIZE) { + if (size < 1 || size > MAX_INT_TEST_SIZE) { return 0; } - /* Pick a random valid base. (When the fuzzed function takes extra - parameters, it's somewhat normal to hash the input to generate those - parameters. We want to exercise all code paths, so we do so here.) */ - int base = Py_HashBuffer(data, size) % 37; + // Use the first byte to pick a base + int base = ((unsigned char) data[0]) % 37; if (base == 1) { // 1 is the only number between 0 and 36 that is not a valid base. base = 0; } - if (base == -1) { - return 0; // An error occurred, bail early. - } - if (base < 0) { - base = -base; - } + + data += 1; + size -= 1; PyObject* s = PyUnicode_FromStringAndSize(data, size); if (s == NULL) { From 788c3291172b55efa7cf8b33a315e4b0fe63540c Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 14 Mar 2026 11:28:49 -0700 Subject: [PATCH 458/498] gh-123720: When closing an asyncio server, stop the handlers (#124689) --- Lib/asyncio/base_events.py | 1 + Lib/test/test_asyncio/test_server.py | 32 +++++++++++++++++++ ...-03-11-10-25-32.gh-issue-123720.TauFRx.rst | 5 +++ 3 files changed, 38 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-03-11-10-25-32.gh-issue-123720.TauFRx.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 0930ef403c6c4b..77c70aaa7b986e 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -381,6 +381,7 @@ async def serve_forever(self): except exceptions.CancelledError: try: self.close() + self.close_clients() await self.wait_closed() finally: raise diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index 5bd0f7e2af4f84..581ea47d2dec97 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -266,6 +266,38 @@ async def serve(rd, wr): await asyncio.sleep(0) self.assertTrue(task.done()) + async def test_close_with_hanging_client(self): + # Synchronize server cancellation only after the socket connection is + # accepted and this event is set + conn_event = asyncio.Event() + class Proto(asyncio.Protocol): + def connection_made(self, transport): + conn_event.set() + + loop = asyncio.get_running_loop() + srv = await loop.create_server(Proto, socket_helper.HOSTv4, 0) + + # Start the server + serve_forever_task = asyncio.create_task(srv.serve_forever()) + await asyncio.sleep(0) + + # Create a connection to server + addr = srv.sockets[0].getsockname() + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect(addr) + self.addCleanup(sock.close) + + # Send a CancelledError into the server to emulate a Ctrl+C + # KeyboardInterrupt whilst the server is handling a hanging client + await conn_event.wait() + serve_forever_task.cancel() + + # Ensure the client is closed within a timeout + async with asyncio.timeout(0.5): + await srv.wait_closed() + + self.assertFalse(srv.is_serving()) + # Test the various corner cases of Unix server socket removal class UnixServerCleanupTests(unittest.IsolatedAsyncioTestCase): diff --git a/Misc/NEWS.d/next/Library/2026-03-11-10-25-32.gh-issue-123720.TauFRx.rst b/Misc/NEWS.d/next/Library/2026-03-11-10-25-32.gh-issue-123720.TauFRx.rst new file mode 100644 index 00000000000000..04e6a377dd816c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-11-10-25-32.gh-issue-123720.TauFRx.rst @@ -0,0 +1,5 @@ +asyncio: Fix :func:`asyncio.Server.serve_forever` shutdown regression. Since +3.12, cancelling ``serve_forever()`` could hang waiting for a handler blocked +on a read from a client that never closed (effectively requiring two +interrupts to stop); the shutdown sequence now ensures client streams are +closed so ``serve_forever()`` exits promptly and handlers observe EOF. From 1dfe99ae3bed6cac01732b47bf7fa637abadf51b Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 14 Mar 2026 22:58:35 -0400 Subject: [PATCH 459/498] gh-141004: Document `PyDTrace*` (GH-141856) --- Doc/howto/instrumentation.rst | 78 +++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index b3db1189e5dcbc..06c1ae40da5e67 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -341,6 +341,84 @@ Available static markers .. versionadded:: 3.8 +C Entry Points +^^^^^^^^^^^^^^ + +To simplify triggering of DTrace markers, Python's C API comes with a number +of helper functions that mirror each static marker. On builds of Python without +DTrace enabled, these do nothing. + +In general, it is not necessary to call these yourself, as Python will do +it for you. + +.. list-table:: + :widths: 50 25 25 + :header-rows: 1 + + * * C API Function + * Static Marker + * Notes + * * .. c:function:: void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) + * :c:func:`!line` + * + * * .. c:function:: void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) + * :c:func:`!function__entry` + * + * * .. c:function:: void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) + * :c:func:`!function__return` + * + * * .. c:function:: void PyDTrace_GC_START(int arg0) + * :c:func:`!gc__start` + * + * * .. c:function:: void PyDTrace_GC_DONE(Py_ssize_t arg0) + * :c:func:`!gc__done` + * + * * .. c:function:: void PyDTrace_INSTANCE_NEW_START(int arg0) + * :c:func:`!instance__new__start` + * Not used by Python + * * .. c:function:: void PyDTrace_INSTANCE_NEW_DONE(int arg0) + * :c:func:`!instance__new__done` + * Not used by Python + * * .. c:function:: void PyDTrace_INSTANCE_DELETE_START(int arg0) + * :c:func:`!instance__delete__start` + * Not used by Python + * * .. c:function:: void PyDTrace_INSTANCE_DELETE_DONE(int arg0) + * :c:func:`!instance__delete__done` + * Not used by Python + * * .. c:function:: void PyDTrace_IMPORT_FIND_LOAD_START(const char *arg0) + * :c:func:`!import__find__load__start` + * + * * .. c:function:: void PyDTrace_IMPORT_FIND_LOAD_DONE(const char *arg0, int arg1) + * :c:func:`!import__find__load__done` + * + * * .. c:function:: void PyDTrace_AUDIT(const char *arg0, void *arg1) + * :c:func:`!audit` + * + + +C Probing Checks +^^^^^^^^^^^^^^^^ + +.. c:function:: int PyDTrace_LINE_ENABLED(void) +.. c:function:: int PyDTrace_FUNCTION_ENTRY_ENABLED(void) +.. c:function:: int PyDTrace_FUNCTION_RETURN_ENABLED(void) +.. c:function:: int PyDTrace_GC_START_ENABLED(void) +.. c:function:: int PyDTrace_GC_DONE_ENABLED(void) +.. c:function:: int PyDTrace_INSTANCE_NEW_START_ENABLED(void) +.. c:function:: int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) +.. c:function:: int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) +.. c:function:: int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) +.. c:function:: int PyDTrace_IMPORT_FIND_LOAD_START_ENABLED(void) +.. c:function:: int PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED(void) +.. c:function:: int PyDTrace_AUDIT_ENABLED(void) + + All calls to ``PyDTrace`` functions must be guarded by a call to one + of these functions. This allows Python to minimize performance impact + when probing is disabled. + + On builds without DTrace enabled, these functions do nothing and return + ``0``. + SystemTap Tapsets ----------------- From e167e06f8c6b24f7b54e8d6b87c1cac1667dd2cf Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Sun, 15 Mar 2026 05:48:56 -0400 Subject: [PATCH 460/498] Bump mypy to 1.19.1 (#145956) --- Lib/test/libregrtest/utils.py | 2 +- Tools/clinic/libclinic/clanguage.py | 2 +- Tools/requirements-dev.txt | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 3bbc3fa127abb3..7cc9d0bf262af1 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -150,7 +150,7 @@ def setup_unraisable_hook() -> None: sys.unraisablehook = regrtest_unraisable_hook -orig_threading_excepthook: Callable[..., None] | None = None +orig_threading_excepthook: Callable[..., object] | None = None def regrtest_threading_excepthook(args) -> None: diff --git a/Tools/clinic/libclinic/clanguage.py b/Tools/clinic/libclinic/clanguage.py index 9e7fa7a7f58f95..341667d2f0bff9 100644 --- a/Tools/clinic/libclinic/clanguage.py +++ b/Tools/clinic/libclinic/clanguage.py @@ -6,7 +6,7 @@ from operator import attrgetter from collections.abc import Iterable -import libclinic +import libclinic.cpp from libclinic import ( unspecified, fail, Sentinels, VersionTuple) from libclinic.codegen import CRenderData, TemplateDict, CodeGen diff --git a/Tools/requirements-dev.txt b/Tools/requirements-dev.txt index 73236767374378..af5cbaa7689f33 100644 --- a/Tools/requirements-dev.txt +++ b/Tools/requirements-dev.txt @@ -1,7 +1,7 @@ # Requirements file for external linters and checks we run on # Tools/clinic, Tools/cases_generator/, and Tools/peg_generator/ in CI -mypy==1.17.1 +mypy==1.19.1 # needed for peg_generator: -types-psutil==7.0.0.20250801 -types-setuptools==80.9.0.20250801 +types-psutil==7.2.2.20260130 +types-setuptools==82.0.0.20260210 From 2f4e4ec2e7292901cab0c1466b78f5ddff48208d Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Sun, 15 Mar 2026 15:57:05 +0100 Subject: [PATCH 461/498] gh-142518: Document thread-safety guarantees of bytearray objects (#145226) --- Doc/library/stdtypes.rst | 5 ++ Doc/library/threadsafety.rst | 101 +++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 6e2c72daf7ac44..24f53a3a272d73 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3514,6 +3514,11 @@ The representation of bytearray objects uses the bytes literal format ``bytearray([46, 46, 46])``. You can always convert a bytearray object into a list of integers using ``list(b)``. +.. seealso:: + + For detailed information on thread-safety guarantees for :class:`bytearray` + objects, see :ref:`thread-safety-bytearray`. + .. _bytes-methods: diff --git a/Doc/library/threadsafety.rst b/Doc/library/threadsafety.rst index 4f2eda19b85e07..8063c2ea5011e7 100644 --- a/Doc/library/threadsafety.rst +++ b/Doc/library/threadsafety.rst @@ -447,3 +447,104 @@ atomic: Consider external synchronization when sharing :class:`set` instances across threads. See :ref:`freethreading-python-howto` for more information. + + +.. _thread-safety-bytearray: + +Thread safety for bytearray objects +=================================== + + The :func:`len` function is lock-free and :term:`atomic `. + + Concatenation and comparisons use the buffer protocol, which prevents + resizing but does not hold the per-object lock. These operations may + observe intermediate states from concurrent modifications: + + .. code-block:: + :class: maybe + + ba + other # may observe concurrent writes + ba == other # may observe concurrent writes + ba < other # may observe concurrent writes + + All other operations from here on hold the per-object lock. + + Reading a single element or slice is safe to call from multiple threads: + + .. code-block:: + :class: good + + ba[i] # bytearray.__getitem__ + ba[i:j] # slice + + The following operations are safe to call from multiple threads and will + not corrupt the bytearray: + + .. code-block:: + :class: good + + ba[i] = x # write single byte + ba[i:j] = values # write slice + ba.append(x) # append single byte + ba.extend(other) # extend with iterable + ba.insert(i, x) # insert single byte + ba.pop() # remove and return last byte + ba.pop(i) # remove and return byte at index + ba.remove(x) # remove first occurrence + ba.reverse() # reverse in place + ba.clear() # remove all bytes + + Slice assignment locks both objects when *values* is a :class:`bytearray`: + + .. code-block:: + :class: good + + ba[i:j] = other_bytearray # both locked + + The following operations return new objects and hold the per-object lock + for the duration: + + .. code-block:: + :class: good + + ba.copy() # returns a shallow copy + ba * n # repeat into new bytearray + + The membership test holds the lock for its duration: + + .. code-block:: + :class: good + + x in ba # bytearray.__contains__ + + All other bytearray methods (such as :meth:`~bytearray.find`, + :meth:`~bytearray.replace`, :meth:`~bytearray.split`, + :meth:`~bytearray.decode`, etc.) hold the per-object lock for their + duration. + + Operations that involve multiple accesses, as well as iteration, are never + atomic: + + .. code-block:: + :class: bad + + # NOT atomic: check-then-act + if x in ba: + ba.remove(x) + + # NOT thread-safe: iteration while modifying + for byte in ba: + process(byte) # another thread may modify ba + + To safely iterate over a bytearray that may be modified by another + thread, iterate over a copy: + + .. code-block:: + :class: good + + # Make a copy to iterate safely + for byte in ba.copy(): + process(byte) + + Consider external synchronization when sharing :class:`bytearray` instances + across threads. See :ref:`freethreading-python-howto` for more information. From 757e2ff9d997fb8314e7270d3a71f38c18cc9235 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:14:27 +0000 Subject: [PATCH 462/498] gh-145976: Remove `Misc/{Porting,vgrindefs}` (#145973) Cleanup outdated files under Misc/ --- .../2026-03-15-11-32-35.gh-issue-145976.mqhzmB.rst | 1 + Misc/Porting | 1 - Misc/README | 2 -- Misc/vgrindefs | 10 ---------- 4 files changed, 1 insertion(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2026-03-15-11-32-35.gh-issue-145976.mqhzmB.rst delete mode 100644 Misc/Porting delete mode 100644 Misc/vgrindefs diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-03-15-11-32-35.gh-issue-145976.mqhzmB.rst b/Misc/NEWS.d/next/Tools-Demos/2026-03-15-11-32-35.gh-issue-145976.mqhzmB.rst new file mode 100644 index 00000000000000..0d74776ff900c1 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2026-03-15-11-32-35.gh-issue-145976.mqhzmB.rst @@ -0,0 +1 @@ +Remove :file:`Misc/vgrindefs` and :file:`Misc/Porting`. diff --git a/Misc/Porting b/Misc/Porting deleted file mode 100644 index f16c460052151c..00000000000000 --- a/Misc/Porting +++ /dev/null @@ -1 +0,0 @@ -This document is moved to https://devguide.python.org/porting/ diff --git a/Misc/README b/Misc/README index cbad9b72dc713c..038f842e0bc02e 100644 --- a/Misc/README +++ b/Misc/README @@ -11,7 +11,6 @@ ACKS Acknowledgements HISTORY News from previous releases -- oldest last indent.pro GNU indent profile approximating my C style NEWS News for this release (for some meaning of "this") -Porting Mini-FAQ on porting to new platforms python-config.in Python script template for python-config python.man UNIX man page for the python interpreter python.pc.in Package configuration info template for pkg-config @@ -22,4 +21,3 @@ SpecialBuilds.txt Describes extra symbols you can set for debug builds svnmap.txt Map of old SVN revs and branches to hg changeset ids, help history-digging valgrind-python.supp Valgrind suppression file, see README.valgrind -vgrindefs Python configuration for vgrind (a generic pretty printer) diff --git a/Misc/vgrindefs b/Misc/vgrindefs deleted file mode 100644 index 3e6d8a4629a455..00000000000000 --- a/Misc/vgrindefs +++ /dev/null @@ -1,10 +0,0 @@ -# vgrind is a pretty-printer that takes source code and outputs -# eye-pleasing postscript. The entry below should be added to your -# local vgrindefs file. Contributed by Neale Pickett . - -python|Python|py:\ - :pb=^\d?(def|class)\d\p(\d|\\|\(|\:):\ - :cb=#:ce=$:sb=":se=\e":lb=':le=\e':\ - :kw=assert and break class continue def del elif else except\ - finally for from global if import in is lambda not or\ - pass print raise return try while yield: From ec5e3a5a073507089b0b5908a5a298f8845bb2e4 Mon Sep 17 00:00:00 2001 From: Matthieu Darbois Date: Sun, 15 Mar 2026 18:46:44 +0100 Subject: [PATCH 463/498] gh-145968: Fix base64.b64decode altchars translation in specific cases (GH-145969) When altchars overlaps with the standard ones, the translation does not always yield to the expected outcome. --- Lib/base64.py | 8 +++++++- Lib/test/test_base64.py | 7 +++++++ .../2026-03-15-10-17-51.gh-issue-145968.gZexry.rst | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-15-10-17-51.gh-issue-145968.gZexry.rst diff --git a/Lib/base64.py b/Lib/base64.py index 36688ce43917ce..dcfcbcc95a39be 100644 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -100,7 +100,13 @@ def b64decode(s, altchars=None, validate=_NOT_SPECIFIED, *, ignorechars=_NOT_SPE break s = s.translate(bytes.maketrans(altchars, b'+/')) else: - trans = bytes.maketrans(b'+/' + altchars, altchars + b'+/') + trans_in = set(b'+/') - set(altchars) + if len(trans_in) == 2: + # we can't use the reqult of unordered sets here + trans = bytes.maketrans(altchars + b'+/', b'+/' + altchars) + else: + trans = bytes.maketrans(altchars + bytes(trans_in), + b'+/' + bytes(set(altchars) - set(b'+/'))) s = s.translate(trans) ignorechars = ignorechars.translate(trans) if ignorechars is _NOT_SPECIFIED: diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 69aa628db7c34c..9648624b267a54 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -293,6 +293,13 @@ def test_b64decode_altchars(self): eq(base64.b64decode(data_str, altchars=altchars_str), res) eq(base64.b64decode(data, altchars=altchars, ignorechars=b'\n'), res) + eq(base64.b64decode(b'/----', altchars=b'-+', ignorechars=b'/'), b'\xfb\xef\xbe') + eq(base64.b64decode(b'/----', altchars=b'+-', ignorechars=b'/'), b'\xff\xff\xff') + eq(base64.b64decode(b'+----', altchars=b'-/', ignorechars=b'+'), b'\xfb\xef\xbe') + eq(base64.b64decode(b'+----', altchars=b'/-', ignorechars=b'+'), b'\xff\xff\xff') + eq(base64.b64decode(b'+/+/', altchars=b'/+', ignorechars=b''), b'\xff\xef\xfe') + eq(base64.b64decode(b'/+/+', altchars=b'+/', ignorechars=b''), b'\xff\xef\xfe') + self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+') self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+/-') self.assertRaises(ValueError, base64.b64decode, '', altchars='+') diff --git a/Misc/NEWS.d/next/Library/2026-03-15-10-17-51.gh-issue-145968.gZexry.rst b/Misc/NEWS.d/next/Library/2026-03-15-10-17-51.gh-issue-145968.gZexry.rst new file mode 100644 index 00000000000000..9eae1dc400838a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-15-10-17-51.gh-issue-145968.gZexry.rst @@ -0,0 +1,2 @@ +Fix translation in :func:`base64.b64decode` when altchars overlaps with the +standard ones. From 4a71946b8fbc364b894a944dc4fd017ed14692cb Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:30:01 -0700 Subject: [PATCH 464/498] gh-122575: gh-142349: fix sys.flags tuple size (it unintentionally increased) (GH-145988) the lazy imports PEP initial implementation (3.15 alpha) inadvertently incremented the length of the sys.flags tuple. In a way that did not do anything useful or related to the lazy imports setting (it exposed sys.flags.gil in the tuple). This fixes that to hard code the length to the 3.13 & 3.14 released length of 18 and have our tests and code comments make it clear that we've since stopped making new sys.flags attributes available via sequence index. --- Lib/test/test_sys.py | 37 +++++++++++++++++++++++++++---------- Python/sysmodule.c | 9 ++++++--- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 8974361c2537d2..a729efee18c3a1 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -858,24 +858,35 @@ def test_subinterp_intern_singleton(self): ''')) self.assertTrue(sys._is_interned(s)) - def test_sys_flags(self): + def test_sys_flags_indexable_attributes(self): self.assertTrue(sys.flags) - attrs = ("debug", + # We've stopped assigning sequence indices to new sys.flags attributes: + # https://github.com/python/cpython/issues/122575#issuecomment-2416497086 + indexable_attrs = ("debug", "inspect", "interactive", "optimize", "dont_write_bytecode", "no_user_site", "no_site", "ignore_environment", "verbose", "bytes_warning", "quiet", "hash_randomization", "isolated", "dev_mode", "utf8_mode", - "warn_default_encoding", "safe_path", "int_max_str_digits", - "lazy_imports") - for attr in attrs: + "warn_default_encoding", "safe_path", "int_max_str_digits") + for attr_idx, attr in enumerate(indexable_attrs): self.assertHasAttr(sys.flags, attr) attr_type = bool if attr in ("dev_mode", "safe_path") else int self.assertEqual(type(getattr(sys.flags, attr)), attr_type, attr) + attr_value = getattr(sys.flags, attr) + self.assertEqual(sys.flags[attr_idx], attr_value, + msg=f"sys.flags .{attr} vs [{attr_idx}]") self.assertTrue(repr(sys.flags)) - self.assertEqual(len(sys.flags), len(attrs)) + self.assertEqual(len(sys.flags), 18, msg="Do not increase, see GH-122575") self.assertIn(sys.flags.utf8_mode, {0, 1, 2}) + def test_sys_flags_name_only_attributes(self): + # non-tuple sequence fields (name only sys.flags attributes) + self.assertIsInstance(sys.flags.gil, int|type(None)) + self.assertIsInstance(sys.flags.thread_inherit_context, int|type(None)) + self.assertIsInstance(sys.flags.context_aware_warnings, int|type(None)) + self.assertIsInstance(sys.flags.lazy_imports, int|type(None)) + def assert_raise_on_new_sys_type(self, sys_attr): # Users are intentionally prevented from creating new instances of # sys.flags, sys.version_info, and sys.getwindowsversion. @@ -1908,10 +1919,16 @@ def test_pythontypes(self): # symtable entry # XXX # sys.flags - # FIXME: The +3 is for the 'gil', 'thread_inherit_context' and - # 'context_aware_warnings' flags and will not be necessary once - # gh-122575 is fixed - check(sys.flags, vsize('') + self.P + self.P * (3 + len(sys.flags))) + # FIXME: The non_sequence_fields adjustment is for these flags: + # - 'gil' + # - 'thread_inherit_context' + # - 'context_aware_warnings' + # - 'lazy_imports' + # Not needing to increment this every time we add a new field + # per GH-122575 would be nice... + # Q: What is the actual point of this sys.flags C size derived from PyStructSequence_Field array assertion? + non_sequence_fields = 4 + check(sys.flags, vsize('') + self.P + self.P * (non_sequence_fields + len(sys.flags))) def test_asyncgen_hooks(self): old = sys.get_asyncgen_hooks() diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 893a116565e37e..646b8a1c3c3a84 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -3495,11 +3495,12 @@ static PyStructSequence_Field flags_fields[] = { {"dev_mode", "-X dev"}, {"utf8_mode", "-X utf8"}, {"warn_default_encoding", "-X warn_default_encoding"}, - {"safe_path", "-P"}, + {"safe_path", "-P"}, {"int_max_str_digits", "-X int_max_str_digits"}, + // Fields below are only usable by sys.flags attribute name, not index: {"gil", "-X gil"}, {"thread_inherit_context", "-X thread_inherit_context"}, - {"context_aware_warnings", "-X context_aware_warnings"}, + {"context_aware_warnings", "-X context_aware_warnings"}, {"lazy_imports", "-X lazy_imports"}, {0} }; @@ -3510,7 +3511,9 @@ static PyStructSequence_Desc flags_desc = { "sys.flags", /* name */ flags__doc__, /* doc */ flags_fields, /* fields */ - 19 + 18 /* NB - do not increase beyond 3.13's value of 18. */ + // New sys.flags fields should NOT be tuple addressable per + // https://github.com/python/cpython/issues/122575#issuecomment-2416497086 }; static void From 33044b015ba1589887629e217d68bba35b1fced5 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 15 Mar 2026 21:29:12 +0000 Subject: [PATCH 465/498] gh-145976: Remove `Misc/indent.pro` (#145992) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- ...-03-15-20-59-29.gh-issue-145976.rEdUI-.rst | 2 ++ Misc/README | 3 +-- Misc/indent.pro | 24 ------------------- 3 files changed, 3 insertions(+), 26 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2026-03-15-20-59-29.gh-issue-145976.rEdUI-.rst delete mode 100644 Misc/indent.pro diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-03-15-20-59-29.gh-issue-145976.rEdUI-.rst b/Misc/NEWS.d/next/Tools-Demos/2026-03-15-20-59-29.gh-issue-145976.rEdUI-.rst new file mode 100644 index 00000000000000..17b0f2d797fa48 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2026-03-15-20-59-29.gh-issue-145976.rEdUI-.rst @@ -0,0 +1,2 @@ +Remove :file:`Misc/indent.pro`, a configuration file for GNU +:manpage:`indent(1)`. diff --git a/Misc/README b/Misc/README index 038f842e0bc02e..1993c58ad8c960 100644 --- a/Misc/README +++ b/Misc/README @@ -9,8 +9,7 @@ Files found here ACKS Acknowledgements HISTORY News from previous releases -- oldest last -indent.pro GNU indent profile approximating my C style -NEWS News for this release (for some meaning of "this") +NEWS.d/ News files for this release (for some meaning of "this") python-config.in Python script template for python-config python.man UNIX man page for the python interpreter python.pc.in Package configuration info template for pkg-config diff --git a/Misc/indent.pro b/Misc/indent.pro deleted file mode 100644 index 02cceb62021453..00000000000000 --- a/Misc/indent.pro +++ /dev/null @@ -1,24 +0,0 @@ ---blank-lines-after-declarations ---blank-lines-after-procedures ---braces-after-func-def-line ---braces-on-if-line ---braces-on-struct-decl-line ---break-after-boolean-operator ---comment-indentation25 ---comment-line-length79 ---continue-at-parentheses ---dont-cuddle-do-while ---dont-cuddle-else ---indent-level4 ---line-length79 ---no-space-after-casts ---no-space-after-function-call-names ---no-space-after-parentheses ---no-tabs ---procnames-start-lines ---space-after-for ---space-after-if ---space-after-while ---swallow-optional-blank-lines --T PyCFunction --T PyObject From eb0e8be3a7e11b87d198a2c3af1ed0eccf532768 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 15 Mar 2026 21:46:06 +0000 Subject: [PATCH 466/498] gh-145986: Avoid unbound C recursion in `conv_content_model` in `pyexpat.c` (CVE 2026-4224) (#145987) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix C stack overflow (CVE-2026-4224) when an Expat parser with a registered `ElementDeclHandler` parses inline DTD containing deeply nested content model. --------- Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_pyexpat.py | 19 +++++++++++++++++++ ...-03-14-17-31-39.gh-issue-145986.ifSSr8.rst | 4 ++++ Modules/pyexpat.c | 9 ++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 31bcee293b2b69..f8afc16d3cb4cb 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -701,6 +701,25 @@ def test_trigger_leak(self): parser.ElementDeclHandler = lambda _1, _2: None self.assertRaises(TypeError, parser.Parse, data, True) + @support.skip_if_unlimited_stack_size + @support.skip_emscripten_stack_overflow() + @support.skip_wasi_stack_overflow() + def test_deeply_nested_content_model(self): + # This should raise a RecursionError and not crash. + # See https://github.com/python/cpython/issues/145986. + N = 500_000 + data = ( + b'\n]>\n\n' + ) + + parser = expat.ParserCreate() + parser.ElementDeclHandler = lambda _1, _2: None + with support.infinite_recursion(): + with self.assertRaises(RecursionError): + parser.Parse(data) + class MalformedInputTest(unittest.TestCase): def test1(self): xml = b"\0\r\n" diff --git a/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst b/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst new file mode 100644 index 00000000000000..79536d1fef543f --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst @@ -0,0 +1,4 @@ +:mod:`xml.parsers.expat`: Fixed a crash caused by unbounded C recursion when +converting deeply nested XML content models with +:meth:`~xml.parsers.expat.xmlparser.ElementDeclHandler`. +This addresses :cve:`2026-4224`. diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index e9255038eee5b5..cadc6706243524 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -3,6 +3,7 @@ #endif #include "Python.h" +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_import.h" // _PyImport_SetModule() #include "pycore_pyhash.h" // _Py_HashSecret #include "pycore_traceback.h" // _PyTraceback_Add() @@ -607,6 +608,10 @@ static PyObject * conv_content_model(XML_Content * const model, PyObject *(*conv_string)(void *)) { + if (_Py_EnterRecursiveCall(" in conv_content_model")) { + return NULL; + } + PyObject *result = NULL; PyObject *children = PyTuple_New(model->numchildren); int i; @@ -618,7 +623,7 @@ conv_content_model(XML_Content * const model, conv_string); if (child == NULL) { Py_XDECREF(children); - return NULL; + goto done; } PyTuple_SET_ITEM(children, i, child); } @@ -626,6 +631,8 @@ conv_content_model(XML_Content * const model, model->type, model->quant, conv_string, model->name, children); } +done: + _Py_LeaveRecursiveCall(); return result; } From f7cb789dc5ac009fa13c20527de19fb34e0e6ab8 Mon Sep 17 00:00:00 2001 From: Shahar Naveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:54:19 +0100 Subject: [PATCH 467/498] gh-145998: Remove duplicated "What's New in 3.15" entry (#145994) --- Doc/whatsnew/3.15.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 459846e55ccf70..c286e3fc4f2bda 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1014,13 +1014,6 @@ symtable (Contributed by Yashp002 in :gh:`143504`.) -symtable --------- - -* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods. - (Contributed by Yashp002 in :gh:`143504`.) - - sys --- From b062f391cfb407b02041737914b4a1f4fb1da87b Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:02:14 -0700 Subject: [PATCH 468/498] gh-145990: Sort `python --help-xoptions` by option name (GH-145991) * Sort --help-xoptions alphabetically by name. * add a sorting regression test in test_help_xoptions --- Lib/test/test_cmd_line.py | 4 +++ ...-03-15-20-47-34.gh-issue-145990.14BUzw.rst | 1 + Python/initconfig.c | 33 ++++++++++--------- 3 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-20-47-34.gh-issue-145990.14BUzw.rst diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index e106ac20809f20..c1dc59677896a5 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -3,6 +3,7 @@ # See test_cmd_line_script.py for testing of script execution import os +import re import subprocess import sys import sysconfig @@ -64,6 +65,9 @@ def test_help_env(self): def test_help_xoptions(self): out = self.verify_valid_flag('--help-xoptions') self.assertIn(b'-X dev', out) + options = re.findall(rb'^-X (\w+)', out, re.MULTILINE) + self.assertEqual(options, sorted(options), + "options should be sorted alphabetically") @support.cpython_only def test_help_all(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-20-47-34.gh-issue-145990.14BUzw.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-20-47-34.gh-issue-145990.14BUzw.rst new file mode 100644 index 00000000000000..f66c156b4bc916 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-20-47-34.gh-issue-145990.14BUzw.rst @@ -0,0 +1 @@ +``python --help-xoptions`` is now sorted by ``-X`` option name. diff --git a/Python/initconfig.c b/Python/initconfig.c index 57629ff8c57380..eff37fc32b4947 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -304,9 +304,15 @@ arg ...: arguments passed to program in sys.argv[1:]\n\ static const char usage_xoptions[] = "\ The following implementation-specific options are available:\n\ +-X context_aware_warnings=[0|1]: if true (1) then the warnings module will\n\ + use a context variables; if false (0) then the warnings module will\n\ + use module globals, which is not concurrent-safe; set to true for\n\ + free-threaded builds and false otherwise; also\n\ + PYTHON_CONTEXT_AWARE_WARNINGS\n\ -X cpu_count=N: override the return value of os.cpu_count();\n\ -X cpu_count=default cancels overriding; also PYTHON_CPU_COUNT\n\ -X dev : enable Python Development Mode; also PYTHONDEVMODE\n\ +-X disable-remote-debug: disable remote debugging; also PYTHON_DISABLE_REMOTE_DEBUG\n\ -X faulthandler: dump the Python traceback on fatal errors;\n\ also PYTHONFAULTHANDLER\n\ -X frozen_modules=[on|off]: whether to use frozen modules; the default is \"on\"\n\ @@ -319,16 +325,18 @@ The following implementation-specific options are available:\n\ "\ -X importtime[=2]: show how long each import takes; use -X importtime=2 to\n\ log imports of already-loaded modules; also PYTHONPROFILEIMPORTTIME\n\ --X lazy_imports=[all|none|normal]: control global lazy imports;\n\ - default is normal; also PYTHON_LAZY_IMPORTS\n\ -X int_max_str_digits=N: limit the size of int<->str conversions;\n\ 0 disables the limit; also PYTHONINTMAXSTRDIGITS\n\ +-X lazy_imports=[all|none|normal]: control global lazy imports;\n\ + default is normal; also PYTHON_LAZY_IMPORTS\n\ -X no_debug_ranges: don't include extra location information in code objects;\n\ also PYTHONNODEBUGRANGES\n\ +-X pathconfig_warnings=[0|1]: if true (1) then path configuration is allowed\n\ + to log warnings into stderr; if false (0) suppress these warnings;\n\ + set to true by default; also PYTHON_PATHCONFIG_WARNINGS\n\ -X perf: support the Linux \"perf\" profiler; also PYTHONPERFSUPPORT=1\n\ -X perf_jit: support the Linux \"perf\" profiler with DWARF support;\n\ also PYTHON_PERF_JIT_SUPPORT=1\n\ --X disable-remote-debug: disable remote debugging; also PYTHON_DISABLE_REMOTE_DEBUG\n\ " #ifdef Py_DEBUG "-X presite=MOD: import this module before site; also PYTHON_PRESITE\n" @@ -343,24 +351,17 @@ The following implementation-specific options are available:\n\ "\ -X showrefcount: output the total reference count and number of used\n\ memory blocks when the program finishes or after each statement in\n\ - the interactive interpreter; only works on debug builds\n" + the interactive interpreter; only works on debug builds\n\ +-X thread_inherit_context=[0|1]: enable (1) or disable (0) threads inheriting\n\ + context vars by default; enabled by default in the free-threaded\n\ + build and disabled otherwise; also PYTHON_THREAD_INHERIT_CONTEXT\n\ +" #ifdef Py_GIL_DISABLED "-X tlbc=[0|1]: enable (1) or disable (0) thread-local bytecode. Also\n\ PYTHON_TLBC\n" #endif "\ --X thread_inherit_context=[0|1]: enable (1) or disable (0) threads inheriting\n\ - context vars by default; enabled by default in the free-threaded\n\ - build and disabled otherwise; also PYTHON_THREAD_INHERIT_CONTEXT\n\ --X context_aware_warnings=[0|1]: if true (1) then the warnings module will\n\ - use a context variables; if false (0) then the warnings module will\n\ - use module globals, which is not concurrent-safe; set to true for\n\ - free-threaded builds and false otherwise; also\n\ - PYTHON_CONTEXT_AWARE_WARNINGS\n\ --X pathconfig_warnings=[0|1]: if true (1) then path configuration is allowed\n\ - to log warnings into stderr; if false (0) suppress these warnings;\n\ - set to true by default; also PYTHON_PATHCONFIG_WARNINGS\n\ --X tracemalloc[=N]: trace Python memory allocations; N sets a traceback limit\n \ +-X tracemalloc[=N]: trace Python memory allocations; N sets a traceback limit\n\ of N frames (default: 1); also PYTHONTRACEMALLOC=N\n\ -X utf8[=0|1]: enable (1) or disable (0) UTF-8 mode; also PYTHONUTF8\n\ -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None';\n\ From 83edae33a5591c52fa45df38da2616af470f290a Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Sun, 15 Mar 2026 15:22:57 -0700 Subject: [PATCH 469/498] gh-145990: sort `--help-env` sections by environment variable name (GH-145997) * sort --help-env alphabetically by name. * add a sorting regression test in test_help_env. --- Lib/test/test_cmd_line.py | 8 +++ ...-03-15-21-45-35.gh-issue-145990.tmXwRB.rst | 1 + Python/initconfig.c | 56 +++++++++---------- 3 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-21-45-35.gh-issue-145990.tmXwRB.rst diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index c1dc59677896a5..5f035c35367d64 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -60,6 +60,14 @@ def test_help(self): def test_help_env(self): out = self.verify_valid_flag('--help-env') self.assertIn(b'PYTHONHOME', out) + # Env vars in each section should be sorted alphabetically + # (ignoring underscores so PYTHON_FOO and PYTHONFOO intermix naturally) + sort_key = lambda name: name.replace(b'_', b'').lower() + sections = out.split(b'These variables have equivalent') + for section in sections: + envvars = re.findall(rb'^(PYTHON\w+)', section, re.MULTILINE) + self.assertEqual(envvars, sorted(envvars, key=sort_key), + "env vars should be sorted alphabetically") @support.cpython_only def test_help_xoptions(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-21-45-35.gh-issue-145990.tmXwRB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-21-45-35.gh-issue-145990.tmXwRB.rst new file mode 100644 index 00000000000000..21b9a524d005f9 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-15-21-45-35.gh-issue-145990.tmXwRB.rst @@ -0,0 +1 @@ +``python --help-env`` sections are now sorted by environment variable name. diff --git a/Python/initconfig.c b/Python/initconfig.c index eff37fc32b4947..caf42f5247c2f2 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -371,34 +371,19 @@ The following implementation-specific options are available:\n\ /* Envvars that don't have equivalent command-line options are listed first */ static const char usage_envvars[] = "Environment variables that change behavior:\n" -"PYTHONSTARTUP : file executed on interactive startup (no default)\n" -"PYTHONPATH : '%lc'-separated list of directories prefixed to the\n" -" default module search path. The result is sys.path.\n" -"PYTHONHOME : alternate directory (or %lc).\n" -" The default module search path uses %s.\n" -"PYTHONPLATLIBDIR: override sys.platlibdir\n" +"PYTHONASYNCIODEBUG: enable asyncio debug mode\n" +"PYTHON_BASIC_REPL: use the traditional parser-based REPL\n" +"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" +" debugger. It can be set to the callable of your debugger of\n" +" choice.\n" "PYTHONCASEOK : ignore case in 'import' statements (Windows)\n" -"PYTHONIOENCODING: encoding[:errors] used for stdin/stdout/stderr\n" -"PYTHONHASHSEED : if this variable is set to 'random', a random value is used\n" -" to seed the hashes of str and bytes objects. It can also be\n" -" set to an integer in the range [0,4294967295] to get hash\n" -" values with a predictable seed.\n" -"PYTHONMALLOC : set the Python memory allocators and/or install debug hooks\n" -" on Python memory allocators. Use PYTHONMALLOC=debug to\n" -" install debug hooks.\n" -"PYTHONMALLOCSTATS: print memory allocator statistics\n" "PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n" " coercion behavior. Use PYTHONCOERCECLOCALE=warn to request\n" " display of locale coercion and locale compatibility warnings\n" " on stderr.\n" -"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" -" debugger. It can be set to the callable of your debugger of\n" -" choice.\n" "PYTHON_COLORS : if this variable is set to 1, the interpreter will colorize\n" " various kinds of output. Setting it to 0 deactivates\n" " this behavior.\n" -"PYTHON_HISTORY : the location of a .python_history file.\n" -"PYTHONASYNCIODEBUG: enable asyncio debug mode\n" #ifdef Py_TRACE_REFS "PYTHONDUMPREFS : dump objects and reference counts still alive after shutdown\n" "PYTHONDUMPREFSFILE: dump objects and reference counts to the specified file\n" @@ -406,14 +391,31 @@ static const char usage_envvars[] = #ifdef __APPLE__ "PYTHONEXECUTABLE: set sys.argv[0] to this value (macOS only)\n" #endif +"PYTHONHASHSEED : if this variable is set to 'random', a random value is used\n" +" to seed the hashes of str and bytes objects. It can also be\n" +" set to an integer in the range [0,4294967295] to get hash\n" +" values with a predictable seed.\n" +"PYTHON_HISTORY : the location of a .python_history file.\n" +"PYTHONHOME : alternate directory (or %lc).\n" +" The default module search path uses %s.\n" +"PYTHONIOENCODING: encoding[:errors] used for stdin/stdout/stderr\n" #ifdef MS_WINDOWS "PYTHONLEGACYWINDOWSFSENCODING: use legacy \"mbcs\" encoding for file system\n" "PYTHONLEGACYWINDOWSSTDIO: use legacy Windows stdio\n" #endif +"PYTHONMALLOC : set the Python memory allocators and/or install debug hooks\n" +" on Python memory allocators. Use PYTHONMALLOC=debug to\n" +" install debug hooks.\n" +"PYTHONMALLOCSTATS: print memory allocator statistics\n" +"PYTHONPATH : '%lc'-separated list of directories prefixed to the\n" +" default module search path. The result is sys.path.\n" +"PYTHONPLATLIBDIR: override sys.platlibdir\n" +"PYTHONSTARTUP : file executed on interactive startup (no default)\n" "PYTHONUSERBASE : defines the user base directory (site.USER_BASE)\n" -"PYTHON_BASIC_REPL: use the traditional parser-based REPL\n" "\n" "These variables have equivalent command-line options (see --help for details):\n" +"PYTHON_CONTEXT_AWARE_WARNINGS: if true (1), enable thread-safe warnings\n" +" module behaviour (-X context_aware_warnings)\n" "PYTHON_CPU_COUNT: override the return value of os.cpu_count() (-X cpu_count)\n" "PYTHONDEBUG : enable parser debug mode (-d)\n" "PYTHONDEVMODE : enable Python Development Mode (-X dev)\n" @@ -428,31 +430,29 @@ static const char usage_envvars[] = "PYTHONINSPECT : inspect interactively after running script (-i)\n" "PYTHONINTMAXSTRDIGITS: limit the size of int<->str conversions;\n" " 0 disables the limit (-X int_max_str_digits=N)\n" +"PYTHON_LAZY_IMPORTS: control global lazy imports (-X lazy_imports)\n" "PYTHONNODEBUGRANGES: don't include extra location information in code objects\n" " (-X no_debug_ranges)\n" "PYTHONNOUSERSITE: disable user site directory (-s)\n" "PYTHONOPTIMIZE : enable level 1 optimizations (-O)\n" -"PYTHONPERFSUPPORT: support the Linux \"perf\" profiler (-X perf)\n" "PYTHON_PERF_JIT_SUPPORT: enable Linux \"perf\" profiler support with JIT\n" " (-X perf_jit)\n" +"PYTHONPERFSUPPORT: support the Linux \"perf\" profiler (-X perf)\n" #ifdef Py_DEBUG "PYTHON_PRESITE: import this module before site (-X presite)\n" #endif "PYTHONPROFILEIMPORTTIME: show how long each import takes (-X importtime)\n" -"PYTHON_LAZY_IMPORTS: control global lazy imports (-X lazy_imports)\n" "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files\n" " (-X pycache_prefix)\n" "PYTHONSAFEPATH : don't prepend a potentially unsafe path to sys.path.\n" #ifdef Py_STATS "PYTHONSTATS : turns on statistics gathering (-X pystats)\n" #endif +"PYTHON_THREAD_INHERIT_CONTEXT: if true (1), threads inherit context vars\n" +" (-X thread_inherit_context)\n" #ifdef Py_GIL_DISABLED "PYTHON_TLBC : when set to 0, disables thread-local bytecode (-X tlbc)\n" #endif -"PYTHON_THREAD_INHERIT_CONTEXT: if true (1), threads inherit context vars\n" -" (-X thread_inherit_context)\n" -"PYTHON_CONTEXT_AWARE_WARNINGS: if true (1), enable thread-safe warnings module\n" -" behaviour (-X context_aware_warnings)\n" "PYTHONTRACEMALLOC: trace Python memory allocations (-X tracemalloc)\n" "PYTHONUNBUFFERED: disable stdout/stderr buffering (-u)\n" "PYTHONUTF8 : control the UTF-8 mode (-X utf8)\n" @@ -2947,7 +2947,7 @@ config_usage(int error, const wchar_t* program) static void config_envvars_usage(void) { - printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP); + printf(usage_envvars, (wint_t)DELIM, PYTHONHOMEHELP, (wint_t)DELIM); } static void From 40095d526bd8ddbabee0603c2b502ed6807e5f4d Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sun, 15 Mar 2026 23:54:20 +0000 Subject: [PATCH 470/498] Expand `fuzz_pycompile.dict` for new syntax --- .../dictionaries/fuzz_pycompile.dict | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict b/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict index c6a44d946284ef..d36f55a40905d2 100644 --- a/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict +++ b/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict @@ -52,7 +52,9 @@ # whitespace " " +"\\t" ":\\n " +"\\\n" # type signatures and functions "-> " @@ -88,6 +90,8 @@ # variable names "x" "y" +"_" +"*x" # strings "r'x'" @@ -98,12 +102,24 @@ "br\"x\"" +"u\"x\"" + "f'{x + 5}'" "f\"{x + 5}\"" +"f'{s!r}'" +"f'{s!s}'" +"f'{s!a}'" +"f'{x=}'" + +"t'{s + 5}'" +"t\"{s + 5}\"" +"tr's'" +"rt\"s\"" "'''" "\"\"\"" +"\\N" "\\u" "\\x" @@ -131,6 +147,7 @@ "while " "try: " "except " +"except* " "finally: " "with " "lambda " @@ -148,6 +165,10 @@ "in " "is " "class " +"match " +"case " +"type " +"lazy " # shebangs and encodings "#!" From ee5318025b0f9f4d30d9358627df68181e0d223f Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:50:19 -0700 Subject: [PATCH 471/498] gh-140814: Fix freeze_support() setting start method as side effect (GH-144608) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit freeze_support() called get_start_method() without allow_none=True, which locked in the default start method context. This caused a subsequent set_start_method() call to raise "context has already been set". Use allow_none=True and accept None as a matching value, since spawn.freeze_support() independently detects spawned child processes. Test that freeze_support() does not lock in the default start method, which would prevent a subsequent set_start_method() call. Co-Authored-By: Claude Opus 4.6 Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/multiprocessing/context.py | 8 +++++++- Lib/test/_test_multiprocessing.py | 14 ++++++++++++++ .../2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index a73261cde856bb..e1d251456024c0 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -145,7 +145,13 @@ def freeze_support(self): '''Check whether this is a fake forked process in a frozen executable. If so then run code specified by commandline and exit. ''' - if self.get_start_method() == 'spawn' and getattr(sys, 'frozen', False): + # gh-140814: allow_none=True avoids locking in the default start + # method, which would cause a later set_start_method() to fail. + # None is safe to pass through: spawn.freeze_support() + # independently detects whether this process is a spawned + # child, so the start method check here is only an optimization. + if (getattr(sys, 'frozen', False) + and self.get_start_method(allow_none=True) in ('spawn', None)): from .spawn import freeze_support freeze_support() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index d67fd13fa33bed..490c7ae5e8076c 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -6005,6 +6005,20 @@ def test_spawn_dont_set_context(self): process.join() self.assertIsNone(multiprocessing.get_start_method(allow_none=True)) + @only_run_in_spawn_testsuite("freeze_support is not start method specific") + def test_freeze_support_dont_set_context(self): + # gh-140814: freeze_support() should not set the start method + # as a side effect, so a later set_start_method() still works. + multiprocessing.set_start_method(None, force=True) + try: + multiprocessing.freeze_support() + self.assertIsNone( + multiprocessing.get_start_method(allow_none=True)) + # Should not raise "context has already been set" + multiprocessing.set_start_method('spawn') + finally: + multiprocessing.set_start_method(None, force=True) + def test_context_check_module_types(self): try: ctx = multiprocessing.get_context('forkserver') diff --git a/Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst b/Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst new file mode 100644 index 00000000000000..6077de8ac9ae51 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst @@ -0,0 +1,3 @@ +:func:`multiprocessing.freeze_support` no longer sets the default start method +as a side effect, which previously caused a subsequent +:func:`multiprocessing.set_start_method` call to raise :exc:`RuntimeError`. From 70397fd1030c310d4d80beeb9c0d88f40c9abed8 Mon Sep 17 00:00:00 2001 From: RayXu Date: Mon, 16 Mar 2026 16:21:49 +0800 Subject: [PATCH 472/498] Docs: fix a form error and a grammatical error in float.rst (#140989) --- Doc/c-api/float.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index ca8d44c25c1ece..6e83e01344a9b2 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -201,8 +201,8 @@ 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. -Note that NaNs type may not be preserved on IEEE platforms (signaling NaN become -quiet NaN), for example on x86 systems in 32-bit mode. +Note that NaN type may not be preserved on IEEE platforms (signaling NaNs become +quiet NaNs), for example on x86 systems in 32-bit mode. 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 @@ -216,7 +216,7 @@ Pack functions The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an :c:expr:`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 +format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` and ``p+7``), zero if you want big-endian format (exponent first, at *p*). The :c:macro:`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. From 6f8867a6765d3e6effdc09a22691830aa887c3d0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 16 Mar 2026 17:29:55 +0900 Subject: [PATCH 473/498] gh-129849: Add tests for `Py_tp_bases` (#143208) --- Lib/test/test_capi/test_misc.py | 12 +++++++++ Modules/_testcapi/heaptype.c | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 3997acbdf84695..db06719919535f 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -916,6 +916,18 @@ def genf(): yield gen = genf() self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code) + def test_tp_bases_slot(self): + cls = _testcapi.HeapCTypeWithBasesSlot + self.assertEqual(cls.__bases__, (int,)) + self.assertEqual(cls.__base__, int) + + def test_tp_bases_slot_none(self): + self.assertRaisesRegex( + SystemError, + "Py_tp_bases is not a tuple", + _testcapi.create_heapctype_with_none_bases_slot + ) + @requires_limited_api class TestHeapTypeRelative(unittest.TestCase): diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index 4fdcc850a339b4..eb9458a066f430 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -543,6 +543,25 @@ pytype_getmodulebytoken(PyObject *self, PyObject *args) return PyType_GetModuleByToken((PyTypeObject *)type, token); } +static PyType_Slot HeapCTypeWithBasesSlotNone_slots[] = { + {Py_tp_bases, NULL}, /* filled out with Py_None in runtime */ + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithBasesSlotNone_spec = { + .name = "_testcapi.HeapCTypeWithBasesSlotNone", + .basicsize = sizeof(PyObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = HeapCTypeWithBasesSlotNone_slots +}; + +static PyObject * +create_heapctype_with_none_bases_slot(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + HeapCTypeWithBasesSlotNone_slots[0].pfunc = Py_None; + return PyType_FromSpec(&HeapCTypeWithBasesSlotNone_spec); +} + static PyMethodDef TestMethods[] = { {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O}, @@ -562,6 +581,8 @@ static PyMethodDef TestMethods[] = { {"pytype_getbasebytoken", pytype_getbasebytoken, METH_VARARGS}, {"pytype_getmodulebydef", pytype_getmodulebydef, METH_O}, {"pytype_getmodulebytoken", pytype_getmodulebytoken, METH_VARARGS}, + {"create_heapctype_with_none_bases_slot", + create_heapctype_with_none_bases_slot, METH_NOARGS}, {NULL}, }; @@ -892,6 +913,18 @@ static PyType_Spec HeapCTypeMetaclassNullNew_spec = { .slots = empty_type_slots }; +static PyType_Slot HeapCTypeWithBasesSlot_slots[] = { + {Py_tp_bases, NULL}, /* filled out in module init function */ + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithBasesSlot_spec = { + .name = "_testcapi.HeapCTypeWithBasesSlot", + .basicsize = sizeof(PyLongObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = HeapCTypeWithBasesSlot_slots +}; + typedef struct { PyObject_HEAD @@ -1432,6 +1465,18 @@ _PyTestCapi_Init_Heaptype(PyObject *m) { &PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *) &PyType_Type); ADD("HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew); + PyObject *bases = PyTuple_Pack(1, &PyLong_Type); + if (bases == NULL) { + return -1; + } + HeapCTypeWithBasesSlot_slots[0].pfunc = bases; + PyObject *HeapCTypeWithBasesSlot = PyType_FromSpec(&HeapCTypeWithBasesSlot_spec); + Py_DECREF(bases); + if (HeapCTypeWithBasesSlot == NULL) { + return -1; + } + ADD("HeapCTypeWithBasesSlot", HeapCTypeWithBasesSlot); + ADD("Py_TP_USE_SPEC", PyLong_FromVoidPtr(Py_TP_USE_SPEC)); PyObject *HeapCCollection = PyType_FromMetaclass( From 3a248564470075cb8c7b8a75fe7ba61f7ea341b2 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 16 Mar 2026 09:53:37 +0100 Subject: [PATCH 474/498] gh-123471: make concurrent iteration over itertools.accumulate thread-safe (#144486) --- Lib/test/test_free_threading/test_itertools.py | 9 ++++++++- .../2026-02-04-20-30-59.gh-issue-123471.1dnPvs.rst | 1 + Modules/itertoolsmodule.c | 12 +++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-04-20-30-59.gh-issue-123471.1dnPvs.rst diff --git a/Lib/test/test_free_threading/test_itertools.py b/Lib/test/test_free_threading/test_itertools.py index bb6047e8669475..20135dd3165acf 100644 --- a/Lib/test/test_free_threading/test_itertools.py +++ b/Lib/test/test_free_threading/test_itertools.py @@ -1,5 +1,5 @@ import unittest -from itertools import batched, chain, combinations_with_replacement, cycle, permutations +from itertools import accumulate, batched, chain, combinations_with_replacement, cycle, permutations from test.support import threading_helper @@ -16,6 +16,13 @@ def work_iterator(it): class ItertoolsThreading(unittest.TestCase): + @threading_helper.reap_threads + def test_accumulate(self): + number_of_iterations = 10 + for _ in range(number_of_iterations): + it = accumulate(tuple(range(40))) + threading_helper.run_concurrently(work_iterator, nthreads=10, args=[it]) + @threading_helper.reap_threads def test_batched(self): number_of_iterations = 10 diff --git a/Misc/NEWS.d/next/Library/2026-02-04-20-30-59.gh-issue-123471.1dnPvs.rst b/Misc/NEWS.d/next/Library/2026-02-04-20-30-59.gh-issue-123471.1dnPvs.rst new file mode 100644 index 00000000000000..d650103e28ee68 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-04-20-30-59.gh-issue-123471.1dnPvs.rst @@ -0,0 +1 @@ +Make concurrent iteration over :class:`itertools.accumulate` safe under free-threading. diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index bc25bf6bfc1bd2..b37256c7928bad 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -3073,7 +3073,7 @@ accumulate_traverse(PyObject *op, visitproc visit, void *arg) } static PyObject * -accumulate_next(PyObject *op) +accumulate_next_lock_held(PyObject *op) { accumulateobject *lz = accumulateobject_CAST(op); PyObject *val, *newtotal; @@ -3105,6 +3105,16 @@ accumulate_next(PyObject *op) return newtotal; } +static PyObject * +accumulate_next(PyObject *op) +{ + PyObject *result; + Py_BEGIN_CRITICAL_SECTION(op); + result = accumulate_next_lock_held(op); + Py_END_CRITICAL_SECTION() + return result; +} + static PyType_Slot accumulate_slots[] = { {Py_tp_dealloc, accumulate_dealloc}, {Py_tp_getattro, PyObject_GenericGetAttr}, From e2e62033aa71508893eb2ffeec44432d80dc3739 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 16 Mar 2026 18:10:34 +0800 Subject: [PATCH 475/498] gh-139038: Link to Savannah's webpage for JIT results (#146013) --- Doc/whatsnew/3.15.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index c286e3fc4f2bda..d4c4483bc5eb78 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1286,11 +1286,11 @@ Upgraded JIT compiler Results from the `pyperformance `__ benchmark suite report -`4-5% `__ +`5-6% `__ geometric mean performance improvement for the JIT over the standard CPython interpreter built with all optimizations enabled on x86-64 Linux. On AArch64 macOS, the JIT has a -`7-8% `__ +`8-9% `__ speedup over the :ref:`tail calling interpreter ` with all optimizations enabled. The speedups for JIT builds versus no JIT builds range from roughly 15% slowdown to over From 36b5284f04b0a946a7d915bcd656534c9b4dbd85 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Mon, 16 Mar 2026 03:55:00 -0700 Subject: [PATCH 476/498] gh-145649: Fix man page text wrapping for -X option (#145656) Replace hardcoded space indentation with proper troff macros (.TP, .RS/.RE, .IP) for -X sub-options so text wraps correctly at any terminal width. Co-authored-by: Claude Opus 4.6 --- ...-03-09-00-00-00.gh-issue-145649.8BcbAB.rst | 2 + Misc/python.man | 175 ++++++++++-------- 2 files changed, 101 insertions(+), 76 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2026-03-09-00-00-00.gh-issue-145649.8BcbAB.rst diff --git a/Misc/NEWS.d/next/Documentation/2026-03-09-00-00-00.gh-issue-145649.8BcbAB.rst b/Misc/NEWS.d/next/Documentation/2026-03-09-00-00-00.gh-issue-145649.8BcbAB.rst new file mode 100644 index 00000000000000..33061f7dd15cc7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2026-03-09-00-00-00.gh-issue-145649.8BcbAB.rst @@ -0,0 +1,2 @@ +Fix text wrapping and formatting of ``-X`` option descriptions in the +:manpage:`python(1)` man page by using proper roff markup. diff --git a/Misc/python.man b/Misc/python.man index 612e2bbf56800e..a65fb98a697b50 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -320,82 +320,105 @@ a regular expression on the warning message. .TP .BI "\-X " option Set implementation-specific option. The following options are available: - - \fB\-X cpu_count=\fIN\fR: override the return value of \fIos.cpu_count()\fR; - \fB\-X cpu_count=default\fR cancels overriding; also \fBPYTHON_CPU_COUNT\fI - - \fB\-X dev\fR: enable CPython's "development mode", introducing additional - runtime checks which are too expensive to be enabled by default. It - will not be more verbose than the default if the code is correct: new - warnings are only emitted when an issue is detected. Effect of the - developer mode: - * Add default warning filter, as \fB\-W default\fR - * Install debug hooks on memory allocators: see the - PyMem_SetupDebugHooks() C function - * Enable the faulthandler module to dump the Python traceback on a - crash - * Enable asyncio debug mode - * Set the dev_mode attribute of sys.flags to True - * io.IOBase destructor logs close() exceptions - - \fB\-X importtime\fR: show how long each import takes. It shows module name, - cumulative time (including nested imports) and self time (excluding - nested imports). Note that its output may be broken in multi-threaded - application. Typical usage is - \fBpython3 \-X importtime \-c 'import asyncio'\fR - - \fB\-X importtime=2\fR enables additional output that indicates when an - imported module has already been loaded. In such cases, the string - \fBcached\fR will be printed in both time columns. - - \fB\-X faulthandler\fR: enable faulthandler - - \fB\-X frozen_modules=\fR[\fBon\fR|\fBoff\fR]: whether or not frozen modules - should be used. - The default is "on" (or "off" if you are running a local build). - - \fB\-X gil=\fR[\fB0\fR|\fB1\fR]: enable (1) or disable (0) the GIL; also - \fBPYTHON_GIL\fR - Only available in builds configured with \fB\-\-disable\-gil\fR. - - \fB\-X int_max_str_digits=\fInumber\fR: limit the size of int<->str conversions. - This helps avoid denial of service attacks when parsing untrusted data. - The default is sys.int_info.default_max_str_digits. 0 disables. - - \fB\-X no_debug_ranges\fR: disable the inclusion of the tables mapping extra - location information (end line, start column offset and end column - offset) to every instruction in code objects. This is useful when - smaller code objects and pyc files are desired as well as suppressing - the extra visual location indicators when the interpreter displays - tracebacks. - - \fB\-X perf\fR: support the Linux "perf" profiler; also \fBPYTHONPERFSUPPORT=1\fR - - \fB\-X perf_jit\fR: support the Linux "perf" profiler with DWARF support; - also \fBPYTHON_PERF_JIT_SUPPORT=1\fR - - \fB\-X presite=\fIMOD\fR: import this module before site; also \fBPYTHON_PRESITE\fR - This only works on debug builds. - - \fB\-X pycache_prefix=\fIPATH\fR: enable writing .pyc files to a parallel - tree rooted at the given directory instead of to the code tree. - - \fB\-X showrefcount\fR: output the total reference count and number of used - memory blocks when the program finishes or after each statement in the - interactive interpreter. This only works on debug builds - - \fB\-X tracemalloc\fR: start tracing Python memory allocations using the - tracemalloc module. By default, only the most recent frame is stored in a - traceback of a trace. Use \-X tracemalloc=NFRAME to start tracing with a - traceback limit of NFRAME frames - - \fB\-X utf8\fR: enable UTF-8 mode for operating system interfaces, - overriding the default locale-aware mode. \fB\-X utf8=0\fR explicitly - disables UTF-8 mode (even when it would otherwise activate - automatically). See \fBPYTHONUTF8\fR for more details - - \fB\-X warn_default_encoding\fR: enable opt-in EncodingWarning for 'encoding=None' - +.RS +.TP +\fB\-X cpu_count=\fIN\fR +Override the return value of \fIos.cpu_count()\fR. +\fB\-X cpu_count=default\fR cancels overriding. +See also \fBPYTHON_CPU_COUNT\fR. +.TP +\fB\-X dev\fR +Enable CPython's "development mode", introducing additional +runtime checks which are too expensive to be enabled by default. It +will not be more verbose than the default if the code is correct: new +warnings are only emitted when an issue is detected. Effect of the +developer mode: +.RS +.IP \(bu 2 +Add default warning filter, as \fB\-W default\fR. +.IP \(bu 2 +Install debug hooks on memory allocators: see the +PyMem_SetupDebugHooks() C function. +.IP \(bu 2 +Enable the faulthandler module to dump the Python traceback on a crash. +.IP \(bu 2 +Enable asyncio debug mode. +.IP \(bu 2 +Set the dev_mode attribute of sys.flags to True. +.IP \(bu 2 +io.IOBase destructor logs close() exceptions. +.RE +.TP +\fB\-X importtime\fR +Show how long each import takes. It shows module name, +cumulative time (including nested imports) and self time (excluding +nested imports). Note that its output may be broken in multi-threaded +application. Typical usage is +\fBpython3 \-X importtime \-c 'import asyncio'\fR. +.IP +\fB\-X importtime=2\fR enables additional output that indicates when an +imported module has already been loaded. In such cases, the string +\fBcached\fR will be printed in both time columns. +.TP +\fB\-X faulthandler\fR +Enable faulthandler. +.TP +\fB\-X frozen_modules=\fR[\fBon\fR|\fBoff\fR] +Whether or not frozen modules should be used. +The default is "on" (or "off" if you are running a local build). +.TP +\fB\-X gil=\fR[\fB0\fR|\fB1\fR] +Enable (1) or disable (0) the GIL. See also \fBPYTHON_GIL\fR. +Only available in builds configured with \fB\-\-disable\-gil\fR. +.TP +\fB\-X int_max_str_digits=\fInumber\fR +Limit the size of int<->str conversions. +This helps avoid denial of service attacks when parsing untrusted data. +The default is sys.int_info.default_max_str_digits. 0 disables. +.TP +\fB\-X no_debug_ranges\fR +Disable the inclusion of the tables mapping extra +location information (end line, start column offset and end column +offset) to every instruction in code objects. This is useful when +smaller code objects and pyc files are desired as well as suppressing +the extra visual location indicators when the interpreter displays +tracebacks. +.TP +\fB\-X perf\fR +Support the Linux "perf" profiler. See also \fBPYTHONPERFSUPPORT=1\fR. +.TP +\fB\-X perf_jit\fR +Support the Linux "perf" profiler with DWARF support. +See also \fBPYTHON_PERF_JIT_SUPPORT=1\fR. +.TP +\fB\-X presite=\fIMOD\fR +Import this module before site. See also \fBPYTHON_PRESITE\fR. +This only works on debug builds. +.TP +\fB\-X pycache_prefix=\fIPATH\fR +Enable writing .pyc files to a parallel +tree rooted at the given directory instead of to the code tree. +.TP +\fB\-X showrefcount\fR +Output the total reference count and number of used +memory blocks when the program finishes or after each statement in the +interactive interpreter. This only works on debug builds. +.TP +\fB\-X tracemalloc\fR +Start tracing Python memory allocations using the +tracemalloc module. By default, only the most recent frame is stored in a +traceback of a trace. Use \fB\-X tracemalloc=\fINFRAME\fR to start tracing with a +traceback limit of NFRAME frames. +.TP +\fB\-X utf8\fR +Enable UTF-8 mode for operating system interfaces, +overriding the default locale-aware mode. \fB\-X utf8=0\fR explicitly +disables UTF-8 mode (even when it would otherwise activate +automatically). See \fBPYTHONUTF8\fR for more details. +.TP +\fB\-X warn_default_encoding\fR +Enable opt-in EncodingWarning for 'encoding=None'. +.RE .TP .B \-x Skip the first line of the source. This is intended for a DOS From 37121ef77ee54bd5bf12582392ecf55afa80f366 Mon Sep 17 00:00:00 2001 From: Sacul <183588943+Sacul0457@users.noreply.github.com> Date: Mon, 16 Mar 2026 19:58:12 +0800 Subject: [PATCH 477/498] gh-145866: Convert `CALL_INTRINSIC_1` to leave its inputs on the stack to be cleaned up by `_POP_TOP`. (GH-145964) --- Include/internal/pycore_opcode_metadata.h | 4 +- Include/internal/pycore_uop_ids.h | 2332 ++++++++++----------- Include/internal/pycore_uop_metadata.h | 8 +- Lib/test/test_capi/test_opt.py | 15 + Modules/_testinternalcapi/test_cases.c.h | 37 +- Python/bytecodes.c | 11 +- Python/executor_cases.c.h | 15 +- Python/generated_cases.c.h | 37 +- Python/optimizer_bytecodes.c | 5 + Python/optimizer_cases.c.h | 8 + 10 files changed, 1257 insertions(+), 1215 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index c64d4e8ba85b3d..fc5689c5afe13a 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1130,7 +1130,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [CALL_EX_NON_PY_GENERAL] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_EX_PY] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [CALL_FUNCTION_EX] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, - [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [CALL_ISINSTANCE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [CALL_KW] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, @@ -1380,7 +1380,7 @@ _PyOpcode_macro_expansion[256] = { [CALL_BUILTIN_O] = { .nuops = 5, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, [CALL_EX_NON_PY_GENERAL] = { .nuops = 4, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CALL_FUNCTION_EX_NON_PY_GENERAL, OPARG_SIMPLE, 1 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 1 } } }, [CALL_EX_PY] = { .nuops = 7, .uops = { { _RECORD_4OS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CHECK_IS_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _PY_FRAME_EX, OPARG_SIMPLE, 1 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, - [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, OPARG_SIMPLE, 0 } } }, + [CALL_INTRINSIC_1] = { .nuops = 2, .uops = { { _CALL_INTRINSIC_1, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } }, [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, OPARG_SIMPLE, 0 } } }, [CALL_ISINSTANCE] = { .nuops = 3, .uops = { { _GUARD_THIRD_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_ISINSTANCE, OPARG_SIMPLE, 3 }, { _CALL_ISINSTANCE, OPARG_SIMPLE, 3 } } }, [CALL_KW_BOUND_METHOD] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION_KW, 2, 1 }, { _EXPAND_METHOD_KW, OPARG_SIMPLE, 3 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 0fdeb56122ecc7..451c0dd5732d85 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -43,167 +43,167 @@ extern "C" { #define _CALL_BUILTIN_FAST_WITH_KEYWORDS 323 #define _CALL_BUILTIN_O 324 #define _CALL_FUNCTION_EX_NON_PY_GENERAL 325 -#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1 +#define _CALL_INTRINSIC_1 326 #define _CALL_INTRINSIC_2 CALL_INTRINSIC_2 -#define _CALL_ISINSTANCE 326 -#define _CALL_KW_NON_PY 327 -#define _CALL_LEN 328 -#define _CALL_LIST_APPEND 329 -#define _CALL_METHOD_DESCRIPTOR_FAST 330 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 331 -#define _CALL_METHOD_DESCRIPTOR_NOARGS 332 -#define _CALL_METHOD_DESCRIPTOR_O 333 -#define _CALL_NON_PY_GENERAL 334 -#define _CALL_STR_1 335 -#define _CALL_TUPLE_1 336 -#define _CALL_TYPE_1 337 -#define _CHECK_AND_ALLOCATE_OBJECT 338 -#define _CHECK_ATTR_CLASS 339 -#define _CHECK_ATTR_METHOD_LAZY_DICT 340 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 341 +#define _CALL_ISINSTANCE 327 +#define _CALL_KW_NON_PY 328 +#define _CALL_LEN 329 +#define _CALL_LIST_APPEND 330 +#define _CALL_METHOD_DESCRIPTOR_FAST 331 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 332 +#define _CALL_METHOD_DESCRIPTOR_NOARGS 333 +#define _CALL_METHOD_DESCRIPTOR_O 334 +#define _CALL_NON_PY_GENERAL 335 +#define _CALL_STR_1 336 +#define _CALL_TUPLE_1 337 +#define _CALL_TYPE_1 338 +#define _CHECK_AND_ALLOCATE_OBJECT 339 +#define _CHECK_ATTR_CLASS 340 +#define _CHECK_ATTR_METHOD_LAZY_DICT 341 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 342 #define _CHECK_EG_MATCH CHECK_EG_MATCH #define _CHECK_EXC_MATCH CHECK_EXC_MATCH -#define _CHECK_FUNCTION_EXACT_ARGS 342 -#define _CHECK_FUNCTION_VERSION 343 -#define _CHECK_FUNCTION_VERSION_INLINE 344 -#define _CHECK_FUNCTION_VERSION_KW 345 -#define _CHECK_IS_NOT_PY_CALLABLE 346 -#define _CHECK_IS_NOT_PY_CALLABLE_EX 347 -#define _CHECK_IS_NOT_PY_CALLABLE_KW 348 -#define _CHECK_IS_PY_CALLABLE_EX 349 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES 350 -#define _CHECK_METHOD_VERSION 351 -#define _CHECK_METHOD_VERSION_KW 352 -#define _CHECK_PEP_523 353 -#define _CHECK_PERIODIC 354 -#define _CHECK_PERIODIC_AT_END 355 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 356 -#define _CHECK_RECURSION_REMAINING 357 -#define _CHECK_STACK_SPACE 358 -#define _CHECK_STACK_SPACE_OPERAND 359 -#define _CHECK_VALIDITY 360 -#define _COLD_DYNAMIC_EXIT 361 -#define _COLD_EXIT 362 -#define _COMPARE_OP 363 -#define _COMPARE_OP_FLOAT 364 -#define _COMPARE_OP_INT 365 -#define _COMPARE_OP_STR 366 -#define _CONTAINS_OP 367 -#define _CONTAINS_OP_DICT 368 -#define _CONTAINS_OP_SET 369 +#define _CHECK_FUNCTION_EXACT_ARGS 343 +#define _CHECK_FUNCTION_VERSION 344 +#define _CHECK_FUNCTION_VERSION_INLINE 345 +#define _CHECK_FUNCTION_VERSION_KW 346 +#define _CHECK_IS_NOT_PY_CALLABLE 347 +#define _CHECK_IS_NOT_PY_CALLABLE_EX 348 +#define _CHECK_IS_NOT_PY_CALLABLE_KW 349 +#define _CHECK_IS_PY_CALLABLE_EX 350 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES 351 +#define _CHECK_METHOD_VERSION 352 +#define _CHECK_METHOD_VERSION_KW 353 +#define _CHECK_PEP_523 354 +#define _CHECK_PERIODIC 355 +#define _CHECK_PERIODIC_AT_END 356 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 357 +#define _CHECK_RECURSION_REMAINING 358 +#define _CHECK_STACK_SPACE 359 +#define _CHECK_STACK_SPACE_OPERAND 360 +#define _CHECK_VALIDITY 361 +#define _COLD_DYNAMIC_EXIT 362 +#define _COLD_EXIT 363 +#define _COMPARE_OP 364 +#define _COMPARE_OP_FLOAT 365 +#define _COMPARE_OP_INT 366 +#define _COMPARE_OP_STR 367 +#define _CONTAINS_OP 368 +#define _CONTAINS_OP_DICT 369 +#define _CONTAINS_OP_SET 370 #define _CONVERT_VALUE CONVERT_VALUE -#define _COPY 370 -#define _COPY_1 371 -#define _COPY_2 372 -#define _COPY_3 373 +#define _COPY 371 +#define _COPY_1 372 +#define _COPY_2 373 +#define _COPY_3 374 #define _COPY_FREE_VARS COPY_FREE_VARS -#define _CREATE_INIT_FRAME 374 +#define _CREATE_INIT_FRAME 375 #define _DELETE_ATTR DELETE_ATTR #define _DELETE_DEREF DELETE_DEREF #define _DELETE_FAST DELETE_FAST #define _DELETE_GLOBAL DELETE_GLOBAL #define _DELETE_NAME DELETE_NAME #define _DELETE_SUBSCR DELETE_SUBSCR -#define _DEOPT 375 +#define _DEOPT 376 #define _DICT_MERGE DICT_MERGE #define _DICT_UPDATE DICT_UPDATE -#define _DO_CALL 376 -#define _DO_CALL_FUNCTION_EX 377 -#define _DO_CALL_KW 378 -#define _DYNAMIC_EXIT 379 +#define _DO_CALL 377 +#define _DO_CALL_FUNCTION_EX 378 +#define _DO_CALL_KW 379 +#define _DYNAMIC_EXIT 380 #define _END_FOR END_FOR #define _END_SEND END_SEND -#define _ERROR_POP_N 380 +#define _ERROR_POP_N 381 #define _EXIT_INIT_CHECK EXIT_INIT_CHECK -#define _EXPAND_METHOD 381 -#define _EXPAND_METHOD_KW 382 -#define _FATAL_ERROR 383 +#define _EXPAND_METHOD 382 +#define _EXPAND_METHOD_KW 383 +#define _FATAL_ERROR 384 #define _FORMAT_SIMPLE FORMAT_SIMPLE #define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC -#define _FOR_ITER 384 -#define _FOR_ITER_GEN_FRAME 385 -#define _FOR_ITER_TIER_TWO 386 +#define _FOR_ITER 385 +#define _FOR_ITER_GEN_FRAME 386 +#define _FOR_ITER_TIER_TWO 387 #define _GET_AITER GET_AITER #define _GET_ANEXT GET_ANEXT #define _GET_AWAITABLE GET_AWAITABLE #define _GET_ITER GET_ITER #define _GET_LEN GET_LEN #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER -#define _GUARD_BINARY_OP_EXTEND 387 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS 388 -#define _GUARD_BIT_IS_SET_POP 389 -#define _GUARD_BIT_IS_SET_POP_4 390 -#define _GUARD_BIT_IS_SET_POP_5 391 -#define _GUARD_BIT_IS_SET_POP_6 392 -#define _GUARD_BIT_IS_SET_POP_7 393 -#define _GUARD_BIT_IS_UNSET_POP 394 -#define _GUARD_BIT_IS_UNSET_POP_4 395 -#define _GUARD_BIT_IS_UNSET_POP_5 396 -#define _GUARD_BIT_IS_UNSET_POP_6 397 -#define _GUARD_BIT_IS_UNSET_POP_7 398 -#define _GUARD_CALLABLE_ISINSTANCE 399 -#define _GUARD_CALLABLE_LEN 400 -#define _GUARD_CALLABLE_LIST_APPEND 401 -#define _GUARD_CALLABLE_STR_1 402 -#define _GUARD_CALLABLE_TUPLE_1 403 -#define _GUARD_CALLABLE_TYPE_1 404 -#define _GUARD_CODE_VERSION 405 -#define _GUARD_DORV_NO_DICT 406 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 407 -#define _GUARD_GLOBALS_VERSION 408 -#define _GUARD_IP_RETURN_GENERATOR 409 -#define _GUARD_IP_RETURN_VALUE 410 -#define _GUARD_IP_YIELD_VALUE 411 -#define _GUARD_IP__PUSH_FRAME 412 -#define _GUARD_IS_FALSE_POP 413 -#define _GUARD_IS_NONE_POP 414 -#define _GUARD_IS_NOT_NONE_POP 415 -#define _GUARD_IS_TRUE_POP 416 -#define _GUARD_KEYS_VERSION 417 -#define _GUARD_NOS_ANY_DICT 418 -#define _GUARD_NOS_COMPACT_ASCII 419 -#define _GUARD_NOS_DICT 420 -#define _GUARD_NOS_FLOAT 421 -#define _GUARD_NOS_INT 422 -#define _GUARD_NOS_LIST 423 -#define _GUARD_NOS_NOT_NULL 424 -#define _GUARD_NOS_NULL 425 -#define _GUARD_NOS_OVERFLOWED 426 -#define _GUARD_NOS_TUPLE 427 -#define _GUARD_NOS_UNICODE 428 -#define _GUARD_NOT_EXHAUSTED_LIST 429 -#define _GUARD_NOT_EXHAUSTED_RANGE 430 -#define _GUARD_NOT_EXHAUSTED_TUPLE 431 -#define _GUARD_THIRD_NULL 432 -#define _GUARD_TOS_ANY_DICT 433 -#define _GUARD_TOS_ANY_SET 434 -#define _GUARD_TOS_DICT 435 -#define _GUARD_TOS_FLOAT 436 -#define _GUARD_TOS_FROZENDICT 437 -#define _GUARD_TOS_FROZENSET 438 -#define _GUARD_TOS_INT 439 -#define _GUARD_TOS_LIST 440 -#define _GUARD_TOS_OVERFLOWED 441 -#define _GUARD_TOS_SET 442 -#define _GUARD_TOS_SLICE 443 -#define _GUARD_TOS_TUPLE 444 -#define _GUARD_TOS_UNICODE 445 -#define _GUARD_TYPE_VERSION 446 -#define _GUARD_TYPE_VERSION_LOCKED 447 -#define _HANDLE_PENDING_AND_DEOPT 448 +#define _GUARD_BINARY_OP_EXTEND 388 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS 389 +#define _GUARD_BIT_IS_SET_POP 390 +#define _GUARD_BIT_IS_SET_POP_4 391 +#define _GUARD_BIT_IS_SET_POP_5 392 +#define _GUARD_BIT_IS_SET_POP_6 393 +#define _GUARD_BIT_IS_SET_POP_7 394 +#define _GUARD_BIT_IS_UNSET_POP 395 +#define _GUARD_BIT_IS_UNSET_POP_4 396 +#define _GUARD_BIT_IS_UNSET_POP_5 397 +#define _GUARD_BIT_IS_UNSET_POP_6 398 +#define _GUARD_BIT_IS_UNSET_POP_7 399 +#define _GUARD_CALLABLE_ISINSTANCE 400 +#define _GUARD_CALLABLE_LEN 401 +#define _GUARD_CALLABLE_LIST_APPEND 402 +#define _GUARD_CALLABLE_STR_1 403 +#define _GUARD_CALLABLE_TUPLE_1 404 +#define _GUARD_CALLABLE_TYPE_1 405 +#define _GUARD_CODE_VERSION 406 +#define _GUARD_DORV_NO_DICT 407 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 408 +#define _GUARD_GLOBALS_VERSION 409 +#define _GUARD_IP_RETURN_GENERATOR 410 +#define _GUARD_IP_RETURN_VALUE 411 +#define _GUARD_IP_YIELD_VALUE 412 +#define _GUARD_IP__PUSH_FRAME 413 +#define _GUARD_IS_FALSE_POP 414 +#define _GUARD_IS_NONE_POP 415 +#define _GUARD_IS_NOT_NONE_POP 416 +#define _GUARD_IS_TRUE_POP 417 +#define _GUARD_KEYS_VERSION 418 +#define _GUARD_NOS_ANY_DICT 419 +#define _GUARD_NOS_COMPACT_ASCII 420 +#define _GUARD_NOS_DICT 421 +#define _GUARD_NOS_FLOAT 422 +#define _GUARD_NOS_INT 423 +#define _GUARD_NOS_LIST 424 +#define _GUARD_NOS_NOT_NULL 425 +#define _GUARD_NOS_NULL 426 +#define _GUARD_NOS_OVERFLOWED 427 +#define _GUARD_NOS_TUPLE 428 +#define _GUARD_NOS_UNICODE 429 +#define _GUARD_NOT_EXHAUSTED_LIST 430 +#define _GUARD_NOT_EXHAUSTED_RANGE 431 +#define _GUARD_NOT_EXHAUSTED_TUPLE 432 +#define _GUARD_THIRD_NULL 433 +#define _GUARD_TOS_ANY_DICT 434 +#define _GUARD_TOS_ANY_SET 435 +#define _GUARD_TOS_DICT 436 +#define _GUARD_TOS_FLOAT 437 +#define _GUARD_TOS_FROZENDICT 438 +#define _GUARD_TOS_FROZENSET 439 +#define _GUARD_TOS_INT 440 +#define _GUARD_TOS_LIST 441 +#define _GUARD_TOS_OVERFLOWED 442 +#define _GUARD_TOS_SET 443 +#define _GUARD_TOS_SLICE 444 +#define _GUARD_TOS_TUPLE 445 +#define _GUARD_TOS_UNICODE 446 +#define _GUARD_TYPE_VERSION 447 +#define _GUARD_TYPE_VERSION_LOCKED 448 +#define _HANDLE_PENDING_AND_DEOPT 449 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 449 -#define _INIT_CALL_PY_EXACT_ARGS 450 -#define _INIT_CALL_PY_EXACT_ARGS_0 451 -#define _INIT_CALL_PY_EXACT_ARGS_1 452 -#define _INIT_CALL_PY_EXACT_ARGS_2 453 -#define _INIT_CALL_PY_EXACT_ARGS_3 454 -#define _INIT_CALL_PY_EXACT_ARGS_4 455 -#define _INSERT_1_LOAD_CONST_INLINE 456 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW 457 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW 458 -#define _INSERT_NULL 459 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 450 +#define _INIT_CALL_PY_EXACT_ARGS 451 +#define _INIT_CALL_PY_EXACT_ARGS_0 452 +#define _INIT_CALL_PY_EXACT_ARGS_1 453 +#define _INIT_CALL_PY_EXACT_ARGS_2 454 +#define _INIT_CALL_PY_EXACT_ARGS_3 455 +#define _INIT_CALL_PY_EXACT_ARGS_4 456 +#define _INSERT_1_LOAD_CONST_INLINE 457 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW 458 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW 459 +#define _INSERT_NULL 460 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -213,1080 +213,1080 @@ extern "C" { #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE -#define _IS_NONE 460 -#define _IS_OP 461 -#define _ITER_CHECK_LIST 462 -#define _ITER_CHECK_RANGE 463 -#define _ITER_CHECK_TUPLE 464 -#define _ITER_JUMP_LIST 465 -#define _ITER_JUMP_RANGE 466 -#define _ITER_JUMP_TUPLE 467 -#define _ITER_NEXT_LIST 468 -#define _ITER_NEXT_LIST_TIER_TWO 469 -#define _ITER_NEXT_RANGE 470 -#define _ITER_NEXT_TUPLE 471 +#define _IS_NONE 461 +#define _IS_OP 462 +#define _ITER_CHECK_LIST 463 +#define _ITER_CHECK_RANGE 464 +#define _ITER_CHECK_TUPLE 465 +#define _ITER_JUMP_LIST 466 +#define _ITER_JUMP_RANGE 467 +#define _ITER_JUMP_TUPLE 468 +#define _ITER_NEXT_LIST 469 +#define _ITER_NEXT_LIST_TIER_TWO 470 +#define _ITER_NEXT_RANGE 471 +#define _ITER_NEXT_TUPLE 472 #define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT -#define _JUMP_TO_TOP 472 +#define _JUMP_TO_TOP 473 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 473 -#define _LOAD_ATTR_CLASS 474 +#define _LOAD_ATTR 474 +#define _LOAD_ATTR_CLASS 475 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 475 -#define _LOAD_ATTR_METHOD_LAZY_DICT 476 -#define _LOAD_ATTR_METHOD_NO_DICT 477 -#define _LOAD_ATTR_METHOD_WITH_VALUES 478 -#define _LOAD_ATTR_MODULE 479 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 480 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 481 -#define _LOAD_ATTR_PROPERTY_FRAME 482 -#define _LOAD_ATTR_SLOT 483 -#define _LOAD_ATTR_WITH_HINT 484 +#define _LOAD_ATTR_INSTANCE_VALUE 476 +#define _LOAD_ATTR_METHOD_LAZY_DICT 477 +#define _LOAD_ATTR_METHOD_NO_DICT 478 +#define _LOAD_ATTR_METHOD_WITH_VALUES 479 +#define _LOAD_ATTR_MODULE 480 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 481 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 482 +#define _LOAD_ATTR_PROPERTY_FRAME 483 +#define _LOAD_ATTR_SLOT 484 +#define _LOAD_ATTR_WITH_HINT 485 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 485 +#define _LOAD_BYTECODE 486 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 486 -#define _LOAD_CONST_INLINE_BORROW 487 -#define _LOAD_CONST_UNDER_INLINE 488 -#define _LOAD_CONST_UNDER_INLINE_BORROW 489 +#define _LOAD_CONST_INLINE 487 +#define _LOAD_CONST_INLINE_BORROW 488 +#define _LOAD_CONST_UNDER_INLINE 489 +#define _LOAD_CONST_UNDER_INLINE_BORROW 490 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 490 -#define _LOAD_FAST_0 491 -#define _LOAD_FAST_1 492 -#define _LOAD_FAST_2 493 -#define _LOAD_FAST_3 494 -#define _LOAD_FAST_4 495 -#define _LOAD_FAST_5 496 -#define _LOAD_FAST_6 497 -#define _LOAD_FAST_7 498 +#define _LOAD_FAST 491 +#define _LOAD_FAST_0 492 +#define _LOAD_FAST_1 493 +#define _LOAD_FAST_2 494 +#define _LOAD_FAST_3 495 +#define _LOAD_FAST_4 496 +#define _LOAD_FAST_5 497 +#define _LOAD_FAST_6 498 +#define _LOAD_FAST_7 499 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 499 -#define _LOAD_FAST_BORROW_0 500 -#define _LOAD_FAST_BORROW_1 501 -#define _LOAD_FAST_BORROW_2 502 -#define _LOAD_FAST_BORROW_3 503 -#define _LOAD_FAST_BORROW_4 504 -#define _LOAD_FAST_BORROW_5 505 -#define _LOAD_FAST_BORROW_6 506 -#define _LOAD_FAST_BORROW_7 507 +#define _LOAD_FAST_BORROW 500 +#define _LOAD_FAST_BORROW_0 501 +#define _LOAD_FAST_BORROW_1 502 +#define _LOAD_FAST_BORROW_2 503 +#define _LOAD_FAST_BORROW_3 504 +#define _LOAD_FAST_BORROW_4 505 +#define _LOAD_FAST_BORROW_5 506 +#define _LOAD_FAST_BORROW_6 507 +#define _LOAD_FAST_BORROW_7 508 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 508 -#define _LOAD_GLOBAL_BUILTINS 509 -#define _LOAD_GLOBAL_MODULE 510 +#define _LOAD_GLOBAL 509 +#define _LOAD_GLOBAL_BUILTINS 510 +#define _LOAD_GLOBAL_MODULE 511 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 511 -#define _LOAD_SMALL_INT_0 512 -#define _LOAD_SMALL_INT_1 513 -#define _LOAD_SMALL_INT_2 514 -#define _LOAD_SMALL_INT_3 515 -#define _LOAD_SPECIAL 516 +#define _LOAD_SMALL_INT 512 +#define _LOAD_SMALL_INT_0 513 +#define _LOAD_SMALL_INT_1 514 +#define _LOAD_SMALL_INT_2 515 +#define _LOAD_SMALL_INT_3 516 +#define _LOAD_SPECIAL 517 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _LOCK_OBJECT 517 -#define _MAKE_CALLARGS_A_TUPLE 518 +#define _LOCK_OBJECT 518 +#define _MAKE_CALLARGS_A_TUPLE 519 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_HEAP_SAFE 519 -#define _MAKE_WARM 520 +#define _MAKE_HEAP_SAFE 520 +#define _MAKE_WARM 521 #define _MAP_ADD MAP_ADD -#define _MATCH_CLASS 521 +#define _MATCH_CLASS 522 #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 522 -#define _MAYBE_EXPAND_METHOD_KW 523 -#define _MONITOR_CALL 524 -#define _MONITOR_CALL_KW 525 -#define _MONITOR_JUMP_BACKWARD 526 -#define _MONITOR_RESUME 527 +#define _MAYBE_EXPAND_METHOD 523 +#define _MAYBE_EXPAND_METHOD_KW 524 +#define _MONITOR_CALL 525 +#define _MONITOR_CALL_KW 526 +#define _MONITOR_JUMP_BACKWARD 527 +#define _MONITOR_RESUME 528 #define _NOP NOP -#define _POP_CALL 528 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 529 -#define _POP_CALL_ONE 530 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 531 -#define _POP_CALL_TWO 532 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 533 +#define _POP_CALL 529 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 530 +#define _POP_CALL_ONE 531 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 532 +#define _POP_CALL_TWO 533 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 534 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 534 -#define _POP_JUMP_IF_TRUE 535 +#define _POP_JUMP_IF_FALSE 535 +#define _POP_JUMP_IF_TRUE 536 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 536 -#define _POP_TOP_INT 537 -#define _POP_TOP_LOAD_CONST_INLINE 538 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 539 -#define _POP_TOP_NOP 540 -#define _POP_TOP_UNICODE 541 -#define _POP_TWO 542 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 543 +#define _POP_TOP_FLOAT 537 +#define _POP_TOP_INT 538 +#define _POP_TOP_LOAD_CONST_INLINE 539 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 540 +#define _POP_TOP_NOP 541 +#define _POP_TOP_UNICODE 542 +#define _POP_TWO 543 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 544 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 544 +#define _PUSH_FRAME 545 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 545 -#define _PY_FRAME_EX 546 -#define _PY_FRAME_GENERAL 547 -#define _PY_FRAME_KW 548 -#define _QUICKEN_RESUME 549 -#define _RECORD_4OS 550 -#define _RECORD_BOUND_METHOD 551 -#define _RECORD_CALLABLE 552 -#define _RECORD_CODE 553 -#define _RECORD_NOS 554 -#define _RECORD_NOS_GEN_FUNC 555 -#define _RECORD_TOS 556 -#define _RECORD_TOS_TYPE 557 -#define _REPLACE_WITH_TRUE 558 +#define _PUSH_NULL_CONDITIONAL 546 +#define _PY_FRAME_EX 547 +#define _PY_FRAME_GENERAL 548 +#define _PY_FRAME_KW 549 +#define _QUICKEN_RESUME 550 +#define _RECORD_4OS 551 +#define _RECORD_BOUND_METHOD 552 +#define _RECORD_CALLABLE 553 +#define _RECORD_CODE 554 +#define _RECORD_NOS 555 +#define _RECORD_NOS_GEN_FUNC 556 +#define _RECORD_TOS 557 +#define _RECORD_TOS_TYPE 558 +#define _REPLACE_WITH_TRUE 559 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE 559 -#define _SAVE_RETURN_OFFSET 560 -#define _SEND 561 -#define _SEND_GEN_FRAME 562 +#define _RETURN_VALUE 560 +#define _SAVE_RETURN_OFFSET 561 +#define _SEND 562 +#define _SEND_GEN_FRAME 563 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 563 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 564 -#define _SPILL_OR_RELOAD 565 -#define _START_EXECUTOR 566 -#define _STORE_ATTR 567 -#define _STORE_ATTR_INSTANCE_VALUE 568 -#define _STORE_ATTR_SLOT 569 -#define _STORE_ATTR_WITH_HINT 570 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW 564 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 565 +#define _SPILL_OR_RELOAD 566 +#define _START_EXECUTOR 567 +#define _STORE_ATTR 568 +#define _STORE_ATTR_INSTANCE_VALUE 569 +#define _STORE_ATTR_SLOT 570 +#define _STORE_ATTR_WITH_HINT 571 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 571 -#define _STORE_SUBSCR 572 -#define _STORE_SUBSCR_DICT 573 -#define _STORE_SUBSCR_LIST_INT 574 -#define _SWAP 575 -#define _SWAP_2 576 -#define _SWAP_3 577 -#define _SWAP_FAST 578 -#define _SWAP_FAST_0 579 -#define _SWAP_FAST_1 580 -#define _SWAP_FAST_2 581 -#define _SWAP_FAST_3 582 -#define _SWAP_FAST_4 583 -#define _SWAP_FAST_5 584 -#define _SWAP_FAST_6 585 -#define _SWAP_FAST_7 586 -#define _TIER2_RESUME_CHECK 587 -#define _TO_BOOL 588 +#define _STORE_SLICE 572 +#define _STORE_SUBSCR 573 +#define _STORE_SUBSCR_DICT 574 +#define _STORE_SUBSCR_LIST_INT 575 +#define _SWAP 576 +#define _SWAP_2 577 +#define _SWAP_3 578 +#define _SWAP_FAST 579 +#define _SWAP_FAST_0 580 +#define _SWAP_FAST_1 581 +#define _SWAP_FAST_2 582 +#define _SWAP_FAST_3 583 +#define _SWAP_FAST_4 584 +#define _SWAP_FAST_5 585 +#define _SWAP_FAST_6 586 +#define _SWAP_FAST_7 587 +#define _TIER2_RESUME_CHECK 588 +#define _TO_BOOL 589 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 589 -#define _TO_BOOL_LIST 590 +#define _TO_BOOL_INT 590 +#define _TO_BOOL_LIST 591 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 591 +#define _TO_BOOL_STR 592 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 592 -#define _UNARY_NEGATIVE 593 +#define _UNARY_INVERT 593 +#define _UNARY_NEGATIVE 594 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 594 -#define _UNPACK_SEQUENCE_LIST 595 -#define _UNPACK_SEQUENCE_TUPLE 596 -#define _UNPACK_SEQUENCE_TWO_TUPLE 597 +#define _UNPACK_SEQUENCE 595 +#define _UNPACK_SEQUENCE_LIST 596 +#define _UNPACK_SEQUENCE_TUPLE 597 +#define _UNPACK_SEQUENCE_TWO_TUPLE 598 #define _WITH_EXCEPT_START WITH_EXCEPT_START -#define _YIELD_VALUE 598 -#define MAX_UOP_ID 598 -#define _BINARY_OP_r23 599 -#define _BINARY_OP_ADD_FLOAT_r03 600 -#define _BINARY_OP_ADD_FLOAT_r13 601 -#define _BINARY_OP_ADD_FLOAT_r23 602 -#define _BINARY_OP_ADD_INT_r03 603 -#define _BINARY_OP_ADD_INT_r13 604 -#define _BINARY_OP_ADD_INT_r23 605 -#define _BINARY_OP_ADD_UNICODE_r03 606 -#define _BINARY_OP_ADD_UNICODE_r13 607 -#define _BINARY_OP_ADD_UNICODE_r23 608 -#define _BINARY_OP_EXTEND_r23 609 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 610 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 611 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 612 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 613 -#define _BINARY_OP_MULTIPLY_INT_r03 614 -#define _BINARY_OP_MULTIPLY_INT_r13 615 -#define _BINARY_OP_MULTIPLY_INT_r23 616 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 617 -#define _BINARY_OP_SUBSCR_DICT_r23 618 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 619 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 620 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 621 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 622 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 623 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 624 -#define _BINARY_OP_SUBSCR_STR_INT_r23 625 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 626 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 627 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 628 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 629 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 630 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 631 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 632 -#define _BINARY_OP_SUBTRACT_INT_r03 633 -#define _BINARY_OP_SUBTRACT_INT_r13 634 -#define _BINARY_OP_SUBTRACT_INT_r23 635 -#define _BINARY_SLICE_r31 636 -#define _BUILD_INTERPOLATION_r01 637 -#define _BUILD_LIST_r01 638 -#define _BUILD_MAP_r01 639 -#define _BUILD_SET_r01 640 -#define _BUILD_SLICE_r01 641 -#define _BUILD_STRING_r01 642 -#define _BUILD_TEMPLATE_r21 643 -#define _BUILD_TUPLE_r01 644 -#define _CALL_BUILTIN_CLASS_r01 645 -#define _CALL_BUILTIN_FAST_r01 646 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 647 -#define _CALL_BUILTIN_O_r03 648 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 649 -#define _CALL_INTRINSIC_1_r11 650 -#define _CALL_INTRINSIC_2_r21 651 -#define _CALL_ISINSTANCE_r31 652 -#define _CALL_KW_NON_PY_r11 653 -#define _CALL_LEN_r33 654 -#define _CALL_LIST_APPEND_r03 655 -#define _CALL_LIST_APPEND_r13 656 -#define _CALL_LIST_APPEND_r23 657 -#define _CALL_LIST_APPEND_r33 658 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 659 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 660 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 661 -#define _CALL_METHOD_DESCRIPTOR_O_r03 662 -#define _CALL_NON_PY_GENERAL_r01 663 -#define _CALL_STR_1_r32 664 -#define _CALL_TUPLE_1_r32 665 -#define _CALL_TYPE_1_r02 666 -#define _CALL_TYPE_1_r12 667 -#define _CALL_TYPE_1_r22 668 -#define _CALL_TYPE_1_r32 669 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 670 -#define _CHECK_ATTR_CLASS_r01 671 -#define _CHECK_ATTR_CLASS_r11 672 -#define _CHECK_ATTR_CLASS_r22 673 -#define _CHECK_ATTR_CLASS_r33 674 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 675 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 676 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 677 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 678 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 679 -#define _CHECK_EG_MATCH_r22 680 -#define _CHECK_EXC_MATCH_r22 681 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 682 -#define _CHECK_FUNCTION_VERSION_r00 683 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 684 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 685 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 686 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 687 -#define _CHECK_FUNCTION_VERSION_KW_r11 688 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 689 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 690 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 691 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 692 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 693 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 694 -#define _CHECK_IS_PY_CALLABLE_EX_r03 695 -#define _CHECK_IS_PY_CALLABLE_EX_r13 696 -#define _CHECK_IS_PY_CALLABLE_EX_r23 697 -#define _CHECK_IS_PY_CALLABLE_EX_r33 698 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 699 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 700 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 701 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 702 -#define _CHECK_METHOD_VERSION_r00 703 -#define _CHECK_METHOD_VERSION_KW_r11 704 -#define _CHECK_PEP_523_r00 705 -#define _CHECK_PEP_523_r11 706 -#define _CHECK_PEP_523_r22 707 -#define _CHECK_PEP_523_r33 708 -#define _CHECK_PERIODIC_r00 709 -#define _CHECK_PERIODIC_AT_END_r00 710 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 711 -#define _CHECK_RECURSION_REMAINING_r00 712 -#define _CHECK_RECURSION_REMAINING_r11 713 -#define _CHECK_RECURSION_REMAINING_r22 714 -#define _CHECK_RECURSION_REMAINING_r33 715 -#define _CHECK_STACK_SPACE_r00 716 -#define _CHECK_STACK_SPACE_OPERAND_r00 717 -#define _CHECK_STACK_SPACE_OPERAND_r11 718 -#define _CHECK_STACK_SPACE_OPERAND_r22 719 -#define _CHECK_STACK_SPACE_OPERAND_r33 720 -#define _CHECK_VALIDITY_r00 721 -#define _CHECK_VALIDITY_r11 722 -#define _CHECK_VALIDITY_r22 723 -#define _CHECK_VALIDITY_r33 724 -#define _COLD_DYNAMIC_EXIT_r00 725 -#define _COLD_EXIT_r00 726 -#define _COMPARE_OP_r21 727 -#define _COMPARE_OP_FLOAT_r03 728 -#define _COMPARE_OP_FLOAT_r13 729 -#define _COMPARE_OP_FLOAT_r23 730 -#define _COMPARE_OP_INT_r23 731 -#define _COMPARE_OP_STR_r23 732 -#define _CONTAINS_OP_r23 733 -#define _CONTAINS_OP_DICT_r23 734 -#define _CONTAINS_OP_SET_r23 735 -#define _CONVERT_VALUE_r11 736 -#define _COPY_r01 737 -#define _COPY_1_r02 738 -#define _COPY_1_r12 739 -#define _COPY_1_r23 740 -#define _COPY_2_r03 741 -#define _COPY_2_r13 742 -#define _COPY_2_r23 743 -#define _COPY_3_r03 744 -#define _COPY_3_r13 745 -#define _COPY_3_r23 746 -#define _COPY_3_r33 747 -#define _COPY_FREE_VARS_r00 748 -#define _COPY_FREE_VARS_r11 749 -#define _COPY_FREE_VARS_r22 750 -#define _COPY_FREE_VARS_r33 751 -#define _CREATE_INIT_FRAME_r01 752 -#define _DELETE_ATTR_r10 753 -#define _DELETE_DEREF_r00 754 -#define _DELETE_FAST_r00 755 -#define _DELETE_GLOBAL_r00 756 -#define _DELETE_NAME_r00 757 -#define _DELETE_SUBSCR_r20 758 -#define _DEOPT_r00 759 -#define _DEOPT_r10 760 -#define _DEOPT_r20 761 -#define _DEOPT_r30 762 -#define _DICT_MERGE_r10 763 -#define _DICT_UPDATE_r10 764 -#define _DO_CALL_r01 765 -#define _DO_CALL_FUNCTION_EX_r31 766 -#define _DO_CALL_KW_r11 767 -#define _DYNAMIC_EXIT_r00 768 -#define _DYNAMIC_EXIT_r10 769 -#define _DYNAMIC_EXIT_r20 770 -#define _DYNAMIC_EXIT_r30 771 -#define _END_FOR_r10 772 -#define _END_SEND_r21 773 -#define _ERROR_POP_N_r00 774 -#define _EXIT_INIT_CHECK_r10 775 -#define _EXIT_TRACE_r00 776 -#define _EXIT_TRACE_r10 777 -#define _EXIT_TRACE_r20 778 -#define _EXIT_TRACE_r30 779 -#define _EXPAND_METHOD_r00 780 -#define _EXPAND_METHOD_KW_r11 781 -#define _FATAL_ERROR_r00 782 -#define _FATAL_ERROR_r11 783 -#define _FATAL_ERROR_r22 784 -#define _FATAL_ERROR_r33 785 -#define _FORMAT_SIMPLE_r11 786 -#define _FORMAT_WITH_SPEC_r21 787 -#define _FOR_ITER_r23 788 -#define _FOR_ITER_GEN_FRAME_r03 789 -#define _FOR_ITER_GEN_FRAME_r13 790 -#define _FOR_ITER_GEN_FRAME_r23 791 -#define _FOR_ITER_TIER_TWO_r23 792 -#define _GET_AITER_r11 793 -#define _GET_ANEXT_r12 794 -#define _GET_AWAITABLE_r11 795 -#define _GET_ITER_r12 796 -#define _GET_LEN_r12 797 -#define _GET_YIELD_FROM_ITER_r11 798 -#define _GUARD_BINARY_OP_EXTEND_r22 799 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 800 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 801 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 802 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 803 -#define _GUARD_BIT_IS_SET_POP_r00 804 -#define _GUARD_BIT_IS_SET_POP_r10 805 -#define _GUARD_BIT_IS_SET_POP_r21 806 -#define _GUARD_BIT_IS_SET_POP_r32 807 -#define _GUARD_BIT_IS_SET_POP_4_r00 808 -#define _GUARD_BIT_IS_SET_POP_4_r10 809 -#define _GUARD_BIT_IS_SET_POP_4_r21 810 -#define _GUARD_BIT_IS_SET_POP_4_r32 811 -#define _GUARD_BIT_IS_SET_POP_5_r00 812 -#define _GUARD_BIT_IS_SET_POP_5_r10 813 -#define _GUARD_BIT_IS_SET_POP_5_r21 814 -#define _GUARD_BIT_IS_SET_POP_5_r32 815 -#define _GUARD_BIT_IS_SET_POP_6_r00 816 -#define _GUARD_BIT_IS_SET_POP_6_r10 817 -#define _GUARD_BIT_IS_SET_POP_6_r21 818 -#define _GUARD_BIT_IS_SET_POP_6_r32 819 -#define _GUARD_BIT_IS_SET_POP_7_r00 820 -#define _GUARD_BIT_IS_SET_POP_7_r10 821 -#define _GUARD_BIT_IS_SET_POP_7_r21 822 -#define _GUARD_BIT_IS_SET_POP_7_r32 823 -#define _GUARD_BIT_IS_UNSET_POP_r00 824 -#define _GUARD_BIT_IS_UNSET_POP_r10 825 -#define _GUARD_BIT_IS_UNSET_POP_r21 826 -#define _GUARD_BIT_IS_UNSET_POP_r32 827 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 828 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 829 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 830 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 831 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 832 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 833 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 834 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 835 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 836 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 837 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 838 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 839 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 840 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 841 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 842 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 843 -#define _GUARD_CALLABLE_ISINSTANCE_r03 844 -#define _GUARD_CALLABLE_ISINSTANCE_r13 845 -#define _GUARD_CALLABLE_ISINSTANCE_r23 846 -#define _GUARD_CALLABLE_ISINSTANCE_r33 847 -#define _GUARD_CALLABLE_LEN_r03 848 -#define _GUARD_CALLABLE_LEN_r13 849 -#define _GUARD_CALLABLE_LEN_r23 850 -#define _GUARD_CALLABLE_LEN_r33 851 -#define _GUARD_CALLABLE_LIST_APPEND_r03 852 -#define _GUARD_CALLABLE_LIST_APPEND_r13 853 -#define _GUARD_CALLABLE_LIST_APPEND_r23 854 -#define _GUARD_CALLABLE_LIST_APPEND_r33 855 -#define _GUARD_CALLABLE_STR_1_r03 856 -#define _GUARD_CALLABLE_STR_1_r13 857 -#define _GUARD_CALLABLE_STR_1_r23 858 -#define _GUARD_CALLABLE_STR_1_r33 859 -#define _GUARD_CALLABLE_TUPLE_1_r03 860 -#define _GUARD_CALLABLE_TUPLE_1_r13 861 -#define _GUARD_CALLABLE_TUPLE_1_r23 862 -#define _GUARD_CALLABLE_TUPLE_1_r33 863 -#define _GUARD_CALLABLE_TYPE_1_r03 864 -#define _GUARD_CALLABLE_TYPE_1_r13 865 -#define _GUARD_CALLABLE_TYPE_1_r23 866 -#define _GUARD_CALLABLE_TYPE_1_r33 867 -#define _GUARD_CODE_VERSION_r00 868 -#define _GUARD_CODE_VERSION_r11 869 -#define _GUARD_CODE_VERSION_r22 870 -#define _GUARD_CODE_VERSION_r33 871 -#define _GUARD_DORV_NO_DICT_r01 872 -#define _GUARD_DORV_NO_DICT_r11 873 -#define _GUARD_DORV_NO_DICT_r22 874 -#define _GUARD_DORV_NO_DICT_r33 875 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 876 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 877 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 878 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 879 -#define _GUARD_GLOBALS_VERSION_r00 880 -#define _GUARD_GLOBALS_VERSION_r11 881 -#define _GUARD_GLOBALS_VERSION_r22 882 -#define _GUARD_GLOBALS_VERSION_r33 883 -#define _GUARD_IP_RETURN_GENERATOR_r00 884 -#define _GUARD_IP_RETURN_GENERATOR_r11 885 -#define _GUARD_IP_RETURN_GENERATOR_r22 886 -#define _GUARD_IP_RETURN_GENERATOR_r33 887 -#define _GUARD_IP_RETURN_VALUE_r00 888 -#define _GUARD_IP_RETURN_VALUE_r11 889 -#define _GUARD_IP_RETURN_VALUE_r22 890 -#define _GUARD_IP_RETURN_VALUE_r33 891 -#define _GUARD_IP_YIELD_VALUE_r00 892 -#define _GUARD_IP_YIELD_VALUE_r11 893 -#define _GUARD_IP_YIELD_VALUE_r22 894 -#define _GUARD_IP_YIELD_VALUE_r33 895 -#define _GUARD_IP__PUSH_FRAME_r00 896 -#define _GUARD_IP__PUSH_FRAME_r11 897 -#define _GUARD_IP__PUSH_FRAME_r22 898 -#define _GUARD_IP__PUSH_FRAME_r33 899 -#define _GUARD_IS_FALSE_POP_r00 900 -#define _GUARD_IS_FALSE_POP_r10 901 -#define _GUARD_IS_FALSE_POP_r21 902 -#define _GUARD_IS_FALSE_POP_r32 903 -#define _GUARD_IS_NONE_POP_r00 904 -#define _GUARD_IS_NONE_POP_r10 905 -#define _GUARD_IS_NONE_POP_r21 906 -#define _GUARD_IS_NONE_POP_r32 907 -#define _GUARD_IS_NOT_NONE_POP_r10 908 -#define _GUARD_IS_TRUE_POP_r00 909 -#define _GUARD_IS_TRUE_POP_r10 910 -#define _GUARD_IS_TRUE_POP_r21 911 -#define _GUARD_IS_TRUE_POP_r32 912 -#define _GUARD_KEYS_VERSION_r01 913 -#define _GUARD_KEYS_VERSION_r11 914 -#define _GUARD_KEYS_VERSION_r22 915 -#define _GUARD_KEYS_VERSION_r33 916 -#define _GUARD_NOS_ANY_DICT_r02 917 -#define _GUARD_NOS_ANY_DICT_r12 918 -#define _GUARD_NOS_ANY_DICT_r22 919 -#define _GUARD_NOS_ANY_DICT_r33 920 -#define _GUARD_NOS_COMPACT_ASCII_r02 921 -#define _GUARD_NOS_COMPACT_ASCII_r12 922 -#define _GUARD_NOS_COMPACT_ASCII_r22 923 -#define _GUARD_NOS_COMPACT_ASCII_r33 924 -#define _GUARD_NOS_DICT_r02 925 -#define _GUARD_NOS_DICT_r12 926 -#define _GUARD_NOS_DICT_r22 927 -#define _GUARD_NOS_DICT_r33 928 -#define _GUARD_NOS_FLOAT_r02 929 -#define _GUARD_NOS_FLOAT_r12 930 -#define _GUARD_NOS_FLOAT_r22 931 -#define _GUARD_NOS_FLOAT_r33 932 -#define _GUARD_NOS_INT_r02 933 -#define _GUARD_NOS_INT_r12 934 -#define _GUARD_NOS_INT_r22 935 -#define _GUARD_NOS_INT_r33 936 -#define _GUARD_NOS_LIST_r02 937 -#define _GUARD_NOS_LIST_r12 938 -#define _GUARD_NOS_LIST_r22 939 -#define _GUARD_NOS_LIST_r33 940 -#define _GUARD_NOS_NOT_NULL_r02 941 -#define _GUARD_NOS_NOT_NULL_r12 942 -#define _GUARD_NOS_NOT_NULL_r22 943 -#define _GUARD_NOS_NOT_NULL_r33 944 -#define _GUARD_NOS_NULL_r02 945 -#define _GUARD_NOS_NULL_r12 946 -#define _GUARD_NOS_NULL_r22 947 -#define _GUARD_NOS_NULL_r33 948 -#define _GUARD_NOS_OVERFLOWED_r02 949 -#define _GUARD_NOS_OVERFLOWED_r12 950 -#define _GUARD_NOS_OVERFLOWED_r22 951 -#define _GUARD_NOS_OVERFLOWED_r33 952 -#define _GUARD_NOS_TUPLE_r02 953 -#define _GUARD_NOS_TUPLE_r12 954 -#define _GUARD_NOS_TUPLE_r22 955 -#define _GUARD_NOS_TUPLE_r33 956 -#define _GUARD_NOS_UNICODE_r02 957 -#define _GUARD_NOS_UNICODE_r12 958 -#define _GUARD_NOS_UNICODE_r22 959 -#define _GUARD_NOS_UNICODE_r33 960 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 961 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 962 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 963 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 964 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 965 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 966 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 967 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 968 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 969 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 970 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 971 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 972 -#define _GUARD_THIRD_NULL_r03 973 -#define _GUARD_THIRD_NULL_r13 974 -#define _GUARD_THIRD_NULL_r23 975 -#define _GUARD_THIRD_NULL_r33 976 -#define _GUARD_TOS_ANY_DICT_r01 977 -#define _GUARD_TOS_ANY_DICT_r11 978 -#define _GUARD_TOS_ANY_DICT_r22 979 -#define _GUARD_TOS_ANY_DICT_r33 980 -#define _GUARD_TOS_ANY_SET_r01 981 -#define _GUARD_TOS_ANY_SET_r11 982 -#define _GUARD_TOS_ANY_SET_r22 983 -#define _GUARD_TOS_ANY_SET_r33 984 -#define _GUARD_TOS_DICT_r01 985 -#define _GUARD_TOS_DICT_r11 986 -#define _GUARD_TOS_DICT_r22 987 -#define _GUARD_TOS_DICT_r33 988 -#define _GUARD_TOS_FLOAT_r01 989 -#define _GUARD_TOS_FLOAT_r11 990 -#define _GUARD_TOS_FLOAT_r22 991 -#define _GUARD_TOS_FLOAT_r33 992 -#define _GUARD_TOS_FROZENDICT_r01 993 -#define _GUARD_TOS_FROZENDICT_r11 994 -#define _GUARD_TOS_FROZENDICT_r22 995 -#define _GUARD_TOS_FROZENDICT_r33 996 -#define _GUARD_TOS_FROZENSET_r01 997 -#define _GUARD_TOS_FROZENSET_r11 998 -#define _GUARD_TOS_FROZENSET_r22 999 -#define _GUARD_TOS_FROZENSET_r33 1000 -#define _GUARD_TOS_INT_r01 1001 -#define _GUARD_TOS_INT_r11 1002 -#define _GUARD_TOS_INT_r22 1003 -#define _GUARD_TOS_INT_r33 1004 -#define _GUARD_TOS_LIST_r01 1005 -#define _GUARD_TOS_LIST_r11 1006 -#define _GUARD_TOS_LIST_r22 1007 -#define _GUARD_TOS_LIST_r33 1008 -#define _GUARD_TOS_OVERFLOWED_r01 1009 -#define _GUARD_TOS_OVERFLOWED_r11 1010 -#define _GUARD_TOS_OVERFLOWED_r22 1011 -#define _GUARD_TOS_OVERFLOWED_r33 1012 -#define _GUARD_TOS_SET_r01 1013 -#define _GUARD_TOS_SET_r11 1014 -#define _GUARD_TOS_SET_r22 1015 -#define _GUARD_TOS_SET_r33 1016 -#define _GUARD_TOS_SLICE_r01 1017 -#define _GUARD_TOS_SLICE_r11 1018 -#define _GUARD_TOS_SLICE_r22 1019 -#define _GUARD_TOS_SLICE_r33 1020 -#define _GUARD_TOS_TUPLE_r01 1021 -#define _GUARD_TOS_TUPLE_r11 1022 -#define _GUARD_TOS_TUPLE_r22 1023 -#define _GUARD_TOS_TUPLE_r33 1024 -#define _GUARD_TOS_UNICODE_r01 1025 -#define _GUARD_TOS_UNICODE_r11 1026 -#define _GUARD_TOS_UNICODE_r22 1027 -#define _GUARD_TOS_UNICODE_r33 1028 -#define _GUARD_TYPE_VERSION_r01 1029 -#define _GUARD_TYPE_VERSION_r11 1030 -#define _GUARD_TYPE_VERSION_r22 1031 -#define _GUARD_TYPE_VERSION_r33 1032 -#define _GUARD_TYPE_VERSION_LOCKED_r01 1033 -#define _GUARD_TYPE_VERSION_LOCKED_r11 1034 -#define _GUARD_TYPE_VERSION_LOCKED_r22 1035 -#define _GUARD_TYPE_VERSION_LOCKED_r33 1036 -#define _HANDLE_PENDING_AND_DEOPT_r00 1037 -#define _HANDLE_PENDING_AND_DEOPT_r10 1038 -#define _HANDLE_PENDING_AND_DEOPT_r20 1039 -#define _HANDLE_PENDING_AND_DEOPT_r30 1040 -#define _IMPORT_FROM_r12 1041 -#define _IMPORT_NAME_r21 1042 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1043 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1044 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1045 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1046 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1047 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1048 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1049 -#define _INSERT_1_LOAD_CONST_INLINE_r02 1050 -#define _INSERT_1_LOAD_CONST_INLINE_r12 1051 -#define _INSERT_1_LOAD_CONST_INLINE_r23 1052 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1053 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1054 -#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1055 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1056 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1057 -#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1058 -#define _INSERT_NULL_r10 1059 -#define _INSTRUMENTED_FOR_ITER_r23 1060 -#define _INSTRUMENTED_INSTRUCTION_r00 1061 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1062 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1063 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1064 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1065 -#define _INSTRUMENTED_LINE_r00 1066 -#define _INSTRUMENTED_NOT_TAKEN_r00 1067 -#define _INSTRUMENTED_NOT_TAKEN_r11 1068 -#define _INSTRUMENTED_NOT_TAKEN_r22 1069 -#define _INSTRUMENTED_NOT_TAKEN_r33 1070 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1071 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1072 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1073 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1074 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1075 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1076 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1077 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1078 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1079 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1080 -#define _IS_NONE_r11 1081 -#define _IS_OP_r03 1082 -#define _IS_OP_r13 1083 -#define _IS_OP_r23 1084 -#define _ITER_CHECK_LIST_r02 1085 -#define _ITER_CHECK_LIST_r12 1086 -#define _ITER_CHECK_LIST_r22 1087 -#define _ITER_CHECK_LIST_r33 1088 -#define _ITER_CHECK_RANGE_r02 1089 -#define _ITER_CHECK_RANGE_r12 1090 -#define _ITER_CHECK_RANGE_r22 1091 -#define _ITER_CHECK_RANGE_r33 1092 -#define _ITER_CHECK_TUPLE_r02 1093 -#define _ITER_CHECK_TUPLE_r12 1094 -#define _ITER_CHECK_TUPLE_r22 1095 -#define _ITER_CHECK_TUPLE_r33 1096 -#define _ITER_JUMP_LIST_r02 1097 -#define _ITER_JUMP_LIST_r12 1098 -#define _ITER_JUMP_LIST_r22 1099 -#define _ITER_JUMP_LIST_r33 1100 -#define _ITER_JUMP_RANGE_r02 1101 -#define _ITER_JUMP_RANGE_r12 1102 -#define _ITER_JUMP_RANGE_r22 1103 -#define _ITER_JUMP_RANGE_r33 1104 -#define _ITER_JUMP_TUPLE_r02 1105 -#define _ITER_JUMP_TUPLE_r12 1106 -#define _ITER_JUMP_TUPLE_r22 1107 -#define _ITER_JUMP_TUPLE_r33 1108 -#define _ITER_NEXT_LIST_r23 1109 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1110 -#define _ITER_NEXT_RANGE_r03 1111 -#define _ITER_NEXT_RANGE_r13 1112 -#define _ITER_NEXT_RANGE_r23 1113 -#define _ITER_NEXT_TUPLE_r03 1114 -#define _ITER_NEXT_TUPLE_r13 1115 -#define _ITER_NEXT_TUPLE_r23 1116 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1117 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1118 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1119 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1120 -#define _JUMP_TO_TOP_r00 1121 -#define _LIST_APPEND_r10 1122 -#define _LIST_EXTEND_r10 1123 -#define _LOAD_ATTR_r10 1124 -#define _LOAD_ATTR_CLASS_r11 1125 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1126 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1127 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1128 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1129 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1130 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1131 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1132 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1133 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1134 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1135 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1136 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1137 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1138 -#define _LOAD_ATTR_MODULE_r12 1139 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1140 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1141 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1142 -#define _LOAD_ATTR_SLOT_r02 1143 -#define _LOAD_ATTR_SLOT_r12 1144 -#define _LOAD_ATTR_SLOT_r23 1145 -#define _LOAD_ATTR_WITH_HINT_r12 1146 -#define _LOAD_BUILD_CLASS_r01 1147 -#define _LOAD_BYTECODE_r00 1148 -#define _LOAD_COMMON_CONSTANT_r01 1149 -#define _LOAD_COMMON_CONSTANT_r12 1150 -#define _LOAD_COMMON_CONSTANT_r23 1151 -#define _LOAD_CONST_r01 1152 -#define _LOAD_CONST_r12 1153 -#define _LOAD_CONST_r23 1154 -#define _LOAD_CONST_INLINE_r01 1155 -#define _LOAD_CONST_INLINE_r12 1156 -#define _LOAD_CONST_INLINE_r23 1157 -#define _LOAD_CONST_INLINE_BORROW_r01 1158 -#define _LOAD_CONST_INLINE_BORROW_r12 1159 -#define _LOAD_CONST_INLINE_BORROW_r23 1160 -#define _LOAD_CONST_UNDER_INLINE_r02 1161 -#define _LOAD_CONST_UNDER_INLINE_r12 1162 -#define _LOAD_CONST_UNDER_INLINE_r23 1163 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1164 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1165 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1166 -#define _LOAD_DEREF_r01 1167 -#define _LOAD_FAST_r01 1168 -#define _LOAD_FAST_r12 1169 -#define _LOAD_FAST_r23 1170 -#define _LOAD_FAST_0_r01 1171 -#define _LOAD_FAST_0_r12 1172 -#define _LOAD_FAST_0_r23 1173 -#define _LOAD_FAST_1_r01 1174 -#define _LOAD_FAST_1_r12 1175 -#define _LOAD_FAST_1_r23 1176 -#define _LOAD_FAST_2_r01 1177 -#define _LOAD_FAST_2_r12 1178 -#define _LOAD_FAST_2_r23 1179 -#define _LOAD_FAST_3_r01 1180 -#define _LOAD_FAST_3_r12 1181 -#define _LOAD_FAST_3_r23 1182 -#define _LOAD_FAST_4_r01 1183 -#define _LOAD_FAST_4_r12 1184 -#define _LOAD_FAST_4_r23 1185 -#define _LOAD_FAST_5_r01 1186 -#define _LOAD_FAST_5_r12 1187 -#define _LOAD_FAST_5_r23 1188 -#define _LOAD_FAST_6_r01 1189 -#define _LOAD_FAST_6_r12 1190 -#define _LOAD_FAST_6_r23 1191 -#define _LOAD_FAST_7_r01 1192 -#define _LOAD_FAST_7_r12 1193 -#define _LOAD_FAST_7_r23 1194 -#define _LOAD_FAST_AND_CLEAR_r01 1195 -#define _LOAD_FAST_AND_CLEAR_r12 1196 -#define _LOAD_FAST_AND_CLEAR_r23 1197 -#define _LOAD_FAST_BORROW_r01 1198 -#define _LOAD_FAST_BORROW_r12 1199 -#define _LOAD_FAST_BORROW_r23 1200 -#define _LOAD_FAST_BORROW_0_r01 1201 -#define _LOAD_FAST_BORROW_0_r12 1202 -#define _LOAD_FAST_BORROW_0_r23 1203 -#define _LOAD_FAST_BORROW_1_r01 1204 -#define _LOAD_FAST_BORROW_1_r12 1205 -#define _LOAD_FAST_BORROW_1_r23 1206 -#define _LOAD_FAST_BORROW_2_r01 1207 -#define _LOAD_FAST_BORROW_2_r12 1208 -#define _LOAD_FAST_BORROW_2_r23 1209 -#define _LOAD_FAST_BORROW_3_r01 1210 -#define _LOAD_FAST_BORROW_3_r12 1211 -#define _LOAD_FAST_BORROW_3_r23 1212 -#define _LOAD_FAST_BORROW_4_r01 1213 -#define _LOAD_FAST_BORROW_4_r12 1214 -#define _LOAD_FAST_BORROW_4_r23 1215 -#define _LOAD_FAST_BORROW_5_r01 1216 -#define _LOAD_FAST_BORROW_5_r12 1217 -#define _LOAD_FAST_BORROW_5_r23 1218 -#define _LOAD_FAST_BORROW_6_r01 1219 -#define _LOAD_FAST_BORROW_6_r12 1220 -#define _LOAD_FAST_BORROW_6_r23 1221 -#define _LOAD_FAST_BORROW_7_r01 1222 -#define _LOAD_FAST_BORROW_7_r12 1223 -#define _LOAD_FAST_BORROW_7_r23 1224 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1225 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1226 -#define _LOAD_FAST_CHECK_r01 1227 -#define _LOAD_FAST_CHECK_r12 1228 -#define _LOAD_FAST_CHECK_r23 1229 -#define _LOAD_FAST_LOAD_FAST_r02 1230 -#define _LOAD_FAST_LOAD_FAST_r13 1231 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1232 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1233 -#define _LOAD_GLOBAL_r00 1234 -#define _LOAD_GLOBAL_BUILTINS_r01 1235 -#define _LOAD_GLOBAL_MODULE_r01 1236 -#define _LOAD_LOCALS_r01 1237 -#define _LOAD_LOCALS_r12 1238 -#define _LOAD_LOCALS_r23 1239 -#define _LOAD_NAME_r01 1240 -#define _LOAD_SMALL_INT_r01 1241 -#define _LOAD_SMALL_INT_r12 1242 -#define _LOAD_SMALL_INT_r23 1243 -#define _LOAD_SMALL_INT_0_r01 1244 -#define _LOAD_SMALL_INT_0_r12 1245 -#define _LOAD_SMALL_INT_0_r23 1246 -#define _LOAD_SMALL_INT_1_r01 1247 -#define _LOAD_SMALL_INT_1_r12 1248 -#define _LOAD_SMALL_INT_1_r23 1249 -#define _LOAD_SMALL_INT_2_r01 1250 -#define _LOAD_SMALL_INT_2_r12 1251 -#define _LOAD_SMALL_INT_2_r23 1252 -#define _LOAD_SMALL_INT_3_r01 1253 -#define _LOAD_SMALL_INT_3_r12 1254 -#define _LOAD_SMALL_INT_3_r23 1255 -#define _LOAD_SPECIAL_r00 1256 -#define _LOAD_SUPER_ATTR_ATTR_r31 1257 -#define _LOAD_SUPER_ATTR_METHOD_r32 1258 -#define _LOCK_OBJECT_r01 1259 -#define _LOCK_OBJECT_r11 1260 -#define _LOCK_OBJECT_r22 1261 -#define _LOCK_OBJECT_r33 1262 -#define _MAKE_CALLARGS_A_TUPLE_r33 1263 -#define _MAKE_CELL_r00 1264 -#define _MAKE_FUNCTION_r11 1265 -#define _MAKE_HEAP_SAFE_r01 1266 -#define _MAKE_HEAP_SAFE_r11 1267 -#define _MAKE_HEAP_SAFE_r22 1268 -#define _MAKE_HEAP_SAFE_r33 1269 -#define _MAKE_WARM_r00 1270 -#define _MAKE_WARM_r11 1271 -#define _MAKE_WARM_r22 1272 -#define _MAKE_WARM_r33 1273 -#define _MAP_ADD_r20 1274 -#define _MATCH_CLASS_r33 1275 -#define _MATCH_KEYS_r23 1276 -#define _MATCH_MAPPING_r02 1277 -#define _MATCH_MAPPING_r12 1278 -#define _MATCH_MAPPING_r23 1279 -#define _MATCH_SEQUENCE_r02 1280 -#define _MATCH_SEQUENCE_r12 1281 -#define _MATCH_SEQUENCE_r23 1282 -#define _MAYBE_EXPAND_METHOD_r00 1283 -#define _MAYBE_EXPAND_METHOD_KW_r11 1284 -#define _MONITOR_CALL_r00 1285 -#define _MONITOR_CALL_KW_r11 1286 -#define _MONITOR_JUMP_BACKWARD_r00 1287 -#define _MONITOR_JUMP_BACKWARD_r11 1288 -#define _MONITOR_JUMP_BACKWARD_r22 1289 -#define _MONITOR_JUMP_BACKWARD_r33 1290 -#define _MONITOR_RESUME_r00 1291 -#define _NOP_r00 1292 -#define _NOP_r11 1293 -#define _NOP_r22 1294 -#define _NOP_r33 1295 -#define _POP_CALL_r20 1296 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1297 -#define _POP_CALL_ONE_r30 1298 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1299 -#define _POP_CALL_TWO_r30 1300 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1301 -#define _POP_EXCEPT_r10 1302 -#define _POP_ITER_r20 1303 -#define _POP_JUMP_IF_FALSE_r00 1304 -#define _POP_JUMP_IF_FALSE_r10 1305 -#define _POP_JUMP_IF_FALSE_r21 1306 -#define _POP_JUMP_IF_FALSE_r32 1307 -#define _POP_JUMP_IF_TRUE_r00 1308 -#define _POP_JUMP_IF_TRUE_r10 1309 -#define _POP_JUMP_IF_TRUE_r21 1310 -#define _POP_JUMP_IF_TRUE_r32 1311 -#define _POP_TOP_r10 1312 -#define _POP_TOP_FLOAT_r00 1313 -#define _POP_TOP_FLOAT_r10 1314 -#define _POP_TOP_FLOAT_r21 1315 -#define _POP_TOP_FLOAT_r32 1316 -#define _POP_TOP_INT_r00 1317 -#define _POP_TOP_INT_r10 1318 -#define _POP_TOP_INT_r21 1319 -#define _POP_TOP_INT_r32 1320 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1321 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1322 -#define _POP_TOP_NOP_r00 1323 -#define _POP_TOP_NOP_r10 1324 -#define _POP_TOP_NOP_r21 1325 -#define _POP_TOP_NOP_r32 1326 -#define _POP_TOP_UNICODE_r00 1327 -#define _POP_TOP_UNICODE_r10 1328 -#define _POP_TOP_UNICODE_r21 1329 -#define _POP_TOP_UNICODE_r32 1330 -#define _POP_TWO_r20 1331 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1332 -#define _PUSH_EXC_INFO_r02 1333 -#define _PUSH_EXC_INFO_r12 1334 -#define _PUSH_EXC_INFO_r23 1335 -#define _PUSH_FRAME_r10 1336 -#define _PUSH_NULL_r01 1337 -#define _PUSH_NULL_r12 1338 -#define _PUSH_NULL_r23 1339 -#define _PUSH_NULL_CONDITIONAL_r00 1340 -#define _PY_FRAME_EX_r31 1341 -#define _PY_FRAME_GENERAL_r01 1342 -#define _PY_FRAME_KW_r11 1343 -#define _QUICKEN_RESUME_r00 1344 -#define _QUICKEN_RESUME_r11 1345 -#define _QUICKEN_RESUME_r22 1346 -#define _QUICKEN_RESUME_r33 1347 -#define _REPLACE_WITH_TRUE_r02 1348 -#define _REPLACE_WITH_TRUE_r12 1349 -#define _REPLACE_WITH_TRUE_r23 1350 -#define _RESUME_CHECK_r00 1351 -#define _RESUME_CHECK_r11 1352 -#define _RESUME_CHECK_r22 1353 -#define _RESUME_CHECK_r33 1354 -#define _RETURN_GENERATOR_r01 1355 -#define _RETURN_VALUE_r11 1356 -#define _SAVE_RETURN_OFFSET_r00 1357 -#define _SAVE_RETURN_OFFSET_r11 1358 -#define _SAVE_RETURN_OFFSET_r22 1359 -#define _SAVE_RETURN_OFFSET_r33 1360 -#define _SEND_r22 1361 -#define _SEND_GEN_FRAME_r22 1362 -#define _SETUP_ANNOTATIONS_r00 1363 -#define _SET_ADD_r10 1364 -#define _SET_FUNCTION_ATTRIBUTE_r01 1365 -#define _SET_FUNCTION_ATTRIBUTE_r11 1366 -#define _SET_FUNCTION_ATTRIBUTE_r21 1367 -#define _SET_FUNCTION_ATTRIBUTE_r32 1368 -#define _SET_IP_r00 1369 -#define _SET_IP_r11 1370 -#define _SET_IP_r22 1371 -#define _SET_IP_r33 1372 -#define _SET_UPDATE_r10 1373 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1374 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1375 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1376 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1377 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1378 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1379 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1380 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1381 -#define _SPILL_OR_RELOAD_r01 1382 -#define _SPILL_OR_RELOAD_r02 1383 -#define _SPILL_OR_RELOAD_r03 1384 -#define _SPILL_OR_RELOAD_r10 1385 -#define _SPILL_OR_RELOAD_r12 1386 -#define _SPILL_OR_RELOAD_r13 1387 -#define _SPILL_OR_RELOAD_r20 1388 -#define _SPILL_OR_RELOAD_r21 1389 -#define _SPILL_OR_RELOAD_r23 1390 -#define _SPILL_OR_RELOAD_r30 1391 -#define _SPILL_OR_RELOAD_r31 1392 -#define _SPILL_OR_RELOAD_r32 1393 -#define _START_EXECUTOR_r00 1394 -#define _STORE_ATTR_r20 1395 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1396 -#define _STORE_ATTR_SLOT_r21 1397 -#define _STORE_ATTR_WITH_HINT_r21 1398 -#define _STORE_DEREF_r10 1399 -#define _STORE_FAST_LOAD_FAST_r11 1400 -#define _STORE_FAST_STORE_FAST_r20 1401 -#define _STORE_GLOBAL_r10 1402 -#define _STORE_NAME_r10 1403 -#define _STORE_SLICE_r30 1404 -#define _STORE_SUBSCR_r30 1405 -#define _STORE_SUBSCR_DICT_r31 1406 -#define _STORE_SUBSCR_LIST_INT_r32 1407 -#define _SWAP_r11 1408 -#define _SWAP_2_r02 1409 -#define _SWAP_2_r12 1410 -#define _SWAP_2_r22 1411 -#define _SWAP_2_r33 1412 -#define _SWAP_3_r03 1413 -#define _SWAP_3_r13 1414 -#define _SWAP_3_r23 1415 -#define _SWAP_3_r33 1416 -#define _SWAP_FAST_r01 1417 -#define _SWAP_FAST_r11 1418 -#define _SWAP_FAST_r22 1419 -#define _SWAP_FAST_r33 1420 -#define _SWAP_FAST_0_r01 1421 -#define _SWAP_FAST_0_r11 1422 -#define _SWAP_FAST_0_r22 1423 -#define _SWAP_FAST_0_r33 1424 -#define _SWAP_FAST_1_r01 1425 -#define _SWAP_FAST_1_r11 1426 -#define _SWAP_FAST_1_r22 1427 -#define _SWAP_FAST_1_r33 1428 -#define _SWAP_FAST_2_r01 1429 -#define _SWAP_FAST_2_r11 1430 -#define _SWAP_FAST_2_r22 1431 -#define _SWAP_FAST_2_r33 1432 -#define _SWAP_FAST_3_r01 1433 -#define _SWAP_FAST_3_r11 1434 -#define _SWAP_FAST_3_r22 1435 -#define _SWAP_FAST_3_r33 1436 -#define _SWAP_FAST_4_r01 1437 -#define _SWAP_FAST_4_r11 1438 -#define _SWAP_FAST_4_r22 1439 -#define _SWAP_FAST_4_r33 1440 -#define _SWAP_FAST_5_r01 1441 -#define _SWAP_FAST_5_r11 1442 -#define _SWAP_FAST_5_r22 1443 -#define _SWAP_FAST_5_r33 1444 -#define _SWAP_FAST_6_r01 1445 -#define _SWAP_FAST_6_r11 1446 -#define _SWAP_FAST_6_r22 1447 -#define _SWAP_FAST_6_r33 1448 -#define _SWAP_FAST_7_r01 1449 -#define _SWAP_FAST_7_r11 1450 -#define _SWAP_FAST_7_r22 1451 -#define _SWAP_FAST_7_r33 1452 -#define _TIER2_RESUME_CHECK_r00 1453 -#define _TIER2_RESUME_CHECK_r11 1454 -#define _TIER2_RESUME_CHECK_r22 1455 -#define _TIER2_RESUME_CHECK_r33 1456 -#define _TO_BOOL_r11 1457 -#define _TO_BOOL_BOOL_r01 1458 -#define _TO_BOOL_BOOL_r11 1459 -#define _TO_BOOL_BOOL_r22 1460 -#define _TO_BOOL_BOOL_r33 1461 -#define _TO_BOOL_INT_r02 1462 -#define _TO_BOOL_INT_r12 1463 -#define _TO_BOOL_INT_r23 1464 -#define _TO_BOOL_LIST_r02 1465 -#define _TO_BOOL_LIST_r12 1466 -#define _TO_BOOL_LIST_r23 1467 -#define _TO_BOOL_NONE_r01 1468 -#define _TO_BOOL_NONE_r11 1469 -#define _TO_BOOL_NONE_r22 1470 -#define _TO_BOOL_NONE_r33 1471 -#define _TO_BOOL_STR_r02 1472 -#define _TO_BOOL_STR_r12 1473 -#define _TO_BOOL_STR_r23 1474 -#define _TRACE_RECORD_r00 1475 -#define _UNARY_INVERT_r12 1476 -#define _UNARY_NEGATIVE_r12 1477 -#define _UNARY_NOT_r01 1478 -#define _UNARY_NOT_r11 1479 -#define _UNARY_NOT_r22 1480 -#define _UNARY_NOT_r33 1481 -#define _UNPACK_EX_r10 1482 -#define _UNPACK_SEQUENCE_r10 1483 -#define _UNPACK_SEQUENCE_LIST_r10 1484 -#define _UNPACK_SEQUENCE_TUPLE_r10 1485 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1486 -#define _WITH_EXCEPT_START_r33 1487 -#define _YIELD_VALUE_r11 1488 -#define MAX_UOP_REGS_ID 1488 +#define _YIELD_VALUE 599 +#define MAX_UOP_ID 599 +#define _BINARY_OP_r23 600 +#define _BINARY_OP_ADD_FLOAT_r03 601 +#define _BINARY_OP_ADD_FLOAT_r13 602 +#define _BINARY_OP_ADD_FLOAT_r23 603 +#define _BINARY_OP_ADD_INT_r03 604 +#define _BINARY_OP_ADD_INT_r13 605 +#define _BINARY_OP_ADD_INT_r23 606 +#define _BINARY_OP_ADD_UNICODE_r03 607 +#define _BINARY_OP_ADD_UNICODE_r13 608 +#define _BINARY_OP_ADD_UNICODE_r23 609 +#define _BINARY_OP_EXTEND_r23 610 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 611 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 612 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 613 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 614 +#define _BINARY_OP_MULTIPLY_INT_r03 615 +#define _BINARY_OP_MULTIPLY_INT_r13 616 +#define _BINARY_OP_MULTIPLY_INT_r23 617 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 618 +#define _BINARY_OP_SUBSCR_DICT_r23 619 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 620 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 621 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 622 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 623 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 624 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 625 +#define _BINARY_OP_SUBSCR_STR_INT_r23 626 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 627 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 628 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 629 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 630 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 631 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 632 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 633 +#define _BINARY_OP_SUBTRACT_INT_r03 634 +#define _BINARY_OP_SUBTRACT_INT_r13 635 +#define _BINARY_OP_SUBTRACT_INT_r23 636 +#define _BINARY_SLICE_r31 637 +#define _BUILD_INTERPOLATION_r01 638 +#define _BUILD_LIST_r01 639 +#define _BUILD_MAP_r01 640 +#define _BUILD_SET_r01 641 +#define _BUILD_SLICE_r01 642 +#define _BUILD_STRING_r01 643 +#define _BUILD_TEMPLATE_r21 644 +#define _BUILD_TUPLE_r01 645 +#define _CALL_BUILTIN_CLASS_r01 646 +#define _CALL_BUILTIN_FAST_r01 647 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 648 +#define _CALL_BUILTIN_O_r03 649 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 650 +#define _CALL_INTRINSIC_1_r12 651 +#define _CALL_INTRINSIC_2_r21 652 +#define _CALL_ISINSTANCE_r31 653 +#define _CALL_KW_NON_PY_r11 654 +#define _CALL_LEN_r33 655 +#define _CALL_LIST_APPEND_r03 656 +#define _CALL_LIST_APPEND_r13 657 +#define _CALL_LIST_APPEND_r23 658 +#define _CALL_LIST_APPEND_r33 659 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 660 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 661 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 662 +#define _CALL_METHOD_DESCRIPTOR_O_r03 663 +#define _CALL_NON_PY_GENERAL_r01 664 +#define _CALL_STR_1_r32 665 +#define _CALL_TUPLE_1_r32 666 +#define _CALL_TYPE_1_r02 667 +#define _CALL_TYPE_1_r12 668 +#define _CALL_TYPE_1_r22 669 +#define _CALL_TYPE_1_r32 670 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 671 +#define _CHECK_ATTR_CLASS_r01 672 +#define _CHECK_ATTR_CLASS_r11 673 +#define _CHECK_ATTR_CLASS_r22 674 +#define _CHECK_ATTR_CLASS_r33 675 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 676 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 677 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 678 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 679 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 680 +#define _CHECK_EG_MATCH_r22 681 +#define _CHECK_EXC_MATCH_r22 682 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 683 +#define _CHECK_FUNCTION_VERSION_r00 684 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 685 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 686 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 687 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 688 +#define _CHECK_FUNCTION_VERSION_KW_r11 689 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 690 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 691 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 692 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 693 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 694 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 695 +#define _CHECK_IS_PY_CALLABLE_EX_r03 696 +#define _CHECK_IS_PY_CALLABLE_EX_r13 697 +#define _CHECK_IS_PY_CALLABLE_EX_r23 698 +#define _CHECK_IS_PY_CALLABLE_EX_r33 699 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 700 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 701 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 702 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 703 +#define _CHECK_METHOD_VERSION_r00 704 +#define _CHECK_METHOD_VERSION_KW_r11 705 +#define _CHECK_PEP_523_r00 706 +#define _CHECK_PEP_523_r11 707 +#define _CHECK_PEP_523_r22 708 +#define _CHECK_PEP_523_r33 709 +#define _CHECK_PERIODIC_r00 710 +#define _CHECK_PERIODIC_AT_END_r00 711 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 712 +#define _CHECK_RECURSION_REMAINING_r00 713 +#define _CHECK_RECURSION_REMAINING_r11 714 +#define _CHECK_RECURSION_REMAINING_r22 715 +#define _CHECK_RECURSION_REMAINING_r33 716 +#define _CHECK_STACK_SPACE_r00 717 +#define _CHECK_STACK_SPACE_OPERAND_r00 718 +#define _CHECK_STACK_SPACE_OPERAND_r11 719 +#define _CHECK_STACK_SPACE_OPERAND_r22 720 +#define _CHECK_STACK_SPACE_OPERAND_r33 721 +#define _CHECK_VALIDITY_r00 722 +#define _CHECK_VALIDITY_r11 723 +#define _CHECK_VALIDITY_r22 724 +#define _CHECK_VALIDITY_r33 725 +#define _COLD_DYNAMIC_EXIT_r00 726 +#define _COLD_EXIT_r00 727 +#define _COMPARE_OP_r21 728 +#define _COMPARE_OP_FLOAT_r03 729 +#define _COMPARE_OP_FLOAT_r13 730 +#define _COMPARE_OP_FLOAT_r23 731 +#define _COMPARE_OP_INT_r23 732 +#define _COMPARE_OP_STR_r23 733 +#define _CONTAINS_OP_r23 734 +#define _CONTAINS_OP_DICT_r23 735 +#define _CONTAINS_OP_SET_r23 736 +#define _CONVERT_VALUE_r11 737 +#define _COPY_r01 738 +#define _COPY_1_r02 739 +#define _COPY_1_r12 740 +#define _COPY_1_r23 741 +#define _COPY_2_r03 742 +#define _COPY_2_r13 743 +#define _COPY_2_r23 744 +#define _COPY_3_r03 745 +#define _COPY_3_r13 746 +#define _COPY_3_r23 747 +#define _COPY_3_r33 748 +#define _COPY_FREE_VARS_r00 749 +#define _COPY_FREE_VARS_r11 750 +#define _COPY_FREE_VARS_r22 751 +#define _COPY_FREE_VARS_r33 752 +#define _CREATE_INIT_FRAME_r01 753 +#define _DELETE_ATTR_r10 754 +#define _DELETE_DEREF_r00 755 +#define _DELETE_FAST_r00 756 +#define _DELETE_GLOBAL_r00 757 +#define _DELETE_NAME_r00 758 +#define _DELETE_SUBSCR_r20 759 +#define _DEOPT_r00 760 +#define _DEOPT_r10 761 +#define _DEOPT_r20 762 +#define _DEOPT_r30 763 +#define _DICT_MERGE_r10 764 +#define _DICT_UPDATE_r10 765 +#define _DO_CALL_r01 766 +#define _DO_CALL_FUNCTION_EX_r31 767 +#define _DO_CALL_KW_r11 768 +#define _DYNAMIC_EXIT_r00 769 +#define _DYNAMIC_EXIT_r10 770 +#define _DYNAMIC_EXIT_r20 771 +#define _DYNAMIC_EXIT_r30 772 +#define _END_FOR_r10 773 +#define _END_SEND_r21 774 +#define _ERROR_POP_N_r00 775 +#define _EXIT_INIT_CHECK_r10 776 +#define _EXIT_TRACE_r00 777 +#define _EXIT_TRACE_r10 778 +#define _EXIT_TRACE_r20 779 +#define _EXIT_TRACE_r30 780 +#define _EXPAND_METHOD_r00 781 +#define _EXPAND_METHOD_KW_r11 782 +#define _FATAL_ERROR_r00 783 +#define _FATAL_ERROR_r11 784 +#define _FATAL_ERROR_r22 785 +#define _FATAL_ERROR_r33 786 +#define _FORMAT_SIMPLE_r11 787 +#define _FORMAT_WITH_SPEC_r21 788 +#define _FOR_ITER_r23 789 +#define _FOR_ITER_GEN_FRAME_r03 790 +#define _FOR_ITER_GEN_FRAME_r13 791 +#define _FOR_ITER_GEN_FRAME_r23 792 +#define _FOR_ITER_TIER_TWO_r23 793 +#define _GET_AITER_r11 794 +#define _GET_ANEXT_r12 795 +#define _GET_AWAITABLE_r11 796 +#define _GET_ITER_r12 797 +#define _GET_LEN_r12 798 +#define _GET_YIELD_FROM_ITER_r11 799 +#define _GUARD_BINARY_OP_EXTEND_r22 800 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 801 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 802 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 803 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 804 +#define _GUARD_BIT_IS_SET_POP_r00 805 +#define _GUARD_BIT_IS_SET_POP_r10 806 +#define _GUARD_BIT_IS_SET_POP_r21 807 +#define _GUARD_BIT_IS_SET_POP_r32 808 +#define _GUARD_BIT_IS_SET_POP_4_r00 809 +#define _GUARD_BIT_IS_SET_POP_4_r10 810 +#define _GUARD_BIT_IS_SET_POP_4_r21 811 +#define _GUARD_BIT_IS_SET_POP_4_r32 812 +#define _GUARD_BIT_IS_SET_POP_5_r00 813 +#define _GUARD_BIT_IS_SET_POP_5_r10 814 +#define _GUARD_BIT_IS_SET_POP_5_r21 815 +#define _GUARD_BIT_IS_SET_POP_5_r32 816 +#define _GUARD_BIT_IS_SET_POP_6_r00 817 +#define _GUARD_BIT_IS_SET_POP_6_r10 818 +#define _GUARD_BIT_IS_SET_POP_6_r21 819 +#define _GUARD_BIT_IS_SET_POP_6_r32 820 +#define _GUARD_BIT_IS_SET_POP_7_r00 821 +#define _GUARD_BIT_IS_SET_POP_7_r10 822 +#define _GUARD_BIT_IS_SET_POP_7_r21 823 +#define _GUARD_BIT_IS_SET_POP_7_r32 824 +#define _GUARD_BIT_IS_UNSET_POP_r00 825 +#define _GUARD_BIT_IS_UNSET_POP_r10 826 +#define _GUARD_BIT_IS_UNSET_POP_r21 827 +#define _GUARD_BIT_IS_UNSET_POP_r32 828 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 829 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 830 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 831 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 832 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 833 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 834 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 835 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 836 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 837 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 838 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 839 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 840 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 841 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 842 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 843 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 844 +#define _GUARD_CALLABLE_ISINSTANCE_r03 845 +#define _GUARD_CALLABLE_ISINSTANCE_r13 846 +#define _GUARD_CALLABLE_ISINSTANCE_r23 847 +#define _GUARD_CALLABLE_ISINSTANCE_r33 848 +#define _GUARD_CALLABLE_LEN_r03 849 +#define _GUARD_CALLABLE_LEN_r13 850 +#define _GUARD_CALLABLE_LEN_r23 851 +#define _GUARD_CALLABLE_LEN_r33 852 +#define _GUARD_CALLABLE_LIST_APPEND_r03 853 +#define _GUARD_CALLABLE_LIST_APPEND_r13 854 +#define _GUARD_CALLABLE_LIST_APPEND_r23 855 +#define _GUARD_CALLABLE_LIST_APPEND_r33 856 +#define _GUARD_CALLABLE_STR_1_r03 857 +#define _GUARD_CALLABLE_STR_1_r13 858 +#define _GUARD_CALLABLE_STR_1_r23 859 +#define _GUARD_CALLABLE_STR_1_r33 860 +#define _GUARD_CALLABLE_TUPLE_1_r03 861 +#define _GUARD_CALLABLE_TUPLE_1_r13 862 +#define _GUARD_CALLABLE_TUPLE_1_r23 863 +#define _GUARD_CALLABLE_TUPLE_1_r33 864 +#define _GUARD_CALLABLE_TYPE_1_r03 865 +#define _GUARD_CALLABLE_TYPE_1_r13 866 +#define _GUARD_CALLABLE_TYPE_1_r23 867 +#define _GUARD_CALLABLE_TYPE_1_r33 868 +#define _GUARD_CODE_VERSION_r00 869 +#define _GUARD_CODE_VERSION_r11 870 +#define _GUARD_CODE_VERSION_r22 871 +#define _GUARD_CODE_VERSION_r33 872 +#define _GUARD_DORV_NO_DICT_r01 873 +#define _GUARD_DORV_NO_DICT_r11 874 +#define _GUARD_DORV_NO_DICT_r22 875 +#define _GUARD_DORV_NO_DICT_r33 876 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 877 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 878 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 879 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 880 +#define _GUARD_GLOBALS_VERSION_r00 881 +#define _GUARD_GLOBALS_VERSION_r11 882 +#define _GUARD_GLOBALS_VERSION_r22 883 +#define _GUARD_GLOBALS_VERSION_r33 884 +#define _GUARD_IP_RETURN_GENERATOR_r00 885 +#define _GUARD_IP_RETURN_GENERATOR_r11 886 +#define _GUARD_IP_RETURN_GENERATOR_r22 887 +#define _GUARD_IP_RETURN_GENERATOR_r33 888 +#define _GUARD_IP_RETURN_VALUE_r00 889 +#define _GUARD_IP_RETURN_VALUE_r11 890 +#define _GUARD_IP_RETURN_VALUE_r22 891 +#define _GUARD_IP_RETURN_VALUE_r33 892 +#define _GUARD_IP_YIELD_VALUE_r00 893 +#define _GUARD_IP_YIELD_VALUE_r11 894 +#define _GUARD_IP_YIELD_VALUE_r22 895 +#define _GUARD_IP_YIELD_VALUE_r33 896 +#define _GUARD_IP__PUSH_FRAME_r00 897 +#define _GUARD_IP__PUSH_FRAME_r11 898 +#define _GUARD_IP__PUSH_FRAME_r22 899 +#define _GUARD_IP__PUSH_FRAME_r33 900 +#define _GUARD_IS_FALSE_POP_r00 901 +#define _GUARD_IS_FALSE_POP_r10 902 +#define _GUARD_IS_FALSE_POP_r21 903 +#define _GUARD_IS_FALSE_POP_r32 904 +#define _GUARD_IS_NONE_POP_r00 905 +#define _GUARD_IS_NONE_POP_r10 906 +#define _GUARD_IS_NONE_POP_r21 907 +#define _GUARD_IS_NONE_POP_r32 908 +#define _GUARD_IS_NOT_NONE_POP_r10 909 +#define _GUARD_IS_TRUE_POP_r00 910 +#define _GUARD_IS_TRUE_POP_r10 911 +#define _GUARD_IS_TRUE_POP_r21 912 +#define _GUARD_IS_TRUE_POP_r32 913 +#define _GUARD_KEYS_VERSION_r01 914 +#define _GUARD_KEYS_VERSION_r11 915 +#define _GUARD_KEYS_VERSION_r22 916 +#define _GUARD_KEYS_VERSION_r33 917 +#define _GUARD_NOS_ANY_DICT_r02 918 +#define _GUARD_NOS_ANY_DICT_r12 919 +#define _GUARD_NOS_ANY_DICT_r22 920 +#define _GUARD_NOS_ANY_DICT_r33 921 +#define _GUARD_NOS_COMPACT_ASCII_r02 922 +#define _GUARD_NOS_COMPACT_ASCII_r12 923 +#define _GUARD_NOS_COMPACT_ASCII_r22 924 +#define _GUARD_NOS_COMPACT_ASCII_r33 925 +#define _GUARD_NOS_DICT_r02 926 +#define _GUARD_NOS_DICT_r12 927 +#define _GUARD_NOS_DICT_r22 928 +#define _GUARD_NOS_DICT_r33 929 +#define _GUARD_NOS_FLOAT_r02 930 +#define _GUARD_NOS_FLOAT_r12 931 +#define _GUARD_NOS_FLOAT_r22 932 +#define _GUARD_NOS_FLOAT_r33 933 +#define _GUARD_NOS_INT_r02 934 +#define _GUARD_NOS_INT_r12 935 +#define _GUARD_NOS_INT_r22 936 +#define _GUARD_NOS_INT_r33 937 +#define _GUARD_NOS_LIST_r02 938 +#define _GUARD_NOS_LIST_r12 939 +#define _GUARD_NOS_LIST_r22 940 +#define _GUARD_NOS_LIST_r33 941 +#define _GUARD_NOS_NOT_NULL_r02 942 +#define _GUARD_NOS_NOT_NULL_r12 943 +#define _GUARD_NOS_NOT_NULL_r22 944 +#define _GUARD_NOS_NOT_NULL_r33 945 +#define _GUARD_NOS_NULL_r02 946 +#define _GUARD_NOS_NULL_r12 947 +#define _GUARD_NOS_NULL_r22 948 +#define _GUARD_NOS_NULL_r33 949 +#define _GUARD_NOS_OVERFLOWED_r02 950 +#define _GUARD_NOS_OVERFLOWED_r12 951 +#define _GUARD_NOS_OVERFLOWED_r22 952 +#define _GUARD_NOS_OVERFLOWED_r33 953 +#define _GUARD_NOS_TUPLE_r02 954 +#define _GUARD_NOS_TUPLE_r12 955 +#define _GUARD_NOS_TUPLE_r22 956 +#define _GUARD_NOS_TUPLE_r33 957 +#define _GUARD_NOS_UNICODE_r02 958 +#define _GUARD_NOS_UNICODE_r12 959 +#define _GUARD_NOS_UNICODE_r22 960 +#define _GUARD_NOS_UNICODE_r33 961 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 962 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 963 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 964 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 965 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 966 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 967 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 968 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 969 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 970 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 971 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 972 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 973 +#define _GUARD_THIRD_NULL_r03 974 +#define _GUARD_THIRD_NULL_r13 975 +#define _GUARD_THIRD_NULL_r23 976 +#define _GUARD_THIRD_NULL_r33 977 +#define _GUARD_TOS_ANY_DICT_r01 978 +#define _GUARD_TOS_ANY_DICT_r11 979 +#define _GUARD_TOS_ANY_DICT_r22 980 +#define _GUARD_TOS_ANY_DICT_r33 981 +#define _GUARD_TOS_ANY_SET_r01 982 +#define _GUARD_TOS_ANY_SET_r11 983 +#define _GUARD_TOS_ANY_SET_r22 984 +#define _GUARD_TOS_ANY_SET_r33 985 +#define _GUARD_TOS_DICT_r01 986 +#define _GUARD_TOS_DICT_r11 987 +#define _GUARD_TOS_DICT_r22 988 +#define _GUARD_TOS_DICT_r33 989 +#define _GUARD_TOS_FLOAT_r01 990 +#define _GUARD_TOS_FLOAT_r11 991 +#define _GUARD_TOS_FLOAT_r22 992 +#define _GUARD_TOS_FLOAT_r33 993 +#define _GUARD_TOS_FROZENDICT_r01 994 +#define _GUARD_TOS_FROZENDICT_r11 995 +#define _GUARD_TOS_FROZENDICT_r22 996 +#define _GUARD_TOS_FROZENDICT_r33 997 +#define _GUARD_TOS_FROZENSET_r01 998 +#define _GUARD_TOS_FROZENSET_r11 999 +#define _GUARD_TOS_FROZENSET_r22 1000 +#define _GUARD_TOS_FROZENSET_r33 1001 +#define _GUARD_TOS_INT_r01 1002 +#define _GUARD_TOS_INT_r11 1003 +#define _GUARD_TOS_INT_r22 1004 +#define _GUARD_TOS_INT_r33 1005 +#define _GUARD_TOS_LIST_r01 1006 +#define _GUARD_TOS_LIST_r11 1007 +#define _GUARD_TOS_LIST_r22 1008 +#define _GUARD_TOS_LIST_r33 1009 +#define _GUARD_TOS_OVERFLOWED_r01 1010 +#define _GUARD_TOS_OVERFLOWED_r11 1011 +#define _GUARD_TOS_OVERFLOWED_r22 1012 +#define _GUARD_TOS_OVERFLOWED_r33 1013 +#define _GUARD_TOS_SET_r01 1014 +#define _GUARD_TOS_SET_r11 1015 +#define _GUARD_TOS_SET_r22 1016 +#define _GUARD_TOS_SET_r33 1017 +#define _GUARD_TOS_SLICE_r01 1018 +#define _GUARD_TOS_SLICE_r11 1019 +#define _GUARD_TOS_SLICE_r22 1020 +#define _GUARD_TOS_SLICE_r33 1021 +#define _GUARD_TOS_TUPLE_r01 1022 +#define _GUARD_TOS_TUPLE_r11 1023 +#define _GUARD_TOS_TUPLE_r22 1024 +#define _GUARD_TOS_TUPLE_r33 1025 +#define _GUARD_TOS_UNICODE_r01 1026 +#define _GUARD_TOS_UNICODE_r11 1027 +#define _GUARD_TOS_UNICODE_r22 1028 +#define _GUARD_TOS_UNICODE_r33 1029 +#define _GUARD_TYPE_VERSION_r01 1030 +#define _GUARD_TYPE_VERSION_r11 1031 +#define _GUARD_TYPE_VERSION_r22 1032 +#define _GUARD_TYPE_VERSION_r33 1033 +#define _GUARD_TYPE_VERSION_LOCKED_r01 1034 +#define _GUARD_TYPE_VERSION_LOCKED_r11 1035 +#define _GUARD_TYPE_VERSION_LOCKED_r22 1036 +#define _GUARD_TYPE_VERSION_LOCKED_r33 1037 +#define _HANDLE_PENDING_AND_DEOPT_r00 1038 +#define _HANDLE_PENDING_AND_DEOPT_r10 1039 +#define _HANDLE_PENDING_AND_DEOPT_r20 1040 +#define _HANDLE_PENDING_AND_DEOPT_r30 1041 +#define _IMPORT_FROM_r12 1042 +#define _IMPORT_NAME_r21 1043 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1044 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1045 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1046 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1047 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1048 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1049 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1050 +#define _INSERT_1_LOAD_CONST_INLINE_r02 1051 +#define _INSERT_1_LOAD_CONST_INLINE_r12 1052 +#define _INSERT_1_LOAD_CONST_INLINE_r23 1053 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r02 1054 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r12 1055 +#define _INSERT_1_LOAD_CONST_INLINE_BORROW_r23 1056 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r03 1057 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r13 1058 +#define _INSERT_2_LOAD_CONST_INLINE_BORROW_r23 1059 +#define _INSERT_NULL_r10 1060 +#define _INSTRUMENTED_FOR_ITER_r23 1061 +#define _INSTRUMENTED_INSTRUCTION_r00 1062 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1063 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1064 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1065 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1066 +#define _INSTRUMENTED_LINE_r00 1067 +#define _INSTRUMENTED_NOT_TAKEN_r00 1068 +#define _INSTRUMENTED_NOT_TAKEN_r11 1069 +#define _INSTRUMENTED_NOT_TAKEN_r22 1070 +#define _INSTRUMENTED_NOT_TAKEN_r33 1071 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1072 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1073 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1074 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1075 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1076 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1077 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1078 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1079 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1080 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1081 +#define _IS_NONE_r11 1082 +#define _IS_OP_r03 1083 +#define _IS_OP_r13 1084 +#define _IS_OP_r23 1085 +#define _ITER_CHECK_LIST_r02 1086 +#define _ITER_CHECK_LIST_r12 1087 +#define _ITER_CHECK_LIST_r22 1088 +#define _ITER_CHECK_LIST_r33 1089 +#define _ITER_CHECK_RANGE_r02 1090 +#define _ITER_CHECK_RANGE_r12 1091 +#define _ITER_CHECK_RANGE_r22 1092 +#define _ITER_CHECK_RANGE_r33 1093 +#define _ITER_CHECK_TUPLE_r02 1094 +#define _ITER_CHECK_TUPLE_r12 1095 +#define _ITER_CHECK_TUPLE_r22 1096 +#define _ITER_CHECK_TUPLE_r33 1097 +#define _ITER_JUMP_LIST_r02 1098 +#define _ITER_JUMP_LIST_r12 1099 +#define _ITER_JUMP_LIST_r22 1100 +#define _ITER_JUMP_LIST_r33 1101 +#define _ITER_JUMP_RANGE_r02 1102 +#define _ITER_JUMP_RANGE_r12 1103 +#define _ITER_JUMP_RANGE_r22 1104 +#define _ITER_JUMP_RANGE_r33 1105 +#define _ITER_JUMP_TUPLE_r02 1106 +#define _ITER_JUMP_TUPLE_r12 1107 +#define _ITER_JUMP_TUPLE_r22 1108 +#define _ITER_JUMP_TUPLE_r33 1109 +#define _ITER_NEXT_LIST_r23 1110 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1111 +#define _ITER_NEXT_RANGE_r03 1112 +#define _ITER_NEXT_RANGE_r13 1113 +#define _ITER_NEXT_RANGE_r23 1114 +#define _ITER_NEXT_TUPLE_r03 1115 +#define _ITER_NEXT_TUPLE_r13 1116 +#define _ITER_NEXT_TUPLE_r23 1117 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1118 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1119 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1120 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1121 +#define _JUMP_TO_TOP_r00 1122 +#define _LIST_APPEND_r10 1123 +#define _LIST_EXTEND_r10 1124 +#define _LOAD_ATTR_r10 1125 +#define _LOAD_ATTR_CLASS_r11 1126 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1127 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1128 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1129 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1130 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1131 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1132 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1133 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1134 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1135 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1136 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1137 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1138 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1139 +#define _LOAD_ATTR_MODULE_r12 1140 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1141 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1142 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1143 +#define _LOAD_ATTR_SLOT_r02 1144 +#define _LOAD_ATTR_SLOT_r12 1145 +#define _LOAD_ATTR_SLOT_r23 1146 +#define _LOAD_ATTR_WITH_HINT_r12 1147 +#define _LOAD_BUILD_CLASS_r01 1148 +#define _LOAD_BYTECODE_r00 1149 +#define _LOAD_COMMON_CONSTANT_r01 1150 +#define _LOAD_COMMON_CONSTANT_r12 1151 +#define _LOAD_COMMON_CONSTANT_r23 1152 +#define _LOAD_CONST_r01 1153 +#define _LOAD_CONST_r12 1154 +#define _LOAD_CONST_r23 1155 +#define _LOAD_CONST_INLINE_r01 1156 +#define _LOAD_CONST_INLINE_r12 1157 +#define _LOAD_CONST_INLINE_r23 1158 +#define _LOAD_CONST_INLINE_BORROW_r01 1159 +#define _LOAD_CONST_INLINE_BORROW_r12 1160 +#define _LOAD_CONST_INLINE_BORROW_r23 1161 +#define _LOAD_CONST_UNDER_INLINE_r02 1162 +#define _LOAD_CONST_UNDER_INLINE_r12 1163 +#define _LOAD_CONST_UNDER_INLINE_r23 1164 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1165 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1166 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1167 +#define _LOAD_DEREF_r01 1168 +#define _LOAD_FAST_r01 1169 +#define _LOAD_FAST_r12 1170 +#define _LOAD_FAST_r23 1171 +#define _LOAD_FAST_0_r01 1172 +#define _LOAD_FAST_0_r12 1173 +#define _LOAD_FAST_0_r23 1174 +#define _LOAD_FAST_1_r01 1175 +#define _LOAD_FAST_1_r12 1176 +#define _LOAD_FAST_1_r23 1177 +#define _LOAD_FAST_2_r01 1178 +#define _LOAD_FAST_2_r12 1179 +#define _LOAD_FAST_2_r23 1180 +#define _LOAD_FAST_3_r01 1181 +#define _LOAD_FAST_3_r12 1182 +#define _LOAD_FAST_3_r23 1183 +#define _LOAD_FAST_4_r01 1184 +#define _LOAD_FAST_4_r12 1185 +#define _LOAD_FAST_4_r23 1186 +#define _LOAD_FAST_5_r01 1187 +#define _LOAD_FAST_5_r12 1188 +#define _LOAD_FAST_5_r23 1189 +#define _LOAD_FAST_6_r01 1190 +#define _LOAD_FAST_6_r12 1191 +#define _LOAD_FAST_6_r23 1192 +#define _LOAD_FAST_7_r01 1193 +#define _LOAD_FAST_7_r12 1194 +#define _LOAD_FAST_7_r23 1195 +#define _LOAD_FAST_AND_CLEAR_r01 1196 +#define _LOAD_FAST_AND_CLEAR_r12 1197 +#define _LOAD_FAST_AND_CLEAR_r23 1198 +#define _LOAD_FAST_BORROW_r01 1199 +#define _LOAD_FAST_BORROW_r12 1200 +#define _LOAD_FAST_BORROW_r23 1201 +#define _LOAD_FAST_BORROW_0_r01 1202 +#define _LOAD_FAST_BORROW_0_r12 1203 +#define _LOAD_FAST_BORROW_0_r23 1204 +#define _LOAD_FAST_BORROW_1_r01 1205 +#define _LOAD_FAST_BORROW_1_r12 1206 +#define _LOAD_FAST_BORROW_1_r23 1207 +#define _LOAD_FAST_BORROW_2_r01 1208 +#define _LOAD_FAST_BORROW_2_r12 1209 +#define _LOAD_FAST_BORROW_2_r23 1210 +#define _LOAD_FAST_BORROW_3_r01 1211 +#define _LOAD_FAST_BORROW_3_r12 1212 +#define _LOAD_FAST_BORROW_3_r23 1213 +#define _LOAD_FAST_BORROW_4_r01 1214 +#define _LOAD_FAST_BORROW_4_r12 1215 +#define _LOAD_FAST_BORROW_4_r23 1216 +#define _LOAD_FAST_BORROW_5_r01 1217 +#define _LOAD_FAST_BORROW_5_r12 1218 +#define _LOAD_FAST_BORROW_5_r23 1219 +#define _LOAD_FAST_BORROW_6_r01 1220 +#define _LOAD_FAST_BORROW_6_r12 1221 +#define _LOAD_FAST_BORROW_6_r23 1222 +#define _LOAD_FAST_BORROW_7_r01 1223 +#define _LOAD_FAST_BORROW_7_r12 1224 +#define _LOAD_FAST_BORROW_7_r23 1225 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1226 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1227 +#define _LOAD_FAST_CHECK_r01 1228 +#define _LOAD_FAST_CHECK_r12 1229 +#define _LOAD_FAST_CHECK_r23 1230 +#define _LOAD_FAST_LOAD_FAST_r02 1231 +#define _LOAD_FAST_LOAD_FAST_r13 1232 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1233 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1234 +#define _LOAD_GLOBAL_r00 1235 +#define _LOAD_GLOBAL_BUILTINS_r01 1236 +#define _LOAD_GLOBAL_MODULE_r01 1237 +#define _LOAD_LOCALS_r01 1238 +#define _LOAD_LOCALS_r12 1239 +#define _LOAD_LOCALS_r23 1240 +#define _LOAD_NAME_r01 1241 +#define _LOAD_SMALL_INT_r01 1242 +#define _LOAD_SMALL_INT_r12 1243 +#define _LOAD_SMALL_INT_r23 1244 +#define _LOAD_SMALL_INT_0_r01 1245 +#define _LOAD_SMALL_INT_0_r12 1246 +#define _LOAD_SMALL_INT_0_r23 1247 +#define _LOAD_SMALL_INT_1_r01 1248 +#define _LOAD_SMALL_INT_1_r12 1249 +#define _LOAD_SMALL_INT_1_r23 1250 +#define _LOAD_SMALL_INT_2_r01 1251 +#define _LOAD_SMALL_INT_2_r12 1252 +#define _LOAD_SMALL_INT_2_r23 1253 +#define _LOAD_SMALL_INT_3_r01 1254 +#define _LOAD_SMALL_INT_3_r12 1255 +#define _LOAD_SMALL_INT_3_r23 1256 +#define _LOAD_SPECIAL_r00 1257 +#define _LOAD_SUPER_ATTR_ATTR_r31 1258 +#define _LOAD_SUPER_ATTR_METHOD_r32 1259 +#define _LOCK_OBJECT_r01 1260 +#define _LOCK_OBJECT_r11 1261 +#define _LOCK_OBJECT_r22 1262 +#define _LOCK_OBJECT_r33 1263 +#define _MAKE_CALLARGS_A_TUPLE_r33 1264 +#define _MAKE_CELL_r00 1265 +#define _MAKE_FUNCTION_r11 1266 +#define _MAKE_HEAP_SAFE_r01 1267 +#define _MAKE_HEAP_SAFE_r11 1268 +#define _MAKE_HEAP_SAFE_r22 1269 +#define _MAKE_HEAP_SAFE_r33 1270 +#define _MAKE_WARM_r00 1271 +#define _MAKE_WARM_r11 1272 +#define _MAKE_WARM_r22 1273 +#define _MAKE_WARM_r33 1274 +#define _MAP_ADD_r20 1275 +#define _MATCH_CLASS_r33 1276 +#define _MATCH_KEYS_r23 1277 +#define _MATCH_MAPPING_r02 1278 +#define _MATCH_MAPPING_r12 1279 +#define _MATCH_MAPPING_r23 1280 +#define _MATCH_SEQUENCE_r02 1281 +#define _MATCH_SEQUENCE_r12 1282 +#define _MATCH_SEQUENCE_r23 1283 +#define _MAYBE_EXPAND_METHOD_r00 1284 +#define _MAYBE_EXPAND_METHOD_KW_r11 1285 +#define _MONITOR_CALL_r00 1286 +#define _MONITOR_CALL_KW_r11 1287 +#define _MONITOR_JUMP_BACKWARD_r00 1288 +#define _MONITOR_JUMP_BACKWARD_r11 1289 +#define _MONITOR_JUMP_BACKWARD_r22 1290 +#define _MONITOR_JUMP_BACKWARD_r33 1291 +#define _MONITOR_RESUME_r00 1292 +#define _NOP_r00 1293 +#define _NOP_r11 1294 +#define _NOP_r22 1295 +#define _NOP_r33 1296 +#define _POP_CALL_r20 1297 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1298 +#define _POP_CALL_ONE_r30 1299 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1300 +#define _POP_CALL_TWO_r30 1301 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1302 +#define _POP_EXCEPT_r10 1303 +#define _POP_ITER_r20 1304 +#define _POP_JUMP_IF_FALSE_r00 1305 +#define _POP_JUMP_IF_FALSE_r10 1306 +#define _POP_JUMP_IF_FALSE_r21 1307 +#define _POP_JUMP_IF_FALSE_r32 1308 +#define _POP_JUMP_IF_TRUE_r00 1309 +#define _POP_JUMP_IF_TRUE_r10 1310 +#define _POP_JUMP_IF_TRUE_r21 1311 +#define _POP_JUMP_IF_TRUE_r32 1312 +#define _POP_TOP_r10 1313 +#define _POP_TOP_FLOAT_r00 1314 +#define _POP_TOP_FLOAT_r10 1315 +#define _POP_TOP_FLOAT_r21 1316 +#define _POP_TOP_FLOAT_r32 1317 +#define _POP_TOP_INT_r00 1318 +#define _POP_TOP_INT_r10 1319 +#define _POP_TOP_INT_r21 1320 +#define _POP_TOP_INT_r32 1321 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1322 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1323 +#define _POP_TOP_NOP_r00 1324 +#define _POP_TOP_NOP_r10 1325 +#define _POP_TOP_NOP_r21 1326 +#define _POP_TOP_NOP_r32 1327 +#define _POP_TOP_UNICODE_r00 1328 +#define _POP_TOP_UNICODE_r10 1329 +#define _POP_TOP_UNICODE_r21 1330 +#define _POP_TOP_UNICODE_r32 1331 +#define _POP_TWO_r20 1332 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1333 +#define _PUSH_EXC_INFO_r02 1334 +#define _PUSH_EXC_INFO_r12 1335 +#define _PUSH_EXC_INFO_r23 1336 +#define _PUSH_FRAME_r10 1337 +#define _PUSH_NULL_r01 1338 +#define _PUSH_NULL_r12 1339 +#define _PUSH_NULL_r23 1340 +#define _PUSH_NULL_CONDITIONAL_r00 1341 +#define _PY_FRAME_EX_r31 1342 +#define _PY_FRAME_GENERAL_r01 1343 +#define _PY_FRAME_KW_r11 1344 +#define _QUICKEN_RESUME_r00 1345 +#define _QUICKEN_RESUME_r11 1346 +#define _QUICKEN_RESUME_r22 1347 +#define _QUICKEN_RESUME_r33 1348 +#define _REPLACE_WITH_TRUE_r02 1349 +#define _REPLACE_WITH_TRUE_r12 1350 +#define _REPLACE_WITH_TRUE_r23 1351 +#define _RESUME_CHECK_r00 1352 +#define _RESUME_CHECK_r11 1353 +#define _RESUME_CHECK_r22 1354 +#define _RESUME_CHECK_r33 1355 +#define _RETURN_GENERATOR_r01 1356 +#define _RETURN_VALUE_r11 1357 +#define _SAVE_RETURN_OFFSET_r00 1358 +#define _SAVE_RETURN_OFFSET_r11 1359 +#define _SAVE_RETURN_OFFSET_r22 1360 +#define _SAVE_RETURN_OFFSET_r33 1361 +#define _SEND_r22 1362 +#define _SEND_GEN_FRAME_r22 1363 +#define _SETUP_ANNOTATIONS_r00 1364 +#define _SET_ADD_r10 1365 +#define _SET_FUNCTION_ATTRIBUTE_r01 1366 +#define _SET_FUNCTION_ATTRIBUTE_r11 1367 +#define _SET_FUNCTION_ATTRIBUTE_r21 1368 +#define _SET_FUNCTION_ATTRIBUTE_r32 1369 +#define _SET_IP_r00 1370 +#define _SET_IP_r11 1371 +#define _SET_IP_r22 1372 +#define _SET_IP_r33 1373 +#define _SET_UPDATE_r10 1374 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1375 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1376 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1377 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1378 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1379 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1380 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1381 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1382 +#define _SPILL_OR_RELOAD_r01 1383 +#define _SPILL_OR_RELOAD_r02 1384 +#define _SPILL_OR_RELOAD_r03 1385 +#define _SPILL_OR_RELOAD_r10 1386 +#define _SPILL_OR_RELOAD_r12 1387 +#define _SPILL_OR_RELOAD_r13 1388 +#define _SPILL_OR_RELOAD_r20 1389 +#define _SPILL_OR_RELOAD_r21 1390 +#define _SPILL_OR_RELOAD_r23 1391 +#define _SPILL_OR_RELOAD_r30 1392 +#define _SPILL_OR_RELOAD_r31 1393 +#define _SPILL_OR_RELOAD_r32 1394 +#define _START_EXECUTOR_r00 1395 +#define _STORE_ATTR_r20 1396 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1397 +#define _STORE_ATTR_SLOT_r21 1398 +#define _STORE_ATTR_WITH_HINT_r21 1399 +#define _STORE_DEREF_r10 1400 +#define _STORE_FAST_LOAD_FAST_r11 1401 +#define _STORE_FAST_STORE_FAST_r20 1402 +#define _STORE_GLOBAL_r10 1403 +#define _STORE_NAME_r10 1404 +#define _STORE_SLICE_r30 1405 +#define _STORE_SUBSCR_r30 1406 +#define _STORE_SUBSCR_DICT_r31 1407 +#define _STORE_SUBSCR_LIST_INT_r32 1408 +#define _SWAP_r11 1409 +#define _SWAP_2_r02 1410 +#define _SWAP_2_r12 1411 +#define _SWAP_2_r22 1412 +#define _SWAP_2_r33 1413 +#define _SWAP_3_r03 1414 +#define _SWAP_3_r13 1415 +#define _SWAP_3_r23 1416 +#define _SWAP_3_r33 1417 +#define _SWAP_FAST_r01 1418 +#define _SWAP_FAST_r11 1419 +#define _SWAP_FAST_r22 1420 +#define _SWAP_FAST_r33 1421 +#define _SWAP_FAST_0_r01 1422 +#define _SWAP_FAST_0_r11 1423 +#define _SWAP_FAST_0_r22 1424 +#define _SWAP_FAST_0_r33 1425 +#define _SWAP_FAST_1_r01 1426 +#define _SWAP_FAST_1_r11 1427 +#define _SWAP_FAST_1_r22 1428 +#define _SWAP_FAST_1_r33 1429 +#define _SWAP_FAST_2_r01 1430 +#define _SWAP_FAST_2_r11 1431 +#define _SWAP_FAST_2_r22 1432 +#define _SWAP_FAST_2_r33 1433 +#define _SWAP_FAST_3_r01 1434 +#define _SWAP_FAST_3_r11 1435 +#define _SWAP_FAST_3_r22 1436 +#define _SWAP_FAST_3_r33 1437 +#define _SWAP_FAST_4_r01 1438 +#define _SWAP_FAST_4_r11 1439 +#define _SWAP_FAST_4_r22 1440 +#define _SWAP_FAST_4_r33 1441 +#define _SWAP_FAST_5_r01 1442 +#define _SWAP_FAST_5_r11 1443 +#define _SWAP_FAST_5_r22 1444 +#define _SWAP_FAST_5_r33 1445 +#define _SWAP_FAST_6_r01 1446 +#define _SWAP_FAST_6_r11 1447 +#define _SWAP_FAST_6_r22 1448 +#define _SWAP_FAST_6_r33 1449 +#define _SWAP_FAST_7_r01 1450 +#define _SWAP_FAST_7_r11 1451 +#define _SWAP_FAST_7_r22 1452 +#define _SWAP_FAST_7_r33 1453 +#define _TIER2_RESUME_CHECK_r00 1454 +#define _TIER2_RESUME_CHECK_r11 1455 +#define _TIER2_RESUME_CHECK_r22 1456 +#define _TIER2_RESUME_CHECK_r33 1457 +#define _TO_BOOL_r11 1458 +#define _TO_BOOL_BOOL_r01 1459 +#define _TO_BOOL_BOOL_r11 1460 +#define _TO_BOOL_BOOL_r22 1461 +#define _TO_BOOL_BOOL_r33 1462 +#define _TO_BOOL_INT_r02 1463 +#define _TO_BOOL_INT_r12 1464 +#define _TO_BOOL_INT_r23 1465 +#define _TO_BOOL_LIST_r02 1466 +#define _TO_BOOL_LIST_r12 1467 +#define _TO_BOOL_LIST_r23 1468 +#define _TO_BOOL_NONE_r01 1469 +#define _TO_BOOL_NONE_r11 1470 +#define _TO_BOOL_NONE_r22 1471 +#define _TO_BOOL_NONE_r33 1472 +#define _TO_BOOL_STR_r02 1473 +#define _TO_BOOL_STR_r12 1474 +#define _TO_BOOL_STR_r23 1475 +#define _TRACE_RECORD_r00 1476 +#define _UNARY_INVERT_r12 1477 +#define _UNARY_NEGATIVE_r12 1478 +#define _UNARY_NOT_r01 1479 +#define _UNARY_NOT_r11 1480 +#define _UNARY_NOT_r22 1481 +#define _UNARY_NOT_r33 1482 +#define _UNPACK_EX_r10 1483 +#define _UNPACK_SEQUENCE_r10 1484 +#define _UNPACK_SEQUENCE_LIST_r10 1485 +#define _UNPACK_SEQUENCE_TUPLE_r10 1486 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1487 +#define _WITH_EXCEPT_START_r33 1488 +#define _YIELD_VALUE_r11 1489 +#define MAX_UOP_REGS_ID 1489 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 9a0852f872d763..ce7ea4c3a77b36 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -140,7 +140,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_STORE_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_STORE_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MAKE_HEAP_SAFE] = 0, [_RETURN_VALUE] = HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG, @@ -1354,7 +1354,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { .best = { 1, 1, 1, 1 }, .entries = { { -1, -1, -1 }, - { 1, 1, _CALL_INTRINSIC_1_r11 }, + { 2, 1, _CALL_INTRINSIC_1_r12 }, { -1, -1, -1 }, { -1, -1, -1 }, }, @@ -3822,7 +3822,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_STORE_SUBSCR_LIST_INT_r32] = _STORE_SUBSCR_LIST_INT, [_STORE_SUBSCR_DICT_r31] = _STORE_SUBSCR_DICT, [_DELETE_SUBSCR_r20] = _DELETE_SUBSCR, - [_CALL_INTRINSIC_1_r11] = _CALL_INTRINSIC_1, + [_CALL_INTRINSIC_1_r12] = _CALL_INTRINSIC_1, [_CALL_INTRINSIC_2_r21] = _CALL_INTRINSIC_2, [_MAKE_HEAP_SAFE_r01] = _MAKE_HEAP_SAFE, [_MAKE_HEAP_SAFE_r11] = _MAKE_HEAP_SAFE, @@ -4441,7 +4441,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_CALL_FUNCTION_EX_NON_PY_GENERAL] = "_CALL_FUNCTION_EX_NON_PY_GENERAL", [_CALL_FUNCTION_EX_NON_PY_GENERAL_r31] = "_CALL_FUNCTION_EX_NON_PY_GENERAL_r31", [_CALL_INTRINSIC_1] = "_CALL_INTRINSIC_1", - [_CALL_INTRINSIC_1_r11] = "_CALL_INTRINSIC_1_r11", + [_CALL_INTRINSIC_1_r12] = "_CALL_INTRINSIC_1_r12", [_CALL_INTRINSIC_2] = "_CALL_INTRINSIC_2", [_CALL_INTRINSIC_2_r21] = "_CALL_INTRINSIC_2_r21", [_CALL_ISINSTANCE] = "_CALL_ISINSTANCE", diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index e5fada1f40ce43..d66031ed31cbe2 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -2546,6 +2546,21 @@ def testfunc(n): self.assertIn("_POP_TOP_NOP", uops) self.assertLessEqual(count_ops(ex, "_POP_TOP"), 4) + def test_call_intrinsic_1(self): + def testfunc(n): + x = 0 + for _ in range(n): + +x + return x + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, 0) + uops = get_opnames(ex) + + self.assertIn("_CALL_INTRINSIC_1", uops) + self.assertEqual(count_ops(ex, "_POP_TOP_NOP"), 1) + self.assertLessEqual(count_ops(ex, "_POP_TOP"), 2) + def test_get_len_with_const_tuple(self): def testfunc(n): x = 0.0 diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 9e86bc42f20074..2f6845399d9e16 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -2982,23 +2982,28 @@ INSTRUCTION_STATS(CALL_INTRINSIC_1); _PyStackRef value; _PyStackRef res; - value = stack_pointer[-1]; - assert(oparg <= MAX_INTRINSIC_1); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (res_o == NULL) { - JUMP_TO_LABEL(error); + _PyStackRef v; + // _CALL_INTRINSIC_1 + { + value = stack_pointer[-1]; + assert(oparg <= MAX_INTRINSIC_1); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (res_o == NULL) { + JUMP_TO_LABEL(error); + } + v = value; + res = PyStackRef_FromPyObjectSteal(res_o); + } + // _POP_TOP + { + value = v; + stack_pointer[-1] = res; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); } - res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); DISPATCH(); } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 43a512611fb1ee..c26ba89b5ab9c8 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1246,14 +1246,19 @@ dummy_func( ERROR_IF(err); } - inst(CALL_INTRINSIC_1, (value -- res)) { + op(_CALL_INTRINSIC_1, (value -- res, v)) { assert(oparg <= MAX_INTRINSIC_1); PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); - PyStackRef_CLOSE(value); - ERROR_IF(res_o == NULL); + if (res_o == NULL) { + ERROR_NO_POP(); + } + v = value; + DEAD(value); res = PyStackRef_FromPyObjectSteal(res_o); } + macro(CALL_INTRINSIC_1) = _CALL_INTRINSIC_1 + POP_TOP; + inst(CALL_INTRINSIC_2, (value2_st, value1_st -- res)) { assert(oparg <= MAX_INTRINSIC_2); PyObject *value1 = PyStackRef_AsPyObjectBorrow(value1_st); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 7a698e422abd77..f00913cd359c1e 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -6833,11 +6833,12 @@ break; } - case _CALL_INTRINSIC_1_r11: { + case _CALL_INTRINSIC_1_r12: { CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef value; _PyStackRef res; + _PyStackRef v; _PyStackRef _stack_item_0 = _tos_cache0; oparg = CURRENT_OPARG(); value = _stack_item_0; @@ -6848,20 +6849,18 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); if (res_o == NULL) { SET_CURRENT_CACHED_VALUES(0); JUMP_TO_ERROR(); } + v = value; res = PyStackRef_FromPyObjectSteal(res_o); + _tos_cache1 = v; _tos_cache0 = res; - _tos_cache1 = PyStackRef_ZERO_BITS; _tos_cache2 = PyStackRef_ZERO_BITS; - SET_CURRENT_CACHED_VALUES(1); + SET_CURRENT_CACHED_VALUES(2); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 72619fd3afa91a..30f0101d2ed0e3 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2982,23 +2982,28 @@ INSTRUCTION_STATS(CALL_INTRINSIC_1); _PyStackRef value; _PyStackRef res; - value = stack_pointer[-1]; - assert(oparg <= MAX_INTRINSIC_1); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (res_o == NULL) { - JUMP_TO_LABEL(error); + _PyStackRef v; + // _CALL_INTRINSIC_1 + { + value = stack_pointer[-1]; + assert(oparg <= MAX_INTRINSIC_1); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (res_o == NULL) { + JUMP_TO_LABEL(error); + } + v = value; + res = PyStackRef_FromPyObjectSteal(res_o); + } + // _POP_TOP + { + value = v; + stack_pointer[-1] = res; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(value); + stack_pointer = _PyFrame_GetStackPointer(frame); } - res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); DISPATCH(); } diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 6092da8c04e708..e0410be55652b4 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1177,6 +1177,11 @@ dummy_func(void) { } } + op(_CALL_INTRINSIC_1, (value -- res, v)) { + res = sym_new_not_null(ctx); + v = value; + } + op(_GUARD_IS_TRUE_POP, (flag -- )) { sym_apply_predicate_narrowing(ctx, flag, true); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 2df50ebbcaa1c0..7e5b26c6d725d6 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1293,9 +1293,17 @@ } case _CALL_INTRINSIC_1: { + JitOptRef value; JitOptRef res; + JitOptRef v; + value = stack_pointer[-1]; res = sym_new_not_null(ctx); + v = value; + CHECK_STACK_BOUNDS(1); stack_pointer[-1] = res; + stack_pointer[0] = v; + stack_pointer += 1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); break; } From e6b9a1406980fbb1d4032eca9cc0b4f8f252b716 Mon Sep 17 00:00:00 2001 From: Ramin Farajpour Cami Date: Mon, 16 Mar 2026 16:00:13 +0330 Subject: [PATCH 478/498] gh-144984: Fix crash in Expat's `ExternalEntityParserCreate` error paths (#144992) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_pyexpat.py | 37 +++++++++++++++++++ ...19-12-00-00.gh-issue-144984.b93995c982.rst | 3 ++ Modules/pyexpat.c | 16 ++++---- 3 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-02-19-12-00-00.gh-issue-144984.b93995c982.rst diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index f8afc16d3cb4cb..c67bfc67479985 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -843,6 +843,43 @@ def test_parent_parser_outlives_its_subparsers__chain(self): del subparser +class ExternalEntityParserCreateErrorTest(unittest.TestCase): + """ExternalEntityParserCreate error paths should not crash or leak + refcounts on the parent parser. + + See https://github.com/python/cpython/issues/144984. + """ + + @classmethod + def setUpClass(cls): + cls.testcapi = import_helper.import_module('_testcapi') + + def test_error_path_no_crash(self): + # When an allocation inside ExternalEntityParserCreate fails, + # the partially-initialized subparser is deallocated. This + # must not dereference NULL handlers or double-decrement the + # parent parser's refcount. + parser = expat.ParserCreate() + parser.buffer_text = True + rc_before = sys.getrefcount(parser) + + # We avoid self.assertRaises(MemoryError) here because the + # context manager itself needs memory allocations that fail + # while the nomemory hook is active. + self.testcapi.set_nomemory(1, 10) + raised = False + try: + parser.ExternalEntityParserCreate(None) + except MemoryError: + raised = True + finally: + self.testcapi.remove_mem_hooks() + self.assertTrue(raised, "MemoryError not raised") + + rc_after = sys.getrefcount(parser) + self.assertEqual(rc_after, rc_before) + + class ReparseDeferralTest(unittest.TestCase): def test_getter_setter_round_trip(self): parser = expat.ParserCreate() diff --git a/Misc/NEWS.d/next/Library/2026-02-19-12-00-00.gh-issue-144984.b93995c982.rst b/Misc/NEWS.d/next/Library/2026-02-19-12-00-00.gh-issue-144984.b93995c982.rst new file mode 100644 index 00000000000000..66e07dc3098c5f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-19-12-00-00.gh-issue-144984.b93995c982.rst @@ -0,0 +1,3 @@ +Fix crash in :meth:`xml.parsers.expat.xmlparser.ExternalEntityParserCreate` +when an allocation fails. The error paths could dereference NULL ``handlers`` +and double-decrement the parent parser's reference count. diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index cadc6706243524..782e552f342b17 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1083,11 +1083,6 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, return NULL; } - // The new subparser will make use of the parent XML_Parser inside of Expat. - // So we need to take subparsers into account with the reference counting - // of their parent parser. - Py_INCREF(self); - new_parser->buffer_size = self->buffer_size; new_parser->buffer_used = 0; new_parser->buffer = NULL; @@ -1097,7 +1092,10 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, new_parser->ns_prefixes = self->ns_prefixes; new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context, encoding); - new_parser->parent = (PyObject *)self; + // The new subparser will make use of the parent XML_Parser inside of Expat. + // So we need to take subparsers into account with the reference counting + // of their parent parser. + new_parser->parent = Py_NewRef(self); new_parser->handlers = 0; new_parser->intern = Py_XNewRef(self->intern); @@ -1105,13 +1103,11 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, new_parser->buffer = PyMem_Malloc(new_parser->buffer_size); if (new_parser->buffer == NULL) { Py_DECREF(new_parser); - Py_DECREF(self); return PyErr_NoMemory(); } } if (!new_parser->itself) { Py_DECREF(new_parser); - Py_DECREF(self); return PyErr_NoMemory(); } @@ -1125,7 +1121,6 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, new_parser->handlers = PyMem_New(PyObject *, i); if (!new_parser->handlers) { Py_DECREF(new_parser); - Py_DECREF(self); return PyErr_NoMemory(); } clear_handlers(new_parser, 1); @@ -2496,6 +2491,9 @@ PyInit_pyexpat(void) static void clear_handlers(xmlparseobject *self, int initial) { + if (self->handlers == NULL) { + return; + } for (size_t i = 0; handler_info[i].name != NULL; i++) { if (initial) { self->handlers[i] = NULL; From 77632f085d0cec29c7576b8528849276109801a1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 16 Mar 2026 14:19:00 +0100 Subject: [PATCH 479/498] gh-141510: Avoid critical section on frozendict copy (#145920) --- Objects/dictobject.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 842d9be73b8792..08e40bf84c42fa 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -968,7 +968,9 @@ clone_combined_dict_keys(PyDictObject *orig) assert(orig->ma_keys != Py_EMPTY_KEYS); assert(orig->ma_keys->dk_refcnt == 1); - ASSERT_DICT_LOCKED(orig); + if (!PyFrozenDict_Check(orig)) { + ASSERT_DICT_LOCKED(orig); + } size_t keys_size = _PyDict_KeysSize(orig->ma_keys); PyDictKeysObject *keys = PyMem_Malloc(keys_size); @@ -4322,7 +4324,10 @@ copy_lock_held(PyObject *o, int as_frozendict) PyObject *copy; PyDictObject *mp; - ASSERT_DICT_LOCKED(o); + // frozendict is immutable and so doesn't need critical section + if (!PyFrozenDict_Check(o)) { + ASSERT_DICT_LOCKED(o); + } mp = (PyDictObject *)o; if (mp->ma_used == 0) { @@ -4445,9 +4450,14 @@ anydict_copy(PyObject *o) assert(PyAnyDict_Check(o)); PyObject *res; - Py_BEGIN_CRITICAL_SECTION(o); - res = copy_lock_held(o, PyFrozenDict_Check(o)); - Py_END_CRITICAL_SECTION(); + if (PyFrozenDict_Check(o)) { + res = copy_lock_held(o, 1); + } + else { + Py_BEGIN_CRITICAL_SECTION(o); + res = copy_lock_held(o, 0); + Py_END_CRITICAL_SECTION(); + } return res; } @@ -4459,9 +4469,14 @@ _PyDict_CopyAsDict(PyObject *o) assert(PyAnyDict_Check(o)); PyObject *res; - Py_BEGIN_CRITICAL_SECTION(o); - res = copy_lock_held(o, 0); - Py_END_CRITICAL_SECTION(); + if (PyFrozenDict_Check(o)) { + res = copy_lock_held(o, 0); + } + else { + Py_BEGIN_CRITICAL_SECTION(o); + res = copy_lock_held(o, 0); + Py_END_CRITICAL_SECTION(); + } return res; } From 57e88c1cf95e1481b94ae57abe1010469d47a6b4 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:43:43 +0000 Subject: [PATCH 480/498] gh-145599, CVE 2026-3644: Reject control characters in `http.cookies.Morsel.update()` (#145600) Reject control characters in `http.cookies.Morsel.update()` and `http.cookies.BaseCookie.js_output`. Co-authored-by: Victor Stinner Co-authored-by: Victor Stinner --- Lib/http/cookies.py | 24 ++++++++++-- Lib/test/test_http_cookies.py | 38 +++++++++++++++++++ ...-03-06-17-03-38.gh-issue-145599.kchwZV.rst | 4 ++ 3 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 917280037d4dbb..769541116993c4 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -337,9 +337,16 @@ def update(self, values): key = key.lower() if key not in self._reserved: raise CookieError("Invalid attribute %r" % (key,)) + if _has_control_character(key, val): + raise CookieError("Control characters are not allowed in " + f"cookies {key!r} {val!r}") data[key] = val dict.update(self, data) + def __ior__(self, values): + self.update(values) + return self + def isReservedKey(self, K): return K.lower() in self._reserved @@ -365,9 +372,15 @@ def __getstate__(self): } def __setstate__(self, state): - self._key = state['key'] - self._value = state['value'] - self._coded_value = state['coded_value'] + key = state['key'] + value = state['value'] + coded_value = state['coded_value'] + if _has_control_character(key, value, coded_value): + raise CookieError("Control characters are not allowed in cookies " + f"{key!r} {value!r} {coded_value!r}") + self._key = key + self._value = value + self._coded_value = coded_value def output(self, attrs=None, header="Set-Cookie:"): return "%s %s" % (header, self.OutputString(attrs)) @@ -379,13 +392,16 @@ def __repr__(self): def js_output(self, attrs=None): # Print javascript + output_string = self.OutputString(attrs) + if _has_control_character(output_string): + raise CookieError("Control characters are not allowed in cookies") return """ - """ % (self.OutputString(attrs).replace('"', r'\"')) + """ % (output_string.replace('"', r'\"')) def OutputString(self, attrs=None): # Build up our result diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py index 7d072d5fd67ca7..e2c7551c0b3341 100644 --- a/Lib/test/test_http_cookies.py +++ b/Lib/test/test_http_cookies.py @@ -604,6 +604,14 @@ def test_control_characters(self): with self.assertRaises(cookies.CookieError): morsel["path"] = c0 + # .__setstate__() + with self.assertRaises(cookies.CookieError): + morsel.__setstate__({'key': c0, 'value': 'val', 'coded_value': 'coded'}) + with self.assertRaises(cookies.CookieError): + morsel.__setstate__({'key': 'key', 'value': c0, 'coded_value': 'coded'}) + with self.assertRaises(cookies.CookieError): + morsel.__setstate__({'key': 'key', 'value': 'val', 'coded_value': c0}) + # .setdefault() with self.assertRaises(cookies.CookieError): morsel.setdefault("path", c0) @@ -618,6 +626,18 @@ def test_control_characters(self): with self.assertRaises(cookies.CookieError): morsel.set("path", "val", c0) + # .update() + with self.assertRaises(cookies.CookieError): + morsel.update({"path": c0}) + with self.assertRaises(cookies.CookieError): + morsel.update({c0: "val"}) + + # .__ior__() + with self.assertRaises(cookies.CookieError): + morsel |= {"path": c0} + with self.assertRaises(cookies.CookieError): + morsel |= {c0: "val"} + def test_control_characters_output(self): # Tests that even if the internals of Morsel are modified # that a call to .output() has control character safeguards. @@ -638,6 +658,24 @@ def test_control_characters_output(self): with self.assertRaises(cookies.CookieError): cookie.output() + # Tests that .js_output() also has control character safeguards. + for c0 in support.control_characters_c0(): + morsel = cookies.Morsel() + morsel.set("key", "value", "coded-value") + morsel._key = c0 # Override private variable. + cookie = cookies.SimpleCookie() + cookie["cookie"] = morsel + with self.assertRaises(cookies.CookieError): + cookie.js_output() + + morsel = cookies.Morsel() + morsel.set("key", "value", "coded-value") + morsel._coded_value = c0 # Override private variable. + cookie = cookies.SimpleCookie() + cookie["cookie"] = morsel + with self.assertRaises(cookies.CookieError): + cookie.js_output() + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(cookies)) diff --git a/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst b/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst new file mode 100644 index 00000000000000..e53a932d12fcdc --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst @@ -0,0 +1,4 @@ +Reject control characters in :class:`http.cookies.Morsel` +:meth:`~http.cookies.Morsel.update` and +:meth:`~http.cookies.BaseCookie.js_output`. +This addresses :cve:`2026-3644`. From fd50b41aa906cd3994dc2e6b884bed8f5dd605cf Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Mon, 16 Mar 2026 18:50:26 +0500 Subject: [PATCH 481/498] GH-145247: Use _PyTuple_FromPair in exceptions.c (GH-145910) --- Objects/exceptions.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index f5edc286243ee1..4e090e5dd863f1 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -13,6 +13,7 @@ #include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" #include "pycore_pyerrors.h" // struct _PyErr_SetRaisedException +#include "pycore_tuple.h" // _PyTuple_FromPair #include "osdefs.h" // SEP #include "clinic/exceptions.c.h" @@ -214,7 +215,7 @@ BaseException___reduce___impl(PyBaseExceptionObject *self) if (self->args && self->dict) return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict); else - return PyTuple_Pack(2, Py_TYPE(self), self->args); + return _PyTuple_FromPair((PyObject *)Py_TYPE(self), self->args); } /* @@ -1008,8 +1009,7 @@ _PyExc_CreateExceptionGroup(const char *msg_str, PyObject *excs) if (!msg) { return NULL; } - PyObject *args = PyTuple_Pack(2, msg, excs); - Py_DECREF(msg); + PyObject *args = _PyTuple_FromPairSteal(msg, Py_NewRef(excs)); if (!args) { return NULL; } @@ -1132,7 +1132,7 @@ BaseExceptionGroup_derive_impl(PyBaseExceptionGroupObject *self, PyObject *excs) /*[clinic end generated code: output=4307564218dfbf06 input=f72009d38e98cec1]*/ { - PyObject *init_args = PyTuple_Pack(2, self->msg, excs); + PyObject *init_args = _PyTuple_FromPair(self->msg, excs); if (!init_args) { return NULL; } @@ -1449,13 +1449,11 @@ BaseExceptionGroup_split_impl(PyBaseExceptionGroupObject *self, return NULL; } - PyObject *result = PyTuple_Pack( - 2, + assert(_Py_IsStaticImmortal(Py_None)); + PyObject *result = _PyTuple_FromPairSteal( split_result.match ? split_result.match : Py_None, split_result.rest ? split_result.rest : Py_None); - Py_XDECREF(split_result.match); - Py_XDECREF(split_result.rest); return result; } @@ -1764,8 +1762,8 @@ static PyObject* create_exception_group_class(void) { struct _Py_exc_state *state = get_exc_state(); - PyObject *bases = PyTuple_Pack( - 2, PyExc_BaseExceptionGroup, PyExc_Exception); + PyObject *bases = _PyTuple_FromPair( + PyExc_BaseExceptionGroup, PyExc_Exception); if (bases == NULL) { return NULL; } @@ -1913,7 +1911,7 @@ ImportError_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) return NULL; PyBaseExceptionObject *exc = PyBaseExceptionObject_CAST(self); if (state == Py_None) - res = PyTuple_Pack(2, Py_TYPE(self), exc->args); + res = _PyTuple_FromPair((PyObject *)Py_TYPE(self), exc->args); else res = PyTuple_Pack(3, Py_TYPE(self), exc->args, state); Py_DECREF(state); @@ -2421,7 +2419,7 @@ OSError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored)) if (self->dict) res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict); else - res = PyTuple_Pack(2, Py_TYPE(self), args); + res = _PyTuple_FromPair((PyObject *)Py_TYPE(self), args); Py_DECREF(args); return res; } From 182aea2f57002dcea39dfdfe3faf642d724dd80b Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 16 Mar 2026 21:52:56 +0800 Subject: [PATCH 482/498] gh-146018: Disable over-aggressive optimization for _GUARD_CODE_VERSION (GH-145923) --- Python/optimizer_bytecodes.c | 4 +++- Python/optimizer_cases.c.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index e0410be55652b4..f3a391b2e37ef9 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1761,7 +1761,9 @@ dummy_func(void) { PyCodeObject *co = get_current_code_object(ctx); if (co->co_version == version) { _Py_BloomFilter_Add(dependencies, co); - REPLACE_OP(this_instr, _NOP, 0, 0); + // TODO gh-144651: + // If we've previously guarded on this code version in a trace, we + // can avoid guarding it again. } else { ctx->done = true; diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 7e5b26c6d725d6..942a730e4faccf 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -4290,7 +4290,6 @@ PyCodeObject *co = get_current_code_object(ctx); if (co->co_version == version) { _Py_BloomFilter_Add(dependencies, co); - REPLACE_OP(this_instr, _NOP, 0, 0); } else { ctx->done = true; From e18abc6a1f1b60434b529d4c1ff4855acde0fd13 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Mon, 16 Mar 2026 11:08:07 -0400 Subject: [PATCH 483/498] gh-135329: Remove flaky test_repl_eio test (gh-145932) The test doesn't actually test any pyrepl code (it runs Python with -S) and has a race condition that causes intermittent timeouts on CI. --- Lib/test/test_pyrepl/eio_test_script.py | 94 ----------------------- Lib/test/test_pyrepl/test_unix_console.py | 35 +-------- 2 files changed, 1 insertion(+), 128 deletions(-) delete mode 100644 Lib/test/test_pyrepl/eio_test_script.py diff --git a/Lib/test/test_pyrepl/eio_test_script.py b/Lib/test/test_pyrepl/eio_test_script.py deleted file mode 100644 index e3ea6caef58e80..00000000000000 --- a/Lib/test/test_pyrepl/eio_test_script.py +++ /dev/null @@ -1,94 +0,0 @@ -import errno -import fcntl -import os -import pty -import signal -import sys -import termios - - -def handler(sig, f): - pass - - -def create_eio_condition(): - # SIGINT handler used to produce an EIO. - # See https://github.com/python/cpython/issues/135329. - try: - master_fd, slave_fd = pty.openpty() - child_pid = os.fork() - if child_pid == 0: - try: - os.setsid() - fcntl.ioctl(slave_fd, termios.TIOCSCTTY, 0) - child_process_group_id = os.getpgrp() - grandchild_pid = os.fork() - if grandchild_pid == 0: - os.setpgid(0, 0) # set process group for grandchild - os.dup2(slave_fd, 0) # redirect stdin - if slave_fd > 2: - os.close(slave_fd) - # Fork grandchild for terminal control manipulation - if os.fork() == 0: - sys.exit(0) # exit the child process that was just obtained - else: - try: - os.tcsetpgrp(0, child_process_group_id) - except OSError: - pass - sys.exit(0) - else: - # Back to child - try: - os.setpgid(grandchild_pid, grandchild_pid) - except ProcessLookupError: - pass - os.tcsetpgrp(slave_fd, grandchild_pid) - if slave_fd > 2: - os.close(slave_fd) - os.waitpid(grandchild_pid, 0) - # Manipulate terminal control to create EIO condition - os.tcsetpgrp(master_fd, child_process_group_id) - # Now try to read from master - this might cause EIO - try: - os.read(master_fd, 1) - except OSError as e: - if e.errno == errno.EIO: - print(f"Setup created EIO condition: {e}", file=sys.stderr) - sys.exit(0) - except Exception as setup_e: - print(f"Setup error: {setup_e}", file=sys.stderr) - sys.exit(1) - else: - # Parent process - os.close(slave_fd) - os.waitpid(child_pid, 0) - # Now replace stdin with master_fd and try to read - os.dup2(master_fd, 0) - os.close(master_fd) - # This should now trigger EIO - print(f"Unexpectedly got input: {input()!r}", file=sys.stderr) - sys.exit(0) - except OSError as e: - if e.errno == errno.EIO: - print(f"Got EIO: {e}", file=sys.stderr) - sys.exit(1) - elif e.errno == errno.ENXIO: - print(f"Got ENXIO (no such device): {e}", file=sys.stderr) - sys.exit(1) # Treat ENXIO as success too - else: - print(f"Got other OSError: errno={e.errno} {e}", file=sys.stderr) - sys.exit(2) - except EOFError as e: - print(f"Got EOFError: {e}", file=sys.stderr) - sys.exit(3) - except Exception as e: - print(f"Got unexpected error: {type(e).__name__}: {e}", file=sys.stderr) - sys.exit(4) - - -if __name__ == "__main__": - # Set up signal handler for coordination - signal.signal(signal.SIGUSR1, lambda *a: create_eio_condition()) - print("READY", flush=True) - signal.pause() diff --git a/Lib/test/test_pyrepl/test_unix_console.py b/Lib/test/test_pyrepl/test_unix_console.py index 680adbc2d968f0..a1ee6d4878fe93 100644 --- a/Lib/test/test_pyrepl/test_unix_console.py +++ b/Lib/test/test_pyrepl/test_unix_console.py @@ -2,14 +2,12 @@ import itertools import os import signal -import subprocess import sys import threading import unittest from functools import partial -from test import support from test.support import os_helper, force_not_colorized_test_class -from test.support import script_helper, threading_helper +from test.support import threading_helper from unittest import TestCase from unittest.mock import MagicMock, call, patch, ANY, Mock @@ -369,34 +367,3 @@ def test_eio_error_handling_in_restore(self, mock_tcgetattr, mock_tcsetattr): # EIO error should be handled gracefully in restore() console.restore() - - @unittest.skipUnless(sys.platform == "linux", "Only valid on Linux") - def test_repl_eio(self): - # Use the pty-based approach to simulate EIO error - script_path = os.path.join(os.path.dirname(__file__), "eio_test_script.py") - - proc = script_helper.spawn_python( - "-S", script_path, - stderr=subprocess.PIPE, - text=True - ) - - ready_line = proc.stdout.readline().strip() - if ready_line != "READY" or proc.poll() is not None: - self.fail("Child process failed to start properly") - - os.kill(proc.pid, signal.SIGUSR1) - # sleep for pty to settle - _, err = proc.communicate(timeout=support.LONG_TIMEOUT) - self.assertEqual( - proc.returncode, - 1, - f"Expected EIO/ENXIO error, got return code {proc.returncode}", - ) - self.assertTrue( - ( - "Got EIO:" in err - or "Got ENXIO:" in err - ), - f"Expected EIO/ENXIO error message in stderr: {err}", - ) From 81ef1b73175378543534ebe1f148c22deb8239b3 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Mon, 16 Mar 2026 23:58:18 +0800 Subject: [PATCH 484/498] gh-144888: Replace bloom filter linked lists with continuous arrays to optimize executor invalidating performance (GH-145873) --- Include/internal/pycore_interp_structs.h | 6 +- Include/internal/pycore_optimizer.h | 6 +- InternalDocs/jit.md | 4 +- Modules/_testinternalcapi.c | 6 +- Objects/funcobject.c | 1 - Python/jit.c | 19 +++- Python/optimizer.c | 121 ++++++++++++----------- Python/pylifecycle.c | 6 ++ Python/pystate.c | 5 +- 9 files changed, 103 insertions(+), 71 deletions(-) diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 776fb9575c2365..e2008f8303e21b 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -14,6 +14,7 @@ extern "C" { #include "pycore_structs.h" // PyHamtObject #include "pycore_tstate.h" // _PyThreadStateImpl #include "pycore_typedefs.h" // _PyRuntimeState +#include "pycore_uop.h" // _PyBloomFilter #define CODE_MAX_WATCHERS 8 #define CONTEXT_MAX_WATCHERS 8 @@ -972,7 +973,10 @@ struct _is { // Optimization configuration (thresholds and flags for JIT and interpreter) _PyOptimizationConfig opt_config; - struct _PyExecutorObject *executor_list_head; + _PyBloomFilter *executor_blooms; // Contiguous bloom filter array + struct _PyExecutorObject **executor_ptrs; // Corresponding executor pointer array + size_t executor_count; // Number of valid executors + size_t executor_capacity; // Array capacity struct _PyExecutorObject *executor_deletion_list_head; struct _PyExecutorObject *cold_executor; struct _PyExecutorObject *cold_dynamic_executor; diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index c63f0167a0f64a..cea9fcce237301 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -128,8 +128,8 @@ typedef struct { bool cold; uint8_t pending_deletion; int32_t index; // Index of ENTER_EXECUTOR (if code isn't NULL, below). - _PyBloomFilter bloom; - _PyExecutorLinkListNode links; + int32_t bloom_array_idx; // Index in interp->executor_blooms/executor_ptrs. + _PyExecutorLinkListNode links; // Used by deletion list. PyCodeObject *code; // Weak (NULL if no corresponding ENTER_EXECUTOR). } _PyVMData; @@ -157,7 +157,7 @@ typedef struct _PyExecutorObject { // Export for '_opcode' shared extension (JIT compiler). PyAPI_FUNC(_PyExecutorObject*) _Py_GetExecutor(PyCodeObject *code, int offset); -void _Py_ExecutorInit(_PyExecutorObject *, const _PyBloomFilter *); +int _Py_ExecutorInit(_PyExecutorObject *, const _PyBloomFilter *); void _Py_ExecutorDetach(_PyExecutorObject *); void _Py_BloomFilter_Init(_PyBloomFilter *); void _Py_BloomFilter_Add(_PyBloomFilter *bloom, void *obj); diff --git a/InternalDocs/jit.md b/InternalDocs/jit.md index 1740b22b85f77b..decfccad2d8d37 100644 --- a/InternalDocs/jit.md +++ b/InternalDocs/jit.md @@ -78,8 +78,8 @@ and execution returns to the adaptive interpreter. ## Invalidating Executors In addition to being stored on the code object, each executor is also -inserted into a list of all executors, which is stored in the interpreter -state's `executor_list_head` field. This list is used when it is necessary +inserted into contiguous arrays (`executor_blooms` and `executor_ptrs`) +stored in the interpreter state. These arrays are used when it is necessary to invalidate executors because values they used in their construction may have changed. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index aa5911ef2fb449..8c316b7c8ddda0 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -278,10 +278,8 @@ get_jit_code_ranges(PyObject *self, PyObject *Py_UNUSED(args)) if (interp == NULL) { return ranges; } - for (_PyExecutorObject *exec = interp->executor_list_head; - exec != NULL; - exec = exec->vm_data.links.next) - { + for (size_t i = 0; i < interp->executor_count; i++) { + _PyExecutorObject *exec = interp->executor_ptrs[i]; if (exec->jit_code == NULL || exec->jit_size == 0) { continue; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index fc32826fb3a861..a7a3d9c78ef3d0 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -12,7 +12,6 @@ #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_stats.h" #include "pycore_weakref.h" // FT_CLEAR_WEAKREFS() -#include "pycore_optimizer.h" // _Py_Executors_InvalidateDependency static const char * func_event_name(PyFunction_WatchEvent event) { diff --git a/Python/jit.c b/Python/jit.c index 3e0a0aa8bfcc81..4990c743224d3c 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -62,6 +62,23 @@ jit_error(const char *message) static size_t _Py_jit_shim_size = 0; +static int +address_in_executor_array(_PyExecutorObject **ptrs, size_t count, uintptr_t addr) +{ + for (size_t i = 0; i < count; i++) { + _PyExecutorObject *exec = ptrs[i]; + if (exec->jit_code == NULL || exec->jit_size == 0) { + continue; + } + uintptr_t start = (uintptr_t)exec->jit_code; + uintptr_t end = start + exec->jit_size; + if (addr >= start && addr < end) { + return 1; + } + } + return 0; +} + static int address_in_executor_list(_PyExecutorObject *head, uintptr_t addr) { @@ -94,7 +111,7 @@ _PyJIT_AddressInJitCode(PyInterpreterState *interp, uintptr_t addr) return 1; } } - if (address_in_executor_list(interp->executor_list_head, addr)) { + if (address_in_executor_array(interp->executor_ptrs, interp->executor_count, addr)) { return 1; } if (address_in_executor_list(interp->executor_deletion_list_head, addr)) { diff --git a/Python/optimizer.c b/Python/optimizer.c index 7315bb6b9f603d..a9e788d0dcb1d5 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1379,7 +1379,10 @@ make_executor_from_uops(_PyThreadStateImpl *tstate, _PyUOpInstruction *buffer, i // linking of executor. Otherwise, the GC tries to untrack a // still untracked object during dealloc. _PyObject_GC_TRACK(executor); - _Py_ExecutorInit(executor, dependencies); + if (_Py_ExecutorInit(executor, dependencies) < 0) { + Py_DECREF(executor); + return NULL; + } #ifdef Py_DEBUG char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); int lltrace = 0; @@ -1646,59 +1649,63 @@ bloom_filter_may_contain(_PyBloomFilter *bloom, _PyBloomFilter *hashes) return true; } -static void -link_executor(_PyExecutorObject *executor) +static int +link_executor(_PyExecutorObject *executor, const _PyBloomFilter *bloom) { PyInterpreterState *interp = _PyInterpreterState_GET(); - _PyExecutorLinkListNode *links = &executor->vm_data.links; - _PyExecutorObject *head = interp->executor_list_head; - if (head == NULL) { - interp->executor_list_head = executor; - links->previous = NULL; - links->next = NULL; - } - else { - assert(head->vm_data.links.previous == NULL); - links->previous = NULL; - links->next = head; - head->vm_data.links.previous = executor; - interp->executor_list_head = executor; - } - /* executor_list_head must be first in list */ - assert(interp->executor_list_head->vm_data.links.previous == NULL); + if (interp->executor_count == interp->executor_capacity) { + size_t new_cap = interp->executor_capacity ? interp->executor_capacity * 2 : 64; + _PyBloomFilter *new_blooms = PyMem_Realloc( + interp->executor_blooms, new_cap * sizeof(_PyBloomFilter)); + if (new_blooms == NULL) { + return -1; + } + _PyExecutorObject **new_ptrs = PyMem_Realloc( + interp->executor_ptrs, new_cap * sizeof(_PyExecutorObject *)); + if (new_ptrs == NULL) { + /* Revert blooms realloc — the old pointer may have been freed by + * a successful realloc, but new_blooms is the valid pointer. */ + interp->executor_blooms = new_blooms; + return -1; + } + interp->executor_blooms = new_blooms; + interp->executor_ptrs = new_ptrs; + interp->executor_capacity = new_cap; + } + size_t idx = interp->executor_count++; + interp->executor_blooms[idx] = *bloom; + interp->executor_ptrs[idx] = executor; + executor->vm_data.bloom_array_idx = (int32_t)idx; + return 0; } static void unlink_executor(_PyExecutorObject *executor) { - _PyExecutorLinkListNode *links = &executor->vm_data.links; - _PyExecutorObject *next = links->next; - _PyExecutorObject *prev = links->previous; - if (next != NULL) { - next->vm_data.links.previous = prev; - } - if (prev != NULL) { - prev->vm_data.links.next = next; - } - else { - // prev == NULL implies that executor is the list head - PyInterpreterState *interp = PyInterpreterState_Get(); - assert(interp->executor_list_head == executor); - interp->executor_list_head = next; + PyInterpreterState *interp = PyInterpreterState_Get(); + int32_t idx = executor->vm_data.bloom_array_idx; + assert(idx >= 0 && (size_t)idx < interp->executor_count); + size_t last = --interp->executor_count; + if ((size_t)idx != last) { + /* Swap-remove: move the last element into the vacated slot */ + interp->executor_blooms[idx] = interp->executor_blooms[last]; + interp->executor_ptrs[idx] = interp->executor_ptrs[last]; + interp->executor_ptrs[idx]->vm_data.bloom_array_idx = idx; } + executor->vm_data.bloom_array_idx = -1; } /* This must be called by optimizers before using the executor */ -void +int _Py_ExecutorInit(_PyExecutorObject *executor, const _PyBloomFilter *dependency_set) { executor->vm_data.valid = true; executor->vm_data.pending_deletion = 0; executor->vm_data.code = NULL; - for (int i = 0; i < _Py_BLOOM_FILTER_WORDS; i++) { - executor->vm_data.bloom.bits[i] = dependency_set->bits[i]; + if (link_executor(executor, dependency_set) < 0) { + return -1; } - link_executor(executor); + return 0; } static _PyExecutorObject * @@ -1809,11 +1816,15 @@ void _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj) { assert(executor->vm_data.valid); - _Py_BloomFilter_Add(&executor->vm_data.bloom, obj); + PyInterpreterState *interp = _PyInterpreterState_GET(); + int32_t idx = executor->vm_data.bloom_array_idx; + assert(idx >= 0 && (size_t)idx < interp->executor_count); + _Py_BloomFilter_Add(&interp->executor_blooms[idx], obj); } /* Invalidate all executors that depend on `obj` - * May cause other executors to be invalidated as well + * May cause other executors to be invalidated as well. + * Uses contiguous bloom filter array for cache-friendly scanning. */ void _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is_invalidation) @@ -1821,23 +1832,20 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is _PyBloomFilter obj_filter; _Py_BloomFilter_Init(&obj_filter); _Py_BloomFilter_Add(&obj_filter, obj); - /* Walk the list of executors */ - /* TO DO -- Use a tree to avoid traversing as many objects */ + /* Scan contiguous bloom filter array */ PyObject *invalidate = PyList_New(0); if (invalidate == NULL) { goto error; } /* Clearing an executor can clear others, so we need to make a list of * executors to invalidate first */ - for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { - assert(exec->vm_data.valid); - _PyExecutorObject *next = exec->vm_data.links.next; - if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter) && - PyList_Append(invalidate, (PyObject *)exec)) + for (size_t i = 0; i < interp->executor_count; i++) { + assert(interp->executor_ptrs[i]->vm_data.valid); + if (bloom_filter_may_contain(&interp->executor_blooms[i], &obj_filter) && + PyList_Append(invalidate, (PyObject *)interp->executor_ptrs[i])) { goto error; } - exec = next; } for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) { PyObject *exec = PyList_GET_ITEM(invalidate, i); @@ -1859,8 +1867,9 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is void _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation) { - while (interp->executor_list_head) { - _PyExecutorObject *executor = interp->executor_list_head; + while (interp->executor_count > 0) { + /* Invalidate from the end to avoid repeated swap-remove shifts */ + _PyExecutorObject *executor = interp->executor_ptrs[interp->executor_count - 1]; assert(executor->vm_data.valid); if (executor->vm_data.code) { // Clear the entire code object so its co_executors array be freed: @@ -1878,8 +1887,7 @@ _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation) void _Py_Executors_InvalidateCold(PyInterpreterState *interp) { - /* Walk the list of executors */ - /* TO DO -- Use a tree to avoid traversing as many objects */ + /* Scan contiguous executor array */ PyObject *invalidate = PyList_New(0); if (invalidate == NULL) { goto error; @@ -1887,9 +1895,9 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp) /* Clearing an executor can deallocate others, so we need to make a list of * executors to invalidate first */ - for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { + for (size_t i = 0; i < interp->executor_count; i++) { + _PyExecutorObject *exec = interp->executor_ptrs[i]; assert(exec->vm_data.valid); - _PyExecutorObject *next = exec->vm_data.links.next; if (exec->vm_data.cold && PyList_Append(invalidate, (PyObject *)exec) < 0) { goto error; @@ -1897,8 +1905,6 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp) else { exec->vm_data.cold = true; } - - exec = next; } for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) { PyObject *exec = PyList_GET_ITEM(invalidate, i); @@ -2142,9 +2148,8 @@ _PyDumpExecutors(FILE *out) fprintf(out, " rankdir = \"LR\"\n\n"); fprintf(out, " node [colorscheme=greys9]\n"); PyInterpreterState *interp = PyInterpreterState_Get(); - for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { - executor_to_gv(exec, out); - exec = exec->vm_data.links.next; + for (size_t i = 0; i < interp->executor_count; i++) { + executor_to_gv(interp->executor_ptrs[i], out); } fprintf(out, "}\n\n"); return 0; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 2b8e9a02cb6184..68052a91d6a1f1 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1761,6 +1761,12 @@ finalize_modules(PyThreadState *tstate) interp->compiling = false; #ifdef _Py_TIER2 _Py_Executors_InvalidateAll(interp, 0); + PyMem_Free(interp->executor_blooms); + PyMem_Free(interp->executor_ptrs); + interp->executor_blooms = NULL; + interp->executor_ptrs = NULL; + interp->executor_count = 0; + interp->executor_capacity = 0; #endif // Stop watching __builtin__ modifications diff --git a/Python/pystate.c b/Python/pystate.c index 17b8430b19c188..fcb73b4dcefe1d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -597,7 +597,10 @@ init_interpreter(PyInterpreterState *interp, interp->_code_object_generation = 0; interp->jit = false; interp->compiling = false; - interp->executor_list_head = NULL; + interp->executor_blooms = NULL; + interp->executor_ptrs = NULL; + interp->executor_count = 0; + interp->executor_capacity = 0; interp->executor_deletion_list_head = NULL; interp->executor_creation_counter = JIT_CLEANUP_THRESHOLD; From 3d0824aef261895bad55f7e1fa7267a926206924 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 17 Mar 2026 00:18:59 +0800 Subject: [PATCH 485/498] gh-127958: Trace from RESUME in the JIT (GH-145905) --- Include/internal/pycore_backoff.h | 14 + Include/internal/pycore_code.h | 1 + Include/internal/pycore_interp_structs.h | 3 + Include/internal/pycore_magic_number.h | 3 +- Include/internal/pycore_opcode_metadata.h | 18 +- Include/internal/pycore_optimizer.h | 2 + Include/internal/pycore_uop.h | 2 +- Include/internal/pycore_uop_ids.h | 309 ++++++------- Include/opcode_ids.h | 31 +- Lib/_opcode_metadata.py | 32 +- Lib/opcode.py | 3 + Lib/test/test_capi/test_opt.py | 24 +- Lib/test/test_code.py | 5 +- Lib/test/test_compile.py | 4 +- Lib/test/test_dis.py | 433 +++++++++--------- Lib/test/test_monitoring.py | 151 +++--- ...-03-13-09-48-57.gh-issue-127958.U-znTv.rst | 1 + Modules/_testinternalcapi.c | 8 + Modules/_testinternalcapi/test_cases.c.h | 115 ++++- Modules/_testinternalcapi/test_targets.h | 9 +- Objects/codeobject.c | 7 +- Objects/genobject.c | 1 + Programs/test_frozenmain.h | 70 +-- Python/assemble.c | 2 +- Python/bytecodes.c | 46 +- Python/ceval.c | 5 +- Python/executor_cases.c.h | 2 - Python/generated_cases.c.h | 115 ++++- Python/instrumentation.c | 1 + Python/opcode_targets.h | 9 +- Python/optimizer.c | 34 +- Python/optimizer_cases.c.h | 2 - Python/pystate.c | 8 + Python/specialize.c | 30 +- 34 files changed, 909 insertions(+), 591 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-13-09-48-57.gh-issue-127958.U-znTv.rst diff --git a/Include/internal/pycore_backoff.h b/Include/internal/pycore_backoff.h index ee907ae0534e4f..38dd82f6fc8a14 100644 --- a/Include/internal/pycore_backoff.h +++ b/Include/internal/pycore_backoff.h @@ -135,6 +135,20 @@ initial_jump_backoff_counter(_PyOptimizationConfig *opt_config) opt_config->jump_backward_initial_backoff); } +// This needs to be around 2-4x of JUMP_BACKWARD_INITIAL_VALUE +// The reasoning is that we always want loop traces to form and inline +// functions before functions themselves warm up and link to them instead +// of inlining. +#define RESUME_INITIAL_VALUE 8190 +#define RESUME_INITIAL_BACKOFF 6 +static inline _Py_BackoffCounter +initial_resume_backoff_counter(_PyOptimizationConfig *opt_config) +{ + return make_backoff_counter( + opt_config->resume_initial_value, + opt_config->resume_initial_backoff); +} + /* Initial exit temperature. * Must be larger than ADAPTIVE_COOLDOWN_VALUE, * otherwise when a side exit warms up we may construct diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index efae3b38654c41..376e68a4c8773c 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -323,6 +323,7 @@ PyAPI_FUNC(void) _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr); PyAPI_FUNC(void) _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr); PyAPI_FUNC(void) _Py_GatherStats_GetIter(_PyStackRef iterable); PyAPI_FUNC(void) _Py_Specialize_CallFunctionEx(_PyStackRef func_st, _Py_CODEUNIT *instr); +PyAPI_FUNC(void) _Py_Specialize_Resume(_Py_CODEUNIT *instr, PyThreadState *tstate, _PyInterpreterFrame *frame); // Utility functions for reading/writing 32/64-bit values in the inline caches. // Great care should be taken to ensure that these functions remain correct and diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index e2008f8303e21b..4822360a8f08d0 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -414,6 +414,9 @@ typedef struct _PyOptimizationConfig { uint16_t jump_backward_initial_value; uint16_t jump_backward_initial_backoff; + uint16_t resume_initial_value; + uint16_t resume_initial_backoff; + // JIT optimization thresholds uint16_t side_exit_initial_value; uint16_t side_exit_initial_backoff; diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 3fcf650426d36d..ec9cfe432371c7 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -292,6 +292,7 @@ Known values: Python 3.15a4 3659 (Add CALL_FUNCTION_EX specialization) Python 3.15a4 3660 (Change generator preamble code) Python 3.15a4 3661 (Lazy imports IMPORT_NAME opcode changes) + Python 3.15a6 3662 (Add counter to RESUME) Python 3.16 will start with 3700 @@ -305,7 +306,7 @@ PC/launcher.c must also be updated. */ -#define PYC_MAGIC_NUMBER 3661 +#define PYC_MAGIC_NUMBER 3662 /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes (little-endian) and then appending b'\r\n'. */ #define PYC_MAGIC_NUMBER_TOKEN \ diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index fc5689c5afe13a..c46015c4d98239 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -426,6 +426,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case RESUME_CHECK: return 0; + case RESUME_CHECK_JIT: + return 0; case RETURN_GENERATOR: return 0; case RETURN_VALUE: @@ -917,6 +919,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 0; case RESUME_CHECK: return 0; + case RESUME_CHECK_JIT: + return 0; case RETURN_GENERATOR: return 1; case RETURN_VALUE: @@ -1209,7 +1213,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, - [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [INTERPRETER_EXIT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, @@ -1278,8 +1282,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG }, [RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [RESERVED] = { true, INSTR_FMT_IX, 0 }, - [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [RESUME] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [RESUME_CHECK] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG }, + [RESUME_CHECK_JIT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, @@ -1493,7 +1498,7 @@ _PyOpcode_macro_expansion[256] = { [POP_TOP] = { .nuops = 1, .uops = { { _POP_TOP, OPARG_SIMPLE, 0 } } }, [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, OPARG_SIMPLE, 0 } } }, [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, OPARG_SIMPLE, 0 } } }, - [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, OPARG_SIMPLE, 0 } } }, + [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, OPARG_SIMPLE, 1 } } }, [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } }, [RETURN_VALUE] = { .nuops = 2, .uops = { { _MAKE_HEAP_SAFE, OPARG_SIMPLE, 0 }, { _RETURN_VALUE, OPARG_SIMPLE, 0 } } }, [SEND_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS_GEN_FUNC, OPARG_SIMPLE, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, @@ -1734,6 +1739,7 @@ const char *_PyOpcode_OpName[267] = { [RESERVED] = "RESERVED", [RESUME] = "RESUME", [RESUME_CHECK] = "RESUME_CHECK", + [RESUME_CHECK_JIT] = "RESUME_CHECK_JIT", [RETURN_GENERATOR] = "RETURN_GENERATOR", [RETURN_VALUE] = "RETURN_VALUE", [SEND] = "SEND", @@ -1785,6 +1791,7 @@ const char *_PyOpcode_OpName[267] = { PyAPI_DATA(const uint8_t) _PyOpcode_Caches[256]; #ifdef NEED_OPCODE_METADATA const uint8_t _PyOpcode_Caches[256] = { + [RESUME] = 1, [TO_BOOL] = 3, [STORE_SUBSCR] = 1, [SEND] = 1, @@ -1818,7 +1825,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [125] = 125, [126] = 126, [127] = 127, - [213] = 213, [214] = 214, [215] = 215, [216] = 216, @@ -2026,6 +2032,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [RESERVED] = RESERVED, [RESUME] = RESUME, [RESUME_CHECK] = RESUME, + [RESUME_CHECK_JIT] = RESUME, [RETURN_GENERATOR] = RETURN_GENERATOR, [RETURN_VALUE] = RETURN_VALUE, [SEND] = SEND, @@ -2079,7 +2086,6 @@ const uint8_t _PyOpcode_Deopt[256] = { case 125: \ case 126: \ case 127: \ - case 213: \ case 214: \ case 215: \ case 216: \ diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index cea9fcce237301..8b52d77538abf2 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -361,6 +361,8 @@ _PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, int oparg, _PyExecutorObject *current_executor); PyAPI_FUNC(void) _PyJit_FinalizeTracing(PyThreadState *tstate, int err); +PyAPI_FUNC(bool) _PyJit_EnterExecutorShouldStopTracing(int og_opcode); + void _PyPrintExecutor(_PyExecutorObject *executor, const _PyUOpInstruction *marker); void _PyJit_TracerFree(_PyThreadStateImpl *_tstate); diff --git a/Include/internal/pycore_uop.h b/Include/internal/pycore_uop.h index f9be01acb57197..e7ac7d59ff7e27 100644 --- a/Include/internal/pycore_uop.h +++ b/Include/internal/pycore_uop.h @@ -36,7 +36,7 @@ typedef struct _PyUOpInstruction{ } _PyUOpInstruction; // This is the length of the trace we translate initially. -#ifdef Py_DEBUG +#if defined(Py_DEBUG) && defined(_Py_JIT) // With asserts, the stencils are a lot larger #define UOP_MAX_TRACE_LENGTH 1000 #else diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 451c0dd5732d85..d29d98d3f16697 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -330,17 +330,16 @@ extern "C" { #define _PY_FRAME_EX 547 #define _PY_FRAME_GENERAL 548 #define _PY_FRAME_KW 549 -#define _QUICKEN_RESUME 550 -#define _RECORD_4OS 551 -#define _RECORD_BOUND_METHOD 552 -#define _RECORD_CALLABLE 553 -#define _RECORD_CODE 554 -#define _RECORD_NOS 555 -#define _RECORD_NOS_GEN_FUNC 556 -#define _RECORD_TOS 557 -#define _RECORD_TOS_TYPE 558 -#define _REPLACE_WITH_TRUE 559 -#define _RESUME_CHECK RESUME_CHECK +#define _RECORD_4OS 550 +#define _RECORD_BOUND_METHOD 551 +#define _RECORD_CALLABLE 552 +#define _RECORD_CODE 553 +#define _RECORD_NOS 554 +#define _RECORD_NOS_GEN_FUNC 555 +#define _RECORD_TOS 556 +#define _RECORD_TOS_TYPE 557 +#define _REPLACE_WITH_TRUE 558 +#define _RESUME_CHECK 559 #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE 560 #define _SAVE_RETURN_OFFSET 561 @@ -1141,152 +1140,148 @@ extern "C" { #define _PY_FRAME_EX_r31 1342 #define _PY_FRAME_GENERAL_r01 1343 #define _PY_FRAME_KW_r11 1344 -#define _QUICKEN_RESUME_r00 1345 -#define _QUICKEN_RESUME_r11 1346 -#define _QUICKEN_RESUME_r22 1347 -#define _QUICKEN_RESUME_r33 1348 -#define _REPLACE_WITH_TRUE_r02 1349 -#define _REPLACE_WITH_TRUE_r12 1350 -#define _REPLACE_WITH_TRUE_r23 1351 -#define _RESUME_CHECK_r00 1352 -#define _RESUME_CHECK_r11 1353 -#define _RESUME_CHECK_r22 1354 -#define _RESUME_CHECK_r33 1355 -#define _RETURN_GENERATOR_r01 1356 -#define _RETURN_VALUE_r11 1357 -#define _SAVE_RETURN_OFFSET_r00 1358 -#define _SAVE_RETURN_OFFSET_r11 1359 -#define _SAVE_RETURN_OFFSET_r22 1360 -#define _SAVE_RETURN_OFFSET_r33 1361 -#define _SEND_r22 1362 -#define _SEND_GEN_FRAME_r22 1363 -#define _SETUP_ANNOTATIONS_r00 1364 -#define _SET_ADD_r10 1365 -#define _SET_FUNCTION_ATTRIBUTE_r01 1366 -#define _SET_FUNCTION_ATTRIBUTE_r11 1367 -#define _SET_FUNCTION_ATTRIBUTE_r21 1368 -#define _SET_FUNCTION_ATTRIBUTE_r32 1369 -#define _SET_IP_r00 1370 -#define _SET_IP_r11 1371 -#define _SET_IP_r22 1372 -#define _SET_IP_r33 1373 -#define _SET_UPDATE_r10 1374 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1375 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1376 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1377 -#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1378 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1379 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1380 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1381 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1382 -#define _SPILL_OR_RELOAD_r01 1383 -#define _SPILL_OR_RELOAD_r02 1384 -#define _SPILL_OR_RELOAD_r03 1385 -#define _SPILL_OR_RELOAD_r10 1386 -#define _SPILL_OR_RELOAD_r12 1387 -#define _SPILL_OR_RELOAD_r13 1388 -#define _SPILL_OR_RELOAD_r20 1389 -#define _SPILL_OR_RELOAD_r21 1390 -#define _SPILL_OR_RELOAD_r23 1391 -#define _SPILL_OR_RELOAD_r30 1392 -#define _SPILL_OR_RELOAD_r31 1393 -#define _SPILL_OR_RELOAD_r32 1394 -#define _START_EXECUTOR_r00 1395 -#define _STORE_ATTR_r20 1396 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1397 -#define _STORE_ATTR_SLOT_r21 1398 -#define _STORE_ATTR_WITH_HINT_r21 1399 -#define _STORE_DEREF_r10 1400 -#define _STORE_FAST_LOAD_FAST_r11 1401 -#define _STORE_FAST_STORE_FAST_r20 1402 -#define _STORE_GLOBAL_r10 1403 -#define _STORE_NAME_r10 1404 -#define _STORE_SLICE_r30 1405 -#define _STORE_SUBSCR_r30 1406 -#define _STORE_SUBSCR_DICT_r31 1407 -#define _STORE_SUBSCR_LIST_INT_r32 1408 -#define _SWAP_r11 1409 -#define _SWAP_2_r02 1410 -#define _SWAP_2_r12 1411 -#define _SWAP_2_r22 1412 -#define _SWAP_2_r33 1413 -#define _SWAP_3_r03 1414 -#define _SWAP_3_r13 1415 -#define _SWAP_3_r23 1416 -#define _SWAP_3_r33 1417 -#define _SWAP_FAST_r01 1418 -#define _SWAP_FAST_r11 1419 -#define _SWAP_FAST_r22 1420 -#define _SWAP_FAST_r33 1421 -#define _SWAP_FAST_0_r01 1422 -#define _SWAP_FAST_0_r11 1423 -#define _SWAP_FAST_0_r22 1424 -#define _SWAP_FAST_0_r33 1425 -#define _SWAP_FAST_1_r01 1426 -#define _SWAP_FAST_1_r11 1427 -#define _SWAP_FAST_1_r22 1428 -#define _SWAP_FAST_1_r33 1429 -#define _SWAP_FAST_2_r01 1430 -#define _SWAP_FAST_2_r11 1431 -#define _SWAP_FAST_2_r22 1432 -#define _SWAP_FAST_2_r33 1433 -#define _SWAP_FAST_3_r01 1434 -#define _SWAP_FAST_3_r11 1435 -#define _SWAP_FAST_3_r22 1436 -#define _SWAP_FAST_3_r33 1437 -#define _SWAP_FAST_4_r01 1438 -#define _SWAP_FAST_4_r11 1439 -#define _SWAP_FAST_4_r22 1440 -#define _SWAP_FAST_4_r33 1441 -#define _SWAP_FAST_5_r01 1442 -#define _SWAP_FAST_5_r11 1443 -#define _SWAP_FAST_5_r22 1444 -#define _SWAP_FAST_5_r33 1445 -#define _SWAP_FAST_6_r01 1446 -#define _SWAP_FAST_6_r11 1447 -#define _SWAP_FAST_6_r22 1448 -#define _SWAP_FAST_6_r33 1449 -#define _SWAP_FAST_7_r01 1450 -#define _SWAP_FAST_7_r11 1451 -#define _SWAP_FAST_7_r22 1452 -#define _SWAP_FAST_7_r33 1453 -#define _TIER2_RESUME_CHECK_r00 1454 -#define _TIER2_RESUME_CHECK_r11 1455 -#define _TIER2_RESUME_CHECK_r22 1456 -#define _TIER2_RESUME_CHECK_r33 1457 -#define _TO_BOOL_r11 1458 -#define _TO_BOOL_BOOL_r01 1459 -#define _TO_BOOL_BOOL_r11 1460 -#define _TO_BOOL_BOOL_r22 1461 -#define _TO_BOOL_BOOL_r33 1462 -#define _TO_BOOL_INT_r02 1463 -#define _TO_BOOL_INT_r12 1464 -#define _TO_BOOL_INT_r23 1465 -#define _TO_BOOL_LIST_r02 1466 -#define _TO_BOOL_LIST_r12 1467 -#define _TO_BOOL_LIST_r23 1468 -#define _TO_BOOL_NONE_r01 1469 -#define _TO_BOOL_NONE_r11 1470 -#define _TO_BOOL_NONE_r22 1471 -#define _TO_BOOL_NONE_r33 1472 -#define _TO_BOOL_STR_r02 1473 -#define _TO_BOOL_STR_r12 1474 -#define _TO_BOOL_STR_r23 1475 -#define _TRACE_RECORD_r00 1476 -#define _UNARY_INVERT_r12 1477 -#define _UNARY_NEGATIVE_r12 1478 -#define _UNARY_NOT_r01 1479 -#define _UNARY_NOT_r11 1480 -#define _UNARY_NOT_r22 1481 -#define _UNARY_NOT_r33 1482 -#define _UNPACK_EX_r10 1483 -#define _UNPACK_SEQUENCE_r10 1484 -#define _UNPACK_SEQUENCE_LIST_r10 1485 -#define _UNPACK_SEQUENCE_TUPLE_r10 1486 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1487 -#define _WITH_EXCEPT_START_r33 1488 -#define _YIELD_VALUE_r11 1489 -#define MAX_UOP_REGS_ID 1489 +#define _REPLACE_WITH_TRUE_r02 1345 +#define _REPLACE_WITH_TRUE_r12 1346 +#define _REPLACE_WITH_TRUE_r23 1347 +#define _RESUME_CHECK_r00 1348 +#define _RESUME_CHECK_r11 1349 +#define _RESUME_CHECK_r22 1350 +#define _RESUME_CHECK_r33 1351 +#define _RETURN_GENERATOR_r01 1352 +#define _RETURN_VALUE_r11 1353 +#define _SAVE_RETURN_OFFSET_r00 1354 +#define _SAVE_RETURN_OFFSET_r11 1355 +#define _SAVE_RETURN_OFFSET_r22 1356 +#define _SAVE_RETURN_OFFSET_r33 1357 +#define _SEND_r22 1358 +#define _SEND_GEN_FRAME_r22 1359 +#define _SETUP_ANNOTATIONS_r00 1360 +#define _SET_ADD_r10 1361 +#define _SET_FUNCTION_ATTRIBUTE_r01 1362 +#define _SET_FUNCTION_ATTRIBUTE_r11 1363 +#define _SET_FUNCTION_ATTRIBUTE_r21 1364 +#define _SET_FUNCTION_ATTRIBUTE_r32 1365 +#define _SET_IP_r00 1366 +#define _SET_IP_r11 1367 +#define _SET_IP_r22 1368 +#define _SET_IP_r33 1369 +#define _SET_UPDATE_r10 1370 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r02 1371 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r12 1372 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r22 1373 +#define _SHUFFLE_2_LOAD_CONST_INLINE_BORROW_r32 1374 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1375 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1376 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1377 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1378 +#define _SPILL_OR_RELOAD_r01 1379 +#define _SPILL_OR_RELOAD_r02 1380 +#define _SPILL_OR_RELOAD_r03 1381 +#define _SPILL_OR_RELOAD_r10 1382 +#define _SPILL_OR_RELOAD_r12 1383 +#define _SPILL_OR_RELOAD_r13 1384 +#define _SPILL_OR_RELOAD_r20 1385 +#define _SPILL_OR_RELOAD_r21 1386 +#define _SPILL_OR_RELOAD_r23 1387 +#define _SPILL_OR_RELOAD_r30 1388 +#define _SPILL_OR_RELOAD_r31 1389 +#define _SPILL_OR_RELOAD_r32 1390 +#define _START_EXECUTOR_r00 1391 +#define _STORE_ATTR_r20 1392 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1393 +#define _STORE_ATTR_SLOT_r21 1394 +#define _STORE_ATTR_WITH_HINT_r21 1395 +#define _STORE_DEREF_r10 1396 +#define _STORE_FAST_LOAD_FAST_r11 1397 +#define _STORE_FAST_STORE_FAST_r20 1398 +#define _STORE_GLOBAL_r10 1399 +#define _STORE_NAME_r10 1400 +#define _STORE_SLICE_r30 1401 +#define _STORE_SUBSCR_r30 1402 +#define _STORE_SUBSCR_DICT_r31 1403 +#define _STORE_SUBSCR_LIST_INT_r32 1404 +#define _SWAP_r11 1405 +#define _SWAP_2_r02 1406 +#define _SWAP_2_r12 1407 +#define _SWAP_2_r22 1408 +#define _SWAP_2_r33 1409 +#define _SWAP_3_r03 1410 +#define _SWAP_3_r13 1411 +#define _SWAP_3_r23 1412 +#define _SWAP_3_r33 1413 +#define _SWAP_FAST_r01 1414 +#define _SWAP_FAST_r11 1415 +#define _SWAP_FAST_r22 1416 +#define _SWAP_FAST_r33 1417 +#define _SWAP_FAST_0_r01 1418 +#define _SWAP_FAST_0_r11 1419 +#define _SWAP_FAST_0_r22 1420 +#define _SWAP_FAST_0_r33 1421 +#define _SWAP_FAST_1_r01 1422 +#define _SWAP_FAST_1_r11 1423 +#define _SWAP_FAST_1_r22 1424 +#define _SWAP_FAST_1_r33 1425 +#define _SWAP_FAST_2_r01 1426 +#define _SWAP_FAST_2_r11 1427 +#define _SWAP_FAST_2_r22 1428 +#define _SWAP_FAST_2_r33 1429 +#define _SWAP_FAST_3_r01 1430 +#define _SWAP_FAST_3_r11 1431 +#define _SWAP_FAST_3_r22 1432 +#define _SWAP_FAST_3_r33 1433 +#define _SWAP_FAST_4_r01 1434 +#define _SWAP_FAST_4_r11 1435 +#define _SWAP_FAST_4_r22 1436 +#define _SWAP_FAST_4_r33 1437 +#define _SWAP_FAST_5_r01 1438 +#define _SWAP_FAST_5_r11 1439 +#define _SWAP_FAST_5_r22 1440 +#define _SWAP_FAST_5_r33 1441 +#define _SWAP_FAST_6_r01 1442 +#define _SWAP_FAST_6_r11 1443 +#define _SWAP_FAST_6_r22 1444 +#define _SWAP_FAST_6_r33 1445 +#define _SWAP_FAST_7_r01 1446 +#define _SWAP_FAST_7_r11 1447 +#define _SWAP_FAST_7_r22 1448 +#define _SWAP_FAST_7_r33 1449 +#define _TIER2_RESUME_CHECK_r00 1450 +#define _TIER2_RESUME_CHECK_r11 1451 +#define _TIER2_RESUME_CHECK_r22 1452 +#define _TIER2_RESUME_CHECK_r33 1453 +#define _TO_BOOL_r11 1454 +#define _TO_BOOL_BOOL_r01 1455 +#define _TO_BOOL_BOOL_r11 1456 +#define _TO_BOOL_BOOL_r22 1457 +#define _TO_BOOL_BOOL_r33 1458 +#define _TO_BOOL_INT_r02 1459 +#define _TO_BOOL_INT_r12 1460 +#define _TO_BOOL_INT_r23 1461 +#define _TO_BOOL_LIST_r02 1462 +#define _TO_BOOL_LIST_r12 1463 +#define _TO_BOOL_LIST_r23 1464 +#define _TO_BOOL_NONE_r01 1465 +#define _TO_BOOL_NONE_r11 1466 +#define _TO_BOOL_NONE_r22 1467 +#define _TO_BOOL_NONE_r33 1468 +#define _TO_BOOL_STR_r02 1469 +#define _TO_BOOL_STR_r12 1470 +#define _TO_BOOL_STR_r23 1471 +#define _TRACE_RECORD_r00 1472 +#define _UNARY_INVERT_r12 1473 +#define _UNARY_NEGATIVE_r12 1474 +#define _UNARY_NOT_r01 1475 +#define _UNARY_NOT_r11 1476 +#define _UNARY_NOT_r22 1477 +#define _UNARY_NOT_r33 1478 +#define _UNPACK_EX_r10 1479 +#define _UNPACK_SEQUENCE_r10 1480 +#define _UNPACK_SEQUENCE_LIST_r10 1481 +#define _UNPACK_SEQUENCE_TUPLE_r10 1482 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1483 +#define _WITH_EXCEPT_START_r33 1484 +#define _YIELD_VALUE_r11 1485 +#define MAX_UOP_REGS_ID 1485 #ifdef __cplusplus } diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index c46368444f4c59..f9173fd83c295e 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -201,21 +201,22 @@ extern "C" { #define LOAD_SUPER_ATTR_ATTR 195 #define LOAD_SUPER_ATTR_METHOD 196 #define RESUME_CHECK 197 -#define SEND_GEN 198 -#define STORE_ATTR_INSTANCE_VALUE 199 -#define STORE_ATTR_SLOT 200 -#define STORE_ATTR_WITH_HINT 201 -#define STORE_SUBSCR_DICT 202 -#define STORE_SUBSCR_LIST_INT 203 -#define TO_BOOL_ALWAYS_TRUE 204 -#define TO_BOOL_BOOL 205 -#define TO_BOOL_INT 206 -#define TO_BOOL_LIST 207 -#define TO_BOOL_NONE 208 -#define TO_BOOL_STR 209 -#define UNPACK_SEQUENCE_LIST 210 -#define UNPACK_SEQUENCE_TUPLE 211 -#define UNPACK_SEQUENCE_TWO_TUPLE 212 +#define RESUME_CHECK_JIT 198 +#define SEND_GEN 199 +#define STORE_ATTR_INSTANCE_VALUE 200 +#define STORE_ATTR_SLOT 201 +#define STORE_ATTR_WITH_HINT 202 +#define STORE_SUBSCR_DICT 203 +#define STORE_SUBSCR_LIST_INT 204 +#define TO_BOOL_ALWAYS_TRUE 205 +#define TO_BOOL_BOOL 206 +#define TO_BOOL_INT 207 +#define TO_BOOL_LIST 208 +#define TO_BOOL_NONE 209 +#define TO_BOOL_STR 210 +#define UNPACK_SEQUENCE_LIST 211 +#define UNPACK_SEQUENCE_TUPLE 212 +#define UNPACK_SEQUENCE_TWO_TUPLE 213 #define INSTRUMENTED_END_FOR 233 #define INSTRUMENTED_POP_ITER 234 #define INSTRUMENTED_END_SEND 235 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 6e37288c32dd9a..8d2c1ece8bc6a8 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -5,6 +5,7 @@ _specializations = frozendict( RESUME=( "RESUME_CHECK", + "RESUME_CHECK_JIT", ), TO_BOOL=( "TO_BOOL_ALWAYS_TRUE", @@ -195,21 +196,22 @@ LOAD_SUPER_ATTR_ATTR=195, LOAD_SUPER_ATTR_METHOD=196, RESUME_CHECK=197, - SEND_GEN=198, - STORE_ATTR_INSTANCE_VALUE=199, - STORE_ATTR_SLOT=200, - STORE_ATTR_WITH_HINT=201, - STORE_SUBSCR_DICT=202, - STORE_SUBSCR_LIST_INT=203, - TO_BOOL_ALWAYS_TRUE=204, - TO_BOOL_BOOL=205, - TO_BOOL_INT=206, - TO_BOOL_LIST=207, - TO_BOOL_NONE=208, - TO_BOOL_STR=209, - UNPACK_SEQUENCE_LIST=210, - UNPACK_SEQUENCE_TUPLE=211, - UNPACK_SEQUENCE_TWO_TUPLE=212, + RESUME_CHECK_JIT=198, + SEND_GEN=199, + STORE_ATTR_INSTANCE_VALUE=200, + STORE_ATTR_SLOT=201, + STORE_ATTR_WITH_HINT=202, + STORE_SUBSCR_DICT=203, + STORE_SUBSCR_LIST_INT=204, + TO_BOOL_ALWAYS_TRUE=205, + TO_BOOL_BOOL=206, + TO_BOOL_INT=207, + TO_BOOL_LIST=208, + TO_BOOL_NONE=209, + TO_BOOL_STR=210, + UNPACK_SEQUENCE_LIST=211, + UNPACK_SEQUENCE_TUPLE=212, + UNPACK_SEQUENCE_TWO_TUPLE=213, ) opmap = frozendict( diff --git a/Lib/opcode.py b/Lib/opcode.py index 165f42baed94e3..d53b94d89b46f7 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -119,6 +119,9 @@ POP_JUMP_IF_NOT_NONE=frozendict( counter=1, ), + RESUME=frozendict( + counter=1, + ), ) _inline_cache_entries = frozendict({ diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index d66031ed31cbe2..1385a7f840d7be 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -15,7 +15,7 @@ _testinternalcapi = import_helper.import_module("_testinternalcapi") -from _testinternalcapi import _PY_NSMALLPOSINTS, TIER2_THRESHOLD +from _testinternalcapi import _PY_NSMALLPOSINTS, TIER2_THRESHOLD, TIER2_RESUME_THRESHOLD #For test of issue 136154 GLOBAL_136154 = 42 @@ -322,6 +322,23 @@ def testfunc(n): uops = get_opnames(ex) self.assertIn("_JUMP_TO_TOP", uops) + def test_resume(self): + def testfunc(x): + if x <= 1: + return 1 + return testfunc(x-1) + + for _ in range((TIER2_RESUME_THRESHOLD + 99)//100): + testfunc(101) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + # 0. _START_EXECUTOR + # 1. _MAKE_WARM + # 2. _TIER2_RESUME_CHECK + self.assertEqual(uops[2], "_TIER2_RESUME_CHECK") + def test_jump_forward(self): def testfunc(n): a = 0 @@ -1419,7 +1436,7 @@ def test_guard_type_version_removed_invalidation(self): def thing(a): x = 0 - for i in range(TIER2_THRESHOLD * 2 + 1): + for i in range(TIER2_THRESHOLD + 1): x += a.attr # The first TIER2_THRESHOLD iterations we set the attribute on # this dummy class, which shouldn't trigger the type watcher. @@ -1437,8 +1454,7 @@ class Bar: res, ex = self._run_with_optimizer(thing, Foo()) opnames = list(iter_opnames(ex)) - self.assertIsNotNone(ex) - self.assertEqual(res, TIER2_THRESHOLD * 6 + 1) + self.assertEqual(res, TIER2_THRESHOLD * 2 + 2) call = opnames.index("_CALL_BUILTIN_FAST") load_attr_top = opnames.index("_POP_TOP_LOAD_CONST_INLINE_BORROW", 0, call) load_attr_bottom = opnames.index("_POP_TOP_LOAD_CONST_INLINE_BORROW", call) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 0d5c6e6e77f5d7..19fa387cd7b271 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -1437,6 +1437,7 @@ def f(): co_code=bytes( [ dis.opmap["RESUME"], 0, + dis.opmap["CACHE"], 0, dis.opmap["LOAD_COMMON_CONSTANT"], 0, dis.opmap["RAISE_VARARGS"], 1, ] @@ -1445,7 +1446,7 @@ def f(): [ (1 << 7) | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3) - | (3 - 1), + | (4 - 1), 0, ] ), @@ -1453,7 +1454,7 @@ def f(): self.assertRaises(AssertionError, f) self.assertEqual( list(f.__code__.co_positions()), - 3 * [(42, 42, None, None)], + 4 * [(42, 42, None, None)], ) @cpython_only diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 302b2c21935efe..ac8837359c1445 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -2458,8 +2458,8 @@ def test_lambda_return_position(self): for i, pos in enumerate(positions): with self.subTest(i=i, pos=pos): start_line, end_line, start_col, end_col = pos - if i == 0 and start_col == end_col == 0: - # ignore the RESUME in the beginning + if i <= 1: + # ignore the RESUME and CACHE in the beginning continue self.assertEqual(start_line, 1) self.assertEqual(end_line, 1) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index cefd64ddfe8417..f4210db5bd788e 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -127,13 +127,13 @@ def _f(a): dis_f_with_offsets = """\ %3d 0 RESUME 0 -%3d 2 LOAD_GLOBAL 1 (print + NULL) - 12 LOAD_FAST_BORROW 0 (a) - 14 CALL 1 - 22 POP_TOP +%3d 4 LOAD_GLOBAL 1 (print + NULL) + 14 LOAD_FAST_BORROW 0 (a) + 16 CALL 1 + 24 POP_TOP -%3d 24 LOAD_SMALL_INT 1 - 26 RETURN_VALUE +%3d 26 LOAD_SMALL_INT 1 + 28 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -617,10 +617,10 @@ async def _asyncwith(c): CALL 0 GET_AWAITABLE 1 LOAD_CONST 0 (None) - L2: SEND 3 (to L5) + L2: SEND 4 (to L5) L3: YIELD_VALUE 1 L4: RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) + JUMP_BACKWARD_NO_INTERRUPT 6 (to L2) L5: END_SEND L6: POP_TOP @@ -633,10 +633,10 @@ async def _asyncwith(c): CALL 3 GET_AWAITABLE 2 LOAD_CONST 0 (None) - L8: SEND 3 (to L11) + L8: SEND 4 (to L11) L9: YIELD_VALUE 1 L10: RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) + JUMP_BACKWARD_NO_INTERRUPT 6 (to L8) L11: END_SEND POP_TOP @@ -646,17 +646,17 @@ async def _asyncwith(c): RETURN_VALUE %4d L12: CLEANUP_THROW - L13: JUMP_BACKWARD_NO_INTERRUPT 26 (to L5) + L13: JUMP_BACKWARD_NO_INTERRUPT 27 (to L5) L14: CLEANUP_THROW L15: JUMP_BACKWARD_NO_INTERRUPT 10 (to L11) L16: PUSH_EXC_INFO WITH_EXCEPT_START GET_AWAITABLE 2 LOAD_CONST 0 (None) - L17: SEND 4 (to L21) + L17: SEND 5 (to L21) L18: YIELD_VALUE 1 L19: RESUME 3 - JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) + JUMP_BACKWARD_NO_INTERRUPT 6 (to L17) L20: CLEANUP_THROW L21: END_SEND TO_BOOL @@ -880,7 +880,7 @@ def foo(x): RETURN_GENERATOR POP_TOP L1: RESUME 0 - L2: FOR_ITER 14 (to L3) + L2: FOR_ITER 15 (to L3) STORE_FAST 1 (z) LOAD_DEREF 2 (x) LOAD_FAST_BORROW 1 (z) @@ -888,7 +888,7 @@ def foo(x): YIELD_VALUE 0 RESUME 5 POP_TOP - JUMP_BACKWARD 16 (to L2) + JUMP_BACKWARD 17 (to L2) L3: END_FOR POP_ITER LOAD_CONST 0 (None) @@ -909,7 +909,7 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d RESUME_CHECK 0 +%3d RESUME_CHECK{: <6} 0 %3d LOAD_FAST_LOAD_FAST 1 (x, y) STORE_FAST_STORE_FAST 50 (b, a) @@ -926,7 +926,7 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d RESUME_CHECK 0 +%3d RESUME_CHECK{: <6} 0 %3d BUILD_LIST 0 LOAD_CONST 2 ((1, 2, 3)) @@ -1323,13 +1323,15 @@ def code_quicken(f): def test_super_instructions(self): self.code_quicken(lambda: load_test(0, 0)) got = self.get_disassembly(load_test, adaptive=True) - self.do_disassembly_compare(got, dis_load_test_quickened_code) + jit = sys._jit.is_enabled() + expected = dis_load_test_quickened_code.format("_JIT" if jit else "") + self.do_disassembly_compare(got, expected) @cpython_only @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK{: <6} 0 1 LOAD_CONST 0 ('a') LOAD_ATTR_SLOT 0 (__class__) @@ -1338,13 +1340,15 @@ def test_load_attr_specialize(self): co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) got = self.get_disassembly(co, adaptive=True) - self.do_disassembly_compare(got, load_attr_quicken) + jit = sys._jit.is_enabled() + expected = load_attr_quicken.format("_JIT" if jit else "") + self.do_disassembly_compare(got, expected) @cpython_only @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK{: <6} 0 1 LOAD_NAME 0 (str) PUSH_NULL @@ -1355,7 +1359,9 @@ def test_call_specialize(self): co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) got = self.get_disassembly(co, adaptive=True) - self.do_disassembly_compare(got, call_quicken) + jit = sys._jit.is_enabled() + expected = call_quicken.format("_JIT" if jit else "") + self.do_disassembly_compare(got, expected) @cpython_only @requires_specialization @@ -1364,7 +1370,9 @@ def test_loop_quicken(self): self.code_quicken(loop_test) got = self.get_disassembly(loop_test, adaptive=True) jit = sys._jit.is_enabled() - expected = dis_loop_test_quickened_code.format("JIT" if jit else "NO_JIT") + resume_str = "_JIT" if jit else "" + jit_str = "JIT " if jit else "NO_JIT" + expected = dis_loop_test_quickened_code.format(resume_str, jit_str) self.do_disassembly_compare(got, expected) @cpython_only @@ -1431,7 +1439,7 @@ def test_show_caches(self): caches = list(self.get_cached_values(quickened, adaptive)) for cache in caches: self.assertRegex(cache, pattern) - total_caches = 21 + total_caches = 22 empty_caches = 7 self.assertEqual(caches.count(""), empty_caches) self.assertEqual(len(caches), total_caches) @@ -1776,210 +1784,210 @@ def _prepare_test_cases(): expected_opinfo_outer = [ make_inst(opname='MAKE_CELL', arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None), make_inst(opname='MAKE_CELL', arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None), - make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1), - make_inst(opname='LOAD_CONST', arg=4, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2), - make_inst(opname='LOAD_FAST_BORROW', arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2), - make_inst(opname='BUILD_TUPLE', arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2), - make_inst(opname='LOAD_CONST', arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2), - make_inst(opname='MAKE_FUNCTION', arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2), - make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2), - make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2), - make_inst(opname='STORE_FAST', arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2), - make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_DEREF', arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7), - make_inst(opname='LOAD_DEREF', arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7), - make_inst(opname='LOAD_CONST', arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7), - make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7), - make_inst(opname='BUILD_LIST', arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7), - make_inst(opname='BUILD_MAP', arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7), - make_inst(opname='LOAD_CONST', arg=3, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7), - make_inst(opname='CALL', arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7), - make_inst(opname='LOAD_FAST_BORROW', arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8), - make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8), + make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=4, argval=(3, 4), argrepr='(3, 4)', offset=8, start_offset=8, starts_line=True, line_number=2), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=2), + make_inst(opname='LOAD_FAST_BORROW', arg=1, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=2), + make_inst(opname='BUILD_TUPLE', arg=2, argval=2, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=2), + make_inst(opname='LOAD_CONST', arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=16, start_offset=16, starts_line=False, line_number=2), + make_inst(opname='MAKE_FUNCTION', arg=None, argval=None, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=2), + make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=8, argval=8, argrepr='closure', offset=20, start_offset=20, starts_line=False, line_number=2), + make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=1, argval=1, argrepr='defaults', offset=22, start_offset=22, starts_line=False, line_number=2), + make_inst(opname='STORE_FAST', arg=2, argval='f', argrepr='f', offset=24, start_offset=24, starts_line=False, line_number=2), + make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=26, start_offset=26, starts_line=True, line_number=7, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_DEREF', arg=0, argval='a', argrepr='a', offset=36, start_offset=36, starts_line=False, line_number=7), + make_inst(opname='LOAD_DEREF', arg=1, argval='b', argrepr='b', offset=38, start_offset=38, starts_line=False, line_number=7), + make_inst(opname='LOAD_CONST', arg=2, argval='', argrepr="''", offset=40, start_offset=40, starts_line=False, line_number=7), + make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7), + make_inst(opname='BUILD_LIST', arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7), + make_inst(opname='BUILD_MAP', arg=0, argval=0, argrepr='', offset=46, start_offset=46, starts_line=False, line_number=7), + make_inst(opname='LOAD_CONST', arg=3, argval='Hello world!', argrepr="'Hello world!'", offset=48, start_offset=48, starts_line=False, line_number=7), + make_inst(opname='CALL', arg=7, argval=7, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=7), + make_inst(opname='LOAD_FAST_BORROW', arg=2, argval='f', argrepr='f', offset=60, start_offset=60, starts_line=True, line_number=8), + make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=62, start_offset=62, starts_line=False, line_number=8), ] expected_opinfo_f = [ make_inst(opname='COPY_FREE_VARS', arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None), make_inst(opname='MAKE_CELL', arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None), make_inst(opname='MAKE_CELL', arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None), - make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2), - make_inst(opname='LOAD_CONST', arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3), - make_inst(opname='LOAD_FAST_BORROW', arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3), - make_inst(opname='LOAD_FAST_BORROW', arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3), - make_inst(opname='LOAD_FAST_BORROW', arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3), - make_inst(opname='BUILD_TUPLE', arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3), - make_inst(opname='LOAD_CONST', arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3), - make_inst(opname='MAKE_FUNCTION', arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3), - make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3), - make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3), - make_inst(opname='STORE_FAST', arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3), - make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_DEREF', arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5), - make_inst(opname='LOAD_DEREF', arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5), - make_inst(opname='LOAD_DEREF', arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5), - make_inst(opname='LOAD_DEREF', arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5), - make_inst(opname='CALL', arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5), - make_inst(opname='LOAD_FAST_BORROW', arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6), - make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6), + make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=2, argval=(5, 6), argrepr='(5, 6)', offset=10, start_offset=10, starts_line=True, line_number=3), + make_inst(opname='LOAD_FAST_BORROW', arg=3, argval='a', argrepr='a', offset=12, start_offset=12, starts_line=False, line_number=3), + make_inst(opname='LOAD_FAST_BORROW', arg=4, argval='b', argrepr='b', offset=14, start_offset=14, starts_line=False, line_number=3), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='c', argrepr='c', offset=16, start_offset=16, starts_line=False, line_number=3), + make_inst(opname='LOAD_FAST_BORROW', arg=1, argval='d', argrepr='d', offset=18, start_offset=18, starts_line=False, line_number=3), + make_inst(opname='BUILD_TUPLE', arg=4, argval=4, argrepr='', offset=20, start_offset=20, starts_line=False, line_number=3), + make_inst(opname='LOAD_CONST', arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=22, start_offset=22, starts_line=False, line_number=3), + make_inst(opname='MAKE_FUNCTION', arg=None, argval=None, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=3), + make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=8, argval=8, argrepr='closure', offset=26, start_offset=26, starts_line=False, line_number=3), + make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=1, argval=1, argrepr='defaults', offset=28, start_offset=28, starts_line=False, line_number=3), + make_inst(opname='STORE_FAST', arg=2, argval='inner', argrepr='inner', offset=30, start_offset=30, starts_line=False, line_number=3), + make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=32, start_offset=32, starts_line=True, line_number=5, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_DEREF', arg=3, argval='a', argrepr='a', offset=42, start_offset=42, starts_line=False, line_number=5), + make_inst(opname='LOAD_DEREF', arg=4, argval='b', argrepr='b', offset=44, start_offset=44, starts_line=False, line_number=5), + make_inst(opname='LOAD_DEREF', arg=0, argval='c', argrepr='c', offset=46, start_offset=46, starts_line=False, line_number=5), + make_inst(opname='LOAD_DEREF', arg=1, argval='d', argrepr='d', offset=48, start_offset=48, starts_line=False, line_number=5), + make_inst(opname='CALL', arg=4, argval=4, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=5, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=58, start_offset=58, starts_line=False, line_number=5), + make_inst(opname='LOAD_FAST_BORROW', arg=2, argval='inner', argrepr='inner', offset=60, start_offset=60, starts_line=True, line_number=6), + make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=62, start_offset=62, starts_line=False, line_number=6), ] expected_opinfo_inner = [ make_inst(opname='COPY_FREE_VARS', arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None), - make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3), - make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_DEREF', arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4), - make_inst(opname='LOAD_DEREF', arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4), - make_inst(opname='LOAD_DEREF', arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4), - make_inst(opname='LOAD_DEREF', arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4), - make_inst(opname='LOAD_FAST_BORROW_LOAD_FAST_BORROW', arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4), - make_inst(opname='CALL', arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4), - make_inst(opname='LOAD_CONST', arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4), - make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4), + make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=6, start_offset=6, starts_line=True, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_DEREF', arg=2, argval='a', argrepr='a', offset=16, start_offset=16, starts_line=False, line_number=4), + make_inst(opname='LOAD_DEREF', arg=3, argval='b', argrepr='b', offset=18, start_offset=18, starts_line=False, line_number=4), + make_inst(opname='LOAD_DEREF', arg=4, argval='c', argrepr='c', offset=20, start_offset=20, starts_line=False, line_number=4), + make_inst(opname='LOAD_DEREF', arg=5, argval='d', argrepr='d', offset=22, start_offset=22, starts_line=False, line_number=4), + make_inst(opname='LOAD_FAST_BORROW_LOAD_FAST_BORROW', arg=1, argval=('e', 'f'), argrepr='e, f', offset=24, start_offset=24, starts_line=False, line_number=4), + make_inst(opname='CALL', arg=6, argval=6, argrepr='', offset=26, start_offset=26, starts_line=False, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=34, start_offset=34, starts_line=False, line_number=4), + make_inst(opname='LOAD_CONST', arg=0, argval=None, argrepr='None', offset=36, start_offset=36, starts_line=False, line_number=4), + make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=38, start_offset=38, starts_line=False, line_number=4), ] expected_opinfo_jumpy = [ - make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1), - make_inst(opname='LOAD_GLOBAL', arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_SMALL_INT', arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='GET_ITER', arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3), - make_inst(opname='FOR_ITER', arg=33, argval=94, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='STORE_FAST', arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5), - make_inst(opname='LOAD_SMALL_INT', arg=4, argval=4, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=5), - make_inst(opname='COMPARE_OP', arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='POP_JUMP_IF_FALSE', arg=3, argval=70, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=64, start_offset=64, starts_line=False, line_number=5), - make_inst(opname='JUMP_BACKWARD', arg=23, argval=24, argrepr='to L1', offset=66, start_offset=66, starts_line=True, line_number=6, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=70, start_offset=70, starts_line=True, line_number=7, label=2), - make_inst(opname='LOAD_SMALL_INT', arg=6, argval=6, argrepr='', offset=72, start_offset=72, starts_line=False, line_number=7), - make_inst(opname='COMPARE_OP', arg=148, argval='>', argrepr='bool(>)', offset=74, start_offset=74, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='POP_JUMP_IF_TRUE', arg=3, argval=88, argrepr='to L3', offset=78, start_offset=78, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=82, start_offset=82, starts_line=False, line_number=7), - make_inst(opname='JUMP_BACKWARD', arg=32, argval=24, argrepr='to L1', offset=84, start_offset=84, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=8, label=3), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=False, line_number=8), - make_inst(opname='JUMP_FORWARD', arg=13, argval=120, argrepr='to L5', offset=92, start_offset=92, starts_line=False, line_number=8), - make_inst(opname='END_FOR', arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=True, line_number=3, label=4), - make_inst(opname='POP_ITER', arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=False, line_number=3), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=98, start_offset=98, starts_line=True, line_number=10, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=1, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=108, start_offset=108, starts_line=False, line_number=10), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=118, start_offset=118, starts_line=False, line_number=10), - make_inst(opname='LOAD_FAST_CHECK', arg=0, argval='i', argrepr='i', offset=120, start_offset=120, starts_line=True, line_number=11, label=5), - make_inst(opname='TO_BOOL', arg=None, argval=None, argrepr='', offset=122, start_offset=122, starts_line=False, line_number=11, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_JUMP_IF_FALSE', arg=40, argval=214, argrepr='to L8', offset=130, start_offset=130, starts_line=False, line_number=11, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=134, start_offset=134, starts_line=False, line_number=11), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=136, start_offset=136, starts_line=True, line_number=12, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=146, start_offset=146, starts_line=False, line_number=12), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=148, start_offset=148, starts_line=False, line_number=12, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=156, start_offset=156, starts_line=False, line_number=12), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=13), - make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=160, start_offset=160, starts_line=False, line_number=13), - make_inst(opname='BINARY_OP', arg=23, argval=23, argrepr='-=', offset=162, start_offset=162, starts_line=False, line_number=13, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]), - make_inst(opname='STORE_FAST', arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=False, line_number=13), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=176, start_offset=176, starts_line=True, line_number=14), - make_inst(opname='LOAD_SMALL_INT', arg=6, argval=6, argrepr='', offset=178, start_offset=178, starts_line=False, line_number=14), - make_inst(opname='COMPARE_OP', arg=148, argval='>', argrepr='bool(>)', offset=180, start_offset=180, starts_line=False, line_number=14, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='POP_JUMP_IF_FALSE', arg=3, argval=194, argrepr='to L6', offset=184, start_offset=184, starts_line=False, line_number=14, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=188, start_offset=188, starts_line=False, line_number=14), - make_inst(opname='JUMP_BACKWARD', arg=37, argval=120, argrepr='to L5', offset=190, start_offset=190, starts_line=True, line_number=15, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=194, start_offset=194, starts_line=True, line_number=16, label=6), - make_inst(opname='LOAD_SMALL_INT', arg=4, argval=4, argrepr='', offset=196, start_offset=196, starts_line=False, line_number=16), - make_inst(opname='COMPARE_OP', arg=18, argval='<', argrepr='bool(<)', offset=198, start_offset=198, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='POP_JUMP_IF_TRUE', arg=3, argval=212, argrepr='to L7', offset=202, start_offset=202, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=206, start_offset=206, starts_line=False, line_number=16), - make_inst(opname='JUMP_BACKWARD', arg=46, argval=120, argrepr='to L5', offset=208, start_offset=208, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='JUMP_FORWARD', arg=11, argval=236, argrepr='to L9', offset=212, start_offset=212, starts_line=True, line_number=17, label=7), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=214, start_offset=214, starts_line=True, line_number=19, label=8, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=2, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=224, start_offset=224, starts_line=False, line_number=19), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=19, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=19), - make_inst(opname='NOP', arg=None, argval=None, argrepr='', offset=236, start_offset=236, starts_line=True, line_number=20, label=9), - make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=238, start_offset=238, starts_line=True, line_number=21), - make_inst(opname='LOAD_SMALL_INT', arg=0, argval=0, argrepr='', offset=240, start_offset=240, starts_line=False, line_number=21), - make_inst(opname='BINARY_OP', arg=11, argval=11, argrepr='/', offset=242, start_offset=242, starts_line=False, line_number=21, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=254, start_offset=254, starts_line=False, line_number=21), - make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=256, start_offset=256, starts_line=True, line_number=25), - make_inst(opname='COPY', arg=1, argval=1, argrepr='', offset=258, start_offset=258, starts_line=False, line_number=25), - make_inst(opname='LOAD_SPECIAL', arg=1, argval=1, argrepr='__exit__', offset=260, start_offset=260, starts_line=False, line_number=25), - make_inst(opname='SWAP', arg=2, argval=2, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=25), - make_inst(opname='SWAP', arg=3, argval=3, argrepr='', offset=264, start_offset=264, starts_line=False, line_number=25), - make_inst(opname='LOAD_SPECIAL', arg=0, argval=0, argrepr='__enter__', offset=266, start_offset=266, starts_line=False, line_number=25), - make_inst(opname='CALL', arg=0, argval=0, argrepr='', offset=268, start_offset=268, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='STORE_FAST', arg=1, argval='dodgy', argrepr='dodgy', offset=276, start_offset=276, starts_line=False, line_number=25), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=278, start_offset=278, starts_line=True, line_number=26, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=3, argval='Never reach this', argrepr="'Never reach this'", offset=288, start_offset=288, starts_line=False, line_number=26), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=290, start_offset=290, starts_line=False, line_number=26, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=298, start_offset=298, starts_line=False, line_number=26), - make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=300, start_offset=300, starts_line=True, line_number=25), - make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=302, start_offset=302, starts_line=False, line_number=25), + make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='LOAD_GLOBAL', arg=1, argval='range', argrepr='range + NULL', offset=4, start_offset=4, starts_line=True, line_number=3, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_SMALL_INT', arg=10, argval=10, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=3, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='GET_ITER', arg=None, argval=None, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=3), + make_inst(opname='FOR_ITER', arg=33, argval=96, argrepr='to L4', offset=26, start_offset=26, starts_line=False, line_number=3, label=1, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='STORE_FAST', arg=0, argval='i', argrepr='i', offset=30, start_offset=30, starts_line=False, line_number=3), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=32, start_offset=32, starts_line=True, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=42, start_offset=42, starts_line=False, line_number=4), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=4, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=52, start_offset=52, starts_line=False, line_number=4), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=54, start_offset=54, starts_line=True, line_number=5), + make_inst(opname='LOAD_SMALL_INT', arg=4, argval=4, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5), + make_inst(opname='COMPARE_OP', arg=18, argval='<', argrepr='bool(<)', offset=58, start_offset=58, starts_line=False, line_number=5, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='POP_JUMP_IF_FALSE', arg=3, argval=72, argrepr='to L2', offset=62, start_offset=62, starts_line=False, line_number=5, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=66, start_offset=66, starts_line=False, line_number=5), + make_inst(opname='JUMP_BACKWARD', arg=23, argval=26, argrepr='to L1', offset=68, start_offset=68, starts_line=True, line_number=6, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=72, start_offset=72, starts_line=True, line_number=7, label=2), + make_inst(opname='LOAD_SMALL_INT', arg=6, argval=6, argrepr='', offset=74, start_offset=74, starts_line=False, line_number=7), + make_inst(opname='COMPARE_OP', arg=148, argval='>', argrepr='bool(>)', offset=76, start_offset=76, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='POP_JUMP_IF_TRUE', arg=3, argval=90, argrepr='to L3', offset=80, start_offset=80, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=False, line_number=7), + make_inst(opname='JUMP_BACKWARD', arg=32, argval=26, argrepr='to L1', offset=86, start_offset=86, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=True, line_number=8, label=3), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=False, line_number=8), + make_inst(opname='JUMP_FORWARD', arg=13, argval=122, argrepr='to L5', offset=94, start_offset=94, starts_line=False, line_number=8), + make_inst(opname='END_FOR', arg=None, argval=None, argrepr='', offset=96, start_offset=96, starts_line=True, line_number=3, label=4), + make_inst(opname='POP_ITER', arg=None, argval=None, argrepr='', offset=98, start_offset=98, starts_line=False, line_number=3), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=100, start_offset=100, starts_line=True, line_number=10, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=1, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=110, start_offset=110, starts_line=False, line_number=10), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=112, start_offset=112, starts_line=False, line_number=10, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=120, start_offset=120, starts_line=False, line_number=10), + make_inst(opname='LOAD_FAST_CHECK', arg=0, argval='i', argrepr='i', offset=122, start_offset=122, starts_line=True, line_number=11, label=5), + make_inst(opname='TO_BOOL', arg=None, argval=None, argrepr='', offset=124, start_offset=124, starts_line=False, line_number=11, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_JUMP_IF_FALSE', arg=40, argval=216, argrepr='to L8', offset=132, start_offset=132, starts_line=False, line_number=11, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=136, start_offset=136, starts_line=False, line_number=11), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=138, start_offset=138, starts_line=True, line_number=12, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=False, line_number=12), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=150, start_offset=150, starts_line=False, line_number=12, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=158, start_offset=158, starts_line=False, line_number=12), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=160, start_offset=160, starts_line=True, line_number=13), + make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=13), + make_inst(opname='BINARY_OP', arg=23, argval=23, argrepr='-=', offset=164, start_offset=164, starts_line=False, line_number=13, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]), + make_inst(opname='STORE_FAST', arg=0, argval='i', argrepr='i', offset=176, start_offset=176, starts_line=False, line_number=13), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=178, start_offset=178, starts_line=True, line_number=14), + make_inst(opname='LOAD_SMALL_INT', arg=6, argval=6, argrepr='', offset=180, start_offset=180, starts_line=False, line_number=14), + make_inst(opname='COMPARE_OP', arg=148, argval='>', argrepr='bool(>)', offset=182, start_offset=182, starts_line=False, line_number=14, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='POP_JUMP_IF_FALSE', arg=3, argval=196, argrepr='to L6', offset=186, start_offset=186, starts_line=False, line_number=14, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=14), + make_inst(opname='JUMP_BACKWARD', arg=37, argval=122, argrepr='to L5', offset=192, start_offset=192, starts_line=True, line_number=15, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=196, start_offset=196, starts_line=True, line_number=16, label=6), + make_inst(opname='LOAD_SMALL_INT', arg=4, argval=4, argrepr='', offset=198, start_offset=198, starts_line=False, line_number=16), + make_inst(opname='COMPARE_OP', arg=18, argval='<', argrepr='bool(<)', offset=200, start_offset=200, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='POP_JUMP_IF_TRUE', arg=3, argval=214, argrepr='to L7', offset=204, start_offset=204, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=208, start_offset=208, starts_line=False, line_number=16), + make_inst(opname='JUMP_BACKWARD', arg=46, argval=122, argrepr='to L5', offset=210, start_offset=210, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='JUMP_FORWARD', arg=11, argval=238, argrepr='to L9', offset=214, start_offset=214, starts_line=True, line_number=17, label=7), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=216, start_offset=216, starts_line=True, line_number=19, label=8, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=2, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=226, start_offset=226, starts_line=False, line_number=19), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=228, start_offset=228, starts_line=False, line_number=19, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=236, start_offset=236, starts_line=False, line_number=19), + make_inst(opname='NOP', arg=None, argval=None, argrepr='', offset=238, start_offset=238, starts_line=True, line_number=20, label=9), + make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=240, start_offset=240, starts_line=True, line_number=21), + make_inst(opname='LOAD_SMALL_INT', arg=0, argval=0, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=21), + make_inst(opname='BINARY_OP', arg=11, argval=11, argrepr='/', offset=244, start_offset=244, starts_line=False, line_number=21, cache_info=[('counter', 1, b'\x00\x00'), ('descr', 4, b'\x00\x00\x00\x00\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=256, start_offset=256, starts_line=False, line_number=21), + make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='i', argrepr='i', offset=258, start_offset=258, starts_line=True, line_number=25), + make_inst(opname='COPY', arg=1, argval=1, argrepr='', offset=260, start_offset=260, starts_line=False, line_number=25), + make_inst(opname='LOAD_SPECIAL', arg=1, argval=1, argrepr='__exit__', offset=262, start_offset=262, starts_line=False, line_number=25), + make_inst(opname='SWAP', arg=2, argval=2, argrepr='', offset=264, start_offset=264, starts_line=False, line_number=25), + make_inst(opname='SWAP', arg=3, argval=3, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=25), + make_inst(opname='LOAD_SPECIAL', arg=0, argval=0, argrepr='__enter__', offset=268, start_offset=268, starts_line=False, line_number=25), + make_inst(opname='CALL', arg=0, argval=0, argrepr='', offset=270, start_offset=270, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='STORE_FAST', arg=1, argval='dodgy', argrepr='dodgy', offset=278, start_offset=278, starts_line=False, line_number=25), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=280, start_offset=280, starts_line=True, line_number=26, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=3, argval='Never reach this', argrepr="'Never reach this'", offset=290, start_offset=290, starts_line=False, line_number=26), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=292, start_offset=292, starts_line=False, line_number=26, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=26), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=302, start_offset=302, starts_line=True, line_number=25), make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=304, start_offset=304, starts_line=False, line_number=25), - make_inst(opname='CALL', arg=3, argval=3, argrepr='', offset=306, start_offset=306, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=314, start_offset=314, starts_line=False, line_number=25), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=316, start_offset=316, starts_line=True, line_number=28, label=10, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=326, start_offset=326, starts_line=False, line_number=28), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=336, start_offset=336, starts_line=False, line_number=28), - make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=338, start_offset=338, starts_line=False, line_number=28), - make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=28), - make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=True, line_number=25), - make_inst(opname='WITH_EXCEPT_START', arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=25), - make_inst(opname='TO_BOOL', arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_JUMP_IF_TRUE', arg=2, argval=362, argrepr='to L11', offset=354, start_offset=354, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=358, start_offset=358, starts_line=False, line_number=25), - make_inst(opname='RERAISE', arg=2, argval=2, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=25), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=25, label=11), - make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=25), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=25), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=25), + make_inst(opname='CALL', arg=3, argval=3, argrepr='', offset=308, start_offset=308, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=318, start_offset=318, starts_line=True, line_number=28, label=10, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=328, start_offset=328, starts_line=False, line_number=28), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=338, start_offset=338, starts_line=False, line_number=28), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=340, start_offset=340, starts_line=False, line_number=28), + make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=28), + make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=True, line_number=25), + make_inst(opname='WITH_EXCEPT_START', arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=25), + make_inst(opname='TO_BOOL', arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_JUMP_IF_TRUE', arg=2, argval=364, argrepr='to L11', offset=356, start_offset=356, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=25), + make_inst(opname='RERAISE', arg=2, argval=2, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=25), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=364, start_offset=364, starts_line=False, line_number=25, label=11), + make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=25), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=25), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=370, start_offset=370, starts_line=False, line_number=25), - make_inst(opname='JUMP_BACKWARD_NO_INTERRUPT', arg=29, argval=316, argrepr='to L10', offset=372, start_offset=372, starts_line=False, line_number=25), - make_inst(opname='COPY', arg=3, argval=3, argrepr='', offset=374, start_offset=374, starts_line=True, line_number=None), - make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=None), - make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=None), - make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=None), - make_inst(opname='LOAD_GLOBAL', arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=382, start_offset=382, starts_line=True, line_number=22, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='CHECK_EXC_MATCH', arg=None, argval=None, argrepr='', offset=392, start_offset=392, starts_line=False, line_number=22), - make_inst(opname='POP_JUMP_IF_FALSE', arg=15, argval=428, argrepr='to L12', offset=394, start_offset=394, starts_line=False, line_number=22, cache_info=[('counter', 1, b'\x00\x00')]), - make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=22), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=22), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=402, start_offset=402, starts_line=True, line_number=23, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=5, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=412, start_offset=412, starts_line=False, line_number=23), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=23, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=23), - make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=23), - make_inst(opname='JUMP_BACKWARD_NO_INTERRUPT', arg=56, argval=316, argrepr='to L10', offset=426, start_offset=426, starts_line=False, line_number=23), - make_inst(opname='RERAISE', arg=0, argval=0, argrepr='', offset=428, start_offset=428, starts_line=True, line_number=22, label=12), - make_inst(opname='COPY', arg=3, argval=3, argrepr='', offset=430, start_offset=430, starts_line=True, line_number=None), - make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None), - make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None), - make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=436, start_offset=436, starts_line=False, line_number=None), - make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=438, start_offset=438, starts_line=True, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=448, start_offset=448, starts_line=False, line_number=28), - make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=450, start_offset=450, starts_line=False, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=458, start_offset=458, starts_line=False, line_number=28), - make_inst(opname='RERAISE', arg=0, argval=0, argrepr='', offset=460, start_offset=460, starts_line=False, line_number=28), - make_inst(opname='COPY', arg=3, argval=3, argrepr='', offset=462, start_offset=462, starts_line=True, line_number=None), - make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=464, start_offset=464, starts_line=False, line_number=None), - make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=466, start_offset=466, starts_line=False, line_number=None), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=372, start_offset=372, starts_line=False, line_number=25), + make_inst(opname='JUMP_BACKWARD_NO_INTERRUPT', arg=29, argval=318, argrepr='to L10', offset=374, start_offset=374, starts_line=False, line_number=25), + make_inst(opname='COPY', arg=3, argval=3, argrepr='', offset=376, start_offset=376, starts_line=True, line_number=None), + make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=378, start_offset=378, starts_line=False, line_number=None), + make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=None), + make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=382, start_offset=382, starts_line=False, line_number=None), + make_inst(opname='LOAD_GLOBAL', arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=384, start_offset=384, starts_line=True, line_number=22, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='CHECK_EXC_MATCH', arg=None, argval=None, argrepr='', offset=394, start_offset=394, starts_line=False, line_number=22), + make_inst(opname='POP_JUMP_IF_FALSE', arg=15, argval=430, argrepr='to L12', offset=396, start_offset=396, starts_line=False, line_number=22, cache_info=[('counter', 1, b'\x00\x00')]), + make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=22), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=402, start_offset=402, starts_line=False, line_number=22), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=404, start_offset=404, starts_line=True, line_number=23, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=5, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=414, start_offset=414, starts_line=False, line_number=23), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=416, start_offset=416, starts_line=False, line_number=23, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=23), + make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=23), + make_inst(opname='JUMP_BACKWARD_NO_INTERRUPT', arg=56, argval=318, argrepr='to L10', offset=428, start_offset=428, starts_line=False, line_number=23), + make_inst(opname='RERAISE', arg=0, argval=0, argrepr='', offset=430, start_offset=430, starts_line=True, line_number=22, label=12), + make_inst(opname='COPY', arg=3, argval=3, argrepr='', offset=432, start_offset=432, starts_line=True, line_number=None), + make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None), + make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=436, start_offset=436, starts_line=False, line_number=None), + make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=438, start_offset=438, starts_line=False, line_number=None), + make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=440, start_offset=440, starts_line=True, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + make_inst(opname='LOAD_CONST', arg=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=450, start_offset=450, starts_line=False, line_number=28), + make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=452, start_offset=452, starts_line=False, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=460, start_offset=460, starts_line=False, line_number=28), + make_inst(opname='RERAISE', arg=0, argval=0, argrepr='', offset=462, start_offset=462, starts_line=False, line_number=28), + make_inst(opname='COPY', arg=3, argval=3, argrepr='', offset=464, start_offset=464, starts_line=True, line_number=None), + make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=466, start_offset=466, starts_line=False, line_number=None), + make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=468, start_offset=468, starts_line=False, line_number=None), ] # One last piece of inspect fodder to check the default line number handling def simple(): pass expected_opinfo_simple = [ make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno), - make_inst(opname='LOAD_CONST', arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno), - make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno), + make_inst(opname='LOAD_CONST', arg=0, argval=None, argrepr='None', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno), + make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=6, start_offset=6, starts_line=False, line_number=simple.__code__.co_firstlineno), ] @@ -2370,8 +2378,10 @@ def test_from_traceback_dis(self): @requires_debug_ranges() def test_bytecode_co_positions(self): bytecode = dis.Bytecode("a=1") - for instr, positions in zip(bytecode, bytecode.codeobj.co_positions()): - assert instr.positions == positions + it = bytecode.codeobj.co_positions() + next(it) # Ignore the CACHE for the RESUME + for instr, positions in zip(bytecode, it): + self.assertEqual(instr.positions, positions) class TestBytecodeTestCase(BytecodeTestCase): def test_assert_not_in_with_op_not_in_bytecode(self): @@ -2439,7 +2449,7 @@ def func(): code = func.__code__ offsets = [linestart[0] for linestart in dis.findlinestarts(code)] - self.assertEqual(offsets, [0, 2]) + self.assertEqual(offsets, [0, 4]) class TestDisTraceback(DisTestBase): @@ -2576,6 +2586,7 @@ def test_show_cache(self): source = 'print()' expect = ''' 0 RESUME 0 + CACHE 0 (counter: 0) 1 LOAD_NAME 0 (print) PUSH_NULL @@ -2596,8 +2607,8 @@ def test_show_offsets(self): expect = ''' 0 0 RESUME 0 - 1 2 LOAD_CONST 0 (None) - 4 RETURN_VALUE + 1 4 LOAD_CONST 0 (None) + 6 RETURN_VALUE ''' for flag in ['-O', '--show-offsets']: self.check_output(source, expect, flag) diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index 1b22e0ec8759ac..116a8bac6fb7b8 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1214,19 +1214,20 @@ def func1(): line3 = 3 self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'get_events', 10), - ('line', 'func1', 1), - ('instruction', 'func1', 2), - ('instruction', 'func1', 4), - ('line', 'func1', 2), - ('instruction', 'func1', 6), - ('instruction', 'func1', 8), - ('line', 'func1', 3), - ('instruction', 'func1', 10), - ('instruction', 'func1', 12), - ('instruction', 'func1', 14), - ('instruction', 'func1', 16), - ('line', 'get_events', 11)]) + ("line", "get_events", 10), + ("line", "func1", 1), + ("instruction", "func1", 4), + ("instruction", "func1", 6), + ("line", "func1", 2), + ("instruction", "func1", 8), + ("instruction", "func1", 10), + ("line", "func1", 3), + ("instruction", "func1", 12), + ("instruction", "func1", 14), + ("instruction", "func1", 16), + ("instruction", "func1", 18), + ("line", "get_events", 11), + ]) def test_c_call(self): @@ -1236,22 +1237,23 @@ def func2(): line3 = 3 self.check_events(func2, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'get_events', 10), - ('line', 'func2', 1), - ('instruction', 'func2', 2), - ('instruction', 'func2', 4), - ('line', 'func2', 2), - ('instruction', 'func2', 6), - ('instruction', 'func2', 8), - ('instruction', 'func2', 28), - ('instruction', 'func2', 30), - ('instruction', 'func2', 38), - ('line', 'func2', 3), - ('instruction', 'func2', 40), - ('instruction', 'func2', 42), - ('instruction', 'func2', 44), - ('instruction', 'func2', 46), - ('line', 'get_events', 11)]) + ("line", "get_events", 10), + ("line", "func2", 1), + ("instruction", "func2", 4), + ("instruction", "func2", 6), + ("line", "func2", 2), + ("instruction", "func2", 8), + ("instruction", "func2", 10), + ("instruction", "func2", 30), + ("instruction", "func2", 32), + ("instruction", "func2", 40), + ("line", "func2", 3), + ("instruction", "func2", 42), + ("instruction", "func2", 44), + ("instruction", "func2", 46), + ("instruction", "func2", 48), + ("line", "get_events", 11), + ]) def test_try_except(self): @@ -1264,28 +1266,29 @@ def func3(): line = 6 self.check_events(func3, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ - ('line', 'get_events', 10), - ('line', 'func3', 1), - ('instruction', 'func3', 2), - ('line', 'func3', 2), - ('instruction', 'func3', 4), - ('instruction', 'func3', 6), - ('line', 'func3', 3), - ('instruction', 'func3', 8), - ('instruction', 'func3', 18), - ('instruction', 'func3', 20), - ('line', 'func3', 4), - ('instruction', 'func3', 22), - ('line', 'func3', 5), - ('instruction', 'func3', 24), - ('instruction', 'func3', 26), - ('instruction', 'func3', 28), - ('line', 'func3', 6), - ('instruction', 'func3', 30), - ('instruction', 'func3', 32), - ('instruction', 'func3', 34), - ('instruction', 'func3', 36), - ('line', 'get_events', 11)]) + ("line", "get_events", 10), + ("line", "func3", 1), + ("instruction", "func3", 4), + ("line", "func3", 2), + ("instruction", "func3", 6), + ("instruction", "func3", 8), + ("line", "func3", 3), + ("instruction", "func3", 10), + ("instruction", "func3", 20), + ("instruction", "func3", 22), + ("line", "func3", 4), + ("instruction", "func3", 24), + ("line", "func3", 5), + ("instruction", "func3", 26), + ("instruction", "func3", 28), + ("instruction", "func3", 30), + ("line", "func3", 6), + ("instruction", "func3", 32), + ("instruction", "func3", 34), + ("instruction", "func3", 36), + ("instruction", "func3", 38), + ("line", "get_events", 11), + ]) def test_with_restart(self): def func1(): @@ -1296,16 +1299,16 @@ def func1(): self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ ('line', 'get_events', 10), ('line', 'func1', 1), - ('instruction', 'func1', 2), ('instruction', 'func1', 4), - ('line', 'func1', 2), ('instruction', 'func1', 6), + ('line', 'func1', 2), ('instruction', 'func1', 8), - ('line', 'func1', 3), ('instruction', 'func1', 10), + ('line', 'func1', 3), ('instruction', 'func1', 12), ('instruction', 'func1', 14), ('instruction', 'func1', 16), + ('instruction', 'func1', 18), ('line', 'get_events', 11)]) sys.monitoring.restart_events() @@ -1313,16 +1316,16 @@ def func1(): self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ ('line', 'get_events', 10), ('line', 'func1', 1), - ('instruction', 'func1', 2), ('instruction', 'func1', 4), - ('line', 'func1', 2), ('instruction', 'func1', 6), + ('line', 'func1', 2), ('instruction', 'func1', 8), - ('line', 'func1', 3), ('instruction', 'func1', 10), + ('line', 'func1', 3), ('instruction', 'func1', 12), ('instruction', 'func1', 14), ('instruction', 'func1', 16), + ('instruction', 'func1', 18), ('line', 'get_events', 11)]) def test_turn_off_only_instruction(self): @@ -1370,10 +1373,10 @@ def func1(): line1 = 1 MUST_INCLUDE_LI = [ - ('instruction', 'func1', 2), - ('line', 'func1', 2), ('instruction', 'func1', 4), - ('instruction', 'func1', 6)] + ('line', 'func1', 2), + ('instruction', 'func1', 6), + ('instruction', 'func1', 8)] def test_line_then_instruction(self): recorders = [ LineRecorder, InstructionRecorder ] @@ -1390,11 +1393,11 @@ def func2(): len(()) MUST_INCLUDE_CI = [ - ('instruction', 'func2', 2), + ('instruction', 'func2', 4), ('call', 'func2', sys.monitoring.MISSING), ('call', 'len', ()), - ('instruction', 'func2', 12), - ('instruction', 'func2', 14)] + ('instruction', 'func2', 14), + ('instruction', 'func2', 16)] @@ -1609,11 +1612,11 @@ def whilefunc(n=0): ('branch right', 'whilefunc', 1, 3)]) self.check_events(func, recorders = BRANCH_OFFSET_RECORDERS, expected = [ - ('branch left', 'func', 28, 32), - ('branch right', 'func', 44, 58), - ('branch left', 'func', 28, 32), - ('branch left', 'func', 44, 50), - ('branch right', 'func', 28, 70)]) + ('branch left', 'func', 30, 34), + ('branch right', 'func', 46, 60), + ('branch left', 'func', 30, 34), + ('branch left', 'func', 46, 52), + ('branch right', 'func', 30, 72)]) def test_except_star(self): @@ -1640,8 +1643,8 @@ def func(): ('branch', 'func', 4, 4), ('line', 'func', 5), ('line', 'meth', 1), - ('jump', 'func', 5, '[offset=120]'), - ('branch', 'func', '[offset=124]', '[offset=130]'), + ('jump', 'func', 5, '[offset=122]'), + ('branch', 'func', '[offset=126]', '[offset=132]'), ('line', 'get_events', 11)]) self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [ @@ -1655,8 +1658,8 @@ def func(): ('line', 'func', 5), ('line', 'meth', 1), ('return', 'meth', None), - ('jump', 'func', 5, '[offset=120]'), - ('branch', 'func', '[offset=124]', '[offset=130]'), + ('jump', 'func', 5, '[offset=122]'), + ('branch', 'func', '[offset=126]', '[offset=132]'), ('return', 'func', None), ('line', 'get_events', 11)]) @@ -1668,8 +1671,8 @@ def foo(n=0): n += 1 return None - in_loop = ('branch left', 'foo', 10, 16) - exit_loop = ('branch right', 'foo', 10, 40) + in_loop = ('branch left', 'foo', 12, 18) + exit_loop = ('branch right', 'foo', 12, 42) self.check_events(foo, recorders = BRANCH_OFFSET_RECORDERS, expected = [ in_loop, in_loop, diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-13-09-48-57.gh-issue-127958.U-znTv.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-13-09-48-57.gh-issue-127958.U-znTv.rst new file mode 100644 index 00000000000000..9808a27e9ea1eb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-13-09-48-57.gh-issue-127958.U-znTv.rst @@ -0,0 +1 @@ +Support tracing from function entrypoints in the JIT. Patch by Ken Jin. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 8c316b7c8ddda0..e1acce8f586685 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -3021,6 +3021,14 @@ module_exec(PyObject *module) return 1; } + // + 1 to specialize from RESUME to RESUME_CHECK_JIT + // + 1 more due to one loop spent on tracing. + long resume_threshold = interp->opt_config.resume_initial_value + 2; + if (PyModule_Add(module, "TIER2_RESUME_THRESHOLD", + PyLong_FromLong(resume_threshold)) < 0) { + return 1; + } + if (PyModule_Add(module, "SPECIALIZATION_THRESHOLD", PyLong_FromLong(ADAPTIVE_WARMUP_VALUE + 1)) < 0) { return 1; diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 2f6845399d9e16..948a413d98ddcd 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -5691,12 +5691,22 @@ INSTRUCTION_STATS(ENTER_EXECUTOR); opcode = ENTER_EXECUTOR; #ifdef _Py_TIER2 + PyCodeObject *code = _PyFrame_GetCode(frame); + _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; if (IS_JIT_TRACING()) { + int og_opcode = executor->vm_data.opcode; + int og_oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; + if (_PyJit_EnterExecutorShouldStopTracing(og_opcode)) { + if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) { + PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter); + } + opcode = og_opcode; + oparg = og_oparg; + DISPATCH_GOTO_NON_TRACING(); + } JUMP_TO_LABEL(stop_tracing); } - PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; assert(executor->vm_data.index == INSTR_OFFSET() - 1); assert(executor->vm_data.code == code); assert(executor->vm_data.valid); @@ -7436,8 +7446,9 @@ _Py_CODEUNIT* const this_instr = next_instr; (void)this_instr; frame->instr_ptr = next_instr; - next_instr += 1; + next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_RESUME); + /* Skip 1 cache entry */ // _LOAD_BYTECODE { #ifdef Py_GIL_DISABLED @@ -7786,16 +7797,19 @@ // _JIT { #ifdef _Py_TIER2 + bool is_resume = this_instr->op.code == RESUME_CHECK_JIT; _Py_BackoffCounter counter = this_instr[1].counter; - if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) && - this_instr->op.code == JUMP_BACKWARD_JIT && + if ((backoff_counter_triggers(counter) && + !IS_JIT_TRACING() && + (this_instr->op.code == JUMP_BACKWARD_JIT || is_resume)) && next_instr->op.code != ENTER_EXECUTOR) { _Py_CODEUNIT *insert_exec_at = this_instr; while (oparg > 255) { oparg >>= 8; insert_exec_at--; } - int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, stack_pointer, 0, NULL, oparg, NULL); + int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, + is_resume ? insert_exec_at : next_instr, stack_pointer, 0, NULL, oparg, NULL); if (succ) { ENTER_TRACING(); } @@ -10448,10 +10462,10 @@ (void)(opcode); #endif frame->instr_ptr = next_instr; - next_instr += 1; + next_instr += 2; INSTRUCTION_STATS(RESUME); PREDICTED_RESUME:; - _Py_CODEUNIT* const this_instr = next_instr - 1; + _Py_CODEUNIT* const this_instr = next_instr - 2; (void)this_instr; // _LOAD_BYTECODE { @@ -10498,11 +10512,11 @@ } // _QUICKEN_RESUME { - #if ENABLE_SPECIALIZATION - if (tstate->tracing == 0 && this_instr->op.code == RESUME) { - FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK); - } - #endif /* ENABLE_SPECIALIZATION */ + uint16_t counter = read_u16(&this_instr[1].cache); + (void)counter; + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_Specialize_Resume(this_instr, tstate, frame); + stack_pointer = _PyFrame_GetStackPointer(frame); } // _CHECK_PERIODIC_IF_NOT_YIELD_FROM { @@ -10527,9 +10541,10 @@ _Py_CODEUNIT* const this_instr = next_instr; (void)this_instr; frame->instr_ptr = next_instr; - next_instr += 1; + next_instr += 2; INSTRUCTION_STATS(RESUME_CHECK); - static_assert(0 == 0, "incorrect cache size"); + static_assert(1 == 1, "incorrect cache size"); + /* Skip 1 cache entry */ #if defined(__EMSCRIPTEN__) if (_Py_emscripten_signal_clock == 0) { UPDATE_MISS_STATS(RESUME); @@ -10557,6 +10572,76 @@ DISPATCH(); } + TARGET(RESUME_CHECK_JIT) { + #if _Py_TAIL_CALL_INTERP + int opcode = RESUME_CHECK_JIT; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(RESUME_CHECK_JIT); + static_assert(1 == 1, "incorrect cache size"); + /* Skip 1 cache entry */ + // _RESUME_CHECK + { + #if defined(__EMSCRIPTEN__) + if (_Py_emscripten_signal_clock == 0) { + UPDATE_MISS_STATS(RESUME); + assert(_PyOpcode_Deopt[opcode] == (RESUME)); + JUMP_TO_PREDICTED(RESUME); + } + _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; + #endif + uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); + uintptr_t version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); + assert((version & _PY_EVAL_EVENTS_MASK) == 0); + if (eval_breaker != version) { + UPDATE_MISS_STATS(RESUME); + assert(_PyOpcode_Deopt[opcode] == (RESUME)); + JUMP_TO_PREDICTED(RESUME); + } + #ifdef Py_GIL_DISABLED + if (frame->tlbc_index != + ((_PyThreadStateImpl *)tstate)->tlbc_index) { + UPDATE_MISS_STATS(RESUME); + assert(_PyOpcode_Deopt[opcode] == (RESUME)); + JUMP_TO_PREDICTED(RESUME); + } + #endif + } + // _JIT + { + #ifdef _Py_TIER2 + bool is_resume = this_instr->op.code == RESUME_CHECK_JIT; + _Py_BackoffCounter counter = this_instr[1].counter; + if ((backoff_counter_triggers(counter) && + !IS_JIT_TRACING() && + (this_instr->op.code == JUMP_BACKWARD_JIT || is_resume)) && + next_instr->op.code != ENTER_EXECUTOR) { + _Py_CODEUNIT *insert_exec_at = this_instr; + while (oparg > 255) { + oparg >>= 8; + insert_exec_at--; + } + int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, + is_resume ? insert_exec_at : next_instr, stack_pointer, 0, NULL, oparg, NULL); + if (succ) { + ENTER_TRACING(); + } + else { + this_instr[1].counter = restart_backoff_counter(counter); + } + } + else { + ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter); + } + #endif + } + DISPATCH(); + } + TARGET(RETURN_GENERATOR) { #if _Py_TAIL_CALL_INTERP int opcode = RETURN_GENERATOR; diff --git a/Modules/_testinternalcapi/test_targets.h b/Modules/_testinternalcapi/test_targets.h index f57c33feec2ac2..def462bacec176 100644 --- a/Modules/_testinternalcapi/test_targets.h +++ b/Modules/_testinternalcapi/test_targets.h @@ -198,6 +198,7 @@ static void *opcode_targets_table[256] = { &&TARGET_LOAD_SUPER_ATTR_ATTR, &&TARGET_LOAD_SUPER_ATTR_METHOD, &&TARGET_RESUME_CHECK, + &&TARGET_RESUME_CHECK_JIT, &&TARGET_SEND_GEN, &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, @@ -232,7 +233,6 @@ static void *opcode_targets_table[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_INSTRUMENTED_END_FOR, &&TARGET_INSTRUMENTED_POP_ITER, &&TARGET_INSTRUMENTED_END_SEND, @@ -472,7 +472,7 @@ static void *opcode_tracing_targets_table[256] = { &&TARGET_TRACE_RECORD, &&TARGET_TRACE_RECORD, &&TARGET_TRACE_RECORD, - &&_unknown_opcode, + &&TARGET_TRACE_RECORD, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -718,6 +718,7 @@ static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RERAISE(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESERVED(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME_CHECK(TAIL_CALL_PARAMS); +static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME_CHECK_JIT(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_GENERATOR(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_VALUE(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND(TAIL_CALL_PARAMS); @@ -959,6 +960,7 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [RESERVED] = _TAIL_CALL_RESERVED, [RESUME] = _TAIL_CALL_RESUME, [RESUME_CHECK] = _TAIL_CALL_RESUME_CHECK, + [RESUME_CHECK_JIT] = _TAIL_CALL_RESUME_CHECK_JIT, [RETURN_GENERATOR] = _TAIL_CALL_RETURN_GENERATOR, [RETURN_VALUE] = _TAIL_CALL_RETURN_VALUE, [SEND] = _TAIL_CALL_SEND, @@ -1007,7 +1009,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [125] = _TAIL_CALL_UNKNOWN_OPCODE, [126] = _TAIL_CALL_UNKNOWN_OPCODE, [127] = _TAIL_CALL_UNKNOWN_OPCODE, - [213] = _TAIL_CALL_UNKNOWN_OPCODE, [214] = _TAIL_CALL_UNKNOWN_OPCODE, [215] = _TAIL_CALL_UNKNOWN_OPCODE, [216] = _TAIL_CALL_UNKNOWN_OPCODE, @@ -1217,6 +1218,7 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [RESERVED] = _TAIL_CALL_TRACE_RECORD, [RESUME] = _TAIL_CALL_TRACE_RECORD, [RESUME_CHECK] = _TAIL_CALL_TRACE_RECORD, + [RESUME_CHECK_JIT] = _TAIL_CALL_TRACE_RECORD, [RETURN_GENERATOR] = _TAIL_CALL_TRACE_RECORD, [RETURN_VALUE] = _TAIL_CALL_TRACE_RECORD, [SEND] = _TAIL_CALL_TRACE_RECORD, @@ -1265,7 +1267,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [125] = _TAIL_CALL_UNKNOWN_OPCODE, [126] = _TAIL_CALL_UNKNOWN_OPCODE, [127] = _TAIL_CALL_UNKNOWN_OPCODE, - [213] = _TAIL_CALL_UNKNOWN_OPCODE, [214] = _TAIL_CALL_UNKNOWN_OPCODE, [215] = _TAIL_CALL_UNKNOWN_OPCODE, [216] = _TAIL_CALL_UNKNOWN_OPCODE, diff --git a/Objects/codeobject.c b/Objects/codeobject.c index d26516f7c2ff66..fbf0985e9050dd 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -931,8 +931,9 @@ PyUnstable_Code_New(int argcount, int kwonlyargcount, // NOTE: When modifying the construction of PyCode_NewEmpty, please also change // test.test_code.CodeLocationTest.test_code_new_empty to keep it in sync! -static const uint8_t assert0[6] = { +static const uint8_t assert0[8] = { RESUME, RESUME_AT_FUNC_START, + CACHE, 0, LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR, RAISE_VARARGS, 1 }; @@ -940,7 +941,7 @@ static const uint8_t assert0[6] = { static const uint8_t linetable[2] = { (1 << 7) // New entry. | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3) - | (3 - 1), // Three code units. + | (4 - 1), // Four code units. 0, // Offset from co_firstlineno. }; @@ -966,7 +967,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) if (filename_ob == NULL) { goto failed; } - code_ob = PyBytes_FromStringAndSize((const char *)assert0, 6); + code_ob = PyBytes_FromStringAndSize((const char *)assert0, 8); if (code_ob == NULL) { goto failed; } diff --git a/Objects/genobject.c b/Objects/genobject.c index 5088500fc4142b..9dece8a7700cab 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -454,6 +454,7 @@ is_resume(_Py_CODEUNIT *instr) return ( code == RESUME || code == RESUME_CHECK || + code == RESUME_CHECK_JIT || code == INSTRUMENTED_RESUME ); } diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index f808544045e153..1411eb1718b683 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,39 +1,39 @@ // 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,9,0,0, - 0,0,0,0,0,243,184,0,0,0,128,0,94,0,82,1, - 73,0,116,0,94,0,82,1,73,4,116,1,93,2,33,0, - 82,2,52,1,0,0,0,0,0,0,31,0,93,2,33,0, - 82,3,93,0,80,6,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,52,2,0,0,0,0,0,0, - 31,0,93,1,80,8,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,33,0,52,0,0,0,0,0, - 0,0,82,4,44,26,0,0,0,0,0,0,0,0,0,0, - 116,5,82,7,16,0,70,24,0,0,116,6,93,2,33,0, - 82,5,93,6,12,0,82,6,93,5,93,6,44,26,0,0, - 0,0,0,0,0,0,0,0,12,0,50,4,52,1,0,0, - 0,0,0,0,31,0,75,26,0,0,9,0,30,0,82,1, - 35,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, - 122,7,99,111,110,102,105,103,32,122,2,58,32,41,5,218, - 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,218,15,117,115,101,95,101, - 110,118,105,114,111,110,109,101,110,116,218,17,99,111,110,102, - 105,103,117,114,101,95,99,95,115,116,100,105,111,218,14,98, - 117,102,102,101,114,101,100,95,115,116,100,105,111,41,7,218, - 3,115,121,115,218,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,218,11,103,101,116,95,99,111,110,102,105,103, - 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, - 0,0,218,18,116,101,115,116,95,102,114,111,122,101,110,109, - 97,105,110,46,112,121,218,8,60,109,111,100,117,108,101,62, - 114,18,0,0,0,1,0,0,0,115,94,0,0,0,240,3, - 1,1,1,243,8,0,1,11,219,0,24,225,0,5,208,6, - 26,212,0,27,217,0,5,128,106,144,35,151,40,145,40,212, - 0,27,216,9,26,215,9,38,210,9,38,211,9,40,168,24, - 213,9,50,128,6,243,2,6,12,2,128,67,241,14,0,5, - 10,136,71,144,67,144,53,152,2,152,54,160,35,157,59,152, - 45,208,10,40,214,4,41,243,15,6,12,2,114,16,0,0, - 0, + 0,0,0,0,0,243,186,0,0,0,128,0,0,0,94,0, + 82,1,73,0,116,0,94,0,82,1,73,4,116,1,93,2, + 33,0,82,2,52,1,0,0,0,0,0,0,31,0,93,2, + 33,0,82,3,93,0,80,6,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,52,2,0,0,0,0, + 0,0,31,0,93,1,80,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,33,0,52,0,0,0, + 0,0,0,0,82,4,44,26,0,0,0,0,0,0,0,0, + 0,0,116,5,82,7,16,0,70,24,0,0,116,6,93,2, + 33,0,82,5,93,6,12,0,82,6,93,5,93,6,44,26, + 0,0,0,0,0,0,0,0,0,0,12,0,50,4,52,1, + 0,0,0,0,0,0,31,0,75,26,0,0,9,0,30,0, + 82,1,35,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,122,7,99,111,110,102,105,103,32,122,2,58,32,41, + 5,218,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,218,15,117,115,101, + 95,101,110,118,105,114,111,110,109,101,110,116,218,17,99,111, + 110,102,105,103,117,114,101,95,99,95,115,116,100,105,111,218, + 14,98,117,102,102,101,114,101,100,95,115,116,100,105,111,41, + 7,218,3,115,121,115,218,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,218,11,103,101,116,95,99,111,110,102, + 105,103,115,114,3,0,0,0,218,3,107,101,121,169,0,243, + 0,0,0,0,218,18,116,101,115,116,95,102,114,111,122,101, + 110,109,97,105,110,46,112,121,218,8,60,109,111,100,117,108, + 101,62,114,18,0,0,0,1,0,0,0,115,94,0,0,0, + 241,3,1,1,1,243,8,0,1,11,219,0,24,225,0,5, + 208,6,26,212,0,27,217,0,5,128,106,144,35,151,40,145, + 40,212,0,27,216,9,26,215,9,38,210,9,38,211,9,40, + 168,24,213,9,50,128,6,243,2,6,12,2,128,67,241,14, + 0,5,10,136,71,144,67,144,53,152,2,152,54,160,35,157, + 59,152,45,208,10,40,214,4,41,243,15,6,12,2,114,16, + 0,0,0, }; diff --git a/Python/assemble.c b/Python/assemble.c index 8cc2d50a3227f8..7c08488092de63 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -669,7 +669,7 @@ makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_ // The offset (in code units) of the END_SEND from the SEND in the `yield from` sequence. -#define END_SEND_OFFSET 5 +#define END_SEND_OFFSET 6 static int resolve_jump_offsets(instr_sequence *instrs) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index c26ba89b5ab9c8..eaa123f88507a7 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -148,8 +148,9 @@ dummy_func( pure inst(NOP, (--)) { } - family(RESUME, 0) = { + family(RESUME, 1) = { RESUME_CHECK, + RESUME_CHECK_JIT, }; macro(NOT_TAKEN) = NOP; @@ -171,12 +172,8 @@ dummy_func( } } - op(_QUICKEN_RESUME, (--)) { - #if ENABLE_SPECIALIZATION - if (tstate->tracing == 0 && this_instr->op.code == RESUME) { - FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK); - } - #endif /* ENABLE_SPECIALIZATION */ + tier1 op(_QUICKEN_RESUME, (counter/1 --)) { + _Py_Specialize_Resume(this_instr, tstate, frame); } tier1 op(_MAYBE_INSTRUMENT, (--)) { @@ -226,7 +223,11 @@ dummy_func( _QUICKEN_RESUME + _CHECK_PERIODIC_IF_NOT_YIELD_FROM; - inst(RESUME_CHECK, (--)) { + macro(RESUME_CHECK) = + unused/1 + + _RESUME_CHECK; + + op(_RESUME_CHECK, (--)) { #if defined(__EMSCRIPTEN__) DEOPT_IF(_Py_emscripten_signal_clock == 0); _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; @@ -241,6 +242,11 @@ dummy_func( #endif } + macro(RESUME_CHECK_JIT) = + unused/1 + + _RESUME_CHECK + + _JIT; + op(_MONITOR_RESUME, (--)) { int err = _Py_call_instrumentation( tstate, oparg == 0 ? PY_MONITORING_EVENT_PY_START : PY_MONITORING_EVENT_PY_RESUME, frame, this_instr); @@ -252,6 +258,7 @@ dummy_func( } macro(INSTRUMENTED_RESUME) = + unused/1 + _LOAD_BYTECODE + _MAYBE_INSTRUMENT + _CHECK_PERIODIC_IF_NOT_YIELD_FROM + @@ -3114,9 +3121,11 @@ dummy_func( tier1 op(_JIT, (--)) { #ifdef _Py_TIER2 + bool is_resume = this_instr->op.code == RESUME_CHECK_JIT; _Py_BackoffCounter counter = this_instr[1].counter; - if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) && - this_instr->op.code == JUMP_BACKWARD_JIT && + if ((backoff_counter_triggers(counter) && + !IS_JIT_TRACING() && + (this_instr->op.code == JUMP_BACKWARD_JIT || is_resume)) && next_instr->op.code != ENTER_EXECUTOR) { /* Back up over EXTENDED_ARGs so executor is inserted at the correct place */ _Py_CODEUNIT *insert_exec_at = this_instr; @@ -3124,7 +3133,8 @@ dummy_func( oparg >>= 8; insert_exec_at--; } - int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, stack_pointer, 0, NULL, oparg, NULL); + int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, + is_resume ? insert_exec_at : next_instr, stack_pointer, 0, NULL, oparg, NULL); if (succ) { ENTER_TRACING(); } @@ -3175,12 +3185,22 @@ dummy_func( tier1 inst(ENTER_EXECUTOR, (--)) { #ifdef _Py_TIER2 + PyCodeObject *code = _PyFrame_GetCode(frame); + _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; if (IS_JIT_TRACING()) { + int og_opcode = executor->vm_data.opcode; + int og_oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; + if (_PyJit_EnterExecutorShouldStopTracing(og_opcode)) { + if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) { + PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter); + } + opcode = og_opcode; + oparg = og_oparg; + DISPATCH_GOTO_NON_TRACING(); + } goto stop_tracing; } - PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; assert(executor->vm_data.index == INSTR_OFFSET() - 1); assert(executor->vm_data.code == code); assert(executor->vm_data.valid); diff --git a/Python/ceval.c b/Python/ceval.c index 950050a6027116..da41851e7448a6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1095,7 +1095,8 @@ static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = { { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on return */ { .op.code = NOP, .op.arg = 0 }, { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on yield */ - { .op.code = RESUME, .op.arg = RESUME_OPARG_DEPTH1_MASK | RESUME_AT_FUNC_START } + { .op.code = RESUME, .op.arg = RESUME_OPARG_DEPTH1_MASK | RESUME_AT_FUNC_START }, + { .op.code = CACHE, .op.arg = 0 } /* RESUME's CACHE */ }; const _Py_CODEUNIT *_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR = (_Py_CODEUNIT*)&_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS; @@ -1371,7 +1372,7 @@ _PyTier2Interpreter( for (;;) { uopcode = next_uop->opcode; #ifdef Py_DEBUG - if (frame->lltrace >= 3) { + if (frame->lltrace >= 4) { dump_stack(frame, stack_pointer); printf(" cache=["); dump_cache_item(_tos_cache0, 0, current_cached_values); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index f00913cd359c1e..e57bdd686dc338 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -93,8 +93,6 @@ break; } - /* _QUICKEN_RESUME is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */ - /* _LOAD_BYTECODE is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */ case _RESUME_CHECK_r00: { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 30f0101d2ed0e3..a66d6ccff2d82d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5691,12 +5691,22 @@ INSTRUCTION_STATS(ENTER_EXECUTOR); opcode = ENTER_EXECUTOR; #ifdef _Py_TIER2 + PyCodeObject *code = _PyFrame_GetCode(frame); + _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; if (IS_JIT_TRACING()) { + int og_opcode = executor->vm_data.opcode; + int og_oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; + if (_PyJit_EnterExecutorShouldStopTracing(og_opcode)) { + if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) { + PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter); + } + opcode = og_opcode; + oparg = og_oparg; + DISPATCH_GOTO_NON_TRACING(); + } JUMP_TO_LABEL(stop_tracing); } - PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; assert(executor->vm_data.index == INSTR_OFFSET() - 1); assert(executor->vm_data.code == code); assert(executor->vm_data.valid); @@ -7436,8 +7446,9 @@ _Py_CODEUNIT* const this_instr = next_instr; (void)this_instr; frame->instr_ptr = next_instr; - next_instr += 1; + next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_RESUME); + /* Skip 1 cache entry */ // _LOAD_BYTECODE { #ifdef Py_GIL_DISABLED @@ -7785,16 +7796,19 @@ // _JIT { #ifdef _Py_TIER2 + bool is_resume = this_instr->op.code == RESUME_CHECK_JIT; _Py_BackoffCounter counter = this_instr[1].counter; - if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) && - this_instr->op.code == JUMP_BACKWARD_JIT && + if ((backoff_counter_triggers(counter) && + !IS_JIT_TRACING() && + (this_instr->op.code == JUMP_BACKWARD_JIT || is_resume)) && next_instr->op.code != ENTER_EXECUTOR) { _Py_CODEUNIT *insert_exec_at = this_instr; while (oparg > 255) { oparg >>= 8; insert_exec_at--; } - int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, stack_pointer, 0, NULL, oparg, NULL); + int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, + is_resume ? insert_exec_at : next_instr, stack_pointer, 0, NULL, oparg, NULL); if (succ) { ENTER_TRACING(); } @@ -10446,10 +10460,10 @@ (void)(opcode); #endif frame->instr_ptr = next_instr; - next_instr += 1; + next_instr += 2; INSTRUCTION_STATS(RESUME); PREDICTED_RESUME:; - _Py_CODEUNIT* const this_instr = next_instr - 1; + _Py_CODEUNIT* const this_instr = next_instr - 2; (void)this_instr; // _LOAD_BYTECODE { @@ -10496,11 +10510,11 @@ } // _QUICKEN_RESUME { - #if ENABLE_SPECIALIZATION - if (tstate->tracing == 0 && this_instr->op.code == RESUME) { - FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK); - } - #endif /* ENABLE_SPECIALIZATION */ + uint16_t counter = read_u16(&this_instr[1].cache); + (void)counter; + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_Specialize_Resume(this_instr, tstate, frame); + stack_pointer = _PyFrame_GetStackPointer(frame); } // _CHECK_PERIODIC_IF_NOT_YIELD_FROM { @@ -10524,9 +10538,10 @@ _Py_CODEUNIT* const this_instr = next_instr; (void)this_instr; frame->instr_ptr = next_instr; - next_instr += 1; + next_instr += 2; INSTRUCTION_STATS(RESUME_CHECK); - static_assert(0 == 0, "incorrect cache size"); + static_assert(1 == 1, "incorrect cache size"); + /* Skip 1 cache entry */ #if defined(__EMSCRIPTEN__) if (_Py_emscripten_signal_clock == 0) { UPDATE_MISS_STATS(RESUME); @@ -10554,6 +10569,76 @@ DISPATCH(); } + TARGET(RESUME_CHECK_JIT) { + #if _Py_TAIL_CALL_INTERP + int opcode = RESUME_CHECK_JIT; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(RESUME_CHECK_JIT); + static_assert(1 == 1, "incorrect cache size"); + /* Skip 1 cache entry */ + // _RESUME_CHECK + { + #if defined(__EMSCRIPTEN__) + if (_Py_emscripten_signal_clock == 0) { + UPDATE_MISS_STATS(RESUME); + assert(_PyOpcode_Deopt[opcode] == (RESUME)); + JUMP_TO_PREDICTED(RESUME); + } + _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; + #endif + uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); + uintptr_t version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version); + assert((version & _PY_EVAL_EVENTS_MASK) == 0); + if (eval_breaker != version) { + UPDATE_MISS_STATS(RESUME); + assert(_PyOpcode_Deopt[opcode] == (RESUME)); + JUMP_TO_PREDICTED(RESUME); + } + #ifdef Py_GIL_DISABLED + if (frame->tlbc_index != + ((_PyThreadStateImpl *)tstate)->tlbc_index) { + UPDATE_MISS_STATS(RESUME); + assert(_PyOpcode_Deopt[opcode] == (RESUME)); + JUMP_TO_PREDICTED(RESUME); + } + #endif + } + // _JIT + { + #ifdef _Py_TIER2 + bool is_resume = this_instr->op.code == RESUME_CHECK_JIT; + _Py_BackoffCounter counter = this_instr[1].counter; + if ((backoff_counter_triggers(counter) && + !IS_JIT_TRACING() && + (this_instr->op.code == JUMP_BACKWARD_JIT || is_resume)) && + next_instr->op.code != ENTER_EXECUTOR) { + _Py_CODEUNIT *insert_exec_at = this_instr; + while (oparg > 255) { + oparg >>= 8; + insert_exec_at--; + } + int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, + is_resume ? insert_exec_at : next_instr, stack_pointer, 0, NULL, oparg, NULL); + if (succ) { + ENTER_TRACING(); + } + else { + this_instr[1].counter = restart_backoff_counter(counter); + } + } + else { + ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter); + } + #endif + } + DISPATCH(); + } + TARGET(RETURN_GENERATOR) { #if _Py_TAIL_CALL_INTERP int opcode = RETURN_GENERATOR; diff --git a/Python/instrumentation.c b/Python/instrumentation.c index b074d23277878b..1aed6769d217fe 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -576,6 +576,7 @@ sanity_check_instrumentation(PyCodeObject *code) CHECK(opcode != END_FOR); CHECK(opcode != RESUME); CHECK(opcode != RESUME_CHECK); + CHECK(opcode != RESUME_CHECK_JIT); CHECK(opcode != INSTRUMENTED_RESUME); if (!is_instrumented(opcode)) { CHECK(_PyOpcode_Deopt[opcode] == opcode); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index f57c33feec2ac2..def462bacec176 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -198,6 +198,7 @@ static void *opcode_targets_table[256] = { &&TARGET_LOAD_SUPER_ATTR_ATTR, &&TARGET_LOAD_SUPER_ATTR_METHOD, &&TARGET_RESUME_CHECK, + &&TARGET_RESUME_CHECK_JIT, &&TARGET_SEND_GEN, &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, @@ -232,7 +233,6 @@ static void *opcode_targets_table[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_INSTRUMENTED_END_FOR, &&TARGET_INSTRUMENTED_POP_ITER, &&TARGET_INSTRUMENTED_END_SEND, @@ -472,7 +472,7 @@ static void *opcode_tracing_targets_table[256] = { &&TARGET_TRACE_RECORD, &&TARGET_TRACE_RECORD, &&TARGET_TRACE_RECORD, - &&_unknown_opcode, + &&TARGET_TRACE_RECORD, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -718,6 +718,7 @@ static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RERAISE(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESERVED(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME_CHECK(TAIL_CALL_PARAMS); +static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RESUME_CHECK_JIT(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_GENERATOR(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_RETURN_VALUE(TAIL_CALL_PARAMS); static PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_SEND(TAIL_CALL_PARAMS); @@ -959,6 +960,7 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [RESERVED] = _TAIL_CALL_RESERVED, [RESUME] = _TAIL_CALL_RESUME, [RESUME_CHECK] = _TAIL_CALL_RESUME_CHECK, + [RESUME_CHECK_JIT] = _TAIL_CALL_RESUME_CHECK_JIT, [RETURN_GENERATOR] = _TAIL_CALL_RETURN_GENERATOR, [RETURN_VALUE] = _TAIL_CALL_RETURN_VALUE, [SEND] = _TAIL_CALL_SEND, @@ -1007,7 +1009,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [125] = _TAIL_CALL_UNKNOWN_OPCODE, [126] = _TAIL_CALL_UNKNOWN_OPCODE, [127] = _TAIL_CALL_UNKNOWN_OPCODE, - [213] = _TAIL_CALL_UNKNOWN_OPCODE, [214] = _TAIL_CALL_UNKNOWN_OPCODE, [215] = _TAIL_CALL_UNKNOWN_OPCODE, [216] = _TAIL_CALL_UNKNOWN_OPCODE, @@ -1217,6 +1218,7 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [RESERVED] = _TAIL_CALL_TRACE_RECORD, [RESUME] = _TAIL_CALL_TRACE_RECORD, [RESUME_CHECK] = _TAIL_CALL_TRACE_RECORD, + [RESUME_CHECK_JIT] = _TAIL_CALL_TRACE_RECORD, [RETURN_GENERATOR] = _TAIL_CALL_TRACE_RECORD, [RETURN_VALUE] = _TAIL_CALL_TRACE_RECORD, [SEND] = _TAIL_CALL_TRACE_RECORD, @@ -1265,7 +1267,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [125] = _TAIL_CALL_UNKNOWN_OPCODE, [126] = _TAIL_CALL_UNKNOWN_OPCODE, [127] = _TAIL_CALL_UNKNOWN_OPCODE, - [213] = _TAIL_CALL_UNKNOWN_OPCODE, [214] = _TAIL_CALL_UNKNOWN_OPCODE, [215] = _TAIL_CALL_UNKNOWN_OPCODE, [216] = _TAIL_CALL_UNKNOWN_OPCODE, diff --git a/Python/optimizer.c b/Python/optimizer.c index a9e788d0dcb1d5..f350b82397f575 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -632,6 +632,12 @@ _PyJit_translate_single_bytecode_to_trace( target--; } + if (opcode == ENTER_EXECUTOR) { + _PyExecutorObject *executor = old_code->co_executors->executors[oparg & 255]; + opcode = executor->vm_data.opcode; + oparg = (oparg & ~255) | executor->vm_data.oparg; + } + if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]] > 0) { uint16_t backoff = (this_instr + 1)->counter.value_and_backoff; // adaptive_counter_cooldown is a fresh specialization. @@ -823,6 +829,7 @@ _PyJit_translate_single_bytecode_to_trace( case RESUME: case RESUME_CHECK: + case RESUME_CHECK_JIT: /* Use a special tier 2 version of RESUME_CHECK to allow traces to * start with RESUME_CHECK */ ADD_TO_TRACE(_TIER2_RESUME_CHECK, 0, 0, target); @@ -1038,12 +1045,9 @@ _PyJit_TryInitializeTracing( _Py_RecordFuncPtr record_func = _PyOpcode_RecordFunctions[record_func_index]; record_func(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value); } - assert(curr_instr->op.code == JUMP_BACKWARD_JIT || (exit != NULL)); + assert(curr_instr->op.code == JUMP_BACKWARD_JIT || curr_instr->op.code == RESUME_CHECK_JIT || (exit != NULL)); tracer->initial_state.jump_backward_instr = curr_instr; - if (_PyOpcode_Caches[_PyOpcode_Deopt[close_loop_instr->op.code]]) { - close_loop_instr[1].counter = trigger_backoff_counter(); - } tracer->is_tracing = true; return 1; } @@ -1063,7 +1067,12 @@ _PyJit_FinalizeTracing(PyThreadState *tstate, int err) tracer->initial_state.jump_backward_instr[1].counter = restart_backoff_counter(counter); } else { - tracer->initial_state.jump_backward_instr[1].counter = initial_jump_backoff_counter(&tstate->interp->opt_config); + if (tracer->initial_state.jump_backward_instr[0].op.code == JUMP_BACKWARD_JIT) { + tracer->initial_state.jump_backward_instr[1].counter = initial_jump_backoff_counter(&tstate->interp->opt_config); + } + else { + tracer->initial_state.jump_backward_instr[1].counter = initial_resume_backoff_counter(&tstate->interp->opt_config); + } } } else if (tracer->initial_state.executor->vm_data.valid) { @@ -1092,6 +1101,19 @@ _PyJit_FinalizeTracing(PyThreadState *tstate, int err) tracer->is_tracing = false; } +bool +_PyJit_EnterExecutorShouldStopTracing(int og_opcode) +{ + // Continue tracing (skip over the executor). If it's a RESUME + // trace to form longer, more optimizeable traces. + // We want to trace over RESUME traces. Otherwise, functions with lots of RESUME + // end up with many fragmented traces which perform badly. + // See for example, the richards benchmark in pyperformance. + // For consideration: We may want to consider tracing over side traces + // inserted into bytecode as well in the future. + return og_opcode == RESUME_CHECK_JIT; +} + void _PyJit_TracerFree(_PyThreadStateImpl *_tstate) { @@ -1780,7 +1802,7 @@ _Py_ExecutorDetach(_PyExecutorObject *executor) assert(instruction->op.code == ENTER_EXECUTOR); int index = instruction->op.arg; assert(code->co_executors->executors[index] == executor); - instruction->op.code = executor->vm_data.opcode; + instruction->op.code = _PyOpcode_Deopt[executor->vm_data.opcode]; instruction->op.arg = executor->vm_data.oparg; executor->vm_data.code = NULL; code->co_executors->executors[index] = NULL; diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 942a730e4faccf..52a0c08ac677b7 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -17,8 +17,6 @@ break; } - /* _QUICKEN_RESUME is not a viable micro-op for tier 2 */ - /* _LOAD_BYTECODE is not a viable micro-op for tier 2 */ case _RESUME_CHECK: { diff --git a/Python/pystate.c b/Python/pystate.c index fcb73b4dcefe1d..143175da0f45c7 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -607,11 +607,13 @@ init_interpreter(PyInterpreterState *interp, // Initialize optimization configuration from environment variables // PYTHON_JIT_STRESS sets aggressive defaults for testing, but can be overridden uint16_t jump_default = JUMP_BACKWARD_INITIAL_VALUE; + uint16_t resume_default = RESUME_INITIAL_VALUE; uint16_t side_exit_default = SIDE_EXIT_INITIAL_VALUE; if (is_env_enabled("PYTHON_JIT_STRESS")) { jump_default = 63; side_exit_default = 63; + resume_default = 127; } init_policy(&interp->opt_config.jump_backward_initial_value, @@ -620,6 +622,12 @@ init_interpreter(PyInterpreterState *interp, init_policy(&interp->opt_config.jump_backward_initial_backoff, "PYTHON_JIT_JUMP_BACKWARD_INITIAL_BACKOFF", JUMP_BACKWARD_INITIAL_BACKOFF, 0, MAX_BACKOFF); + init_policy(&interp->opt_config.resume_initial_value, + "PYTHON_JIT_RESUME_INITIAL_VALUE", + resume_default, 1, MAX_VALUE); + init_policy(&interp->opt_config.resume_initial_backoff, + "PYTHON_JIT_RESUME_INITIAL_BACKOFF", + RESUME_INITIAL_BACKOFF, 0, MAX_BACKOFF); init_policy(&interp->opt_config.side_exit_initial_value, "PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE", side_exit_default, 1, MAX_VALUE); diff --git a/Python/specialize.c b/Python/specialize.c index 1eabdb1b5b194e..4ef8b27795650c 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -46,16 +46,18 @@ void _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters) { #if ENABLE_SPECIALIZATION - _Py_BackoffCounter jump_counter, adaptive_counter; + _Py_BackoffCounter jump_counter, adaptive_counter, resume_counter; if (enable_counters) { PyThreadState *tstate = _PyThreadState_GET(); PyInterpreterState *interp = tstate->interp; jump_counter = initial_jump_backoff_counter(&interp->opt_config); adaptive_counter = adaptive_counter_warmup(); + resume_counter = initial_resume_backoff_counter(&interp->opt_config); } else { jump_counter = initial_unreachable_backoff_counter(); adaptive_counter = initial_unreachable_backoff_counter(); + resume_counter = initial_unreachable_backoff_counter(); } int opcode = 0; int oparg = 0; @@ -70,6 +72,9 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters case JUMP_BACKWARD: instructions[i + 1].counter = jump_counter; break; + case RESUME: + instructions[i + 1].counter = resume_counter; + break; case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: case POP_JUMP_IF_NONE: @@ -2781,6 +2786,28 @@ _Py_Specialize_ContainsOp(_PyStackRef value_st, _Py_CODEUNIT *instr) return; } + +void +_Py_Specialize_Resume(_Py_CODEUNIT *instr, PyThreadState *tstate, _PyInterpreterFrame *frame) +{ + if (tstate->tracing == 0 && instr->op.code == RESUME) { + if (tstate->interp->jit) { + PyCodeObject *co = (PyCodeObject *)PyStackRef_AsPyObjectBorrow(frame->f_executable); + if (co != NULL && + PyCode_Check(co) && + (co->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) == 0) { + specialize(instr, RESUME_CHECK_JIT); + set_counter((_Py_BackoffCounter *)instr + 1, initial_resume_backoff_counter(&tstate->interp->opt_config)); + return; + } + } + specialize(instr, RESUME_CHECK); + return; + } + unspecialize(instr); + return; +} + #ifdef Py_STATS void _Py_GatherStats_GetIter(_PyStackRef iterable) @@ -2883,5 +2910,6 @@ const struct _PyCode8 _Py_InitCleanup = { EXIT_INIT_CHECK, 0, RETURN_VALUE, 0, RESUME, RESUME_AT_FUNC_START, + CACHE, 0, /* RESUME's cache */ } }; From ae1b3074330b8eefada470fd921b05664e6646f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 19:07:07 +0100 Subject: [PATCH 486/498] build(deps): bump hypothesis from 6.135.26 to 6.151.9 in /Tools (#145948) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.135.26 to 6.151.9. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.135.26...hypothesis-python-6.151.9) --- updated-dependencies: - dependency-name: hypothesis dependency-version: 6.151.9 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Tools/requirements-hypothesis.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/requirements-hypothesis.txt b/Tools/requirements-hypothesis.txt index e5deac497fbe3f..8ecf796ec7343a 100644 --- a/Tools/requirements-hypothesis.txt +++ b/Tools/requirements-hypothesis.txt @@ -1,4 +1,4 @@ # Requirements file for hypothesis that # we use to run our property-based tests in CI. -hypothesis==6.135.26 +hypothesis==6.151.9 From 2a0fa500f82fc160feb726c0631f58c9a2f76796 Mon Sep 17 00:00:00 2001 From: wavebyrd <160968744+wavebyrd@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:25:31 -0400 Subject: [PATCH 487/498] gh-145870: Fix Format.SOURCE reference in get_annotations docstring (#145889) The get_annotations() docstring incorrectly referred to the SOURCE format, which was renamed to STRING during PEP 749 development. Co-authored-by: Carson Jones --- Lib/annotationlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 832d160de7f4e5..df8fb5e4c62079 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -919,7 +919,7 @@ def get_annotations( does not exist, the __annotate__ function is called. The FORWARDREF format uses __annotations__ if it exists and can be evaluated, and otherwise falls back to calling the __annotate__ function. - The SOURCE format tries __annotate__ first, and falls back to + The STRING format tries __annotate__ first, and falls back to using __annotations__, stringified using annotations_to_string(). This function handles several details for you: From 4e96282ee42ab51cf325b52a0173ddddbe66c05c Mon Sep 17 00:00:00 2001 From: trag1c Date: Mon, 16 Mar 2026 20:55:29 +0100 Subject: [PATCH 488/498] Docs: remove unmatched parenthesis for `asyncio.TaskGroup` note (#146035) --- Doc/library/asyncio-task.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 1b7c8ff0c762a6..e2a6752be12b67 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -557,7 +557,7 @@ Running Tasks Concurrently provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks: if a task (or a subtask, a task scheduled by a task) raises an exception, *TaskGroup* will, while *gather* will not, - cancel the remaining scheduled tasks). + cancel the remaining scheduled tasks. .. _asyncio_example_gather: From 104cae039ac428709c7bcf9b1a00102f97be0a5c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 17 Mar 2026 00:01:41 +0100 Subject: [PATCH 489/498] gh-142927: Move hotspots up flamegraph sidebar (#145428) --- .../flamegraph_template.html | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html b/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html index 07b15a5a2b48c7..c0d40b2712beea 100644 --- a/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html +++ b/Lib/profiling/sampling/_flamegraph_assets/flamegraph_template.html @@ -178,6 +178,51 @@

    Profile Summary